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.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.collections.CollectionUtils;
031 import org.apache.commons.lang.ObjectUtils;
032 import org.apache.commons.lang.StringUtils;
033 import org.apache.commons.lang.math.NumberUtils;
034 import org.apache.struts.action.ActionForm;
035 import org.apache.struts.action.ActionForward;
036 import org.apache.struts.action.ActionMapping;
037 import org.displaytag.tags.TableTagParameters;
038 import org.displaytag.util.ParamEncoder;
039 import org.hsqldb.lib.StringUtil;
040 import org.kuali.hr.lm.leavecalendar.LeaveCalendarDocument;
041 import org.kuali.hr.lm.workflow.LeaveCalendarDocumentHeader;
042 import org.kuali.hr.time.approval.web.ApprovalLeaveSummaryRow;
043 import org.kuali.hr.time.assignment.Assignment;
044 import org.kuali.hr.time.base.web.ApprovalAction;
045 import org.kuali.hr.time.base.web.ApprovalForm;
046 import org.kuali.hr.time.calendar.Calendar;
047 import org.kuali.hr.time.calendar.CalendarEntries;
048 import org.kuali.hr.time.detail.web.ActionFormUtils;
049 import org.kuali.hr.time.person.TKPerson;
050 import org.kuali.hr.time.service.base.TkServiceLocator;
051 import org.kuali.hr.time.util.TKContext;
052 import org.kuali.hr.time.util.TKUser;
053 import org.kuali.hr.time.util.TKUtils;
054 import org.kuali.hr.time.util.TkConstants;
055 import org.kuali.hr.time.workarea.WorkArea;
056
057 public class LeaveApprovalAction extends ApprovalAction{
058
059 public ActionForward searchResult(ActionMapping mapping, ActionForm form,
060 HttpServletRequest request, HttpServletResponse response)
061 throws Exception {
062 LeaveApprovalActionForm laaf = (LeaveApprovalActionForm)form;
063
064 if (StringUtils.equals("documentId", laaf.getSearchField())) {
065 LeaveCalendarDocumentHeader lcd = TkServiceLocator.getLeaveCalendarDocumentHeaderService().getDocumentHeader(laaf.getSearchTerm());
066 laaf.setSearchTerm(lcd != null ? lcd.getPrincipalId() : StringUtils.EMPTY);
067 }
068
069 laaf.setSearchField("principalId");
070 List<String> principalIds = new ArrayList<String>();
071 principalIds.add(laaf.getSearchTerm());
072 List<TKPerson> persons = TkServiceLocator.getPersonService().getPersonCollection(principalIds);
073 CalendarEntries payCalendarEntries = TkServiceLocator.getCalendarEntriesService().getCalendarEntries(laaf.getHrPyCalendarEntriesId());
074 if (persons.isEmpty()) {
075 laaf.setLeaveApprovalRows(new ArrayList<ApprovalLeaveSummaryRow>());
076 laaf.setResultSize(0);
077 } else {
078 this.setApprovalTables(laaf, principalIds, request, payCalendarEntries);
079
080 laaf.setPayCalendarEntries(payCalendarEntries);
081 laaf.setLeaveCalendarDates(TkServiceLocator.getLeaveSummaryService().getLeaveSummaryDates(payCalendarEntries));
082
083 List<Assignment> assignments = TkServiceLocator.getAssignmentService().getAssignments(laaf.getSearchTerm(), payCalendarEntries.getEndPeriodDate());
084 if(!assignments.isEmpty()){
085 for(Long wa : laaf.getWorkAreaDescr().keySet()){
086 for (Assignment assign : assignments) {
087 if (assign.getWorkArea().toString().equals(wa.toString())) {
088 laaf.setSelectedWorkArea(wa.toString());
089 break;
090 }
091 }
092 }
093 }
094 }
095
096 return mapping.findForward("basic");
097 }
098
099 public ActionForward approve(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
100 LeaveApprovalActionForm laaf = (LeaveApprovalActionForm) form;
101
102 List<ApprovalLeaveSummaryRow> lstLeaveRows = laaf.getLeaveApprovalRows();
103 for (ApprovalLeaveSummaryRow ar : lstLeaveRows) {
104 if (ar.isApprovable() && StringUtils.equals(ar.getSelected(), "on")) {
105 String documentNumber = ar.getDocumentId();
106 LeaveCalendarDocument lcd = TkServiceLocator.getLeaveCalendarService().getLeaveCalendarDocument(documentNumber);
107 TkServiceLocator.getLeaveCalendarService().approveLeaveCalendar(TKContext.getPrincipalId(), lcd);
108 }
109 }
110
111 return mapping.findForward("basic");
112 }
113
114 public ActionForward selectNewDept(ActionMapping mapping, ActionForm form,
115 HttpServletRequest request, HttpServletResponse response)
116 throws Exception {
117 LeaveApprovalActionForm laaf = (LeaveApprovalActionForm)form;
118 laaf.setSearchField(null);
119 laaf.setSearchTerm(null);
120
121 CalendarEntries payCalendarEntries = TkServiceLocator.getCalendarEntriesService().getCalendarEntries(laaf.getHrPyCalendarEntriesId());
122 laaf.setPayCalendarEntries(payCalendarEntries);
123 laaf.setLeaveCalendarDates(TkServiceLocator.getLeaveSummaryService().getLeaveSummaryDates(payCalendarEntries));
124
125 laaf.getWorkAreaDescr().clear();
126 laaf.setSelectedWorkArea("");
127 List<WorkArea> workAreas = TkServiceLocator.getWorkAreaService().getWorkAreas(laaf.getSelectedDept(), new java.sql.Date(laaf.getPayBeginDate().getTime()));
128 for(WorkArea wa : workAreas){
129 if (TKContext.getUser().getApproverWorkAreas().contains(wa.getWorkArea())
130 || TKContext.getUser().getReviewerWorkAreas().contains(wa.getWorkArea())) {
131 laaf.getWorkAreaDescr().put(wa.getWorkArea(),wa.getDescription()+"("+wa.getWorkArea()+")");
132 }
133 }
134
135 List<String> principalIds = this.getPrincipalIdsToPopulateTable(laaf);
136 this.setApprovalTables(laaf, principalIds, request, payCalendarEntries);
137
138 this.populateCalendarAndPayPeriodLists(request, laaf);
139 return mapping.findForward("basic");
140 }
141
142 public ActionForward selectNewWorkArea(ActionMapping mapping, ActionForm form,
143 HttpServletRequest request, HttpServletResponse response)
144 throws Exception {
145 LeaveApprovalActionForm laaf = (LeaveApprovalActionForm)form;
146 laaf.setSearchField(null);
147 laaf.setSearchTerm(null);
148
149 CalendarEntries payCalendarEntries = TkServiceLocator.getCalendarEntriesService().getCalendarEntries(laaf.getHrPyCalendarEntriesId());
150 laaf.setLeaveCalendarDates(TkServiceLocator.getLeaveSummaryService().getLeaveSummaryDates(payCalendarEntries));
151
152 List<String> idList = this.getPrincipalIdsToPopulateTable(laaf);
153 this.setApprovalTables(laaf, idList , request, payCalendarEntries);
154
155 return mapping.findForward("basic");
156 }
157
158 private List<String> getPrincipalIdsToPopulateTable(LeaveApprovalActionForm laaf) {
159 List<String> workAreaList = new ArrayList<String>();
160 if(StringUtil.isEmpty(laaf.getSelectedWorkArea())) {
161 for(Long aKey : laaf.getWorkAreaDescr().keySet()) {
162 workAreaList.add(aKey.toString());
163 }
164 } else {
165 workAreaList.add(laaf.getSelectedWorkArea());
166 }
167 java.sql.Date endDate = new java.sql.Date(laaf.getPayEndDate().getTime());
168 java.sql.Date beginDate = new java.sql.Date(laaf.getPayBeginDate().getTime());
169
170 List<String> idList = TkServiceLocator.getLeaveApprovalService()
171 .getLeavePrincipalIdsWithSearchCriteria(workAreaList, laaf.getSelectedPayCalendarGroup(), endDate, beginDate, endDate);
172 return idList;
173 }
174
175 private void setApprovalTables(LeaveApprovalActionForm laaf, List<String> principalIds, HttpServletRequest request, CalendarEntries payCalendarEntries) {
176 laaf.setLeaveCalendarDates(TkServiceLocator.getLeaveSummaryService().getLeaveSummaryDates(payCalendarEntries));
177
178 if (principalIds.isEmpty()) {
179 laaf.setLeaveApprovalRows(new ArrayList<ApprovalLeaveSummaryRow>());
180 laaf.setResultSize(0);
181 } else {
182 List<TKPerson> persons = TkServiceLocator.getPersonService().getPersonCollection(principalIds);
183 List<ApprovalLeaveSummaryRow> approvalRows = getApprovalLeaveRows(laaf, getSubListPrincipalIds(request, persons));
184
185 final String sortField = request.getParameter("sortField");
186 if (StringUtils.equals(sortField, "Name")) {
187 final boolean sortNameAscending = Boolean.parseBoolean(request.getParameter("sortNameAscending"));
188 Collections.sort(approvalRows, new Comparator<ApprovalLeaveSummaryRow>() {
189 @Override
190 public int compare(ApprovalLeaveSummaryRow row1, ApprovalLeaveSummaryRow row2) {
191 if (sortNameAscending) {
192 return ObjectUtils.compare(StringUtils.lowerCase(row1.getName()), StringUtils.lowerCase(row2.getName()));
193 } else {
194 return ObjectUtils.compare(StringUtils.lowerCase(row2.getName()), StringUtils.lowerCase(row1.getName()));
195 }
196 }
197 });
198 } else if (StringUtils.equals(sortField, "DocumentID")) {
199 final boolean sortDocumentIdAscending = Boolean.parseBoolean(request.getParameter("sortDocumentIDAscending"));
200 Collections.sort(approvalRows, new Comparator<ApprovalLeaveSummaryRow>() {
201 @Override
202 public int compare(ApprovalLeaveSummaryRow row1, ApprovalLeaveSummaryRow row2) {
203 if (sortDocumentIdAscending) {
204 return ObjectUtils.compare(NumberUtils.toInt(row1.getDocumentId()), NumberUtils.toInt(row2.getDocumentId()));
205 } else {
206 return ObjectUtils.compare(NumberUtils.toInt(row2.getDocumentId()), NumberUtils.toInt(row1.getDocumentId()));
207 }
208 }
209 });
210 } else if (StringUtils.equals(sortField, "Status")) {
211 final boolean sortStatusIdAscending = Boolean.parseBoolean(request.getParameter("sortStatusAscending"));
212 Collections.sort(approvalRows, new Comparator<ApprovalLeaveSummaryRow>() {
213 @Override
214 public int compare(ApprovalLeaveSummaryRow row1, ApprovalLeaveSummaryRow row2) {
215 if (sortStatusIdAscending) {
216 return ObjectUtils.compare(StringUtils.lowerCase(row1.getApprovalStatus()), StringUtils.lowerCase(row2.getApprovalStatus()));
217 } else {
218 return ObjectUtils.compare(StringUtils.lowerCase(row2.getApprovalStatus()), StringUtils.lowerCase(row1.getApprovalStatus()));
219 }
220 }
221 });
222 }
223
224 laaf.setLeaveApprovalRows(approvalRows);
225 laaf.setResultSize(persons.size());
226 }
227 }
228
229 @Override
230 public ActionForward loadApprovalTab(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
231 throws Exception {
232 ActionForward fwd = mapping.findForward("basic");
233 TKUser user = TKContext.getUser();
234 LeaveApprovalActionForm laaf = (LeaveApprovalActionForm) form;
235 Date currentDate = null;
236 CalendarEntries payCalendarEntries = null;
237 Calendar currentPayCalendar = null;
238 String page = request.getParameter((new ParamEncoder(TkConstants.APPROVAL_TABLE_ID).encodeParameterName(TableTagParameters.PARAMETER_PAGE)));
239
240
241 //reset state
242 if(StringUtils.isBlank(laaf.getSelectedDept())){
243 resetState(form, request);
244 }
245
246 // Set current pay calendar entries if present. Decide if the current date should be today or the end period date
247 if (laaf.getHrPyCalendarEntriesId() != null) {
248 if(payCalendarEntries == null){
249 payCalendarEntries = TkServiceLocator.getCalendarEntriesService().getCalendarEntries(laaf.getHrPyCalendarEntriesId());
250 }
251 currentDate = payCalendarEntries.getEndPeriodDate();
252 } else {
253 currentDate = TKUtils.getTimelessDate(null);
254 }
255 Set<Long> workAreas = TkServiceLocator.getTkRoleService().getWorkAreasForApprover(TKContext.getPrincipalId(), currentDate);
256 // should we use all three roles to find work areas???
257 // List<String> roleNameList = Arrays.asList(TkConstants.ROLE_TK_APPROVER, TkConstants.ROLE_TK_APPROVER_DELEGATE, TkConstants.ROLE_TK_REVIEWER);
258 // Set<Long> workAreas = TkServiceLocator.getTkRoleService().getWorkAreasForRoleNames(TKContext.getPrincipalId(), roleNameList, currentDate);
259
260 List<String> principalIds = new ArrayList<String>();
261 for (Long workArea : workAreas) {
262 List<Assignment> assignments = TkServiceLocator.getAssignmentService().getActiveAssignmentsForWorkArea(workArea, currentDate);
263 for (Assignment a : assignments) {
264 principalIds.add(a.getPrincipalId());
265 }
266 }
267
268 // Set calendar groups
269 List<String> calGroups = new ArrayList<String>();
270 if (CollectionUtils.isNotEmpty(principalIds)) {
271 calGroups = TkServiceLocator.getLeaveApprovalService().getUniqueLeavePayGroupsForPrincipalIds(principalIds);
272 }
273 laaf.setPayCalendarGroups(calGroups);
274
275 if (StringUtils.isBlank(laaf.getSelectedPayCalendarGroup())
276 && CollectionUtils.isNotEmpty(calGroups)) {
277 laaf.setSelectedPayCalendarGroup(calGroups.get(0));
278
279 }
280
281 // Set current pay calendar entries if present. Decide if the current date should be today or the end period date
282 if (laaf.getHrPyCalendarEntriesId() != null) {
283 payCalendarEntries = TkServiceLocator.getCalendarEntriesService().getCalendarEntries(laaf.getHrPyCalendarEntriesId());
284 } else {
285 currentPayCalendar = TkServiceLocator.getCalendarService().getCalendarByGroup(laaf.getSelectedPayCalendarGroup());
286 if (currentPayCalendar != null) {
287 payCalendarEntries = TkServiceLocator.getCalendarEntriesService().getCurrentCalendarEntriesByCalendarId(currentPayCalendar.getHrCalendarId(), currentDate);
288 }
289 }
290 laaf.setPayCalendarEntries(payCalendarEntries);
291
292
293 if(laaf.getPayCalendarEntries() != null) {
294 populateCalendarAndPayPeriodLists(request, laaf);
295 }
296 setupDocumentOnFormContext(request,laaf,payCalendarEntries, page);
297 return fwd;
298 }
299
300 @Override
301 protected void setupDocumentOnFormContext(HttpServletRequest request,ApprovalForm form, CalendarEntries payCalendarEntries, String page) {
302 super.setupDocumentOnFormContext(request, form, payCalendarEntries, page);
303 LeaveApprovalActionForm laaf = (LeaveApprovalActionForm)form;
304
305 if (payCalendarEntries != null) {
306 laaf.setLeaveCalendarDates(TkServiceLocator.getLeaveSummaryService().getLeaveSummaryDates(payCalendarEntries));
307 List<String> principalIds = this.getPrincipalIdsToPopulateTable(laaf);
308 this.setApprovalTables(laaf, principalIds, request, payCalendarEntries);
309 laaf.setOnCurrentPeriod(ActionFormUtils.getOnCurrentPeriodFlag(laaf.getPayCalendarEntries()));
310 }
311 }
312
313 public ActionForward selectNewPayCalendar(ActionMapping mapping, ActionForm form,
314 HttpServletRequest request, HttpServletResponse response)
315 throws Exception {
316 // resets the common fields for approval pages
317 super.resetMainFields(form);
318 LeaveApprovalActionForm laaf = (LeaveApprovalActionForm)form;
319 // KPME-909
320 laaf.setLeaveApprovalRows(new ArrayList<ApprovalLeaveSummaryRow>());
321
322 return loadApprovalTab(mapping, form, request, response);
323 }
324
325 protected List<ApprovalLeaveSummaryRow> getApprovalLeaveRows(LeaveApprovalActionForm laaf, List<TKPerson> assignmentPrincipalIds) {
326 return TkServiceLocator.getLeaveApprovalService().getLeaveApprovalSummaryRows
327 (assignmentPrincipalIds, laaf.getPayCalendarEntries(), laaf.getLeaveCalendarDates());
328 }
329
330 public void resetState(ActionForm form, HttpServletRequest request) {
331 LeaveApprovalActionForm laaf = (LeaveApprovalActionForm) form;
332 String page = request.getParameter((new ParamEncoder(TkConstants.APPROVAL_TABLE_ID).encodeParameterName(TableTagParameters.PARAMETER_PAGE)));
333
334 if (StringUtils.isBlank(page)) {
335 laaf.getDepartments().clear();
336 laaf.getWorkAreaDescr().clear();
337 laaf.setLeaveApprovalRows(new ArrayList<ApprovalLeaveSummaryRow>());
338 laaf.setSelectedDept(null);
339 laaf.setSearchField(null);
340 laaf.setSearchTerm(null);
341 }
342 }
343
344 @Override
345 protected void populateCalendarAndPayPeriodLists(HttpServletRequest request, ApprovalForm taf) {
346 LeaveApprovalActionForm laaf = (LeaveApprovalActionForm) taf;
347 // set calendar year list
348 Set<String> yearSet = new HashSet<String>();
349 SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
350 // if selected calendar year is passed in
351 if(!StringUtils.isEmpty(request.getParameter("selectedCY"))) {
352 laaf.setSelectedCalendarYear(request.getParameter("selectedCY").toString());
353 } else {
354 laaf.setSelectedCalendarYear(sdf.format(laaf.getPayCalendarEntries().getBeginPeriodDate()));
355 }
356
357 List<CalendarEntries> pcListForYear = new ArrayList<CalendarEntries>();
358 List<CalendarEntries> pceList = new ArrayList<CalendarEntries>();
359 pceList.addAll(TkServiceLocator.getLeaveApprovalService()
360 .getAllLeavePayCalendarEntriesForApprover(TKContext.getPrincipalId(), TKUtils.getTimelessDate(null)));
361
362 for(CalendarEntries pce : pceList) {
363 yearSet.add(sdf.format(pce.getBeginPeriodDate()));
364 if(sdf.format(pce.getBeginPeriodDate()).equals(laaf.getSelectedCalendarYear())) {
365 pcListForYear.add(pce);
366 }
367 }
368 List<String> yearList = new ArrayList<String>(yearSet);
369 Collections.sort(yearList);
370 Collections.reverse(yearList); // newest on top
371 laaf.setCalendarYears(yearList);
372
373 // set pay period list contents
374 if(!StringUtils.isEmpty(request.getParameter("selectedPP"))) {
375 laaf.setSelectedPayPeriod(request.getParameter("selectedPP").toString());
376 } else {
377 laaf.setSelectedPayPeriod(laaf.getPayCalendarEntries().getHrCalendarEntriesId());
378 laaf.setPayPeriodsMap(ActionFormUtils.getPayPeriodsMap(pcListForYear));
379 }
380 if(laaf.getPayPeriodsMap().isEmpty()) {
381 laaf.setPayPeriodsMap(ActionFormUtils.getPayPeriodsMap(pcListForYear));
382 }
383 }
384
385 }