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