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