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    }