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.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.hsqldb.lib.StringUtil; 039 import org.kuali.hr.time.assignment.Assignment; 040 import org.kuali.hr.time.base.web.ApprovalAction; 041 import org.kuali.hr.time.base.web.ApprovalForm; 042 import org.kuali.hr.time.calendar.Calendar; 043 import org.kuali.hr.time.calendar.CalendarEntries; 044 import org.kuali.hr.time.detail.web.ActionFormUtils; 045 import org.kuali.hr.time.person.TKPerson; 046 import org.kuali.hr.time.service.base.TkServiceLocator; 047 import org.kuali.hr.time.timesheet.TimesheetDocument; 048 import org.kuali.hr.time.util.TKContext; 049 import org.kuali.hr.time.util.TKUser; 050 import org.kuali.hr.time.util.TKUtils; 051 import org.kuali.hr.time.util.TkConstants; 052 import org.kuali.hr.time.workarea.WorkArea; 053 import org.kuali.hr.time.workflow.TimesheetDocumentHeader; 054 055 public class TimeApprovalAction extends ApprovalAction{ 056 057 public ActionForward searchResult(ActionMapping mapping, ActionForm form, 058 HttpServletRequest request, HttpServletResponse response) 059 throws Exception { 060 TimeApprovalActionForm taaf = (TimeApprovalActionForm)form; 061 062 if (StringUtils.equals("documentId", taaf.getSearchField())) { 063 TimesheetDocumentHeader tdh = TkServiceLocator.getTimesheetDocumentHeaderService().getDocumentHeader(taaf.getSearchTerm()); 064 taaf.setSearchTerm(tdh != null ? tdh.getPrincipalId() : StringUtils.EMPTY); 065 } 066 067 taaf.setSearchField("principalId"); 068 List<String> principalIds = new ArrayList<String>(); 069 principalIds.add(taaf.getSearchTerm()); 070 List<TKPerson> persons = TkServiceLocator.getPersonService().getPersonCollection(principalIds); 071 if (persons.isEmpty()) { 072 taaf.setApprovalRows(new ArrayList<ApprovalTimeSummaryRow>()); 073 taaf.setResultSize(0); 074 } else { 075 taaf.setResultSize(persons.size()); 076 taaf.setApprovalRows(getApprovalRows(taaf, persons)); 077 078 CalendarEntries payCalendarEntries = TkServiceLocator.getCalendarEntriesService().getCalendarEntries(taaf.getHrPyCalendarEntriesId()); 079 taaf.setPayCalendarEntries(payCalendarEntries); 080 taaf.setPayCalendarLabels(TkServiceLocator.getTimeSummaryService().getHeaderForSummary(payCalendarEntries, new ArrayList<Boolean>())); 081 082 List<Assignment> assignments = TkServiceLocator.getAssignmentService().getAssignments(taaf.getSearchTerm(), payCalendarEntries.getEndPeriodDate()); 083 if(!assignments.isEmpty()){ 084 for(Long wa : taaf.getWorkAreaDescr().keySet()){ 085 for (Assignment assign : assignments) { 086 if (assign.getWorkArea().toString().equals(wa.toString())) { 087 taaf.setSelectedWorkArea(wa.toString()); 088 break; 089 } 090 } 091 } 092 } 093 } 094 095 return mapping.findForward("basic"); 096 } 097 098 public ActionForward approve(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 099 TimeApprovalActionForm taaf = (TimeApprovalActionForm) form; 100 List<ApprovalTimeSummaryRow> lstApprovalRows = taaf.getApprovalRows(); 101 for (ApprovalTimeSummaryRow ar : lstApprovalRows) { 102 if (ar.isApprovable() && StringUtils.equals(ar.getSelected(), "on")) { 103 String documentNumber = ar.getDocumentId(); 104 TimesheetDocument tDoc = TkServiceLocator.getTimesheetService().getTimesheetDocument(documentNumber); 105 TkServiceLocator.getTimesheetService().approveTimesheet(TKContext.getTargetPrincipalId(), tDoc); 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 TimeApprovalActionForm taaf = (TimeApprovalActionForm)form; 115 taaf.setSearchField(null); 116 taaf.setSearchTerm(null); 117 118 CalendarEntries payCalendarEntries = TkServiceLocator.getCalendarEntriesService().getCalendarEntries(taaf.getHrPyCalendarEntriesId()); 119 taaf.setPayCalendarEntries(payCalendarEntries); 120 taaf.setPayCalendarLabels(TkServiceLocator.getTimeSummaryService().getHeaderForSummary(payCalendarEntries, new ArrayList<Boolean>())); 121 122 taaf.getWorkAreaDescr().clear(); 123 List<WorkArea> workAreas = TkServiceLocator.getWorkAreaService().getWorkAreas(taaf.getSelectedDept(), new java.sql.Date(taaf.getPayBeginDate().getTime())); 124 for(WorkArea wa : workAreas){ 125 if (TKUser.getApproverWorkAreas().contains(wa.getWorkArea()) 126 || TKUser.getReviewerWorkAreas().contains(wa.getWorkArea())) { 127 taaf.getWorkAreaDescr().put(wa.getWorkArea(),wa.getDescription()+"("+wa.getWorkArea()+")"); 128 } 129 } 130 131 List<String> principalIds = this.getPrincipalIdsToPopulateTable(taaf); 132 if (principalIds.isEmpty()) { 133 taaf.setApprovalRows(new ArrayList<ApprovalTimeSummaryRow>()); 134 taaf.setResultSize(0); 135 } 136 else { 137 List<TKPerson> persons = TkServiceLocator.getPersonService().getPersonCollection(principalIds); 138 Collections.sort(persons); 139 taaf.setApprovalRows(getApprovalRows(taaf, getSubListPrincipalIds(request, persons))); 140 taaf.setResultSize(persons.size()); 141 } 142 143 this.populateCalendarAndPayPeriodLists(request, taaf); 144 return mapping.findForward("basic"); 145 } 146 147 public ActionForward selectNewWorkArea(ActionMapping mapping, ActionForm form, 148 HttpServletRequest request, HttpServletResponse response) 149 throws Exception { 150 TimeApprovalActionForm taaf = (TimeApprovalActionForm)form; 151 taaf.setSearchField(null); 152 taaf.setSearchTerm(null); 153 154 CalendarEntries payCalendarEntries = TkServiceLocator.getCalendarEntriesService().getCalendarEntries(taaf.getHrPyCalendarEntriesId()); 155 taaf.setPayCalendarLabels(TkServiceLocator.getTimeSummaryService().getHeaderForSummary(payCalendarEntries, new ArrayList<Boolean>())); 156 157 List<String> principalIds = this.getPrincipalIdsToPopulateTable(taaf); 158 if (principalIds.isEmpty()) { 159 taaf.setApprovalRows(new ArrayList<ApprovalTimeSummaryRow>()); 160 taaf.setResultSize(0); 161 } 162 else { 163 List<TKPerson> persons = TkServiceLocator.getPersonService().getPersonCollection(principalIds); 164 Collections.sort(persons); 165 taaf.setApprovalRows(getApprovalRows(taaf, getSubListPrincipalIds(request, persons))); 166 taaf.setResultSize(persons.size()); 167 } 168 return mapping.findForward("basic"); 169 } 170 171 @Override 172 public ActionForward loadApprovalTab(ActionMapping mapping, ActionForm form, 173 HttpServletRequest request, HttpServletResponse response) 174 throws Exception { 175 ActionForward fwd = mapping.findForward("basic"); 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.getPrincipalHRAttributeService().getUniqueTimePayGroups(); 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 } else { 198 currentDate = TKUtils.getTimelessDate(null); 199 currentPayCalendar = TkServiceLocator.getCalendarService().getCalendarByGroup(taaf.getSelectedPayCalendarGroup()); 200 payCalendarEntries = TkServiceLocator.getCalendarEntriesService().getCurrentCalendarEntriesByCalendarId(currentPayCalendar.getHrCalendarId(), currentDate); 201 } 202 taaf.setPayCalendarEntries(payCalendarEntries); 203 204 205 if(taaf.getPayCalendarEntries() != null) { 206 populateCalendarAndPayPeriodLists(request, taaf); 207 } 208 setupDocumentOnFormContext(request,taaf,payCalendarEntries, page); 209 return fwd; 210 } 211 212 @Override 213 protected void setupDocumentOnFormContext(HttpServletRequest request,ApprovalForm form, CalendarEntries payCalendarEntries, String page) { 214 super.setupDocumentOnFormContext(request, form, payCalendarEntries, page); 215 TimeApprovalActionForm taaf = (TimeApprovalActionForm) form; 216 taaf.setPayCalendarLabels(TkServiceLocator.getTimeSummaryService().getHeaderForSummary(payCalendarEntries, new ArrayList<Boolean>())); 217 218 List<String> principalIds = this.getPrincipalIdsToPopulateTable(taaf); 219 if (principalIds.isEmpty()) { 220 taaf.setApprovalRows(new ArrayList<ApprovalTimeSummaryRow>()); 221 taaf.setResultSize(0); 222 } else { 223 List<TKPerson> persons = TkServiceLocator.getPersonService().getPersonCollection(principalIds); 224 List<ApprovalTimeSummaryRow> approvalRows = getApprovalRows(taaf, getSubListPrincipalIds(request, persons)); 225 226 final String sortField = request.getParameter("sortField"); 227 if (StringUtils.equals(sortField, "Name")) { 228 final boolean sortNameAscending = Boolean.parseBoolean(request.getParameter("sortNameAscending")); 229 Collections.sort(approvalRows, new Comparator<ApprovalTimeSummaryRow>() { 230 @Override 231 public int compare(ApprovalTimeSummaryRow row1, ApprovalTimeSummaryRow row2) { 232 if (sortNameAscending) { 233 return ObjectUtils.compare(StringUtils.lowerCase(row1.getName()), StringUtils.lowerCase(row2.getName())); 234 } else { 235 return ObjectUtils.compare(StringUtils.lowerCase(row2.getName()), StringUtils.lowerCase(row1.getName())); 236 } 237 } 238 }); 239 } else if (StringUtils.equals(sortField, "DocumentID")) { 240 final boolean sortDocumentIdAscending = Boolean.parseBoolean(request.getParameter("sortDocumentIDAscending")); 241 Collections.sort(approvalRows, new Comparator<ApprovalTimeSummaryRow>() { 242 @Override 243 public int compare(ApprovalTimeSummaryRow row1, ApprovalTimeSummaryRow row2) { 244 if (sortDocumentIdAscending) { 245 return ObjectUtils.compare(NumberUtils.toInt(row1.getDocumentId()), NumberUtils.toInt(row2.getDocumentId())); 246 } else { 247 return ObjectUtils.compare(NumberUtils.toInt(row2.getDocumentId()), NumberUtils.toInt(row1.getDocumentId())); 248 } 249 } 250 }); 251 } else if (StringUtils.equals(sortField, "Status")) { 252 final boolean sortStatusIdAscending = Boolean.parseBoolean(request.getParameter("sortStatusAscending")); 253 Collections.sort(approvalRows, new Comparator<ApprovalTimeSummaryRow>() { 254 @Override 255 public int compare(ApprovalTimeSummaryRow row1, ApprovalTimeSummaryRow row2) { 256 if (sortStatusIdAscending) { 257 return ObjectUtils.compare(StringUtils.lowerCase(row1.getApprovalStatus()), StringUtils.lowerCase(row2.getApprovalStatus())); 258 } else { 259 return ObjectUtils.compare(StringUtils.lowerCase(row2.getApprovalStatus()), StringUtils.lowerCase(row1.getApprovalStatus())); 260 } 261 } 262 }); 263 } 264 265 taaf.setApprovalRows(approvalRows); 266 taaf.setResultSize(persons.size()); 267 } 268 269 taaf.setOnCurrentPeriod(ActionFormUtils.getOnCurrentPeriodFlag(taaf.getPayCalendarEntries())); 270 } 271 272 public ActionForward selectNewPayCalendar(ActionMapping mapping, ActionForm form, 273 HttpServletRequest request, HttpServletResponse response) 274 throws Exception { 275 // resets the common fields for approval pages 276 super.resetMainFields(form); 277 TimeApprovalActionForm taaf = (TimeApprovalActionForm)form; 278 // KPME-909 279 taaf.setApprovalRows(new ArrayList<ApprovalTimeSummaryRow>()); 280 return loadApprovalTab(mapping, form, request, response); 281 } 282 283 /** 284 * Helper method to modify / manage the list of records needed to display approval data to the user. 285 * 286 * @param taaf 287 * @return 288 */ 289 protected List<ApprovalTimeSummaryRow> getApprovalRows(TimeApprovalActionForm taaf, List<TKPerson> assignmentPrincipalIds) { 290 return TkServiceLocator.getTimeApproveService().getApprovalSummaryRows(taaf.getPayBeginDate(), taaf.getPayEndDate(), taaf.getSelectedPayCalendarGroup(), assignmentPrincipalIds, taaf.getPayCalendarLabels(), taaf.getPayCalendarEntries()); 291 } 292 293 public void resetState(ActionForm form, HttpServletRequest request) { 294 TimeApprovalActionForm taaf = (TimeApprovalActionForm) form; 295 String page = request.getParameter((new ParamEncoder(TkConstants.APPROVAL_TABLE_ID).encodeParameterName(TableTagParameters.PARAMETER_PAGE))); 296 297 if (StringUtils.isBlank(page)) { 298 taaf.getDepartments().clear(); 299 taaf.getWorkAreaDescr().clear(); 300 taaf.setApprovalRows(new ArrayList<ApprovalTimeSummaryRow>()); 301 taaf.setSelectedDept(null); 302 taaf.setSearchField(null); 303 taaf.setSearchTerm(null); 304 } 305 } 306 307 @Override 308 protected void populateCalendarAndPayPeriodLists(HttpServletRequest request, ApprovalForm taf) { 309 TimeApprovalActionForm taaf = (TimeApprovalActionForm)taf; 310 // set calendar year list 311 Set<String> yearSet = new HashSet<String>(); 312 SimpleDateFormat sdf = new SimpleDateFormat("yyyy"); 313 // if selected calendar year is passed in 314 if(!StringUtils.isEmpty(request.getParameter("selectedCY"))) { 315 taaf.setSelectedCalendarYear(request.getParameter("selectedCY").toString()); 316 } else { 317 taaf.setSelectedCalendarYear(sdf.format(taaf.getPayCalendarEntries().getBeginPeriodDate())); 318 } 319 320 List<CalendarEntries> pcListForYear = new ArrayList<CalendarEntries>(); 321 List<CalendarEntries> pceList = TkServiceLocator.getTimeApproveService() 322 .getAllPayCalendarEntriesForApprover(TKContext.getTargetPrincipalId(), TKUtils.getTimelessDate(null)); 323 for(CalendarEntries pce : pceList) { 324 yearSet.add(sdf.format(pce.getBeginPeriodDate())); 325 if(sdf.format(pce.getBeginPeriodDate()).equals(taaf.getSelectedCalendarYear())) { 326 pcListForYear.add(pce); 327 } 328 } 329 List<String> yearList = new ArrayList<String>(yearSet); 330 Collections.sort(yearList); 331 Collections.reverse(yearList); // newest on top 332 taaf.setCalendarYears(yearList); 333 334 // set pay period list contents 335 if(!StringUtils.isEmpty(request.getParameter("selectedPP"))) { 336 taaf.setSelectedPayPeriod(request.getParameter("selectedPP").toString()); 337 } else { 338 taaf.setSelectedPayPeriod(taaf.getPayCalendarEntries().getHrCalendarEntriesId()); 339 taaf.setPayPeriodsMap(ActionFormUtils.getPayPeriodsMap(pcListForYear, null)); 340 } 341 if(taaf.getPayPeriodsMap().isEmpty()) { 342 taaf.setPayPeriodsMap(ActionFormUtils.getPayPeriodsMap(pcListForYear, null)); 343 } 344 } 345 346 private List<String> getPrincipalIdsToPopulateTable(TimeApprovalActionForm taf) { 347 if (taf.getPayBeginDate() == null 348 && taf.getPayEndDate() == null) { 349 return Collections.emptyList(); 350 } 351 List<String> workAreaList = new ArrayList<String>(); 352 if(StringUtil.isEmpty(taf.getSelectedWorkArea())) { 353 for(Long aKey : taf.getWorkAreaDescr().keySet()) { 354 workAreaList.add(aKey.toString()); 355 } 356 } else { 357 workAreaList.add(taf.getSelectedWorkArea()); 358 } 359 java.sql.Date endDate = new java.sql.Date(taf.getPayEndDate().getTime()); 360 java.sql.Date beginDate = new java.sql.Date(taf.getPayBeginDate().getTime()); 361 362 List<String> idList = TkServiceLocator.getTimeApproveService() 363 .getTimePrincipalIdsWithSearchCriteria(workAreaList, taf.getSelectedPayCalendarGroup(), endDate, beginDate, endDate); 364 return idList; 365 } 366 }