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