001 /**
002 * Copyright 2004-2013 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.lm.approval.web;
017
018 import java.sql.Date;
019 import java.text.SimpleDateFormat;
020 import java.util.*;
021
022 import javax.servlet.http.HttpServletRequest;
023 import javax.servlet.http.HttpServletResponse;
024
025 import org.apache.commons.collections.CollectionUtils;
026 import org.apache.commons.lang.ObjectUtils;
027 import org.apache.commons.lang.StringUtils;
028 import org.apache.commons.lang.math.NumberUtils;
029 import org.apache.struts.action.ActionForm;
030 import org.apache.struts.action.ActionForward;
031 import org.apache.struts.action.ActionMapping;
032 import org.displaytag.tags.TableTagParameters;
033 import org.displaytag.util.ParamEncoder;
034 import org.hsqldb.lib.StringUtil;
035 import org.joda.time.DateTime;
036 import org.kuali.hr.core.document.calendar.CalendarDocumentContract;
037 import org.kuali.hr.lm.leavecalendar.LeaveCalendarDocument;
038 import org.kuali.hr.lm.workflow.LeaveCalendarDocumentHeader;
039 import org.kuali.hr.time.approval.web.ApprovalLeaveSummaryRow;
040 import org.kuali.hr.time.assignment.Assignment;
041 import org.kuali.hr.time.base.web.ApprovalAction;
042 import org.kuali.hr.time.base.web.ApprovalForm;
043 import org.kuali.hr.time.calendar.Calendar;
044 import org.kuali.hr.time.calendar.CalendarEntries;
045 import org.kuali.hr.time.detail.web.ActionFormUtils;
046 import org.kuali.hr.time.roles.TkUserRoles;
047 import org.kuali.hr.time.roles.UserRoles;
048 import org.kuali.hr.time.service.base.TkServiceLocator;
049 import org.kuali.hr.time.util.TKContext;
050 import org.kuali.hr.time.util.TKUser;
051 import org.kuali.hr.time.util.TKUtils;
052 import org.kuali.hr.time.util.TkConstants;
053 import org.kuali.hr.time.workarea.WorkArea;
054
055 public class LeaveApprovalAction extends ApprovalAction{
056
057 public ActionForward searchResult(ActionMapping mapping, ActionForm form,
058 HttpServletRequest request, HttpServletResponse response)
059 throws Exception {
060 LeaveApprovalActionForm laaf = (LeaveApprovalActionForm)form;
061
062 if (StringUtils.equals("documentId", laaf.getSearchField())) {
063 LeaveCalendarDocumentHeader lcd = TkServiceLocator.getLeaveCalendarDocumentHeaderService().getDocumentHeader(laaf.getSearchTerm());
064 laaf.setSearchTerm(lcd != null ? lcd.getPrincipalId() : StringUtils.EMPTY);
065 }
066
067 laaf.setSearchField("principalId");
068 List<String> principalIds = new ArrayList<String>();
069 principalIds.add(laaf.getSearchTerm());
070 CalendarEntries payCalendarEntries = TkServiceLocator.getCalendarEntriesService().getCalendarEntries(laaf.getHrPyCalendarEntriesId());
071 if (principalIds.isEmpty()) {
072 laaf.setLeaveApprovalRows(new ArrayList<ApprovalLeaveSummaryRow>());
073 laaf.setResultSize(0);
074 } else {
075 this.setApprovalTables(laaf, principalIds, request, payCalendarEntries);
076
077 laaf.setPayCalendarEntries(payCalendarEntries);
078 laaf.setLeaveCalendarDates(TkServiceLocator.getLeaveSummaryService().getLeaveSummaryDates(payCalendarEntries));
079
080 List<Assignment> assignments = TkServiceLocator.getAssignmentService().getAssignments(laaf.getSearchTerm(), payCalendarEntries.getEndPeriodDate());
081 if(!assignments.isEmpty()){
082 for(Long wa : laaf.getWorkAreaDescr().keySet()){
083 for (Assignment assign : assignments) {
084 if (assign.getWorkArea().toString().equals(wa.toString())) {
085 laaf.setSelectedWorkArea(wa.toString());
086 break;
087 }
088 }
089 }
090 }
091 }
092
093 return mapping.findForward("basic");
094 }
095
096 public ActionForward approve(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
097 LeaveApprovalActionForm laaf = (LeaveApprovalActionForm) form;
098
099 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 }