001 /**
002 * Copyright 2004-2013 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.kuali.hr.time.overtime.daily.rule.service;
017
018 import java.math.BigDecimal;
019 import java.util.ArrayList;
020 import java.util.HashMap;
021 import java.util.List;
022
023 import org.joda.time.DateTime;
024 import org.junit.Assert;
025 import org.junit.Test;
026 import org.kuali.hr.KPMEWebTestCase;
027 import org.kuali.kpme.core.FunctionalTest;
028 import org.kuali.kpme.core.calendar.entry.CalendarEntry;
029 import org.kuali.kpme.core.service.HrServiceLocator;
030 import org.kuali.kpme.core.util.TKUtils;
031 import org.kuali.kpme.tklm.time.rules.overtime.daily.DailyOvertimeRule;
032 import org.kuali.kpme.tklm.time.rules.overtime.daily.service.DailyOvertimeRuleService;
033 import org.kuali.kpme.tklm.time.service.TkServiceLocator;
034 import org.kuali.kpme.tklm.time.timeblock.TimeBlock;
035 import org.kuali.kpme.tklm.time.timesheet.TimesheetDocument;
036 import org.kuali.kpme.tklm.time.util.TkTimeBlockAggregate;
037 import org.kuali.kpme.tklm.utils.TkTestUtils;
038
039 @FunctionalTest
040 public class DailyOvertimeRuleServiceTest extends KPMEWebTestCase {
041
042 public static final String USER_PRINCIPAL_ID = "admin";
043 private DateTime JAN_AS_OF_DATE = new DateTime(2010, 1, 1, 0, 0, 0, 0, TKUtils.getSystemDateTimeZone());
044
045
046 private void createDailyOvertimeRule(String fromEarnGroup, String earnCode, String location, String paytype, String dept, Long workArea, Long task, BigDecimal minHours, BigDecimal maxGap, String overtimePref) {
047 DailyOvertimeRuleService service = TkServiceLocator.getDailyOvertimeRuleService();
048 DailyOvertimeRule rule = new DailyOvertimeRule();
049
050 rule.setEffectiveLocalDate(JAN_AS_OF_DATE.toLocalDate());
051 rule.setFromEarnGroup(fromEarnGroup);
052 rule.setEarnCode(earnCode);
053 rule.setLocation(location);
054 rule.setPaytype(paytype);
055 rule.setDept(dept);
056 rule.setWorkArea(workArea);
057 rule.setMaxGap(maxGap);
058 rule.setMinHours(minHours);
059 rule.setActive(true);
060
061 service.saveOrUpdate(rule);
062 }
063
064
065 @SuppressWarnings("serial")
066 @Test
067 public void testDailyOvertimeGapExceeded() throws Exception {
068 Long jobNumber = 30L;
069 Long workArea = 30L;
070 Long task = 30L;
071 createDailyOvertimeRule("REG", "OVT", "SD1", "BW", "TEST-DEPT", workArea,
072 task, new BigDecimal(8), new BigDecimal("0.10"), null);
073 // Create Time Blocks (2 days, 2 blocks on each day, 15 minute gap between blocks, 4 hours first block, 5 the next.
074 // Should end up with 2 hours total OVT.
075 DateTime start = new DateTime(2010, 3, 29, 14, 0, 0, 0, TKUtils.getSystemDateTimeZone());
076 List<TimeBlock> blocks = new ArrayList<TimeBlock>();
077 CalendarEntry payCalendarEntry = HrServiceLocator.getCalendarEntryService().getCurrentCalendarDates("admin", start);
078 blocks.addAll(TkTestUtils.createUniformTimeBlocks(start, 2, new BigDecimal("4"), "REG", jobNumber, workArea, task));
079 blocks.addAll(TkTestUtils.createUniformTimeBlocks(start.plusHours(4).plusMinutes(15), 2, new BigDecimal("5"), "REG", jobNumber, workArea, task));
080 TkTimeBlockAggregate aggregate = new TkTimeBlockAggregate(blocks, payCalendarEntry);
081
082 // Verify pre-Rule Run
083 TkTestUtils.verifyAggregateHourSums("Pre-Check", new HashMap<String,BigDecimal>() {{put("OVT", BigDecimal.ZERO);put("REG", new BigDecimal(18));}},aggregate,2);
084
085 // Run Rule
086 TimesheetDocument tdoc = TkTestUtils.populateBlankTimesheetDocument(start, "admin");
087 tdoc.setTimeBlocks(blocks);
088 TkServiceLocator.getDailyOvertimeRuleService().processDailyOvertimeRules(tdoc, aggregate);
089
090 // Verify post-Rule Run
091 TkTestUtils.verifyAggregateHourSums("Post Rules Check", new HashMap<String,BigDecimal>() {{put("OVT", new BigDecimal(0));put("REG", new BigDecimal(18));}},aggregate,2);
092 }
093
094
095 @SuppressWarnings("serial")
096 @Test
097 public void testDailyOvertimeSimpleCase() throws Exception {
098 Long jobNumber = 30L;
099 Long workArea = 30L;
100 Long task = 30L;
101 createDailyOvertimeRule("REG", "OVT", "SD1", "BW", "TEST-DEPT", workArea,
102 task, new BigDecimal(8), new BigDecimal("15.0"), null);
103
104 // Create Time Blocks (2 days, 2 blocks on each day, 15 minute gap between blocks, 4 hours first block, 5 the next.
105 // Should end up with 2 hours total OVT.
106 DateTime start = new DateTime(2010, 3, 29, 14, 0, 0, 0, TKUtils.getSystemDateTimeZone());
107 List<TimeBlock> blocks = new ArrayList<TimeBlock>();
108 CalendarEntry payCalendarEntry = HrServiceLocator.getCalendarEntryService().getCurrentCalendarDates("admin", start);
109 blocks.addAll(TkTestUtils.createUniformTimeBlocks(start, 2, new BigDecimal("4"), "REG", jobNumber, workArea, task));
110 blocks.addAll(TkTestUtils.createUniformTimeBlocks(start.plusHours(4).plusMinutes(15), 2, new BigDecimal("5"), "REG", jobNumber, workArea, task));
111 TkTimeBlockAggregate aggregate = new TkTimeBlockAggregate(blocks, payCalendarEntry);
112
113 // Verify pre-Rule Run
114 TkTestUtils.verifyAggregateHourSums("Pre-Check", new HashMap<String,BigDecimal>() {{put("OVT", BigDecimal.ZERO);put("REG", new BigDecimal(18));}},aggregate,2);
115
116 // Run Rule
117 TimesheetDocument tdoc = TkTestUtils.populateBlankTimesheetDocument(start, "admin");
118 tdoc.setTimeBlocks(blocks);
119 TkServiceLocator.getDailyOvertimeRuleService().processDailyOvertimeRules(tdoc, aggregate);
120
121 // Verify post-Rule Run
122 TkTestUtils.verifyAggregateHourSums("Post Rules Check", new HashMap<String,BigDecimal>() {{put("OVT", new BigDecimal(2));put("REG", new BigDecimal(16));}},aggregate,2);
123 }
124
125 @Test
126 public void testRuleCreationAndRetrieval() throws Exception {
127 Long workArea = 0L;
128 Long task = 30L;
129 createDailyOvertimeRule("REG", "OVT", "SD1", "BW", "TEST-DEPT", workArea,
130 task, new BigDecimal(8), new BigDecimal("0.25"), null);
131 DailyOvertimeRule rule = TkServiceLocator.getDailyOvertimeRuleService().getDailyOvertimeRule("SD1", "BW", "TEST-DEPT", workArea, JAN_AS_OF_DATE.toLocalDate());
132 Assert.assertNotNull("Rule not created.", rule);
133 }
134
135 @Test
136 public void testSearchDailyOvertimeRules() throws Exception {
137 createDailyOvertimeRule("REG", "OVT", "SD1", "BL", "TEST-DEPT", 30L, 30L, new BigDecimal(8), new BigDecimal("0.10"), null);
138 createDailyOvertimeRule("REG", "OVT", "SD1", "BL", "TEST-DEPT5", 5555L, 30L, new BigDecimal(8), new BigDecimal("0.10"), null);
139
140 List<DailyOvertimeRule> allResults = TkServiceLocator.getDailyOvertimeRuleService().getDailyOvertimeRules("admin", null, null, null, null, null, "Y", "N");
141 Assert.assertEquals("Search returned the wrong number of results.", 2, allResults.size());
142
143 List<DailyOvertimeRule> restrictedResults = TkServiceLocator.getDailyOvertimeRuleService().getDailyOvertimeRules("fran", null, null, null, null, null, "Y", "N");
144 Assert.assertEquals("Search returned the wrong number of results.", 0, restrictedResults.size());
145 }
146
147 }