View Javadoc

1   /**
2    * Copyright 2004-2012 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.hr.time.detail.web;
17  
18  import java.sql.Date;
19  import java.sql.Timestamp;
20  import java.text.SimpleDateFormat;
21  import java.util.ArrayList;
22  import java.util.Collection;
23  import java.util.Collections;
24  import java.util.HashSet;
25  import java.util.List;
26  import java.util.Map;
27  import java.util.Set;
28  
29  import javax.servlet.http.HttpServletRequest;
30  import javax.servlet.http.HttpServletResponse;
31  
32  import org.apache.commons.lang.StringUtils;
33  import org.apache.struts.action.ActionForm;
34  import org.apache.struts.action.ActionForward;
35  import org.apache.struts.action.ActionMapping;
36  import org.joda.time.DateTime;
37  import org.joda.time.Interval;
38  import org.kuali.hr.time.assignment.Assignment;
39  import org.kuali.hr.time.calendar.Calendar;
40  import org.kuali.hr.time.calendar.CalendarEntries;
41  import org.kuali.hr.time.calendar.TkCalendar;
42  import org.kuali.hr.time.roles.TkUserRoles;
43  import org.kuali.hr.time.roles.UserRoles;
44  import org.kuali.hr.time.service.base.TkServiceLocator;
45  import org.kuali.hr.time.task.Task;
46  import org.kuali.hr.time.timeblock.TimeBlock;
47  import org.kuali.hr.time.timeblock.TimeBlockHistory;
48  import org.kuali.hr.time.timesheet.TimesheetDocument;
49  import org.kuali.hr.time.timesheet.web.TimesheetAction;
50  import org.kuali.hr.time.timesheet.web.TimesheetActionForm;
51  import org.kuali.hr.time.timesummary.AssignmentRow;
52  import org.kuali.hr.time.timesummary.EarnCodeSection;
53  import org.kuali.hr.time.timesummary.EarnGroupSection;
54  import org.kuali.hr.time.timesummary.TimeSummary;
55  import org.kuali.hr.time.util.TKContext;
56  import org.kuali.hr.time.util.TKUser;
57  import org.kuali.hr.time.util.TKUtils;
58  import org.kuali.hr.time.util.TkConstants;
59  import org.kuali.hr.time.util.TkTimeBlockAggregate;
60  import org.kuali.hr.time.workflow.TimesheetDocumentHeader;
61  import org.kuali.rice.kew.service.KEWServiceLocator;
62  import org.kuali.rice.krad.exception.AuthorizationException;
63  import org.kuali.rice.krad.util.GlobalVariables;
64  
65  public class TimeDetailAction extends TimesheetAction {
66  
67      @Override
68      protected void checkTKAuthorization(ActionForm form, String methodToCall) throws AuthorizationException {
69          super.checkTKAuthorization(form, methodToCall); // Checks for read access first.
70          TKUser user = TKContext.getUser();
71          UserRoles roles = TkUserRoles.getUserRoles(GlobalVariables.getUserSession().getPrincipalId());
72          TimesheetDocument doc = TKContext.getCurrentTimesheetDocument();
73  
74          // Check for write access to Timeblock.
75          if (StringUtils.equals(methodToCall, "addTimeBlock") || StringUtils.equals(methodToCall, "deleteTimeBlock") || StringUtils.equals(methodToCall, "updateTimeBlock")) {
76              if (!roles.isDocumentWritable(doc)) {
77                  throw new AuthorizationException(roles.getPrincipalId(), "TimeDetailAction", "");
78              }
79          }
80      }
81  
82      @Override
83      public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
84          ActionForward forward = super.execute(mapping, form, request, response);
85          if (forward.getRedirect()) {
86              return forward;
87          }
88          TimeDetailActionForm tdaf = (TimeDetailActionForm) form;
89          tdaf.setAssignmentDescriptions(TkServiceLocator.getAssignmentService().getAssignmentDescriptions(TKContext.getCurrentTimesheetDocument(), false));
90  
91          // Handle User preference / timezone information (pushed up from TkCalendar to avoid duplication)
92          // Set calendar
93          CalendarEntries payCalendarEntry = tdaf.getPayCalendarDates();
94          Calendar payCalendar = TkServiceLocator.getCalendarService().getCalendar(payCalendarEntry.getHrCalendarId());
95          
96          //List<TimeBlock> timeBlocks = TkServiceLocator.getTimeBlockService().getTimeBlocks(Long.parseLong(tdaf.getTimesheetDocument().getDocumentHeader().getTimesheetDocumentId()));
97          List<TimeBlock> timeBlocks = TKContext.getCurrentTimesheetDocument().getTimeBlocks();
98          
99          this.assignStypeClassMapForTimeSummary(tdaf,timeBlocks);
100         
101         List<Interval> intervals = TKUtils.getFullWeekDaySpanForCalendarEntry(payCalendarEntry);
102         TkTimeBlockAggregate aggregate = new TkTimeBlockAggregate(timeBlocks, payCalendarEntry, payCalendar, true, intervals);
103         TkCalendar cal = TkCalendar.getCalendar(aggregate);
104         cal.assignAssignmentStyle(tdaf.getAssignStyleClassMap());
105         tdaf.setTkCalendar(cal);
106      
107         this.populateCalendarAndPayPeriodLists(request, tdaf);
108 
109         tdaf.setTimeBlockString(ActionFormUtils.getTimeBlocksJson(aggregate.getFlattenedTimeBlockList()));
110 
111         tdaf.setOvertimeEarnCodes(TkServiceLocator.getEarnCodeService().getOvertimeEarnCodesStrs(TKContext.getCurrentTimesheetDocument().getAsOfDate()));
112 
113         if (StringUtils.equals(TKContext.getCurrentTimesheetDocument().getPrincipalId(), GlobalVariables.getUserSession().getPrincipalId())) {
114         	tdaf.setWorkingOnItsOwn("true");
115         }
116         
117         tdaf.setDocEditable("false");
118         if (TKContext.getUser().isSystemAdmin()) {
119             tdaf.setDocEditable("true");
120         } else {
121             boolean docFinal = TKContext.getCurrentTimesheetDocument().getDocumentHeader().getDocumentStatus().equals(TkConstants.ROUTE_STATUS.FINAL);
122             if (!docFinal) {
123             	if(StringUtils.equals(TKContext.getCurrentTimesheetDocument().getPrincipalId(), GlobalVariables.getUserSession().getPrincipalId())
124 	            		|| TKContext.getUser().isSystemAdmin() 
125 	            		|| TKContext.getUser().isLocationAdmin() 
126 	            		|| TKContext.getUser().isDepartmentAdmin() 
127 	            		|| TKContext.getUser().isReviewer() 
128 	            		|| TKContext.getUser().isApprover()) {
129                     tdaf.setDocEditable("true");
130                 }
131             	
132 	            //if the timesheet has been approved by at least one of the approvers, the employee should not be able to edit it
133 	            if (StringUtils.equals(TKContext.getCurrentTimesheetDocument().getPrincipalId(), GlobalVariables.getUserSession().getPrincipalId())
134 	            		&& TKContext.getCurrentTimesheetDocument().getDocumentHeader().getDocumentStatus().equals(TkConstants.ROUTE_STATUS.ENROUTE)) {
135 		        	Collection actions = KEWServiceLocator.getActionTakenService().findByDocIdAndAction(TKContext.getCurrentTimesheetDocument().getDocumentHeader().getDocumentId(), TkConstants.DOCUMENT_ACTIONS.APPROVE);
136 	        		if(!actions.isEmpty()) {
137 	        			tdaf.setDocEditable("false");  
138 	        		}
139 		        }
140             }
141         }
142 
143         return forward;
144     }
145 
146     // use lists of time blocks and leave blocks to build the style class map and assign css class to associated summary rows
147 	private void assignStypeClassMapForTimeSummary(TimeDetailActionForm tdaf, List<TimeBlock> timeBlocks) throws Exception {
148 		TimeSummary ts = TkServiceLocator.getTimeSummaryService().getTimeSummary(TKContext.getCurrentTimesheetDocument());
149         tdaf.setAssignStyleClassMap(ActionFormUtils.buildAssignmentStyleClassMap(timeBlocks));
150         Map<String, String> aMap = tdaf.getAssignStyleClassMap();
151         // set css classes for each assignment row
152         for (EarnGroupSection earnGroupSection : ts.getSections()) {
153             for (EarnCodeSection section : earnGroupSection.getEarnCodeSections()) {
154                 for (AssignmentRow assignRow : section.getAssignmentsRows()) {
155                     if (assignRow.getAssignmentKey() != null && aMap.containsKey(assignRow.getAssignmentKey())) {
156                         assignRow.setCssClass(aMap.get(assignRow.getAssignmentKey()));
157                     } else {
158                         assignRow.setCssClass("");
159                     }
160                 }
161             }
162 
163         }
164         tdaf.setTimeSummary(ts);
165         ActionFormUtils.validateHourLimit(tdaf);
166         ActionFormUtils.addWarningTextFromEarnGroup(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         //Remove from the list of timeblocks
229         List<TimeBlock> referenceTimeBlocks = new ArrayList<TimeBlock>(tdaf.getTimesheetDocument().getTimeBlocks().size());
230         for (TimeBlock b : tdaf.getTimesheetDocument().getTimeBlocks()) {
231             referenceTimeBlocks.add(b.copy());
232         }
233 
234         // simple pointer, for clarity
235         List<TimeBlock> newTimeBlocks = tdaf.getTimesheetDocument().getTimeBlocks();
236         newTimeBlocks.remove(deletedTimeBlock);
237 
238         //Delete timeblock
239         TkServiceLocator.getTimeBlockService().deleteTimeBlock(deletedTimeBlock);
240         // Add a row to the history table
241         TimeBlockHistory tbh = new TimeBlockHistory(deletedTimeBlock);
242         tbh.setActionHistory(TkConstants.ACTIONS.DELETE_TIME_BLOCK);
243         TkServiceLocator.getTimeBlockHistoryService().saveTimeBlockHistory(tbh);
244         //reset time block
245         TkServiceLocator.getTimesheetService().resetTimeBlock(newTimeBlocks);
246         TkServiceLocator.getTkRuleControllerService().applyRules(TkConstants.ACTIONS.ADD_TIME_BLOCK, newTimeBlocks, tdaf.getPayCalendarDates(), tdaf.getTimesheetDocument(), TKContext.getPrincipalId());
247         TkServiceLocator.getTimeBlockService().saveTimeBlocks(referenceTimeBlocks, newTimeBlocks);
248 
249         return mapping.findForward("basic");
250     }
251 
252     /**
253      * This method involves creating an object-copy of every TimeBlock on the
254      * time sheet for overtime re-calculation.
255      *
256      * @throws Exception
257      */
258     public ActionForward addTimeBlock(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
259         TimeDetailActionForm tdaf = (TimeDetailActionForm) form;
260         	this.changeTimeBlocks(tdaf);
261         
262         ActionFormUtils.validateHourLimit(tdaf);
263         ActionFormUtils.addWarningTextFromEarnGroup(tdaf);
264 
265         return mapping.findForward("basic");
266     }
267     
268     private void removeOldTimeBlock(TimeDetailActionForm tdaf) {
269 	  if (tdaf.getTkTimeBlockId() != null) {
270 	      TimeBlock tb = TkServiceLocator.getTimeBlockService().getTimeBlock(tdaf.getTkTimeBlockId());
271 	      if (tb != null) {
272 	          TimeBlockHistory tbh = new TimeBlockHistory(tb);
273 	          TkServiceLocator.getTimeBlockService().deleteTimeBlock(tb);
274 	
275 	          // mark the original timeblock as deleted in the history table
276 			  tbh.setActionHistory(TkConstants.ACTIONS.DELETE_TIME_BLOCK);
277 			  TkServiceLocator.getTimeBlockHistoryService().saveTimeBlockHistory(tbh);
278 	
279 			  // delete the timeblock from the memory
280 	          tdaf.getTimesheetDocument().getTimeBlocks().remove(tb);
281 	      }
282 	  }
283     }
284     
285     
286     // add/update time blocks 
287 	private void changeTimeBlocks(TimeDetailActionForm tdaf) {
288 		Timestamp overtimeBeginTimestamp = null;
289         Timestamp overtimeEndTimestamp = null;
290         
291         // This is for updating a timeblock or changing
292         // 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.
293         if (tdaf.getTkTimeBlockId() != null) {
294             TimeBlock tb = TkServiceLocator.getTimeBlockService().getTimeBlock(tdaf.getTkTimeBlockId());
295             if (StringUtils.isNotEmpty(tdaf.getOvertimePref())) {
296                 overtimeBeginTimestamp = tb.getBeginTimestamp();
297                 overtimeEndTimestamp = tb.getEndTimestamp();
298             }
299             this.removeOldTimeBlock(tdaf);
300         }
301 
302         Assignment assignment = TkServiceLocator.getAssignmentService().getAssignment(tdaf.getTimesheetDocument(), tdaf.getSelectedAssignment());
303 
304 
305         // Surgery point - Need to construct a Date/Time with Appropriate Timezone.
306         Timestamp startTime = TKUtils.convertDateStringToTimestamp(tdaf.getStartDate(), tdaf.getStartTime());
307         Timestamp endTime = TKUtils.convertDateStringToTimestamp(tdaf.getEndDate(), tdaf.getEndTime());
308 
309         // We need a  cloned reference set so we know whether or not to
310         // persist any potential changes without making hundreds of DB calls.
311         List<TimeBlock> referenceTimeBlocks = new ArrayList<TimeBlock>(tdaf.getTimesheetDocument().getTimeBlocks().size());
312         for (TimeBlock tb : tdaf.getTimesheetDocument().getTimeBlocks()) {
313             referenceTimeBlocks.add(tb.copy());
314         }
315 
316         // This is just a reference, for code clarity, the above list is actually
317         // separate at the object level.
318         List<TimeBlock> newTimeBlocks = tdaf.getTimesheetDocument().getTimeBlocks();
319         DateTime startTemp = new DateTime(startTime);
320         DateTime endTemp = new DateTime(endTime);
321         // KPME-1446 add spanningweeks to the calls below 
322         if (StringUtils.equals(tdaf.getAcrossDays(), "y")
323                 && !(endTemp.getDayOfYear() - startTemp.getDayOfYear() <= 1
324                 && endTemp.getHourOfDay() == 0)) {
325             newTimeBlocks.addAll(TkServiceLocator.getTimeBlockService().buildTimeBlocksSpanDates(assignment,
326                     tdaf.getSelectedEarnCode(), tdaf.getTimesheetDocument(), startTime,
327                     endTime, tdaf.getHours(), tdaf.getAmount(), false, Boolean.parseBoolean(tdaf.getLunchDeleted()), tdaf.getSpanningWeeks()));
328         } else {
329             newTimeBlocks.addAll(TkServiceLocator.getTimeBlockService().buildTimeBlocks(assignment,
330                     tdaf.getSelectedEarnCode(), tdaf.getTimesheetDocument(), startTime,
331                     endTime, tdaf.getHours(), tdaf.getAmount(), false, Boolean.parseBoolean(tdaf.getLunchDeleted())));
332         }
333 
334         //reset time block
335         TkServiceLocator.getTimesheetService().resetTimeBlock(newTimeBlocks);
336 
337         // apply overtime pref
338         for (TimeBlock tb : newTimeBlocks) {
339             if (tb.getBeginTimestamp().equals(overtimeBeginTimestamp) && tb.getEndTimestamp().equals(overtimeEndTimestamp) && StringUtils.isNotEmpty(tdaf.getOvertimePref())) {
340                 tb.setOvertimePref(tdaf.getOvertimePref());
341             }
342 
343         }
344 
345         TkServiceLocator.getTkRuleControllerService().applyRules(TkConstants.ACTIONS.ADD_TIME_BLOCK, newTimeBlocks, tdaf.getPayCalendarDates(), tdaf.getTimesheetDocument(), TKContext.getPrincipalId());
346         TkServiceLocator.getTimeBlockService().saveTimeBlocks(referenceTimeBlocks, newTimeBlocks);
347 	}
348 
349     public ActionForward updateTimeBlock(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
350 
351         TimeDetailActionForm tdaf = (TimeDetailActionForm) form;
352         Assignment assignment = TkServiceLocator.getAssignmentService().getAssignment(tdaf.getTimesheetDocument(), tdaf.getSelectedAssignment());
353 
354         //Grab timeblock to be updated from form
355         List<TimeBlock> timeBlocks = tdaf.getTimesheetDocument().getTimeBlocks();
356         TimeBlock updatedTimeBlock = null;
357         for (TimeBlock tb : timeBlocks) {
358             if (tb.getTkTimeBlockId().compareTo(tdaf.getTkTimeBlockId()) == 0) {
359                 updatedTimeBlock = tb;
360                 tb.setJobNumber(assignment.getJobNumber());
361                 tb.setWorkArea(assignment.getWorkArea());
362                 tb.setTask(assignment.getTask());
363                 tb.setTkWorkAreaId(assignment.getWorkAreaObj().getTkWorkAreaId());
364                 tb.setHrJobId(assignment.getJob().getHrJobId());
365                 String tkTaskId = "0";
366                 for (Task task : assignment.getWorkAreaObj().getTasks()) {
367                     if (task.getTask().compareTo(assignment.getTask()) == 0) {
368                         tkTaskId = task.getTkTaskId();
369                         break;
370                     }
371                 }
372                 tb.setTkTaskId(tkTaskId);
373                 break;
374             }
375         }
376 
377         TkServiceLocator.getTimeBlockService().updateTimeBlock(updatedTimeBlock);
378 
379         TimeBlockHistory tbh = new TimeBlockHistory(updatedTimeBlock);
380         tbh.setActionHistory(TkConstants.ACTIONS.UPDATE_TIME_BLOCK);
381         TkServiceLocator.getTimeBlockHistoryService().saveTimeBlockHistory(tbh);
382         tdaf.setMethodToCall("addTimeBlock");
383         return mapping.findForward("basic");
384     }
385 
386 
387     public ActionForward actualTimeInquiry(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
388         TimeDetailActionForm tdaf = (TimeDetailActionForm) form;
389         return mapping.findForward("ati");
390     }
391 
392     public ActionForward deleteLunchDeduction(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
393 
394         TimeDetailActionForm tdaf = (TimeDetailActionForm) form;
395         String timeHourDetailId = tdaf.getTkTimeHourDetailId();
396         TkServiceLocator.getTimeBlockService().deleteLunchDeduction(timeHourDetailId);
397 
398         List<TimeBlock> newTimeBlocks = tdaf.getTimesheetDocument().getTimeBlocks();
399         TkServiceLocator.getTimesheetService().resetTimeBlock(newTimeBlocks);
400 
401         return mapping.findForward("basic");
402     }
403       
404   public ActionForward gotoCurrentPayPeriod(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
405 	  String viewPrincipal = TKUser.getCurrentTargetPerson().getPrincipalId();
406 	  Date currentDate = TKUtils.getTimelessDate(null);
407       CalendarEntries pce = TkServiceLocator.getCalendarService().getCurrentCalendarDates(viewPrincipal, currentDate);
408       TimesheetDocument td = TkServiceLocator.getTimesheetService().openTimesheetDocument(viewPrincipal, pce);
409       setupDocumentOnFormContext((TimesheetActionForm)form, td);
410 	  return mapping.findForward("basic");
411   }
412   
413   //Triggered by changes of pay period drop down list, reload the whole page based on the selected pay period
414   public ActionForward changeCalendarYear(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
415 	  
416 	  TimeDetailActionForm tdaf = (TimeDetailActionForm) form;
417 	  if(request.getParameter("selectedCY") != null) {
418 		  tdaf.setSelectedCalendarYear(request.getParameter("selectedCY").toString());
419 	  }
420 	  return mapping.findForward("basic");
421   }
422   
423   //Triggered by changes of pay period drop down list, reload the whole page based on the selected pay period
424   public ActionForward changePayPeriod(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
425 	  TimeDetailActionForm tdaf = (TimeDetailActionForm) form;
426 	  if(request.getParameter("selectedPP") != null) {
427 		  tdaf.setSelectedPayPeriod(request.getParameter("selectedPP").toString());
428           CalendarEntries pce = TkServiceLocator.getCalendarEntriesService()
429 		  	.getCalendarEntries(request.getParameter("selectedPP").toString());
430 		  if(pce != null) {
431 			  String viewPrincipal = TKUser.getCurrentTargetPerson().getPrincipalId();
432 			  TimesheetDocument td = TkServiceLocator.getTimesheetService().openTimesheetDocument(viewPrincipal, pce);
433 			  setupDocumentOnFormContext((TimesheetActionForm)form, td);
434 		  }
435 	  }
436 	  return mapping.findForward("basic");
437   }
438 
439 }