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