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