1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.hr.time.earncode.service;
17
18 import java.math.BigDecimal;
19 import java.sql.Date;
20 import java.util.ArrayList;
21 import java.util.Comparator;
22 import java.util.LinkedHashMap;
23 import java.util.LinkedList;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Set;
27
28 import org.apache.commons.lang.StringUtils;
29 import org.kuali.hr.job.Job;
30 import org.kuali.hr.lm.LMConstants;
31 import org.kuali.hr.lm.accrual.AccrualCategory;
32 import org.kuali.hr.lm.earncodesec.EarnCodeSecurity;
33 import org.kuali.hr.lm.earncodesec.EarnCodeType;
34 import org.kuali.hr.time.assignment.Assignment;
35 import org.kuali.hr.time.collection.rule.TimeCollectionRule;
36 import org.kuali.hr.time.earncode.EarnCode;
37 import org.kuali.hr.time.earncode.dao.EarnCodeDao;
38 import org.kuali.hr.time.principal.PrincipalHRAttributes;
39 import org.kuali.hr.time.roles.TkUserRoles;
40 import org.kuali.hr.time.service.base.TkServiceLocator;
41 import org.kuali.hr.time.util.TKContext;
42 import org.kuali.hr.time.util.TKUser;
43 import org.kuali.hr.time.util.TKUtils;
44 import org.kuali.hr.time.util.TkConstants;
45 import org.kuali.hr.time.workarea.WorkArea;
46 import org.kuali.rice.krad.util.GlobalVariables;
47
48 import com.google.common.collect.Ordering;
49
50 public class EarnCodeServiceImpl implements EarnCodeService {
51
52 private EarnCodeDao earnCodeDao;
53
54 public void setEarnCodeDao(EarnCodeDao earnCodeDao) {
55 this.earnCodeDao = earnCodeDao;
56 }
57
58 public List<EarnCode> getEarnCodesForLeaveAndTime(Assignment a, Date asOfDate, boolean isLeavePlanningCalendar) {
59
60
61 List<EarnCode> earnCodes = getEarnCodesForTime(a, asOfDate);
62 List<EarnCode> leaveEarnCodes = getEarnCodesForLeave(a, asOfDate, isLeavePlanningCalendar);
63
64 earnCodes.removeAll(leaveEarnCodes);
65 earnCodes.addAll(leaveEarnCodes);
66
67 return earnCodes;
68 }
69
70 public List<EarnCode> getEarnCodesForTime(Assignment a, Date asOfDate) {
71
72
73 if (a == null) throw new RuntimeException("No assignment parameter.");
74 Job job = a.getJob();
75 if (job == null || job.getPayTypeObj() == null) throw new RuntimeException("Null job or null job pay type on assignment.");
76
77 List<EarnCode> earnCodes = new LinkedList<EarnCode>();
78 String earnTypeCode = EarnCodeType.TIME.getCode();
79
80 TimeCollectionRule tcr = a.getTimeCollectionRule();
81
82 boolean isClockUser = tcr == null || tcr.isClockUserFl();
83 boolean isUsersTimesheet = StringUtils.equals(TKContext.getPrincipalId(),a.getPrincipalId());
84
85
86 EarnCode regularEarnCode = getEarnCode(job.getPayTypeObj().getRegEarnCode(), asOfDate);
87 if (regularEarnCode == null) {
88 throw new RuntimeException("No regular earn code defined for job pay type.");
89 } else {
90
91 if (isClockUser && isUsersTimesheet) {
92
93 } else {
94 earnCodes.add(regularEarnCode);
95 }
96 }
97
98 List<String> listAccrualCategories = new LinkedList<String>();
99 String accrualCategory;
100
101
102 PrincipalHRAttributes principalHRAttributes = TkServiceLocator.getPrincipalHRAttributeService().getPrincipalCalendar(job.getPrincipalId(), asOfDate);
103 boolean fmlaEligible = principalHRAttributes.isFmlaEligible();
104 boolean workersCompEligible = principalHRAttributes.isWorkersCompEligible();
105
106 String leavePlan = principalHRAttributes.getLeavePlan();
107 if (leavePlan != null) {
108 for (AccrualCategory accrualCategories : TkServiceLocator.getAccrualCategoryService().getActiveAccrualCategoriesForLeavePlan(leavePlan, asOfDate)) {
109 accrualCategory = accrualCategories.getAccrualCategory();
110 if(accrualCategory != null) {
111 listAccrualCategories.add(accrualCategory);
112 }
113 }
114 }
115
116
117 List<EarnCodeSecurity> decs = TkServiceLocator.getEarnCodeSecurityService().getEarnCodeSecurities(job.getDept(), job.getHrSalGroup(), job.getLocation(), asOfDate);
118 for (EarnCodeSecurity dec : decs) {
119
120 boolean addEarnCode = addEarnCodeBasedOnEmployeeApproverSettings(dec, a, asOfDate);
121 if (addEarnCode) {
122
123
124 if (earnTypeCode.equals(dec.getEarnCodeType()) || EarnCodeType.BOTH.getCode().equals(dec.getEarnCodeType())) {
125 EarnCode ec = getEarnCode(dec.getEarnCode(), asOfDate);
126
127
128 if (ec != null) {
129
130
131
132 if (listAccrualCategories.contains(ec.getAccrualCategory()) || ec.getAccrualCategory() == null) {
133
134
135
136
137
138
139
140
141
142
143 if ( (fmlaEligible || ec.getFmla().equals("N")) ) {
144
145
146
147 if ( (workersCompEligible || ec.getWorkmansComp().equals("N")) ) {
148
149
150
151 if ( showEarnCodeIfHoliday(ec, dec) ) {
152
153
154 if ( StringUtils.equals(regularEarnCode.toString(), dec.getEarnCode()) ) {
155
156
157 } else {
158
159 earnCodes.add(ec);
160 }
161 } else {
162
163 }
164 } else {
165
166 }
167 } else {
168
169 }
170 } else {
171
172 }
173 } else {
174
175 }
176 } else {
177
178 }
179 } else {
180
181 }
182 }
183
184 return earnCodes;
185 }
186
187 public List<EarnCode> getEarnCodesForLeave(Assignment a, Date asOfDate, boolean isLeavePlanningCalendar) {
188
189
190 if (a == null) throw new RuntimeException("No assignment parameter.");
191 Job job = a.getJob();
192 if (job == null || job.getPayTypeObj() == null) throw new RuntimeException("Null job or null job pay type on assignment.");
193
194 List<EarnCode> earnCodes = new LinkedList<EarnCode>();
195 String earnTypeCode = EarnCodeType.LEAVE.getCode();
196
197
198 List<String> listAccrualCategories = new LinkedList<String>();
199 String accrualCategory;
200
201
202 PrincipalHRAttributes principalHRAttributes = TkServiceLocator.getPrincipalHRAttributeService().getPrincipalCalendar(job.getPrincipalId(), asOfDate);
203 boolean fmlaEligible = principalHRAttributes.isFmlaEligible();
204 boolean workersCompEligible = principalHRAttributes.isWorkersCompEligible();
205
206 String leavePlan = principalHRAttributes.getLeavePlan();
207 if (leavePlan != null) {
208 for (AccrualCategory accrualCategories : TkServiceLocator.getAccrualCategoryService().getActiveAccrualCategoriesForLeavePlan(leavePlan, asOfDate)) {
209 accrualCategory = accrualCategories.getAccrualCategory();
210 if(accrualCategory != null) {
211 listAccrualCategories.add(accrualCategory);
212 }
213 }
214 }
215
216
217 List<EarnCodeSecurity> decs = TkServiceLocator.getEarnCodeSecurityService().getEarnCodeSecurities(job.getDept(), job.getHrSalGroup(), job.getLocation(), asOfDate);
218 for (EarnCodeSecurity dec : decs) {
219
220 boolean addEarnCode = addEarnCodeBasedOnEmployeeApproverSettings(dec, a, asOfDate);
221 if (addEarnCode) {
222
223
224 if (earnTypeCode.equals(dec.getEarnCodeType()) || EarnCodeType.BOTH.getCode().equals(dec.getEarnCodeType())) {
225 EarnCode ec = getEarnCode(dec.getEarnCode(), asOfDate);
226
227
228 if (ec != null) {
229
230
231
232 if (listAccrualCategories.contains(ec.getAccrualCategory()) || ec.getAccrualCategory() == null) {
233
234
235
236
237
238
239
240
241
242
243 if ( (fmlaEligible || ec.getFmla().equals("N")) ) {
244
245
246
247 if ( (workersCompEligible || ec.getWorkmansComp().equals("N")) ) {
248
249
250
251
252 if (isLeavePlanningCalendar) {
253
254
255 if (ec.getAllowScheduledLeave().equals("Y")) {
256 earnCodes.add(ec);
257 } else {
258
259 }
260
261 } else {
262
263 earnCodes.add(ec);
264 }
265
266 } else {
267
268 }
269 } else {
270
271 }
272 } else {
273
274 }
275 } else {
276
277 }
278 } else {
279
280 }
281 } else {
282
283 }
284 }
285
286 return earnCodes;
287 }
288
289 private boolean addEarnCodeBasedOnEmployeeApproverSettings(EarnCodeSecurity security, Assignment a, Date asOfDate) {
290 boolean addEarnCode = false;
291 if (security.isEmployee() &&
292 (StringUtils.equals(TKUser.getCurrentTargetPerson().getEmployeeId(), GlobalVariables.getUserSession().getPerson().getEmployeeId()))) {
293 addEarnCode = true;
294 }
295
296 if (!addEarnCode && security.isApprover()) {
297 Set<Long> workAreas = TkUserRoles.getUserRoles(GlobalVariables.getUserSession().getPrincipalId()).getApproverWorkAreas();
298 for (Long wa : workAreas) {
299 WorkArea workArea = TkServiceLocator.getWorkAreaService().getWorkArea(wa, asOfDate);
300 if (workArea!= null && a.getWorkArea().compareTo(workArea.getWorkArea())==0) {
301 addEarnCode = true;
302 break;
303 }
304 }
305 }
306 return addEarnCode;
307 }
308
309 private boolean showEarnCodeIfHoliday(EarnCode earnCode, EarnCodeSecurity security) {
310 if (earnCode.getEarnCode().equals(TkConstants.HOLIDAY_EARN_CODE)) {
311 if (security.isApprover() || TkUserRoles.getUserRoles(GlobalVariables.getUserSession().getPrincipalId()).isSystemAdmin()) {
312 return true;
313 } else {
314 return false;
315 }
316 } else {
317 return true;
318 }
319 }
320
321 @Override
322 public List<EarnCode> getEarnCodesForPrincipal(String principalId, Date asOfDate, boolean isLeavePlanningCalendar) {
323 List<EarnCode> earnCodes = new LinkedList<EarnCode>();
324 List<Assignment> assignments = TkServiceLocator.getAssignmentService().getAssignments(principalId, asOfDate);
325 for (Assignment assignment : assignments) {
326 List<EarnCode> assignmentEarnCodes = getEarnCodesForLeave(assignment, asOfDate, isLeavePlanningCalendar);
327
328 earnCodes.removeAll(assignmentEarnCodes);
329 earnCodes.addAll(assignmentEarnCodes);
330 }
331
332 return earnCodes;
333 }
334
335 public EarnCode getEarnCode(String earnCode, Date asOfDate) {
336 return earnCodeDao.getEarnCode(earnCode, asOfDate);
337 }
338
339 @Override
340 public String getEarnCodeType(String earnCode, Date asOfDate) {
341 EarnCode earnCodeObj = getEarnCode(earnCode, asOfDate);
342 return earnCodeObj.getEarnCodeType();
343 }
344
345 @Override
346 public EarnCode getEarnCodeById(String earnCodeId) {
347 return earnCodeDao.getEarnCodeById(earnCodeId);
348 }
349
350 public List<EarnCode> getOvertimeEarnCodes(Date asOfDate){
351 return earnCodeDao.getOvertimeEarnCodes(asOfDate);
352 }
353
354 public List<String> getOvertimeEarnCodesStrs(Date asOfDate){
355 List<String> ovtEarnCodeStrs = new ArrayList<String>();
356 List<EarnCode> ovtEarnCodes = getOvertimeEarnCodes(asOfDate);
357 if(ovtEarnCodes != null){
358 for(EarnCode ovtEc : ovtEarnCodes){
359 ovtEarnCodeStrs.add(ovtEc.getEarnCode());
360 }
361 }
362 return ovtEarnCodeStrs;
363 }
364
365 @Override
366 public int getEarnCodeCount(String earnCode) {
367 return earnCodeDao.getEarnCodeCount(earnCode);
368 }
369
370 @Override
371 public int getNewerEarnCodeCount(String earnCode, Date effdt) {
372 return earnCodeDao.getNewerEarnCodeCount(earnCode, effdt);
373 }
374
375 @Override
376 public BigDecimal roundHrsWithEarnCode(BigDecimal hours, EarnCode earnCode) {
377 String roundOption = LMConstants.ROUND_OPTION_MAP.get(earnCode.getRoundingOption());
378 BigDecimal fractScale = new BigDecimal(earnCode.getFractionalTimeAllowed());
379 if(roundOption == null) {
380 throw new RuntimeException("Rounding option of Earn Code " + earnCode.getEarnCode() + " is not recognized.");
381 }
382 BigDecimal roundedHours = hours;
383 if(roundOption.equals("Traditional")) {
384 roundedHours = hours.setScale(fractScale.scale(), BigDecimal.ROUND_HALF_EVEN);
385 } else if(roundOption.equals("Truncate")) {
386 roundedHours = hours.setScale(fractScale.scale(), BigDecimal.ROUND_DOWN);
387 }
388 return roundedHours;
389 }
390
391 @Override
392 public Map<String, String> getEarnCodesForDisplay(String principalId, boolean isLeavePlanningCalendar) {
393 return getEarnCodesForDisplayWithEffectiveDate(principalId, TKUtils.getCurrentDate(), isLeavePlanningCalendar);
394 }
395
396 public List<EarnCode> getEarnCodes(String earnCode, String ovtEarnCode, String descr, String leavePlan, String accrualCategory, Date fromEffdt, Date toEffdt, String active, String showHist) {
397 return earnCodeDao.getEarnCodes(earnCode, ovtEarnCode, descr, leavePlan, accrualCategory, fromEffdt, toEffdt, active, showHist);
398 }
399
400 @Override
401 public Map<String, String> getEarnCodesForDisplayWithEffectiveDate(String principalId, Date asOfDate, boolean isLeavePlanningCalendar) {
402 List<EarnCode> earnCodes = this.getEarnCodesForPrincipal(principalId, asOfDate, isLeavePlanningCalendar);
403
404 Date currentDate = TKUtils.getCurrentDate();
405 boolean futureDate = asOfDate.after(currentDate);
406 List<EarnCode> copyList = new ArrayList<EarnCode>();
407 copyList.addAll(earnCodes);
408 for (EarnCode earnCode : copyList) {
409 if ( futureDate
410 && !earnCode.getAllowScheduledLeave().equalsIgnoreCase("Y")) {
411 earnCodes.remove(earnCode);
412 }
413 }
414 Comparator<EarnCode> earnCodeComparator = new Comparator<EarnCode>() {
415 @Override
416 public int compare(EarnCode ec1, EarnCode ec2) {
417 return ec1.getEarnCode().compareToIgnoreCase(ec2.getEarnCode());
418 }
419 };
420
421 Ordering<EarnCode> ordering = Ordering.from(earnCodeComparator);
422
423 Map<String, String> earnCodesForDisplay = new LinkedHashMap<String, String>();
424 for (EarnCode earnCode : ordering.sortedCopy(earnCodes)) {
425 earnCodesForDisplay.put(earnCode.getEarnCodeKeyForDisplay(), earnCode.getEarnCodeValueForDisplay());
426 }
427 return earnCodesForDisplay;
428 }
429
430 }