1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.hr.time.approval.service;
17
18 import com.google.common.collect.HashMultimap;
19 import com.google.common.collect.Multimap;
20 import org.apache.commons.collections.CollectionUtils;
21 import org.apache.commons.lang.StringUtils;
22 import org.apache.commons.lang3.time.DateUtils;
23 import org.apache.log4j.Logger;
24 import org.joda.time.*;
25 import org.joda.time.format.DateTimeFormat;
26 import org.joda.time.format.DateTimeFormatter;
27 import org.kuali.hr.lm.LMConstants;
28 import org.kuali.hr.lm.accrual.AccrualCategory;
29 import org.kuali.hr.lm.accrual.AccrualCategoryRule;
30 import org.kuali.hr.lm.leavecalendar.validation.LeaveCalendarValidationUtil;
31 import org.kuali.hr.time.approval.web.ApprovalTimeSummaryRow;
32 import org.kuali.hr.time.assignment.Assignment;
33 import org.kuali.hr.time.assignment.AssignmentDescriptionKey;
34 import org.kuali.hr.time.calendar.Calendar;
35 import org.kuali.hr.time.calendar.CalendarEntries;
36 import org.kuali.hr.time.clocklog.ClockLog;
37 import org.kuali.hr.time.flsa.FlsaDay;
38 import org.kuali.hr.time.flsa.FlsaWeek;
39 import org.kuali.hr.time.person.TKPerson;
40 import org.kuali.hr.time.principal.PrincipalHRAttributes;
41 import org.kuali.hr.time.roles.TkUserRoles;
42 import org.kuali.hr.time.service.base.TkServiceLocator;
43 import org.kuali.hr.time.timeblock.TimeBlock;
44 import org.kuali.hr.time.timesheet.TimesheetDocument;
45 import org.kuali.hr.time.util.*;
46 import org.kuali.hr.time.workarea.WorkArea;
47 import org.kuali.hr.time.workflow.TimesheetDocumentHeader;
48 import org.kuali.rice.kew.api.KewApiServiceLocator;
49 import org.kuali.rice.kew.api.note.Note;
50 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
51 import org.kuali.rice.kew.service.KEWServiceLocator;
52 import org.kuali.rice.krad.util.GlobalVariables;
53 import org.springframework.jdbc.support.rowset.SqlRowSet;
54
55 import java.math.BigDecimal;
56 import java.sql.Types;
57 import java.text.SimpleDateFormat;
58 import java.util.*;
59 import java.util.Map.Entry;
60
61 public class TimeApproveServiceImpl implements TimeApproveService {
62
63 private static final Logger LOG = Logger
64 .getLogger(TimeApproveServiceImpl.class);
65
66 public static final int DAYS_WINDOW_DELTA = 31;
67
68 public Map<String, CalendarEntries> getPayCalendarEntriesForDept(
69 String dept, Date currentDate) {
70 DateTime minDt = new DateTime(currentDate,
71 TKUtils.getSystemDateTimeZone());
72 minDt = minDt.minusDays(DAYS_WINDOW_DELTA);
73 java.sql.Date windowDate = TKUtils.getTimelessDate(minDt.toDate());
74
75 Map<String, CalendarEntries> pceMap = new HashMap<String, CalendarEntries>();
76 Set<String> principals = new HashSet<String>();
77 List<WorkArea> workAreasForDept = TkServiceLocator.getWorkAreaService()
78 .getWorkAreas(dept, new java.sql.Date(currentDate.getTime()));
79
80 for (WorkArea workArea : workAreasForDept) {
81 Long waNum = workArea.getWorkArea();
82 List<Assignment> assignments = TkServiceLocator
83 .getAssignmentService().getActiveAssignmentsForWorkArea(
84 waNum, TKUtils.getTimelessDate(currentDate));
85
86 if (assignments != null) {
87 for (Assignment assignment : assignments) {
88 principals.add(assignment.getPrincipalId());
89 }
90 } else {
91 assignments = TkServiceLocator.getAssignmentService()
92 .getActiveAssignmentsForWorkArea(waNum, windowDate);
93 if (assignments != null) {
94 for (Assignment assignment : assignments) {
95 principals.add(assignment.getPrincipalId());
96 }
97 }
98 }
99 }
100
101
102 Set<Calendar> payCals = new HashSet<Calendar>();
103 for (String pid : principals) {
104 PrincipalHRAttributes pc = TkServiceLocator
105 .getPrincipalHRAttributeService().getPrincipalCalendar(pid,
106 currentDate);
107 if (pc == null)
108 pc = TkServiceLocator.getPrincipalHRAttributeService()
109 .getPrincipalCalendar(pid, windowDate);
110
111 if (pc != null) {
112 payCals.add(pc.getCalendar());
113 } else {
114 LOG.warn("PrincipalCalendar null for principal: '" + pid + "'");
115 }
116 }
117
118
119 for (Calendar pc : payCals) {
120 CalendarEntries pce = TkServiceLocator
121 .getCalendarEntriesService()
122 .getCurrentCalendarEntriesByCalendarId(
123 pc.getHrCalendarId(), currentDate);
124 pceMap.put(pc.getCalendarName(), pce);
125 }
126
127 return pceMap;
128 }
129
130 @Override
131 public Map<String, CalendarEntries> getPayCalendarEntriesForApprover(
132 String principalId, Date currentDate, String dept) {
133 TKUser tkUser = TKContext.getUser();
134
135 Map<String, CalendarEntries> pceMap = new HashMap<String, CalendarEntries>();
136 Set<String> principals = new HashSet<String>();
137 DateTime minDt = new DateTime(currentDate,
138 TKUtils.getSystemDateTimeZone());
139 minDt = minDt.minusDays(DAYS_WINDOW_DELTA);
140 java.sql.Date windowDate = TKUtils.getTimelessDate(minDt.toDate());
141 Set<Long> approverWorkAreas = TkUserRoles.getUserRoles(GlobalVariables.getUserSession().getPrincipalId()).getApproverWorkAreas();
142
143
144 for (Long waNum : approverWorkAreas) {
145 List<Assignment> assignments = TkServiceLocator
146 .getAssignmentService().getActiveAssignmentsForWorkArea(
147 waNum, TKUtils.getTimelessDate(currentDate));
148
149 if (assignments != null) {
150 for (Assignment assignment : assignments) {
151 principals.add(assignment.getPrincipalId());
152 }
153 }
154 }
155
156
157 Set<Calendar> payCals = new HashSet<Calendar>();
158 for (String pid : principals) {
159 PrincipalHRAttributes pc = TkServiceLocator
160 .getPrincipalHRAttributeService().getPrincipalCalendar(pid,
161 currentDate);
162 if (pc == null)
163 pc = TkServiceLocator.getPrincipalHRAttributeService()
164 .getPrincipalCalendar(pid, windowDate);
165
166 if (pc != null) {
167 payCals.add(pc.getCalendar());
168 } else {
169 LOG.warn("PrincipalCalendar null for principal: '" + pid + "'");
170 }
171 }
172
173
174 for (Calendar pc : payCals) {
175 CalendarEntries pce = TkServiceLocator
176 .getCalendarEntriesService()
177 .getCurrentCalendarEntriesByCalendarId(
178 pc.getHrCalendarId(), currentDate);
179 pceMap.put(pc.getCalendarName(), pce);
180 }
181
182 return pceMap;
183 }
184
185 public SortedSet<String> getApproverPayCalendarGroups(Date payBeginDate,
186 Date payEndDate) {
187 SortedSet<String> pcg = new TreeSet<String>();
188
189 TKUser tkUser = TKContext.getUser();
190 Set<Long> approverWorkAreas = TkUserRoles.getUserRoles(GlobalVariables.getUserSession().getPrincipalId()).getApproverWorkAreas();
191 List<Assignment> assignments = new ArrayList<Assignment>();
192
193 for (Long workArea : approverWorkAreas) {
194 if (workArea != null) {
195 assignments.addAll(TkServiceLocator.getAssignmentService()
196 .getActiveAssignmentsForWorkArea(workArea,
197 new java.sql.Date(payBeginDate.getTime())));
198 }
199 }
200 if (!assignments.isEmpty()) {
201 for (Assignment assign : assignments) {
202 String principalId = assign.getPrincipalId();
203 TimesheetDocumentHeader tdh = TkServiceLocator
204 .getTimesheetDocumentHeaderService().getDocumentHeader(
205 principalId, payBeginDate, payEndDate);
206 if (tdh != null) {
207 String pyCalendarGroup = TkServiceLocator
208 .getPrincipalHRAttributeService()
209 .getPrincipalCalendar(principalId, tdh.getBeginDate())
210 .getCalendar().getCalendarName();
211 pcg.add(pyCalendarGroup);
212 }
213 }
214 }
215 return pcg;
216 }
217
218 @SuppressWarnings("rawtypes")
219 @Override
220 public List<ApprovalTimeSummaryRow> getApprovalSummaryRows(
221 Date payBeginDate, Date payEndDate, String calGroup,
222 List<TKPerson> persons, List<String> payCalendarLabels,
223 CalendarEntries payCalendarEntries) {
224 List<ApprovalTimeSummaryRow> rows = new LinkedList<ApprovalTimeSummaryRow>();
225 Map<String, TimesheetDocumentHeader> principalDocumentHeader = getPrincipalDocumehtHeader(
226 persons, payBeginDate, payEndDate);
227
228 Calendar payCalendar = TkServiceLocator.getCalendarService()
229 .getCalendar(payCalendarEntries.getHrCalendarId());
230 DateTimeZone dateTimeZone = TkServiceLocator.getTimezoneService()
231 .getUserTimezoneWithFallback();
232 List<Interval> dayIntervals = TKUtils
233 .getDaySpanForCalendarEntry(payCalendarEntries);
234
235 for (TKPerson person : persons) {
236 TimesheetDocumentHeader tdh = new TimesheetDocumentHeader();
237 String documentId = "";
238 if (principalDocumentHeader.containsKey(person.getPrincipalId())) {
239 tdh = principalDocumentHeader.get(person.getPrincipalId());
240 documentId = principalDocumentHeader.get(
241 person.getPrincipalId()).getDocumentId();
242 }
243 List<TimeBlock> timeBlocks = new ArrayList<TimeBlock>();
244 List<Note> notes = new ArrayList<Note>();
245 List<String> warnings = new ArrayList<String>();
246
247 ApprovalTimeSummaryRow approvalSummaryRow = new ApprovalTimeSummaryRow();
248
249 if (principalDocumentHeader.containsKey(person.getPrincipalId())) {
250 approvalSummaryRow
251 .setApprovalStatus(TkConstants.DOC_ROUTE_STATUS.get(tdh
252 .getDocumentStatus()));
253 }
254
255 if (StringUtils.isNotBlank(documentId)) {
256 timeBlocks = TkServiceLocator.getTimeBlockService()
257 .getTimeBlocks(documentId);
258 notes = getNotesForDocument(documentId);
259 TimesheetDocument td = TkServiceLocator.getTimesheetService().getTimesheetDocument(documentId);
260 warnings = TkServiceLocator.getWarningService().getWarnings(td);
261
262 }
263
264 Map<String, Set<String>> transactionalWarnings = LeaveCalendarValidationUtil.validatePendingTransactions(person.getPrincipalId(), payCalendarEntries.getBeginPeriodDate(), payCalendarEntries.getEndPeriodDate());
265
266 warnings.addAll(transactionalWarnings.get("infoMessages"));
267 warnings.addAll(transactionalWarnings.get("warningMessages"));
268 warnings.addAll(transactionalWarnings.get("actionMessages"));
269
270 Map<String, Set<String>> eligibleTransfers = findWarnings(tdh,payCalendarEntries);
271 warnings.addAll(eligibleTransfers.get("warningMessages"));
272
273 Map<String, BigDecimal> hoursToPayLabelMap = getHoursToPayDayMap(
274 person.getPrincipalId(), payEndDate, payCalendarLabels,
275 timeBlocks, null, payCalendarEntries, payCalendar,
276 dateTimeZone, dayIntervals);
277
278 Map<String, BigDecimal> hoursToFlsaPayLabelMap = getHoursToFlsaWeekMap(
279 person.getPrincipalId(), payEndDate, payCalendarLabels,
280 timeBlocks, null, payCalendarEntries, payCalendar,
281 dateTimeZone, dayIntervals);
282
283 approvalSummaryRow.setName(person.getPrincipalName());
284 approvalSummaryRow.setPrincipalId(person.getPrincipalId());
285 approvalSummaryRow.setPayCalendarGroup(calGroup);
286 approvalSummaryRow.setDocumentId(documentId);
287 approvalSummaryRow.setHoursToPayLabelMap(hoursToPayLabelMap);
288 approvalSummaryRow.setHoursToFlsaPayLabelMap(hoursToFlsaPayLabelMap);
289 approvalSummaryRow.setPeriodTotal(hoursToPayLabelMap
290 .get("Period Total"));
291 approvalSummaryRow.setLstTimeBlocks(timeBlocks);
292 approvalSummaryRow.setNotes(notes);
293 approvalSummaryRow.setWarnings(warnings);
294
295
296
297 ClockLog lastClockLog = TkServiceLocator.getClockLogService()
298 .getLastClockLog(person.getPrincipalId());
299 approvalSummaryRow
300 .setClockStatusMessage(createLabelForLastClockLog(lastClockLog));
301 if (lastClockLog != null
302 && (StringUtils.equals(lastClockLog.getClockAction(),
303 TkConstants.CLOCK_IN) || StringUtils
304 .equals(lastClockLog.getClockAction(),
305 TkConstants.LUNCH_IN))) {
306 DateTime startTime = new DateTime(lastClockLog
307 .getClockTimestamp().getTime());
308 DateTime endTime = new DateTime(System.currentTimeMillis());
309
310 Hours hour = Hours.hoursBetween(startTime, endTime);
311 if (hour != null) {
312 int elapsedHours = hour.getHours();
313 if (elapsedHours >= TkConstants.NUMBER_OF_HOURS_CLOCKED_IN_APPROVE_TAB_HIGHLIGHT) {
314 approvalSummaryRow.setClockedInOverThreshold(true);
315 }
316 }
317
318 }
319 rows.add(approvalSummaryRow);
320 }
321 return rows;
322 }
323
324 public List<TimesheetDocumentHeader> getDocumentHeadersByPrincipalIds(
325 Date payBeginDate, Date payEndDate, List<String> principalIds) {
326 List<TimesheetDocumentHeader> headers = new LinkedList<TimesheetDocumentHeader>();
327 for (String principalId : principalIds) {
328 TimesheetDocumentHeader tdh = TkServiceLocator
329 .getTimesheetDocumentHeaderService().getDocumentHeader(
330 principalId, payBeginDate, payEndDate);
331 if (tdh != null) {
332 headers.add(tdh);
333 }
334 }
335
336 return headers;
337 }
338
339
340
341
342 public List<String> getPayCalendarLabelsForApprovalTab(Date payBeginDate,
343 Date payEndDate) {
344
345
346 List<String> lstPayCalendarLabels = new ArrayList<String>();
347 DateTime payBegin = new DateTime(payBeginDate.getTime());
348 DateTime payEnd = new DateTime(payEndDate.getTime());
349 DateTime currTime = payBegin;
350 int dayCounter = 1;
351 int weekCounter = 1;
352
353 while (currTime.isBefore(payEnd)) {
354 String labelForDay = createLabelForDay(currTime);
355 lstPayCalendarLabels.add(labelForDay);
356 currTime = currTime.plusDays(1);
357 if ((dayCounter % 7) == 0) {
358 lstPayCalendarLabels.add("Week " + weekCounter);
359 weekCounter++;
360 }
361 dayCounter++;
362 }
363 lstPayCalendarLabels.add("Total Hours");
364 return lstPayCalendarLabels;
365 }
366
367 private Map<String, Set<String>> findWarnings(TimesheetDocumentHeader tdh, CalendarEntries calendarEntry) {
368
369 Map<String, Set<String>> allMessages = new HashMap<String,Set<String>>();
370 allMessages.put("warningMessages", new HashSet<String>());
371
372 if (tdh != null) {
373 Map<String, ArrayList<String>> eligibilities;
374 try {
375 eligibilities = TkServiceLocator.getBalanceTransferService().getEligibleTransfers(calendarEntry, tdh.getPrincipalId());
376 } catch (Exception e) {
377 eligibilities = null;
378 }
379 if (eligibilities != null) {
380 for (Entry<String,ArrayList<String>> entry : eligibilities.entrySet()) {
381 for(String accrualRuleId : entry.getValue()) {
382 AccrualCategoryRule rule = TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(accrualRuleId);
383 if (rule != null) {
384 AccrualCategory accrualCategory = TkServiceLocator.getAccrualCategoryService().getAccrualCategory(rule.getLmAccrualCategoryId());
385 if (rule.getActionAtMaxBalance().equals(LMConstants.ACTION_AT_MAX_BAL.TRANSFER)) {
386
387 allMessages.get("warningMessages").add("Accrual Category '" + accrualCategory.getAccrualCategory() + "' is over max balance.");
388 } else if (rule.getActionAtMaxBalance().equals(LMConstants.ACTION_AT_MAX_BAL.LOSE)) {
389
390 allMessages.get("warningMessages").add("Accrual Category '" + accrualCategory.getAccrualCategory() + "' is over max balance.");
391 }
392
393 }
394 }
395 }
396 }
397 Map<String, ArrayList<String>> payoutEligible;
398 try {
399 payoutEligible = TkServiceLocator.getLeavePayoutService().getEligiblePayouts(calendarEntry, tdh.getPrincipalId());
400 } catch (Exception e) {
401 payoutEligible = null;
402 }
403 if (payoutEligible != null) {
404 for (Entry<String,ArrayList<String>> entry : payoutEligible.entrySet()) {
405 for(String accrualRuleId : entry.getValue()) {
406 AccrualCategoryRule rule = TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(accrualRuleId);
407 if (rule != null) {
408 AccrualCategory accrualCategory = TkServiceLocator.getAccrualCategoryService().getAccrualCategory(rule.getLmAccrualCategoryId());
409 allMessages.get("warningMessages").add("Accrual category '" + accrualCategory.getAccrualCategory() + "' is over max balance.");
410 }
411
412 }
413 }
414 }
415 }
416 return allMessages;
417 }
418
419
420
421
422
423
424
425 private String createLabelForDay(DateTime fromDate) {
426 DateMidnight dateMidnight = new DateMidnight(fromDate);
427 if (dateMidnight.compareTo(fromDate) == 0) {
428 DateTimeFormatter fmt = DateTimeFormat.forPattern("MMM/dd");
429 return fmt.print(fromDate);
430 }
431 DateTime toDate = fromDate.plusDays(1);
432 DateTimeFormatter fmt = DateTimeFormat.forPattern("MMM/dd k:m:s");
433 return fmt.print(fromDate) + "-" + fmt.print(toDate);
434 }
435
436
437
438
439
440
441
442 private String createLabelForLastClockLog(ClockLog cl) {
443
444 if (cl == null) {
445 return "No previous clock information";
446 }
447 SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy hh:mm a");
448 String dateTime = sdf.format(new java.sql.Date(cl.getClockTimestamp()
449 .getTime()));
450 if (StringUtils.equals(cl.getClockAction(), TkConstants.CLOCK_IN)) {
451 return "Clocked in since: " + dateTime;
452 } else if (StringUtils.equals(cl.getClockAction(),
453 TkConstants.LUNCH_OUT)) {
454 return "At Lunch since: " + dateTime;
455 } else if (StringUtils
456 .equals(cl.getClockAction(), TkConstants.LUNCH_IN)) {
457 return "Returned from Lunch : " + dateTime;
458 } else if (StringUtils.equals(cl.getClockAction(),
459 TkConstants.CLOCK_OUT)) {
460 return "Clocked out since: " + dateTime;
461 } else {
462 return "No previous clock information";
463 }
464
465 }
466
467 public List<Map<String, Map<String, BigDecimal>>> getHoursByDayAssignmentBuckets(
468 TkTimeBlockAggregate aggregate,
469 List<Assignment> approverAssignments, List<String> payCalendarLabels) {
470 Map<String, Assignment> mappedAssignments = mapAssignmentsByAssignmentKey(approverAssignments);
471 List<List<TimeBlock>> blocksByDay = aggregate.getDayTimeBlockList();
472
473
474 Map<String, List<BigDecimal>> approverHours = new HashMap<String, List<BigDecimal>>();
475 Map<String, List<BigDecimal>> otherHours = new HashMap<String, List<BigDecimal>>();
476 for (int day = 0; day < blocksByDay.size(); day++) {
477 List<TimeBlock> dayBlocks = blocksByDay.get(day);
478 for (TimeBlock block : dayBlocks) {
479 List<BigDecimal> hours;
480
481 if (mappedAssignments.containsKey(block.getAssignmentKey())) {
482 hours = approverHours.get(block.getAssignmentKey());
483 if (hours == null) {
484 hours = new ArrayList<BigDecimal>();
485 approverHours.put(block.getAssignmentKey(), hours);
486 }
487 } else {
488 hours = otherHours.get(block.getAssignmentKey());
489 if (hours == null) {
490 hours = new ArrayList<BigDecimal>();
491 otherHours.put(block.getAssignmentKey(), hours);
492 }
493 }
494
495
496 for (int fill = hours.size(); fill <= day; fill++) {
497 hours.add(TkConstants.BIG_DECIMAL_SCALED_ZERO);
498 }
499
500
501 BigDecimal timeToAdd = hours.get(day);
502 timeToAdd = timeToAdd.add(block.getHours(),
503 TkConstants.MATH_CONTEXT);
504 hours.set(day, timeToAdd);
505 }
506 }
507
508
509
510
511 Map<String, Map<String, BigDecimal>> approverAssignToPayHourTotals = new HashMap<String, Map<String, BigDecimal>>();
512 Map<String, Map<String, BigDecimal>> otherAssignToPayHourTotals = new HashMap<String, Map<String, BigDecimal>>();
513
514
515 generateSummaries(approverAssignToPayHourTotals, approverHours,
516 payCalendarLabels);
517 generateSummaries(otherAssignToPayHourTotals, otherHours,
518 payCalendarLabels);
519
520
521 List<Map<String, Map<String, BigDecimal>>> returnTuple = new ArrayList<Map<String, Map<String, BigDecimal>>>(
522 2);
523 returnTuple.add(approverAssignToPayHourTotals);
524 returnTuple.add(otherAssignToPayHourTotals);
525
526 return returnTuple;
527 }
528
529
530 private void generateSummaries(
531 Map<String, Map<String, BigDecimal>> payHourTotals,
532 Map<String, List<BigDecimal>> assignmentToHours,
533 List<String> payCalendarLabels) {
534 for (String key : assignmentToHours.keySet()) {
535
536 Map<String, BigDecimal> hoursToPayLabelMap = new LinkedHashMap<String, BigDecimal>();
537 List<BigDecimal> dayTotals = assignmentToHours.get(key);
538 int dayCount = 0;
539 BigDecimal weekTotal = new BigDecimal(0.00);
540 BigDecimal periodTotal = new BigDecimal(0.00);
541 for (String payCalendarLabel : payCalendarLabels) {
542 if (StringUtils.contains(payCalendarLabel, "Week")) {
543 hoursToPayLabelMap.put(payCalendarLabel, weekTotal);
544 weekTotal = new BigDecimal(0.00);
545 } else if (StringUtils
546 .contains(payCalendarLabel, "Total Hours")) {
547 hoursToPayLabelMap.put(payCalendarLabel, periodTotal);
548 } else {
549 BigDecimal dayTotal = TkConstants.BIG_DECIMAL_SCALED_ZERO;
550 if (dayCount < dayTotals.size())
551 dayTotal = dayTotals.get(dayCount);
552
553 hoursToPayLabelMap.put(payCalendarLabel, dayTotal);
554 weekTotal = weekTotal.add(dayTotal,
555 TkConstants.MATH_CONTEXT);
556 periodTotal = periodTotal.add(dayTotal);
557 dayCount++;
558 }
559 }
560 payHourTotals.put(key, hoursToPayLabelMap);
561 }
562 }
563
564 private Map<String, Assignment> mapAssignmentsByAssignmentKey(
565 List<Assignment> assignments) {
566 Map<String, Assignment> assignmentMap = new HashMap<String, Assignment>();
567 for (Assignment assignment : assignments) {
568 assignmentMap
569 .put(AssignmentDescriptionKey
570 .getAssignmentKeyString(assignment), assignment);
571 }
572 return assignmentMap;
573 }
574
575
576
577
578 @Override
579 public Map<String, BigDecimal> getHoursToPayDayMap(String principalId,
580 Date payEndDate, List<String> payCalendarLabels,
581 List<TimeBlock> lstTimeBlocks, Long workArea,
582 CalendarEntries payCalendarEntries, Calendar payCalendar,
583 DateTimeZone dateTimeZone, List<Interval> dayIntervals) {
584 Map<String, BigDecimal> hoursToPayLabelMap = new LinkedHashMap<String, BigDecimal>();
585 List<BigDecimal> dayTotals = new ArrayList<BigDecimal>();
586
587 TkTimeBlockAggregate tkTimeBlockAggregate = new TkTimeBlockAggregate(
588 lstTimeBlocks, payCalendarEntries, payCalendar, true,
589 dayIntervals);
590 List<FlsaWeek> flsaWeeks = tkTimeBlockAggregate
591 .getFlsaWeeks(dateTimeZone);
592 for (FlsaWeek week : flsaWeeks) {
593 for (FlsaDay day : week.getFlsaDays()) {
594 BigDecimal total = new BigDecimal(0.00);
595 for (TimeBlock tb : day.getAppliedTimeBlocks()) {
596 if (workArea != null) {
597 if (tb.getWorkArea().compareTo(workArea) == 0) {
598 total = total.add(tb.getHours(),
599 TkConstants.MATH_CONTEXT);
600 } else {
601 total = total.add(new BigDecimal("0"),
602 TkConstants.MATH_CONTEXT);
603 }
604 } else {
605 total = total.add(tb.getHours(),
606 TkConstants.MATH_CONTEXT);
607 }
608 }
609 dayTotals.add(total);
610 }
611 }
612
613 int dayCount = 0;
614 BigDecimal weekTotal = new BigDecimal(0.00);
615 BigDecimal periodTotal = new BigDecimal(0.00);
616 for (String payCalendarLabel : payCalendarLabels) {
617 if (StringUtils.contains(payCalendarLabel, "Week")) {
618 hoursToPayLabelMap.put(payCalendarLabel, weekTotal);
619 weekTotal = new BigDecimal(0.00);
620 } else if (StringUtils.contains(payCalendarLabel, "Period Total")) {
621 hoursToPayLabelMap.put(payCalendarLabel, periodTotal);
622 } else {
623 if(dayCount < dayTotals.size()) {
624 hoursToPayLabelMap.put(payCalendarLabel,
625 dayTotals.get(dayCount));
626 weekTotal = weekTotal.add(dayTotals.get(dayCount),
627 TkConstants.MATH_CONTEXT);
628 periodTotal = periodTotal.add(dayTotals.get(dayCount));
629 dayCount++;
630 }
631
632 }
633
634 }
635 return hoursToPayLabelMap;
636 }
637
638
639
640
641 @Override
642 public Map<String, BigDecimal> getHoursToFlsaWeekMap(String principalId,
643 Date payEndDate, List<String> payCalendarLabels,
644 List<TimeBlock> lstTimeBlocks, Long workArea,
645 CalendarEntries payCalendarEntries, Calendar payCalendar,
646 DateTimeZone dateTimeZone, List<Interval> dayIntervals) {
647
648 Map<String, BigDecimal> hoursToFlsaWeekMap = new LinkedHashMap<String, BigDecimal>();
649
650 TkTimeBlockAggregate tkTimeBlockAggregate = new TkTimeBlockAggregate(lstTimeBlocks, payCalendarEntries, payCalendar, true, dayIntervals);
651 List<List<FlsaWeek>> flsaWeeks = tkTimeBlockAggregate.getFlsaWeeks(dateTimeZone, principalId);
652
653 int weekCount = 1;
654 for (List<FlsaWeek> flsaWeekParts : flsaWeeks) {
655 BigDecimal weekTotal = new BigDecimal(0.00);
656 for (FlsaWeek flsaWeekPart : flsaWeekParts) {
657 for (FlsaDay flsaDay : flsaWeekPart.getFlsaDays()) {
658 for (TimeBlock timeBlock : flsaDay.getAppliedTimeBlocks()) {
659 if (workArea != null) {
660 if (timeBlock.getWorkArea().compareTo(workArea) == 0) {
661 weekTotal = weekTotal.add(timeBlock.getHours(), TkConstants.MATH_CONTEXT);
662 } else {
663 weekTotal = weekTotal.add(new BigDecimal("0"), TkConstants.MATH_CONTEXT);
664 }
665 } else {
666 weekTotal = weekTotal.add(timeBlock.getHours(),TkConstants.MATH_CONTEXT);
667 }
668 }
669 }
670 }
671 hoursToFlsaWeekMap.put("Week " + weekCount++, weekTotal);
672 }
673
674 return hoursToFlsaWeekMap;
675 }
676
677 public boolean doesApproverHavePrincipalsForCalendarGroup(Date asOfDate,
678 String calGroup) {
679 TKUser tkUser = TKContext.getUser();
680 Set<Long> approverWorkAreas = TkUserRoles.getUserRoles(GlobalVariables.getUserSession().getPrincipalId()).getApproverWorkAreas();
681 for (Long workArea : approverWorkAreas) {
682 List<Assignment> assignments = TkServiceLocator
683 .getAssignmentService().getActiveAssignmentsForWorkArea(
684 workArea, new java.sql.Date(asOfDate.getTime()));
685 List<String> principalIds = new ArrayList<String>();
686 for (Assignment assign : assignments) {
687 if (principalIds.contains(assign.getPrincipalId())) {
688 continue;
689 }
690 principalIds.add(assign.getPrincipalId());
691 }
692
693 for (String principalId : principalIds) {
694 PrincipalHRAttributes principalCal = TkServiceLocator
695 .getPrincipalHRAttributeService().getPrincipalCalendar(
696 principalId, asOfDate);
697 if (StringUtils.equals(principalCal.getPayCalendar(),
698 calGroup)) {
699 return true;
700 }
701 }
702 }
703 return false;
704 }
705
706 @Override
707 public List<Note> getNotesForDocument(String documentNumber) {
708 return KewApiServiceLocator.getNoteService().getNotes(documentNumber);
709 }
710
711 @Override
712 public List<String> getTimePrincipalIdsWithSearchCriteria(List<String> workAreaList, String calendarGroup, java.sql.Date effdt, java.sql.Date beginDate, java.sql.Date endDate) {
713 if (CollectionUtils.isEmpty(workAreaList)) {
714 return new ArrayList<String>();
715 }
716 List<Assignment> assignmentList = TkServiceLocator.getAssignmentService().getAssignments(workAreaList, effdt, beginDate, endDate);
717 List<Assignment> tempList = this.removeNoTimeAssignment(assignmentList);
718 Set<String> pids = new HashSet<String>();
719 for(Assignment anAssignment : tempList) {
720 if(anAssignment != null) {
721 pids.add(anAssignment.getPrincipalId());
722 }
723 }
724 List<String> ids = new ArrayList<String>();
725 ids.addAll(pids);
726
727 if(CollectionUtils.isEmpty(ids)) {
728 return new ArrayList<String>();
729 }
730
731 List<String> idList = TkServiceLocator.getPrincipalHRAttributeService()
732 .getActiveEmployeesIdForTimeCalendarAndIdList(calendarGroup, ids, endDate);
733 if(CollectionUtils.isEmpty(idList)) {
734 return new ArrayList<String>();
735 }
736 return idList;
737 }
738
739 private List<Assignment> removeNoTimeAssignment(List<Assignment> assignmentList) {
740 List<Assignment> results = new ArrayList<Assignment>();
741 if(CollectionUtils.isNotEmpty(assignmentList)) {
742 for(Assignment anAssignment: assignmentList) {
743 if(anAssignment != null
744 && anAssignment.getJob() != null
745 && anAssignment.getJob().getFlsaStatus() != null
746 && anAssignment.getJob().getFlsaStatus().equalsIgnoreCase(TkConstants.FLSA_STATUS_NON_EXEMPT)) {
747 results.add(anAssignment);
748 }
749 }
750 }
751 return results;
752 }
753
754 @Override
755 public Map<String, TimesheetDocumentHeader> getPrincipalDocumehtHeader(
756 List<TKPerson> persons, Date payBeginDate, Date payEndDate) {
757 Map<String, TimesheetDocumentHeader> principalDocumentHeader = new LinkedHashMap<String, TimesheetDocumentHeader>();
758 for (TKPerson person : persons) {
759 String principalId = person.getPrincipalId();
760
761 TimesheetDocumentHeader tdh = TkServiceLocator.getTimesheetDocumentHeaderService().getDocumentHeader(principalId, payBeginDate, DateUtils.addMilliseconds(payEndDate, 1));
762 if(tdh != null) {
763 principalDocumentHeader.put(principalId, tdh);
764 }
765 }
766 return principalDocumentHeader;
767 }
768
769 @Override
770 public Multimap<String, Long> getDeptWorkAreasByWorkAreas(
771 Set<Long> approverWorkAreas) {
772 Multimap<String, Long> deptWorkAreas = HashMultimap.create();
773
774 if (approverWorkAreas.size() > 0) {
775
776 StringBuilder workAreas = new StringBuilder();
777 for (Long workarea : approverWorkAreas) {
778 if(workarea != null) {
779 workAreas.append("work_area = " + workarea + " or ");
780 }
781 }
782 String workAreasForQuery = workAreas.substring(0,
783 workAreas.length() - 3);
784 String sql = "SELECT DISTINCT work_area, dept FROM tk_work_area_t "
785 + "WHERE " + workAreasForQuery + " AND effdt <= ?";
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801 SqlRowSet rs = TkServiceLocator.getTkJdbcTemplate().queryForRowSet(
802 sql, new Object[] { TKUtils.getCurrentDate() },
803 new int[] { Types.DATE });
804 while (rs.next()) {
805 deptWorkAreas
806 .put(rs.getString("dept"), rs.getLong("work_area"));
807 }
808 }
809 return deptWorkAreas;
810 }
811
812 @Override
813 public Multimap<String, Long> getDeptWorkAreasByDepts(Set<String> userDepts) {
814 Multimap<String, Long> deptWorkAreas = HashMultimap.create();
815
816 if (userDepts.size() > 0) {
817
818 StringBuilder depts = new StringBuilder();
819 for (String dept : userDepts) {
820 depts.append("dept = '" + dept + "' or ");
821 }
822 String deptsForQuery = depts.substring(0, depts.length() - 4);
823 String sql = "SELECT DISTINCT work_area, dept FROM tk_work_area_t "
824 + "WHERE " + deptsForQuery + " AND effdt <= ?";
825
826 SqlRowSet rs = TkServiceLocator.getTkJdbcTemplate().queryForRowSet(
827 sql, new Object[] { TKUtils.getCurrentDate() },
828 new int[] { Types.DATE });
829 while (rs.next()) {
830 deptWorkAreas
831 .put(rs.getString("dept"), rs.getLong("work_area"));
832 }
833 }
834 return deptWorkAreas;
835 }
836
837 public DocumentRouteHeaderValue getRouteHeader(String documentId) {
838 return KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentId);
839 }
840
841 @Override
842 public List<CalendarEntries> getAllPayCalendarEntriesForApprover(String principalId, Date currentDate) {
843 TKUser tkUser = TKContext.getUser();
844 Set<String> principals = new HashSet<String>();
845 DateTime minDt = new DateTime(currentDate,
846 TKUtils.getSystemDateTimeZone());
847 minDt = minDt.minusDays(DAYS_WINDOW_DELTA);
848 Set<Long> approverWorkAreas = TkUserRoles.getUserRoles(GlobalVariables.getUserSession().getPrincipalId()).getApproverWorkAreas();
849
850
851 for (Long waNum : approverWorkAreas) {
852 List<Assignment> assignments = TkServiceLocator
853 .getAssignmentService().getActiveAssignmentsForWorkArea(waNum, TKUtils.getTimelessDate(currentDate));
854
855 if (assignments != null) {
856 for (Assignment assignment : assignments) {
857 principals.add(assignment.getPrincipalId());
858 }
859 }
860 }
861 List<TimesheetDocumentHeader> documentHeaders = new ArrayList<TimesheetDocumentHeader>();
862 for(String pid : principals) {
863 documentHeaders.addAll(TkServiceLocator.getTimesheetDocumentHeaderService().getDocumentHeadersForPrincipalId(pid));
864 }
865 Set<CalendarEntries> payPeriodSet = new HashSet<CalendarEntries>();
866 for(TimesheetDocumentHeader tdh : documentHeaders) {
867 CalendarEntries pe = TkServiceLocator.getCalendarEntriesService().getCalendarEntriesByBeginAndEndDate(tdh.getBeginDate(), tdh.getEndDate());
868 if(pe != null) {
869 payPeriodSet.add(pe);
870 }
871 }
872 List<CalendarEntries> ppList = new ArrayList<CalendarEntries>(payPeriodSet);
873
874 return ppList;
875 }
876
877 }