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 (TKUser.getApproverWorkAreas().contains(wa.getWorkArea()) 130 || TKUser.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 LeaveApprovalActionForm laaf = (LeaveApprovalActionForm) form; 234 Date currentDate = null; 235 CalendarEntries payCalendarEntries = null; 236 Calendar currentPayCalendar = null; 237 String page = request.getParameter((new ParamEncoder(TkConstants.APPROVAL_TABLE_ID).encodeParameterName(TableTagParameters.PARAMETER_PAGE))); 238 239 240 //reset state 241 if(StringUtils.isBlank(laaf.getSelectedDept())){ 242 resetState(form, request); 243 } 244 245 // Set current pay calendar entries if present. Decide if the current date should be today or the end period date 246 if (laaf.getHrPyCalendarEntriesId() != null) { 247 if(payCalendarEntries == null){ 248 payCalendarEntries = TkServiceLocator.getCalendarEntriesService().getCalendarEntries(laaf.getHrPyCalendarEntriesId()); 249 } 250 currentDate = payCalendarEntries.getEndPeriodDate(); 251 } else { 252 currentDate = TKUtils.getTimelessDate(null); 253 } 254 Set<Long> workAreas = TkServiceLocator.getTkRoleService().getWorkAreasForApprover(TKContext.getPrincipalId(), currentDate); 255 // should we use all three roles to find work areas??? 256 // List<String> roleNameList = Arrays.asList(TkConstants.ROLE_TK_APPROVER, TkConstants.ROLE_TK_APPROVER_DELEGATE, TkConstants.ROLE_TK_REVIEWER); 257 // Set<Long> workAreas = TkServiceLocator.getTkRoleService().getWorkAreasForRoleNames(TKContext.getPrincipalId(), roleNameList, currentDate); 258 259 List<String> principalIds = new ArrayList<String>(); 260 for (Long workArea : workAreas) { 261 List<Assignment> assignments = TkServiceLocator.getAssignmentService().getActiveAssignmentsForWorkArea(workArea, currentDate); 262 for (Assignment a : assignments) { 263 principalIds.add(a.getPrincipalId()); 264 } 265 } 266 267 // Set calendar groups 268 List<String> calGroups = new ArrayList<String>(); 269 if (CollectionUtils.isNotEmpty(principalIds)) { 270 calGroups = TkServiceLocator.getLeaveApprovalService().getUniqueLeavePayGroupsForPrincipalIds(principalIds); 271 } 272 laaf.setPayCalendarGroups(calGroups); 273 274 if (StringUtils.isBlank(laaf.getSelectedPayCalendarGroup()) 275 && CollectionUtils.isNotEmpty(calGroups)) { 276 laaf.setSelectedPayCalendarGroup(calGroups.get(0)); 277 278 } 279 280 // Set current pay calendar entries if present. Decide if the current date should be today or the end period date 281 if (laaf.getHrPyCalendarEntriesId() != null) { 282 payCalendarEntries = TkServiceLocator.getCalendarEntriesService().getCalendarEntries(laaf.getHrPyCalendarEntriesId()); 283 } else { 284 currentPayCalendar = TkServiceLocator.getCalendarService().getCalendarByGroup(laaf.getSelectedPayCalendarGroup()); 285 if (currentPayCalendar != null) { 286 payCalendarEntries = TkServiceLocator.getCalendarEntriesService().getCurrentCalendarEntriesByCalendarId(currentPayCalendar.getHrCalendarId(), currentDate); 287 } 288 } 289 laaf.setPayCalendarEntries(payCalendarEntries); 290 291 292 if(laaf.getPayCalendarEntries() != null) { 293 populateCalendarAndPayPeriodLists(request, laaf); 294 } 295 setupDocumentOnFormContext(request,laaf,payCalendarEntries, page); 296 return fwd; 297 } 298 299 @Override 300 protected void setupDocumentOnFormContext(HttpServletRequest request,ApprovalForm form, CalendarEntries payCalendarEntries, String page) { 301 super.setupDocumentOnFormContext(request, form, payCalendarEntries, page); 302 LeaveApprovalActionForm laaf = (LeaveApprovalActionForm)form; 303 304 if (payCalendarEntries != null) { 305 laaf.setLeaveCalendarDates(TkServiceLocator.getLeaveSummaryService().getLeaveSummaryDates(payCalendarEntries)); 306 List<String> principalIds = this.getPrincipalIdsToPopulateTable(laaf); 307 this.setApprovalTables(laaf, principalIds, request, payCalendarEntries); 308 laaf.setOnCurrentPeriod(ActionFormUtils.getOnCurrentPeriodFlag(laaf.getPayCalendarEntries())); 309 } 310 } 311 312 public ActionForward selectNewPayCalendar(ActionMapping mapping, ActionForm form, 313 HttpServletRequest request, HttpServletResponse response) 314 throws Exception { 315 // resets the common fields for approval pages 316 super.resetMainFields(form); 317 LeaveApprovalActionForm laaf = (LeaveApprovalActionForm)form; 318 // KPME-909 319 laaf.setLeaveApprovalRows(new ArrayList<ApprovalLeaveSummaryRow>()); 320 321 return loadApprovalTab(mapping, form, request, response); 322 } 323 324 protected List<ApprovalLeaveSummaryRow> getApprovalLeaveRows(LeaveApprovalActionForm laaf, List<TKPerson> assignmentPrincipalIds) { 325 return TkServiceLocator.getLeaveApprovalService().getLeaveApprovalSummaryRows 326 (assignmentPrincipalIds, laaf.getPayCalendarEntries(), laaf.getLeaveCalendarDates()); 327 } 328 329 public void resetState(ActionForm form, HttpServletRequest request) { 330 LeaveApprovalActionForm laaf = (LeaveApprovalActionForm) form; 331 String page = request.getParameter((new ParamEncoder(TkConstants.APPROVAL_TABLE_ID).encodeParameterName(TableTagParameters.PARAMETER_PAGE))); 332 333 if (StringUtils.isBlank(page)) { 334 laaf.getDepartments().clear(); 335 laaf.getWorkAreaDescr().clear(); 336 laaf.setLeaveApprovalRows(new ArrayList<ApprovalLeaveSummaryRow>()); 337 laaf.setSelectedDept(null); 338 laaf.setSearchField(null); 339 laaf.setSearchTerm(null); 340 } 341 } 342 343 @Override 344 protected void populateCalendarAndPayPeriodLists(HttpServletRequest request, ApprovalForm taf) { 345 LeaveApprovalActionForm laaf = (LeaveApprovalActionForm) taf; 346 // set calendar year list 347 Set<String> yearSet = new HashSet<String>(); 348 SimpleDateFormat sdf = new SimpleDateFormat("yyyy"); 349 // if selected calendar year is passed in 350 if(!StringUtils.isEmpty(request.getParameter("selectedCY"))) { 351 laaf.setSelectedCalendarYear(request.getParameter("selectedCY").toString()); 352 } else { 353 laaf.setSelectedCalendarYear(sdf.format(laaf.getPayCalendarEntries().getBeginPeriodDate())); 354 } 355 356 List<CalendarEntries> pcListForYear = new ArrayList<CalendarEntries>(); 357 List<CalendarEntries> pceList = new ArrayList<CalendarEntries>(); 358 pceList.addAll(TkServiceLocator.getLeaveApprovalService() 359 .getAllLeavePayCalendarEntriesForApprover(TKContext.getPrincipalId(), TKUtils.getTimelessDate(null))); 360 361 for(CalendarEntries pce : pceList) { 362 yearSet.add(sdf.format(pce.getBeginPeriodDate())); 363 if(sdf.format(pce.getBeginPeriodDate()).equals(laaf.getSelectedCalendarYear())) { 364 pcListForYear.add(pce); 365 } 366 } 367 List<String> yearList = new ArrayList<String>(yearSet); 368 Collections.sort(yearList); 369 Collections.reverse(yearList); // newest on top 370 laaf.setCalendarYears(yearList); 371 372 // set pay period list contents 373 if(!StringUtils.isEmpty(request.getParameter("selectedPP"))) { 374 laaf.setSelectedPayPeriod(request.getParameter("selectedPP").toString()); 375 } else { 376 laaf.setSelectedPayPeriod(laaf.getPayCalendarEntries().getHrCalendarEntriesId()); 377 laaf.setPayPeriodsMap(ActionFormUtils.getPayPeriodsMap(pcListForYear, null)); 378 } 379 if(laaf.getPayPeriodsMap().isEmpty()) { 380 laaf.setPayPeriodsMap(ActionFormUtils.getPayPeriodsMap(pcListForYear, null)); 381 } 382 } 383 384 }