001    /**
002     * Copyright 2004-2012 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.task.Task;
046    import org.kuali.hr.time.timeblock.TimeBlock;
047    import org.kuali.hr.time.timeblock.TimeBlockHistory;
048    import org.kuali.hr.time.timesheet.TimesheetDocument;
049    import org.kuali.hr.time.timesheet.web.TimesheetAction;
050    import org.kuali.hr.time.timesheet.web.TimesheetActionForm;
051    import org.kuali.hr.time.timesummary.AssignmentRow;
052    import org.kuali.hr.time.timesummary.EarnCodeSection;
053    import org.kuali.hr.time.timesummary.EarnGroupSection;
054    import org.kuali.hr.time.timesummary.TimeSummary;
055    import org.kuali.hr.time.util.TKContext;
056    import org.kuali.hr.time.util.TKUser;
057    import org.kuali.hr.time.util.TKUtils;
058    import org.kuali.hr.time.util.TkConstants;
059    import org.kuali.hr.time.util.TkTimeBlockAggregate;
060    import org.kuali.hr.time.workflow.TimesheetDocumentHeader;
061    import org.kuali.rice.kew.service.KEWServiceLocator;
062    import org.kuali.rice.krad.exception.AuthorizationException;
063    import org.kuali.rice.krad.util.GlobalVariables;
064    
065    public class TimeDetailAction extends TimesheetAction {
066    
067        @Override
068        protected void checkTKAuthorization(ActionForm form, String methodToCall) throws AuthorizationException {
069            super.checkTKAuthorization(form, methodToCall); // Checks for read access first.
070            TKUser user = TKContext.getUser();
071            UserRoles roles = TkUserRoles.getUserRoles(GlobalVariables.getUserSession().getPrincipalId());
072            TimesheetDocument doc = TKContext.getCurrentTimesheetDocument();
073    
074            // Check for write access to Timeblock.
075            if (StringUtils.equals(methodToCall, "addTimeBlock") || StringUtils.equals(methodToCall, "deleteTimeBlock") || StringUtils.equals(methodToCall, "updateTimeBlock")) {
076                if (!roles.isDocumentWritable(doc)) {
077                    throw new AuthorizationException(roles.getPrincipalId(), "TimeDetailAction", "");
078                }
079            }
080        }
081    
082        @Override
083        public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
084            ActionForward forward = super.execute(mapping, form, request, response);
085            if (forward.getRedirect()) {
086                return forward;
087            }
088            TimeDetailActionForm tdaf = (TimeDetailActionForm) form;
089            tdaf.setAssignmentDescriptions(TkServiceLocator.getAssignmentService().getAssignmentDescriptions(TKContext.getCurrentTimesheetDocument(), false));
090    
091            // Handle User preference / timezone information (pushed up from TkCalendar to avoid duplication)
092            // Set calendar
093            CalendarEntries payCalendarEntry = tdaf.getPayCalendarDates();
094            Calendar payCalendar = TkServiceLocator.getCalendarService().getCalendar(payCalendarEntry.getHrCalendarId());
095            
096            //List<TimeBlock> timeBlocks = TkServiceLocator.getTimeBlockService().getTimeBlocks(Long.parseLong(tdaf.getTimesheetDocument().getDocumentHeader().getTimesheetDocumentId()));
097            List<TimeBlock> timeBlocks = TKContext.getCurrentTimesheetDocument().getTimeBlocks();
098            
099            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    }