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.getCurrentTargetPersonId();
061                    if (TKUser.getCurrentTargetPersonId() != 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) {
107                            if (leaveBlockHistory.getAction().equalsIgnoreCase(LMConstants.ACTION.DELETE)) {
108                                leaveBlockHistory.setPrincipalIdModified(leaveBlockHistory.getPrincipalIdDeleted());
109                                leaveBlockHistory.setTimestamp(leaveBlockHistory.getTimestampDeleted());
110                            } else if (leaveBlockHistory.getAction().equalsIgnoreCase(LMConstants.ACTION.MODIFIED)) {
111                                leaveBlockHistory.setPrincipalIdModified(leaveBlockHistory.getPrincipalIdDeleted());
112                            }
113                        }
114    
115                                            this.assignDocumentStatusToLeaveBlock(leaveBlockHistory);
116                                            // if it is not generated by accrual then add it to the inactivelist
117                                            // Set Description
118                                            if(leaveBlockHistory.getDescription() == null || leaveBlockHistory.getDescription().trim().isEmpty()) {
119                                                    leaveBlockHistory.setDescription(this.retrieveDescriptionAccordingToLeaveType(leaveBlockHistory.getLeaveBlockType()));
120                                            }
121                                            if (StringUtils.isNotBlank(leaveBlockHistory.getRequestStatus())) {
122                                                    leaveBlockHistory.setRequestStatus(LMConstants.REQUEST_STATUS_STRINGS.get(leaveBlockHistory.getRequestStatus()));
123                                            }
124                                            leaveEntries.add(leaveBlockHistory);
125                                    }
126                            }
127                    }
128                    lbdf.setInActiveLeaveEntries(leaveEntries);
129                    
130                return forward;
131            }
132            
133            private List<AccrualCategory> getAccrualCategories(String leavePlan) {
134                    List<AccrualCategory> accrualCategories = new ArrayList<AccrualCategory>();
135                    
136                    List<AccrualCategory> allAccrualCategories = TkServiceLocator.getAccrualCategoryService().getActiveAccrualCategoriesForLeavePlan(leavePlan, TKUtils.getCurrentDate());
137                    if (allAccrualCategories != null) {
138                            for (AccrualCategory ac : allAccrualCategories) {
139                                    if (StringUtils.equalsIgnoreCase(ac.getShowOnGrid(), "Y")) {
140                                            accrualCategories.add(ac);
141                                    }
142                            }
143                            Collections.sort(accrualCategories, new Comparator<AccrualCategory>() {
144                                    @Override
145                                    public int compare(AccrualCategory o1, AccrualCategory o2) {
146                                            return ObjectUtils.compare(o1.getAccrualCategory(), o2.getAccrualCategory());
147                                    }
148                            });
149                    }
150                    
151                    return accrualCategories;
152            }
153            
154            private List<LeaveBlockDisplay> getLeaveEntries(String principalId, Date serviceDate, Date beginDate, Date endDate, List<AccrualCategory> accrualCategories) {
155                    List<LeaveBlockDisplay> leaveEntries = new ArrayList<LeaveBlockDisplay>();
156                    
157                    List<LeaveBlock> leaveBlocks = TkServiceLocator.getLeaveBlockService().getLeaveBlocks(principalId, beginDate, endDate);
158                    
159                    for (LeaveBlock leaveBlock : leaveBlocks) {
160                if (!leaveBlock.getLeaveBlockType().equals(LMConstants.LEAVE_BLOCK_TYPE.CARRY_OVER)) {
161                                leaveEntries.add(new LeaveBlockDisplay(leaveBlock));
162                }
163                    }
164                    Collections.sort(leaveEntries, new Comparator<LeaveBlockDisplay>() {
165                            @Override
166                            public int compare(LeaveBlockDisplay o1, LeaveBlockDisplay o2) {
167                                    return ObjectUtils.compare(o1.getLeaveDate(), o2.getLeaveDate());
168                            }
169                    });
170                    
171                    SortedMap<String, BigDecimal> accrualBalances = getPreviousAccrualBalances(principalId, serviceDate, beginDate, accrualCategories);
172                                    
173                    for (LeaveBlockDisplay leaveEntry : leaveEntries) {
174                            for (AccrualCategory accrualCategory : accrualCategories) {
175                                    if (!accrualBalances.containsKey(accrualCategory.getAccrualCategory())) {
176                                            accrualBalances.put(accrualCategory.getAccrualCategory(), BigDecimal.ZERO);
177                                    }
178                                    BigDecimal currentAccrualBalance = accrualBalances.get(accrualCategory.getAccrualCategory());
179                                    
180                                    if (StringUtils.equals(leaveEntry.getAccrualCategory(), accrualCategory.getAccrualCategory())) {
181                                            BigDecimal accruedBalance = currentAccrualBalance.add(leaveEntry.getLeaveAmount());
182                                            accrualBalances.put(accrualCategory.getAccrualCategory(), accruedBalance);
183                                    }
184                                    
185                                    leaveEntry.setAccrualBalance(accrualCategory.getAccrualCategory(), accrualBalances.get(accrualCategory.getAccrualCategory()));
186                            }
187                    }
188                    
189                    return leaveEntries;
190            }
191            
192            private SortedMap<String, BigDecimal> getPreviousAccrualBalances(String principalId, Date serviceDate, Date beginDate, List<AccrualCategory> accrualCategories) {
193                    SortedMap<String, BigDecimal> previousAccrualBalances = new TreeMap<String, BigDecimal>();
194    
195            LeaveSummary leaveSummary = TkServiceLocator.getLeaveSummaryService().getLeaveSummaryAsOfDateWithoutFuture(principalId, new java.sql.Date(new DateTime(beginDate).getMillis()));
196    
197            for (LeaveSummaryRow row : leaveSummary.getLeaveSummaryRows()) {
198                previousAccrualBalances.put(row.getAccrualCategory(), row.getLeaveBalance());
199            }
200                    
201                    return previousAccrualBalances;
202            }
203    
204            private void assignDocumentStatusToLeaveBlock(LeaveBlock leaveBlock) {
205                    //lookup document associated with this leave block and assign document status
206                    if(StringUtils.isNotEmpty(leaveBlock.getDocumentId())) {
207                            LeaveCalendarDocumentHeader lcdh = TkServiceLocator.getLeaveCalendarDocumentHeaderService().getDocumentHeader(leaveBlock.getDocumentId());
208                            if(lcdh != null ) {
209                                    leaveBlock.setDocumentStatus(KewApiConstants.DOCUMENT_STATUSES.get(lcdh.getDocumentStatus()));
210                            }
211                    }
212            }
213            
214            private String retrieveDescriptionAccordingToLeaveType(String leaveType) {
215                    String description = null;
216                    description = LMConstants.LEAVE_BLOCK_TYPE_MAP.get(leaveType);
217                    return description;
218            }
219    }