1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.kpme.tklm.time.timesheet.service;
17
18 import java.math.BigDecimal;
19 import java.util.ArrayList;
20 import java.util.LinkedList;
21 import java.util.List;
22
23 import org.apache.commons.collections.CollectionUtils;
24 import org.apache.commons.lang.StringUtils;
25 import org.apache.log4j.Logger;
26 import org.joda.time.DateTime;
27 import org.joda.time.LocalDate;
28 import org.kuali.kpme.core.accrualcategory.AccrualCategory;
29 import org.kuali.kpme.core.assignment.Assignment;
30 import org.kuali.kpme.core.batch.BatchJobUtil;
31 import org.kuali.kpme.core.calendar.entry.CalendarEntry;
32 import org.kuali.kpme.core.earncode.EarnCode;
33 import org.kuali.kpme.core.earncode.security.EarnCodeSecurity;
34 import org.kuali.kpme.core.earncode.security.EarnCodeType;
35 import org.kuali.kpme.core.job.Job;
36 import org.kuali.kpme.core.principal.PrincipalHRAttributes;
37 import org.kuali.kpme.core.service.HrServiceLocator;
38 import org.kuali.kpme.core.service.permission.HRPermissionService;
39 import org.kuali.kpme.core.util.HrConstants;
40 import org.kuali.kpme.core.util.HrContext;
41 import org.kuali.kpme.core.util.TKUtils;
42 import org.kuali.kpme.tklm.common.LMConstants;
43 import org.kuali.kpme.tklm.common.TkConstants;
44 import org.kuali.kpme.tklm.leave.block.LeaveBlock;
45 import org.kuali.kpme.tklm.leave.service.LmServiceLocator;
46 import org.kuali.kpme.tklm.leave.timeoff.SystemScheduledTimeOff;
47 import org.kuali.kpme.tklm.time.rules.timecollection.TimeCollectionRule;
48 import org.kuali.kpme.tklm.time.service.TkServiceLocator;
49 import org.kuali.kpme.tklm.time.service.permission.TKPermissionService;
50 import org.kuali.kpme.core.block.CalendarBlockPermissions;
51 import org.kuali.kpme.tklm.time.timeblock.TimeBlock;
52 import org.kuali.kpme.tklm.time.timesheet.TimesheetDocument;
53 import org.kuali.kpme.tklm.time.workflow.TimesheetDocumentHeader;
54 import org.kuali.rice.core.api.config.property.ConfigContext;
55 import org.kuali.rice.kew.api.KewApiServiceLocator;
56 import org.kuali.rice.kew.api.WorkflowDocument;
57 import org.kuali.rice.kew.api.WorkflowDocumentFactory;
58 import org.kuali.rice.kew.api.exception.WorkflowException;
59 import org.kuali.rice.kew.api.note.Note;
60 import org.kuali.rice.kim.api.identity.principal.EntityNamePrincipalName;
61 import org.kuali.rice.kim.api.identity.principal.Principal;
62 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
63 import org.kuali.rice.krad.util.GlobalVariables;
64
65 public class TimesheetServiceImpl implements TimesheetService {
66
67 private static final Logger LOG = Logger.getLogger(TimesheetServiceImpl.class);
68
69 private HRPermissionService hrPermissionService;
70
71 @Override
72 public void routeTimesheet(String principalId, TimesheetDocument timesheetDocument) {
73 routeTimesheet(principalId, timesheetDocument, HrConstants.DOCUMENT_ACTIONS.ROUTE);
74 }
75
76 @Override
77 public void routeTimesheet(String principalId, TimesheetDocument timesheetDocument, String action) {
78 timesheetAction(action, principalId, timesheetDocument);
79 }
80
81 @Override
82 public void approveTimesheet(String principalId, TimesheetDocument timesheetDocument) {
83 timesheetAction(HrConstants.DOCUMENT_ACTIONS.APPROVE, principalId, timesheetDocument);
84 }
85
86 @Override
87 public void approveTimesheet(String principalId, TimesheetDocument timesheetDocument, String action) {
88 timesheetAction(action, principalId, timesheetDocument);
89 }
90
91 @Override
92 public void disapproveTimesheet(String principalId, TimesheetDocument timesheetDocument) {
93 timesheetAction(HrConstants.DOCUMENT_ACTIONS.DISAPPROVE, principalId, timesheetDocument);
94 }
95
96 protected void timesheetAction(String action, String principalId, TimesheetDocument timesheetDocument) {
97 WorkflowDocument wd = null;
98 if (timesheetDocument != null) {
99 String rhid = timesheetDocument.getDocumentId();
100 wd = WorkflowDocumentFactory.loadDocument(principalId, rhid);
101
102 if (StringUtils.equals(action, HrConstants.DOCUMENT_ACTIONS.ROUTE)) {
103 wd.route("Routing for Approval");
104 } else if (StringUtils.equals(action, HrConstants.BATCH_JOB_ACTIONS.BATCH_JOB_ROUTE)) {
105 Note.Builder builder = Note.Builder.create(rhid, principalId);
106 builder.setCreateDate(new DateTime());
107 builder.setText("Routed via Employee Approval batch job");
108 KewApiServiceLocator.getNoteService().createNote(builder.build());
109
110 wd.route("Batch job routing timesheet");
111 } else if (StringUtils.equals(action, HrConstants.DOCUMENT_ACTIONS.APPROVE)) {
112 if (HrServiceLocator.getHRPermissionService().canSuperUserAdministerCalendarDocument(GlobalVariables.getUserSession().getPrincipalId(), timesheetDocument)
113 && !HrServiceLocator.getHRPermissionService().canApproveCalendarDocument(GlobalVariables.getUserSession().getPrincipalId(), timesheetDocument)) {
114 wd.superUserBlanketApprove("Superuser approving timesheet.");
115 } else {
116 wd.approve("Approving timesheet.");
117 }
118 } else if (StringUtils.equals(action, HrConstants.BATCH_JOB_ACTIONS.BATCH_JOB_APPROVE)) {
119 Note.Builder builder = Note.Builder.create(rhid, principalId);
120 builder.setCreateDate(new DateTime());
121 builder.setText("Approved via Supervisor Approval batch job");
122 KewApiServiceLocator.getNoteService().createNote(builder.build());
123
124 wd.superUserBlanketApprove("Batch job approving timesheet.");
125 } else if (StringUtils.equals(action, HrConstants.DOCUMENT_ACTIONS.DISAPPROVE)) {
126 if (HrServiceLocator.getHRPermissionService().canSuperUserAdministerCalendarDocument(GlobalVariables.getUserSession().getPrincipalId(), timesheetDocument)
127 && !HrServiceLocator.getHRPermissionService().canApproveCalendarDocument(GlobalVariables.getUserSession().getPrincipalId(), timesheetDocument)) {
128 wd.superUserDisapprove("Superuser disapproving timesheet.");
129 } else {
130 wd.disapprove("Disapproving timesheet.");
131 }
132 }
133 clearTimesheetTimeblockPermissions(timesheetDocument);
134 }
135 }
136
137 @Override
138 public TimesheetDocument openTimesheetDocument(String principalId, CalendarEntry calendarDates) throws WorkflowException {
139 TimesheetDocument timesheetDocument = null;
140
141 DateTime begin = calendarDates.getBeginPeriodFullDateTime();
142 DateTime end = calendarDates.getEndPeriodFullDateTime();
143
144 TimesheetDocumentHeader header = TkServiceLocator.getTimesheetDocumentHeaderService().getDocumentHeader(principalId, begin, end);
145
146 if (header == null) {
147 List<Assignment> activeAssignments = HrServiceLocator.getAssignmentService().getAssignmentsByCalEntryForTimeCalendar(principalId, calendarDates);
148
149 if (activeAssignments.size() == 0) {
150 LOG.warn("No active assignments for " + principalId + " for " + calendarDates.getEndPeriodDate());
151 return null;
152
153 }
154
155 EntityNamePrincipalName person = KimApiServiceLocator.getIdentityService().getDefaultNamesForPrincipalId(principalId);
156 String principalName = person != null && person.getDefaultName() != null ? person.getDefaultName().getCompositeName() : StringUtils.EMPTY;
157 String endDateString = TKUtils.formatDate(end.toLocalDate());
158 String timesheetDocumentTitle = TimesheetDocument.TIMESHEET_DOCUMENT_TYPE + " - " + principalName + " (" + principalId + ") - " + endDateString;
159
160 timesheetDocument = this.initiateWorkflowDocument(principalId, begin, end, calendarDates, TimesheetDocument.TIMESHEET_DOCUMENT_TYPE, timesheetDocumentTitle);
161
162
163
164
165 } else {
166 timesheetDocument = this.getTimesheetDocument(header.getDocumentId());
167 if (timesheetDocument != null) {
168 timesheetDocument.setCalendarEntry(calendarDates);
169 }
170 }
171
172
173
174
175
176 return timesheetDocument;
177 }
178
179 public void loadHolidaysOnTimesheet(TimesheetDocument timesheetDocument, String principalId, LocalDate beginDate, LocalDate endDate) {
180 PrincipalHRAttributes principalCalendar = HrServiceLocator.getPrincipalHRAttributeService().getPrincipalCalendar(principalId, beginDate);
181 if (principalCalendar != null && StringUtils.isNotEmpty(principalCalendar.getLeavePlan())) {
182 List<SystemScheduledTimeOff> sstoList = LmServiceLocator.getSysSchTimeOffService()
183 .getSystemScheduledTimeOffForPayPeriod(principalCalendar.getLeavePlan(), beginDate, endDate);
184 Assignment sstoAssign = getAssignmentToApplyScheduledTimeOff(timesheetDocument.getPrincipalId(), timesheetDocument.getAssignments(), endDate);
185 if (sstoAssign != null) {
186 for(SystemScheduledTimeOff ssto : sstoList) {
187 BigDecimal sstoCalcHours = LmServiceLocator.getSysSchTimeOffService().calculateSysSchTimeOffHours(sstoAssign.getJob(), ssto.getAmountofTime());
188 TimeBlock timeBlock = TkServiceLocator.getTimeBlockService().createTimeBlock(timesheetDocument, ssto.getScheduledTimeOffLocalDate().toDateTimeAtStartOfDay(),
189 ssto.getScheduledTimeOffLocalDate().toDateTimeAtStartOfDay(), sstoAssign, HrConstants.HOLIDAY_EARN_CODE, sstoCalcHours, BigDecimal.ZERO, false, false, HrContext.getPrincipalId());
190 timesheetDocument.getTimeBlocks().add(timeBlock);
191 }
192
193 if (CollectionUtils.isNotEmpty(sstoList)) {
194 TkServiceLocator.getTimeBlockService().saveTimeBlocks(new LinkedList<TimeBlock>(), timesheetDocument.getTimeBlocks(), HrContext.getPrincipalId());
195 }
196 }
197 }
198 }
199
200 private Assignment getAssignmentToApplyScheduledTimeOff(String principalId, List<Assignment> assignments, LocalDate endDate) {
201 Job primaryJob = HrServiceLocator.getJobService().getPrimaryJob(principalId, endDate);
202 for(Assignment assign : assignments){
203 if(assign.getJobNumber().equals(primaryJob.getJobNumber())){
204 return assign;
205 }
206 }
207 return null;
208 }
209
210 protected TimesheetDocument initiateWorkflowDocument(String principalId, DateTime payBeginDate, DateTime payEndDate, CalendarEntry calendarEntry, String documentType, String title) throws WorkflowException {
211 TimesheetDocument timesheetDocument = null;
212 WorkflowDocument workflowDocument = null;
213
214 workflowDocument = WorkflowDocumentFactory.createDocument(principalId, documentType, title);
215
216 String status = workflowDocument.getStatus().getCode();
217 TimesheetDocumentHeader documentHeader = new TimesheetDocumentHeader(workflowDocument.getDocumentId(), principalId, payBeginDate.toDate(), payEndDate.toDate(), status);
218
219 documentHeader.setDocumentId(workflowDocument.getDocumentId().toString());
220 documentHeader.setDocumentStatus("I");
221
222 TkServiceLocator.getTimesheetDocumentHeaderService().saveOrUpdate(documentHeader);
223 timesheetDocument = new TimesheetDocument(documentHeader);
224 timesheetDocument.setCalendarEntry(calendarEntry);
225 loadTimesheetDocumentData(timesheetDocument, principalId, calendarEntry);
226 TkServiceLocator.getTkSearchableAttributeService().updateSearchableAttribute(timesheetDocument, payEndDate.toLocalDate());
227
228 if (LmServiceLocator.getLeaveApprovalService().isActiveAssignmentFoundOnJobFlsaStatus(principalId, HrConstants.FLSA_STATUS_NON_EXEMPT, true)) {
229 deleteNonApprovedLeaveBlocks(principalId, calendarEntry.getBeginPeriodFullDateTime().toLocalDate(), calendarEntry.getEndPeriodFullDateTime().toLocalDate());
230 }
231
232 return timesheetDocument;
233 }
234
235 private void deleteNonApprovedLeaveBlocks(String principalId, LocalDate beginDate, LocalDate endDate) {
236 String batchUserPrincipalId = BatchJobUtil.getBatchUserPrincipalId();
237
238 if (batchUserPrincipalId != null) {
239 List<LeaveBlock> leaveBlocks = LmServiceLocator.getLeaveBlockService().getLeaveBlocks(principalId, beginDate, endDate);
240
241 for (LeaveBlock leaveBlock : leaveBlocks) {
242 if (!StringUtils.equals(leaveBlock.getRequestStatus(), HrConstants.REQUEST_STATUS.APPROVED)) {
243 LmServiceLocator.getLeaveRequestDocumentService().suCancelLeave(
244 leaveBlock.getLeaveRequestDocumentId(), batchUserPrincipalId);
245 LmServiceLocator.getLeaveBlockService().deleteLeaveBlock(leaveBlock.getLmLeaveBlockId(), batchUserPrincipalId);
246 }
247 }
248 } else {
249 String principalName = BatchJobUtil.getBatchUserPrincipalName();
250 LOG.error("Could not delete leave request blocks due to missing batch user " + principalName);
251 }
252 }
253
254
255 public List<TimeBlock> getPrevDocumentTimeBlocks(String principalId, DateTime payBeginDate) {
256 TimesheetDocumentHeader prevTdh = TkServiceLocator.getTimesheetDocumentHeaderService().getPreviousDocumentHeader(principalId, payBeginDate);
257 if (prevTdh == null) {
258 return new ArrayList<TimeBlock>();
259 }
260 return TkServiceLocator.getTimeBlockService().getTimeBlocks(prevTdh.getDocumentId());
261 }
262
263 @Override
264 public TimesheetDocument getTimesheetDocument(String documentId) {
265 TimesheetDocument timesheetDocument = null;
266 TimesheetDocumentHeader tdh = TkServiceLocator.getTimesheetDocumentHeaderService().getDocumentHeader(documentId);
267
268 if (tdh != null) {
269 timesheetDocument = new TimesheetDocument(tdh);
270 CalendarEntry pce = HrServiceLocator.getCalendarEntryService().getCalendarDatesByPayEndDate(tdh.getPrincipalId(), tdh.getEndDateTime(), HrConstants.PAY_CALENDAR_TYPE);
271 loadTimesheetDocumentData(timesheetDocument, tdh.getPrincipalId(), pce);
272
273 timesheetDocument.setCalendarEntry(pce);
274 }
275
276 return timesheetDocument;
277 }
278
279 protected void loadTimesheetDocumentData(TimesheetDocument tdoc, String principalId, CalendarEntry payCalEntry) {
280 tdoc.setAssignments(HrServiceLocator.getAssignmentService().getAssignmentsByCalEntryForTimeCalendar(principalId, payCalEntry));
281 if (payCalEntry != null) {
282 tdoc.setJobs(HrServiceLocator.getJobService().getJobs(principalId, payCalEntry.getEndPeriodFullDateTime().toLocalDate()));
283 }
284 tdoc.setTimeBlocks(TkServiceLocator.getTimeBlockService().getTimeBlocks(tdoc.getDocumentHeader().getDocumentId()));
285 }
286
287 public boolean isSynchronousUser() {
288 List<Assignment> assignments = HrServiceLocator.getAssignmentService().getAssignments(HrContext.getTargetPrincipalId(), LocalDate.now());
289 boolean isSynchronousUser = true;
290 for (Assignment assignment : assignments) {
291 if(assignment.getJob() != null) {
292 TimeCollectionRule tcr = TkServiceLocator.getTimeCollectionRuleService().getTimeCollectionRule(assignment.getDept(), assignment.getWorkArea(), assignment.getJob().getHrPayType(), LocalDate.now());
293 isSynchronousUser &= tcr == null || tcr.isClockUserFl();
294 }
295 }
296 return isSynchronousUser;
297 }
298
299
300 public void deleteTimesheet(String documentId) {
301 TkServiceLocator.getTimeBlockService().deleteTimeBlocksAssociatedWithDocumentId(documentId);
302 TkServiceLocator.getTimesheetDocumentHeaderService().deleteTimesheetHeader(documentId);
303 }
304
305 public TimeBlock resetWorkedHours(TimeBlock previousTimeBlock, TimeBlock timeBlock, LocalDate asOfDate) {
306 EarnCode earnCodeObj = HrServiceLocator.getEarnCodeService().getEarnCode(timeBlock.getEarnCode(), asOfDate);
307
308 if (timeBlock.getBeginTime() != null && timeBlock.getEndTime() != null && StringUtils.equals(timeBlock.getEarnCodeType(), HrConstants.EARN_CODE_TIME)) {
309 BigDecimal hours = TKUtils.getHoursBetween(timeBlock.getBeginTime().getTime(), timeBlock.getEndTime().getTime());
310
311
312
313
314 if (earnCodeObj.getInflateMinHours() != null) {
315 if ((earnCodeObj.getInflateMinHours().compareTo(BigDecimal.ZERO) != 0) &&
316 earnCodeObj.getInflateMinHours().compareTo(hours) > 0) {
317
318 if(previousTimeBlock != null && StringUtils.equals(earnCodeObj.getEarnCode(),previousTimeBlock.getEarnCode()) &&
319 (timeBlock.getBeginTime().getTime() - previousTimeBlock.getEndTime().getTime() == 0L)) {
320 BigDecimal prevTimeBlockHours = TKUtils.getHoursBetween(previousTimeBlock.getBeginTime().getTime(), previousTimeBlock.getEndTime().getTime());
321 previousTimeBlock.setHours(prevTimeBlockHours);
322 if(earnCodeObj.getInflateMinHours().compareTo(prevTimeBlockHours.add(hours,HrConstants.MATH_CONTEXT)) > 0) {
323
324 }
325 }
326 }
327 }
328
329
330
331
332
333
334
335
336 timeBlock.setHours(hours);
337 }
338 return timeBlock;
339 }
340
341 @Override
342 public void resetTimeBlock(List<TimeBlock> timeBlocks, LocalDate asOfDate) {
343 TimeBlock previous = null;
344 for (TimeBlock tb : timeBlocks) {
345 resetWorkedHours(previous, tb, asOfDate);
346 previous = tb;
347 }
348 TkServiceLocator.getTimeBlockService().resetTimeHourDetail(timeBlocks);
349 }
350
351 @Override
352 public boolean isReadyToApprove(TimesheetDocument document) {
353 if (document == null) {
354 return false;
355 }
356 List<LeaveBlock> leaveBlocks = LmServiceLocator.getLeaveBlockService().getLeaveBlocksWithType(document.getPrincipalId(),
357 document.getCalendarEntry().getBeginPeriodFullDateTime().toLocalDate(), document.getCalendarEntry().getEndPeriodFullDateTime().toLocalDate(), LMConstants.LEAVE_BLOCK_TYPE.BALANCE_TRANSFER);
358 leaveBlocks.addAll(LmServiceLocator.getLeaveBlockService().getLeaveBlocksWithType(document.getPrincipalId(),
359 document.getCalendarEntry().getBeginPeriodFullDateTime().toLocalDate(), document.getCalendarEntry().getEndPeriodFullDateTime().toLocalDate(), LMConstants.LEAVE_BLOCK_TYPE.LEAVE_PAYOUT));
360 for(LeaveBlock lb : leaveBlocks) {
361 if(!StringUtils.equals(lb.getRequestStatus(),HrConstants.REQUEST_STATUS.APPROVED) &&
362 !StringUtils.equals(lb.getRequestStatus(), HrConstants.REQUEST_STATUS.DISAPPROVED))
363 return false;
364 }
365 return true;
366 }
367
368 public List<EarnCode> getEarnCodesForTime(Assignment a, LocalDate asOfDate, boolean includeRegularEarnCode) {
369
370
371 if (a == null) {
372 LOG.error("No assignment parameter.");
373 return null;
374
375 }
376 Job job = a.getJob();
377 if (job == null || job.getPayTypeObj() == null) {
378 LOG.error("Null job or null job pay type on assignment.");
379 return null;
380
381 }
382
383 List<EarnCode> earnCodes = new LinkedList<EarnCode>();
384 String earnTypeCode = EarnCodeType.TIME.getCode();
385
386 TimeCollectionRule tcr = null;
387 if(a.getJob() != null)
388 tcr = TkServiceLocator.getTimeCollectionRuleService().getTimeCollectionRule(a.getDept(), a.getWorkArea(), a.getJob().getHrPayType(), asOfDate);
389
390 boolean isClockUser = tcr == null || tcr.isClockUserFl();
391 boolean isUsersTimesheet = StringUtils.equals(HrContext.getPrincipalId(),a.getPrincipalId());
392
393
394 EarnCode regularEarnCode = HrServiceLocator.getEarnCodeService().getEarnCode(job.getPayTypeObj().getRegEarnCode(), asOfDate);
395 if (regularEarnCode == null) {
396 LOG.error("No regular earn code defined for job pay type.");
397 return null;
398
399 } else {
400
401 if (!isClockUser || !isUsersTimesheet || includeRegularEarnCode) {
402 earnCodes.add(regularEarnCode);
403 }
404 }
405
406 List<String> listAccrualCategories = new LinkedList<String>();
407 String accrualCategory;
408
409
410 PrincipalHRAttributes principalHRAttributes = HrServiceLocator.getPrincipalHRAttributeService().getPrincipalCalendar(job.getPrincipalId(), asOfDate);
411 boolean fmlaEligible = principalHRAttributes.isFmlaEligible();
412 boolean workersCompEligible = principalHRAttributes.isWorkersCompEligible();
413
414 String leavePlan = principalHRAttributes.getLeavePlan();
415 if (leavePlan != null) {
416 for (AccrualCategory accrualCategories : HrServiceLocator.getAccrualCategoryService().getActiveAccrualCategoriesForLeavePlan(leavePlan, asOfDate)) {
417 accrualCategory = accrualCategories.getAccrualCategory();
418 if(accrualCategory != null) {
419 listAccrualCategories.add(accrualCategory);
420 }
421 }
422 }
423
424
425 List<EarnCodeSecurity> decs = HrServiceLocator.getEarnCodeSecurityService().getEarnCodeSecurities(job.getDept(), job.getHrSalGroup(), job.getLocation(), asOfDate);
426 for (EarnCodeSecurity dec : decs) {
427
428 boolean addEarnCode = HrServiceLocator.getEarnCodeService().addEarnCodeBasedOnEmployeeApproverSettings(dec, a, asOfDate);
429 if (addEarnCode) {
430
431
432 if (earnTypeCode.equals(dec.getEarnCodeType()) || EarnCodeType.BOTH.getCode().equals(dec.getEarnCodeType())) {
433 EarnCode ec = HrServiceLocator.getEarnCodeService().getEarnCode(dec.getEarnCode(), asOfDate);
434
435
436 if (ec != null) {
437
438
439
440 if( (StringUtils.isNotBlank(leavePlan) && StringUtils.isBlank(ec.getLeavePlan()))
441 || (StringUtils.isNotBlank(leavePlan) && StringUtils.isNotBlank(ec.getLeavePlan()) && leavePlan.equals(ec.getLeavePlan()))
442 || (StringUtils.isBlank(leavePlan) && StringUtils.isBlank(ec.getLeavePlan()))) {
443
444
445
446
447
448
449
450
451 if ( (fmlaEligible || ec.getFmla().equals("N")) ) {
452 if (ec.getAccrualCategory() == null
453 || (listAccrualCategories.contains(ec.getAccrualCategory())
454 && HrConstants.ACCRUAL_BALANCE_ACTION.USAGE.equals(ec.getAccrualBalanceAction()))) {
455
456
457
458 if ( (workersCompEligible || ec.getWorkmansComp().equals("N")) ) {
459
460
461
462 if ( showEarnCodeIfHoliday(ec, dec) ) {
463
464
465
466 if (!StringUtils.equals(regularEarnCode.getEarnCode(), dec.getEarnCode()) ) {
467
468 earnCodes.add(ec);
469 }
470 }
471 }
472 }
473 }
474 }
475 }
476 }
477 }
478 }
479
480 return earnCodes;
481 }
482
483 public List<EarnCode> getEarnCodesForTime(Assignment a, LocalDate asOfDate) {
484 return getEarnCodesForTime(a, asOfDate, false);
485 }
486
487 private boolean showEarnCodeIfHoliday(EarnCode earnCode, EarnCodeSecurity security) {
488 if (earnCode.getEarnCode().equals(HrConstants.HOLIDAY_EARN_CODE)) {
489 if (security.isApprover() || HrContext.isSystemAdmin()) {
490 return true;
491 } else {
492 return false;
493 }
494 } else {
495 return true;
496 }
497 }
498
499 public HRPermissionService getHRPermissionService() {
500 if (hrPermissionService == null) {
501 hrPermissionService = HrServiceLocator.getHRPermissionService();
502 }
503 return hrPermissionService;
504 }
505
506 private void clearTimesheetTimeblockPermissions(TimesheetDocument doc) {
507 for (TimeBlock tb : doc.getTimeBlocks()) {
508 getHRPermissionService().updateTimeBlockPermissions(CalendarBlockPermissions.newInstance(tb.getTkTimeBlockId()));
509 }
510 }
511 }