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