View Javadoc

1   /**
2    * Copyright 2004-2013 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.service;
17  
18  import java.math.BigDecimal;
19  import java.sql.Date;
20  import java.sql.Time;
21  import java.util.ArrayList;
22  import java.util.HashMap;
23  import java.util.List;
24  
25  import org.joda.time.DateTime;
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.test.KPMETestCase;
31  import org.kuali.hr.time.assignment.Assignment;
32  import org.kuali.hr.time.assignment.AssignmentDescriptionKey;
33  import org.kuali.hr.time.calendar.CalendarEntries;
34  import org.kuali.hr.time.service.base.TkServiceLocator;
35  import org.kuali.hr.time.shiftdiff.rule.ShiftDifferentialRule;
36  import org.kuali.hr.time.test.TkTestUtils;
37  import org.kuali.hr.time.timeblock.TimeBlock;
38  import org.kuali.hr.time.timesheet.TimesheetDocument;
39  import org.kuali.hr.time.util.TKUtils;
40  import org.kuali.hr.time.util.TkConstants;
41  import org.kuali.hr.time.util.TkTimeBlockAggregate;
42  
43  /**
44   *
45   * @author djunk
46   *
47   */
48  public class ShiftDifferentialRuleServiceProcessTest extends KPMETestCase {
49  
50  
51  	public static final String USER_PRINCIPAL_ID = "admin";
52  	private Date JAN_AS_OF_DATE = new Date((new DateTime(2010, 1, 1, 0, 0, 0, 0, TKUtils.getSystemDateTimeZone())).getMillis());
53  
54  
55  	/**
56  	 * Test with boundary carryover and overlapping rules.
57  	 *
58  	 * Rule 1:
59  	 *
60  	 * Runs on Tu, Wed, Th on the interval: [22:00, 4:00)
61  	 * Max Gap: 15 minutes
62  	 * Min Hours: 3
63  	 *
64  	 * Rule 2:
65  	 *
66  	 * Runs on Tu, Th on the interval: [23:00, 2:00)
67  	 * Max Gap: 2 hours
68  	 * Min Hours: 3
69  	 *
70  	 * Rule 3:
71  	 *
72  	 * Runs on W, Th on the interval: [5:00, 12:00)
73  	 * Max Gap: 15 minutes
74  	 * Min Hours: 7 hours
75  	 *
76  	 * Rule 4:
77  	 *
78  	 * Runs on W on the interval: [5:00, 12:00)
79  	 * Max Gap: 15 minutes
80  	 * Min Hours: 5
81  	 *
82  	 *
83  	 * |--------------+----+------------+------------|
84  	 * | Tu : 8/31/10 | XX | W : 9/1/10 | Th: 9/2/10 |
85  	 * |--------------+----+------------+------------|
86  	 * | 9:45p - 11:45| XX | Mid - 5a   | 5p - 11p   |
87  	 * |              | XX | 6a - Noon  |            |
88  	 * |--------------+----+------------+------------|
89       *
90       *
91       * Aug 31: 2h  : 21:45 - 23:45 (Tue) **
92       *                           [1: 5h 45m]  // [2: 2h 45m] - Not qualifying, min hours must be 3.
93       * Sep  1: 5h  : 00:00 - 05:00 (Wed) **
94       * Sep  1: 6h  : 06:00 - 12:00 (Wed) [4: 6h]
95       *
96       * Sep  1: 2h  : 22:00 - 24:00 (Wed)
97       * Sep  2: 1h  : 00:00 - 01:00 (Thu) [1: 3h]
98       *
99       * 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 }