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 }