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