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.lm.leave.web;
017    
018    import java.math.BigDecimal;
019    import java.util.ArrayList;
020    import java.util.Calendar;
021    import java.util.Collections;
022    import java.util.Comparator;
023    import java.util.Date;
024    import java.util.List;
025    import java.util.SortedMap;
026    import java.util.TreeMap;
027    
028    import javax.servlet.http.HttpServletRequest;
029    import javax.servlet.http.HttpServletResponse;
030    
031    import org.apache.commons.lang.ObjectUtils;
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.kuali.hr.lm.LMConstants;
038    import org.kuali.hr.lm.accrual.AccrualCategory;
039    import org.kuali.hr.lm.leaveSummary.LeaveSummary;
040    import org.kuali.hr.lm.leaveSummary.LeaveSummaryRow;
041    import org.kuali.hr.lm.leaveSummary.service.LeaveSummaryServiceImpl;
042    import org.kuali.hr.lm.leaveblock.LeaveBlock;
043    import org.kuali.hr.lm.leaveblock.LeaveBlockHistory;
044    import org.kuali.hr.lm.workflow.LeaveCalendarDocumentHeader;
045    import org.kuali.hr.time.base.web.TkAction;
046    import org.kuali.hr.time.principal.PrincipalHRAttributes;
047    import org.kuali.hr.time.service.base.TkServiceLocator;
048    import org.kuali.hr.time.util.TKUser;
049    import org.kuali.hr.time.util.TKUtils;
050    import org.kuali.rice.kew.api.KewApiConstants;
051    
052    public class LeaveBlockDisplayAction extends TkAction {
053    
054            @Override
055            public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
056                    ActionForward forward = super.execute(mapping, form, request, response);
057                    
058                    LeaveBlockDisplayForm lbdf = (LeaveBlockDisplayForm) form;      
059            
060                    String principalId = TKUser.getCurrentTargetPerson().getPrincipalId();
061                    if (TKUser.getCurrentTargetPerson() != null) {
062                            lbdf.setTargetName(TKUser.getCurrentTargetPerson().getName());
063                    }
064    
065                    PrincipalHRAttributes principalHRAttributes = TkServiceLocator.getPrincipalHRAttributeService().getPrincipalCalendar(principalId, TKUtils.getCurrentDate());
066                    String leavePlan = (principalHRAttributes != null) ? principalHRAttributes.getLeavePlan() : null;
067    
068                    Calendar currentCalendar = Calendar.getInstance();
069                    if (lbdf.getNavString() == null) {
070                            lbdf.setYear(currentCalendar.get(Calendar.YEAR));
071                    } else if(lbdf.getNavString().equals("NEXT")) {
072                            lbdf.setYear(lbdf.getYear() + 1);
073                    } else if(lbdf.getNavString().equals("PREV")) {
074                            lbdf.setYear(lbdf.getYear() - 1);
075                    }
076                    currentCalendar.set(lbdf.getYear(), 0, 1);
077                    Date serviceDate = (principalHRAttributes != null) ? principalHRAttributes.getServiceDate() : TKUtils.getTimelessDate(currentCalendar.getTime());
078                    Date beginDate = TKUtils.getTimelessDate(currentCalendar.getTime());
079                    currentCalendar.set(lbdf.getYear(), 11, 31);
080                    Date endDate = TKUtils.getTimelessDate(currentCalendar.getTime());
081    
082                    lbdf.setAccrualCategories(getAccrualCategories(leavePlan));
083                    lbdf.setLeaveEntries(getLeaveEntries(principalId, serviceDate, beginDate, endDate, lbdf.getAccrualCategories()));
084    
085                    List<LeaveBlockHistory> correctedLeaveEntries = TkServiceLocator.getLeaveBlockHistoryService().getLeaveBlockHistoriesForLeaveDisplay(principalId, beginDate, endDate, Boolean.TRUE);
086                    if (correctedLeaveEntries != null) {
087                            for (LeaveBlockHistory leaveBlockHistory : correctedLeaveEntries) {
088                                    if (leaveBlockHistory.getAction() != null && leaveBlockHistory.getAction().equalsIgnoreCase(LMConstants.ACTION.DELETE)) {
089                                            leaveBlockHistory.setPrincipalIdModified(leaveBlockHistory.getPrincipalIdDeleted());
090                                            leaveBlockHistory.setTimestamp(leaveBlockHistory.getTimestampDeleted());
091                                    }
092                                    // Set Description
093                                    if(leaveBlockHistory.getDescription() == null || leaveBlockHistory.getDescription().trim().isEmpty()) {
094                                            leaveBlockHistory.setDescription(this.retrieveDescriptionAccordingToLeaveType(leaveBlockHistory.getLeaveBlockType()));
095                                    }
096                            }
097                    }
098                    lbdf.setCorrectedLeaveEntries(correctedLeaveEntries);
099                    
100                    List<LeaveBlockHistory> inActiveLeaveEntries = TkServiceLocator.getLeaveBlockHistoryService() .getLeaveBlockHistoriesForLeaveDisplay(principalId, beginDate, endDate, Boolean.FALSE);
101                    List<LeaveBlockHistory> leaveEntries = null;
102                    if (inActiveLeaveEntries != null) {
103                            leaveEntries = new ArrayList<LeaveBlockHistory>();
104                            for (LeaveBlockHistory leaveBlockHistory:inActiveLeaveEntries) {
105                                    if (leaveBlockHistory.getAccrualGenerated() == null || !leaveBlockHistory.getAccrualGenerated()) {
106                                            if (leaveBlockHistory.getAction()!= null && leaveBlockHistory.getAction().equalsIgnoreCase(LMConstants.ACTION.DELETE)) {
107                                                    leaveBlockHistory.setPrincipalIdModified(leaveBlockHistory.getPrincipalIdDeleted());
108                                                    leaveBlockHistory.setTimestamp(leaveBlockHistory.getTimestampDeleted());
109                                            }
110                                            this.assignDocumentStatusToLeaveBlock(leaveBlockHistory);
111                                            // if it is not generated by accrual then add it to the inactivelist
112                                            // Set Description
113                                            if(leaveBlockHistory.getDescription() == null || leaveBlockHistory.getDescription().trim().isEmpty()) {
114                                                    leaveBlockHistory.setDescription(this.retrieveDescriptionAccordingToLeaveType(leaveBlockHistory.getLeaveBlockType()));
115                                            }
116                                            if (StringUtils.isNotBlank(leaveBlockHistory.getRequestStatus())) {
117                                                    leaveBlockHistory.setRequestStatus(LMConstants.REQUEST_STATUS_STRINGS.get(leaveBlockHistory.getRequestStatus()));
118                                            }
119                                            leaveEntries.add(leaveBlockHistory);
120                                    }
121                            }
122                    }
123                    lbdf.setInActiveLeaveEntries(leaveEntries);
124                    
125                return forward;
126            }
127            
128            private List<AccrualCategory> getAccrualCategories(String leavePlan) {
129                    List<AccrualCategory> accrualCategories = new ArrayList<AccrualCategory>();
130                    
131                    List<AccrualCategory> allAccrualCategories = TkServiceLocator.getAccrualCategoryService().getActiveAccrualCategoriesForLeavePlan(leavePlan, TKUtils.getCurrentDate());
132                    if (allAccrualCategories != null) {
133                            for (AccrualCategory ac : allAccrualCategories) {
134                                    if (StringUtils.equalsIgnoreCase(ac.getShowOnGrid(), "Y")) {
135                                            accrualCategories.add(ac);
136                                    }
137                            }
138                            Collections.sort(accrualCategories, new Comparator<AccrualCategory>() {
139                                    @Override
140                                    public int compare(AccrualCategory o1, AccrualCategory o2) {
141                                            return ObjectUtils.compare(o1.getAccrualCategory(), o2.getAccrualCategory());
142                                    }
143                            });
144                    }
145                    
146                    return accrualCategories;
147            }
148            
149            private List<LeaveBlockDisplay> getLeaveEntries(String principalId, Date serviceDate, Date beginDate, Date endDate, List<AccrualCategory> accrualCategories) {
150                    List<LeaveBlockDisplay> leaveEntries = new ArrayList<LeaveBlockDisplay>();
151                    
152                    List<LeaveBlock> leaveBlocks = TkServiceLocator.getLeaveBlockService().getLeaveBlocks(principalId, beginDate, endDate);
153                    
154                    for (LeaveBlock leaveBlock : leaveBlocks) {
155                if (!leaveBlock.getLeaveBlockType().equals(LMConstants.LEAVE_BLOCK_TYPE.CARRY_OVER)) {
156                                leaveEntries.add(new LeaveBlockDisplay(leaveBlock));
157                }
158                    }
159                    Collections.sort(leaveEntries, new Comparator<LeaveBlockDisplay>() {
160                            @Override
161                            public int compare(LeaveBlockDisplay o1, LeaveBlockDisplay o2) {
162                                    return ObjectUtils.compare(o1.getLeaveDate(), o2.getLeaveDate());
163                            }
164                    });
165                    
166                    SortedMap<String, BigDecimal> accrualBalances = getPreviousAccrualBalances(principalId, serviceDate, beginDate, accrualCategories);
167                                    
168                    for (LeaveBlockDisplay leaveEntry : leaveEntries) {
169                            for (AccrualCategory accrualCategory : accrualCategories) {
170                                    if (!accrualBalances.containsKey(accrualCategory.getAccrualCategory())) {
171                                            accrualBalances.put(accrualCategory.getAccrualCategory(), BigDecimal.ZERO);
172                                    }
173                                    BigDecimal currentAccrualBalance = accrualBalances.get(accrualCategory.getAccrualCategory());
174                                    
175                                    if (StringUtils.equals(leaveEntry.getAccrualCategory(), accrualCategory.getAccrualCategory())) {
176                                            BigDecimal accruedBalance = currentAccrualBalance.add(leaveEntry.getLeaveAmount());
177                                            accrualBalances.put(accrualCategory.getAccrualCategory(), accruedBalance);
178                                    }
179                                    
180                                    leaveEntry.setAccrualBalance(accrualCategory.getAccrualCategory(), accrualBalances.get(accrualCategory.getAccrualCategory()));
181                            }
182                    }
183                    
184                    return leaveEntries;
185            }
186            
187            private SortedMap<String, BigDecimal> getPreviousAccrualBalances(String principalId, Date serviceDate, Date beginDate, List<AccrualCategory> accrualCategories) {
188                    SortedMap<String, BigDecimal> previousAccrualBalances = new TreeMap<String, BigDecimal>();
189    
190            LeaveSummary leaveSummary = TkServiceLocator.getLeaveSummaryService().getLeaveSummaryAsOfDateWithoutFuture(principalId, new java.sql.Date(new DateTime(beginDate).getMillis()));
191    
192            for (LeaveSummaryRow row : leaveSummary.getLeaveSummaryRows()) {
193                previousAccrualBalances.put(row.getAccrualCategory(), row.getLeaveBalance());
194            }
195                    
196                    return previousAccrualBalances;
197            }
198    
199            private void assignDocumentStatusToLeaveBlock(LeaveBlock leaveBlock) {
200                    //lookup document associated with this leave block and assign document status
201                    if(StringUtils.isNotEmpty(leaveBlock.getDocumentId())) {
202                            LeaveCalendarDocumentHeader lcdh = TkServiceLocator.getLeaveCalendarDocumentHeaderService().getDocumentHeader(leaveBlock.getDocumentId());
203                            if(lcdh != null ) {
204                                    leaveBlock.setDocumentStatus(KewApiConstants.DOCUMENT_STATUSES.get(lcdh.getDocumentStatus()));
205                            }
206                    }
207            }
208            
209            private String retrieveDescriptionAccordingToLeaveType(String leaveType) {
210                    String description = null;
211                    description = LMConstants.LEAVE_BLOCK_TYPE_MAP.get(leaveType);
212                    return description;
213            }
214    }