1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.kpme.core.assignment.service;
17
18 import org.apache.commons.collections.CollectionUtils;
19 import org.apache.commons.collections.MapUtils;
20 import org.apache.commons.lang.StringUtils;
21 import org.apache.log4j.Logger;
22 import org.joda.time.DateTime;
23 import org.joda.time.Days;
24 import org.joda.time.DurationFieldType;
25 import org.joda.time.LocalDate;
26 import org.kuali.kpme.core.api.assignment.Assignment;
27 import org.kuali.kpme.core.api.assignment.AssignmentDescriptionKey;
28 import org.kuali.kpme.core.api.assignment.service.AssignmentService;
29 import org.kuali.kpme.core.api.calendar.entry.CalendarEntry;
30 import org.kuali.kpme.core.api.job.JobContract;
31 import org.kuali.kpme.core.api.namespace.KPMENamespace;
32 import org.kuali.kpme.core.api.task.TaskContract;
33 import org.kuali.kpme.core.api.util.KpmeUtils;
34 import org.kuali.kpme.core.api.workarea.WorkArea;
35 import org.kuali.kpme.core.assignment.AssignmentBo;
36 import org.kuali.kpme.core.assignment.dao.AssignmentDao;
37 import org.kuali.kpme.core.job.JobBo;
38 import org.kuali.kpme.core.role.KPMERole;
39 import org.kuali.kpme.core.service.HrServiceLocator;
40 import org.kuali.kpme.core.task.TaskBo;
41 import org.kuali.kpme.core.util.HrConstants;
42 import org.kuali.kpme.core.util.TKUtils;
43 import org.kuali.kpme.core.workarea.WorkAreaBo;
44 import org.kuali.rice.core.api.config.property.ConfigContext;
45 import org.kuali.rice.core.api.mo.ModelObjectUtils;
46 import org.kuali.rice.core.api.util.type.KualiDecimal;
47 import org.kuali.rice.kim.api.role.RoleService;
48 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
49
50 import java.util.*;
51
52 public class AssignmentServiceImpl implements AssignmentService {
53
54 private static final Logger LOG = Logger.getLogger(AssignmentServiceImpl.class);
55 private AssignmentDao assignmentDao;
56
57 public void setAssignmentDao(AssignmentDao assignmentDao) {
58 this.assignmentDao = assignmentDao;
59 }
60
61 protected List<Assignment> convertToImmutable(List<AssignmentBo> bos) {
62 return ModelObjectUtils.transform(bos, AssignmentBo.toAssignment);
63 }
64
65
66 @Override
67 public List<Assignment> getAssignments(String principalId, LocalDate asOfDate) {
68 List<Assignment> assigns = new ArrayList<Assignment>();
69 if (asOfDate == null) {
70 asOfDate = LocalDate.now();
71 }
72
73 List<AssignmentBo> assignments = assignmentDao.findAssignments(principalId, asOfDate);
74
75 for (AssignmentBo assignment : assignments) {
76 assigns.add(AssignmentBo.to(populateAssignment(assignment, asOfDate)));
77 }
78
79 return assigns;
80 }
81
82
83 public List<Assignment> getAssignments(String principalId, LocalDate beginDate, LocalDate endDate) {
84 List<AssignmentBo> assignments = assignmentDao.findAssignmentsWithinPeriod(principalId, beginDate, endDate);
85 List<Assignment> assigns = new ArrayList<Assignment>();
86 for (AssignmentBo assignment : assignments) {
87 assigns.add(AssignmentBo.to(populateAssignment(assignment, assignment.getEffectiveLocalDate())));
88 }
89
90 return assigns;
91 }
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120 public List<Assignment> getAssignmentsByPayEntry(String principalId, CalendarEntry payCalendarEntry) {
121 DateTime entryEndDate = payCalendarEntry.getEndPeriodLocalDateTime().toDateTime();
122 if (entryEndDate.getHourOfDay() == 0) {
123 entryEndDate = entryEndDate.minusDays(1);
124 }
125 List<Assignment> beginPeriodAssign = getAssignments(principalId, payCalendarEntry.getBeginPeriodFullDateTime().toLocalDate());
126 List<Assignment> endPeriodAssign = getAssignments(principalId, entryEndDate.toLocalDate());
127 List<Assignment> assignsWithPeriod = getAssignments(principalId, payCalendarEntry.getBeginPeriodFullDateTime().toLocalDate(), entryEndDate.toLocalDate());
128
129 List<Assignment> finalAssignments = new ArrayList<Assignment>();
130 Map<String, Assignment> assignKeyToAssignmentMap = new HashMap<String, Assignment>();
131 for (Assignment assign : endPeriodAssign) {
132 assignKeyToAssignmentMap.put(AssignmentDescriptionKey.getAssignmentKeyString(assign), assign);
133 finalAssignments.add(assign);
134 }
135
136
137 for (Assignment assign : beginPeriodAssign) {
138 String assignKey = AssignmentDescriptionKey.getAssignmentKeyString(assign);
139 if (!assignKeyToAssignmentMap.containsKey(assignKey)) {
140 finalAssignments.add(assign);
141 }
142 }
143
144
145 for (Assignment assign : assignsWithPeriod) {
146 String assignKey = AssignmentDescriptionKey.getAssignmentKeyString(assign);
147 if (!assignKeyToAssignmentMap.containsKey(assignKey)) {
148 finalAssignments.add(assign);
149 }
150 }
151
152 return finalAssignments;
153
154 }
155
156 public Map<LocalDate, List<Assignment>> getAssignmentsByCalEntryForTimeCalendar(String principalId, CalendarEntry payCalendarEntry){
157 if (StringUtils.isEmpty(principalId)
158 || payCalendarEntry == null) {
159 return Collections.emptyMap();
160 }
161
162 return getAssignmentHistoryBetweenDaysInternal(principalId, payCalendarEntry.getBeginPeriodFullDateTime().toLocalDate(), payCalendarEntry.getEndPeriodFullDateTime().toLocalDate(), HrConstants.FLSA_STATUS_NON_EXEMPT, false);
163 }
164
165 public List<Assignment> getAllAssignmentsByCalEntryForTimeCalendar(String principalId, CalendarEntry payCalendarEntry){
166 Map<LocalDate, List<Assignment>> history = getAssignmentsByCalEntryForTimeCalendar(principalId, payCalendarEntry);
167 return KpmeUtils.getUniqueAssignments(history);
168 }
169
170 public Map<LocalDate, List<Assignment>> getAssignmentsByCalEntryForLeaveCalendar(String principalId, CalendarEntry payCalendarEntry){
171 if (StringUtils.isEmpty(principalId)
172 || payCalendarEntry == null) {
173 return Collections.emptyMap();
174 }
175 return getAssignmentHistoryBetweenDaysInternal(principalId, payCalendarEntry.getBeginPeriodFullDateTime().toLocalDate(), payCalendarEntry.getEndPeriodFullDateTime().toLocalDate(), null, true);
176 }
177
178 public List<Assignment> getAllAssignmentsByCalEntryForLeaveCalendar(String principalId, CalendarEntry payCalendarEntry){
179 Map<LocalDate, List<Assignment>> history = getAssignmentsByCalEntryForLeaveCalendar(principalId, payCalendarEntry);
180 return KpmeUtils.getUniqueAssignments(history);
181 }
182
183 public List<Assignment> filterAssignments(List<Assignment> assignments, String flsaStatus, boolean chkForLeaveEligible) {
184 List<Assignment> results = new ArrayList<Assignment>();
185 for(Assignment assignment : assignments) {
186 boolean flag = false;
187 if(StringUtils.isNotEmpty(flsaStatus)) {
188 if(assignment != null
189 && assignment.getJob() != null
190 && assignment.getJob().getFlsaStatus() != null
191 && assignment.getJob().getFlsaStatus().equalsIgnoreCase(flsaStatus)) {
192 if(chkForLeaveEligible) {
193 if(assignment.getJob().isEligibleForLeave()) {
194 flag = true;
195 }
196 }else {
197 flag = true;
198 }
199 }
200 }else {
201 if(chkForLeaveEligible) {
202 if(assignment != null && assignment.getJob() != null && assignment.getJob().isEligibleForLeave()) {
203 flag = true;
204 }
205 } else {
206 flag = true;
207 }
208 }
209
210 if(flag) {
211 results.add(assignment);
212 }
213 }
214
215 return results;
216
217 }
218
219 @Override
220 public AssignmentDescriptionKey getAssignmentDescriptionKey(String assignmentKey) {
221 return AssignmentDescriptionKey.get(assignmentKey);
222 }
223
224 @Override
225 public Map<String, String> getAssignmentDescriptions(Assignment assignment) {
226 Map<String, String> assignmentDescriptions = new LinkedHashMap<String, String>();
227 if (assignment == null) {
228 LOG.warn("Assignment is null");
229
230 } else {
231 assignmentDescriptions.putAll(TKUtils.formatAssignmentDescription(assignment));
232 }
233 return assignmentDescriptions;
234
235 }
236
237 @Override
238 public Assignment getAssignment(String tkAssignmentId) {
239 return AssignmentBo.to(assignmentDao.getAssignment(tkAssignmentId));
240 }
241
242
243 @Override
244 public List<Assignment> getActiveAssignmentsForWorkArea(Long workArea, LocalDate asOfDate) {
245 List<AssignmentBo> assignments = assignmentDao.getActiveAssignmentsInWorkArea(workArea, asOfDate);
246 List<Assignment> assigns = new ArrayList<Assignment>(assignments.size());
247 for (AssignmentBo assignment : assignments) {
248 assigns.add(AssignmentBo.to(populateAssignment(assignment, asOfDate)));
249 }
250 return assigns;
251 }
252
253 @Override
254 public List<String> getPrincipalIdsInActiveAssignmentsForWorkArea(Long workArea, LocalDate asOfDate) {
255 List<AssignmentBo> assignments = assignmentDao.getActiveAssignmentsInWorkArea(workArea, asOfDate);
256 Set<String> principalIds = new HashSet<String>();
257 for (AssignmentBo assignment : assignments) {
258 principalIds.add(assignment.getPrincipalId());
259 }
260 return new ArrayList<String>(principalIds);
261 }
262
263 @Override
264 public List<String> getPrincipalIdsInActiveAssignmentsForWorkAreas(List<Long> workAreas, LocalDate asOfDate) {
265 if (org.springframework.util.CollectionUtils.isEmpty(workAreas)) {
266 return Collections.emptyList();
267 }
268 List<AssignmentBo> assignments = assignmentDao.getActiveAssignmentsInWorkAreas(workAreas, asOfDate);
269 Set<String> principalIds = new HashSet<String>();
270 for (AssignmentBo assignment : assignments) {
271 principalIds.add(assignment.getPrincipalId());
272 }
273 return new ArrayList<String>(principalIds);
274 }
275
276 @Override
277 public List<Assignment> getActiveAssignments(LocalDate asOfDate) {
278 return convertToImmutable(assignmentDao.getActiveAssignments(asOfDate));
279 }
280
281 protected AssignmentBo populateAssignment(AssignmentBo assignment, LocalDate asOfDate) {
282 assignment.setJob(JobBo.from(HrServiceLocator.getJobService().getJob(assignment.getPrincipalId(), assignment.getJobNumber(), asOfDate)));
283 assignment.setWorkAreaObj(WorkAreaBo.from(HrServiceLocator.getWorkAreaService().getWorkArea(assignment.getWorkArea(), asOfDate)));
284 assignment.setTaskObj(TaskBo.from(HrServiceLocator.getTaskService().getTask(assignment.getTask(), asOfDate)));
285 assignment.populateAssignmentDescription(asOfDate);
286 return assignment;
287 }
288
289 public Assignment getAssignment(String principalId, AssignmentDescriptionKey key, LocalDate asOfDate) {
290 AssignmentBo a = null;
291
292 if (key != null) {
293 a = assignmentDao.getAssignment(principalId, key.getGroupKeyCode(), key.getJobNumber(), key.getWorkArea(), key.getTask(), asOfDate);
294 }
295 if (a != null) {
296 a = populateAssignment(a, asOfDate);
297 }
298
299 return AssignmentBo.to(a);
300 }
301
302 @Override
303 public Assignment getAssignmentForTargetPrincipal(AssignmentDescriptionKey key, LocalDate asOfDate) {
304 AssignmentBo a = null;
305
306 if (key != null) {
307 a = assignmentDao.getAssignmentForTargetPrincipal(key.getGroupKeyCode(), key.getJobNumber(), key.getWorkArea(), key.getTask(), asOfDate);
308 }
309
310 return AssignmentBo.to(a);
311 }
312
313
314
315
316
317 @Override
318 public List<Assignment> getActiveAssignmentsForJob(String principalId, Long jobNumber, LocalDate asOfDate) {
319 List<AssignmentBo> assignments = assignmentDao.getActiveAssignmentsForJob(principalId, jobNumber, asOfDate);
320
321 return convertToImmutable(assignments);
322 }
323
324 @Override
325 public Map<String, String> getAssignmentDescriptionsForAssignments(List<Assignment> assignments) {
326 Map<String, String> assignmentDescriptions = new LinkedHashMap<String, String>();
327 for (Assignment assignment : assignments) {
328 assignmentDescriptions.putAll(TKUtils.formatAssignmentDescription(assignment));
329 }
330 return assignmentDescriptions;
331 }
332
333 @Override
334 public Assignment getAssignment(List<Assignment> assignments, String assignmentKey, LocalDate beginDate) {
335 AssignmentDescriptionKey desc = getAssignmentDescriptionKey(assignmentKey);
336 if (CollectionUtils.isNotEmpty(assignments)) {
337 for (Assignment assignment : assignments) {
338 if (assignment.getJobNumber().compareTo(desc.getJobNumber()) == 0 &&
339 assignment.getWorkArea().compareTo(desc.getWorkArea()) == 0 &&
340 assignment.getTask().compareTo(desc.getTask()) == 0) {
341 return assignment;
342 }
343 }
344 }
345
346
347 Assignment assign = getAssignmentForTargetPrincipal(desc, beginDate);
348 if (assign != null) {
349 return assign;
350 }
351
352 LOG.warn("no matched assignment found");
353 return null;
354 }
355
356 @Override
357 public Assignment getMaxTimestampAssignment(String principalId) {
358 return AssignmentBo.to(assignmentDao.getMaxTimestampAssignment(principalId));
359 }
360
361 public List<String> getPrincipalIds(List<String> workAreaList, LocalDate effdt, LocalDate startDate, LocalDate endDate) {
362 if (CollectionUtils.isEmpty(workAreaList)) {
363 return new ArrayList<String>();
364 }
365 return assignmentDao.getPrincipalIds(workAreaList, effdt, startDate, endDate);
366 }
367
368 public List<Assignment> getAssignments(List<String> workAreaList, LocalDate effdt, LocalDate startDate, LocalDate endDate) {
369 if (CollectionUtils.isEmpty(workAreaList)) {
370 return Collections.emptyList();
371 }
372 return convertToImmutable(assignmentDao.getAssignments(workAreaList, effdt, startDate, endDate));
373 }
374
375 @Override
376 public String getAssignmentDescription(String principalId, String groupKeyCode, Long jobNumber, Long workArea, Long task, LocalDate asOfDate) {
377 StringBuilder builder = new StringBuilder();
378
379 if (jobNumber != null && workArea != null && task != null) {
380 JobContract jobObj = HrServiceLocator.getJobService().getJob(principalId, jobNumber, asOfDate);
381 WorkArea workAreaObj = HrServiceLocator.getWorkAreaService().getWorkArea(workArea, asOfDate);
382 TaskContract taskObj = HrServiceLocator.getTaskService().getTask(task, asOfDate);
383
384 String workAreaDescription = workAreaObj != null ? workAreaObj.getDescription() : StringUtils.EMPTY;
385 KualiDecimal compensationRate = jobObj != null ? jobObj.getCompRate() : KualiDecimal.ZERO;
386 String department = jobObj != null ? jobObj.getDept() : StringUtils.EMPTY;
387 String taskDescription = taskObj != null && !HrConstants.TASK_DEFAULT_DESP.equals(taskObj.getDescription()) ? taskObj.getDescription() : StringUtils.EMPTY;
388
389 builder.append(workAreaDescription).append(" : $").append(compensationRate).append(" Rcd ").append(jobNumber).append(" ").append(department);
390 if (StringUtils.isNotBlank(taskDescription)) {
391 builder.append(" ").append(taskDescription);
392 }
393 }
394
395 return builder.toString();
396 }
397
398
399 @Override
400 public List<Assignment> getRecentAssignments(String principalId) {
401
402 Integer limit = Integer.parseInt(ConfigContext.getCurrentContextConfig().getProperty("kpme.tklm.target.employee.time.limit"));
403 LocalDate startDate = LocalDate.now().minusDays(limit);
404 LocalDate endDate = LocalDate.now();
405
406 return getRecentAssignmentsBetweenDays(principalId, startDate, endDate);
407 }
408
409 @Override
410 public List<Assignment> getRecentAssignmentsBetweenDays(String principalId, LocalDate startDate, LocalDate endDate) {
411 Set<Assignment> assignmentSet = new HashSet<Assignment>();
412 List<Assignment> assignmentList = new ArrayList<Assignment>();
413
414 Map<LocalDate, List<Assignment>> assignmentMap = getAssignmentHistoryBetweenDaysInternal(principalId, startDate, endDate, StringUtils.EMPTY, false);
415
416
417
418 for (Map.Entry<LocalDate, List<Assignment>> entry : assignmentMap.entrySet()) {
419 for (Assignment assignment : entry.getValue()) {
420 assignmentSet.add(assignment);
421 }
422 }
423
424
425 assignmentList.addAll(assignmentSet);
426
427 return assignmentList;
428 }
429
430 @Override
431 public String getAssignmentDescriptionForAssignment(Assignment assignment, LocalDate asOfDate) {
432 return getAssignmentDescription(assignment.getPrincipalId(), assignment.getGroupKeyCode(), assignment.getJobNumber(), assignment.getWorkArea(), assignment.getTask(), asOfDate);
433 }
434
435
436
437
438
439
440
441
442
443
444
445
446
447 @Override
448 public Map<LocalDate, List<Assignment>> getAssignmentHistoryBetweenDays(String principalId, LocalDate beginDate, LocalDate endDate) {
449 return getAssignmentHistoryBetweenDaysInternal(principalId, beginDate, endDate, HrConstants.FLSA_STATUS_NON_EXEMPT, false);
450 }
451
452 @Override
453 public List<Assignment> filterAssignmentListForUser(String userPrincipalId, List<Assignment> assignments) {
454 if (CollectionUtils.isEmpty(assignments)) {
455 return Collections.emptyList();
456 }
457 List<Assignment> filteredAssignments = new ArrayList<Assignment>();
458
459
460 boolean systemAdmin = HrServiceLocator.getKPMEGroupService().isMemberOfSystemAdministratorGroup(userPrincipalId, LocalDate.now().toDateTimeAtStartOfDay());
461
462 List<String> roleIds = new ArrayList<String>();
463 RoleService roleService = KimApiServiceLocator.getRoleService();
464 roleIds.add(roleService.getRoleIdByNamespaceCodeAndName(KPMENamespace.KPME_HR.getNamespaceCode(), KPMERole.REVIEWER.getRoleName()));
465 roleIds.add(roleService.getRoleIdByNamespaceCodeAndName(KPMENamespace.KPME_HR.getNamespaceCode(), KPMERole.APPROVER_DELEGATE.getRoleName()));
466 roleIds.add(roleService.getRoleIdByNamespaceCodeAndName(KPMENamespace.KPME_HR.getNamespaceCode(), KPMERole.APPROVER.getRoleName()));
467 roleIds.add(roleService.getRoleIdByNamespaceCodeAndName(KPMENamespace.KPME_HR.getNamespaceCode(), KPMERole.PAYROLL_PROCESSOR.getRoleName()));
468 roleIds.add(roleService.getRoleIdByNamespaceCodeAndName(KPMENamespace.KPME_HR.getNamespaceCode(), KPMERole.PAYROLL_PROCESSOR_DELEGATE.getRoleName()));
469 List<Long> reportingWorkAreas = HrServiceLocator.getKPMERoleService().getWorkAreasForPrincipalInRoles(userPrincipalId, roleIds, LocalDate.now().toDateTimeAtStartOfDay(), true);
470 for (Assignment assignment : assignments) {
471
472
473 if (!StringUtils.equals(userPrincipalId, assignment.getPrincipalId())) {
474 if (!systemAdmin && !reportingWorkAreas.contains(assignment.getWorkArea())) {
475 continue;
476 }
477 }
478
479 filteredAssignments.add(assignment);
480 }
481
482 return filteredAssignments;
483 }
484
485
486 @Override
487 public Map<LocalDate, List<Assignment>> getAssignmentHistoryForCalendarEntry(String principalId, CalendarEntry calendarEntry) {
488 return getAssignmentHistoryBetweenDaysInternal(principalId, calendarEntry.getBeginPeriodFullDateTime().toLocalDate(), calendarEntry.getEndPeriodFullDateTime().toLocalDate(), HrConstants.FLSA_STATUS_NON_EXEMPT, false);
489 }
490
491 protected Map<LocalDate, List<Assignment>> getAssignmentHistoryBetweenDaysInternal(String principalId, LocalDate beginDate, LocalDate endDate, String flsaStatus, boolean checkLeaveEligible) {
492 Map<LocalDate, List<Assignment>> history = new HashMap<LocalDate, List<Assignment>>();
493
494
495 List<Assignment> beginAssignments = getAssignments(principalId, beginDate);
496
497
498 history.put(beginDate, filterAssignments(new ArrayList<Assignment>(beginAssignments), flsaStatus, checkLeaveEligible));
499
500 if(beginDate.equals(endDate)) {
501 return history;
502 }
503
504 List<AssignmentBo> assignmentChanges = assignmentDao.findAssignmentsHistoryForPeriod(principalId, beginDate, endDate);
505
506
507 Map<LocalDate, List<Assignment>> assignmentChangeMap = new HashMap<LocalDate, List<Assignment>>();
508 for (AssignmentBo change : assignmentChanges) {
509 LocalDate key = change.getEffectiveLocalDate();
510 if (assignmentChangeMap.containsKey(key)) {
511 assignmentChangeMap.get(key).add(AssignmentBo.to(change));
512 } else {
513 List<Assignment> changeList = new ArrayList<Assignment>();
514 changeList.add(AssignmentBo.to(change));
515 assignmentChangeMap.put(key, changeList);
516 }
517 }
518
519
520 List<LocalDate> localDates = new ArrayList<LocalDate>();
521 int days = Days.daysBetween(beginDate, endDate).getDays()+1;
522 for (int i=0; i < days; i++) {
523 LocalDate d = beginDate.withFieldAdded(DurationFieldType.days(), i);
524 localDates.add(d);
525 }
526
527 LocalDate previousDay = beginDate;
528 for (LocalDate ldate : localDates) {
529 if (!ldate.equals(beginDate)) {
530 List<Assignment> previousAssignments = history.get(previousDay);
531 List<Assignment> todaysAssignments = new ArrayList<Assignment>(previousAssignments);
532
533 if (assignmentChangeMap.containsKey(ldate)) {
534
535 for (Assignment a : assignmentChangeMap.get(ldate)) {
536 if (!a.isActive()) {
537
538 Iterator<Assignment> iter = todaysAssignments.iterator();
539 while (iter.hasNext()) {
540 Assignment iterAssign = iter.next();
541 if (iterAssign.getAssignmentKey().equals(a.getAssignmentKey())) {
542 iter.remove();
543 }
544 }
545 } else {
546
547 ListIterator<Assignment> iter = todaysAssignments.listIterator();
548 boolean replaced = false;
549 while (iter.hasNext()) {
550 Assignment iterAssign = iter.next();
551 if (iterAssign.getAssignmentKey().equals(a.getAssignmentKey())) {
552 iter.set(a);
553 replaced = true;
554 }
555 }
556
557
558 if (!replaced) {
559 todaysAssignments.add(a);
560 }
561 }
562 }
563 todaysAssignments = filterAssignments(todaysAssignments, flsaStatus, checkLeaveEligible);
564 }
565
566 history.put(ldate, todaysAssignments);
567 previousDay = ldate;
568 }
569 }
570
571 return history;
572 }
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623 }