001 /** 002 * Copyright 2004-2014 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 }