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.lm.approval.web;
17  
18  import java.sql.Date;
19  import java.text.SimpleDateFormat;
20  import java.util.ArrayList;
21  import java.util.Collections;
22  import java.util.Comparator;
23  import java.util.HashSet;
24  import java.util.List;
25  import java.util.Set;
26  
27  import javax.servlet.http.HttpServletRequest;
28  import javax.servlet.http.HttpServletResponse;
29  
30  import org.apache.commons.collections.CollectionUtils;
31  import org.apache.commons.lang.ObjectUtils;
32  import org.apache.commons.lang.StringUtils;
33  import org.apache.commons.lang.math.NumberUtils;
34  import org.apache.struts.action.ActionForm;
35  import org.apache.struts.action.ActionForward;
36  import org.apache.struts.action.ActionMapping;
37  import org.displaytag.tags.TableTagParameters;
38  import org.displaytag.util.ParamEncoder;
39  import org.hsqldb.lib.StringUtil;
40  import org.kuali.hr.lm.leavecalendar.LeaveCalendarDocument;
41  import org.kuali.hr.lm.workflow.LeaveCalendarDocumentHeader;
42  import org.kuali.hr.time.approval.web.ApprovalLeaveSummaryRow;
43  import org.kuali.hr.time.assignment.Assignment;
44  import org.kuali.hr.time.base.web.ApprovalAction;
45  import org.kuali.hr.time.base.web.ApprovalForm;
46  import org.kuali.hr.time.calendar.Calendar;
47  import org.kuali.hr.time.calendar.CalendarEntries;
48  import org.kuali.hr.time.detail.web.ActionFormUtils;
49  import org.kuali.hr.time.person.TKPerson;
50  import org.kuali.hr.time.service.base.TkServiceLocator;
51  import org.kuali.hr.time.util.TKContext;
52  import org.kuali.hr.time.util.TKUser;
53  import org.kuali.hr.time.util.TKUtils;
54  import org.kuali.hr.time.util.TkConstants;
55  import org.kuali.hr.time.workarea.WorkArea;
56  
57  public class LeaveApprovalAction extends ApprovalAction{
58  	
59  	public ActionForward searchResult(ActionMapping mapping, ActionForm form,
60  			HttpServletRequest request, HttpServletResponse response)
61  			throws Exception {
62  		LeaveApprovalActionForm laaf = (LeaveApprovalActionForm)form;
63  		
64          if (StringUtils.equals("documentId", laaf.getSearchField())) {
65          	LeaveCalendarDocumentHeader lcd = TkServiceLocator.getLeaveCalendarDocumentHeaderService().getDocumentHeader(laaf.getSearchTerm());
66          	laaf.setSearchTerm(lcd != null ? lcd.getPrincipalId() : StringUtils.EMPTY);
67          }
68          
69      	laaf.setSearchField("principalId");
70          List<String> principalIds = new ArrayList<String>();
71          principalIds.add(laaf.getSearchTerm());
72          List<TKPerson> persons = TkServiceLocator.getPersonService().getPersonCollection(principalIds);
73          CalendarEntries payCalendarEntries = TkServiceLocator.getCalendarEntriesService().getCalendarEntries(laaf.getHrPyCalendarEntriesId());
74          if (persons.isEmpty()) {
75          	laaf.setLeaveApprovalRows(new ArrayList<ApprovalLeaveSummaryRow>());
76          	laaf.setResultSize(0);
77          } else {
78          	this.setApprovalTables(laaf, principalIds, request, payCalendarEntries);
79          	
80     	        laaf.setPayCalendarEntries(payCalendarEntries);
81     	        laaf.setLeaveCalendarDates(TkServiceLocator.getLeaveSummaryService().getLeaveSummaryDates(payCalendarEntries));
82          	
83  	        List<Assignment> assignments = TkServiceLocator.getAssignmentService().getAssignments(laaf.getSearchTerm(), payCalendarEntries.getEndPeriodDate());
84  	        if(!assignments.isEmpty()){
85  	        	 for(Long wa : laaf.getWorkAreaDescr().keySet()){
86  	        		for (Assignment assign : assignments) {
87  		             	if (assign.getWorkArea().toString().equals(wa.toString())) {
88  		             		laaf.setSelectedWorkArea(wa.toString());
89  		             		break;
90  		             	}
91  	        		}
92  	             }
93  	        }
94          }
95   
96  		return mapping.findForward("basic");
97  	}
98  	
99      public ActionForward approve(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
100         LeaveApprovalActionForm laaf = (LeaveApprovalActionForm) form;
101        
102         List<ApprovalLeaveSummaryRow> lstLeaveRows = laaf.getLeaveApprovalRows();
103         for (ApprovalLeaveSummaryRow ar : lstLeaveRows) {
104             if (ar.isApprovable() && StringUtils.equals(ar.getSelected(), "on")) {
105                 String documentNumber = ar.getDocumentId();
106                 LeaveCalendarDocument lcd = TkServiceLocator.getLeaveCalendarService().getLeaveCalendarDocument(documentNumber);
107                 TkServiceLocator.getLeaveCalendarService().approveLeaveCalendar(TKContext.getPrincipalId(), lcd);
108             }
109         }  
110         
111         return mapping.findForward("basic");
112     }
113         
114 	public ActionForward selectNewDept(ActionMapping mapping, ActionForm form,
115 			HttpServletRequest request, HttpServletResponse response)
116 			throws Exception {
117 		LeaveApprovalActionForm laaf = (LeaveApprovalActionForm)form;
118 		laaf.setSearchField(null);
119 		laaf.setSearchTerm(null);
120 
121         CalendarEntries payCalendarEntries = TkServiceLocator.getCalendarEntriesService().getCalendarEntries(laaf.getHrPyCalendarEntriesId());
122         laaf.setPayCalendarEntries(payCalendarEntries);
123         laaf.setLeaveCalendarDates(TkServiceLocator.getLeaveSummaryService().getLeaveSummaryDates(payCalendarEntries));
124 
125 		laaf.getWorkAreaDescr().clear();
126 		laaf.setSelectedWorkArea("");
127     	List<WorkArea> workAreas = TkServiceLocator.getWorkAreaService().getWorkAreas(laaf.getSelectedDept(), new java.sql.Date(laaf.getPayBeginDate().getTime()));
128         for(WorkArea wa : workAreas){
129         	if (TKUser.getApproverWorkAreas().contains(wa.getWorkArea())
130         			|| TKUser.getReviewerWorkAreas().contains(wa.getWorkArea())) {
131         		laaf.getWorkAreaDescr().put(wa.getWorkArea(),wa.getDescription()+"("+wa.getWorkArea()+")");
132         	}
133         }
134 	
135         List<String> principalIds = this.getPrincipalIdsToPopulateTable(laaf);
136     	this.setApprovalTables(laaf, principalIds, request, payCalendarEntries);
137     	
138     	this.populateCalendarAndPayPeriodLists(request, laaf);
139 		return mapping.findForward("basic");
140 	}
141 	
142 	public ActionForward selectNewWorkArea(ActionMapping mapping, ActionForm form,
143 			HttpServletRequest request, HttpServletResponse response)
144 			throws Exception {
145 		LeaveApprovalActionForm laaf = (LeaveApprovalActionForm)form;
146 		laaf.setSearchField(null);
147 		laaf.setSearchTerm(null);
148 
149 	    CalendarEntries payCalendarEntries = TkServiceLocator.getCalendarEntriesService().getCalendarEntries(laaf.getHrPyCalendarEntriesId());
150         laaf.setLeaveCalendarDates(TkServiceLocator.getLeaveSummaryService().getLeaveSummaryDates(payCalendarEntries));
151    
152         List<String> idList = this.getPrincipalIdsToPopulateTable(laaf);
153         this.setApprovalTables(laaf, idList , request, payCalendarEntries);
154         
155 		return mapping.findForward("basic");
156 	}	
157 
158 	private List<String> getPrincipalIdsToPopulateTable(LeaveApprovalActionForm laaf) {
159         List<String> workAreaList = new ArrayList<String>();
160         if(StringUtil.isEmpty(laaf.getSelectedWorkArea())) {
161         	for(Long aKey : laaf.getWorkAreaDescr().keySet()) {
162         		workAreaList.add(aKey.toString());
163         	}
164         } else {
165         	workAreaList.add(laaf.getSelectedWorkArea());
166         }
167         java.sql.Date endDate = new java.sql.Date(laaf.getPayEndDate().getTime());
168         java.sql.Date beginDate = new java.sql.Date(laaf.getPayBeginDate().getTime());
169 
170         List<String> idList = TkServiceLocator.getLeaveApprovalService()
171         		.getLeavePrincipalIdsWithSearchCriteria(workAreaList, laaf.getSelectedPayCalendarGroup(), endDate, beginDate, endDate);      
172         return idList;
173 	}	
174 	
175 	private void setApprovalTables(LeaveApprovalActionForm laaf, List<String> principalIds, HttpServletRequest request, CalendarEntries payCalendarEntries) {
176 		laaf.setLeaveCalendarDates(TkServiceLocator.getLeaveSummaryService().getLeaveSummaryDates(payCalendarEntries));
177 		
178 		if (principalIds.isEmpty()) {
179 			laaf.setLeaveApprovalRows(new ArrayList<ApprovalLeaveSummaryRow>());
180 			laaf.setResultSize(0);
181 		} else {
182 			List<TKPerson> persons = TkServiceLocator.getPersonService().getPersonCollection(principalIds);
183 			List<ApprovalLeaveSummaryRow> approvalRows = getApprovalLeaveRows(laaf, getSubListPrincipalIds(request, persons)); 
184 		    
185 			final String sortField = request.getParameter("sortField");		    
186 		    if (StringUtils.equals(sortField, "Name")) {
187 			    final boolean sortNameAscending = Boolean.parseBoolean(request.getParameter("sortNameAscending"));
188 		    	Collections.sort(approvalRows, new Comparator<ApprovalLeaveSummaryRow>() {
189 					@Override
190 					public int compare(ApprovalLeaveSummaryRow row1, ApprovalLeaveSummaryRow row2) {
191 						if (sortNameAscending) {
192 							return ObjectUtils.compare(StringUtils.lowerCase(row1.getName()), StringUtils.lowerCase(row2.getName()));
193 						} else {
194 							return ObjectUtils.compare(StringUtils.lowerCase(row2.getName()), StringUtils.lowerCase(row1.getName()));
195 						}
196 					}
197 		    	});
198 		    } else if (StringUtils.equals(sortField, "DocumentID")) {
199 			    final boolean sortDocumentIdAscending = Boolean.parseBoolean(request.getParameter("sortDocumentIDAscending"));
200 		    	Collections.sort(approvalRows, new Comparator<ApprovalLeaveSummaryRow>() {
201 					@Override
202 					public int compare(ApprovalLeaveSummaryRow row1, ApprovalLeaveSummaryRow row2) {
203 						if (sortDocumentIdAscending) {
204 							return ObjectUtils.compare(NumberUtils.toInt(row1.getDocumentId()), NumberUtils.toInt(row2.getDocumentId()));
205 						} else {
206 							return ObjectUtils.compare(NumberUtils.toInt(row2.getDocumentId()), NumberUtils.toInt(row1.getDocumentId()));
207 						}
208 					}
209 		    	});
210 		    } else if (StringUtils.equals(sortField, "Status")) {
211 			    final boolean sortStatusIdAscending = Boolean.parseBoolean(request.getParameter("sortStatusAscending"));
212 		    	Collections.sort(approvalRows, new Comparator<ApprovalLeaveSummaryRow>() {
213 					@Override
214 					public int compare(ApprovalLeaveSummaryRow row1, ApprovalLeaveSummaryRow row2) {
215 						if (sortStatusIdAscending) {
216 							return ObjectUtils.compare(StringUtils.lowerCase(row1.getApprovalStatus()), StringUtils.lowerCase(row2.getApprovalStatus()));
217 						} else {
218 							return ObjectUtils.compare(StringUtils.lowerCase(row2.getApprovalStatus()), StringUtils.lowerCase(row1.getApprovalStatus()));
219 						}
220 					}
221 		    	});
222 		    }
223 		    
224 			laaf.setLeaveApprovalRows(approvalRows);
225 		    laaf.setResultSize(persons.size());
226 		}
227 	}
228 	
229 	@Override
230 	public ActionForward loadApprovalTab(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
231 				throws Exception {
232 		ActionForward fwd = mapping.findForward("basic");
233         LeaveApprovalActionForm laaf = (LeaveApprovalActionForm) form;
234         Date currentDate = null;
235         CalendarEntries payCalendarEntries = null;
236         Calendar currentPayCalendar = null;
237         String page = request.getParameter((new ParamEncoder(TkConstants.APPROVAL_TABLE_ID).encodeParameterName(TableTagParameters.PARAMETER_PAGE)));
238 
239 
240         //reset state
241         if(StringUtils.isBlank(laaf.getSelectedDept())){
242         	resetState(form, request);
243         }
244 
245         // Set current pay calendar entries if present. Decide if the current date should be today or the end period date
246         if (laaf.getHrPyCalendarEntriesId() != null) {
247             if(payCalendarEntries == null){
248                payCalendarEntries = TkServiceLocator.getCalendarEntriesService().getCalendarEntries(laaf.getHrPyCalendarEntriesId());
249             }
250             currentDate = payCalendarEntries.getEndPeriodDate();
251         } else {
252             currentDate = TKUtils.getTimelessDate(null);
253         }
254         Set<Long> workAreas = TkServiceLocator.getTkRoleService().getWorkAreasForApprover(TKContext.getPrincipalId(), currentDate);
255         // should we use all three roles to find work areas???
256 //        List<String> roleNameList = Arrays.asList(TkConstants.ROLE_TK_APPROVER, TkConstants.ROLE_TK_APPROVER_DELEGATE, TkConstants.ROLE_TK_REVIEWER);
257 //        Set<Long> workAreas = TkServiceLocator.getTkRoleService().getWorkAreasForRoleNames(TKContext.getPrincipalId(), roleNameList, currentDate);
258         
259         List<String> principalIds = new ArrayList<String>();
260         for (Long workArea : workAreas) {
261             List<Assignment> assignments = TkServiceLocator.getAssignmentService().getActiveAssignmentsForWorkArea(workArea, currentDate);
262             for (Assignment a : assignments) {
263                 principalIds.add(a.getPrincipalId());
264             }
265         }
266 
267         // Set calendar groups
268         List<String> calGroups =  new ArrayList<String>();
269         if (CollectionUtils.isNotEmpty(principalIds)) {
270             calGroups = TkServiceLocator.getLeaveApprovalService().getUniqueLeavePayGroupsForPrincipalIds(principalIds);
271         }
272         laaf.setPayCalendarGroups(calGroups);
273 
274         if (StringUtils.isBlank(laaf.getSelectedPayCalendarGroup())
275                 && CollectionUtils.isNotEmpty(calGroups)) {
276             laaf.setSelectedPayCalendarGroup(calGroups.get(0));
277 
278         }
279         
280         // Set current pay calendar entries if present. Decide if the current date should be today or the end period date
281         if (laaf.getHrPyCalendarEntriesId() != null) {
282             payCalendarEntries = TkServiceLocator.getCalendarEntriesService().getCalendarEntries(laaf.getHrPyCalendarEntriesId());
283         } else {
284             currentPayCalendar = TkServiceLocator.getCalendarService().getCalendarByGroup(laaf.getSelectedPayCalendarGroup());
285             if (currentPayCalendar != null) {
286                 payCalendarEntries = TkServiceLocator.getCalendarEntriesService().getCurrentCalendarEntriesByCalendarId(currentPayCalendar.getHrCalendarId(), currentDate);
287             }
288         }
289         laaf.setPayCalendarEntries(payCalendarEntries);
290         
291         
292         if(laaf.getPayCalendarEntries() != null) {
293 	        populateCalendarAndPayPeriodLists(request, laaf);
294         }
295         setupDocumentOnFormContext(request,laaf,payCalendarEntries, page);
296         return fwd;
297 	}
298 
299 	@Override
300 	protected void setupDocumentOnFormContext(HttpServletRequest request,ApprovalForm form, CalendarEntries payCalendarEntries, String page) {
301 		super.setupDocumentOnFormContext(request, form, payCalendarEntries, page);
302 		LeaveApprovalActionForm laaf = (LeaveApprovalActionForm)form;
303 
304         if (payCalendarEntries != null) {
305 		    laaf.setLeaveCalendarDates(TkServiceLocator.getLeaveSummaryService().getLeaveSummaryDates(payCalendarEntries));	    
306 		    List<String> principalIds = this.getPrincipalIdsToPopulateTable(laaf); 
307             this.setApprovalTables(laaf, principalIds, request, payCalendarEntries);
308             laaf.setOnCurrentPeriod(ActionFormUtils.getOnCurrentPeriodFlag(laaf.getPayCalendarEntries()));
309         }
310 	}
311 	
312 	public ActionForward selectNewPayCalendar(ActionMapping mapping, ActionForm form,
313 			HttpServletRequest request, HttpServletResponse response)
314 			throws Exception {
315 		// resets the common fields for approval pages
316 		super.resetMainFields(form);
317 		LeaveApprovalActionForm laaf = (LeaveApprovalActionForm)form;
318         // KPME-909
319         laaf.setLeaveApprovalRows(new ArrayList<ApprovalLeaveSummaryRow>());
320 		
321 		return loadApprovalTab(mapping, form, request, response);
322 	}
323 	   
324     protected List<ApprovalLeaveSummaryRow> getApprovalLeaveRows(LeaveApprovalActionForm laaf, List<TKPerson> assignmentPrincipalIds) {
325         return TkServiceLocator.getLeaveApprovalService().getLeaveApprovalSummaryRows
326         	(assignmentPrincipalIds, laaf.getPayCalendarEntries(), laaf.getLeaveCalendarDates());
327     }
328 	
329     public void resetState(ActionForm form, HttpServletRequest request) {
330     	  LeaveApprovalActionForm laaf = (LeaveApprovalActionForm) form;
331  	      String page = request.getParameter((new ParamEncoder(TkConstants.APPROVAL_TABLE_ID).encodeParameterName(TableTagParameters.PARAMETER_PAGE)));
332  	      
333  	      if (StringUtils.isBlank(page)) {
334  			  laaf.getDepartments().clear();
335  			  laaf.getWorkAreaDescr().clear();
336  			  laaf.setLeaveApprovalRows(new ArrayList<ApprovalLeaveSummaryRow>());
337  			  laaf.setSelectedDept(null);
338  			  laaf.setSearchField(null);
339  			  laaf.setSearchTerm(null);
340  	      }
341 	}
342     
343     @Override
344     protected void populateCalendarAndPayPeriodLists(HttpServletRequest request, ApprovalForm taf) {
345     	 LeaveApprovalActionForm laaf = (LeaveApprovalActionForm) taf;
346 		// set calendar year list
347 		Set<String> yearSet = new HashSet<String>();
348 		SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
349 		// if selected calendar year is passed in
350 		if(!StringUtils.isEmpty(request.getParameter("selectedCY"))) {
351 			laaf.setSelectedCalendarYear(request.getParameter("selectedCY").toString());
352 		} else {
353 			laaf.setSelectedCalendarYear(sdf.format(laaf.getPayCalendarEntries().getBeginPeriodDate()));
354 		}
355 		
356 		List<CalendarEntries> pcListForYear = new ArrayList<CalendarEntries>();
357 		List<CalendarEntries> pceList =  new ArrayList<CalendarEntries>();
358 		pceList.addAll(TkServiceLocator.getLeaveApprovalService()
359 			.getAllLeavePayCalendarEntriesForApprover(TKContext.getPrincipalId(), TKUtils.getTimelessDate(null)));
360 		
361 	    for(CalendarEntries pce : pceList) {
362 	    	yearSet.add(sdf.format(pce.getBeginPeriodDate()));
363 	    	if(sdf.format(pce.getBeginPeriodDate()).equals(laaf.getSelectedCalendarYear())) {
364 	    		pcListForYear.add(pce);
365 	    	}
366 	    }
367 	    List<String> yearList = new ArrayList<String>(yearSet);
368 	    Collections.sort(yearList);
369 	    Collections.reverse(yearList);	// newest on top
370 	    laaf.setCalendarYears(yearList);
371 		
372 		// set pay period list contents
373 		if(!StringUtils.isEmpty(request.getParameter("selectedPP"))) {
374 			laaf.setSelectedPayPeriod(request.getParameter("selectedPP").toString());
375 		} else {
376 			laaf.setSelectedPayPeriod(laaf.getPayCalendarEntries().getHrCalendarEntriesId());
377 			laaf.setPayPeriodsMap(ActionFormUtils.getPayPeriodsMap(pcListForYear, null));
378 		}
379 		if(laaf.getPayPeriodsMap().isEmpty()) {
380 		    laaf.setPayPeriodsMap(ActionFormUtils.getPayPeriodsMap(pcListForYear, null));
381 		}
382 	}
383 
384 }