View Javadoc
1   /**
2    * Copyright 2004-2014 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.kpme.tklm.leave.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.kpme.core.api.accrualcategory.AccrualCategoryContract;
24  import org.kuali.kpme.core.api.accrualcategory.AccrualCategoryService;
25  import org.kuali.kpme.core.api.assignment.Assignment;
26  import org.kuali.kpme.core.api.assignment.service.AssignmentService;
27  import org.kuali.kpme.core.api.calendar.entry.service.CalendarEntryService;
28  import org.kuali.kpme.core.api.leaveplan.LeavePlanContract;
29  import org.kuali.kpme.core.api.leaveplan.LeavePlanService;
30  import org.kuali.kpme.core.api.principal.PrincipalHRAttributes;
31  import org.kuali.kpme.core.api.principal.service.PrincipalHRAttributesService;
32  import org.kuali.kpme.core.batch.BatchJob;
33  import org.kuali.kpme.core.service.HrServiceLocator;
34  import org.kuali.kpme.core.util.HrConstants;
35  import org.kuali.kpme.tklm.api.leave.block.LeaveBlock;
36  import org.kuali.kpme.tklm.api.leave.block.LeaveBlockService;
37  import org.kuali.kpme.tklm.api.leave.summary.LeaveSummaryContract;
38  import org.kuali.kpme.tklm.api.leave.summary.LeaveSummaryRowContract;
39  import org.kuali.kpme.tklm.api.leave.summary.LeaveSummaryService;
40  import org.kuali.kpme.tklm.common.LMConstants;
41  import org.kuali.kpme.tklm.leave.block.LeaveBlockBo;
42  import org.kuali.kpme.tklm.leave.service.LmServiceLocator;
43  import org.quartz.JobDataMap;
44  import org.quartz.JobExecutionContext;
45  import org.quartz.JobExecutionException;
46  
47  import java.util.ArrayList;
48  import java.util.HashMap;
49  import java.util.HashSet;
50  import java.util.List;
51  import java.util.Map;
52  import java.util.Set;
53  
54  public class CarryOverJob extends BatchJob {
55  
56  	private static final Logger LOG = Logger.getLogger(CarryOverJob.class);
57  
58  	private AccrualCategoryService accrualCategoryService;
59  	private AssignmentService assignmentService;
60  	private LeavePlanService leavePlanService;
61  	private PrincipalHRAttributesService principalHRAttributesService;
62  	private LeaveSummaryService leaveSummaryService;
63  	private CalendarEntryService calendarEntryService;
64  	private LeaveBlockService leaveBlockService;
65  
66  	@Override
67  	public void execute(JobExecutionContext context) throws JobExecutionException {
68          String batchUserPrincipalId = getBatchUserPrincipalId();
69  
70          if (batchUserPrincipalId != null) {
71              JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
72              String leavePlan = jobDataMap.getString("leavePlan");
73              if (leavePlan!= null) {
74  
75              	LocalDate asOfDate = LocalDate.now();
76                  LeavePlanContract leavePlanObj = getLeavePlanService().getLeavePlan(leavePlan, asOfDate);
77                  List<Assignment> assignments = getAssignmentService().getActiveAssignments(asOfDate);
78  
79                  //holds a list of principalIds so this isn't run multiple time for the same person
80                  Set<String> principalIds = new HashSet<String>();
81                  for (Assignment assignment : assignments) {
82                      String principalId = assignment.getPrincipalId();
83                      if (assignment.getJob().isEligibleForLeave() && !principalIds.contains(principalId)) {
84  
85                          PrincipalHRAttributes principalHRAttributes = getPrincipalHRAttributesService().getPrincipalCalendar(principalId, asOfDate);
86                          principalIds.add(principalId);
87  
88                          if (principalHRAttributes != null) {
89                              LocalDate serviceDate = principalHRAttributes.getServiceLocalDate();
90                              if(serviceDate != null){
91  
92                                  if (leavePlanObj != null && leavePlanObj.getLeavePlan().equalsIgnoreCase(principalHRAttributes.getLeavePlan())) {
93  
94                                      DateTime leavePlanStartDate = getLeavePlanService().getFirstDayOfLeavePlan(leavePlan, LocalDate.now());
95  
96                                      DateTime lpPreviousLastDay = (new LocalDateTime(leavePlanStartDate)).toDateTime().minus(1);
97                                      DateTime lpPreviousFirstDay = getLeavePlanService().getFirstDayOfLeavePlan(leavePlan, lpPreviousLastDay.toLocalDate());
98  
99                                      List<LeaveBlock> prevYearCarryOverleaveBlocks = getLeaveBlockService().getLeaveBlocksWithType(principalId,  lpPreviousFirstDay.toLocalDate(), lpPreviousLastDay.toLocalDate(), LMConstants.LEAVE_BLOCK_TYPE.CARRY_OVER);
100                                     LeaveSummaryContract leaveSummary = getLeaveSummaryService().getLeaveSummaryAsOfDateWithoutFuture(principalId, lpPreviousLastDay.toLocalDate());
101                                     //no existing carry over blocks.  just create new
102                                     if(CollectionUtils.isEmpty(prevYearCarryOverleaveBlocks)){
103                                         getLeaveBlockService().saveLeaveBlocks(createCarryOverLeaveBlocks(principalId, lpPreviousLastDay, leaveSummary));
104                                     } else {
105                                         Map<String, LeaveBlock> existingCarryOver = new HashMap<String, LeaveBlock>(prevYearCarryOverleaveBlocks.size());
106                                         // just easier to get to things when in a map...
107                                         for (LeaveBlock lb : prevYearCarryOverleaveBlocks) {
108                                             existingCarryOver.put(lb.getAccrualCategory(), lb);
109                                         }
110 
111                                         // update existing first
112                                         for (Map.Entry<String, LeaveBlock> entry : existingCarryOver.entrySet()) {
113                                             LeaveBlock.Builder carryOverBlock = LeaveBlock.Builder.create(entry.getValue());
114                                             LeaveSummaryRowContract lsr = leaveSummary.getLeaveSummaryRowForAccrualCtgy(entry.getKey());
115 
116                                             //update values
117                                             if(lsr.getAccruedBalance() != null)  {
118                                                 if(lsr.getMaxCarryOver() != null && lsr.getAccruedBalance().compareTo(lsr.getMaxCarryOver()) > 0 ){
119                                                     carryOverBlock.setLeaveAmount(lsr.getMaxCarryOver());
120                                                 } else {
121                                                     carryOverBlock.setLeaveAmount(lsr.getAccruedBalance());
122                                                 }
123                                                 getLeaveBlockService().updateLeaveBlock(carryOverBlock.build(), batchUserPrincipalId);
124                                             }
125 
126                                             //remove row from leave summary
127                                             leaveSummary.getLeaveSummaryRows().remove(lsr);
128                                         }
129 
130 
131                                         // create for any new accrual categories
132                                         getLeaveBlockService().saveLeaveBlocks(createCarryOverLeaveBlocks(principalId, lpPreviousLastDay, leaveSummary));
133                                     }
134                                 }
135                             }
136                         }
137                     }
138                 }
139             }
140         } else {
141             String principalName = getBatchUserPrincipalName();
142             LOG.error("Could not run batch jobs due to missing batch user " + principalName);
143         }
144 	
145 	}
146 
147 	private AccrualCategoryService getAccrualCategoryService() {
148         if (accrualCategoryService == null) {
149             accrualCategoryService = HrServiceLocator.getAccrualCategoryService();
150         }
151 		return accrualCategoryService;
152 	}
153 
154 	public void setAccrualCategoryService(AccrualCategoryService accrualCategoryService) {
155 		this.accrualCategoryService = accrualCategoryService;
156 	}
157 
158 	private AssignmentService getAssignmentService() {
159 		if (assignmentService == null) {
160             assignmentService = HrServiceLocator.getAssignmentService();
161         }
162 		return assignmentService;
163 	}
164 
165 	public void setAssignmentService(AssignmentService assignmentService) {
166 		this.assignmentService = assignmentService;
167 	}
168 
169 	public LeavePlanService getLeavePlanService() {
170         if (leavePlanService == null) {
171 		    leavePlanService = HrServiceLocator.getLeavePlanService();
172         }
173 		return leavePlanService;
174 	}
175 
176 	public void setLeavePlanService(LeavePlanService leavePlanService) {
177 		this.leavePlanService = leavePlanService;
178 	}
179 
180 	private PrincipalHRAttributesService getPrincipalHRAttributesService() {
181         if (principalHRAttributesService == null) {
182 		    principalHRAttributesService = HrServiceLocator.getPrincipalHRAttributeService();
183         }
184 		return principalHRAttributesService;
185 	}
186 
187 	public void setPrincipalHRAttributesService(PrincipalHRAttributesService principalHRAttributesService) {
188 		this.principalHRAttributesService = principalHRAttributesService;
189 	}
190 
191 	private LeaveSummaryService getLeaveSummaryService() {
192         if (leaveSummaryService == null) {
193 		    leaveSummaryService = LmServiceLocator.getLeaveSummaryService();
194         }
195 		return leaveSummaryService;
196 	}
197 
198 	public void setLeaveSummaryService(LeaveSummaryService leaveSummaryService) {
199 		this.leaveSummaryService = leaveSummaryService;
200 	}
201 
202 	private CalendarEntryService getCalendarEntryService() {
203         if (calendarEntryService == null) {
204 		    calendarEntryService = HrServiceLocator.getCalendarEntryService();
205         }
206 		return calendarEntryService;
207 	}
208 
209 	public void setCalendarEntryService(CalendarEntryService calendarEntryService) {
210 		this.calendarEntryService = calendarEntryService;
211 	}
212 
213 	private LeaveBlockService getLeaveBlockService() {
214         if (leaveBlockService == null) {
215 		    leaveBlockService = LmServiceLocator.getLeaveBlockService();
216         }
217 		return leaveBlockService;
218 	}
219 
220 	public void setLeaveBlockService(LeaveBlockService leaveBlockService) {
221 		this.leaveBlockService = leaveBlockService;
222 	}
223 	
224 	private List<LeaveBlock> createCarryOverLeaveBlocks(String principalId,
225                                                         DateTime prevCalEndDate,
226                                                         LeaveSummaryContract leaveSummary) {
227 
228         List<LeaveBlock> leaveBlocks = new ArrayList<LeaveBlock>();
229         List<? extends LeaveSummaryRowContract> leaveSummaryRows = leaveSummary.getLeaveSummaryRows();
230         if(leaveSummaryRows !=null && !leaveSummaryRows.isEmpty()){
231 
232             for(LeaveSummaryRowContract lsr : leaveSummaryRows){
233                 AccrualCategoryContract accrualCategory = getAccrualCategoryService().getAccrualCategory(lsr.getAccrualCategoryId());
234 
235                 LeaveBlockBo leaveBlock = new LeaveBlockBo();
236                 leaveBlock.setAccrualCategory(lsr.getAccrualCategory());
237                 leaveBlock.setLeaveLocalDate(prevCalEndDate.toLocalDate());
238                 leaveBlock.setLeaveBlockType(LMConstants.LEAVE_BLOCK_TYPE.CARRY_OVER);
239 
240                 //More than one earn code can be associated with an accrual category. Which one does this get?
241                 if(accrualCategory != null && accrualCategory.getEarnCode() != null ){
242                     leaveBlock.setEarnCode(accrualCategory.getEarnCode());
243                 }
244 
245                 leaveBlock.setAccrualGenerated(true);
246                 leaveBlock.setBlockId(0L);
247 
248                 // ASk--Set null
249                 leaveBlock.setScheduleTimeOffId(null);
250 
251                 if(lsr.getAccruedBalance() != null)  {
252                     if(lsr.getMaxCarryOver() != null && lsr.getAccruedBalance().compareTo(lsr.getMaxCarryOver()) > 0 ){
253                         leaveBlock.setLeaveAmount(lsr.getMaxCarryOver());
254                     } else {
255                         leaveBlock.setLeaveAmount(lsr.getAccruedBalance());
256                     }
257                 }
258 
259                 leaveBlock.setPrincipalId(principalId);
260                 leaveBlock.setRequestStatus(HrConstants.REQUEST_STATUS.APPROVED);
261 
262                 // Set EarnCode
263                 if(leaveBlock.getLeaveAmount() != null && leaveBlock.getEarnCode() != null) {
264                     leaveBlocks.add(LeaveBlockBo.to(leaveBlock));
265                 }
266             }
267         }
268 
269 
270 		return leaveBlocks;
271 	}
272 
273 
274 
275 }