1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.hr.lm.leaveSummary.service;
17
18 import org.apache.commons.collections.CollectionUtils;
19 import org.apache.commons.lang.StringUtils;
20 import org.apache.commons.lang.time.DateUtils;
21 import org.joda.time.DateMidnight;
22 import org.joda.time.DateTime;
23 import org.joda.time.Interval;
24 import org.joda.time.LocalDateTime;
25 import org.kuali.hr.lm.LMConstants;
26 import org.kuali.hr.lm.accrual.AccrualCategory;
27 import org.kuali.hr.lm.accrual.AccrualCategoryRule;
28 import org.kuali.hr.lm.employeeoverride.EmployeeOverride;
29 import org.kuali.hr.lm.leaveSummary.LeaveSummary;
30 import org.kuali.hr.lm.leaveSummary.LeaveSummaryRow;
31 import org.kuali.hr.lm.leaveblock.LeaveBlock;
32 import org.kuali.hr.lm.leaveblock.service.LeaveBlockService;
33 import org.kuali.hr.lm.leaveplan.LeavePlan;
34 import org.kuali.hr.lm.workflow.LeaveCalendarDocumentHeader;
35 import org.kuali.hr.time.calendar.CalendarEntries;
36 import org.kuali.hr.time.earncode.EarnCode;
37 import org.kuali.hr.time.principal.PrincipalHRAttributes;
38 import org.kuali.hr.time.service.base.TkServiceLocator;
39 import org.kuali.hr.time.util.TKUtils;
40 import org.kuali.hr.time.util.TkConstants;
41 import org.kuali.rice.krad.util.ObjectUtils;
42
43 import java.math.BigDecimal;
44 import java.sql.Timestamp;
45 import java.text.DateFormat;
46 import java.text.ParseException;
47 import java.text.SimpleDateFormat;
48 import java.util.*;
49
50 public class LeaveSummaryServiceImpl implements LeaveSummaryService {
51 private LeaveBlockService leaveBlockService;
52
53 @Override
54 public LeaveSummary getLeaveSummaryAsOfDate(String principalId, java.sql.Date asOfDate) {
55 return getLeaveSummary(principalId, asOfDate, asOfDate, null, true);
56 }
57
58 public LeaveSummary getLeaveSummaryAsOfDateWithoutFuture(String principalId, java.sql.Date asOfDate) {
59 return getLeaveSummary(principalId, asOfDate, asOfDate, null, false);
60 }
61
62 @Override
63 public LeaveSummary getLeaveSummary(String principalId, CalendarEntries calendarEntry) {
64 return getLeaveSummary(principalId, calendarEntry.getBeginPeriodDate(), calendarEntry.getEndPeriodDate(), null, true);
65 }
66
67 @Override
68 public LeaveSummary getLeaveSummaryAsOfDateForAccrualCategory(String principalId, java.sql.Date asOfDate, String accrualCategory) {
69 return getLeaveSummary(principalId, asOfDate, asOfDate, accrualCategory, true);
70 }
71
72 @Override
73
74
75 public BigDecimal getLeaveBalanceForAccrCatUpToDate(String principalId,
76 java.sql.Date startDate,
77 java.sql.Date endDate,
78 String accrualCategory,
79 Date usageEndDate) {
80 BigDecimal leaveBalance = BigDecimal.ZERO;
81 if(StringUtils.isEmpty(principalId) || startDate == null || endDate == null || StringUtils.isEmpty(accrualCategory) || usageEndDate == null) {
82 return leaveBalance;
83 }
84
85 LeaveSummaryRow lsr = new LeaveSummaryRow();
86 AccrualCategory ac = TkServiceLocator.getAccrualCategoryService().getAccrualCategory(accrualCategory, endDate);
87
88 if(ac != null) {
89 LeavePlan lp = TkServiceLocator.getLeavePlanService().getLeavePlan(ac.getLeavePlan(), ac.getEffectiveDate());
90 if(lp == null) {
91 return leaveBalance;
92 }
93 PrincipalHRAttributes pha = getPrincipalHrAttributes(principalId, startDate, endDate);
94
95
96 Map<String, LeaveBlock> carryOverBlocks = getLeaveBlockService().getLastCarryOverBlocks(principalId, startDate);
97
98 LeaveBlock carryOverBlock = carryOverBlocks.get(accrualCategory);
99 carryOverBlocks = new HashMap<String, LeaveBlock>(1);
100 if(ObjectUtils.isNotNull(carryOverBlock))
101 carryOverBlocks.put(carryOverBlock.getAccrualCategory(), carryOverBlock);
102
103 List<LeaveBlock> leaveBlocks = getLeaveBlockService().getLeaveBlocksSinceCarryOver(principalId, carryOverBlocks, (new LocalDateTime(endDate)).toDateTime(), true);
104 List<LeaveBlock> acLeaveBlocks = new ArrayList<LeaveBlock>();
105 for(LeaveBlock lb : leaveBlocks) {
106 if(StringUtils.equals(lb.getAccrualCategory(), accrualCategory)) {
107 acLeaveBlocks.add(lb);
108 }
109 }
110
111 List<LeaveBlock> futureLeaveBlocks = getLeaveBlockService().getLeaveBlocksWithAccrualCategory(principalId, endDate, usageEndDate, accrualCategory);
112 EmployeeOverride maxUsageOverride = TkServiceLocator.getEmployeeOverrideService().getEmployeeOverride(principalId, lp.getLeavePlan(), accrualCategory, "MU", new java.sql.Date(usageEndDate.getTime()));
113
114
115 AccrualCategoryRule acRule = TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRuleForDate(ac, TKUtils.getCurrentDate(), pha.getServiceDate());
116
117
118 lsr.setAccrualCategoryRuleId(acRule == null ? null : acRule.getLmAccrualCategoryRuleId());
119 if(acRule != null &&
120 (acRule.getMaxBalance()!= null
121 || acRule.getMaxUsage() != null)) {
122 if (acRule.getMaxUsage() != null) {
123 lsr.setUsageLimit(new BigDecimal(acRule.getMaxUsage()).setScale(2));
124 } else {
125 lsr.setUsageLimit(null);
126 }
127 } else {
128 lsr.setUsageLimit(null);
129 }
130
131 if(maxUsageOverride !=null)
132 lsr.setUsageLimit(new BigDecimal(maxUsageOverride.getOverrideValue()));
133
134
135 BigDecimal carryOver = BigDecimal.ZERO.setScale(2);
136 lsr.setCarryOver(carryOver);
137
138 assignApprovedValuesToRow(lsr, ac.getAccrualCategory(), acLeaveBlocks, lp, startDate, endDate);
139
140
141 if (carryOverBlocks.containsKey(lsr.getAccrualCategory())) {
142 carryOver = carryOverBlocks.get(lsr.getAccrualCategory()).getLeaveAmount();
143 }
144 Set<String> keyset = new HashSet<String>();
145 keyset.addAll(lsr.getPriorYearsUsage().keySet());
146 keyset.addAll(lsr.getPriorYearsTotalAccrued().keySet());
147 for (String key : keyset) {
148 BigDecimal value = lsr.getPriorYearsTotalAccrued().get(key);
149 if (value == null) {
150 value = BigDecimal.ZERO;
151 }
152 carryOver = carryOver.add(value);
153 BigDecimal use = lsr.getPriorYearsUsage().containsKey(key) ? lsr.getPriorYearsUsage().get(key) : BigDecimal.ZERO;
154 carryOver = carryOver.add(use);
155 if (acRule != null && acRule.getMaxCarryOver() != null && acRule.getMaxCarryOver() < carryOver.longValue()) {
156 carryOver = new BigDecimal(acRule.getMaxCarryOver());
157 }
158 }
159
160 lsr.setCarryOver(carryOver);
161
162 assignPendingValuesToRow(lsr, ac.getAccrualCategory(), futureLeaveBlocks);
163
164 leaveBalance = lsr.getAccruedBalance().subtract(lsr.getPendingLeaveRequests());
165 if(lsr.getUsageLimit()!=null) {
166 BigDecimal availableUsage = lsr.getUsageLimit().subtract(lsr.getYtdApprovedUsage().add(lsr.getPendingLeaveRequests()));
167 if(leaveBalance.compareTo( availableUsage ) > 0)
168 lsr.setLeaveBalance(availableUsage);
169 else
170 lsr.setLeaveBalance(leaveBalance);
171 } else {
172 lsr.setLeaveBalance(leaveBalance);
173 }
174 }
175 leaveBalance = lsr.getLeaveBalance();
176 return leaveBalance;
177 }
178
179 protected LeaveSummary getLeaveSummary(String principalId,
180 java.sql.Date startDate,
181 java.sql.Date endDate,
182 String accrualCategory,
183 boolean includeFuture) {
184 LeaveSummary ls = new LeaveSummary();
185 List<LeaveSummaryRow> rows = new ArrayList<LeaveSummaryRow>();
186
187 if(StringUtils.isEmpty(principalId) || startDate == null || endDate == null) {
188 return ls;
189 }
190
191 Set<String> leavePlans = getLeavePlans(principalId, startDate, endDate);
192 PrincipalHRAttributes pha = getPrincipalHrAttributes(principalId, startDate, endDate);
193 if (CollectionUtils.isNotEmpty(leavePlans)) {
194 for(String aLpString : leavePlans) {
195 LeavePlan lp = TkServiceLocator.getLeavePlanService().getLeavePlan(aLpString, startDate);
196 if(lp == null) {
197 continue;
198 }
199 DateFormat formatter = new SimpleDateFormat("MMMM d");
200 DateFormat formatter2 = new SimpleDateFormat("MMMM d yyyy");
201 DateTime entryEndDate = new LocalDateTime(endDate).toDateTime();
202 if (entryEndDate.getHourOfDay() == 0) {
203 entryEndDate = entryEndDate.minusDays(1);
204 }
205 String aString = formatter.format(startDate) + " - " + formatter2.format(entryEndDate.toDate());
206 ls.setPendingDatesString(aString);
207
208 LeaveCalendarDocumentHeader approvedLcdh = TkServiceLocator.getLeaveCalendarDocumentHeaderService().getMaxEndDateApprovedLeaveCalendar(principalId);
209 if(approvedLcdh != null) {
210 Date endApprovedDate = new java.sql.Date(approvedLcdh.getEndDate().getTime());
211 LocalDateTime aLocalTime = new DateTime(approvedLcdh.getEndDate()).toLocalDateTime();
212 DateTime endApprovedTime = aLocalTime.toDateTime(TkServiceLocator.getTimezoneService().getUserTimezoneWithFallback());
213 if(endApprovedTime.getHourOfDay() == 0) {
214 endApprovedDate = TKUtils.addDates(endApprovedDate, -1);
215 }
216 String datesString = formatter.format(approvedLcdh.getBeginDate()) + " - " + formatter2.format(endApprovedDate);
217 ls.setYtdDatesString(datesString);
218 }
219
220
221
222 Map<String, LeaveBlock> carryOverBlocks = getLeaveBlockService().getLastCarryOverBlocks(principalId, startDate);
223
224 boolean filterByAccrualCategory = false;
225 if (StringUtils.isNotEmpty(accrualCategory)) {
226 filterByAccrualCategory = true;
227
228 LeaveBlock carryOverBlock = carryOverBlocks.get(accrualCategory);
229 carryOverBlocks = new HashMap<String, LeaveBlock>(1);
230 if(ObjectUtils.isNotNull(carryOverBlock))
231 carryOverBlocks.put(carryOverBlock.getAccrualCategory(), carryOverBlock);
232 }
233 List<LeaveBlock> leaveBlocks = getLeaveBlockService().getLeaveBlocksSinceCarryOver(principalId, carryOverBlocks, (new LocalDateTime(endDate)).toDateTime(), filterByAccrualCategory);
234
235 List<LeaveBlock> futureLeaveBlocks = new ArrayList<LeaveBlock>();
236 if (includeFuture) {
237 if (!filterByAccrualCategory) {
238 futureLeaveBlocks = getLeaveBlockService().getLeaveBlocks(principalId, endDate, (new LocalDateTime(endDate)).toDateTime().plusMonths(Integer.parseInt(lp.getPlanningMonths())).toDate());
239 } else {
240 futureLeaveBlocks = getLeaveBlockService().getLeaveBlocksWithAccrualCategory(principalId, endDate, (new LocalDateTime(endDate)).toDateTime().plusMonths(Integer.parseInt(lp.getPlanningMonths())).toDate(), accrualCategory);
241 }
242 }
243 Map<String, List<LeaveBlock>> leaveBlockMap = mapLeaveBlocksByAccrualCategory(leaveBlocks);
244 Map<String, List<LeaveBlock>> futureLeaveBlockMap = mapLeaveBlocksByAccrualCategory(futureLeaveBlocks);
245 List<AccrualCategory> acList = TkServiceLocator.getAccrualCategoryService().getActiveAccrualCategoriesForLeavePlan(lp.getLeavePlan(), endDate);
246 if(CollectionUtils.isNotEmpty(acList)) {
247 for(AccrualCategory ac : acList) {
248 if(ac.getShowOnGrid().equals("Y")) {
249
250 LeaveSummaryRow lsr = new LeaveSummaryRow();
251 lsr.setAccrualCategory(ac.getAccrualCategory());
252 lsr.setAccrualCategoryId(ac.getLmAccrualCategoryId());
253
254 AccrualCategoryRule acRule = TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRuleForDate(ac, endDate, pha.getServiceDate());
255
256
257 EmployeeOverride maxUsageOverride = TkServiceLocator.getEmployeeOverrideService().getEmployeeOverride(principalId, lp.getLeavePlan(), ac.getAccrualCategory(), "MU", endDate);
258
259 lsr.setAccrualCategoryRuleId(acRule == null ? null : acRule.getLmAccrualCategoryRuleId());
260 if(acRule != null &&
261 (acRule.getMaxBalance()!= null
262 || acRule.getMaxUsage() != null)) {
263 if (acRule.getMaxUsage() != null) {
264 lsr.setUsageLimit(new BigDecimal(acRule.getMaxUsage()).setScale(2));
265 } else {
266 lsr.setUsageLimit(null);
267 }
268
269 } else {
270 lsr.setUsageLimit(null);
271 }
272
273 if(maxUsageOverride !=null)
274 lsr.setUsageLimit(new BigDecimal(maxUsageOverride.getOverrideValue()));
275
276
277 BigDecimal carryOver = BigDecimal.ZERO.setScale(2);
278 lsr.setCarryOver(carryOver);
279
280
281
282 assignApprovedValuesToRow(lsr, ac.getAccrualCategory(), leaveBlockMap.get(ac.getAccrualCategory()), lp, startDate, endDate);
283
284
285
286
287
288
289
290
291
292
293
294
295
296 if (carryOverBlocks.containsKey(lsr.getAccrualCategory())) {
297 carryOver = carryOverBlocks.get(lsr.getAccrualCategory()).getLeaveAmount();
298 carryOver = carryOver.setScale(2);
299 }
300 Set<String> keyset = new HashSet<String>();
301 keyset.addAll(lsr.getPriorYearsUsage().keySet());
302 keyset.addAll(lsr.getPriorYearsTotalAccrued().keySet());
303 for (String key : keyset) {
304 BigDecimal value = lsr.getPriorYearsTotalAccrued().get(key);
305 if (value == null) {
306 value = BigDecimal.ZERO;
307 }
308 carryOver = carryOver.add(value);
309 BigDecimal use = lsr.getPriorYearsUsage().containsKey(key) ? lsr.getPriorYearsUsage().get(key) : BigDecimal.ZERO;
310 carryOver = carryOver.add(use);
311 EmployeeOverride carryOverOverride = TkServiceLocator.getEmployeeOverrideService().getEmployeeOverride(principalId, lp.getLeavePlan(), ac.getAccrualCategory(), "MAC", endDate);
312 if (acRule != null && acRule.getMaxCarryOver() != null) {
313 BigDecimal carryOverDisplay = BigDecimal.ZERO;
314 if(carryOverOverride != null)
315 carryOverDisplay = new BigDecimal(carryOverOverride.getOverrideValue() < carryOver.longValue() ? carryOverOverride.getOverrideValue() : carryOver.longValue());
316 else
317 carryOverDisplay = new BigDecimal(acRule.getMaxCarryOver() < carryOver.longValue() ? acRule.getMaxCarryOver() : carryOver.longValue());
318 carryOver = carryOverDisplay;
319 }
320 }
321
322 lsr.setCarryOver(carryOver);
323 if (acRule != null && acRule.getMaxCarryOver() != null) {
324 EmployeeOverride carryOverOverride = TkServiceLocator.getEmployeeOverrideService().getEmployeeOverride(principalId, lp.getLeavePlan(), ac.getAccrualCategory(), "MAC", endDate);
325 if(carryOverOverride != null)
326 lsr.setMaxCarryOver(new BigDecimal(carryOverOverride.getOverrideValue()));
327 else
328 lsr.setMaxCarryOver(new BigDecimal(acRule.getMaxCarryOver() < carryOver.longValue() ? acRule.getMaxCarryOver() : carryOver.longValue()));
329 }
330
331
332 assignPendingValuesToRow(lsr, ac.getAccrualCategory(), futureLeaveBlockMap.get(ac.getAccrualCategory()));
333
334
335 BigDecimal leaveBalance = lsr.getAccruedBalance().subtract(lsr.getPendingLeaveRequests());
336
337
338
339
340
341
342
343
344 if(lsr.getUsageLimit()!=null) {
345 BigDecimal availableUsage = lsr.getUsageLimit().subtract(lsr.getYtdApprovedUsage().add(lsr.getPendingLeaveRequests()));
346 if(leaveBalance.compareTo( availableUsage ) > 0)
347 lsr.setLeaveBalance(availableUsage);
348 else
349 lsr.setLeaveBalance(leaveBalance);
350 } else {
351 lsr.setLeaveBalance(leaveBalance);
352 }
353
354 rows.add(lsr);
355 }
356 }
357
358 if (leaveBlockMap.containsKey(null)
359 || futureLeaveBlockMap.containsKey(null)) {
360 LeaveSummaryRow otherLeaveSummary = new LeaveSummaryRow();
361
362
363 assignApprovedValuesToRow(otherLeaveSummary, null, leaveBlockMap.get(null), lp, startDate, endDate);
364 BigDecimal carryOver = BigDecimal.ZERO.setScale(2);
365 for (Map.Entry<String, BigDecimal> entry : otherLeaveSummary.getPriorYearsTotalAccrued().entrySet()) {
366 carryOver = carryOver.add(entry.getValue());
367 BigDecimal use = otherLeaveSummary.getPriorYearsUsage().containsKey(entry.getKey()) ? otherLeaveSummary.getPriorYearsUsage().get(entry.getKey()) : BigDecimal.ZERO;
368 carryOver = carryOver.add(use);
369 }
370 otherLeaveSummary.setCarryOver(carryOver);
371 assignPendingValuesToRow(otherLeaveSummary, null, futureLeaveBlockMap.get(null));
372 otherLeaveSummary.setAccrualCategory("Other");
373
374
375
376 otherLeaveSummary.setUsageLimit(null);
377 otherLeaveSummary.setLeaveBalance(null);
378
379 rows.add(otherLeaveSummary);
380 }
381 }
382 }
383 }
384 ls.setLeaveSummaryRows(rows);
385 return ls;
386 }
387
388 private PrincipalHRAttributes getPrincipalHrAttributes(String principalId, Date startDate, Date endDate) {
389 PrincipalHRAttributes pha = TkServiceLocator.getPrincipalHRAttributeService().getPrincipalCalendar(principalId, startDate);
390 if(pha == null) {
391 pha = TkServiceLocator.getPrincipalHRAttributeService().getPrincipalCalendar(principalId, endDate);
392 }
393 return pha;
394 }
395
396 private Set<String> getLeavePlans(String principalId, Date startDate, Date endDate) {
397 Set<String> lpStrings = new HashSet<String>();
398
399 PrincipalHRAttributes pha = getPrincipalHrAttributes(principalId, startDate, endDate);
400
401 List<PrincipalHRAttributes> phaList = TkServiceLocator.getPrincipalHRAttributeService()
402 .getActivePrincipalHrAttributesForRange(principalId, startDate, endDate);
403 if(pha != null) {
404 lpStrings.add(pha.getLeavePlan());
405 }
406 if(CollectionUtils.isNotEmpty(phaList)) {
407 for(PrincipalHRAttributes aPha : phaList) {
408 lpStrings.add(aPha.getLeavePlan());
409 }
410 }
411
412 return lpStrings;
413 }
414
415
416 private Map<String, List<LeaveBlock>> mapLeaveBlocksByAccrualCategory(List<LeaveBlock> leaveBlocks) {
417 Map<String, List<LeaveBlock>> map = new HashMap<String, List<LeaveBlock>>();
418 for (LeaveBlock lb : leaveBlocks) {
419 if (map.containsKey(lb.getAccrualCategory())) {
420 map.get(lb.getAccrualCategory()).add(lb);
421 } else {
422 List<LeaveBlock> splitLeaveBlocks = new ArrayList<LeaveBlock>();
423 splitLeaveBlocks.add(lb);
424 map.put(lb.getAccrualCategory(), splitLeaveBlocks);
425 }
426 }
427 return map;
428 }
429
430
431
432
433
434
435
436 private void markTransferable(LeaveSummaryRow lsr, AccrualCategoryRule accrualCategoryRule, String principalId) {
437
438
439
440
441 boolean transferable = false;
442 if(ObjectUtils.isNotNull(accrualCategoryRule)) {
443 if(ObjectUtils.isNotNull(accrualCategoryRule.getMaxBalance())) {
444 BigDecimal maxBalance = accrualCategoryRule.getMaxBalance();
445 BigDecimal fte = TkServiceLocator.getJobService().getFteSumForAllActiveLeaveEligibleJobs(principalId, TKUtils.getCurrentDate());
446 BigDecimal adjustedMaxBalance = maxBalance.multiply(fte);
447 List<EmployeeOverride> overrides = TkServiceLocator.getEmployeeOverrideService().getEmployeeOverrides(principalId, TKUtils.getCurrentDate());
448 for(EmployeeOverride override : overrides) {
449 if(StringUtils.equals(override.getOverrideType(),TkConstants.EMPLOYEE_OVERRIDE_TYPE.get("MB"))
450 && override.isActive()) {
451 adjustedMaxBalance = new BigDecimal(override.getOverrideValue());
452 break;
453 }
454 }
455 if(adjustedMaxBalance.compareTo(lsr.getAccruedBalance()) < 0) {
456 if(StringUtils.equals(accrualCategoryRule.getActionAtMaxBalance(), LMConstants.ACTION_AT_MAX_BAL.TRANSFER) &&
457 StringUtils.equals(accrualCategoryRule.getMaxBalanceActionFrequency(),LMConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND))
458 transferable = true;
459 }
460 }
461 }
462 lsr.setTransferable(transferable);
463 }
464
465
466
467
468
469
470
471 private void markPayoutable(LeaveSummaryRow lsr, AccrualCategoryRule accrualCategoryRule, String principalId) {
472
473
474
475
476 boolean payoutable = false;
477 if(ObjectUtils.isNotNull(accrualCategoryRule)) {
478 if(ObjectUtils.isNotNull(accrualCategoryRule.getMaxBalance())) {
479 BigDecimal maxBalance = accrualCategoryRule.getMaxBalance();
480 BigDecimal fte = TkServiceLocator.getJobService().getFteSumForAllActiveLeaveEligibleJobs(principalId, TKUtils.getCurrentDate());
481 BigDecimal adjustedMaxBalance = maxBalance.multiply(fte);
482 List<EmployeeOverride> overrides = TkServiceLocator.getEmployeeOverrideService().getEmployeeOverrides(principalId, TKUtils.getCurrentDate());
483 for(EmployeeOverride override : overrides) {
484 if(StringUtils.equals(override.getOverrideType(),TkConstants.EMPLOYEE_OVERRIDE_TYPE.get("MB"))
485 && override.isActive()) {
486 adjustedMaxBalance = new BigDecimal(override.getOverrideValue());
487 break;
488 }
489 }
490 if(adjustedMaxBalance.compareTo(lsr.getAccruedBalance()) < 0) {
491 if(StringUtils.equals(accrualCategoryRule.getActionAtMaxBalance(), LMConstants.ACTION_AT_MAX_BAL.PAYOUT) &&
492 StringUtils.equals(accrualCategoryRule.getMaxBalanceActionFrequency(),LMConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND))
493 payoutable = true;
494 }
495 }
496 }
497 lsr.setPayoutable(payoutable);
498 }
499
500 private void assignApprovedValuesToRow(LeaveSummaryRow lsr, String accrualCategory, List<LeaveBlock> approvedLeaveBlocks, LeavePlan lp, Date ytdEarnedEffectiveDate, Date effectiveDate) {
501
502 SortedMap<String, BigDecimal> yearlyAccrued = new TreeMap<String, BigDecimal>();
503 SortedMap<String, BigDecimal> yearlyUsage = new TreeMap<String, BigDecimal>();
504 BigDecimal accrualedBalance = BigDecimal.ZERO.setScale(2);
505 BigDecimal approvedUsage = BigDecimal.ZERO.setScale(2);
506 BigDecimal fmlaUsage = BigDecimal.ZERO.setScale(2);
507
508 Date cutOffDateToCheck = ytdEarnedEffectiveDate != null ? ytdEarnedEffectiveDate : effectiveDate;
509 DateTime cutOffDate = TkServiceLocator.getLeavePlanService().getFirstDayOfLeavePlan(lp.getLeavePlan(), cutOffDateToCheck).minus(1);
510
511 Timestamp priorYearCutOff = new Timestamp(cutOffDate.getMillis());
512
513 if (CollectionUtils.isNotEmpty(approvedLeaveBlocks)) {
514
515 for(LeaveBlock aLeaveBlock : approvedLeaveBlocks) {
516
517 if(!aLeaveBlock.getLeaveBlockType().equals(LMConstants.LEAVE_BLOCK_TYPE.CARRY_OVER)
518 && aLeaveBlock.getLeaveDate().getTime() < effectiveDate.getTime()) {
519 if((StringUtils.isBlank(accrualCategory) && StringUtils.isBlank(aLeaveBlock.getAccrualCategory()))
520 || (StringUtils.isNotBlank(aLeaveBlock.getAccrualCategory())
521 && StringUtils.equals(aLeaveBlock.getAccrualCategory(), accrualCategory))) {
522 if(aLeaveBlock.getLeaveAmount().compareTo(BigDecimal.ZERO) >= 0
523 && !aLeaveBlock.getLeaveBlockType().equals(LMConstants.LEAVE_BLOCK_TYPE.LEAVE_CALENDAR)) {
524 if(!(StringUtils.equals(LMConstants.REQUEST_STATUS.DISAPPROVED, aLeaveBlock.getRequestStatus()) ||
525 StringUtils.equals(LMConstants.REQUEST_STATUS.DEFERRED, aLeaveBlock.getRequestStatus()))) {
526 if (aLeaveBlock.getLeaveDate().getTime() <= priorYearCutOff.getTime()) {
527 String yearKey = getYearKey(aLeaveBlock.getLeaveDate(), lp);
528 BigDecimal co = yearlyAccrued.get(yearKey);
529 if (co == null) {
530 co = BigDecimal.ZERO.setScale(2);
531 }
532 co = co.add(aLeaveBlock.getLeaveAmount());
533 yearlyAccrued.put(yearKey, co);
534 } else if(aLeaveBlock.getLeaveDate().getTime() < ytdEarnedEffectiveDate.getTime()) {
535 accrualedBalance = accrualedBalance.add(aLeaveBlock.getLeaveAmount());
536 }
537 }
538 } else {
539 BigDecimal currentLeaveAmount = aLeaveBlock.getLeaveAmount().compareTo(BigDecimal.ZERO) > 0 ? aLeaveBlock.getLeaveAmount().negate() : aLeaveBlock.getLeaveAmount();
540
541 if(!(StringUtils.equals(LMConstants.REQUEST_STATUS.DISAPPROVED, aLeaveBlock.getRequestStatus()) ||
542 StringUtils.equals(LMConstants.REQUEST_STATUS.DEFERRED, aLeaveBlock.getRequestStatus()))) {
543
544 EarnCode ec = TkServiceLocator.getEarnCodeService().getEarnCode(aLeaveBlock.getEarnCode(), aLeaveBlock.getLeaveDate());
545
546 if ((ec != null && StringUtils.equals(ec.getAccrualBalanceAction(), LMConstants.ACCRUAL_BALANCE_ACTION.USAGE))
547 || aLeaveBlock.getLeaveBlockType().equals(LMConstants.LEAVE_BLOCK_TYPE.BALANCE_TRANSFER)
548 || aLeaveBlock.getLeaveBlockType().equals(LMConstants.LEAVE_BLOCK_TYPE.LEAVE_PAYOUT)
549 || aLeaveBlock.getLeaveBlockType().equals(LMConstants.LEAVE_BLOCK_TYPE.LEAVE_ADJUSTMENT_MAINT)
550 || aLeaveBlock.getLeaveBlockType().equals(LMConstants.LEAVE_BLOCK_TYPE.DONATION_MAINT)){
551 if (aLeaveBlock.getLeaveDate().getTime() > priorYearCutOff.getTime()) {
552
553 approvedUsage = approvedUsage.add(currentLeaveAmount);
554
555 if(ec != null && ec.getFmla().equals("Y")) {
556 fmlaUsage = fmlaUsage.add(aLeaveBlock.getLeaveAmount());
557 }
558 } else {
559
560 String yearKey = getYearKey(aLeaveBlock.getLeaveDate(), lp);
561 BigDecimal use = yearlyUsage.get(yearKey);
562 if (use == null) {
563 use = BigDecimal.ZERO.setScale(2);
564 }
565 use = use.add(currentLeaveAmount);
566 yearlyUsage.put(yearKey, use);
567 }
568 }
569 }
570 }
571
572
573 }
574 } else {
575
576
577 }
578 }
579 }
580
581 lsr.setPriorYearsTotalAccrued(yearlyAccrued);
582 lsr.setPriorYearsUsage(yearlyUsage);
583 lsr.setYtdAccruedBalance(accrualedBalance);
584 lsr.setYtdApprovedUsage(approvedUsage.negate());
585 lsr.setFmlaUsage(fmlaUsage.negate());
586
587
588 }
589
590 private String getYearKey(Date leaveDate, LeavePlan lp){
591 Calendar cal = Calendar.getInstance();
592 Calendar leavePlanCal = Calendar.getInstance();
593 cal.setTime(leaveDate);
594 String yearKey = Integer.toString(cal.get(Calendar.YEAR));
595 leavePlanCal.set(Calendar.MONTH, Integer.parseInt(lp.getCalendarYearStartMonth()) - 1);
596 leavePlanCal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(lp.getCalendarYearStartDayOfMonth()));
597 leavePlanCal.set(Calendar.YEAR, cal.get(Calendar.YEAR));
598 leavePlanCal.set(Calendar.HOUR_OF_DAY, 0);
599 leavePlanCal.set(Calendar.MINUTE, 0);
600 leavePlanCal.set(Calendar.SECOND, 0);
601 leavePlanCal.set(Calendar.MILLISECOND, 0);
602
603 if (cal.getTime().before(leavePlanCal.getTime())) {
604 yearKey = Integer.toString(cal.get(Calendar.YEAR) - 1);
605 }
606 return yearKey;
607 }
608
609 private void assignPendingValuesToRow(LeaveSummaryRow lsr, String accrualCategory, List<LeaveBlock> pendingLeaveBlocks ) {
610 BigDecimal pendingAccrual= BigDecimal.ZERO.setScale(2);
611 BigDecimal pendingRequests = BigDecimal.ZERO.setScale(2);
612 if (CollectionUtils.isNotEmpty(pendingLeaveBlocks)) {
613 for(LeaveBlock aLeaveBlock : pendingLeaveBlocks) {
614 if(!aLeaveBlock.getLeaveBlockType().equals(LMConstants.LEAVE_BLOCK_TYPE.CARRY_OVER)) {
615 if((StringUtils.isBlank(accrualCategory) && StringUtils.isBlank(aLeaveBlock.getAccrualCategory()))
616 || (StringUtils.isNotBlank(aLeaveBlock.getAccrualCategory())
617 && StringUtils.equals(aLeaveBlock.getAccrualCategory(), accrualCategory))) {
618 if(aLeaveBlock.getLeaveAmount().compareTo(BigDecimal.ZERO) >= 0) {
619 pendingAccrual = pendingAccrual.add(aLeaveBlock.getLeaveAmount());
620 } else {
621 pendingRequests = pendingRequests.add(aLeaveBlock.getLeaveAmount());
622 }
623 }
624 }
625 }
626 }
627 lsr.setPendingLeaveAccrual(pendingAccrual);
628 lsr.setPendingLeaveRequests(pendingRequests.negate());
629 }
630
631 @Override
632 public List<Date> getLeaveSummaryDates(CalendarEntries calendarEntry) {
633 List<Date> leaveSummaryDates = new ArrayList<Date>();
634
635 DateTime start = calendarEntry.getBeginLocalDateTime().toDateTime();
636 DateTime end = calendarEntry.getEndLocalDateTime().toDateTime();
637 Interval interval = new Interval(start, end);
638
639 for (DateTime day = interval.getStart(); day.isBefore(interval.getEnd()); day = day.plusDays(1)) {
640 leaveSummaryDates.add(day.toLocalDate().toDateTimeAtStartOfDay().toDate());
641 }
642
643 return leaveSummaryDates;
644 }
645
646 protected LeaveBlockService getLeaveBlockService() {
647 if (leaveBlockService == null) {
648 leaveBlockService = TkServiceLocator.getLeaveBlockService();
649 }
650 return leaveBlockService;
651 }
652
653
654 }
655