View Javadoc

1   /**
2    * Copyright 2004-2014 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.hr.time.shiftdiff.rule;
17  
18  import java.math.BigDecimal;
19  import java.sql.Time;
20  import java.util.ArrayList;
21  import java.util.HashMap;
22  import java.util.List;
23  
24  import org.joda.time.DateTime;
25  import org.joda.time.DateTimeZone;
26  import org.joda.time.LocalTime;
27  import org.junit.Assert;
28  import org.junit.Ignore;
29  import org.junit.Test;
30  import org.kuali.hr.KPMEWebTestCase;
31  import org.kuali.kpme.core.FunctionalTest;
32  import org.kuali.kpme.core.assignment.Assignment;
33  import org.kuali.kpme.core.assignment.AssignmentDescriptionKey;
34  import org.kuali.kpme.core.calendar.entry.CalendarEntry;
35  import org.kuali.kpme.core.service.HrServiceLocator;
36  import org.kuali.kpme.core.util.TKUtils;
37  import org.kuali.kpme.tklm.time.rules.shiftdifferential.ShiftDifferentialRule;
38  import org.kuali.kpme.tklm.time.rules.shiftdifferential.service.ShiftDifferentialRuleService;
39  import org.kuali.kpme.tklm.time.service.TkServiceLocator;
40  import org.kuali.kpme.tklm.time.timeblock.TimeBlock;
41  import org.kuali.kpme.tklm.time.timesheet.TimesheetDocument;
42  import org.kuali.kpme.tklm.time.util.TkTimeBlockAggregate;
43  import org.kuali.kpme.tklm.utils.TkTestUtils;
44  
45  /**
46   *
47   * @author djunk
48   *
49   */
50  @FunctionalTest
51  public class ShiftDifferentialRuleServiceProcessTest extends KPMEWebTestCase {
52  
53  
54  	public static final String USER_PRINCIPAL_ID = "admin";
55  	private DateTime JAN_AS_OF_DATE = new DateTime(2010, 1, 1, 0, 0, 0, 0, TKUtils.getSystemDateTimeZone());
56  
57  
58  	/**
59  	 * Test with boundary carryover and overlapping rules.
60  	 *
61  	 * Rule 1:
62  	 *
63  	 * Runs on Tu, Wed, Th on the interval: [22:00, 4:00)
64  	 * Max Gap: 15 minutes
65  	 * Min Hours: 3
66  	 *
67  	 * Rule 2:
68  	 *
69  	 * Runs on Tu, Th on the interval: [23:00, 2:00)
70  	 * Max Gap: 2 hours
71  	 * Min Hours: 3
72  	 *
73  	 * Rule 3:
74  	 *
75  	 * Runs on W, Th on the interval: [5:00, 12:00)
76  	 * Max Gap: 15 minutes
77  	 * Min Hours: 7 hours
78  	 *
79  	 * Rule 4:
80  	 *
81  	 * Runs on W on the interval: [5:00, 12:00)
82  	 * Max Gap: 15 minutes
83  	 * Min Hours: 5
84  	 *
85  	 *
86  	 * |--------------+----+------------+------------|
87  	 * | Tu : 8/31/10 | XX | W : 9/1/10 | Th: 9/2/10 |
88  	 * |--------------+----+------------+------------|
89  	 * | 9:45p - 11:45| XX | Mid - 5a   | 5p - 11p   |
90  	 * |              | XX | 6a - Noon  |            |
91  	 * |--------------+----+------------+------------|
92       *
93       *
94       * Aug 31: 2h  : 21:45 - 23:45 (Tue) **
95       *                           [1: 5h 45m]  // [2: 2h 45m] - Not qualifying, min hours must be 3.
96       * Sep  1: 5h  : 00:00 - 05:00 (Wed) **
97       * Sep  1: 6h  : 06:00 - 12:00 (Wed) [4: 6h]
98       *
99       * 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("15.00"), // 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.00"), // 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("15.00"), // 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 }