001 /** 002 * Copyright 2004-2013 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.kuali.hr.time.batch.service; 017 018 import java.text.ParseException; 019 import java.text.SimpleDateFormat; 020 import java.util.Date; 021 import java.util.HashMap; 022 import java.util.List; 023 import java.util.Map; 024 025 import org.apache.commons.exec.util.MapUtils; 026 import org.apache.commons.lang.ArrayUtils; 027 import org.apache.commons.lang.StringUtils; 028 import org.apache.log4j.Logger; 029 import org.joda.time.DateTime; 030 import org.kuali.hr.core.document.CalendarDocumentHeaderContract; 031 import org.kuali.hr.job.Job; 032 import org.kuali.hr.lm.leaveplan.LeavePlan; 033 import org.kuali.hr.lm.workflow.LeaveCalendarDocumentHeader; 034 import org.kuali.hr.lm.workflow.service.LeaveCalendarDocumentHeaderService; 035 import org.kuali.hr.time.assignment.Assignment; 036 import org.kuali.hr.time.assignment.service.AssignmentService; 037 import org.kuali.hr.time.batch.BatchJobUtil; 038 import org.kuali.hr.time.batch.CarryOverJob; 039 import org.kuali.hr.time.batch.EmployeeApprovalJob; 040 import org.kuali.hr.time.batch.EndPayPeriodJob; 041 import org.kuali.hr.time.batch.EndReportingPeriodJob; 042 import org.kuali.hr.time.batch.InitiateJob; 043 import org.kuali.hr.time.batch.MissedPunchApprovalJob; 044 import org.kuali.hr.time.batch.SupervisorApprovalJob; 045 import org.kuali.hr.time.calendar.Calendar; 046 import org.kuali.hr.time.calendar.CalendarEntries; 047 import org.kuali.hr.time.calendar.service.CalendarService; 048 import org.kuali.hr.time.clocklog.ClockLog; 049 import org.kuali.hr.time.clocklog.service.ClockLogService; 050 import org.kuali.hr.time.missedpunch.MissedPunchDocument; 051 import org.kuali.hr.time.missedpunch.service.MissedPunchService; 052 import org.kuali.hr.time.principal.PrincipalHRAttributes; 053 import org.kuali.hr.time.principal.service.PrincipalHRAttributesService; 054 import org.kuali.hr.time.util.TkConstants; 055 import org.kuali.hr.time.workflow.TimesheetDocumentHeader; 056 import org.kuali.hr.time.workflow.service.TimesheetDocumentHeaderService; 057 import org.kuali.rice.kew.api.document.DocumentStatus; 058 import org.quartz.JobDataMap; 059 import org.quartz.JobDetail; 060 import org.quartz.Scheduler; 061 import org.quartz.SchedulerException; 062 import org.quartz.SimpleTrigger; 063 import org.quartz.Trigger; 064 065 public class BatchJobServiceImpl implements BatchJobService { 066 067 private static final Logger LOG = Logger.getLogger(BatchJobServiceImpl.class); 068 069 private Scheduler scheduler; 070 071 private AssignmentService assignmentService; 072 private CalendarService calendarService; 073 private ClockLogService clockLogService; 074 private LeaveCalendarDocumentHeaderService leaveCalendarDocumentHeaderService; 075 private MissedPunchService missedPunchService; 076 private PrincipalHRAttributesService principalHRAttributesService; 077 private TimesheetDocumentHeaderService timesheetDocumentHeaderService; 078 079 @Override 080 public void scheduleInitiateJobs(CalendarEntries calendarEntry) throws SchedulerException { 081 scheduleInitiateJobs(calendarEntry, calendarEntry.getBatchInitiateDateTime()); 082 } 083 084 @Override 085 public void scheduleInitiateJobs(CalendarEntries calendarEntry, Date scheduleDate) throws SchedulerException { 086 Calendar calendar = getCalendarService().getCalendar(calendarEntry.getHrCalendarId()); 087 String calendarTypes = calendar.getCalendarTypes(); 088 String calendarName = calendar.getCalendarName(); 089 java.util.Date beginDate = calendarEntry.getBeginPeriodDateTime(); 090 java.util.Date endDate = calendarEntry.getEndPeriodDateTime(); 091 092 if (StringUtils.equals(calendarTypes, "Pay")) { 093 List<PrincipalHRAttributes> principalHRAttributes = getPrincipalHRAttributesService().getActiveEmployeesForPayCalendar(calendarName, scheduleDate); 094 095 for (PrincipalHRAttributes principalHRAttribute : principalHRAttributes) { 096 String principalId = principalHRAttribute.getPrincipalId(); 097 List<Assignment> assignments = getAssignmentService().getAssignmentsByCalEntryForTimeCalendar(principalId, calendarEntry); 098 099 for (Assignment assignment : assignments) { 100 Job job = assignment.getJob(); 101 102 if (StringUtils.equalsIgnoreCase(job.getFlsaStatus(), TkConstants.FLSA_STATUS_EXEMPT)) { 103 TimesheetDocumentHeader timesheetDocumentHeader = getTimesheetDocumentHeaderService().getDocumentHeader(principalId, beginDate, endDate); 104 if (timesheetDocumentHeader == null || StringUtils.equals(timesheetDocumentHeader.getDocumentStatus(), TkConstants.ROUTE_STATUS.CANCEL)) { 105 scheduleInitiateJob(calendarEntry, scheduleDate, assignment.getPrincipalId()); 106 } 107 } 108 } 109 } 110 } else if (StringUtils.equals(calendarTypes, "Leave")) { 111 List<PrincipalHRAttributes> principalHRAttributes = getPrincipalHRAttributesService().getActiveEmployeesForLeaveCalendar(calendarName, scheduleDate); 112 113 for (PrincipalHRAttributes principalHRAttribute : principalHRAttributes) { 114 String principalId = principalHRAttribute.getPrincipalId(); 115 List<Assignment> assignments = getAssignmentService().getAssignmentsByCalEntryForLeaveCalendar(principalId, calendarEntry); 116 117 for (Assignment assignment : assignments) { 118 Job job = assignment.getJob(); 119 120 if (job.isEligibleForLeave() && StringUtils.equalsIgnoreCase(job.getFlsaStatus(), TkConstants.FLSA_STATUS_NON_EXEMPT)) { 121 LeaveCalendarDocumentHeader leaveCalendarDocumentHeader = getLeaveCalendarDocumentHeaderService().getDocumentHeader(principalId, beginDate, endDate); 122 if (leaveCalendarDocumentHeader == null || StringUtils.equals(leaveCalendarDocumentHeader.getDocumentStatus(), TkConstants.ROUTE_STATUS.CANCEL)) { 123 scheduleInitiateJob(calendarEntry, scheduleDate, assignment.getPrincipalId()); 124 } 125 } 126 } 127 } 128 } 129 } 130 131 private void scheduleInitiateJob(CalendarEntries calendarEntry, Date scheduleDate, String principalId) throws SchedulerException { 132 Map<String, String> jobGroupDataMap = new HashMap<String, String>(); 133 jobGroupDataMap.put("hrCalendarEntriesId", calendarEntry.getHrCalendarEntriesId()); 134 135 Map<String, String> jobDataMap = new HashMap<String, String>(); 136 jobDataMap.put("principalId", principalId); 137 138 scheduleJob(InitiateJob.class, scheduleDate, jobGroupDataMap, jobDataMap); 139 } 140 141 @Override 142 public void scheduleEndReportingPeriodJobs(CalendarEntries calendarEntry) throws SchedulerException { 143 scheduleEndReportingPeriodJobs(calendarEntry, calendarEntry.getEndPeriodDateTime()); 144 } 145 146 @Override 147 public void scheduleEndReportingPeriodJobs(CalendarEntries calendarEntry, Date scheduleDate) throws SchedulerException { 148 Calendar calendar = getCalendarService().getCalendar(calendarEntry.getHrCalendarId()); 149 String calendarTypes = calendar.getCalendarTypes(); 150 String calendarName = calendar.getCalendarName(); 151 java.util.Date beginDate = calendarEntry.getBeginPeriodDateTime(); 152 java.util.Date endDate = calendarEntry.getEndPeriodDateTime(); 153 154 if (StringUtils.equals(calendarTypes, "Pay")) { 155 List<PrincipalHRAttributes> principalHRAttributes = getPrincipalHRAttributesService().getActiveEmployeesForPayCalendar(calendarName, scheduleDate); 156 157 for (PrincipalHRAttributes principalHRAttribute : principalHRAttributes) { 158 String principalId = principalHRAttribute.getPrincipalId(); 159 TimesheetDocumentHeader timesheetDocumentHeader = getTimesheetDocumentHeaderService().getDocumentHeader(principalId, beginDate, endDate); 160 161 if (timesheetDocumentHeader != null) { 162 scheduleEndReportingPeriodJob(calendarEntry, scheduleDate, principalId); 163 } 164 } 165 } else if (StringUtils.equals(calendarTypes, "Leave")) { 166 List<PrincipalHRAttributes> principalHRAttributes = getPrincipalHRAttributesService().getActiveEmployeesForLeaveCalendar(calendarName, scheduleDate); 167 168 for (PrincipalHRAttributes principalHRAttribute : principalHRAttributes) { 169 String principalId = principalHRAttribute.getPrincipalId(); 170 LeaveCalendarDocumentHeader leaveCalendarDocumentHeader = getLeaveCalendarDocumentHeaderService().getDocumentHeader(principalId, beginDate, endDate); 171 172 if (leaveCalendarDocumentHeader != null) { 173 scheduleEndReportingPeriodJob(calendarEntry, scheduleDate, principalId); 174 } 175 } 176 } 177 } 178 179 private void scheduleEndReportingPeriodJob(CalendarEntries calendarEntry, Date scheduleDate, String principalId) throws SchedulerException { 180 Map<String, String> jobGroupDataMap = new HashMap<String, String>(); 181 jobGroupDataMap.put("hrCalendarEntriesId", calendarEntry.getHrCalendarEntriesId()); 182 183 Map<String, String> jobDataMap = new HashMap<String, String>(); 184 jobDataMap.put("principalId", principalId); 185 186 scheduleJob(EndReportingPeriodJob.class, scheduleDate, jobGroupDataMap, jobDataMap); 187 } 188 189 @Override 190 public void scheduleEndPayPeriodJobs(CalendarEntries calendarEntry) throws SchedulerException { 191 scheduleEndPayPeriodJobs(calendarEntry, calendarEntry.getBatchEndPayPeriodDateTime()); 192 } 193 194 @Override 195 public void scheduleEndPayPeriodJobs(CalendarEntries calendarEntry, Date scheduleDate) throws SchedulerException { 196 String calendarName = calendarEntry.getCalendarName(); 197 198 List<PrincipalHRAttributes> principalHRAttributes = getPrincipalHRAttributesService().getActiveEmployeesForPayCalendar(calendarName, scheduleDate); 199 for (PrincipalHRAttributes principalHRAttribute : principalHRAttributes) { 200 String principalId = principalHRAttribute.getPrincipalId(); 201 202 List<Assignment> assignments = getAssignmentService().getAssignmentsByCalEntryForTimeCalendar(principalId, calendarEntry); 203 for (Assignment assignment : assignments) { 204 String jobNumber = String.valueOf(assignment.getJobNumber()); 205 String workArea = String.valueOf(assignment.getWorkArea()); 206 String task = String.valueOf(assignment.getTask()); 207 208 ClockLog lastClockLog = getClockLogService().getLastClockLog(principalId, jobNumber, workArea, task, calendarEntry); 209 if (lastClockLog != null && TkConstants.ON_THE_CLOCK_CODES.contains(lastClockLog.getClockAction())) { 210 scheduleEndPayPeriodJob(calendarEntry, scheduleDate, lastClockLog); 211 } 212 } 213 } 214 } 215 216 private void scheduleEndPayPeriodJob(CalendarEntries calendarEntry, Date scheduleDate, ClockLog clockLog) throws SchedulerException { 217 Map<String, String> jobGroupDataMap = new HashMap<String, String>(); 218 jobGroupDataMap.put("hrCalendarEntriesId", calendarEntry.getHrCalendarEntriesId()); 219 220 Map<String, String> jobDataMap = new HashMap<String, String>(); 221 jobDataMap.put("tkClockLogId", clockLog.getTkClockLogId()); 222 223 scheduleJob(EndPayPeriodJob.class, scheduleDate, jobGroupDataMap, jobDataMap); 224 } 225 226 @Override 227 public void scheduleEmployeeApprovalJobs(CalendarEntries calendarEntry) throws SchedulerException { 228 scheduleEmployeeApprovalJobs(calendarEntry, calendarEntry.getBatchEmployeeApprovalDateTime()); 229 } 230 231 @Override 232 public void scheduleEmployeeApprovalJobs(CalendarEntries calendarEntry, Date scheduleDate) throws SchedulerException { 233 java.util.Date beginDate = calendarEntry.getBeginPeriodDateTime(); 234 java.util.Date endDate = calendarEntry.getEndPeriodDateTime(); 235 Calendar calendar = getCalendarService().getCalendar(calendarEntry.getHrCalendarId()); 236 237 if (StringUtils.equals(calendar.getCalendarTypes(), "Pay")) { 238 List<TimesheetDocumentHeader> timesheetDocumentHeaders = getTimesheetDocumentHeaderService().getDocumentHeaders(beginDate, endDate); 239 for (TimesheetDocumentHeader timesheetDocumentHeader : timesheetDocumentHeaders) { 240 scheduleEmployeeApprovalJob(calendarEntry, scheduleDate, timesheetDocumentHeader); 241 } 242 } else if (StringUtils.equals(calendar.getCalendarTypes(), "Leave")) { 243 List<LeaveCalendarDocumentHeader> leaveCalendarDocumentHeaders = getLeaveCalendarDocumentHeaderService().getDocumentHeaders(beginDate, endDate); 244 for (LeaveCalendarDocumentHeader leaveCalendarDocumentHeader : leaveCalendarDocumentHeaders) { 245 scheduleEmployeeApprovalJob(calendarEntry, scheduleDate, leaveCalendarDocumentHeader); 246 } 247 } 248 } 249 250 private void scheduleEmployeeApprovalJob(CalendarEntries calendarEntry, Date scheduleDate, CalendarDocumentHeaderContract calendarDocumentHeaderContract) throws SchedulerException { 251 Map<String, String> jobGroupDataMap = new HashMap<String, String>(); 252 jobGroupDataMap.put("hrCalendarEntriesId", calendarEntry.getHrCalendarEntriesId()); 253 254 Map<String, String> jobDataMap = new HashMap<String, String>(); 255 jobDataMap.put("documentId", calendarDocumentHeaderContract.getDocumentId()); 256 257 scheduleJob(EmployeeApprovalJob.class, scheduleDate, jobGroupDataMap, jobDataMap); 258 } 259 260 @Override 261 public void scheduleMissedPunchApprovalJobs(CalendarEntries calendarEntry) throws SchedulerException { 262 scheduleMissedPunchApprovalJobs(calendarEntry, calendarEntry.getBatchSupervisorApprovalDateTime()); 263 } 264 265 @Override 266 public void scheduleMissedPunchApprovalJobs(CalendarEntries calendarEntry, Date scheduleDate) throws SchedulerException { 267 java.util.Date beginDate = calendarEntry.getBeginPeriodDateTime(); 268 java.util.Date endDate = calendarEntry.getEndPeriodDateTime(); 269 270 List<TimesheetDocumentHeader> timesheetDocumentHeaders = getTimesheetDocumentHeaderService().getDocumentHeaders(beginDate, endDate); 271 for (TimesheetDocumentHeader timesheetDocumentHeader : timesheetDocumentHeaders) { 272 List<MissedPunchDocument> missedPunchDocuments = getMissedPunchService().getMissedPunchDocsByTimesheetDocumentId(timesheetDocumentHeader.getDocumentId()); 273 for (MissedPunchDocument missedPunchDocument : missedPunchDocuments) { 274 if (StringUtils.equals(missedPunchDocument.getDocumentStatus(), DocumentStatus.ENROUTE.getCode())) { 275 scheduleMissedPunchApprovalJob(calendarEntry, scheduleDate, missedPunchDocument); 276 } 277 } 278 } 279 } 280 281 private void scheduleMissedPunchApprovalJob(CalendarEntries calendarEntry, Date scheduleDate, MissedPunchDocument missedPunchDocument) throws SchedulerException { 282 Map<String, String> jobGroupDataMap = new HashMap<String, String>(); 283 jobGroupDataMap.put("hrCalendarEntriesId", calendarEntry.getHrCalendarEntriesId()); 284 285 Map<String, String> jobDataMap = new HashMap<String, String>(); 286 jobDataMap.put("principalId", missedPunchDocument.getPrincipalId()); 287 288 scheduleJob(MissedPunchApprovalJob.class, scheduleDate, jobGroupDataMap, jobDataMap); 289 } 290 291 @Override 292 public void scheduleSupervisorApprovalJobs(CalendarEntries calendarEntry) throws SchedulerException { 293 scheduleSupervisorApprovalJobs(calendarEntry, calendarEntry.getBatchSupervisorApprovalDateTime()); 294 } 295 296 @Override 297 public void scheduleSupervisorApprovalJobs(CalendarEntries calendarEntry, Date scheduleDate) throws SchedulerException { 298 java.util.Date beginDate = calendarEntry.getBeginPeriodDateTime(); 299 java.util.Date endDate = calendarEntry.getEndPeriodDateTime(); 300 Calendar calendar = getCalendarService().getCalendar(calendarEntry.getHrCalendarId()); 301 302 if (StringUtils.equals(calendar.getCalendarTypes(), "Pay")) { 303 List<TimesheetDocumentHeader> timesheetDocumentHeaders = getTimesheetDocumentHeaderService().getDocumentHeaders(beginDate, endDate); 304 for (TimesheetDocumentHeader timesheetDocumentHeader : timesheetDocumentHeaders) { 305 scheduleSupervisorApprovalJob(calendarEntry, scheduleDate, timesheetDocumentHeader); 306 } 307 } else if (StringUtils.equals(calendar.getCalendarTypes(), "Leave")) { 308 List<LeaveCalendarDocumentHeader> leaveCalendarDocumentHeaders = getLeaveCalendarDocumentHeaderService().getDocumentHeaders(beginDate, endDate); 309 for (LeaveCalendarDocumentHeader leaveCalendarDocumentHeader : leaveCalendarDocumentHeaders) { 310 scheduleSupervisorApprovalJob(calendarEntry, scheduleDate, leaveCalendarDocumentHeader); 311 } 312 } 313 } 314 315 private void scheduleSupervisorApprovalJob(CalendarEntries calendarEntry, Date scheduleDate, CalendarDocumentHeaderContract calendarDocumentHeaderContract) throws SchedulerException { 316 Map<String, String> jobGroupDataMap = new HashMap<String, String>(); 317 jobGroupDataMap.put("hrCalendarEntriesId", calendarEntry.getHrCalendarEntriesId()); 318 319 Map<String, String> jobDataMap = new HashMap<String, String>(); 320 jobDataMap.put("documentId", calendarDocumentHeaderContract.getDocumentId()); 321 322 scheduleJob(SupervisorApprovalJob.class, scheduleDate, jobGroupDataMap, jobDataMap); 323 } 324 325 326 @Override 327 public void scheduleLeaveCarryOverJobs(LeavePlan leavePlan) throws SchedulerException { 328 String batchJobDate = leavePlan.getBatchPriorYearCarryOverStartDate(); 329 java.util.Calendar batchJobTimeCal = java.util.Calendar.getInstance(); 330 batchJobTimeCal.setTimeInMillis(leavePlan.getBatchPriorYearCarryOverStartTime().getTime()); 331 SimpleDateFormat sdf = new SimpleDateFormat("MM/dd"); 332 sdf.setLenient(false); 333 java.util.Date batchJobStart = null; 334 335 try { 336 batchJobStart = sdf.parse(batchJobDate); 337 } catch (ParseException e) { 338 } 339 340 java.util.Calendar batchJobStartDateTime = java.util.Calendar.getInstance(); 341 batchJobStartDateTime.setTime(batchJobStart); 342 batchJobStartDateTime.set(java.util.Calendar.YEAR,java.util.Calendar.getInstance().get(java.util.Calendar.YEAR)); 343 batchJobStartDateTime.set(java.util.Calendar.HOUR_OF_DAY,batchJobTimeCal.get(java.util.Calendar.HOUR_OF_DAY)); 344 batchJobStartDateTime.set(java.util.Calendar.MINUTE,batchJobTimeCal.get(java.util.Calendar.MINUTE)); 345 batchJobStartDateTime.set(java.util.Calendar.SECOND, 0); 346 batchJobStartDateTime.set(java.util.Calendar.MILLISECOND, 0); 347 348 scheduleLeaveCarryOverJob(leavePlan, batchJobStartDateTime.getTime()); 349 } 350 351 @Override 352 public void scheduleLeaveCarryOverJobs(LeavePlan leavePlan, Date scheduleDate) throws SchedulerException { 353 scheduleLeaveCarryOverJob(leavePlan, scheduleDate); 354 } 355 356 private void scheduleLeaveCarryOverJob(LeavePlan leavePlan, Date scheduleDate) throws SchedulerException { 357 Map<String, String> jobGroupDataMap = new HashMap<String, String>(); 358 jobGroupDataMap.put("date", BatchJobUtil.FORMAT.print(new DateTime(scheduleDate))); 359 Map<String, String> jobDataMap = new HashMap<String, String>(); 360 jobDataMap.put("leavePlan", leavePlan.getLeavePlan()); 361 scheduleJob(CarryOverJob.class, scheduleDate, jobGroupDataMap, jobDataMap); 362 } 363 364 @SuppressWarnings("unchecked") 365 private void scheduleJob(Class<?> jobClass, Date jobDate, Map<String, String> jobGroupDataMap, Map<String, String> jobDataMap) throws SchedulerException { 366 String jobGroupName = BatchJobUtil.getJobGroupName(jobClass, jobGroupDataMap); 367 String jobName = BatchJobUtil.getJobName(jobClass, jobDataMap); 368 String[] jobNames = getScheduler().getJobNames(jobGroupName); 369 if (!ArrayUtils.contains(jobNames, jobName)) { 370 Map<String, String> mergedDataMap = MapUtils.merge(jobGroupDataMap, jobDataMap); 371 372 JobDetail jobDetail = new JobDetail(jobName, jobGroupName, jobClass, false, true, false); 373 jobDetail.setJobDataMap(new JobDataMap(mergedDataMap)); 374 375 String triggerGroupName = BatchJobUtil.getTriggerGroupName(jobClass, MapUtils.merge(jobGroupDataMap, jobDataMap)); 376 String triggerName = BatchJobUtil.getTriggerName(jobClass, jobDate); 377 Trigger trigger = new SimpleTrigger(triggerName, triggerGroupName, jobDate); 378 trigger.setJobGroup(jobGroupName); 379 trigger.setJobName(jobName); 380 381 LOG.info("Scheduing " + jobDetail.getFullName() + " to be run on " + jobDate); 382 383 getScheduler().scheduleJob(jobDetail, trigger); 384 } 385 } 386 387 public Scheduler getScheduler() { 388 return scheduler; 389 } 390 391 public void setScheduler(Scheduler scheduler) { 392 this.scheduler = scheduler; 393 } 394 395 public AssignmentService getAssignmentService() { 396 return assignmentService; 397 } 398 399 public void setAssignmentService(AssignmentService assignmentService) { 400 this.assignmentService = assignmentService; 401 } 402 403 public CalendarService getCalendarService() { 404 return calendarService; 405 } 406 407 public void setCalendarService(CalendarService calendarService) { 408 this.calendarService = calendarService; 409 } 410 411 public ClockLogService getClockLogService() { 412 return clockLogService; 413 } 414 415 public void setClockLogService(ClockLogService clockLogService) { 416 this.clockLogService = clockLogService; 417 } 418 419 public LeaveCalendarDocumentHeaderService getLeaveCalendarDocumentHeaderService() { 420 return leaveCalendarDocumentHeaderService; 421 } 422 423 public void setLeaveCalendarDocumentHeaderService(LeaveCalendarDocumentHeaderService leaveCalendarDocumentHeaderService) { 424 this.leaveCalendarDocumentHeaderService = leaveCalendarDocumentHeaderService; 425 } 426 427 public MissedPunchService getMissedPunchService() { 428 return missedPunchService; 429 } 430 431 public void setMissedPunchService(MissedPunchService missedPunchService) { 432 this.missedPunchService = missedPunchService; 433 } 434 435 public PrincipalHRAttributesService getPrincipalHRAttributesService() { 436 return principalHRAttributesService; 437 } 438 439 public void setPrincipalHRAttributesService(PrincipalHRAttributesService principalHRAttributesService) { 440 this.principalHRAttributesService = principalHRAttributesService; 441 } 442 443 public TimesheetDocumentHeaderService getTimesheetDocumentHeaderService() { 444 return timesheetDocumentHeaderService; 445 } 446 447 public void setTimesheetDocumentHeaderService(TimesheetDocumentHeaderService timesheetDocumentHeaderService) { 448 this.timesheetDocumentHeaderService = timesheetDocumentHeaderService; 449 } 450 451 }