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;
017    
018    import org.apache.commons.lang.StringUtils;
019    import org.apache.log4j.Logger;
020    import org.joda.time.DateTime;
021    import org.kuali.hr.lm.leavecalendar.LeaveCalendarDocument;
022    import org.kuali.hr.lm.workflow.LeaveCalendarDocumentHeader;
023    import org.kuali.hr.time.calendar.Calendar;
024    import org.kuali.hr.time.calendar.CalendarEntries;
025    import org.kuali.hr.time.missedpunch.MissedPunchDocument;
026    import org.kuali.hr.time.service.base.TkServiceLocator;
027    import org.kuali.hr.time.timesheet.TimesheetDocument;
028    import org.kuali.hr.time.util.TkConstants;
029    import org.kuali.hr.time.workflow.TimesheetDocumentHeader;
030    import org.kuali.rice.core.api.config.property.ConfigContext;
031    import org.kuali.rice.kew.actionitem.ActionItemActionListExtension;
032    import org.kuali.rice.kew.service.KEWServiceLocator;
033    import org.kuali.rice.kim.api.identity.principal.Principal;
034    import org.kuali.rice.kim.api.services.KimApiServiceLocator;
035    import org.quartz.*;
036    
037    import java.util.Collection;
038    import java.util.Date;
039    import java.util.List;
040    
041    public class SupervisorApprovalJob implements Job {
042            
043            private static final Logger LOG = Logger.getLogger(SupervisorApprovalJob.class);
044            
045            public void execute(JobExecutionContext context) throws JobExecutionException {
046                    String batchUserPrincipalId = getBatchUserPrincipalId();
047            
048                    if (batchUserPrincipalId != null) {
049                            JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
050            
051                            String hrCalendarEntriesId = jobDataMap.getString("hrCalendarEntriesId");
052                            String documentId = jobDataMap.getString("documentId");
053            
054                            CalendarEntries calendarEntry = TkServiceLocator.getCalendarEntriesService().getCalendarEntries(hrCalendarEntriesId);
055                            Calendar calendar = TkServiceLocator.getCalendarService().getCalendar(calendarEntry.getHrCalendarId());
056                                            
057                            if (StringUtils.equals(calendar.getCalendarTypes(), "Pay")) {
058                                    TimesheetDocumentHeader timesheetDocumentHeader = TkServiceLocator.getTimesheetDocumentHeaderService().getDocumentHeader(documentId);
059                                    if (timesheetDocumentHeader != null) {
060                                            if (missedPunchDocumentsNotFinal(documentId) || documentNotEnroute(documentId)) {
061                                                    rescheduleJob(context);
062                                            } else {
063                                                    TimesheetDocument timesheetDocument = TkServiceLocator.getTimesheetService().getTimesheetDocument(documentId);
064                                                    TkServiceLocator.getTimesheetService().approveTimesheet(batchUserPrincipalId, timesheetDocument, TkConstants.BATCH_JOB_ACTIONS.BATCH_JOB_APPROVE);
065                                            }
066                                    }
067                            } else if (StringUtils.equals(calendar.getCalendarTypes(), "Leave")) {
068                                    LeaveCalendarDocumentHeader leaveCalendarDocumentHeader = TkServiceLocator.getLeaveCalendarDocumentHeaderService().getDocumentHeader(documentId);
069                                    if (leaveCalendarDocumentHeader != null) {
070                                            if (documentNotEnroute(documentId)) {
071                                                    rescheduleJob(context);
072                                            } else {
073                                                    LeaveCalendarDocument leaveCalendarDocument = TkServiceLocator.getLeaveCalendarService().getLeaveCalendarDocument(documentId);
074                                                    TkServiceLocator.getLeaveCalendarService().approveLeaveCalendar(batchUserPrincipalId, leaveCalendarDocument, TkConstants.BATCH_JOB_ACTIONS.BATCH_JOB_APPROVE);
075                                            }
076                                    }
077                            }
078            } else {
079                    String principalName = ConfigContext.getCurrentContextConfig().getProperty(TkConstants.BATCH_USER_PRINCIPAL_NAME);
080                    LOG.error("Could not run batch jobs due to missing batch user " + principalName);
081            }
082            }
083            
084        private String getBatchUserPrincipalId() {
085            String principalName = ConfigContext.getCurrentContextConfig().getProperty(TkConstants.BATCH_USER_PRINCIPAL_NAME);
086            Principal principal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName(principalName);
087            return principal == null ? null : principal.getPrincipalId();
088        }
089            
090            private boolean missedPunchDocumentsNotFinal(String documentId) {
091                    boolean missedPunchDocumentsNotFinal = false;
092                    
093                    List<MissedPunchDocument> missedPunchDocuments = TkServiceLocator.getMissedPunchService().getMissedPunchDocsByTimesheetDocumentId(documentId);
094                    for (MissedPunchDocument missedPunchDocument : missedPunchDocuments) {
095                            Collection<ActionItemActionListExtension> actionItems = KEWServiceLocator.getActionListService().getActionListForSingleDocument(missedPunchDocument.getDocumentNumber());
096                            for (ActionItemActionListExtension actionItem : actionItems) {
097                                    if (!actionItem.getRouteHeader().isFinal()) {
098                                            missedPunchDocumentsNotFinal = true;
099                                            break;
100                                    }
101                            }
102                    }
103                    
104                    return missedPunchDocumentsNotFinal;
105            }
106            
107            private boolean documentNotEnroute(String documentId) {
108                    boolean documentNotInAStateToBeApproved = false;
109                    
110                    Collection<ActionItemActionListExtension> actionItems = KEWServiceLocator.getActionListService().getActionListForSingleDocument(documentId);
111                    for (ActionItemActionListExtension actionItem : actionItems) {
112                            if (!actionItem.getRouteHeader().isEnroute()) {
113                                    documentNotInAStateToBeApproved = true;
114                                    break;
115                            }
116                    }
117                    
118                    return documentNotInAStateToBeApproved;
119            }
120            
121            private void rescheduleJob(JobExecutionContext context) throws JobExecutionException {
122                    try {
123                            Scheduler scheduler = context.getScheduler();
124                            Trigger oldTrigger = context.getTrigger();
125                            
126                            Date newStartTime = new DateTime().plusMinutes(5).toDate();
127                            String newTriggerName = BatchJobUtil.getTriggerName(SupervisorApprovalJob.class, newStartTime);
128                            Trigger newTrigger = new SimpleTrigger(newTriggerName, oldTrigger.getGroup(), newStartTime);
129                            newTrigger.setJobName(oldTrigger.getJobName());
130                            newTrigger.setJobGroup(oldTrigger.getJobGroup());
131                            
132                            LOG.info("Rescheduing " + newTrigger.getFullJobName() + " to be run on " + newTrigger.getStartTime());
133                            
134                            scheduler.rescheduleJob(oldTrigger.getName(), oldTrigger.getGroup(), newTrigger);
135                    } catch (SchedulerException se) {
136                            throw new JobExecutionException(se);
137                    }
138            }
139            
140    }