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.getPrincipalId(), 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 (TKContext.getUser().getApproverWorkAreas().contains(wa.getWorkArea()) 126 || TKContext.getUser().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 TKUser user = TKContext.getUser(); 177 TimeApprovalActionForm taaf = (TimeApprovalActionForm) form; 178 Date currentDate = null; 179 CalendarEntries payCalendarEntries = null; 180 Calendar currentPayCalendar = null; 181 String page = request.getParameter((new ParamEncoder(TkConstants.APPROVAL_TABLE_ID).encodeParameterName(TableTagParameters.PARAMETER_PAGE))); 182 183 //reset state 184 if(StringUtils.isBlank(taaf.getSelectedDept())){ 185 resetState(form, request); 186 } 187 // Set calendar groups 188 List<String> calGroups = TkServiceLocator.getPrincipalHRAttributeService().getUniqueTimePayGroups(); 189 taaf.setPayCalendarGroups(calGroups); 190 191 if (StringUtils.isBlank(taaf.getSelectedPayCalendarGroup())) { 192 taaf.setSelectedPayCalendarGroup(calGroups.get(0)); 193 } 194 195 // Set current pay calendar entries if present. Decide if the current date should be today or the end period date 196 if (taaf.getHrPyCalendarEntriesId() != null) { 197 payCalendarEntries = TkServiceLocator.getCalendarEntriesService().getCalendarEntries(taaf.getHrPyCalendarEntriesId()); 198 currentDate = payCalendarEntries.getEndPeriodDate(); 199 } else { 200 currentDate = TKUtils.getTimelessDate(null); 201 currentPayCalendar = TkServiceLocator.getCalendarService().getCalendarByGroup(taaf.getSelectedPayCalendarGroup()); 202 payCalendarEntries = TkServiceLocator.getCalendarEntriesService().getCurrentCalendarEntriesByCalendarId(currentPayCalendar.getHrCalendarId(), currentDate); 203 } 204 taaf.setPayCalendarEntries(payCalendarEntries); 205 206 207 if(taaf.getPayCalendarEntries() != null) { 208 populateCalendarAndPayPeriodLists(request, taaf); 209 } 210 setupDocumentOnFormContext(request,taaf,payCalendarEntries, page); 211 return fwd; 212 } 213 214 @Override 215 protected void setupDocumentOnFormContext(HttpServletRequest request,ApprovalForm form, CalendarEntries payCalendarEntries, String page) { 216 super.setupDocumentOnFormContext(request, form, payCalendarEntries, page); 217 TimeApprovalActionForm taaf = (TimeApprovalActionForm) form; 218 taaf.setPayCalendarLabels(TkServiceLocator.getTimeSummaryService().getHeaderForSummary(payCalendarEntries, new ArrayList<Boolean>())); 219 220 List<String> principalIds = this.getPrincipalIdsToPopulateTable(taaf); 221 if (principalIds.isEmpty()) { 222 taaf.setApprovalRows(new ArrayList<ApprovalTimeSummaryRow>()); 223 taaf.setResultSize(0); 224 } else { 225 List<TKPerson> persons = TkServiceLocator.getPersonService().getPersonCollection(principalIds); 226 List<ApprovalTimeSummaryRow> approvalRows = getApprovalRows(taaf, getSubListPrincipalIds(request, persons)); 227 228 final String sortField = request.getParameter("sortField"); 229 if (StringUtils.equals(sortField, "Name")) { 230 final boolean sortNameAscending = Boolean.parseBoolean(request.getParameter("sortNameAscending")); 231 Collections.sort(approvalRows, new Comparator<ApprovalTimeSummaryRow>() { 232 @Override 233 public int compare(ApprovalTimeSummaryRow row1, ApprovalTimeSummaryRow row2) { 234 if (sortNameAscending) { 235 return ObjectUtils.compare(StringUtils.lowerCase(row1.getName()), StringUtils.lowerCase(row2.getName())); 236 } else { 237 return ObjectUtils.compare(StringUtils.lowerCase(row2.getName()), StringUtils.lowerCase(row1.getName())); 238 } 239 } 240 }); 241 } else if (StringUtils.equals(sortField, "DocumentID")) { 242 final boolean sortDocumentIdAscending = Boolean.parseBoolean(request.getParameter("sortDocumentIDAscending")); 243 Collections.sort(approvalRows, new Comparator<ApprovalTimeSummaryRow>() { 244 @Override 245 public int compare(ApprovalTimeSummaryRow row1, ApprovalTimeSummaryRow row2) { 246 if (sortDocumentIdAscending) { 247 return ObjectUtils.compare(NumberUtils.toInt(row1.getDocumentId()), NumberUtils.toInt(row2.getDocumentId())); 248 } else { 249 return ObjectUtils.compare(NumberUtils.toInt(row2.getDocumentId()), NumberUtils.toInt(row1.getDocumentId())); 250 } 251 } 252 }); 253 } else if (StringUtils.equals(sortField, "Status")) { 254 final boolean sortStatusIdAscending = Boolean.parseBoolean(request.getParameter("sortStatusAscending")); 255 Collections.sort(approvalRows, new Comparator<ApprovalTimeSummaryRow>() { 256 @Override 257 public int compare(ApprovalTimeSummaryRow row1, ApprovalTimeSummaryRow row2) { 258 if (sortStatusIdAscending) { 259 return ObjectUtils.compare(StringUtils.lowerCase(row1.getApprovalStatus()), StringUtils.lowerCase(row2.getApprovalStatus())); 260 } else { 261 return ObjectUtils.compare(StringUtils.lowerCase(row2.getApprovalStatus()), StringUtils.lowerCase(row1.getApprovalStatus())); 262 } 263 } 264 }); 265 } 266 267 taaf.setApprovalRows(approvalRows); 268 taaf.setResultSize(persons.size()); 269 } 270 271 taaf.setOnCurrentPeriod(ActionFormUtils.getOnCurrentPeriodFlag(taaf.getPayCalendarEntries())); 272 } 273 274 public ActionForward selectNewPayCalendar(ActionMapping mapping, ActionForm form, 275 HttpServletRequest request, HttpServletResponse response) 276 throws Exception { 277 // resets the common fields for approval pages 278 super.resetMainFields(form); 279 TimeApprovalActionForm taaf = (TimeApprovalActionForm)form; 280 // KPME-909 281 taaf.setApprovalRows(new ArrayList<ApprovalTimeSummaryRow>()); 282 return loadApprovalTab(mapping, form, request, response); 283 } 284 285 /** 286 * Helper method to modify / manage the list of records needed to display approval data to the user. 287 * 288 * @param taaf 289 * @return 290 */ 291 protected List<ApprovalTimeSummaryRow> getApprovalRows(TimeApprovalActionForm taaf, List<TKPerson> assignmentPrincipalIds) { 292 return TkServiceLocator.getTimeApproveService().getApprovalSummaryRows(taaf.getPayBeginDate(), taaf.getPayEndDate(), taaf.getSelectedPayCalendarGroup(), assignmentPrincipalIds, taaf.getPayCalendarLabels(), taaf.getPayCalendarEntries()); 293 } 294 295 public void resetState(ActionForm form, HttpServletRequest request) { 296 TimeApprovalActionForm taaf = (TimeApprovalActionForm) form; 297 String page = request.getParameter((new ParamEncoder(TkConstants.APPROVAL_TABLE_ID).encodeParameterName(TableTagParameters.PARAMETER_PAGE))); 298 299 if (StringUtils.isBlank(page)) { 300 taaf.getDepartments().clear(); 301 taaf.getWorkAreaDescr().clear(); 302 taaf.setApprovalRows(new ArrayList<ApprovalTimeSummaryRow>()); 303 taaf.setSelectedDept(null); 304 taaf.setSearchField(null); 305 taaf.setSearchTerm(null); 306 } 307 } 308 309 @Override 310 protected void populateCalendarAndPayPeriodLists(HttpServletRequest request, ApprovalForm taf) { 311 TimeApprovalActionForm taaf = (TimeApprovalActionForm)taf; 312 // set calendar year list 313 Set<String> yearSet = new HashSet<String>(); 314 SimpleDateFormat sdf = new SimpleDateFormat("yyyy"); 315 // if selected calendar year is passed in 316 if(!StringUtils.isEmpty(request.getParameter("selectedCY"))) { 317 taaf.setSelectedCalendarYear(request.getParameter("selectedCY").toString()); 318 } else { 319 taaf.setSelectedCalendarYear(sdf.format(taaf.getPayCalendarEntries().getBeginPeriodDate())); 320 } 321 322 List<CalendarEntries> pcListForYear = new ArrayList<CalendarEntries>(); 323 List<CalendarEntries> pceList = TkServiceLocator.getTimeApproveService() 324 .getAllPayCalendarEntriesForApprover(TKContext.getPrincipalId(), TKUtils.getTimelessDate(null)); 325 for(CalendarEntries pce : pceList) { 326 yearSet.add(sdf.format(pce.getBeginPeriodDate())); 327 if(sdf.format(pce.getBeginPeriodDate()).equals(taaf.getSelectedCalendarYear())) { 328 pcListForYear.add(pce); 329 } 330 } 331 List<String> yearList = new ArrayList<String>(yearSet); 332 Collections.sort(yearList); 333 Collections.reverse(yearList); // newest on top 334 taaf.setCalendarYears(yearList); 335 336 // set pay period list contents 337 if(!StringUtils.isEmpty(request.getParameter("selectedPP"))) { 338 taaf.setSelectedPayPeriod(request.getParameter("selectedPP").toString()); 339 } else { 340 taaf.setSelectedPayPeriod(taaf.getPayCalendarEntries().getHrCalendarEntriesId()); 341 taaf.setPayPeriodsMap(ActionFormUtils.getPayPeriodsMap(pcListForYear)); 342 } 343 if(taaf.getPayPeriodsMap().isEmpty()) { 344 taaf.setPayPeriodsMap(ActionFormUtils.getPayPeriodsMap(pcListForYear)); 345 } 346 } 347 348 private List<String> getPrincipalIdsToPopulateTable(TimeApprovalActionForm taf) { 349 List<String> workAreaList = new ArrayList<String>(); 350 if(StringUtil.isEmpty(taf.getSelectedWorkArea())) { 351 for(Long aKey : taf.getWorkAreaDescr().keySet()) { 352 workAreaList.add(aKey.toString()); 353 } 354 } else { 355 workAreaList.add(taf.getSelectedWorkArea()); 356 } 357 java.sql.Date endDate = new java.sql.Date(taf.getPayEndDate().getTime()); 358 java.sql.Date beginDate = new java.sql.Date(taf.getPayBeginDate().getTime()); 359 360 List<String> idList = TkServiceLocator.getTimeApproveService() 361 .getTimePrincipalIdsWithSearchCriteria(workAreaList, taf.getSelectedPayCalendarGroup(), endDate, beginDate, endDate); 362 return idList; 363 } 364 }