View Javadoc

1   /**
2    * Copyright 2004-2013 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.hr.time.batch;
17  
18  import org.apache.commons.collections.CollectionUtils;
19  import org.apache.log4j.Logger;
20  import org.joda.time.DateTime;
21  import org.joda.time.LocalDate;
22  import org.joda.time.LocalDateTime;
23  import org.kuali.hr.lm.LMConstants;
24  import org.kuali.hr.lm.accrual.AccrualCategory;
25  import org.kuali.hr.lm.accrual.service.AccrualCategoryService;
26  import org.kuali.hr.lm.leaveSummary.LeaveSummary;
27  import org.kuali.hr.lm.leaveSummary.LeaveSummaryRow;
28  import org.kuali.hr.lm.leaveSummary.service.LeaveSummaryService;
29  import org.kuali.hr.lm.leaveblock.LeaveBlock;
30  import org.kuali.hr.lm.leaveblock.service.LeaveBlockService;
31  import org.kuali.hr.lm.leaveplan.LeavePlan;
32  import org.kuali.hr.lm.leaveplan.service.LeavePlanService;
33  import org.kuali.hr.time.assignment.Assignment;
34  import org.kuali.hr.time.assignment.service.AssignmentService;
35  import org.kuali.hr.time.calendar.service.CalendarEntriesService;
36  import org.kuali.hr.time.principal.PrincipalHRAttributes;
37  import org.kuali.hr.time.principal.service.PrincipalHRAttributesService;
38  import org.kuali.hr.time.service.base.TkServiceLocator;
39  import org.kuali.hr.time.util.TKUtils;
40  import org.kuali.hr.time.util.TkConstants;
41  import org.kuali.rice.core.api.config.property.ConfigContext;
42  import org.kuali.rice.kim.api.identity.principal.Principal;
43  import org.kuali.rice.kim.api.services.KimApiServiceLocator;
44  import org.quartz.Job;
45  import org.quartz.JobDataMap;
46  import org.quartz.JobExecutionContext;
47  import org.quartz.JobExecutionException;
48  
49  import java.sql.Date;
50  import java.sql.Timestamp;
51  import java.util.*;
52  
53  public class CarryOverJob implements Job{
54  
55  	private static final Logger LOG = Logger.getLogger(CarryOverJob.class);
56  
57  	private AccrualCategoryService accrualCategoryService;
58  	private AssignmentService assignmentService;
59  	private LeavePlanService leavePlanService;
60  	private PrincipalHRAttributesService principalHRAttributesService;
61  	private LeaveSummaryService leaveSummaryService;
62  	private CalendarEntriesService calendarEntriesService;
63  	private LeaveBlockService leaveBlockService;
64  
65  	@Override
66  	public void execute(JobExecutionContext context) throws JobExecutionException {
67          String batchUserPrincipalId = getBatchUserPrincipalId();
68  
69          if (batchUserPrincipalId != null) {
70              JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
71              String leavePlan = jobDataMap.getString("leavePlan");
72              if (leavePlan!= null) {
73  
74                  Date asOfDate = TKUtils.getCurrentDate();
75                  LeavePlan leavePlanObj = getLeavePlanService().getLeavePlan(leavePlan, asOfDate);
76                  List<Assignment> assignments = getAssignmentService().getActiveAssignments(asOfDate);
77  
78                  //holds a list of principalIds so this isn't run multiple time for the same person
79                  Set<String> principalIds = new HashSet<String>();
80                  for (Assignment assignment : assignments) {
81                      String principalId = assignment.getPrincipalId();
82                      if (assignment.getJob().isEligibleForLeave() && !principalIds.contains(principalId)) {
83  
84                          PrincipalHRAttributes principalHRAttributes = getPrincipalHRAttributesService().getPrincipalCalendar(principalId, asOfDate);
85                          principalIds.add(principalId);
86  
87                          if (principalHRAttributes != null) {
88                              Date serviceDate = principalHRAttributes.getServiceDate();
89                              if(serviceDate != null){
90  
91                                  if (leavePlanObj != null && leavePlanObj.getLeavePlan().equalsIgnoreCase(principalHRAttributes.getLeavePlan())) {
92  
93                                      DateTime leavePlanStartDate = getLeavePlanService().getFirstDayOfLeavePlan(leavePlan, TKUtils.getCurrentDate());
94  
95                                      DateTime lpPreviousLastDay = (new LocalDateTime(leavePlanStartDate)).toDateTime().minus(1);
96                                      DateTime lpPreviousFirstDay = new DateTime(getLeavePlanService().getFirstDayOfLeavePlan(leavePlan, new Date(lpPreviousLastDay.toDateTime().toDateMidnight().getMillis())));
97  
98                                      List<LeaveBlock> prevYearCarryOverleaveBlocks = getLeaveBlockService().getLeaveBlocksWithType(principalId,  lpPreviousFirstDay.toDateMidnight().toDate(), lpPreviousLastDay.toDateMidnight().toDate(), LMConstants.LEAVE_BLOCK_TYPE.CARRY_OVER);
99                                      LeaveSummary leaveSummary = getLeaveSummaryService().getLeaveSummaryAsOfDateWithoutFuture(principalId, new java.sql.Date(lpPreviousLastDay.getMillis()));
100                                     //no existing carry over blocks.  just create new
101                                     if(CollectionUtils.isEmpty(prevYearCarryOverleaveBlocks)){
102                                         getLeaveBlockService().saveLeaveBlocks(createCarryOverLeaveBlocks(principalId, lpPreviousLastDay, leaveSummary));
103                                     } else {
104                                         Map<String, LeaveBlock> existingCarryOver = new HashMap<String, LeaveBlock>(prevYearCarryOverleaveBlocks.size());
105                                         // just easier to get to things when in a map...
106                                         for (LeaveBlock lb : prevYearCarryOverleaveBlocks) {
107                                             existingCarryOver.put(lb.getAccrualCategory(), lb);
108                                         }
109 
110                                         // update existing first
111                                         for (Map.Entry<String, LeaveBlock> entry : existingCarryOver.entrySet()) {
112                                             LeaveBlock carryOverBlock = entry.getValue();
113                                             LeaveSummaryRow lsr = leaveSummary.getLeaveSummaryRowForAccrualCtgy(entry.getKey());
114 
115                                             //update values
116                                             if(lsr.getAccruedBalance() != null)  {
117                                                 if(lsr.getMaxCarryOver() != null && lsr.getAccruedBalance().compareTo(lsr.getMaxCarryOver()) > 0 ){
118                                                     carryOverBlock.setLeaveAmount(lsr.getMaxCarryOver());
119                                                 } else {
120                                                     carryOverBlock.setLeaveAmount(lsr.getAccruedBalance());
121                                                 }
122                                             }
123                                             getLeaveBlockService().updateLeaveBlock(carryOverBlock, batchUserPrincipalId);
124                                             //remove row from leave summary
125                                             leaveSummary.getLeaveSummaryRows().remove(lsr);
126                                         }
127 
128 
129                                         // create for any new accrual categories
130                                         getLeaveBlockService().saveLeaveBlocks(createCarryOverLeaveBlocks(principalId, lpPreviousLastDay, leaveSummary));
131                                     }
132                                 }
133                             }
134                         }
135                     }
136                 }
137             }
138         } else {
139             String principalName = ConfigContext.getCurrentContextConfig().getProperty(TkConstants.BATCH_USER_PRINCIPAL_NAME);
140             LOG.error("Could not run batch jobs due to missing batch user " + principalName);
141         }
142 	
143 	}
144 
145 	private AccrualCategoryService getAccrualCategoryService() {
146         if (accrualCategoryService == null) {
147             accrualCategoryService = TkServiceLocator.getAccrualCategoryService();
148         }
149 		return accrualCategoryService;
150 	}
151 
152 	public void setAccrualCategoryService(AccrualCategoryService accrualCategoryService) {
153 		this.accrualCategoryService = accrualCategoryService;
154 	}
155 
156 	private AssignmentService getAssignmentService() {
157 		if (assignmentService == null) {
158             assignmentService = TkServiceLocator.getAssignmentService();
159         }
160 		return assignmentService;
161 	}
162 
163 	public void setAssignmentService(AssignmentService assignmentService) {
164 		this.assignmentService = assignmentService;
165 	}
166 
167 	public LeavePlanService getLeavePlanService() {
168         if (leavePlanService == null) {
169 		    leavePlanService = TkServiceLocator.getLeavePlanService();
170         }
171 		return leavePlanService;
172 	}
173 
174 	public void setLeavePlanService(LeavePlanService leavePlanService) {
175 		this.leavePlanService = leavePlanService;
176 	}
177 
178 	private PrincipalHRAttributesService getPrincipalHRAttributesService() {
179         if (principalHRAttributesService == null) {
180 		    principalHRAttributesService = TkServiceLocator.getPrincipalHRAttributeService();
181         }
182 		return principalHRAttributesService;
183 	}
184 
185 	public void setPrincipalHRAttributesService(PrincipalHRAttributesService principalHRAttributesService) {
186 		this.principalHRAttributesService = principalHRAttributesService;
187 	}
188 
189 	private LeaveSummaryService getLeaveSummaryService() {
190         if (leaveSummaryService == null) {
191 		    leaveSummaryService = TkServiceLocator.getLeaveSummaryService();
192         }
193 		return leaveSummaryService;
194 	}
195 
196 	public void setLeaveSummaryService(LeaveSummaryService leaveSummaryService) {
197 		this.leaveSummaryService = leaveSummaryService;
198 	}
199 
200 	private CalendarEntriesService getCalendarEntriesService() {
201         if (calendarEntriesService == null) {
202 		    calendarEntriesService = TkServiceLocator.getCalendarEntriesService();
203         }
204 		return calendarEntriesService;
205 	}
206 
207 	public void setCalendarEntriesService(CalendarEntriesService calendarEntriesService) {
208 		this.calendarEntriesService = calendarEntriesService;
209 	}
210 
211 	private LeaveBlockService getLeaveBlockService() {
212         if (leaveBlockService == null) {
213 		    leaveBlockService = TkServiceLocator.getLeaveBlockService();
214         }
215 		return leaveBlockService;
216 	}
217 
218 	public void setLeaveBlockService(LeaveBlockService leaveBlockService) {
219 		this.leaveBlockService = leaveBlockService;
220 	}
221 	
222 	private List<LeaveBlock> createCarryOverLeaveBlocks(String principalId,
223                                                         DateTime prevCalEndDate,
224                                                         LeaveSummary leaveSummary) {
225 
226         List<LeaveBlock> leaveBlocks = new ArrayList<LeaveBlock>();
227         List<LeaveSummaryRow> leaveSummaryRows = leaveSummary.getLeaveSummaryRows();
228         if(leaveSummaryRows !=null && !leaveSummaryRows.isEmpty()){
229 
230             for(LeaveSummaryRow lsr : leaveSummaryRows){
231                 AccrualCategory accrualCategory = getAccrualCategoryService().getAccrualCategory(lsr.getAccrualCategoryId());
232 
233                 LeaveBlock leaveBlock = new LeaveBlock();
234                 leaveBlock.setAccrualCategory(lsr.getAccrualCategory());
235                 leaveBlock.setLeaveDate(TKUtils.getTimelessDate(prevCalEndDate.toDateMidnight().toDate()));
236                 leaveBlock.setLeaveBlockType(LMConstants.LEAVE_BLOCK_TYPE.CARRY_OVER);
237 
238                 //More than one earn code can be associated with an accrual category. Which one does this get?
239                 if(accrualCategory != null && accrualCategory.getEarnCode() != null ){
240                     leaveBlock.setEarnCode(accrualCategory.getEarnCode());
241                 }
242 
243                 leaveBlock.setDateAndTime(new Timestamp(new java.util.Date().getTime()));
244                 leaveBlock.setAccrualGenerated(true);
245                 leaveBlock.setBlockId(0L);
246 
247                 // ASk--Set null
248                 leaveBlock.setScheduleTimeOffId(null);
249 
250                 if(lsr.getAccruedBalance() != null)  {
251                     if(lsr.getMaxCarryOver() != null && lsr.getAccruedBalance().compareTo(lsr.getMaxCarryOver()) > 0 ){
252                         leaveBlock.setLeaveAmount(lsr.getMaxCarryOver());
253                     } else {
254                         leaveBlock.setLeaveAmount(lsr.getAccruedBalance());
255                     }
256                 }
257 
258                 leaveBlock.setPrincipalId(principalId);
259                 leaveBlock.setRequestStatus(LMConstants.REQUEST_STATUS.APPROVED);
260 
261                 // Set EarnCode
262                 if(leaveBlock.getLeaveAmount() != null && leaveBlock.getEarnCode() != null) {
263                     leaveBlocks.add(leaveBlock);
264                 }
265             }
266         }
267 
268 
269 		return leaveBlocks;
270 	}
271 
272     private String getBatchUserPrincipalId() {
273         String principalName = ConfigContext.getCurrentContextConfig().getProperty(TkConstants.BATCH_USER_PRINCIPAL_NAME);
274         Principal principal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName(principalName);
275         return principal == null ? null : principal.getPrincipalId();
276     }
277 
278 }