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