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.detail.web; 017 018 import java.sql.Date; 019 import java.sql.Timestamp; 020 import java.text.SimpleDateFormat; 021 import java.util.ArrayList; 022 import java.util.Collection; 023 import java.util.Collections; 024 import java.util.HashSet; 025 import java.util.List; 026 import java.util.Map; 027 import java.util.Set; 028 029 import javax.servlet.http.HttpServletRequest; 030 import javax.servlet.http.HttpServletResponse; 031 032 import org.apache.commons.lang.StringUtils; 033 import org.apache.struts.action.ActionForm; 034 import org.apache.struts.action.ActionForward; 035 import org.apache.struts.action.ActionMapping; 036 import org.joda.time.DateTime; 037 import org.joda.time.Interval; 038 import org.kuali.hr.time.assignment.Assignment; 039 import org.kuali.hr.time.calendar.Calendar; 040 import org.kuali.hr.time.calendar.CalendarEntries; 041 import org.kuali.hr.time.calendar.TkCalendar; 042 import org.kuali.hr.time.roles.TkUserRoles; 043 import org.kuali.hr.time.roles.UserRoles; 044 import org.kuali.hr.time.service.base.TkServiceLocator; 045 import org.kuali.hr.time.timeblock.TimeBlock; 046 import org.kuali.hr.time.timeblock.TimeBlockHistory; 047 import org.kuali.hr.time.timesheet.TimesheetDocument; 048 import org.kuali.hr.time.timesheet.web.TimesheetAction; 049 import org.kuali.hr.time.timesheet.web.TimesheetActionForm; 050 import org.kuali.hr.time.timesummary.AssignmentRow; 051 import org.kuali.hr.time.timesummary.EarnCodeSection; 052 import org.kuali.hr.time.timesummary.EarnGroupSection; 053 import org.kuali.hr.time.timesummary.TimeSummary; 054 import org.kuali.hr.time.util.TKContext; 055 import org.kuali.hr.time.util.TKUser; 056 import org.kuali.hr.time.util.TKUtils; 057 import org.kuali.hr.time.util.TkConstants; 058 import org.kuali.hr.time.util.TkTimeBlockAggregate; 059 import org.kuali.hr.time.workflow.TimesheetDocumentHeader; 060 import org.kuali.rice.kew.service.KEWServiceLocator; 061 import org.kuali.rice.krad.exception.AuthorizationException; 062 import org.kuali.rice.krad.util.GlobalVariables; 063 064 public class TimeDetailAction extends TimesheetAction { 065 066 @Override 067 protected void checkTKAuthorization(ActionForm form, String methodToCall) throws AuthorizationException { 068 super.checkTKAuthorization(form, methodToCall); // Checks for read access first. 069 TKUser user = TKContext.getUser(); 070 UserRoles roles = TkUserRoles.getUserRoles(GlobalVariables.getUserSession().getPrincipalId()); 071 TimesheetDocument doc = TKContext.getCurrentTimesheetDocument(); 072 073 // Check for write access to Timeblock. 074 if (StringUtils.equals(methodToCall, "addTimeBlock") || StringUtils.equals(methodToCall, "deleteTimeBlock") || StringUtils.equals(methodToCall, "updateTimeBlock")) { 075 if (!roles.isDocumentWritable(doc)) { 076 throw new AuthorizationException(roles.getPrincipalId(), "TimeDetailAction", ""); 077 } 078 } 079 } 080 081 @Override 082 public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 083 ActionForward forward = super.execute(mapping, form, request, response); 084 if (forward.getRedirect()) { 085 return forward; 086 } 087 TimeDetailActionForm tdaf = (TimeDetailActionForm) form; 088 tdaf.setAssignmentDescriptions(TkServiceLocator.getAssignmentService().getAssignmentDescriptions(TKContext.getCurrentTimesheetDocument(), false)); 089 090 // Handle User preference / timezone information (pushed up from TkCalendar to avoid duplication) 091 // Set calendar 092 CalendarEntries payCalendarEntry = tdaf.getPayCalendarDates(); 093 Calendar payCalendar = TkServiceLocator.getCalendarService().getCalendar(payCalendarEntry.getHrCalendarId()); 094 095 //List<TimeBlock> timeBlocks = TkServiceLocator.getTimeBlockService().getTimeBlocks(Long.parseLong(tdaf.getTimesheetDocument().getDocumentHeader().getTimesheetDocumentId())); 096 List<TimeBlock> timeBlocks = TKContext.getCurrentTimesheetDocument().getTimeBlocks(); 097 098 this.assignStypeClassMapForTimeSummary(tdaf,timeBlocks); 099 100 List<Interval> intervals = TKUtils.getFullWeekDaySpanForCalendarEntry(payCalendarEntry); 101 TkTimeBlockAggregate aggregate = new TkTimeBlockAggregate(timeBlocks, payCalendarEntry, payCalendar, true, intervals); 102 TkCalendar cal = TkCalendar.getCalendar(aggregate); 103 cal.assignAssignmentStyle(tdaf.getAssignStyleClassMap()); 104 tdaf.setTkCalendar(cal); 105 106 this.populateCalendarAndPayPeriodLists(request, tdaf); 107 108 tdaf.setTimeBlockString(ActionFormUtils.getTimeBlocksJson(aggregate.getFlattenedTimeBlockList())); 109 110 tdaf.setOvertimeEarnCodes(TkServiceLocator.getEarnCodeService().getOvertimeEarnCodesStrs(TKContext.getCurrentTimesheetDocument().getAsOfDate())); 111 112 if (StringUtils.equals(TKContext.getCurrentTimesheetDocument().getPrincipalId(), GlobalVariables.getUserSession().getPrincipalId())) { 113 tdaf.setWorkingOnItsOwn("true"); 114 } 115 116 tdaf.setDocEditable("false"); 117 if (TKContext.getUser().isSystemAdmin()) { 118 tdaf.setDocEditable("true"); 119 } else { 120 boolean docFinal = TKContext.getCurrentTimesheetDocument().getDocumentHeader().getDocumentStatus().equals(TkConstants.ROUTE_STATUS.FINAL); 121 if (!docFinal) { 122 if(StringUtils.equals(TKContext.getCurrentTimesheetDocument().getPrincipalId(), GlobalVariables.getUserSession().getPrincipalId()) 123 || TKContext.getUser().isSystemAdmin() 124 || TKContext.getUser().isLocationAdmin() 125 || TKContext.getUser().isDepartmentAdmin() 126 || TKContext.getUser().isReviewer() 127 || TKContext.getUser().isApprover()) { 128 tdaf.setDocEditable("true"); 129 } 130 131 //if the timesheet has been approved by at least one of the approvers, the employee should not be able to edit it 132 if (StringUtils.equals(TKContext.getCurrentTimesheetDocument().getPrincipalId(), GlobalVariables.getUserSession().getPrincipalId()) 133 && TKContext.getCurrentTimesheetDocument().getDocumentHeader().getDocumentStatus().equals(TkConstants.ROUTE_STATUS.ENROUTE)) { 134 Collection actions = KEWServiceLocator.getActionTakenService().findByDocIdAndAction(TKContext.getCurrentTimesheetDocument().getDocumentHeader().getDocumentId(), TkConstants.DOCUMENT_ACTIONS.APPROVE); 135 if(!actions.isEmpty()) { 136 tdaf.setDocEditable("false"); 137 } 138 } 139 } 140 } 141 142 return forward; 143 } 144 145 // use lists of time blocks and leave blocks to build the style class map and assign css class to associated summary rows 146 private void assignStypeClassMapForTimeSummary(TimeDetailActionForm tdaf, List<TimeBlock> timeBlocks) throws Exception { 147 TimeSummary ts = TkServiceLocator.getTimeSummaryService().getTimeSummary(TKContext.getCurrentTimesheetDocument()); 148 tdaf.setAssignStyleClassMap(ActionFormUtils.buildAssignmentStyleClassMap(timeBlocks)); 149 Map<String, String> aMap = tdaf.getAssignStyleClassMap(); 150 // set css classes for each assignment row 151 for (EarnGroupSection earnGroupSection : ts.getSections()) { 152 for (EarnCodeSection section : earnGroupSection.getEarnCodeSections()) { 153 for (AssignmentRow assignRow : section.getAssignmentsRows()) { 154 if (assignRow.getAssignmentKey() != null && aMap.containsKey(assignRow.getAssignmentKey())) { 155 assignRow.setCssClass(aMap.get(assignRow.getAssignmentKey())); 156 } else { 157 assignRow.setCssClass(""); 158 } 159 } 160 } 161 162 } 163 tdaf.setTimeSummary(ts); 164 ActionFormUtils.validateHourLimit(tdaf); 165 ActionFormUtils.addWarningTextFromEarnGroup(tdaf); 166 ActionFormUtils.addUnapprovedIPWarningFromClockLog(tdaf); 167 } 168 169 private void populateCalendarAndPayPeriodLists(HttpServletRequest request, TimeDetailActionForm tdaf) { 170 List<TimesheetDocumentHeader> documentHeaders = (List<TimesheetDocumentHeader>) TkServiceLocator.getTimesheetDocumentHeaderService().getDocumentHeadersForPrincipalId(GlobalVariables.getUserSession().getPrincipalId()); 171 SimpleDateFormat sdf = new SimpleDateFormat("yyyy"); 172 if(tdaf.getCalendarYears().isEmpty()) { 173 // get calendar year drop down list contents 174 Set<String> yearSet = new HashSet<String>(); 175 176 for(TimesheetDocumentHeader tdh : documentHeaders) { 177 yearSet.add(sdf.format(tdh.getPayBeginDate())); 178 } 179 List<String> yearList = new ArrayList<String>(yearSet); 180 Collections.sort(yearList); 181 Collections.reverse(yearList); // newest on top 182 tdaf.setCalendarYears(yearList); 183 } 184 // if selected calendar year is passed in 185 if(request.getParameter("selectedCY")!= null) { 186 tdaf.setSelectedCalendarYear(request.getParameter("selectedCY").toString()); 187 } 188 // if there is no selected calendr year, use the year of current pay calendar entry 189 if(StringUtils.isEmpty(tdaf.getSelectedCalendarYear())) { 190 tdaf.setSelectedCalendarYear(sdf.format(tdaf.getPayCalendarDates().getBeginPeriodDate())); 191 } 192 if(tdaf.getPayPeriodsMap().isEmpty()) { 193 List<CalendarEntries> payPeriodList = new ArrayList<CalendarEntries>(); 194 for(TimesheetDocumentHeader tdh : documentHeaders) { 195 if(sdf.format(tdh.getPayBeginDate()).equals(tdaf.getSelectedCalendarYear())) { 196 CalendarEntries pe = TkServiceLocator.getCalendarEntriesService().getCalendarEntriesByBeginAndEndDate(tdh.getPayBeginDate(), tdh.getPayEndDate()); 197 payPeriodList.add(pe); 198 } 199 } 200 tdaf.setPayPeriodsMap(ActionFormUtils.getPayPeriodsMap(payPeriodList)); 201 } 202 if(request.getParameter("selectedPP")!= null) { 203 tdaf.setSelectedPayPeriod(request.getParameter("selectedPP").toString()); 204 } 205 if(StringUtils.isEmpty(tdaf.getSelectedPayPeriod())) { 206 tdaf.setSelectedPayPeriod(tdaf.getPayCalendarDates().getHrCalendarEntriesId()); 207 } 208 } 209 210 211 /** 212 * This method involves creating an object-copy of every TimeBlock on the 213 * time sheet for overtime re-calculation. 214 * 215 * @throws Exception 216 */ 217 public ActionForward deleteTimeBlock(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 218 TimeDetailActionForm tdaf = (TimeDetailActionForm) form; 219 //Grab timeblock to be deleted from form 220 List<TimeBlock> timeBlocks = tdaf.getTimesheetDocument().getTimeBlocks(); 221 TimeBlock deletedTimeBlock = null; 222 for (TimeBlock tb : timeBlocks) { 223 if (tb.getTkTimeBlockId().compareTo(tdaf.getTkTimeBlockId()) == 0) { 224 deletedTimeBlock = tb; 225 break; 226 } 227 } 228 if (deletedTimeBlock == null) { 229 return mapping.findForward("basic"); 230 } 231 //Remove from the list of timeblocks 232 List<TimeBlock> referenceTimeBlocks = new ArrayList<TimeBlock>(tdaf.getTimesheetDocument().getTimeBlocks().size()); 233 for (TimeBlock b : tdaf.getTimesheetDocument().getTimeBlocks()) { 234 referenceTimeBlocks.add(b.copy()); 235 } 236 237 // simple pointer, for clarity 238 List<TimeBlock> newTimeBlocks = tdaf.getTimesheetDocument().getTimeBlocks(); 239 newTimeBlocks.remove(deletedTimeBlock); 240 241 //Delete timeblock 242 TkServiceLocator.getTimeBlockService().deleteTimeBlock(deletedTimeBlock); 243 // Add a row to the history table 244 TimeBlockHistory tbh = new TimeBlockHistory(deletedTimeBlock); 245 tbh.setActionHistory(TkConstants.ACTIONS.DELETE_TIME_BLOCK); 246 TkServiceLocator.getTimeBlockHistoryService().saveTimeBlockHistory(tbh); 247 //reset time block 248 TkServiceLocator.getTimesheetService().resetTimeBlock(newTimeBlocks); 249 TkServiceLocator.getTkRuleControllerService().applyRules(TkConstants.ACTIONS.ADD_TIME_BLOCK, newTimeBlocks, tdaf.getPayCalendarDates(), tdaf.getTimesheetDocument(), TKContext.getPrincipalId()); 250 TkServiceLocator.getTimeBlockService().saveTimeBlocks(referenceTimeBlocks, newTimeBlocks); 251 252 return mapping.findForward("basic"); 253 } 254 255 /** 256 * This method involves creating an object-copy of every TimeBlock on the 257 * time sheet for overtime re-calculation. 258 * 259 * @throws Exception 260 */ 261 public ActionForward addTimeBlock(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 262 TimeDetailActionForm tdaf = (TimeDetailActionForm) form; 263 this.changeTimeBlocks(tdaf); 264 265 ActionFormUtils.validateHourLimit(tdaf); 266 ActionFormUtils.addWarningTextFromEarnGroup(tdaf); 267 268 return mapping.findForward("basic"); 269 } 270 271 private void removeOldTimeBlock(TimeDetailActionForm tdaf) { 272 if (tdaf.getTkTimeBlockId() != null) { 273 TimeBlock tb = TkServiceLocator.getTimeBlockService().getTimeBlock(tdaf.getTkTimeBlockId()); 274 if (tb != null) { 275 TimeBlockHistory tbh = new TimeBlockHistory(tb); 276 TkServiceLocator.getTimeBlockService().deleteTimeBlock(tb); 277 278 // mark the original timeblock as deleted in the history table 279 tbh.setActionHistory(TkConstants.ACTIONS.DELETE_TIME_BLOCK); 280 TkServiceLocator.getTimeBlockHistoryService().saveTimeBlockHistory(tbh); 281 282 // delete the timeblock from the memory 283 tdaf.getTimesheetDocument().getTimeBlocks().remove(tb); 284 } 285 } 286 } 287 288 289 // add/update time blocks 290 private void changeTimeBlocks(TimeDetailActionForm tdaf) { 291 Timestamp overtimeBeginTimestamp = null; 292 Timestamp overtimeEndTimestamp = null; 293 boolean isClockLogCreated = false; 294 295 // This is for updating a timeblock or changing 296 // If tkTimeBlockId is not null and the new timeblock is valid, delete the existing timeblock and a new one will be created after submitting the form. 297 if (tdaf.getTkTimeBlockId() != null) { 298 TimeBlock tb = TkServiceLocator.getTimeBlockService().getTimeBlock(tdaf.getTkTimeBlockId()); 299 if (tb != null) { 300 isClockLogCreated = tb.getClockLogCreated(); 301 if (StringUtils.isNotEmpty(tdaf.getOvertimePref())) { 302 overtimeBeginTimestamp = tb.getBeginTimestamp(); 303 overtimeEndTimestamp = tb.getEndTimestamp(); 304 } 305 } 306 this.removeOldTimeBlock(tdaf); 307 } 308 309 Assignment assignment = TkServiceLocator.getAssignmentService().getAssignment(tdaf.getTimesheetDocument(), tdaf.getSelectedAssignment()); 310 311 312 // Surgery point - Need to construct a Date/Time with Appropriate Timezone. 313 Timestamp startTime = TKUtils.convertDateStringToTimestamp(tdaf.getStartDate(), tdaf.getStartTime()); 314 Timestamp endTime = TKUtils.convertDateStringToTimestamp(tdaf.getEndDate(), tdaf.getEndTime()); 315 316 // We need a cloned reference set so we know whether or not to 317 // persist any potential changes without making hundreds of DB calls. 318 List<TimeBlock> referenceTimeBlocks = new ArrayList<TimeBlock>(tdaf.getTimesheetDocument().getTimeBlocks().size()); 319 for (TimeBlock tb : tdaf.getTimesheetDocument().getTimeBlocks()) { 320 referenceTimeBlocks.add(tb.copy()); 321 } 322 323 // This is just a reference, for code clarity, the above list is actually 324 // separate at the object level. 325 List<TimeBlock> newTimeBlocks = tdaf.getTimesheetDocument().getTimeBlocks(); 326 DateTime startTemp = new DateTime(startTime); 327 DateTime endTemp = new DateTime(endTime); 328 // KPME-1446 add spanningweeks to the calls below 329 if (StringUtils.equals(tdaf.getAcrossDays(), "y") 330 && !(endTemp.getDayOfYear() - startTemp.getDayOfYear() <= 1 331 && endTemp.getHourOfDay() == 0)) { 332 List<TimeBlock> timeBlocksToAdd = TkServiceLocator.getTimeBlockService().buildTimeBlocksSpanDates(assignment, 333 tdaf.getSelectedEarnCode(), tdaf.getTimesheetDocument(), startTime, 334 endTime, tdaf.getHours(), tdaf.getAmount(), isClockLogCreated, Boolean.parseBoolean(tdaf.getLunchDeleted()), tdaf.getSpanningWeeks()); 335 for (TimeBlock tb : timeBlocksToAdd) { 336 if (!newTimeBlocks.contains(tb)) { 337 newTimeBlocks.add(tb); 338 } 339 } 340 } else { 341 List<TimeBlock> timeBlocksToAdd = TkServiceLocator.getTimeBlockService().buildTimeBlocks(assignment, 342 tdaf.getSelectedEarnCode(), tdaf.getTimesheetDocument(), startTime, 343 endTime, tdaf.getHours(), tdaf.getAmount(), isClockLogCreated, Boolean.parseBoolean(tdaf.getLunchDeleted())); 344 for (TimeBlock tb : timeBlocksToAdd) { 345 if (!newTimeBlocks.contains(tb)) { 346 newTimeBlocks.add(tb); 347 } 348 } 349 } 350 351 //reset time block 352 TkServiceLocator.getTimesheetService().resetTimeBlock(newTimeBlocks); 353 354 // apply overtime pref 355 for (TimeBlock tb : newTimeBlocks) { 356 if (tb.getBeginTimestamp().equals(overtimeBeginTimestamp) && tb.getEndTimestamp().equals(overtimeEndTimestamp) && StringUtils.isNotEmpty(tdaf.getOvertimePref())) { 357 tb.setOvertimePref(tdaf.getOvertimePref()); 358 } 359 360 } 361 362 TkServiceLocator.getTkRuleControllerService().applyRules(TkConstants.ACTIONS.ADD_TIME_BLOCK, newTimeBlocks, tdaf.getPayCalendarDates(), tdaf.getTimesheetDocument(), TKContext.getPrincipalId()); 363 TkServiceLocator.getTimeBlockService().saveTimeBlocks(referenceTimeBlocks, newTimeBlocks); 364 } 365 366 public ActionForward updateTimeBlock(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 367 368 TimeDetailActionForm tdaf = (TimeDetailActionForm) form; 369 Assignment assignment = TkServiceLocator.getAssignmentService().getAssignment(tdaf.getTimesheetDocument(), tdaf.getSelectedAssignment()); 370 371 //Grab timeblock to be updated from form 372 List<TimeBlock> timeBlocks = tdaf.getTimesheetDocument().getTimeBlocks(); 373 TimeBlock updatedTimeBlock = null; 374 for (TimeBlock tb : timeBlocks) { 375 if (tb.getTkTimeBlockId().compareTo(tdaf.getTkTimeBlockId()) == 0) { 376 updatedTimeBlock = tb; 377 tb.setJobNumber(assignment.getJobNumber()); 378 tb.setWorkArea(assignment.getWorkArea()); 379 tb.setTask(assignment.getTask()); 380 break; 381 } 382 } 383 384 TkServiceLocator.getTimeBlockService().updateTimeBlock(updatedTimeBlock); 385 386 TimeBlockHistory tbh = new TimeBlockHistory(updatedTimeBlock); 387 tbh.setActionHistory(TkConstants.ACTIONS.UPDATE_TIME_BLOCK); 388 TkServiceLocator.getTimeBlockHistoryService().saveTimeBlockHistory(tbh); 389 tdaf.setMethodToCall("addTimeBlock"); 390 return mapping.findForward("basic"); 391 } 392 393 394 public ActionForward actualTimeInquiry(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 395 TimeDetailActionForm tdaf = (TimeDetailActionForm) form; 396 return mapping.findForward("ati"); 397 } 398 399 public ActionForward deleteLunchDeduction(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 400 401 TimeDetailActionForm tdaf = (TimeDetailActionForm) form; 402 String timeHourDetailId = tdaf.getTkTimeHourDetailId(); 403 TkServiceLocator.getTimeBlockService().deleteLunchDeduction(timeHourDetailId); 404 405 List<TimeBlock> newTimeBlocks = tdaf.getTimesheetDocument().getTimeBlocks(); 406 407 TkServiceLocator.getTimesheetService().resetTimeBlock(newTimeBlocks); 408 409 // KPME-1340 410 TkServiceLocator.getTkRuleControllerService().applyRules(TkConstants.ACTIONS.ADD_TIME_BLOCK, newTimeBlocks, tdaf.getPayCalendarDates(), tdaf.getTimesheetDocument(), TKContext.getPrincipalId()); 411 TkServiceLocator.getTimeBlockService().saveTimeBlocks(newTimeBlocks); 412 TKContext.getCurrentTimesheetDocument().setTimeBlocks(newTimeBlocks); 413 414 return mapping.findForward("basic"); 415 } 416 417 public ActionForward gotoCurrentPayPeriod(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 418 String viewPrincipal = TKUser.getCurrentTargetPerson().getPrincipalId(); 419 Date currentDate = TKUtils.getTimelessDate(null); 420 CalendarEntries pce = TkServiceLocator.getCalendarService().getCurrentCalendarDates(viewPrincipal, currentDate); 421 TimesheetDocument td = TkServiceLocator.getTimesheetService().openTimesheetDocument(viewPrincipal, pce); 422 setupDocumentOnFormContext((TimesheetActionForm)form, td); 423 return mapping.findForward("basic"); 424 } 425 426 //Triggered by changes of pay period drop down list, reload the whole page based on the selected pay period 427 public ActionForward changeCalendarYear(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 428 429 TimeDetailActionForm tdaf = (TimeDetailActionForm) form; 430 if(request.getParameter("selectedCY") != null) { 431 tdaf.setSelectedCalendarYear(request.getParameter("selectedCY").toString()); 432 } 433 return mapping.findForward("basic"); 434 } 435 436 //Triggered by changes of pay period drop down list, reload the whole page based on the selected pay period 437 public ActionForward changePayPeriod(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 438 TimeDetailActionForm tdaf = (TimeDetailActionForm) form; 439 if(request.getParameter("selectedPP") != null) { 440 tdaf.setSelectedPayPeriod(request.getParameter("selectedPP").toString()); 441 CalendarEntries pce = TkServiceLocator.getCalendarEntriesService() 442 .getCalendarEntries(request.getParameter("selectedPP").toString()); 443 if(pce != null) { 444 String viewPrincipal = TKUser.getCurrentTargetPerson().getPrincipalId(); 445 TimesheetDocument td = TkServiceLocator.getTimesheetService().openTimesheetDocument(viewPrincipal, pce); 446 setupDocumentOnFormContext((TimesheetActionForm)form, td); 447 } 448 } 449 return mapping.findForward("basic"); 450 } 451 452 }