1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.kpme.tklm.leave.approval.service;
17
18 import java.math.BigDecimal;
19 import java.text.SimpleDateFormat;
20 import java.util.ArrayList;
21 import java.util.Date;
22 import java.util.HashMap;
23 import java.util.HashSet;
24 import java.util.LinkedHashMap;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Map.Entry;
28 import java.util.Set;
29 import java.util.TreeSet;
30
31 import org.apache.commons.collections.CollectionUtils;
32 import org.apache.commons.lang.StringUtils;
33 import org.joda.time.DateTime;
34 import org.joda.time.DateTimeConstants;
35 import org.joda.time.DateTimeFieldType;
36 import org.joda.time.LocalDate;
37 import org.joda.time.LocalDateTime;
38 import org.kuali.kpme.core.accrualcategory.AccrualCategory;
39 import org.kuali.kpme.core.accrualcategory.rule.AccrualCategoryRule;
40 import org.kuali.kpme.core.assignment.Assignment;
41 import org.kuali.kpme.core.calendar.Calendar;
42 import org.kuali.kpme.core.calendar.entry.CalendarEntry;
43 import org.kuali.kpme.core.principal.PrincipalHRAttributes;
44 import org.kuali.kpme.core.service.HrServiceLocator;
45 import org.kuali.kpme.core.util.HrConstants;
46 import org.kuali.kpme.tklm.common.LMConstants;
47 import org.kuali.kpme.tklm.common.TkConstants;
48 import org.kuali.kpme.tklm.leave.approval.web.ApprovalLeaveSummaryRow;
49 import org.kuali.kpme.tklm.leave.block.LeaveBlock;
50 import org.kuali.kpme.tklm.leave.calendar.LeaveCalendarDocument;
51 import org.kuali.kpme.tklm.leave.calendar.validation.LeaveCalendarValidationUtil;
52 import org.kuali.kpme.tklm.leave.service.LmServiceLocator;
53 import org.kuali.kpme.tklm.leave.summary.LeaveSummary;
54 import org.kuali.kpme.tklm.leave.summary.LeaveSummaryRow;
55 import org.kuali.kpme.tklm.leave.workflow.LeaveCalendarDocumentHeader;
56 import org.kuali.kpme.tklm.time.timesummary.TimeSummary;
57 import org.kuali.rice.kew.api.KewApiServiceLocator;
58 import org.kuali.rice.kew.api.action.ActionRequest;
59 import org.kuali.rice.kew.api.exception.WorkflowException;
60 import org.kuali.rice.kew.api.note.Note;
61 import org.kuali.rice.kim.api.identity.principal.EntityNamePrincipalName;
62 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
63
64 public class LeaveApprovalServiceImpl implements LeaveApprovalService {
65
66 public static final int DAYS_WINDOW_DELTA = 31;
67
68 @Override
69 public List<ApprovalLeaveSummaryRow> getLeaveApprovalSummaryRows(List<String> principalIds, CalendarEntry payCalendarEntry, List<Date> leaveSummaryDates, String docIdSearchTerm) {
70 DateTime payBeginDate = payCalendarEntry.getBeginPeriodFullDateTime();
71 DateTime payEndDate = payCalendarEntry.getEndPeriodFullDateTime();
72 List<ApprovalLeaveSummaryRow> rowList = new ArrayList<ApprovalLeaveSummaryRow>();
73 for(String principalId : principalIds) {
74
75 ApprovalLeaveSummaryRow aRow = new ApprovalLeaveSummaryRow();
76 List<Note> notes = new ArrayList<Note>();
77
78 EntityNamePrincipalName name = KimApiServiceLocator.getIdentityService().getDefaultNamesForPrincipalId(principalId);
79 aRow.setName(name != null
80 && name.getDefaultName() != null
81 && name.getDefaultName().getCompositeName() != null ? name.getDefaultName().getCompositeName() : principalId);
82 aRow.setPrincipalId(principalId);
83
84 try {
85 aRow.setLeaveSummary(LmServiceLocator.getLeaveSummaryService().getLeaveSummary(principalId, payCalendarEntry));
86 } catch (Exception e1) {
87
88 e1.printStackTrace();
89 }
90
91 String lastApprovedString = "No previous approved leave calendar information";
92 LeaveCalendarDocumentHeader lastApprovedDoc = LmServiceLocator.getLeaveCalendarDocumentHeaderService().getMaxEndDateApprovedLeaveCalendar(principalId);
93 if(lastApprovedDoc != null) {
94 lastApprovedString = "Last Approved: " + (new SimpleDateFormat("MMM yyyy")).format(lastApprovedDoc.getBeginDate());
95 }
96 aRow.setLastApproveMessage(lastApprovedString);
97
98 LeaveCalendarDocumentHeader aDoc = LmServiceLocator.getLeaveCalendarDocumentHeaderService().getDocumentHeader(principalId, payBeginDate, payEndDate);
99 if(aDoc != null) {
100 if(StringUtils.isNotBlank(docIdSearchTerm) && !aDoc.getDocumentId().contains(docIdSearchTerm)) {
101 continue;
102 }
103 aRow.setDocumentId(aDoc.getDocumentId());
104 aRow.setApprovalStatus(HrConstants.DOC_ROUTE_STATUS.get(aDoc.getDocumentStatus()));
105 notes = getNotesForDocument(aDoc.getDocumentId());
106 if (StringUtils.isNotBlank(aRow.getDocumentId())) {
107 List<ActionRequest> actionRequests = KewApiServiceLocator.getWorkflowDocumentService().getPendingActionRequests(aRow.getDocumentId());
108 Map<String, String> roleNames = new HashMap<String, String>();
109 for (ActionRequest ar : actionRequests) {
110 roleNames.put(ar.getPrincipalId(), ar.getQualifiedRoleNameLabel());
111 }
112 aRow.setRoleNames(roleNames);
113 }
114 }
115 List<LeaveCalendarDocumentHeader> docList = LmServiceLocator.getLeaveCalendarDocumentHeaderService().getApprovalDelinquentDocumentHeaders(principalId);
116 if(docList.size() > LMConstants.DELINQUENT_LEAVE_CALENDARS_LIMIT ) {
117 aRow.setMoreThanOneCalendar(true);
118 }
119
120
121
122 LocalDate endDate = payEndDate.toLocalDate();
123 if(payEndDate.getHourOfDay() == 0) {
124 endDate = endDate.plusDays(-1);
125 }
126 List<LeaveBlock> leaveBlocks = LmServiceLocator.getLeaveBlockService().getLeaveBlocks(principalId, payBeginDate.toLocalDate(), endDate);
127 if(aDoc != null ){
128 Map<Integer, String> weeklyDistribution = getWeekHeadersForSummary(principalId,aDoc,payCalendarEntry,aRow.getWeekDates(), aRow.getWeekDateList(), aRow.getDetailMap(), aRow.getEnableWeekDetails());
129 aRow.setWeeklyDistribution(weeklyDistribution);
130 }else {
131
132 if (payCalendarEntry != null) {
133 try{
134 LeaveCalendarDocument leaveCalendarDocument = null;
135 if (LmServiceLocator.getLeaveCalendarService().shouldCreateLeaveDocument(principalId, payCalendarEntry)) {
136 leaveCalendarDocument = LmServiceLocator.getLeaveCalendarService().openLeaveCalendarDocument(principalId, payCalendarEntry);
137 } else {
138 aDoc = LmServiceLocator.getLeaveCalendarDocumentHeaderService().getDocumentHeader(principalId, payCalendarEntry.getBeginPeriodFullDateTime(), payCalendarEntry.getEndPeriodFullDateTime());
139 if (aDoc != null) {
140 leaveCalendarDocument = LmServiceLocator.getLeaveCalendarService().getLeaveCalendarDocument(aDoc.getDocumentId());
141 }
142 }
143
144 } catch (WorkflowException e) {
145 e.printStackTrace();
146 }
147 }
148
149 Map<Integer, String> weeklyDistribution = getWeekHeadersForSummary(principalId,aDoc,payCalendarEntry,aRow.getWeekDates(), aRow.getWeekDateList(), aRow.getDetailMap(), aRow.getEnableWeekDetails());
150 aRow.setWeeklyDistribution(weeklyDistribution);
151
152 }
153
154 aRow.setLeaveBlockList(leaveBlocks);
155
156 Map<Date, Map<String, BigDecimal>> earnCodeLeaveHours = getEarnCodeLeaveHours(leaveBlocks, leaveSummaryDates);
157 aRow.setEarnCodeLeaveHours(earnCodeLeaveHours);
158 aRow.setNotes(notes);
159
160 Map<String, Set<String>> allMessages = findWarnings(principalId, payCalendarEntry, leaveBlocks);
161
162 Map<String,Set<String>> transactionalMessages = findTransactionsWithinPeriod(aDoc, payCalendarEntry);
163
164 allMessages.get("infoMessages").addAll(transactionalMessages.get("infoMessages"));
165 allMessages.get("warningMessages").addAll(transactionalMessages.get("warningMessages"));
166 allMessages.get("actionMessages").addAll(transactionalMessages.get("actionMessages"));
167
168 if(aRow.getLeaveSummary() != null && aRow.getLeaveSummary().getLeaveSummaryRows().size() > 0) {
169 for(LeaveSummaryRow summaryRow : aRow.getLeaveSummary().getLeaveSummaryRows()){
170
171 if(summaryRow.getLeaveBalance() != null && summaryRow.getLeaveBalance().compareTo(BigDecimal.ZERO) < 0) {
172 String message = "Negative available balance found for the accrual category '"+summaryRow.getAccrualCategory()+ "'.";
173 allMessages.get("warningMessages").add(message);
174 }
175 }
176 }
177
178 List<String> warningMessages = new ArrayList<String>();
179 warningMessages.addAll(allMessages.get("warningMessages"));
180 warningMessages.addAll(allMessages.get("infoMessages"));
181 warningMessages.addAll(allMessages.get("actionMessages"));
182
183
184
185 aRow.setWarnings(warningMessages);
186
187 rowList.add(aRow);
188
189 }
190
191 return rowList;
192 }
193 private Calendar getPayCalendarForEntry(CalendarEntry calEntry) {
194 Calendar cal = null;
195
196 if (calEntry != null) {
197 cal = HrServiceLocator.getCalendarService().getCalendar(calEntry.getHrCalendarId());
198 }
199
200 return cal;
201 }
202
203 private Map<Integer, String> getWeekHeadersForSummary(String principalId,LeaveCalendarDocumentHeader lcdh,CalendarEntry cal, Map<String, String> weekDates, Map<String, Set<Date>> weekDateList, Map<String,List<Map<String, Object>>> weekDetailMap, Map<String,Boolean> enableWeekDetails) {
204
205 Map<Integer, String> header = new LinkedHashMap<Integer,String>();
206 header.put(DateTimeConstants.SUNDAY, "Sun");
207 header.put(DateTimeConstants.MONDAY, "Mon");
208 header.put(DateTimeConstants.TUESDAY, "Tue");
209 header.put(DateTimeConstants.WEDNESDAY, "Wed");
210 header.put(DateTimeConstants.THURSDAY, "Thu");
211 header.put(DateTimeConstants.FRIDAY, "Fri");
212 header.put(DateTimeConstants.SATURDAY, "Sat");
213
214 int flsaBeginDay = this.getPayCalendarForEntry(cal).getFlsaBeginDayConstant();
215 if(flsaBeginDay <= 0) {
216 flsaBeginDay = DateTimeConstants.SUNDAY;
217 }
218 LocalDateTime startDate = cal.getBeginPeriodLocalDateTime();
219 LocalDateTime endDate = cal.getEndPeriodLocalDateTime();
220
221 LocalDateTime actualStartDate = cal.getBeginPeriodLocalDateTime();
222 LocalDateTime actualEndDate = cal.getEndPeriodLocalDateTime();
223
224
225 if(cal.getEndPeriodFullDateTime().getHourOfDay() == 0) {
226 endDate = endDate.plusDays(-1);
227 }
228
229 int daysToMinus = 0;
230 if(DateTimeConstants.SUNDAY != startDate.getDayOfWeek()) {
231 daysToMinus = startDate.getDayOfWeek();
232 }
233
234 actualStartDate = startDate.minusDays(daysToMinus);
235 int daysToAdd = 0;
236 if(endDate.getDayOfWeek() != DateTimeConstants.SUNDAY) {
237 daysToAdd = DateTimeConstants.SATURDAY - endDate.getDayOfWeek();
238 } else {
239 daysToAdd = DateTimeConstants.SATURDAY;
240 }
241
242 actualEndDate = endDate.plusDays(daysToAdd);
243
244
245
246
247 if (endDate.get(DateTimeFieldType.hourOfDay()) != 0 || endDate.get(DateTimeFieldType.minuteOfHour()) != 0 ||
248 endDate.get(DateTimeFieldType.secondOfMinute()) != 0)
249 {
250 actualEndDate = endDate.plusDays(1);
251 }
252
253 boolean afterFirstDay = false;
254 int week = 1;
255
256 LocalDateTime weekStart = actualStartDate;
257 LocalDateTime weekEnd = actualStartDate;
258 Set<Date> dates = new TreeSet<Date>();
259 for (LocalDateTime currentDate = actualStartDate; currentDate.compareTo(actualEndDate) <= 0; currentDate = currentDate.plusDays(1)) {
260
261 if ( (currentDate.getDayOfWeek() == flsaBeginDay && afterFirstDay)
262 || currentDate.compareTo(actualEndDate) == 0) {
263 String weekString = "Week " + week;
264 StringBuilder display = new StringBuilder();
265
266 String startDateString = weekStart.isBefore(startDate) ?
267 startDate.toString(TkConstants.DT_ABBREV_DATE_FORMAT) : weekStart.toString(TkConstants.DT_ABBREV_DATE_FORMAT);
268 display.append(startDateString);
269 display.append(" - ");
270 String endDateString = weekEnd.minusDays(1).isAfter(endDate) ?
271 endDate.toString(TkConstants.DT_ABBREV_DATE_FORMAT) : weekEnd.minusDays(1).toString(TkConstants.DT_ABBREV_DATE_FORMAT);
272 display.append(endDateString);
273 weekDates.put(weekString, display.toString());
274 if(currentDate.compareTo(actualEndDate) == 0) {
275 dates.add(currentDate.toDate());
276 }
277 weekDateList.put(weekString, dates);
278 dates = new TreeSet<Date>();
279 dates.add(currentDate.toDate());
280 weekStart = currentDate;
281 week++;
282 } else {
283 dates.add(currentDate.toDate());
284 }
285 weekEnd = weekEnd.plusDays(1);
286 afterFirstDay = true;
287 }
288
289
290
291
292 if (!header.isEmpty() && !header.get(header.size() - 1).startsWith("Week")) {
293 if(weekStart.compareTo(endDate) < 0) {
294 StringBuilder display = new StringBuilder();
295
296 String startDateString = weekStart.isBefore(startDate) ?
297 startDate.toString(TkConstants.DT_ABBREV_DATE_FORMAT) : weekStart.toString(TkConstants.DT_ABBREV_DATE_FORMAT);
298 display.append(startDateString);
299 display.append(" - ");
300 String endDateString = actualEndDate.isAfter(endDate) ?
301 endDate.toString(TkConstants.DT_ABBREV_DATE_FORMAT) : actualEndDate.toString(TkConstants.DT_ABBREV_DATE_FORMAT);
302 display.append(endDateString);
303 weekDates.put("Week "+week, display.toString());
304 dates.add(actualEndDate.toDate());
305 weekDateList.put("Week "+week, dates);
306 }
307
308 }
309
310
311 int cnt = 1;
312 for(String key : weekDateList.keySet()) {
313
314 Set<Date> dateList = weekDateList.get(key);
315 Date[] datesArray = new Date[dateList.size()];
316 datesArray = dateList.toArray(datesArray);
317 LocalDateTime sd = new LocalDateTime(datesArray[0].getTime());
318 LocalDateTime ed = new LocalDateTime(datesArray[datesArray.length -1].getTime());
319 if(cnt == 1) {
320 sd = startDate;
321 }
322 if (cnt == weekDateList.size()) {
323 ed = endDate;
324 }
325 List<Map<String, Object>> detailMap = this.getLeaveApprovalDetailSections(principalId, lcdh,sd.toDateTime(), ed.toDateTime(), new ArrayList<Date>(dateList), key, enableWeekDetails);
326 weekDetailMap.put(key, detailMap);
327 cnt++;
328 }
329
330 return header;
331 }
332
333 private Map<String,Set<String>> findTransactionsWithinPeriod(LeaveCalendarDocumentHeader aDoc,
334 CalendarEntry payCalendarEntry) {
335 Map<String,Set<String>> allMessages = new HashMap<String,Set<String>>();
336
337 allMessages.put("actionMessages", new HashSet<String>());
338 allMessages.put("infoMessages", new HashSet<String>());
339 allMessages.put("warningMessages", new HashSet<String>());
340 if(aDoc != null) {
341 allMessages = LeaveCalendarValidationUtil.validatePendingTransactions(aDoc.getPrincipalId(), payCalendarEntry.getBeginPeriodFullDateTime().toLocalDate(), payCalendarEntry.getEndPeriodFullDateTime().toLocalDate());
342 }
343 return allMessages;
344 }
345
346 private Map<String, Set<String>> findWarnings(String principalId, CalendarEntry calendarEntry, List<LeaveBlock> leaveBlocks) {
347
348 Map<String, Set<String>> allMessages= LeaveCalendarValidationUtil.getWarningMessagesForLeaveBlocks(leaveBlocks, calendarEntry.getBeginPeriodDate(), calendarEntry.getEndPeriodDate());
349
350 Map<String, Set<LeaveBlock>> eligibilities;
351 try {
352 eligibilities = LmServiceLocator.getAccrualCategoryMaxBalanceService().getMaxBalanceViolations(calendarEntry, principalId);
353 } catch (Exception e) {
354 eligibilities = null;
355 }
356 if (eligibilities != null) {
357 for (Entry<String,Set<LeaveBlock>> entry : eligibilities.entrySet()) {
358 for(LeaveBlock block : entry.getValue()) {
359 AccrualCategoryRule rule = block.getAccrualCategoryRule();
360 if (rule != null) {
361 AccrualCategory accrualCategory = HrServiceLocator.getAccrualCategoryService().getAccrualCategory(rule.getLmAccrualCategoryId());
362 if (rule.getActionAtMaxBalance().equals(HrConstants.ACTION_AT_MAX_BALANCE.TRANSFER)) {
363
364 allMessages.get("warningMessages").add("Accrual Category '" + accrualCategory.getAccrualCategory() + "' is over max balance.");
365 } else if (rule.getActionAtMaxBalance().equals(HrConstants.ACTION_AT_MAX_BALANCE.LOSE)) {
366
367 allMessages.get("warningMessages").add("Accrual Category '" + accrualCategory.getAccrualCategory() + "' is over max balance.");
368 } else if (rule.getActionAtMaxBalance().equals(HrConstants.ACTION_AT_MAX_BALANCE.PAYOUT)){
369
370 allMessages.get("warningMessages").add("Accrual Category '" + accrualCategory.getAccrualCategory() + "' is over max balance.");
371
372 }
373
374 }
375 }
376 }
377 }
378 return allMessages;
379 }
380
381 @Override
382 public Map<Date, Map<String, BigDecimal>> getEarnCodeLeaveHours(List<LeaveBlock> leaveBlocks, List<Date> leaveSummaryDates) {
383 Map<Date, Map<String, BigDecimal>> earnCodeLeaveHours = new LinkedHashMap<Date, Map<String, BigDecimal>>();
384
385 for (Date leaveSummaryDate : leaveSummaryDates) {
386 earnCodeLeaveHours.put(leaveSummaryDate, new LinkedHashMap<String, BigDecimal>());
387 }
388
389 for (LeaveBlock lb : leaveBlocks) {
390 DateTime leaveDate = lb.getLeaveLocalDate().toDateTimeAtStartOfDay();
391
392 if (earnCodeLeaveHours.get(leaveDate.toDate()) != null) {
393
394 Map<String, BigDecimal> leaveHours = earnCodeLeaveHours.get(leaveDate.toDate());
395
396 BigDecimal amount = lb.getLeaveAmount();
397 String key = lb.getEarnCode() + "|" + lb.getRequestStatus() + "|" + lb.getLeaveBlockType();
398 if (leaveHours.get(key) != null) {
399 amount = leaveHours.get(key).add(lb.getLeaveAmount());
400 }
401
402 leaveHours.put(key, amount);
403 }
404 }
405
406 return earnCodeLeaveHours;
407 }
408
409 @Override
410 public List<Map<String, Object>> getLeaveApprovalDetailSections(LeaveCalendarDocumentHeader lcdh) {
411
412 List<Map<String, Object>> acRows = new ArrayList<Map<String, Object>>();
413
414 if (lcdh == null) {
415 return acRows;
416 }
417
418 String principalId = lcdh.getPrincipalId();
419 CalendarEntry calendarEntry = LmServiceLocator.getLeaveCalendarService().getLeaveCalendarDocument(lcdh.getDocumentId()).getCalendarEntry();
420
421 if(calendarEntry != null) {
422 DateTime beginDate = calendarEntry.getBeginPeriodFullDateTime();
423 DateTime endDate = calendarEntry.getEndPeriodFullDateTime();
424 LeaveSummary leaveSummary;
425 List<Date> leaveSummaryDates = LmServiceLocator.getLeaveSummaryService().getLeaveSummaryDates(calendarEntry);
426 try {
427 leaveSummary = LmServiceLocator.getLeaveSummaryService().getLeaveSummary(principalId, calendarEntry);
428 } catch (Exception e) {
429 leaveSummary = null;
430 }
431 List<LeaveBlock> leaveBlocks = LmServiceLocator.getLeaveBlockService().getLeaveBlocks(principalId, beginDate.toLocalDate(), endDate.toLocalDate());
432 Map<Date, Map<String, BigDecimal>> accrualCategoryLeaveHours = getAccrualCategoryLeaveHours(leaveBlocks, leaveSummaryDates);
433
434
435 PrincipalHRAttributes pha = HrServiceLocator.getPrincipalHRAttributeService().getPrincipalCalendar(principalId, endDate.toLocalDate());
436 if(pha != null) {
437 List<AccrualCategory> acList = HrServiceLocator.getAccrualCategoryService().getActiveAccrualCategoriesForLeavePlan(pha.getLeavePlan(), endDate.toLocalDate());
438 for(AccrualCategory ac : acList) {
439 List<BigDecimal> acDayDetails = new ArrayList<BigDecimal>();
440 Map<String, Object> displayMap = new HashMap<String, Object>();
441 BigDecimal totalAmount = BigDecimal.ZERO;
442 displayMap.put("accrualCategory", ac.getAccrualCategory());
443 int index = 0;
444 for (Date leaveSummaryDate : leaveSummaryDates) {
445 acDayDetails.add(index, null);
446 if (accrualCategoryLeaveHours.get(leaveSummaryDate) != null) {
447 Map<String, BigDecimal> leaveHours = accrualCategoryLeaveHours.get(leaveSummaryDate);
448 if (leaveHours.containsKey(ac.getAccrualCategory())) {
449 BigDecimal amount = leaveHours.get(ac.getAccrualCategory());
450 totalAmount = totalAmount.add(amount);
451 acDayDetails.set(index, amount);
452 }
453 }
454 index++;
455 }
456 LeaveSummaryRow lsr = leaveSummary == null ? null : leaveSummary.getLeaveSummaryRowForAccrualCtgy(ac.getAccrualCategory());
457 displayMap.put("periodUsage", totalAmount);
458 displayMap.put("availableBalance", BigDecimal.ZERO);
459 displayMap.put("availableBalance", lsr == null ? BigDecimal.ZERO : lsr.getLeaveBalance());
460 displayMap.put("daysDetail", acDayDetails);
461 displayMap.put("daysSize", acDayDetails.size());
462 acRows.add(displayMap);
463 }
464 }
465
466 }
467 return acRows;
468 }
469
470 public List<Map<String, Object>> getLeaveApprovalDetailSections(String principalId, LeaveCalendarDocumentHeader lcdh,DateTime beginDate, DateTime endDate, List<Date> leaveSummaryDates, String week, Map<String,Boolean> enableWeekDetails) {
471 List<Map<String, Object>> acRows = new ArrayList<Map<String, Object>>();
472
473
474
475
476 LeaveSummary leaveSummary;
477 PrincipalHRAttributes pha;
478
479 try {
480 leaveSummary = LmServiceLocator.getLeaveSummaryService().getLeaveSummaryAsOfDate(principalId, endDate.toLocalDate());
481 pha = HrServiceLocator.getPrincipalHRAttributeService().getPrincipalCalendar(principalId, endDate.toLocalDate());
482 } catch (Exception e) {
483 leaveSummary = null;
484 pha=null;
485 }
486 List<LeaveBlock> leaveBlocks = LmServiceLocator.getLeaveBlockService().getLeaveBlocks(principalId, beginDate.toLocalDate(), endDate.toLocalDate());
487 Map<Date, Map<String, BigDecimal>> accrualCategoryLeaveHours = getAccrualCategoryLeaveHours(leaveBlocks, leaveSummaryDates);
488
489
490 if(pha != null) {
491 List<AccrualCategory> acList = HrServiceLocator.getAccrualCategoryService().getActiveAccrualCategoriesForLeavePlan(pha.getLeavePlan(), endDate.toLocalDate());
492 for(AccrualCategory ac : acList) {
493 List<BigDecimal> acDayDetails = new ArrayList<BigDecimal>();
494 Map<String, Object> displayMap = new HashMap<String, Object>();
495 BigDecimal totalAmount = BigDecimal.ZERO;
496 displayMap.put("accrualCategory", ac.getAccrualCategory());
497 int index = 0;
498 for (Date leaveSummaryDate : leaveSummaryDates) {
499 if(leaveSummaryDate.compareTo(beginDate.toDate()) >= 0 && leaveSummaryDate.compareTo(endDate.toDate())<=0) {
500 acDayDetails.add(index, null);
501 if (accrualCategoryLeaveHours.get(leaveSummaryDate) != null) {
502 Map<String, BigDecimal> leaveHours = accrualCategoryLeaveHours.get(leaveSummaryDate);
503 if (leaveHours.containsKey(ac.getAccrualCategory())) {
504 BigDecimal amount = leaveHours.get(ac.getAccrualCategory());
505 totalAmount = totalAmount.add(amount);
506 acDayDetails.set(index, amount);
507 }
508 }
509 index++;
510 }
511 }
512 LeaveSummaryRow lsr = leaveSummary == null ? null : leaveSummary.getLeaveSummaryRowForAccrualCtgy(ac.getAccrualCategory());
513 if(!totalAmount.equals(BigDecimal.ZERO)) {
514 enableWeekDetails.put(week, Boolean.TRUE);
515
516 }
517 displayMap.put("periodUsage", totalAmount);
518 displayMap.put("availableBalance", BigDecimal.ZERO);
519 displayMap.put("availableBalance", lsr == null ? BigDecimal.ZERO : lsr.getLeaveBalance());
520 displayMap.put("daysDetail", acDayDetails);
521 displayMap.put("daysSize", acDayDetails.size());
522 acRows.add(displayMap);
523 }
524 }
525 return acRows;
526 }
527
528 @Override
529 public List<Note> getNotesForDocument(String documentNumber) {
530 return KewApiServiceLocator.getNoteService().getNotes(documentNumber);
531 }
532
533 @Override
534 public Map<Date, Map<String, BigDecimal>> getAccrualCategoryLeaveHours(List<LeaveBlock> leaveBlocks, List<Date> leaveSummaryDates) {
535 Map<Date, Map<String, BigDecimal>> accrualCategoryLeaveHours = new LinkedHashMap<Date, Map<String, BigDecimal>>();
536
537 for (Date leaveSummaryDate : leaveSummaryDates) {
538 accrualCategoryLeaveHours.put(leaveSummaryDate, new LinkedHashMap<String, BigDecimal>());
539 }
540
541 for (LeaveBlock lb : leaveBlocks) {
542 DateTime leaveDate = lb.getLeaveLocalDate().toDateTimeAtStartOfDay();
543
544 AccrualCategory ac = lb.getAccrualCategoryObj();
545 if (ac != null && ac.getShowOnGrid().equals("Y")) {
546 if (accrualCategoryLeaveHours.get(leaveDate.toDate()) != null) {
547 Map<String, BigDecimal> leaveHours = accrualCategoryLeaveHours.get(leaveDate.toDate());
548
549 BigDecimal amount = lb.getLeaveAmount();
550 if (leaveHours.get(ac.getAccrualCategory()) != null) {
551 amount = leaveHours.get(ac.getAccrualCategory()).add(lb.getLeaveAmount());
552 }
553
554 leaveHours.put(ac.getAccrualCategory(), amount);
555 }
556 }
557 }
558
559 return accrualCategoryLeaveHours;
560 }
561
562 @Override
563 public void removeNonLeaveEmployees(List<String> principalIds) {
564 if(CollectionUtils.isNotEmpty(principalIds)) {
565 LocalDate asOfDate = LocalDate.now();
566 List<String> idList = new ArrayList<String>();
567 idList.addAll(principalIds);
568 for(String principalId: idList) {
569 boolean leaveFlag = false;
570 List<Assignment> activeAssignments = HrServiceLocator.getAssignmentService().getAssignments(principalId, asOfDate);
571 if(CollectionUtils.isNotEmpty(activeAssignments)) {
572 for(Assignment assignment : activeAssignments) {
573 if(assignment != null && assignment.getJob() != null && assignment.getJob().isEligibleForLeave()) {
574 leaveFlag = true;
575 break;
576 }
577 }
578 if(!leaveFlag) {
579 principalIds.remove(principalId);
580 }
581 }
582 }
583 }
584 }
585
586 @Override
587 public List<String> getLeavePrincipalIdsWithSearchCriteria(List<String> workAreaList, String calendarGroup, LocalDate effdt, LocalDate beginDate, LocalDate endDate) {
588 if (CollectionUtils.isEmpty(workAreaList)) {
589 return new ArrayList<String>();
590 }
591
592 List<String> principalIds = HrServiceLocator.getAssignmentService().getPrincipalIds(workAreaList, effdt, beginDate, endDate);
593 LmServiceLocator.getLeaveApprovalService().removeNonLeaveEmployees(principalIds);
594
595 if(CollectionUtils.isEmpty(principalIds)) {
596 return new ArrayList<String>();
597 }
598
599 List<String> idList = CollectionUtils.isEmpty(principalIds) ?
600 new ArrayList<String> ()
601 : HrServiceLocator.getPrincipalHRAttributeService()
602 .getActiveEmployeesIdForLeaveCalendarAndIdList(calendarGroup, principalIds, endDate);
603
604 return idList;
605 }
606
607 @Override
608 public Map<String, LeaveCalendarDocumentHeader> getPrincipalDocumentHeader(List<String> principalIds, DateTime payBeginDate, DateTime payEndDate) {
609 Map<String, LeaveCalendarDocumentHeader> principalDocumentHeader = new LinkedHashMap<String, LeaveCalendarDocumentHeader>();
610 for (String principalId : principalIds) {
611 LeaveCalendarDocumentHeader lcdh = LmServiceLocator.getLeaveCalendarDocumentHeaderService().getDocumentHeader(principalId, payBeginDate, payEndDate);
612 if(lcdh != null) {
613 principalDocumentHeader.put(principalId, lcdh);
614 }
615 }
616
617 return principalDocumentHeader;
618 }
619
620 @Override
621 public boolean isActiveAssignmentFoundOnJobFlsaStatus(String principalId,
622 String flsaStatus, boolean chkForLeaveEligible) {
623 boolean isActiveAssFound = false;
624 LocalDate asOfDate = LocalDate.now();
625 List<Assignment> activeAssignments = HrServiceLocator
626 .getAssignmentService().getAssignments(principalId, asOfDate);
627 if (activeAssignments != null && !activeAssignments.isEmpty()) {
628 for (Assignment assignment : activeAssignments) {
629 if (assignment != null
630 && assignment.getJob() != null
631 && assignment.getJob().getFlsaStatus() != null
632 && assignment.getJob().getFlsaStatus()
633 .equalsIgnoreCase(flsaStatus)) {
634 if (chkForLeaveEligible) {
635 isActiveAssFound = assignment.getJob()
636 .isEligibleForLeave();
637 if (!isActiveAssFound) {
638 continue;
639 }
640 }
641 isActiveAssFound = true;
642 break;
643 }
644 }
645 }
646 return isActiveAssFound;
647 }
648 }