View Javadoc

1   /**
2    * Copyright 2004-2013 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.hr.lm.balancetransfer.validation;
17  
18  import java.math.BigDecimal;
19  import java.sql.Date;
20  import java.util.List;
21  
22  import org.apache.commons.lang.StringUtils;
23  import org.kuali.hr.lm.LMConstants;
24  import org.kuali.hr.lm.accrual.AccrualCategory;
25  import org.kuali.hr.lm.accrual.AccrualCategoryRule;
26  import org.kuali.hr.lm.balancetransfer.BalanceTransfer;
27  import org.kuali.hr.lm.employeeoverride.EmployeeOverride;
28  import org.kuali.hr.lm.timeoff.SystemScheduledTimeOff;
29  import org.kuali.hr.time.principal.PrincipalHRAttributes;
30  import org.kuali.hr.time.service.base.TkServiceLocator;
31  import org.kuali.hr.time.util.TKUtils;
32  import org.kuali.hr.time.util.TkConstants;
33  import org.kuali.rice.krad.util.GlobalVariables;
34  import org.kuali.rice.krad.util.ObjectUtils;
35  
36  public class BalanceTransferValidationUtils {
37  
38  	public static boolean validateTransfer(BalanceTransfer balanceTransfer) {
39  		boolean isValid = true;
40  		if(StringUtils.isNotEmpty(balanceTransfer.getSstoId())) {
41  			return isValid && validateSstoTranser(balanceTransfer) ;
42  		}
43  		String principalId = balanceTransfer.getPrincipalId();
44  		Date effectiveDate = balanceTransfer.getEffectiveDate();
45  		String fromAccrualCategory = balanceTransfer.getFromAccrualCategory();
46  		String toAccrualCategory = balanceTransfer.getToAccrualCategory();
47  		AccrualCategory fromCat = TkServiceLocator.getAccrualCategoryService().getAccrualCategory(fromAccrualCategory, effectiveDate);
48  		AccrualCategory toCat = TkServiceLocator.getAccrualCategoryService().getAccrualCategory(toAccrualCategory, effectiveDate);
49  		PrincipalHRAttributes pha = TkServiceLocator.getPrincipalHRAttributeService().getPrincipalCalendar(principalId,effectiveDate);
50  		
51  		if(ObjectUtils.isNotNull(pha)) {
52  			if(ObjectUtils.isNotNull(pha.getLeavePlan())) {
53  				AccrualCategoryRule acr = TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRuleForDate(fromCat,
54  						effectiveDate, pha.getServiceDate());
55  				if(ObjectUtils.isNotNull(acr)) {
56  					if(ObjectUtils.isNotNull(acr.getMaxBalFlag())
57  							&& StringUtils.isNotBlank(acr.getMaxBalFlag())
58  							&& StringUtils.isNotEmpty(acr.getMaxBalFlag())
59  							&& StringUtils.equals(acr.getMaxBalFlag(), "Y")) {
60  						if(ObjectUtils.isNotNull(acr.getMaxBalanceTransferToAccrualCategory()) || StringUtils.equals(LMConstants.ACTION_AT_MAX_BAL.LOSE, acr.getActionAtMaxBalance())) {
61  /*							isValid &= validatePrincipal(pha,principalId);
62  							isValid &= validateEffectiveDate(effectiveDate);
63  							isValid &= validateAgainstLeavePlan(pha,fromCat,toCat,effectiveDate);
64  							isValid &= validateTransferFromAccrualCategory(fromCat,principalId,effectiveDate,acr);
65  							isValid &= validateTransferToAccrualCategory(toCat,principalId,effectiveDate,acr);*/
66  							isValid &= validateMaxCarryOver(balanceTransfer.getAmountTransferred(),toCat,principalId,effectiveDate,acr, pha);
67  							isValid &= validateTransferAmount(balanceTransfer.getTransferAmount(),fromCat,toCat, principalId, effectiveDate, acr);
68  						}
69  						else {
70  							//should never be the case if accrual category rules are validated correctly.
71  							GlobalVariables.getMessageMap().putError("document.newMaintainableObject.fromAccrualCategory",
72  									"balanceTransfer.fromAccrualCategory.rules.transferToAccrualCategory",
73  									fromAccrualCategory);
74  							isValid &= false;
75  						}
76  					}
77  					else {
78  						//max bal flag null, blank, empty, or "N"
79  						GlobalVariables.getMessageMap().putError("document.newMaintinableObject.fromAccrualCategory",
80  								"balanceTransfer.fromAccrualCategory.rules.maxBalFlag", fromAccrualCategory);
81  						isValid &= false;
82  					}
83  				}
84  				else {
85  					//department admins must validate amount to transfer does not exceed current balance.
86  					GlobalVariables.getMessageMap().putError("document.newMaintainableObject.fromAccrualCategory",
87  							"balanceTransfer.fromAccrualCategory.rules.exist",fromCat.getAccrualCategory());
88  					isValid &= false;
89  				}
90  			}
91  			else {
92  				//if the principal doesn't have a leave plan, there aren't any accrual categories that can be debited/credited.
93  				GlobalVariables.getMessageMap().putError("document.newMaintainableObject.principalId","balanceTransfer.principal.noLeavePlan");
94  				isValid &=false;
95  			}
96  		}
97  		else  {
98  			//if the principal has no principal hr attributes, they're not a principal.
99  			GlobalVariables.getMessageMap().putError("document.newMaintainableObject.principalId","balanceTransfer.principal.noAttributes");
100 			isValid &= false;
101 		}
102 /*		}*/
103 		return isValid;
104 
105 	}
106 
107 	private static boolean validateMaxCarryOver(BigDecimal amountTransferred,
108 			AccrualCategory toCat, String principalId, Date effectiveDate,
109 			AccrualCategoryRule acr, PrincipalHRAttributes pha) {
110 /*		List<AccrualCategoryRule> rules = toCat.getAccrualCategoryRules();
111 		Date serviceDate = pha.getServiceDate();
112 		Interval interval = new Interval(serviceDate.getTime(), effectiveDate.getTime());
113 		for(AccrualCategoryRule rule : rules) {
114 			String unitOfTime = rule.getServiceUnitOfTime();
115 			if(StringUtils.equals(unitOfTime, LMConstants.SERVICE_TIME_MONTHS))
116 		}*/
117 		return true;
118 	}
119 
120 	private static boolean validateTransferAmount(BigDecimal transferAmount,
121 			AccrualCategory fromCat, AccrualCategory toCat, String principalId,
122 			Date effectiveDate, AccrualCategoryRule accrualRule) {
123 
124 		//transfer amount must be less than the max transfer amount defined in the accrual category rule.
125 		//it cannot be negative.
126 		boolean isValid = true;
127 		BigDecimal maxTransferAmount = null;
128 		BigDecimal adjustedMaxTransferAmount = null;
129 		if(ObjectUtils.isNotNull(accrualRule.getMaxTransferAmount())) {
130 			maxTransferAmount = new BigDecimal(accrualRule.getMaxTransferAmount());
131 			BigDecimal fullTimeEngagement = TkServiceLocator.getJobService().getFteSumForAllActiveLeaveEligibleJobs(principalId, effectiveDate);
132 			adjustedMaxTransferAmount = maxTransferAmount.multiply(fullTimeEngagement);
133 		}
134 		
135 		//use override if one exists.
136 		List<EmployeeOverride> overrides = TkServiceLocator.getEmployeeOverrideService().getEmployeeOverrides(principalId, effectiveDate);
137 		for(EmployeeOverride override : overrides) {
138 			if(override.getOverrideType().equals(TkConstants.EMPLOYEE_OVERRIDE_TYPE.get("MTA")))
139 				adjustedMaxTransferAmount = new BigDecimal(override.getOverrideValue());
140 		}
141 				
142 		if(ObjectUtils.isNotNull(adjustedMaxTransferAmount)) {
143 			if(transferAmount.compareTo(adjustedMaxTransferAmount) > 0) {
144 				isValid &= false;
145 				String fromUnitOfTime = TkConstants.UNIT_OF_TIME.get(fromCat.getUnitOfTime());
146 				GlobalVariables.getMessageMap().putError("balanceTransfer.transferAmount","balanceTransfer.transferAmount.maxTransferAmount",adjustedMaxTransferAmount.toString(),fromUnitOfTime);
147 			}
148 		}
149 		// check for a positive amount.
150 		if(transferAmount.compareTo(BigDecimal.ZERO) < 0 ) {
151 			isValid &= false;
152 			GlobalVariables.getMessageMap().putError("balanceTransfer.transferAmount","balanceTransfer.transferAmount.negative");
153 		}
154 		return isValid;
155 	}
156 	
157 	public static boolean validateSstoTranser(BalanceTransfer bt) {
158 		// make sure from accrual category is consistent with the ssto's
159 		SystemScheduledTimeOff ssto = TkServiceLocator.getSysSchTimeOffService().getSystemScheduledTimeOff(bt.getSstoId());
160 		if(ssto == null) {
161 			GlobalVariables.getMessageMap().putError("document.newMaintainableObject.fromAccrualCategory", "balanceTransfer.transferSSTO.sstoDoesNotExis", bt.getSstoId());
162 			return false;
163 		}
164 		if(!ssto.getAccrualCategory().equals(bt.getFromAccrualCategory())) {
165 			GlobalVariables.getMessageMap().putError("document.newMaintainableObject.fromAccrualCategory", "balanceTransfer.transferSSTO.fromACWrong", bt.getFromAccrualCategory(), ssto.getAccrualCategory());
166 			return false;
167 		}
168 		
169 		if(bt.getFromAccrualCategory().equals(bt.getToAccrualCategory())) {
170 			GlobalVariables.getMessageMap().putError("document.newMaintainableObject.fromAccrualCategory", "balanceTransfer.transferSSTO.fromAndToACTheSame");
171 			return false;
172 		}
173 		
174 		AccrualCategory fromAC = TkServiceLocator.getAccrualCategoryService().getAccrualCategory(bt.getFromAccrualCategory(), bt.getEffectiveDate());
175 		if(fromAC == null) {
176 			GlobalVariables.getMessageMap().putError("document.newMaintainableObject.fromAccrualCategory", "balanceTransfer.transferSSTO.acDoesNotExist", bt.getFromAccrualCategory());
177 			return false;
178 		}
179 		AccrualCategory toAC = TkServiceLocator.getAccrualCategoryService().getAccrualCategory(bt.getToAccrualCategory(), bt.getEffectiveDate());
180 		if(toAC == null) {
181 			GlobalVariables.getMessageMap().putError("document.newMaintainableObject.toAccrualCategory", "balanceTransfer.transferSSTO.acDoesNotExist", bt.getToAccrualCategory());
182 			return false;
183 		}
184 		// make sure the leave plan of from/to accrual categories are consistent with the employee's leave plan
185 		PrincipalHRAttributes pha = TkServiceLocator.getPrincipalHRAttributeService().getPrincipalCalendar(bt.getPrincipalId(),bt.getEffectiveDate());
186 		if(StringUtils.isNotEmpty(fromAC.getLeavePlan())){
187 			if(!fromAC.getLeavePlan().equals(pha.getLeavePlan())) {
188 				GlobalVariables.getMessageMap().putError("document.newMaintainableObject.fromAccrualCategory", "balanceTransfer.transferSSTO.wrongACLeavePlan", fromAC.getLeavePlan(), pha.getLeavePlan());
189 				return false;
190 			}
191 		}
192 		if(StringUtils.isNotEmpty(toAC.getLeavePlan())){
193 			if(!fromAC.getLeavePlan().equals(pha.getLeavePlan())) {
194 				GlobalVariables.getMessageMap().putError("document.newMaintainableObject.toAccrualCategory", "balanceTransfer.transferSSTO.wrongACLeavePlan", toAC.getLeavePlan(), pha.getLeavePlan());
195 				return false;
196 			}
197 		}
198 		
199 		return true;
200 	}
201 	
202 
203 }