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.shiftdiff.rule; 017 018 import java.math.BigDecimal; 019 import java.sql.Time; 020 import java.util.ArrayList; 021 import java.util.HashMap; 022 import java.util.List; 023 024 import org.joda.time.DateTime; 025 import org.joda.time.DateTimeZone; 026 import org.joda.time.LocalTime; 027 import org.junit.Assert; 028 import org.junit.Ignore; 029 import org.junit.Test; 030 import org.kuali.hr.KPMEWebTestCase; 031 import org.kuali.kpme.core.FunctionalTest; 032 import org.kuali.kpme.core.assignment.Assignment; 033 import org.kuali.kpme.core.assignment.AssignmentDescriptionKey; 034 import org.kuali.kpme.core.calendar.entry.CalendarEntry; 035 import org.kuali.kpme.core.service.HrServiceLocator; 036 import org.kuali.kpme.core.util.TKUtils; 037 import org.kuali.kpme.tklm.time.rules.shiftdifferential.ShiftDifferentialRule; 038 import org.kuali.kpme.tklm.time.rules.shiftdifferential.service.ShiftDifferentialRuleService; 039 import org.kuali.kpme.tklm.time.service.TkServiceLocator; 040 import org.kuali.kpme.tklm.time.timeblock.TimeBlock; 041 import org.kuali.kpme.tklm.time.timesheet.TimesheetDocument; 042 import org.kuali.kpme.tklm.time.util.TkTimeBlockAggregate; 043 import org.kuali.kpme.tklm.utils.TkTestUtils; 044 045 /** 046 * 047 * @author djunk 048 * 049 */ 050 @FunctionalTest 051 public class ShiftDifferentialRuleServiceProcessTest extends KPMEWebTestCase { 052 053 054 public static final String USER_PRINCIPAL_ID = "admin"; 055 private DateTime JAN_AS_OF_DATE = new DateTime(2010, 1, 1, 0, 0, 0, 0, TKUtils.getSystemDateTimeZone()); 056 057 058 /** 059 * Test with boundary carryover and overlapping rules. 060 * 061 * Rule 1: 062 * 063 * Runs on Tu, Wed, Th on the interval: [22:00, 4:00) 064 * Max Gap: 15 minutes 065 * Min Hours: 3 066 * 067 * Rule 2: 068 * 069 * Runs on Tu, Th on the interval: [23:00, 2:00) 070 * Max Gap: 2 hours 071 * Min Hours: 3 072 * 073 * Rule 3: 074 * 075 * Runs on W, Th on the interval: [5:00, 12:00) 076 * Max Gap: 15 minutes 077 * Min Hours: 7 hours 078 * 079 * Rule 4: 080 * 081 * Runs on W on the interval: [5:00, 12:00) 082 * Max Gap: 15 minutes 083 * Min Hours: 5 084 * 085 * 086 * |--------------+----+------------+------------| 087 * | Tu : 8/31/10 | XX | W : 9/1/10 | Th: 9/2/10 | 088 * |--------------+----+------------+------------| 089 * | 9:45p - 11:45| XX | Mid - 5a | 5p - 11p | 090 * | | XX | 6a - Noon | | 091 * |--------------+----+------------+------------| 092 * 093 * 094 * Aug 31: 2h : 21:45 - 23:45 (Tue) ** 095 * [1: 5h 45m] // [2: 2h 45m] - Not qualifying, min hours must be 3. 096 * Sep 1: 5h : 00:00 - 05:00 (Wed) ** 097 * Sep 1: 6h : 06:00 - 12:00 (Wed) [4: 6h] 098 * 099 * Sep 1: 2h : 22:00 - 24:00 (Wed) 100 * Sep 2: 1h : 00:00 - 01:00 (Thu) [1: 3h] 101 * 102 * Sep 2: 6h : 17:00 - 22:00 (Thu) 103 * 104 * 1: [22:00, 4:00) (Tue/Wed/Thu) minimum: 3h gap: 15m 105 * 2: [23:00, 2:00) (Tue/Thu) minimum: 3h gap: 2h 106 * 3: [05:00, 12:00) (Wed/Thu) minimum: 7h gap: 15m 107 * 4: [05:00, 12:00) (Wed) minimum: 5h gap: 15m 108 * 109 */ 110 @SuppressWarnings("serial") 111 @Test 112 public void testProcessTimesheetBoundaryCarryoverOverlapCase() throws Exception { 113 DateTimeZone tz = HrServiceLocator.getTimezoneService().getUserTimezoneWithFallback(); 114 // Create the Rule Sun, Mon, Tue, Wed, Thu, Fri, Sat 115 boolean[] dayArray = {false, false, true, true, true, true, true}; 116 // Matches HR Job ID #1 (job # 30) 117 Long jobNumber = 30L; 118 Long workArea = 0L; 119 this.createShiftDifferentialRule( 120 "BWS-CAL", "REG", "PRM", "SD1", "SD1", "SD1", 121 (new DateTime(2010, 8, 31, 22, 0, 0, 0, tz)), 122 (new DateTime(2010, 8, 31, 4, 0, 0, 0, tz)), 123 new BigDecimal(3), // minHours 124 new BigDecimal("0.25"), // maxGap 125 dayArray); 126 127 // dayArray = new boolean [] {false, false, true, false, true, true, true}; 128 // this.createShiftDifferentialRule( 129 // "BWS-CAL", "REG", "PRM", "SD1", "SD1", "SD1", 130 // (new DateTime(2010, 8, 31, 23, 0, 0, 0, tz)), 131 // (new DateTime(2010, 8, 31, 2, 0, 0, 0, tz)), 132 // new BigDecimal(3), // minHours 133 // new BigDecimal("2.0"), // maxGap 134 // dayArray); 135 // 136 // dayArray = new boolean[] {false, false, false, true, true, false, false}; 137 // this.createShiftDifferentialRule( 138 // "BWS-CAL", "REG", "PRM", "SD1", "SD1", "SD1", 139 // (new DateTime(2010, 8, 31, 5, 0, 0, 0, tz)), 140 // (new DateTime(2010, 8, 31, 12, 0, 0, 0, tz)), 141 // new BigDecimal("7.0"), // minHours 142 // new BigDecimal(".25"), // maxGap 143 // dayArray); 144 // dayArray = new boolean[] {false, false, false, true, false, false, false}; 145 // this.createShiftDifferentialRule( 146 // "BWS-CAL", "REG", "PRM", "SD1", "SD1", "SD1", 147 // (new DateTime(2010, 8, 31, 5, 0, 0, 0, tz)), 148 // (new DateTime(2010, 8, 31, 12, 0, 0, 0, tz)), 149 // new BigDecimal("5"), // minHours 150 // new BigDecimal("0.25"), // maxGap 151 // dayArray); 152 153 // Timeblocks 154 155 // August 156 DateTime beginPeriodDate = new DateTime(2010, 8, 15, 0, 0, 0, 0, tz); 157 DateTime endPeriodDate = new DateTime(2010, 9, 1, 0, 0, 0, 0); 158 CalendarEntry endOfAugust = HrServiceLocator.getCalendarEntryService().getCalendarEntryByIdAndPeriodEndDate("2", endPeriodDate); 159 DateTime start = new DateTime(2010, 8, 31, 21, 45, 0, 0, tz); 160 List<TimeBlock> blocks = new ArrayList<TimeBlock>(); 161 TimesheetDocument tdoc = TkServiceLocator.getTimesheetService().openTimesheetDocument("admin", endOfAugust); 162 Assignment assignment = HrServiceLocator.getAssignmentService().getAssignment("admin", AssignmentDescriptionKey.get("30_30_30"), beginPeriodDate.toLocalDate()); 163 blocks.addAll(TkTestUtils.createUniformActualTimeBlocks(tdoc, assignment, "RGN", start, 1, new BigDecimal(2), BigDecimal.ZERO, "admin")); 164 TkTimeBlockAggregate aggregate = new TkTimeBlockAggregate(blocks, endOfAugust, HrServiceLocator.getCalendarService().getCalendar(endOfAugust.getHrCalendarId()), true); 165 tdoc.setTimeBlocks(blocks); 166 TkServiceLocator.getShiftDifferentialRuleService().processShiftDifferentialRules(tdoc, aggregate); 167 TkTestUtils.verifyAggregateHourSumsFlatList("August Pre-Check", new HashMap<String,BigDecimal>() {{put("PRM", BigDecimal.ZERO);put("RGN", new BigDecimal(2));}},aggregate); 168 TkServiceLocator.getTimeBlockService().saveTimeBlocks(new ArrayList<TimeBlock>(), aggregate.getFlattenedTimeBlockList(), "admin"); 169 170 171 // September 172 173 start = new DateTime(2010, 9, 1, 0, 0, 0, 0, tz); 174 CalendarEntry payCalendarEntry = HrServiceLocator.getCalendarEntryService().getCurrentCalendarDates("admin", start.toLocalDate().toDateTimeAtStartOfDay()); 175 tdoc = TkServiceLocator.getTimesheetService().openTimesheetDocument("admin", payCalendarEntry); 176 blocks = new ArrayList<TimeBlock>(); 177 blocks.addAll(TkTestUtils.createUniformTimeBlocks(start, 1, new BigDecimal("5"), "RGN", jobNumber, workArea)); 178 blocks.addAll(TkTestUtils.createUniformTimeBlocks(start.plusHours(6), 1, new BigDecimal("6"), "RGN", jobNumber, workArea)); 179 blocks.addAll(TkTestUtils.createUniformTimeBlocks(start.plusHours(22), 1, new BigDecimal("2"), "RGN", jobNumber, workArea)); 180 blocks.addAll(TkTestUtils.createUniformTimeBlocks(start.plusDays(1), 1, new BigDecimal("1"), "RGN", jobNumber, workArea)); 181 blocks.addAll(TkTestUtils.createUniformTimeBlocks(start.plusDays(1).plusHours(17), 1, new BigDecimal("6"), "RGN", jobNumber, workArea)); 182 setDocumentIdOnBlocks(blocks, tdoc.getDocumentId()); 183 184 aggregate = new TkTimeBlockAggregate(blocks, payCalendarEntry, HrServiceLocator.getCalendarService().getCalendar(payCalendarEntry.getHrCalendarId()), true); 185 186 TkTestUtils.verifyAggregateHourSumsFlatList("September Pre-Check", new HashMap<String,BigDecimal>() {{put("PRM", BigDecimal.ZERO);put("RGN", new BigDecimal(20));}},aggregate); 187 188 // Verify carry over and applied PRM bucket 189 TkServiceLocator.getShiftDifferentialRuleService().processShiftDifferentialRules(tdoc, aggregate); 190 TkTestUtils.verifyAggregateHourSumsFlatList("September Post-Check", new HashMap<String,BigDecimal>() {{put("PRM", new BigDecimal("8.75"));put("RGN", new BigDecimal(20));}},aggregate); 191 } 192 193 private void setDocumentIdOnBlocks(List<TimeBlock> blocks, String id) { 194 for (TimeBlock b : blocks) { 195 b.setDocumentId(id); 196 } 197 } 198 199 200 /** 201 * Test where previous time sheet contains hours that should be added to 202 * the next pay periods first day shift. 203 * 204 * Runs on Tu, Th on the interval: [22:00, 4:00) 205 * Max Gap: 15 minutes 206 * Min Hours: 3 207 * 208 * |--------------+----+------------+-------------| 209 * | Tu : 8/31/10 | XX | W : 9/1/10 | Th : 9/2/10 | 210 * |--------------+----+------------+-------------| 211 * | 10pm - Mid | XX | Mid - 5am | 5pm - 11pm | 212 * |--------------+----+------------+-------------| 213 * 214 * @throws Exception 215 */ 216 @SuppressWarnings("serial") 217 @Test 218 public void testProcessShiftTimesheeetBoundaryCarryoverCase() throws Exception { 219 // Create the Rule Sun, Mon, Tue, Wed, Thu, Fri, Sat 220 boolean[] dayArray = {false, false, true, false, true, true, true}; 221 // Matches HR Job ID #1 (job # 30) 222 Long jobNumber = 30L; 223 Long workArea = 0L; 224 225 DateTimeZone tz = HrServiceLocator.getTimezoneService().getUserTimezoneWithFallback(); 226 this.createShiftDifferentialRule( 227 "BWS-CAL", 228 "REG", 229 "PRM", 230 "SD1", 231 "SD1", 232 "SD1", 233 (new DateTime(2010, 8, 31, 22, 0, 0, 0, tz)), 234 (new DateTime(2010, 8, 31, 5, 0, 0, 0, tz)), 235 new BigDecimal(3), // minHours 236 new BigDecimal("0.25"), // maxGap 237 dayArray); 238 239 // August 240 DateTime endPeriodDate = new DateTime(2010, 9, 1, 0, 0, 0, 0); 241 CalendarEntry endOfAugust = HrServiceLocator.getCalendarEntryService().getCalendarEntryByIdAndPeriodEndDate("2", endPeriodDate); 242 DateTime start = new DateTime(2010, 8, 31, 22, 0, 0, 0, tz); 243 List<TimeBlock> blocks = new ArrayList<TimeBlock>(); 244 TimesheetDocument tdoc = TkServiceLocator.getTimesheetService().openTimesheetDocument("admin", endOfAugust); 245 Assignment assignment = HrServiceLocator.getAssignmentService().getAssignment("admin", AssignmentDescriptionKey.get("30_30_30"), endOfAugust.getBeginPeriodFullDateTime().toLocalDate()); 246 blocks.addAll(TkTestUtils.createUniformActualTimeBlocks(tdoc, assignment, "RGN", start, 1, new BigDecimal(2), BigDecimal.ZERO, "admin")); 247 TkTimeBlockAggregate aggregate = new TkTimeBlockAggregate(blocks, endOfAugust, HrServiceLocator.getCalendarService().getCalendar(endOfAugust.getHrCalendarId()), true); 248 249 250 251 tdoc.setTimeBlocks(blocks); 252 TkServiceLocator.getShiftDifferentialRuleService().processShiftDifferentialRules(tdoc, aggregate); 253 TkTestUtils.verifyAggregateHourSumsFlatList("August Pre-Check", new HashMap<String,BigDecimal>() {{put("PRM", BigDecimal.ZERO);put("RGN", new BigDecimal(2));}},aggregate); 254 TkServiceLocator.getTimeBlockService().saveTimeBlocks(new ArrayList<TimeBlock>(), aggregate.getFlattenedTimeBlockList(), "admin"); 255 256 257 // September 258 start = new DateTime(2010, 9, 1, 0, 0, 0, 0, tz); 259 CalendarEntry payCalendarEntry = HrServiceLocator.getCalendarEntryService().getCurrentCalendarDates("admin", start.toLocalDate().toDateTimeAtStartOfDay()); 260 tdoc = TkServiceLocator.getTimesheetService().openTimesheetDocument("admin", payCalendarEntry); 261 blocks = new ArrayList<TimeBlock>(); 262 blocks.addAll(TkTestUtils.createUniformTimeBlocks(start, 1, new BigDecimal("5"), "RGN", jobNumber, workArea)); 263 aggregate = new TkTimeBlockAggregate(blocks, payCalendarEntry, HrServiceLocator.getCalendarService().getCalendar(payCalendarEntry.getHrCalendarId()), true); 264 TkTestUtils.verifyAggregateHourSumsFlatList("September Pre-Check", new HashMap<String,BigDecimal>() {{put("PRM", BigDecimal.ZERO);put("RGN", new BigDecimal(5));}},aggregate); 265 266 // Verify carry over and applied PRM bucket 267 TkServiceLocator.getShiftDifferentialRuleService().processShiftDifferentialRules(tdoc, aggregate); 268 TkTestUtils.verifyAggregateHourSumsFlatList("September Post-Check", new HashMap<String,BigDecimal>() {{put("PRM", new BigDecimal(7));put("RGN", new BigDecimal(5));}},aggregate); 269 } 270 271 @SuppressWarnings("serial") 272 @Test 273 /** 274 * Runs on every day on the interval: [16:00, 24:00) 275 * Max Gap: 15 minutes 276 * Min Hours: 4 277 * 278 * Added some extra time blocks that are not in the shift interval, but 279 * close to the time blocks that are. 280 * 281 * @throws Exception 282 */ 283 public void testProcessShiftSimpleNoisyCase() throws Exception { 284 // Create the Rule 285 boolean[] dayArray = {true, true, true, true, true, true, true}; 286 // Matches HR Job ID #1 (job # 30) 287 Long jobNumber = 30L; 288 Long workArea = 0L; 289 this.createShiftDifferentialRule( 290 "BWS-CAL", 291 "REG", 292 "PRM", 293 "SD1", 294 "SD1", 295 "SD1", 296 (new DateTime(2010, 3, 29, 16, 0, 0, 0, TKUtils.getSystemDateTimeZone())), 297 (new DateTime(2010, 3, 30, 0, 0, 0, 0, TKUtils.getSystemDateTimeZone())), 298 new BigDecimal(4), // minHours 299 new BigDecimal("15"), // maxGap 300 dayArray); 301 302 // Create Time Blocks (2 days, 2 blocks on each day, 15 minute gap between blocks, 4 hours total each. 303 DateTime start = new DateTime(2010, 3, 29, 14, 0, 0, 0, TKUtils.getSystemDateTimeZone()); 304 List<TimeBlock> blocks = new ArrayList<TimeBlock>(); 305 CalendarEntry payCalendarEntry = HrServiceLocator.getCalendarEntryService().getCurrentCalendarDates("admin", start); 306 blocks.addAll(TkTestUtils.createUniformTimeBlocks(start, 2, new BigDecimal("4"), "RGN", jobNumber, workArea)); 307 blocks.addAll(TkTestUtils.createUniformTimeBlocks(start.plusHours(4).plusMinutes(15), 2, new BigDecimal("2"), "RGN", jobNumber, workArea)); 308 blocks.addAll(TkTestUtils.createUniformTimeBlocks(new DateTime(2010, 3, 29, 12, 58, 0, 0, TKUtils.getSystemDateTimeZone()), 2, new BigDecimal(1), "RGN", jobNumber, workArea)); 309 TkTimeBlockAggregate aggregate = new TkTimeBlockAggregate(blocks, payCalendarEntry); 310 311 // Verify pre-Rule Run 312 TkTestUtils.verifyAggregateHourSums("Pre-Check", new HashMap<String,BigDecimal>() {{put("PRM", BigDecimal.ZERO);put("RGN", new BigDecimal(14));}},aggregate,2); 313 314 // Run Rule 315 TimesheetDocument tdoc = TkTestUtils.populateBlankTimesheetDocument(start, "admin"); 316 tdoc.setTimeBlocks(blocks); 317 TkServiceLocator.getShiftDifferentialRuleService().processShiftDifferentialRules(tdoc, aggregate); 318 319 // Verify post-Rule Run 320 TkTestUtils.verifyAggregateHourSums("Post Rules Check", new HashMap<String,BigDecimal>() {{put("PRM", new BigDecimal(8));put("RGN", new BigDecimal(14));}},aggregate,2); 321 } 322 323 @SuppressWarnings("serial") 324 @Test 325 /** 326 * Runs on every day on the interval: [16:00, 24:00) 327 * Max Gap: 15 minutes 328 * Min Hours: 4 329 * 330 * @throws Exception 331 */ 332 public void testProcessShiftSimpleCase() throws Exception { 333 // Create the Rule 334 boolean[] dayArray = {true, true, true, true, true, true, true}; 335 // Matches HR Job ID #1 (job # 30) 336 Long jobNumber = 30L; 337 Long workArea = 0L; 338 this.createShiftDifferentialRule( 339 "BWS-CAL", 340 "REG", 341 "PRM", 342 "SD1", 343 "SD1", 344 "SD1", 345 (new DateTime(2010, 3, 29, 16, 0, 0, 0, TKUtils.getSystemDateTimeZone())), 346 (new DateTime(2010, 3, 30, 0, 0, 0, 0, TKUtils.getSystemDateTimeZone())), 347 new BigDecimal(4), // minHours 348 new BigDecimal("15"), // maxGap 349 dayArray); 350 351 // Create Time Blocks (2 days, 2 blocks on each day, 15 minute gap between blocks, 4 hours total each. 352 DateTime start = new DateTime(2010, 3, 29, 14, 0, 0, 0, TKUtils.getSystemDateTimeZone()); 353 List<TimeBlock> blocks = new ArrayList<TimeBlock>(); 354 CalendarEntry payCalendarEntry = HrServiceLocator.getCalendarEntryService().getCurrentCalendarDates("admin", start); 355 blocks.addAll(TkTestUtils.createUniformTimeBlocks(start, 2, new BigDecimal("4"), "REG", jobNumber, workArea)); 356 blocks.addAll(TkTestUtils.createUniformTimeBlocks(start.plusHours(4).plusMinutes(15), 2, new BigDecimal("2"), "REG", jobNumber, workArea)); 357 TkTimeBlockAggregate aggregate = new TkTimeBlockAggregate(blocks, payCalendarEntry); 358 359 // Verify pre-Rule Run 360 TkTestUtils.verifyAggregateHourSums("Pre-Check", new HashMap<String,BigDecimal>() {{put("PRM", BigDecimal.ZERO);put("REG", new BigDecimal(12));}},aggregate,2); 361 362 // Run Rule 363 TimesheetDocument tdoc = TkTestUtils.populateBlankTimesheetDocument(start, "admin"); 364 tdoc.setTimeBlocks(blocks); 365 TkServiceLocator.getShiftDifferentialRuleService().processShiftDifferentialRules(tdoc, aggregate); 366 367 // Verify post-Rule Run 368 TkTestUtils.verifyAggregateHourSums("Post Rules Check", new HashMap<String,BigDecimal>() {{put("PRM", new BigDecimal(8));put("REG", new BigDecimal(12));}},aggregate,2); 369 } 370 371 /** 372 * Stores the Shift Differential Rule in the database for testing. 373 * 374 * dayBooleans[] is a 7 element array of booleans, [0, 6] is [sun, sat] 375 */ 376 private void createShiftDifferentialRule(String pyCalendarGroup, String fromEarnGroup, String premiumEarnCode, String location, String payGrade, String hrSalGroup, DateTime startTime, DateTime endTime, BigDecimal minHours, BigDecimal maxGap, boolean dayBooleans[]) { 377 Assert.assertTrue("Wrong number of day booleans", dayBooleans.length == 7); 378 379 ShiftDifferentialRuleService service = TkServiceLocator.getShiftDifferentialRuleService(); 380 ShiftDifferentialRule sdr = new ShiftDifferentialRule(); 381 382 sdr.setBeginTime(new Time(startTime.getMillis())); 383 sdr.setEndTime(new Time(endTime.getMillis())); 384 sdr.setMinHours(minHours); 385 sdr.setMaxGap(maxGap); 386 sdr.setActive(true); 387 sdr.setUserPrincipalId(USER_PRINCIPAL_ID); 388 sdr.setEffectiveLocalDate(JAN_AS_OF_DATE.toLocalDate()); 389 sdr.setLocation(location); 390 sdr.setPayGrade(payGrade); 391 sdr.setHrSalGroup(hrSalGroup); 392 sdr.setFromEarnGroup(fromEarnGroup); 393 sdr.setPyCalendarGroup(pyCalendarGroup); 394 sdr.setEarnCode(premiumEarnCode); 395 396 for (int i=0; i<dayBooleans.length; i++) { 397 switch(i) { 398 case 0: 399 sdr.setSunday(dayBooleans[i]); 400 break; 401 case 1: 402 sdr.setMonday(dayBooleans[i]); 403 break; 404 case 2: 405 sdr.setTuesday(dayBooleans[i]); 406 break; 407 case 3: 408 sdr.setWednesday(dayBooleans[i]); 409 break; 410 case 4: 411 sdr.setThursday(dayBooleans[i]); 412 break; 413 case 5: 414 sdr.setFriday(dayBooleans[i]); 415 break; 416 case 6: 417 sdr.setSaturday(dayBooleans[i]); 418 break; 419 } 420 } 421 422 service.saveOrUpdate(sdr); 423 424 ShiftDifferentialRule sdrBack = service.getShiftDifferentialRule(sdr.getTkShiftDiffRuleId()); 425 426 DateTimeZone tz = HrServiceLocator.getTimezoneService().getUserTimezoneWithFallback(); 427 LocalTime orig_start = new LocalTime(sdr.getBeginTime(), tz); 428 LocalTime orig_end = new LocalTime(sdr.getEndTime(), tz); 429 430 LocalTime stored_start = new LocalTime(sdrBack.getBeginTime(), tz); 431 LocalTime stored_end = new LocalTime(sdrBack.getEndTime(), tz); 432 433 Assert.assertTrue("Start times not equal.", orig_start.equals(stored_start)); 434 Assert.assertTrue("End times not equal.", orig_end.equals(stored_end)); 435 } 436 437 438 @Ignore 439 @Test 440 /** 441 * Tests WorkSchedules impact on Shift Differential Rule: Simple Case 442 * 443 * Create a timeblock on two days, one day has normal REG shift eligible 444 * hours, one day has HOL time. 445 * 446 * Modified version of the simple case, SDR from 12:00 to 17:00, every day, 447 * must have at least 4 hours with a maximum 15 minute gap. 448 * 449 */ 450 public void simpleCaseWithWorkSchedule() throws Exception { 451 // Create the Rule 452 boolean[] dayArray = {true, true, true, true, true, true, true}; 453 // Matches HR Job ID #1 (job # 30) 454 Long jobNumber = 30L; 455 Long workArea = 0L; 456 this.createShiftDifferentialRule( 457 "BWS-CAL", 458 "REG", 459 "PRM", 460 "SD1", 461 "SD1", 462 "SD1", 463 (new DateTime(2010, 3, 29, 12, 0, 0, 0, TKUtils.getSystemDateTimeZone())), 464 (new DateTime(2010, 3, 29, 17, 0, 0, 0, TKUtils.getSystemDateTimeZone())), 465 new BigDecimal(4), // minHours 466 new BigDecimal("0.25"), // maxGap 467 dayArray); 468 469 // Create Time Blocks (2 days, 2 blocks on each day, 15 minute gap between blocks, 4 hours total each. 470 DateTime start = new DateTime(2010, 3, 29, 12, 0, 0, 0, TKUtils.getSystemDateTimeZone()); 471 DateTime holtime = new DateTime(2010, 3, 30, 0, 0, 0, 0, TKUtils.getSystemDateTimeZone()); 472 List<TimeBlock> blocks = new ArrayList<TimeBlock>(); 473 CalendarEntry payCalendarEntry = HrServiceLocator.getCalendarEntryService().getCurrentCalendarDates("admin", start); 474 blocks.addAll(TkTestUtils.createUniformTimeBlocks(start, 1, new BigDecimal("4"), "REG", jobNumber, workArea)); 475 blocks.addAll(TkTestUtils.createUniformTimeBlocks(holtime, 1, new BigDecimal("4"), "HOL", jobNumber, workArea)); 476 477 TkTimeBlockAggregate aggregate = new TkTimeBlockAggregate(blocks, payCalendarEntry); 478 479 // Verify pre-Rule Run 480 TkTestUtils.verifyAggregateHourSums("Pre-Check", new HashMap<String,BigDecimal>() {{put("PRM", BigDecimal.ZERO);put("REG", new BigDecimal(4));put("HOL", new BigDecimal(4));}},aggregate,2); 481 482 // Run Rule 483 TimesheetDocument tdoc = TkTestUtils.populateBlankTimesheetDocument(start, "admin"); 484 tdoc.setTimeBlocks(blocks); 485 TkServiceLocator.getShiftDifferentialRuleService().processShiftDifferentialRules(tdoc, aggregate); 486 487 // Verify post-Rule Run 488 TkTestUtils.verifyAggregateHourSums("Post Rules Check", new HashMap<String,BigDecimal>() {{put("PRM", new BigDecimal(8));put("REG", new BigDecimal(4));}},aggregate,2); 489 490 } 491 492 }