001 /**
002 * Copyright 2004-2012 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.kuali.hr.time.approval.web;
017
018 import java.sql.Date;
019 import java.text.SimpleDateFormat;
020 import java.util.ArrayList;
021 import java.util.Collections;
022 import java.util.Comparator;
023 import java.util.HashSet;
024 import java.util.List;
025 import java.util.Set;
026
027 import javax.servlet.http.HttpServletRequest;
028 import javax.servlet.http.HttpServletResponse;
029
030 import org.apache.commons.lang.ObjectUtils;
031 import org.apache.commons.lang.StringUtils;
032 import org.apache.commons.lang.math.NumberUtils;
033 import org.apache.struts.action.ActionForm;
034 import org.apache.struts.action.ActionForward;
035 import org.apache.struts.action.ActionMapping;
036 import org.displaytag.tags.TableTagParameters;
037 import org.displaytag.util.ParamEncoder;
038 import org.kuali.hr.time.assignment.Assignment;
039 import org.kuali.hr.time.base.web.ApprovalAction;
040 import org.kuali.hr.time.base.web.ApprovalForm;
041 import org.kuali.hr.time.calendar.Calendar;
042 import org.kuali.hr.time.calendar.CalendarEntries;
043 import org.kuali.hr.time.detail.web.ActionFormUtils;
044 import org.kuali.hr.time.person.TKPerson;
045 import org.kuali.hr.time.service.base.TkServiceLocator;
046 import org.kuali.hr.time.timesheet.TimesheetDocument;
047 import org.kuali.hr.time.util.TKContext;
048 import org.kuali.hr.time.util.TKUser;
049 import org.kuali.hr.time.util.TKUtils;
050 import org.kuali.hr.time.util.TkConstants;
051 import org.kuali.hr.time.workarea.WorkArea;
052 import org.kuali.hr.time.workflow.TimesheetDocumentHeader;
053
054 public class TimeApprovalAction extends ApprovalAction{
055
056 public ActionForward searchResult(ActionMapping mapping, ActionForm form,
057 HttpServletRequest request, HttpServletResponse response)
058 throws Exception {
059 TimeApprovalActionForm taaf = (TimeApprovalActionForm)form;
060 String searchField = taaf.getSearchField();
061 String searchTerm = taaf.getSearchTerm();
062 String principalId;
063
064 if(StringUtils.equals("documentId", searchField)){
065 TimesheetDocumentHeader tdh = TkServiceLocator.getTimesheetDocumentHeaderService().getDocumentHeader(searchTerm);
066 principalId = tdh.getPrincipalId();
067 } else {
068 principalId = searchTerm;
069 }
070 taaf.setSearchField("principalId");
071 taaf.setSearchTerm(principalId);
072
073 List<String> principalIds = new ArrayList<String>();
074 principalIds.add(principalId);
075 List<TKPerson> persons = TkServiceLocator.getPersonService().getPersonCollection(principalIds);
076 if (persons.isEmpty()) {
077 taaf.setApprovalRows(new ArrayList<ApprovalTimeSummaryRow>());
078 taaf.setResultSize(0);
079 } else {
080 taaf.setResultSize(persons.size());
081 taaf.setApprovalRows(getApprovalRows(taaf, persons));
082
083 CalendarEntries payCalendarEntries = TkServiceLocator.getCalendarEntriesService().getCalendarEntries(taaf.getHrPyCalendarEntriesId());
084 taaf.setPayCalendarEntries(payCalendarEntries);
085 taaf.setPayCalendarLabels(TkServiceLocator.getTimeSummaryService().getHeaderForSummary(payCalendarEntries, new ArrayList<Boolean>()));
086
087 List<Assignment> assignments = TkServiceLocator.getAssignmentService().getAssignments(principalId, payCalendarEntries.getEndPeriodDate());
088 if(!assignments.isEmpty()){
089 for(Long wa : taaf.getWorkAreaDescr().keySet()){
090 for (Assignment assign : assignments) {
091 if (assign.getWorkArea().toString().equals(wa.toString())) {
092 taaf.setSelectedWorkArea(wa.toString());
093 break;
094 }
095 }
096 }
097 }
098 }
099
100 return mapping.findForward("basic");
101 }
102
103 public ActionForward approve(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
104 TimeApprovalActionForm taaf = (TimeApprovalActionForm) form;
105 List<ApprovalTimeSummaryRow> lstApprovalRows = taaf.getApprovalRows();
106 for (ApprovalTimeSummaryRow ar : lstApprovalRows) {
107 if (ar.isApprovable() && StringUtils.equals(ar.getSelected(), "on")) {
108 String documentNumber = ar.getDocumentId();
109 TimesheetDocument tDoc = TkServiceLocator.getTimesheetService().getTimesheetDocument(documentNumber);
110 TkServiceLocator.getTimesheetService().approveTimesheet(TKContext.getPrincipalId(), tDoc);
111 }
112 }
113 return mapping.findForward("basic");
114 }
115
116 public ActionForward selectNewDept(ActionMapping mapping, ActionForm form,
117 HttpServletRequest request, HttpServletResponse response)
118 throws Exception {
119 TimeApprovalActionForm taaf = (TimeApprovalActionForm)form;
120 taaf.setSearchField(null);
121 taaf.setSearchTerm(null);
122
123 CalendarEntries payCalendarEntries = TkServiceLocator.getCalendarEntriesService().getCalendarEntries(taaf.getHrPyCalendarEntriesId());
124 taaf.setPayCalendarEntries(payCalendarEntries);
125 taaf.setPayCalendarLabels(TkServiceLocator.getTimeSummaryService().getHeaderForSummary(payCalendarEntries, new ArrayList<Boolean>()));
126
127 taaf.getWorkAreaDescr().clear();
128 List<WorkArea> workAreas = TkServiceLocator.getWorkAreaService().getWorkAreas(taaf.getSelectedDept(), new java.sql.Date(taaf.getPayBeginDate().getTime()));
129 for(WorkArea wa : workAreas){
130 if (TKContext.getUser().getApproverWorkAreas().contains(wa.getWorkArea())
131 || TKContext.getUser().getReviewerWorkAreas().contains(wa.getWorkArea())) {
132 taaf.getWorkAreaDescr().put(wa.getWorkArea(),wa.getDescription()+"("+wa.getWorkArea()+")");
133 }
134 }
135
136 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());
137 if (principalIds.isEmpty()) {
138 taaf.setApprovalRows(new ArrayList<ApprovalTimeSummaryRow>());
139 taaf.setResultSize(0);
140 }
141 else {
142 List<TKPerson> persons = TkServiceLocator.getPersonService().getPersonCollection(principalIds);
143 Collections.sort(persons);
144 taaf.setApprovalRows(getApprovalRows(taaf, getSubListPrincipalIds(request, persons)));
145 taaf.setResultSize(persons.size());
146 }
147
148 this.populateCalendarAndPayPeriodLists(request, taaf);
149 return mapping.findForward("basic");
150 }
151
152 public ActionForward selectNewWorkArea(ActionMapping mapping, ActionForm form,
153 HttpServletRequest request, HttpServletResponse response)
154 throws Exception {
155 TimeApprovalActionForm taaf = (TimeApprovalActionForm)form;
156 taaf.setSearchField(null);
157 taaf.setSearchTerm(null);
158
159 CalendarEntries payCalendarEntries = TkServiceLocator.getCalendarEntriesService().getCalendarEntries(taaf.getHrPyCalendarEntriesId());
160 taaf.setPayCalendarLabels(TkServiceLocator.getTimeSummaryService().getHeaderForSummary(payCalendarEntries, new ArrayList<Boolean>()));
161
162 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());
163 if (principalIds.isEmpty()) {
164 taaf.setApprovalRows(new ArrayList<ApprovalTimeSummaryRow>());
165 taaf.setResultSize(0);
166 }
167 else {
168 List<TKPerson> persons = TkServiceLocator.getPersonService().getPersonCollection(principalIds);
169 Collections.sort(persons);
170 taaf.setApprovalRows(getApprovalRows(taaf, getSubListPrincipalIds(request, persons)));
171 taaf.setResultSize(persons.size());
172 }
173 return mapping.findForward("basic");
174 }
175
176 public ActionForward loadApprovalTab(ActionMapping mapping, ActionForm form,
177 HttpServletRequest request, HttpServletResponse response)
178 throws Exception {
179 ActionForward fwd = mapping.findForward("basic");
180 TKUser user = TKContext.getUser();
181 TimeApprovalActionForm taaf = (TimeApprovalActionForm) form;
182 Date currentDate = null;
183 CalendarEntries payCalendarEntries = null;
184 Calendar currentPayCalendar = null;
185 String page = request.getParameter((new ParamEncoder(TkConstants.APPROVAL_TABLE_ID).encodeParameterName(TableTagParameters.PARAMETER_PAGE)));
186
187 //reset state
188 if(StringUtils.isBlank(taaf.getSelectedDept())){
189 resetState(form, request);
190 }
191 // Set calendar groups
192 List<String> calGroups = TkServiceLocator.getTimeApproveService().getUniquePayGroups();
193 taaf.setPayCalendarGroups(calGroups);
194
195 if (StringUtils.isBlank(taaf.getSelectedPayCalendarGroup())) {
196 taaf.setSelectedPayCalendarGroup(calGroups.get(0));
197 }
198
199 // Set current pay calendar entries if present. Decide if the current date should be today or the end period date
200 if (taaf.getHrPyCalendarEntriesId() != null) {
201 payCalendarEntries = TkServiceLocator.getCalendarEntriesService().getCalendarEntries(taaf.getHrPyCalendarEntriesId());
202 currentDate = payCalendarEntries.getEndPeriodDate();
203 } else {
204 currentDate = TKUtils.getTimelessDate(null);
205 currentPayCalendar = TkServiceLocator.getCalendarService().getCalendarByGroup(taaf.getSelectedPayCalendarGroup());
206 payCalendarEntries = TkServiceLocator.getCalendarEntriesService().getCurrentCalendarEntriesByCalendarId(currentPayCalendar.getHrCalendarId(), currentDate);
207 }
208 taaf.setPayCalendarEntries(payCalendarEntries);
209
210
211 if(taaf.getPayCalendarEntries() != null) {
212 populateCalendarAndPayPeriodLists(request, taaf);
213 }
214 setupDocumentOnFormContext(request,taaf,payCalendarEntries, page);
215 return fwd;
216 }
217
218 @Override
219 protected void setupDocumentOnFormContext(HttpServletRequest request,ApprovalForm form, CalendarEntries payCalendarEntries, String page) {
220 super.setupDocumentOnFormContext(request, form, payCalendarEntries, page);
221 TimeApprovalActionForm taaf = (TimeApprovalActionForm) form;
222 taaf.setPayCalendarLabels(TkServiceLocator.getTimeSummaryService().getHeaderForSummary(payCalendarEntries, new ArrayList<Boolean>()));
223
224 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());
225 if (principalIds.isEmpty()) {
226 taaf.setApprovalRows(new ArrayList<ApprovalTimeSummaryRow>());
227 taaf.setResultSize(0);
228 } else {
229 List<TKPerson> persons = TkServiceLocator.getPersonService().getPersonCollection(principalIds);
230 List<ApprovalTimeSummaryRow> approvalRows = getApprovalRows(taaf, getSubListPrincipalIds(request, persons));
231
232 final String sortField = request.getParameter("sortField");
233 if (StringUtils.equals(sortField, "Name")) {
234 final boolean sortNameAscending = Boolean.parseBoolean(request.getParameter("sortNameAscending"));
235 Collections.sort(approvalRows, new Comparator<ApprovalTimeSummaryRow>() {
236 @Override
237 public int compare(ApprovalTimeSummaryRow row1, ApprovalTimeSummaryRow row2) {
238 if (sortNameAscending) {
239 return ObjectUtils.compare(StringUtils.lowerCase(row1.getName()), StringUtils.lowerCase(row2.getName()));
240 } else {
241 return ObjectUtils.compare(StringUtils.lowerCase(row2.getName()), StringUtils.lowerCase(row1.getName()));
242 }
243 }
244 });
245 } else if (StringUtils.equals(sortField, "DocumentID")) {
246 final boolean sortDocumentIdAscending = Boolean.parseBoolean(request.getParameter("sortDocumentIDAscending"));
247 Collections.sort(approvalRows, new Comparator<ApprovalTimeSummaryRow>() {
248 @Override
249 public int compare(ApprovalTimeSummaryRow row1, ApprovalTimeSummaryRow row2) {
250 if (sortDocumentIdAscending) {
251 return ObjectUtils.compare(NumberUtils.toInt(row1.getDocumentId()), NumberUtils.toInt(row2.getDocumentId()));
252 } else {
253 return ObjectUtils.compare(NumberUtils.toInt(row2.getDocumentId()), NumberUtils.toInt(row1.getDocumentId()));
254 }
255 }
256 });
257 }
258
259 taaf.setApprovalRows(approvalRows);
260 taaf.setResultSize(persons.size());
261 }
262
263 taaf.setOnCurrentPeriod(ActionFormUtils.getOnCurrentPeriodFlag(taaf.getPayCalendarEntries()));
264 }
265
266 public ActionForward selectNewPayCalendar(ActionMapping mapping, ActionForm form,
267 HttpServletRequest request, HttpServletResponse response)
268 throws Exception {
269 // resets the common fields for approval pages
270 super.resetMainFields(form);
271 TimeApprovalActionForm taaf = (TimeApprovalActionForm)form;
272 // KPME-909
273 taaf.setApprovalRows(new ArrayList<ApprovalTimeSummaryRow>());
274 return loadApprovalTab(mapping, form, request, response);
275 }
276
277 /**
278 * Helper method to modify / manage the list of records needed to display approval data to the user.
279 *
280 * @param taaf
281 * @return
282 */
283 protected List<ApprovalTimeSummaryRow> getApprovalRows(TimeApprovalActionForm taaf, List<TKPerson> assignmentPrincipalIds) {
284 return TkServiceLocator.getTimeApproveService().getApprovalSummaryRows(taaf.getPayBeginDate(), taaf.getPayEndDate(), taaf.getSelectedPayCalendarGroup(), assignmentPrincipalIds, taaf.getPayCalendarLabels(), taaf.getPayCalendarEntries());
285 }
286
287 public void resetState(ActionForm form, HttpServletRequest request) {
288 TimeApprovalActionForm taaf = (TimeApprovalActionForm) form;
289 String page = request.getParameter((new ParamEncoder(TkConstants.APPROVAL_TABLE_ID).encodeParameterName(TableTagParameters.PARAMETER_PAGE)));
290
291 if (StringUtils.isBlank(page)) {
292 taaf.getDepartments().clear();
293 taaf.getWorkAreaDescr().clear();
294 taaf.setApprovalRows(new ArrayList<ApprovalTimeSummaryRow>());
295 taaf.setSelectedDept(null);
296 taaf.setSearchField(null);
297 taaf.setSearchTerm(null);
298 }
299 }
300
301 @Override
302 protected void populateCalendarAndPayPeriodLists(HttpServletRequest request, ApprovalForm taf) {
303 TimeApprovalActionForm taaf = (TimeApprovalActionForm)taf;
304 // set calendar year list
305 Set<String> yearSet = new HashSet<String>();
306 SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
307 // if selected calendar year is passed in
308 if(!StringUtils.isEmpty(request.getParameter("selectedCY"))) {
309 taaf.setSelectedCalendarYear(request.getParameter("selectedCY").toString());
310 } else {
311 taaf.setSelectedCalendarYear(sdf.format(taaf.getPayCalendarEntries().getBeginPeriodDate()));
312 }
313
314 List<CalendarEntries> pcListForYear = new ArrayList<CalendarEntries>();
315 List<CalendarEntries> pceList = TkServiceLocator.getTimeApproveService()
316 .getAllPayCalendarEntriesForApprover(TKContext.getPrincipalId(), TKUtils.getTimelessDate(null));
317 for(CalendarEntries pce : pceList) {
318 yearSet.add(sdf.format(pce.getBeginPeriodDate()));
319 if(sdf.format(pce.getBeginPeriodDate()).equals(taaf.getSelectedCalendarYear())) {
320 pcListForYear.add(pce);
321 }
322 }
323 List<String> yearList = new ArrayList<String>(yearSet);
324 Collections.sort(yearList);
325 Collections.reverse(yearList); // newest on top
326 taaf.setCalendarYears(yearList);
327
328 // set pay period list contents
329 if(!StringUtils.isEmpty(request.getParameter("selectedPP"))) {
330 taaf.setSelectedPayPeriod(request.getParameter("selectedPP").toString());
331 } else {
332 taaf.setSelectedPayPeriod(taaf.getPayCalendarEntries().getHrCalendarEntriesId());
333 taaf.setPayPeriodsMap(ActionFormUtils.getPayPeriodsMap(pcListForYear));
334 }
335 if(taaf.getPayPeriodsMap().isEmpty()) {
336 taaf.setPayPeriodsMap(ActionFormUtils.getPayPeriodsMap(pcListForYear));
337 }
338 }
339 }