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