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