1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.kpme.core.earncode.service;
17
18 import com.google.common.collect.Ordering;
19 import org.apache.commons.lang.StringUtils;
20 import org.apache.log4j.Logger;
21 import org.joda.time.LocalDate;
22 import org.kuali.kpme.core.api.accrualcategory.AccrualCategoryContract;
23 import org.kuali.kpme.core.api.assignment.Assignment;
24 import org.kuali.kpme.core.api.department.Department;
25 import org.kuali.kpme.core.api.earncode.EarnCode;
26 import org.kuali.kpme.core.api.earncode.EarnCodeContract;
27 import org.kuali.kpme.core.api.earncode.security.EarnCodeSecurityContract;
28 import org.kuali.kpme.core.api.earncode.service.EarnCodeService;
29 import org.kuali.kpme.core.api.job.JobContract;
30 import org.kuali.kpme.core.api.namespace.KPMENamespace;
31 import org.kuali.kpme.core.api.principal.PrincipalHRAttributes;
32 import org.kuali.kpme.core.api.workarea.WorkArea;
33 import org.kuali.kpme.core.department.DepartmentBo;
34 import org.kuali.kpme.core.earncode.EarnCodeBo;
35 import org.kuali.kpme.core.earncode.dao.EarnCodeDao;
36 import org.kuali.kpme.core.earncode.security.EarnCodeType;
37 import org.kuali.kpme.core.role.KPMERole;
38 import org.kuali.kpme.core.service.HrServiceLocator;
39 import org.kuali.kpme.core.util.HrConstants;
40 import org.kuali.kpme.core.util.HrContext;
41 import org.kuali.rice.core.api.mo.ModelObjectUtils;
42 import org.kuali.rice.kim.api.role.RoleService;
43 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
44 import org.kuali.rice.krad.util.GlobalVariables;
45
46 import java.math.BigDecimal;
47 import java.util.ArrayList;
48 import java.util.Comparator;
49 import java.util.HashSet;
50 import java.util.LinkedHashMap;
51 import java.util.LinkedList;
52 import java.util.List;
53 import java.util.Map;
54 import java.util.Set;
55
56 public class EarnCodeServiceImpl implements EarnCodeService {
57
58 private EarnCodeDao earnCodeDao;
59 private static final ModelObjectUtils.Transformer<EarnCodeBo, EarnCode> toEarnCode =
60 new ModelObjectUtils.Transformer<EarnCodeBo, EarnCode>() {
61 public EarnCode transform(EarnCodeBo input) {
62 return EarnCodeBo.to(input);
63 };
64 };
65 private static final Logger LOG = Logger.getLogger(EarnCodeServiceImpl.class);
66
67 public void setEarnCodeDao(EarnCodeDao earnCodeDao) {
68 this.earnCodeDao = earnCodeDao;
69 }
70
71 @Override
72 public List<EarnCode> getEarnCodesForLeave(Assignment a, LocalDate asOfDate, boolean isLeavePlanningCalendar) {
73 return ModelObjectUtils.transform(getEarnCodeBosForLeave(a, asOfDate, isLeavePlanningCalendar), toEarnCode);
74 }
75
76
77 protected List<EarnCodeBo> getEarnCodeBosForLeave(Assignment a, LocalDate asOfDate, boolean isLeavePlanningCalendar) {
78
79
80 if (a == null){
81 LOG.error("No assignment parameter.");
82 return null;
83
84 }
85
86 JobContract job = a.getJob();
87 if (job == null || job.getPayTypeObj() == null) {
88
89 LOG.error("Null job or null job pay type on assignment.");
90 return null;
91 }
92
93 List<EarnCodeBo> earnCodes = new LinkedList<EarnCodeBo>();
94 String earnTypeCode = EarnCodeType.LEAVE.getCode();
95
96
97 List<String> listAccrualCategories = new LinkedList<String>();
98 String accrualCategory;
99
100
101 PrincipalHRAttributes principalHRAttributes = HrServiceLocator.getPrincipalHRAttributeService().getPrincipalCalendar(job.getPrincipalId(), asOfDate);
102 boolean fmlaEligible = principalHRAttributes.isFmlaEligible();
103 boolean workersCompEligible = principalHRAttributes.isWorkersCompEligible();
104
105 String leavePlan = principalHRAttributes.getLeavePlan();
106 if (leavePlan != null) {
107 for (AccrualCategoryContract accrualCategories : HrServiceLocator.getAccrualCategoryService().getActiveAccrualCategoriesForLeavePlan(leavePlan, asOfDate)) {
108 accrualCategory = accrualCategories.getAccrualCategory();
109 if(accrualCategory != null) {
110 listAccrualCategories.add(accrualCategory);
111 }
112 }
113 }
114
115
116 List<? extends EarnCodeSecurityContract> decs = HrServiceLocator.getEarnCodeSecurityService().getEarnCodeSecurities(job.getDept(), job.getHrSalGroup(), asOfDate, job.getGroupKey().getGroupKeyCode());
117
118
119 for (EarnCodeSecurityContract dec : decs) {
120
121 boolean addEarnCode = addEarnCodeBasedOnEmployeeApproverSettings(dec, a, asOfDate);
122 if (addEarnCode) {
123
124
125 if (earnTypeCode.equals(dec.getEarnCodeType()) || EarnCodeType.BOTH.getCode().equals(dec.getEarnCodeType())) {
126 EarnCodeBo ec = getEarnCodeBo(dec.getEarnCode(), asOfDate);
127
128
129 if (ec != null) {
130
131 if((StringUtils.isNotBlank(leavePlan) && StringUtils.isNotBlank(ec.getLeavePlan()) && leavePlan.equals(ec.getLeavePlan()))
132 || (StringUtils.isBlank(leavePlan) && StringUtils.isBlank(ec.getLeavePlan()))) {
133
134
135
136
137
138
139
140
141
142 if ( (fmlaEligible || ec.getFmla().equals("N")) ) {
143 if (listAccrualCategories.contains(ec.getAccrualCategory()) || ec.getAccrualCategory() == null) {
144 if (StringUtils.equals(ec.getAccrualBalanceAction(), HrConstants.ACCRUAL_BALANCE_ACTION.USAGE)) {
145
146
147
148 if ( (workersCompEligible || ec.getWorkmansComp().equals("N")) ) {
149
150
151
152
153 if (isLeavePlanningCalendar) {
154
155
156 if (ec.getAllowScheduledLeave().equals("Y")) {
157 earnCodes.add(ec);
158 }
159
160 } else {
161
162 earnCodes.add(ec);
163 }
164 }
165 }
166 }
167 }
168 }
169 }
170 }
171 }
172 }
173
174 return earnCodes;
175 }
176
177 public boolean addEarnCodeBasedOnEmployeeApproverSettings(EarnCodeSecurityContract security, Assignment a, LocalDate asOfDate) {
178 boolean addEarnCode = false;
179 if (security.isEmployee() &&
180 (StringUtils.equals(HrContext.getTargetPrincipalId(), GlobalVariables.getUserSession().getPrincipalId())
181 || HrServiceLocator.getKPMEGroupService().isMemberOfSystemAdministratorGroup(GlobalVariables.getUserSession().getPrincipalId(), asOfDate.toDateTimeAtCurrentTime()))) {
182 addEarnCode = true;
183 }
184
185 RoleService roleService = KimApiServiceLocator.getRoleService();
186 if (!addEarnCode && (security.isEmployee() || security.isApprover() || security.isPayrollProcessor())) {
187 String principalId = GlobalVariables.getUserSession().getPrincipalId();
188 List<String> roleIds = new ArrayList<String>();
189 roleIds.add(roleService.getRoleIdByNamespaceCodeAndName(KPMENamespace.KPME_TK.getNamespaceCode(), KPMERole.TIME_LOCATION_ADMINISTRATOR.getRoleName()));
190 roleIds.add(roleService.getRoleIdByNamespaceCodeAndName(KPMENamespace.KPME_TK.getNamespaceCode(), KPMERole.TIME_SYSTEM_ADMINISTRATOR.getRoleName()));
191 roleIds.add(roleService.getRoleIdByNamespaceCodeAndName(KPMENamespace.KPME_LM.getNamespaceCode(), KPMERole.LEAVE_SYSTEM_ADMINISTRATOR.getRoleName()));
192 roleIds.add(roleService.getRoleIdByNamespaceCodeAndName(KPMENamespace.KPME_LM.getNamespaceCode(), KPMERole.LEAVE_LOCATION_ADMINISTRATOR.getRoleName()));
193 List<Long> workAreas = HrServiceLocator.getKPMERoleService().getWorkAreasForPrincipalInRoles(principalId, roleIds, asOfDate.toDateTimeAtStartOfDay(), true);
194
195 List<WorkArea> workAreaList = HrServiceLocator.getWorkAreaService().getWorkAreasForList(workAreas, asOfDate);
196 for (WorkArea workArea : workAreaList) {
197 if (a.getWorkArea().compareTo(workArea.getWorkArea())==0) {
198 addEarnCode = true;
199 break;
200 }
201 }
202 }
203
204 if (!addEarnCode && security.isApprover()) {
205 String principalId = GlobalVariables.getUserSession().getPrincipalId();
206
207 List<String> roleIds = new ArrayList<String>();
208 roleIds.add(roleService.getRoleIdByNamespaceCodeAndName(KPMENamespace.KPME_HR.getNamespaceCode(), KPMERole.APPROVER.getRoleName()));
209 roleIds.add(roleService.getRoleIdByNamespaceCodeAndName(KPMENamespace.KPME_HR.getNamespaceCode(), KPMERole.APPROVER_DELEGATE.getRoleName()));
210 roleIds.add(roleService.getRoleIdByNamespaceCodeAndName(KPMENamespace.KPME_HR.getNamespaceCode(), KPMERole.REVIEWER.getRoleName()));
211 List<Long> workAreas = HrServiceLocator.getKPMERoleService().getWorkAreasForPrincipalInRoles(principalId, roleIds, asOfDate.toDateTimeAtStartOfDay(), true);
212
213 List<WorkArea> workAreaList = HrServiceLocator.getWorkAreaService().getWorkAreasForList(workAreas, asOfDate);
214 for (WorkArea workArea : workAreaList) {
215 if (a.getWorkArea().compareTo(workArea.getWorkArea())==0) {
216 addEarnCode = true;
217 break;
218 }
219 }
220 }
221
222 if (!addEarnCode && security.isPayrollProcessor()) {
223 String principalId = GlobalVariables.getUserSession().getPrincipalId();
224 List<String> roleIds = new ArrayList<String>();
225 roleIds.add(roleService.getRoleIdByNamespaceCodeAndName(KPMENamespace.KPME_HR.getNamespaceCode(), KPMERole.PAYROLL_PROCESSOR.getRoleName()));
226 roleIds.add(roleService.getRoleIdByNamespaceCodeAndName(KPMENamespace.KPME_HR.getNamespaceCode(), KPMERole.PAYROLL_PROCESSOR_DELEGATE.getRoleName()));
227 List<String> depts = HrServiceLocator.getKPMERoleService().getDepartmentsForPrincipalInRoles(principalId, roleIds, asOfDate.toDateTimeAtStartOfDay(), true);
228
229
230 for (String dept : depts) {
231 Department department = HrServiceLocator.getDepartmentService().getDepartment(DepartmentBo.getDeptFromBusinessKeyId(dept), DepartmentBo.getGroupKeycodeFromBusinessKeyId(dept), asOfDate);
232 if (department!= null
233 && StringUtils.equals(a.getDept(), department.getDept())
234 && StringUtils.equals(a.getGroupKeyCode(), department.getGroupKeyCode())) {
235 addEarnCode = true;
236 break;
237 }
238 }
239
240 }
241 return addEarnCode;
242 }
243
244 @Override
245 public List<EarnCode> getEarnCodesForPrincipal(String principalId, LocalDate asOfDate, boolean isLeavePlanningCalendar) {
246 Set<EarnCodeBo> earnCodes = new HashSet<EarnCodeBo>();
247 List<Assignment> assignments = HrServiceLocator.getAssignmentService().getAssignments(principalId, asOfDate);
248 for (Assignment assignment : assignments) {
249 List<EarnCodeBo> assignmentEarnCodes = getEarnCodeBosForLeave(assignment, asOfDate, isLeavePlanningCalendar);
250
251 earnCodes.addAll(assignmentEarnCodes);
252 }
253
254 return ModelObjectUtils.transform(new ArrayList<EarnCodeBo>(earnCodes), toEarnCode);
255 }
256
257 @Override
258 public EarnCode getEarnCode(String earnCode, LocalDate asOfDate) {
259 return EarnCodeBo.to(getEarnCodeBo(earnCode, asOfDate));
260 }
261
262 protected EarnCodeBo getEarnCodeBo(String earnCode, LocalDate asOfDate) {
263 return earnCodeDao.getEarnCode(earnCode, asOfDate);
264 }
265
266 @Override
267 public String getEarnCodeType(String earnCode, LocalDate asOfDate) {
268 EarnCodeBo earnCodeObj = getEarnCodeBo(earnCode, asOfDate);
269 return earnCodeObj != null ? earnCodeObj.getEarnCodeType() : "";
270 }
271
272 @Override
273 public EarnCode getEarnCodeById(String earnCodeId) {
274 return EarnCodeBo.to(getEarnCodeBoById(earnCodeId));
275 }
276
277 public EarnCodeBo getEarnCodeBoById(String earnCodeId) {
278 return earnCodeDao.getEarnCodeById(earnCodeId);
279 }
280
281 public List<EarnCode> getOvertimeEarnCodes(LocalDate asOfDate){
282 return ModelObjectUtils.transform(earnCodeDao.getOvertimeEarnCodes(asOfDate), toEarnCode);
283 }
284
285 public List<String> getOvertimeEarnCodesStrs(LocalDate asOfDate){
286 List<String> ovtEarnCodeStrs = new ArrayList<String>();
287 List<EarnCode> ovtEarnCodes = getOvertimeEarnCodes(asOfDate);
288 if(ovtEarnCodes != null){
289 for(EarnCode ovtEc : ovtEarnCodes){
290 ovtEarnCodeStrs.add(ovtEc.getEarnCode());
291 }
292 }
293 return ovtEarnCodeStrs;
294 }
295
296 @Override
297 public int getEarnCodeCount(String earnCode) {
298 return earnCodeDao.getEarnCodeCount(earnCode);
299 }
300
301 @Override
302 public int getNewerEarnCodeCount(String earnCode, LocalDate effdt) {
303 return earnCodeDao.getNewerEarnCodeCount(earnCode, effdt);
304 }
305
306 @Override
307 public BigDecimal roundHrsWithEarnCode(BigDecimal hours, EarnCodeContract earnCode) {
308 String roundOption = HrConstants.ROUND_OPTION_MAP.get(earnCode.getRoundingOption());
309 BigDecimal fractScale = new BigDecimal(earnCode.getFractionalTimeAllowed());
310 if(roundOption == null) {
311 LOG.error("Rounding option of Earn Code " + earnCode.getEarnCode() + " is not recognized.");
312 return null;
313
314 }
315 BigDecimal roundedHours = hours;
316 if(roundOption.equals("Traditional")) {
317 roundedHours = hours.setScale(fractScale.scale(), BigDecimal.ROUND_HALF_EVEN);
318 } else if(roundOption.equals("Truncate")) {
319 roundedHours = hours.setScale(fractScale.scale(), BigDecimal.ROUND_DOWN);
320 }
321 return roundedHours;
322 }
323
324 @Override
325 public Map<String, String> getEarnCodesForDisplay(String principalId, boolean isLeavePlanningCalendar) {
326 return getEarnCodesForDisplayWithEffectiveDate(principalId, LocalDate.now(), isLeavePlanningCalendar);
327 }
328
329 public List<EarnCode> getEarnCodes(String earnCode, String ovtEarnCode, String descr, String leavePlan, String accrualCategory, LocalDate fromEffdt, LocalDate toEffdt, String active, String showHist) {
330 return ModelObjectUtils.transform(earnCodeDao.getEarnCodes(earnCode, ovtEarnCode, descr, leavePlan, accrualCategory, fromEffdt, toEffdt, active, showHist), toEarnCode);
331 }
332
333 @Override
334 public Map<String, String> getEarnCodesForDisplayWithEffectiveDate(String principalId, LocalDate asOfDate, boolean isLeavePlanningCalendar) {
335 List<EarnCode> earnCodes = this.getEarnCodesForPrincipal(principalId, asOfDate, isLeavePlanningCalendar);
336
337 boolean futureDate = asOfDate.isAfter(LocalDate.now());
338 List<EarnCode> copyList = new ArrayList<EarnCode>();
339 copyList.addAll(earnCodes);
340 for (EarnCode earnCode : copyList) {
341 if ( futureDate
342 && !earnCode.getAllowScheduledLeave().equalsIgnoreCase("Y")) {
343 earnCodes.remove(earnCode);
344 }
345 }
346 Comparator<EarnCode> earnCodeComparator = new Comparator<EarnCode>() {
347 @Override
348 public int compare(EarnCode ec1, EarnCode ec2) {
349 return ec1.getEarnCode().compareToIgnoreCase(ec2.getEarnCode());
350 }
351 };
352
353 Ordering<EarnCode> ordering = Ordering.from(earnCodeComparator);
354
355 Map<String, String> earnCodesForDisplay = new LinkedHashMap<String, String>();
356 for (EarnCode earnCode : ordering.sortedCopy(earnCodes)) {
357 earnCodesForDisplay.put(getEarnCodeKeyForDisplay(earnCode), getEarnCodeValueForDisplay(earnCode));
358 }
359 return earnCodesForDisplay;
360 }
361
362 protected String getEarnCodeKeyForDisplay(EarnCode earnCode) {
363 return earnCode.getHrEarnCodeId();
364 }
365
366 protected String getEarnCodeValueForDisplay(EarnCode earnCode) {
367 return earnCode.getEarnCode() + " : " + earnCode.getDescription();
368 }
369
370 }