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