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 if (StringUtils.equals(ec.getAccrualBalanceAction(), LMConstants.ACCRUAL_BALANCE_ACTION.USAGE)) {
146
147
148
149 if ( (workersCompEligible || ec.getWorkmansComp().equals("N")) ) {
150
151
152
153 if ( showEarnCodeIfHoliday(ec, dec) ) {
154
155 if ( !StringUtils.equals(regularEarnCode.toString(), dec.getEarnCode()) ) {
156
157 earnCodes.add(ec);
158 }
159 }
160 }
161 }
162 }
163 }
164 }
165 }
166 }
167 }
168
169 return earnCodes;
170 }
171
172 public List<EarnCode> getEarnCodesForLeave(Assignment a, Date asOfDate, boolean isLeavePlanningCalendar) {
173
174
175 if (a == null) throw new RuntimeException("No assignment parameter.");
176 Job job = a.getJob();
177 if (job == null || job.getPayTypeObj() == null) throw new RuntimeException("Null job or null job pay type on assignment.");
178
179 List<EarnCode> earnCodes = new LinkedList<EarnCode>();
180 String earnTypeCode = EarnCodeType.LEAVE.getCode();
181
182
183 List<String> listAccrualCategories = new LinkedList<String>();
184 String accrualCategory;
185
186
187 PrincipalHRAttributes principalHRAttributes = TkServiceLocator.getPrincipalHRAttributeService().getPrincipalCalendar(job.getPrincipalId(), asOfDate);
188 boolean fmlaEligible = principalHRAttributes.isFmlaEligible();
189 boolean workersCompEligible = principalHRAttributes.isWorkersCompEligible();
190
191 String leavePlan = principalHRAttributes.getLeavePlan();
192 if (leavePlan != null) {
193 for (AccrualCategory accrualCategories : TkServiceLocator.getAccrualCategoryService().getActiveAccrualCategoriesForLeavePlan(leavePlan, asOfDate)) {
194 accrualCategory = accrualCategories.getAccrualCategory();
195 if(accrualCategory != null) {
196 listAccrualCategories.add(accrualCategory);
197 }
198 }
199 }
200
201
202 List<EarnCodeSecurity> decs = TkServiceLocator.getEarnCodeSecurityService().getEarnCodeSecurities(job.getDept(), job.getHrSalGroup(), job.getLocation(), asOfDate);
203 for (EarnCodeSecurity dec : decs) {
204
205 boolean addEarnCode = addEarnCodeBasedOnEmployeeApproverSettings(dec, a, asOfDate);
206 if (addEarnCode) {
207
208
209 if (earnTypeCode.equals(dec.getEarnCodeType()) || EarnCodeType.BOTH.getCode().equals(dec.getEarnCodeType())) {
210 EarnCode ec = getEarnCode(dec.getEarnCode(), asOfDate);
211
212
213 if (ec != null) {
214
215
216
217 if (listAccrualCategories.contains(ec.getAccrualCategory()) || ec.getAccrualCategory() == null) {
218
219
220
221
222
223
224
225
226
227
228 if ( (fmlaEligible || ec.getFmla().equals("N")) ) {
229
230
231
232 if ( (workersCompEligible || ec.getWorkmansComp().equals("N")) ) {
233
234
235
236 if (StringUtils.equals(ec.getAccrualBalanceAction(), LMConstants.ACCRUAL_BALANCE_ACTION.USAGE)) {
237
238
239 if (isLeavePlanningCalendar) {
240
241
242 if (ec.getAllowScheduledLeave().equals("Y")) {
243 earnCodes.add(ec);
244 }
245
246 } else {
247
248 earnCodes.add(ec);
249 }
250 }
251 }
252 }
253 }
254 }
255 }
256 }
257 }
258
259 return earnCodes;
260 }
261
262 private boolean addEarnCodeBasedOnEmployeeApproverSettings(EarnCodeSecurity security, Assignment a, Date asOfDate) {
263 boolean addEarnCode = false;
264 if (security.isEmployee() &&
265 (StringUtils.equals(TKUser.getCurrentTargetPerson().getEmployeeId(), GlobalVariables.getUserSession().getPerson().getEmployeeId()))) {
266 addEarnCode = true;
267 }
268
269 if (!addEarnCode && security.isApprover()) {
270 Set<Long> workAreas = TkUserRoles.getUserRoles(GlobalVariables.getUserSession().getPrincipalId()).getApproverWorkAreas();
271 for (Long wa : workAreas) {
272 WorkArea workArea = TkServiceLocator.getWorkAreaService().getWorkArea(wa, asOfDate);
273 if (workArea!= null && a.getWorkArea().compareTo(workArea.getWorkArea())==0) {
274 addEarnCode = true;
275 break;
276 }
277 }
278 }
279 return addEarnCode;
280 }
281
282 private boolean showEarnCodeIfHoliday(EarnCode earnCode, EarnCodeSecurity security) {
283 if (earnCode.getEarnCode().equals(TkConstants.HOLIDAY_EARN_CODE)) {
284 if (security.isApprover() || TkUserRoles.getUserRoles(GlobalVariables.getUserSession().getPrincipalId()).isSystemAdmin()) {
285 return true;
286 } else {
287 return false;
288 }
289 } else {
290 return true;
291 }
292 }
293
294 @Override
295 public List<EarnCode> getEarnCodesForPrincipal(String principalId, Date asOfDate, boolean isLeavePlanningCalendar) {
296 List<EarnCode> earnCodes = new LinkedList<EarnCode>();
297 List<Assignment> assignments = TkServiceLocator.getAssignmentService().getAssignments(principalId, asOfDate);
298 for (Assignment assignment : assignments) {
299 List<EarnCode> assignmentEarnCodes = getEarnCodesForLeave(assignment, asOfDate, isLeavePlanningCalendar);
300
301 earnCodes.removeAll(assignmentEarnCodes);
302 earnCodes.addAll(assignmentEarnCodes);
303 }
304
305 return earnCodes;
306 }
307
308 public EarnCode getEarnCode(String earnCode, Date asOfDate) {
309 return earnCodeDao.getEarnCode(earnCode, asOfDate);
310 }
311
312 @Override
313 public String getEarnCodeType(String earnCode, Date asOfDate) {
314 EarnCode earnCodeObj = getEarnCode(earnCode, asOfDate);
315 return earnCodeObj.getEarnCodeType();
316 }
317
318 @Override
319 public EarnCode getEarnCodeById(String earnCodeId) {
320 return earnCodeDao.getEarnCodeById(earnCodeId);
321 }
322
323 public List<EarnCode> getOvertimeEarnCodes(Date asOfDate){
324 return earnCodeDao.getOvertimeEarnCodes(asOfDate);
325 }
326
327 public List<String> getOvertimeEarnCodesStrs(Date asOfDate){
328 List<String> ovtEarnCodeStrs = new ArrayList<String>();
329 List<EarnCode> ovtEarnCodes = getOvertimeEarnCodes(asOfDate);
330 if(ovtEarnCodes != null){
331 for(EarnCode ovtEc : ovtEarnCodes){
332 ovtEarnCodeStrs.add(ovtEc.getEarnCode());
333 }
334 }
335 return ovtEarnCodeStrs;
336 }
337
338 @Override
339 public int getEarnCodeCount(String earnCode) {
340 return earnCodeDao.getEarnCodeCount(earnCode);
341 }
342
343 @Override
344 public int getNewerEarnCodeCount(String earnCode, Date effdt) {
345 return earnCodeDao.getNewerEarnCodeCount(earnCode, effdt);
346 }
347
348 @Override
349 public BigDecimal roundHrsWithEarnCode(BigDecimal hours, EarnCode earnCode) {
350 String roundOption = LMConstants.ROUND_OPTION_MAP.get(earnCode.getRoundingOption());
351 BigDecimal fractScale = new BigDecimal(earnCode.getFractionalTimeAllowed());
352 if(roundOption == null) {
353 throw new RuntimeException("Rounding option of Earn Code " + earnCode.getEarnCode() + " is not recognized.");
354 }
355 BigDecimal roundedHours = hours;
356 if(roundOption.equals("Traditional")) {
357 roundedHours = hours.setScale(fractScale.scale(), BigDecimal.ROUND_HALF_EVEN);
358 } else if(roundOption.equals("Truncate")) {
359 roundedHours = hours.setScale(fractScale.scale(), BigDecimal.ROUND_DOWN);
360 }
361 return roundedHours;
362 }
363
364 @Override
365 public Map<String, String> getEarnCodesForDisplay(String principalId, boolean isLeavePlanningCalendar) {
366 return getEarnCodesForDisplayWithEffectiveDate(principalId, TKUtils.getCurrentDate(), isLeavePlanningCalendar);
367 }
368
369 public List<EarnCode> getEarnCodes(String earnCode, String ovtEarnCode, String descr, String leavePlan, String accrualCategory, Date fromEffdt, Date toEffdt, String active, String showHist) {
370 return earnCodeDao.getEarnCodes(earnCode, ovtEarnCode, descr, leavePlan, accrualCategory, fromEffdt, toEffdt, active, showHist);
371 }
372
373 @Override
374 public Map<String, String> getEarnCodesForDisplayWithEffectiveDate(String principalId, Date asOfDate, boolean isLeavePlanningCalendar) {
375 List<EarnCode> earnCodes = this.getEarnCodesForPrincipal(principalId, asOfDate, isLeavePlanningCalendar);
376
377 Date currentDate = TKUtils.getCurrentDate();
378 boolean futureDate = asOfDate.after(currentDate);
379 List<EarnCode> copyList = new ArrayList<EarnCode>();
380 copyList.addAll(earnCodes);
381 for (EarnCode earnCode : copyList) {
382 if ( futureDate
383 && !earnCode.getAllowScheduledLeave().equalsIgnoreCase("Y")) {
384 earnCodes.remove(earnCode);
385 }
386 }
387 Comparator<EarnCode> earnCodeComparator = new Comparator<EarnCode>() {
388 @Override
389 public int compare(EarnCode ec1, EarnCode ec2) {
390 return ec1.getEarnCode().compareToIgnoreCase(ec2.getEarnCode());
391 }
392 };
393
394 Ordering<EarnCode> ordering = Ordering.from(earnCodeComparator);
395
396 Map<String, String> earnCodesForDisplay = new LinkedHashMap<String, String>();
397 for (EarnCode earnCode : ordering.sortedCopy(earnCodes)) {
398 earnCodesForDisplay.put(earnCode.getEarnCodeKeyForDisplay(), earnCode.getEarnCodeValueForDisplay());
399 }
400 return earnCodesForDisplay;
401 }
402
403 }