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 }