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.leavecalendar.web; 017 018 import java.util.ArrayList; 019 import java.util.Comparator; 020 import java.util.HashSet; 021 import java.util.List; 022 import java.util.Map; 023 import java.util.Map.Entry; 024 import java.util.Set; 025 026 import org.apache.commons.lang.StringUtils; 027 import org.apache.commons.lang.time.DateUtils; 028 import org.apache.struts.action.ActionForm; 029 import org.apache.struts.action.ActionForward; 030 import org.apache.struts.action.ActionMapping; 031 import org.apache.struts.action.ActionRedirect; 032 import org.displaytag.tags.TableTagParameters; 033 import org.displaytag.util.ParamEncoder; 034 import org.joda.time.Interval; 035 import org.kuali.hr.lm.LMConstants; 036 import org.kuali.hr.lm.accrual.AccrualCategory; 037 import org.kuali.hr.lm.accrual.AccrualCategoryRule; 038 import org.kuali.hr.lm.leaveblock.LeaveBlock; 039 import org.kuali.hr.lm.leavecalendar.LeaveCalendarDocument; 040 import org.kuali.hr.lm.leaveplan.LeavePlan; 041 import org.kuali.hr.lm.workflow.service.LeaveCalendarDocumentHeaderService; 042 import org.kuali.hr.time.base.web.TkAction; 043 import org.kuali.hr.time.calendar.Calendar; 044 import org.kuali.hr.time.principal.PrincipalHRAttributes; 045 import org.kuali.hr.time.roles.TkUserRoles; 046 import org.kuali.hr.time.roles.UserRoles; 047 import org.kuali.hr.time.service.base.TkServiceLocator; 048 import org.kuali.hr.time.util.TKContext; 049 import org.kuali.hr.time.util.TKUser; 050 import org.kuali.hr.time.util.TKUtils; 051 import org.kuali.hr.time.util.TkConstants; 052 import org.kuali.rice.kew.api.document.DocumentStatus; 053 import org.kuali.rice.krad.exception.AuthorizationException; 054 import org.kuali.rice.krad.util.GlobalVariables; 055 import org.kuali.rice.krad.util.ObjectUtils; 056 057 import edu.emory.mathcs.backport.java.util.Collections; 058 059 import javax.servlet.http.HttpServletRequest; 060 import javax.servlet.http.HttpServletResponse; 061 062 063 public class LeaveCalendarSubmitAction extends TkAction { 064 @Override 065 protected void checkTKAuthorization(ActionForm form, String methodToCall) throws AuthorizationException { 066 LeaveCalendarSubmitForm lcf = (LeaveCalendarSubmitForm)form; 067 068 String principal = TKContext.getPrincipalId(); 069 UserRoles roles = TkUserRoles.getUserRoles(GlobalVariables.getUserSession().getPrincipalId()); 070 071 LeaveCalendarDocument document = TkServiceLocator.getLeaveCalendarService().getLeaveCalendarDocument(lcf.getDocumentId()); 072 if (!roles.isDocumentWritable(document)) { 073 throw new AuthorizationException(principal, "LeaveCalendarSubmitAction", ""); 074 } 075 } 076 077 public ActionForward approveLeaveCalendar(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 078 String documentId = request.getParameter("documentId"); 079 String action = request.getParameter("action"); 080 LeaveCalendarDocument document = TkServiceLocator.getLeaveCalendarService().getLeaveCalendarDocument(documentId); 081 082 // Switched to grab the target (chain, resolution: target -> backdoor -> actual) user. 083 // Approvals still using backdoor > actual 084 if (StringUtils.equals(action, TkConstants.DOCUMENT_ACTIONS.ROUTE)) { 085 if (DocumentStatus.INITIATED.getCode().equals(document.getDocumentHeader().getDocumentStatus()) 086 || DocumentStatus.SAVED.getCode().equals(document.getDocumentHeader().getDocumentStatus())) { 087 088 Map<String,Set<LeaveBlock>> eligibilities = TkServiceLocator.getAccrualCategoryMaxBalanceService().getMaxBalanceViolations(document.getCalendarEntry(), document.getPrincipalId()); 089 090 ActionRedirect transferRedirect = new ActionRedirect(); 091 ActionRedirect payoutRedirect = new ActionRedirect(); 092 093 List<LeaveBlock> eligibleTransfers = new ArrayList<LeaveBlock>(); 094 List<LeaveBlock> eligiblePayouts = new ArrayList<LeaveBlock>(); 095 Interval interval = new Interval(document.getCalendarEntry().getBeginPeriodDate().getTime(), document.getCalendarEntry().getEndPeriodDate().getTime()); 096 for(Entry<String,Set<LeaveBlock>> entry : eligibilities.entrySet()) { 097 098 for(LeaveBlock lb : entry.getValue()) { 099 if(interval.contains(lb.getLeaveDate().getTime())) { 100 //maxBalanceViolations should, if a violation exists, return a leave block with leave date either current date, or the end period date - 1 days. 101 PrincipalHRAttributes pha = TkServiceLocator.getPrincipalHRAttributeService().getPrincipalCalendar(document.getPrincipalId(), lb.getLeaveDate()); 102 AccrualCategoryRule aRule = TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(lb.getAccrualCategoryRuleId()); 103 104 if(ObjectUtils.isNotNull(aRule) 105 && !StringUtils.equals(aRule.getMaxBalanceActionFrequency(),LMConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND)) { 106 if(StringUtils.equals(aRule.getMaxBalanceActionFrequency(),LMConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE) 107 || (StringUtils.equals(aRule.getMaxBalanceActionFrequency(),LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END) 108 && TkServiceLocator.getLeavePlanService().isLastCalendarPeriodOfLeavePlan(document.getCalendarEntry(),pha.getLeavePlan(),lb.getLeaveDate()))) 109 if(StringUtils.equals(aRule.getActionAtMaxBalance(),LMConstants.ACTION_AT_MAX_BAL.PAYOUT)) { 110 eligiblePayouts.add(lb); 111 } 112 else if(StringUtils.equals(aRule.getActionAtMaxBalance(), LMConstants.ACTION_AT_MAX_BAL.TRANSFER) 113 || StringUtils.equals(aRule.getActionAtMaxBalance(), LMConstants.ACTION_AT_MAX_BAL.LOSE)) { 114 eligibleTransfers.add(lb); 115 } 116 } 117 } 118 } 119 } 120 if(!eligibleTransfers.isEmpty()) { 121 transferRedirect.setPath("/BalanceTransfer.do?"+request.getQueryString()); 122 request.getSession().setAttribute("eligibilities", eligibleTransfers); 123 return transferRedirect; 124 } 125 if(!eligiblePayouts.isEmpty()) { 126 payoutRedirect.setPath("/LeavePayout.do?"+request.getQueryString()); 127 request.getSession().setAttribute("eligibilities", eligiblePayouts); 128 return payoutRedirect; 129 } 130 TkServiceLocator.getLeaveCalendarService().routeLeaveCalendar(TKContext.getTargetPrincipalId(), document); 131 } 132 } else if (StringUtils.equals(action, TkConstants.DOCUMENT_ACTIONS.APPROVE)) { 133 if (TkServiceLocator.getLeaveCalendarService().isReadyToApprove(document)) { 134 if (document.getDocumentHeader().getDocumentStatus().equals(DocumentStatus.ENROUTE.getCode())) { 135 TkServiceLocator.getLeaveCalendarService().approveLeaveCalendar(TKContext.getPrincipalId(), document); 136 } 137 } else { 138 //ERROR!!!! 139 } 140 } else if (StringUtils.equals(action, TkConstants.DOCUMENT_ACTIONS.DISAPPROVE)) { 141 if (document.getDocumentHeader().getDocumentStatus().equals(DocumentStatus.ENROUTE.getCode())) { 142 TkServiceLocator.getLeaveCalendarService().disapproveLeaveCalendar(TKContext.getPrincipalId(), document); 143 } 144 } 145 ActionRedirect rd = new ActionRedirect(mapping.findForward("leaveCalendarRedirect")); 146 TkServiceLocator.getTkSearchableAttributeService().updateSearchableAttribute(document, document.getAsOfDate()); 147 rd.addParameter("documentId", documentId); 148 149 return rd; 150 } 151 152 public ActionForward approveApprovalTab(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 153 LeaveCalendarSubmitForm lcf = (LeaveCalendarSubmitForm)form; 154 LeaveCalendarDocument document = TkServiceLocator.getLeaveCalendarService().getLeaveCalendarDocument(lcf.getDocumentId()); 155 156 // Switched to grab the target (chain, resolution: target -> backdoor -> actual) user. 157 // Approvals still using backdoor > actual 158 if (StringUtils.equals(lcf.getAction(), TkConstants.DOCUMENT_ACTIONS.ROUTE)) { 159 if (document.getDocumentHeader().getDocumentStatus().equals(DocumentStatus.INITIATED.getCode())) { 160 TkServiceLocator.getLeaveCalendarService().routeLeaveCalendar(TKContext.getTargetPrincipalId(), document); 161 } 162 } else if (StringUtils.equals(lcf.getAction(), TkConstants.DOCUMENT_ACTIONS.APPROVE)) { 163 //Todo: check for unfinalized BalanceTransfer on current leave calendar. 164 if (TkServiceLocator.getLeaveCalendarService().isReadyToApprove(document)) { 165 if (document.getDocumentHeader().getDocumentStatus().equals(DocumentStatus.ENROUTE.getCode())) { 166 TkServiceLocator.getLeaveCalendarService().approveLeaveCalendar(TKContext.getPrincipalId(), document); 167 } 168 } else { 169 //ERROR!!!! 170 } 171 172 } else if (StringUtils.equals(lcf.getAction(), TkConstants.DOCUMENT_ACTIONS.DISAPPROVE)) { 173 if (document.getDocumentHeader().getDocumentStatus().equals(DocumentStatus.ENROUTE.getCode())) { 174 TkServiceLocator.getLeaveCalendarService().disapproveLeaveCalendar(TKContext.getPrincipalId(), document); 175 } 176 } 177 178 TKUser.clearTargetUser(); 179 String page = new ParamEncoder(TkConstants.APPROVAL_TABLE_ID).encodeParameterName(TableTagParameters.PARAMETER_PAGE); 180 String pageVal = request.getParameter(page); 181 ActionRedirect ar = new ActionRedirect(mapping.findForward("approverRedirect")); 182 183 if (StringUtils.isNotEmpty(pageVal)) { 184 ar.addParameter(page, pageVal); 185 } 186 return ar; 187 188 } 189 190 }