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