1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.hr.time.shiftdiff.rule.service;
17
18 import org.apache.log4j.Logger;
19 import org.joda.time.*;
20 import org.kuali.hr.job.Job;
21 import org.kuali.hr.time.calendar.CalendarEntries;
22 import org.kuali.hr.time.principal.PrincipalHRAttributes;
23 import org.kuali.hr.time.service.base.TkServiceLocator;
24 import org.kuali.hr.time.shiftdiff.rule.ShiftDifferentialRule;
25 import org.kuali.hr.time.shiftdiff.rule.dao.ShiftDifferentialRuleDao;
26 import org.kuali.hr.time.timeblock.TimeBlock;
27 import org.kuali.hr.time.timeblock.TimeHourDetail;
28 import org.kuali.hr.time.timesheet.TimesheetDocument;
29 import org.kuali.hr.time.util.TKUtils;
30 import org.kuali.hr.time.util.TkConstants;
31 import org.kuali.hr.time.util.TkTimeBlockAggregate;
32 import org.kuali.hr.time.workflow.TimesheetDocumentHeader;
33
34 import java.math.BigDecimal;
35 import java.sql.Date;
36 import java.util.*;
37
38
39 public class ShiftDifferentialRuleServiceImpl implements ShiftDifferentialRuleService {
40
41 @SuppressWarnings("unused")
42 private static final Logger LOG = Logger.getLogger(ShiftDifferentialRuleServiceImpl.class);
43
44
45
46
47 private ShiftDifferentialRuleDao shiftDifferentialRuleDao = null;
48
49 private Map<Long,List<ShiftDifferentialRule>> getJobNumberToShiftRuleMap(TimesheetDocument timesheetDocument) {
50 Map<Long,List<ShiftDifferentialRule>> jobNumberToShifts = new HashMap<Long,List<ShiftDifferentialRule>>();
51 PrincipalHRAttributes principalCal = TkServiceLocator.getPrincipalHRAttributeService().getPrincipalCalendar(timesheetDocument.getPrincipalId(),timesheetDocument.getCalendarEntry().getEndPeriodDate());
52
53 for (Job job : timesheetDocument.getJobs()) {
54 List<ShiftDifferentialRule> shiftDifferentialRules = getShiftDifferentalRules(job.getLocation(),job.getHrSalGroup(),job.getPayGrade(),principalCal.getPayCalendar(),
55 TKUtils.getTimelessDate(timesheetDocument.getCalendarEntry().getBeginPeriodDateTime()));
56 if (shiftDifferentialRules.size() > 0)
57 jobNumberToShifts.put(job.getJobNumber(), shiftDifferentialRules);
58 }
59
60 return jobNumberToShifts;
61 }
62
63 private Map<Long,List<TimeBlock>> getPreviousPayPeriodLastDayJobToTimeBlockMap(TimesheetDocument timesheetDocument, Map<Long,List<ShiftDifferentialRule>> jobNumberToShifts) {
64 Map<Long, List<TimeBlock>> jobNumberToTimeBlocksPreviousDay = null;
65
66
67
68 List<TimeBlock> prevBlocks = TkServiceLocator.getTimesheetService().getPrevDocumentTimeBlocks(timesheetDocument.getPrincipalId(), timesheetDocument.getDocumentHeader().getBeginDate());
69 if (prevBlocks.size() > 0) {
70 TimesheetDocumentHeader prevTdh = TkServiceLocator.getTimesheetDocumentHeaderService().getPreviousDocumentHeader(timesheetDocument.getPrincipalId(), timesheetDocument.getDocumentHeader().getBeginDate());
71 if (prevTdh != null) {
72 CalendarEntries prevPayCalendarEntry = TkServiceLocator.getCalendarService().getCalendarDatesByPayEndDate(timesheetDocument.getPrincipalId(), prevTdh.getEndDate(), TkConstants.PAY_CALENDAR_TYPE);
73 TkTimeBlockAggregate prevTimeAggregate = new TkTimeBlockAggregate(prevBlocks, prevPayCalendarEntry, prevPayCalendarEntry.getCalendarObj(), true);
74 List<List<TimeBlock>> dayBlocks = prevTimeAggregate.getDayTimeBlockList();
75 List<TimeBlock> previousPeriodLastDayBlocks = dayBlocks.get(dayBlocks.size() - 1);
76
77 if (previousPeriodLastDayBlocks.size() > 0) {
78 jobNumberToTimeBlocksPreviousDay = new HashMap<Long, List<TimeBlock>>();
79
80 for (TimeBlock block : previousPeriodLastDayBlocks) {
81
82
83 Long jobNumber = block.getJobNumber();
84 if (jobNumberToShifts.containsKey(jobNumber)) {
85
86 List<TimeBlock> jblist = jobNumberToTimeBlocksPreviousDay.get(jobNumber);
87 if (jblist == null) {
88 jblist = new ArrayList<TimeBlock>();
89 jobNumberToTimeBlocksPreviousDay.put(jobNumber, jblist);
90 }
91 jblist.add(block);
92 }
93 }
94 }
95 }
96 }
97
98 return jobNumberToTimeBlocksPreviousDay;
99 }
100
101 private boolean timeBlockHasEarnCode(Set<String> earnCodes, TimeBlock block) {
102 boolean present = false;
103
104 if (block != null && earnCodes != null)
105 present = earnCodes.contains(block.getEarnCode());
106
107 return present;
108 }
109
110
111
112
113
114
115
116
117
118
119 private BigDecimal negativeTimeHourDetailSum(TimeBlock block) {
120 BigDecimal sum = BigDecimal.ZERO;
121
122 if (block != null) {
123 List<TimeHourDetail> details = block.getTimeHourDetails();
124 for (TimeHourDetail detail : details) {
125 if (detail.getEarnCode().equals(TkConstants.LUNCH_EARN_CODE)) {
126 sum = sum.add(detail.getHours());
127 }
128 }
129 }
130
131 return sum;
132 }
133
134 @Override
135 public void processShiftDifferentialRules(TimesheetDocument timesheetDocument, TkTimeBlockAggregate aggregate) {
136 DateTimeZone zone = TkServiceLocator.getTimezoneService().getUserTimezoneWithFallback();
137 List<List<TimeBlock>> blockDays = aggregate.getDayTimeBlockList();
138 DateTime periodStartDateTime = timesheetDocument.getCalendarEntry().getBeginLocalDateTime().toDateTime(zone);
139 Map<Long,List<ShiftDifferentialRule>> jobNumberToShifts = getJobNumberToShiftRuleMap(timesheetDocument);
140
141
142
143 if (jobNumberToShifts.isEmpty()) {
144 return;
145 }
146
147
148
149
150
151
152 boolean previousPayPeriodPrevDay = true;
153 Map<Long, List<TimeBlock>> jobNumberToTimeBlocksPreviousDay =
154 getPreviousPayPeriodLastDayJobToTimeBlockMap(timesheetDocument, jobNumberToShifts);
155
156
157
158
159 for (int pos = 0; pos < blockDays.size(); pos++) {
160 List<TimeBlock> blocks = blockDays.get(pos);
161 if (blocks.isEmpty())
162 continue;
163
164 DateTime currentDay = periodStartDateTime.plusDays(pos);
165 Interval virtualDay = new Interval(currentDay, currentDay.plusHours(24));
166
167
168
169
170
171
172
173 Map<Long, List<TimeBlock>> jobNumberToTimeBlocks = new HashMap<Long,List<TimeBlock>>();
174 for (TimeBlock block : blocks) {
175 Long jobNumber = block.getJobNumber();
176 if (jobNumberToShifts.containsKey(jobNumber)) {
177 List<TimeBlock> jblist = jobNumberToTimeBlocks.get(jobNumber);
178 if (jblist == null) {
179 jblist = new ArrayList<TimeBlock>();
180 jobNumberToTimeBlocks.put(jobNumber, jblist);
181 }
182 jblist.add(block);
183 }
184 }
185
186
187
188
189
190
191
192
193
194 for (Long jobNumber: jobNumberToShifts.keySet()) {
195 List<ShiftDifferentialRule> shiftDifferentialRules = jobNumberToShifts.get(jobNumber);
196
197 List<TimeBlock> ruleTimeBlocksPrev = null;
198 List<TimeBlock> ruleTimeBlocksCurr = jobNumberToTimeBlocks.get(jobNumber);
199 if (ruleTimeBlocksCurr != null && ruleTimeBlocksCurr.size() > 0) {
200 if (jobNumberToTimeBlocksPreviousDay != null)
201 ruleTimeBlocksPrev = jobNumberToTimeBlocksPreviousDay.get(jobNumber);
202 if (ruleTimeBlocksPrev != null && ruleTimeBlocksPrev.size() > 0)
203 this.sortTimeBlocksInverse(ruleTimeBlocksPrev);
204 this.sortTimeBlocksNatural(ruleTimeBlocksCurr);
205 } else {
206
207
208
209 continue;
210 }
211
212 for (ShiftDifferentialRule rule : shiftDifferentialRules) {
213 Set<String> fromEarnGroup = TkServiceLocator.getEarnCodeGroupService().getEarnCodeListForEarnCodeGroup(rule.getFromEarnGroup(), TKUtils.getTimelessDate(timesheetDocument.getCalendarEntry().getBeginPeriodDateTime()));
214
215 LocalTime ruleStart = new LocalTime(rule.getBeginTime(), zone);
216 LocalTime ruleEnd = new LocalTime(rule.getEndTime(), zone);
217
218
219 DateTime shiftEnd = ruleEnd.toDateTime(currentDay);
220 DateTime shiftStart = ruleStart.toDateTime(currentDay);
221
222 if (shiftEnd.isBefore(shiftStart) || shiftEnd.isEqual(shiftStart)) {
223 shiftEnd = shiftEnd.plusDays(1);
224 }
225 Interval shiftInterval = new Interval(shiftStart, shiftEnd);
226
227
228 BigDecimal hoursBeforeVirtualDay = BigDecimal.ZERO;
229
230
231
232 TimeBlock firstBlockOfCurrentDay = null;
233 for (TimeBlock b : ruleTimeBlocksCurr) {
234 if (timeBlockHasEarnCode(fromEarnGroup, b)) {
235 firstBlockOfCurrentDay = b;
236 break;
237 }
238 }
239
240
241 Interval previousDayShiftInterval = new Interval(shiftStart.minusDays(1), shiftEnd.minusDays(1));
242
243
244 Interval evalInterval = null;
245 if (ruleTimeBlocksPrev != null && ruleTimeBlocksPrev.size() > 0 && dayIsRuleActive(currentDay.minusDays(1), rule)) {
246
247
248 if (shiftEnd.isAfter(virtualDay.getEnd())) {
249
250 TimeBlock firstBlockOfPreviousDay = null;
251 for (TimeBlock b : ruleTimeBlocksPrev) {
252 if (timeBlockHasEarnCode(fromEarnGroup, b)) {
253 firstBlockOfPreviousDay = b;
254 break;
255 }
256 }
257
258
259
260
261 if ( (firstBlockOfPreviousDay != null) && (firstBlockOfCurrentDay != null)) {
262 Interval previousBlockInterval = new Interval(new DateTime(firstBlockOfPreviousDay.getEndTimestamp(), zone), new DateTime(firstBlockOfCurrentDay.getBeginTimestamp(), zone));
263 Duration blockGapDuration = previousBlockInterval.toDuration();
264 BigDecimal bgdHours = TKUtils.convertMillisToHours(blockGapDuration.getMillis());
265
266 if (rule.getMaxGap().compareTo(BigDecimal.ZERO) == 0 || bgdHours.compareTo(rule.getMaxGap()) <= 0) {
267
268
269
270
271 for (int i=0; i<ruleTimeBlocksPrev.size(); i++) {
272 TimeBlock b = ruleTimeBlocksPrev.get(i);
273 if (timeBlockHasEarnCode(fromEarnGroup, b)) {
274 Interval blockInterval = new Interval(new DateTime(b.getBeginTimestamp(), zone), new DateTime(b.getEndTimestamp(), zone));
275
276
277 if (previousBlockInterval != null) {
278 blockGapDuration = new Duration(new DateTime(b.getEndTimestamp(), zone), previousBlockInterval.getStart());
279 bgdHours = TKUtils.convertMillisToHours(blockGapDuration.getMillis());
280 }
281
282
283 if (rule.getMaxGap().compareTo(BigDecimal.ZERO) == 0 || bgdHours.compareTo(rule.getMaxGap()) <= 0) {
284
285 if (blockInterval.overlaps(previousDayShiftInterval)) {
286 BigDecimal hrs = TKUtils.convertMillisToHours(blockInterval.overlap(previousDayShiftInterval).toDurationMillis());
287 hoursBeforeVirtualDay = hoursBeforeVirtualDay.add(hrs);
288 }
289
290 } else {
291
292 break;
293 }
294
295 previousBlockInterval = blockInterval;
296
297 }
298 }
299 } else {
300
301 }
302 }
303 }
304 }
305
306 BigDecimal hoursToApply = BigDecimal.ZERO;
307 BigDecimal hoursToApplyPrevious = BigDecimal.ZERO;
308
309
310
311 if (hoursBeforeVirtualDay.compareTo(rule.getMinHours()) <= 0) {
312
313 hoursToApplyPrevious = hoursBeforeVirtualDay;
314 }
315
316
317
318
319 TimeBlock previous = null;
320 List<TimeBlock> accumulatedBlocks = new ArrayList<TimeBlock>();
321 List<Interval> accumulatedBlockIntervals = new ArrayList<Interval>();
322
323 long accumulatedMillis = TKUtils.convertHoursToMillis(hoursBeforeVirtualDay);
324
325 boolean previousDayOnly = false;
326 if (!dayIsRuleActive(currentDay, rule)) {
327 if (dayIsRuleActive(currentDay.minusDays(1), rule)) {
328 previousDayOnly = true;
329 } else {
330
331 continue;
332 }
333
334 }
335
336
337
338
339
340
341
342
343
344
345
346
347 List<TimeBlock> previousBlocksFiltered = (previousPayPeriodPrevDay) ? null : filterBlocksByApplicableEarnGroup(fromEarnGroup, ruleTimeBlocksPrev);
348
349 for (TimeBlock current : ruleTimeBlocksCurr) {
350 if (!timeBlockHasEarnCode(fromEarnGroup, current)) {
351
352 continue;
353 }
354
355 Interval blockInterval = new Interval(new DateTime(current.getBeginTimestamp(), zone), new DateTime(current.getEndTimestamp(), zone));
356
357
358
359
360 if (previousDayShiftInterval.overlaps(shiftInterval))
361 throw new RuntimeException("Interval of greater than 24 hours created in the rules processing.");
362
363
364
365
366
367 Interval overlap = previousDayShiftInterval.overlap(blockInterval);
368 evalInterval = previousDayShiftInterval;
369 if (overlap == null) {
370 if (hoursToApplyPrevious.compareTo(BigDecimal.ZERO) > 0) {
371
372
373
374
375 BigDecimal accumHours = TKUtils.convertMillisToHours(accumulatedMillis);
376 this.applyAccumulatedWrapper(accumHours, evalInterval, accumulatedBlockIntervals, accumulatedBlocks, previousBlocksFiltered, hoursToApplyPrevious, hoursToApply, rule);
377 accumulatedMillis = 0L;
378 hoursToApply = BigDecimal.ZERO;
379 hoursToApplyPrevious = BigDecimal.ZERO;
380 }
381
382
383
384
385
386 if (previousDayOnly) {
387 continue;
388 }
389
390 overlap = shiftInterval.overlap(blockInterval);
391 evalInterval = shiftInterval;
392 }
393
394
395
396 if (overlap != null) {
397
398 if (previous != null) {
399
400 if (rule.getMaxGap().compareTo(BigDecimal.ZERO) != 0 && exceedsMaxGap(previous, current, rule.getMaxGap())) {
401 BigDecimal accumHours = TKUtils.convertMillisToHours(accumulatedMillis);
402 this.applyAccumulatedWrapper(accumHours, evalInterval, accumulatedBlockIntervals, accumulatedBlocks, previousBlocksFiltered, hoursToApplyPrevious, hoursToApply, rule);
403 accumulatedMillis = 0L;
404 hoursToApply = BigDecimal.ZERO;
405 hoursToApplyPrevious = BigDecimal.ZERO;
406 } else {
407 long millis = overlap.toDurationMillis();
408 accumulatedMillis += millis;
409 hoursToApply = hoursToApply.add(TKUtils.convertMillisToHours(millis));
410 }
411 } else {
412
413 long millis = overlap.toDurationMillis();
414 accumulatedMillis += millis;
415 hoursToApply = hoursToApply.add(TKUtils.convertMillisToHours(millis));
416 }
417 accumulatedBlocks.add(current);
418 accumulatedBlockIntervals.add(blockInterval);
419 previous = current;
420 } else {
421
422 if (previous != null) {
423 BigDecimal accumHours = TKUtils.convertMillisToHours(accumulatedMillis);
424 this.applyAccumulatedWrapper(accumHours, evalInterval, accumulatedBlockIntervals, accumulatedBlocks, previousBlocksFiltered, hoursToApplyPrevious, hoursToApply, rule);
425 accumulatedMillis = 0L;
426 hoursToApply = BigDecimal.ZERO;
427 hoursToApplyPrevious = BigDecimal.ZERO;
428 }
429 }
430
431 }
432
433
434
435 BigDecimal accumHours = TKUtils.convertMillisToHours(accumulatedMillis);
436 this.applyAccumulatedWrapper(accumHours, evalInterval, accumulatedBlockIntervals, accumulatedBlocks, previousBlocksFiltered, hoursToApplyPrevious, hoursToApply, rule);
437 }
438 }
439
440 jobNumberToTimeBlocksPreviousDay = jobNumberToTimeBlocks;
441 previousPayPeriodPrevDay = false;
442 }
443
444 }
445
446 @Override
447 public List<ShiftDifferentialRule> getShiftDifferentialRules(String location, String hrSalGroup, String payGrade, Date fromEffdt, Date toEffdt, String active, String showHist) {
448 return shiftDifferentialRuleDao.getShiftDifferentialRules(location, hrSalGroup, payGrade, fromEffdt, toEffdt, active, showHist);
449 }
450
451 private List<TimeBlock> filterBlocksByApplicableEarnGroup(Set<String> fromEarnGroup, List<TimeBlock> blocks) {
452 List<TimeBlock> filtered;
453
454 if (blocks == null || blocks.size() == 0)
455 filtered = null;
456 else {
457 filtered = new ArrayList<TimeBlock>();
458 for (TimeBlock b : blocks) {
459 if (timeBlockHasEarnCode(fromEarnGroup, b))
460 filtered.add(b);
461 }
462 }
463
464 return filtered;
465 }
466
467 private void applyAccumulatedWrapper(BigDecimal accumHours,
468 Interval evalInterval,
469 List<Interval>accumulatedBlockIntervals,
470 List<TimeBlock>accumulatedBlocks,
471 List<TimeBlock> previousBlocks,
472 BigDecimal hoursToApplyPrevious,
473 BigDecimal hoursToApply,
474 ShiftDifferentialRule rule) {
475 if (accumHours.compareTo(rule.getMinHours()) >= 0) {
476 this.applyPremium(evalInterval, accumulatedBlockIntervals, accumulatedBlocks, previousBlocks, hoursToApplyPrevious, hoursToApply, rule.getEarnCode());
477 }
478 accumulatedBlocks.clear();
479 accumulatedBlockIntervals.clear();
480 }
481
482 private void sortTimeBlocksInverse(List<TimeBlock> blocks) {
483 Collections.sort(blocks, new Comparator<TimeBlock>() {
484 public int compare(TimeBlock tb1, TimeBlock tb2) {
485 if (tb1 != null && tb2 != null)
486 return -1 * tb1.getBeginTimestamp().compareTo(tb2.getBeginTimestamp());
487 return 0;
488 }
489 });
490 }
491
492 private void sortTimeBlocksNatural(List<TimeBlock> blocks) {
493 Collections.sort(blocks, new Comparator<TimeBlock>() {
494 public int compare(TimeBlock tb1, TimeBlock tb2) {
495 if (tb1 != null && tb2 != null)
496 return tb1.getBeginTimestamp().compareTo(tb2.getBeginTimestamp());
497 return 0;
498 }
499 });
500 }
501
502
503
504
505
506
507
508
509
510
511
512 void applyPremium(Interval shift, List<Interval> blockIntervals, List<TimeBlock> blocks, List<TimeBlock> previousBlocks, BigDecimal initialHours, BigDecimal hours, String earnCode) {
513 for (int i=0; i<blocks.size(); i++) {
514 TimeBlock b = blocks.get(i);
515
516
517 if (i == 0 && (initialHours.compareTo(BigDecimal.ZERO) > 0)) {
518
519
520 if (previousBlocks != null && previousBlocks.size() > 0 && previousBlocks.get(0).getDocumentId().equals(b.getDocumentId())) {
521 for (TimeBlock pb : previousBlocks) {
522 BigDecimal lunchSub = this.negativeTimeHourDetailSum(pb);
523 initialHours = BigDecimal.ZERO.max(initialHours.add(lunchSub));
524 if (initialHours.compareTo(BigDecimal.ZERO) <= 0)
525 break;
526
527
528 BigDecimal hoursToApply = initialHours.min(pb.getHours().add(lunchSub));
529 addPremiumTimeHourDetail(pb, hoursToApply, earnCode);
530 initialHours = initialHours.subtract(hoursToApply, TkConstants.MATH_CONTEXT);
531 if (initialHours.compareTo(BigDecimal.ZERO) <= 0)
532 break;
533 }
534 } else {
535 addPremiumTimeHourDetail(b, initialHours, earnCode);
536 }
537 }
538
539 BigDecimal lunchSub = this.negativeTimeHourDetailSum(b);
540 hours = BigDecimal.ZERO.max(hours.add(lunchSub));
541
542 if (hours.compareTo(BigDecimal.ZERO) > 0) {
543 Interval blockInterval = blockIntervals.get(i);
544 Interval overlapInterval = shift.overlap(blockInterval);
545 if (overlapInterval == null)
546 continue;
547
548 long overlap = overlapInterval.toDurationMillis();
549 BigDecimal hoursMax = TKUtils.convertMillisToHours(overlap);
550
551
552 BigDecimal hoursToApply = hours.min(hoursMax.add(lunchSub));
553
554 addPremiumTimeHourDetail(b, hoursToApply, earnCode);
555 hours = hours.subtract(hoursToApply, TkConstants.MATH_CONTEXT);
556 }
557 }
558 }
559
560 void addPremiumTimeHourDetail(TimeBlock block, BigDecimal hours, String earnCode) {
561 List<TimeHourDetail> details = block.getTimeHourDetails();
562 TimeHourDetail premium = new TimeHourDetail();
563 premium.setHours(hours);
564 premium.setEarnCode(earnCode);
565 premium.setTkTimeBlockId(block.getTkTimeBlockId());
566 details.add(premium);
567 }
568
569
570
571
572
573
574
575
576
577
578 boolean exceedsMaxGap(TimeBlock previous, TimeBlock current, BigDecimal maxGap) {
579 long difference = current.getBeginTimestamp().getTime() - previous.getEndTimestamp().getTime();
580 BigDecimal gapMinutes = TKUtils.convertMillisToMinutes(difference);
581
582 return (gapMinutes.compareTo(maxGap) > 0);
583 }
584
585 public void setShiftDifferentialRuleDao(ShiftDifferentialRuleDao shiftDifferentialRuleDao) {
586 this.shiftDifferentialRuleDao = shiftDifferentialRuleDao;
587 }
588
589 @Override
590 public ShiftDifferentialRule getShiftDifferentialRule(String tkShiftDifferentialRuleId) {
591 return this.shiftDifferentialRuleDao.findShiftDifferentialRule(tkShiftDifferentialRuleId);
592 }
593
594 @Override
595 public List<ShiftDifferentialRule> getShiftDifferentalRules(String location, String hrSalGroup, String payGrade, String pyCalendarGroup, Date asOfDate) {
596 List<ShiftDifferentialRule> sdrs = new ArrayList<ShiftDifferentialRule>();
597
598
599
600 sdrs.addAll(shiftDifferentialRuleDao.findShiftDifferentialRules(location, hrSalGroup, payGrade, pyCalendarGroup, asOfDate));
601
602
603 sdrs.addAll(shiftDifferentialRuleDao.findShiftDifferentialRules(location, hrSalGroup, "%", pyCalendarGroup, asOfDate));
604
605
606 sdrs.addAll(shiftDifferentialRuleDao.findShiftDifferentialRules(location, "%", payGrade, pyCalendarGroup, asOfDate));
607
608
609 sdrs.addAll(shiftDifferentialRuleDao.findShiftDifferentialRules(location, "%", "%", pyCalendarGroup, asOfDate));
610
611
612 sdrs.addAll(shiftDifferentialRuleDao.findShiftDifferentialRules("%", hrSalGroup, payGrade, pyCalendarGroup, asOfDate));
613
614
615 sdrs.addAll(shiftDifferentialRuleDao.findShiftDifferentialRules("%", hrSalGroup, "%", pyCalendarGroup, asOfDate));
616
617
618 sdrs.addAll(shiftDifferentialRuleDao.findShiftDifferentialRules("%", "%", payGrade, pyCalendarGroup, asOfDate));
619
620
621 sdrs.addAll(shiftDifferentialRuleDao.findShiftDifferentialRules("%", "%", "%", pyCalendarGroup, asOfDate));
622
623 if (sdrs == null)
624 sdrs = Collections.emptyList();
625
626 return sdrs;
627 }
628
629 private boolean dayIsRuleActive(DateTime currentDate, ShiftDifferentialRule sdr) {
630 boolean active = false;
631
632 switch (currentDate.getDayOfWeek()) {
633 case DateTimeConstants.MONDAY:
634 active = sdr.isMonday();
635 break;
636 case DateTimeConstants.TUESDAY:
637 active = sdr.isTuesday();
638 break;
639 case DateTimeConstants.WEDNESDAY:
640 active = sdr.isWednesday();
641 break;
642 case DateTimeConstants.THURSDAY:
643 active = sdr.isThursday();
644 break;
645 case DateTimeConstants.FRIDAY:
646 active = sdr.isFriday();
647 break;
648 case DateTimeConstants.SATURDAY:
649 active = sdr.isSaturday();
650 break;
651 case DateTimeConstants.SUNDAY:
652 active = sdr.isSunday();
653 break;
654 }
655
656 return active;
657 }
658
659 @Override
660 public void saveOrUpdate(List<ShiftDifferentialRule> shiftDifferentialRules) {
661 shiftDifferentialRuleDao.saveOrUpdate(shiftDifferentialRules);
662 }
663
664 @Override
665 public void saveOrUpdate(ShiftDifferentialRule shiftDifferentialRule) {
666 shiftDifferentialRuleDao.saveOrUpdate(shiftDifferentialRule);
667 }
668
669 }