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