View Javadoc
1   /**
2    * Copyright 2004-2015 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.kpme.core.earncode.validation;
17  
18  import java.util.List;
19  
20  import org.apache.commons.lang.StringUtils;
21  import org.joda.time.DateTime;
22  import org.joda.time.LocalDate;
23  import org.kuali.kpme.core.accrualcategory.AccrualCategory;
24  import org.kuali.kpme.core.block.CalendarBlock;
25  import org.kuali.kpme.core.earncode.EarnCode;
26  import org.kuali.kpme.core.service.HrServiceLocator;
27  import org.kuali.kpme.core.util.HrConstants;
28  import org.kuali.kpme.core.util.ValidationUtils;
29  import org.kuali.rice.kns.document.MaintenanceDocument;
30  import org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase;
31  
32  @SuppressWarnings("deprecation")
33  public class EarnCodeValidation extends MaintenanceDocumentRuleBase{
34  	
35  	boolean validateRollupToEarnCode(String earnCode, LocalDate asOfDate) {
36  		boolean valid = true;
37  		if (!StringUtils.isEmpty(earnCode) && !ValidationUtils.validateEarnCode(earnCode, asOfDate)) {
38  			this.putFieldError("rollupToEarnCode", "earncode.rollupToEarnCode.notfound", "Roll up to Earn code "
39  					+ earnCode + "'");
40  			valid = false;
41  		}
42  		return valid;
43  	}
44  	
45  	boolean validateDefaultAmountOfTime(Long defaultAmountofTime) {
46  		boolean valid = true;
47  		if ( defaultAmountofTime != null ){
48  			if (defaultAmountofTime.compareTo(24L) > 0  || defaultAmountofTime.compareTo(0L) < 0) {
49  				this.putFieldError("defaultAmountofTime", "error.leaveCode.hours", "Default Amount of Time '"
50  						+ defaultAmountofTime + "'");
51  				valid = false;
52  			}
53  		}
54  		return valid;
55  	}
56  	
57  	boolean validateRecordMethod(String recordMethod, String accrualCategory, LocalDate asOfDate){
58  		boolean valid = true;
59  		if(recordMethod != null) {
60  			if(StringUtils.isNotEmpty(accrualCategory)) {
61  				valid = ValidationUtils.validateRecordMethod(recordMethod, accrualCategory, asOfDate);
62  				if(!valid) {
63  					this.putFieldError("recordMethod", "earncode.recordMethod.invalid", "Record Method");
64  				}
65  			}
66  		}
67  		return valid;
68  	}
69  	
70  	boolean validateLeavePlan(EarnCode earnCode) {
71  		
72  		boolean valid = true;
73  		
74  		if (StringUtils.isNotBlank(earnCode.getLeavePlan())) {
75  
76  			if (!ValidationUtils.validateLeavePlan(earnCode.getLeavePlan(), earnCode.getEffectiveLocalDate())) {
77  				this.putFieldError("leavePlan", "error.existence", "leavePlan '"
78  						+ earnCode.getLeavePlan() + "'");
79  				valid = false;
80  				return valid;
81  			}
82  			
83  			if (earnCode.getEffectiveDate() != null && StringUtils.isNotBlank(earnCode.getAccrualCategory())) {
84  				AccrualCategory myTestAccrualCategoryObj =  HrServiceLocator.getAccrualCategoryService().getAccrualCategory(earnCode.getAccrualCategory(), earnCode.getEffectiveLocalDate());
85  				if(myTestAccrualCategoryObj != null) {
86  					if (!myTestAccrualCategoryObj.getLeavePlan().equals(earnCode.getLeavePlan())) {
87  						this.putFieldError("leavePlan", "error.leaveCode.leavePlanMismatch", myTestAccrualCategoryObj.getLeavePlan());
88  						valid = false;
89  						return valid;
90  					}
91  					earnCode.setLeavePlan(myTestAccrualCategoryObj.getLeavePlan());
92  				} 
93  			}
94  		}
95  		return valid;
96  	}
97  	
98  	@Override
99  	protected boolean processCustomRouteDocumentBusinessRules(MaintenanceDocument document) {
100 		EarnCode earnCode = (EarnCode)this.getNewBo();
101 		EarnCode oldEarnCode = (EarnCode)this.getOldBo();
102 		if ((StringUtils.equals(oldEarnCode.getEarnCode(), HrConstants.LUNCH_EARN_CODE) 
103 				|| StringUtils.equals(oldEarnCode.getEarnCode(), HrConstants.HOLIDAY_EARN_CODE))
104 					&& !earnCode.isActive()) {
105 			this.putFieldError("active", "earncode.inactivate.locked", earnCode
106 					.getEarnCode());
107 		}
108 		//if earn code is not designated how to record then throw error
109 		if (earnCode.getHrEarnCodeId() == null) {
110 			if (ValidationUtils.validateEarnCode(earnCode.getEarnCode(), null)) {
111 				// If there IS an earn code, ie, it is valid, we need to report
112 				// an error as earn codes must be unique.			
113 				this.putFieldError("earnCode", "earncode.earncode.unique");
114 				return false;
115 			}
116 		}
117 		
118 		 //check if the effective date of the leave plan is prior to effective date of the earn code 
119 		 //accrual category is an optional field
120 		if(StringUtils.isNotEmpty(earnCode.getLeavePlan())){
121 			boolean valid = validateLeavePlan(earnCode);
122 			if(!valid) {
123 				return false;
124 			}
125 		}
126 		//check if the effective date of the accrual category is prior to effective date of the earn code 
127 		//accrual category is an optional field
128 		if(StringUtils.isNotEmpty(earnCode.getAccrualCategory())){
129 			if (!ValidationUtils.validateAccrualCategory(earnCode.getAccrualCategory(), earnCode.getEffectiveLocalDate())) {
130 				this.putFieldError("accrualCategory", "earncode.accrualCategory.invalid", new String[]{earnCode.getAccrualCategory(),earnCode.getLeavePlan()});
131 				return false;
132 			}
133 		}
134 		
135 		// check if there's a newer version of the Earn Code
136 		int count = HrServiceLocator.getEarnCodeService().getNewerEarnCodeCount(earnCode.getEarnCode(), earnCode.getEffectiveLocalDate());
137 		if(count > 0) {
138 			this.putFieldError("effectiveDate", "earncode.effectiveDate.newer.exists");
139 			return false;
140 		}
141 		
142 		// kpme-937 can not deactivate an earn code if it used in active timeblocks
143 		// kpme-2344: modularity induced changes
144 		DateTime latestEndTimestamp =  HrServiceLocator.getCalendarBlockService().getLatestEndTimestampForEarnCode(earnCode.getEarnCode(), "Time");
145 
146 		if(latestEndTimestamp != null) {
147 			LocalDate earnCodeEffectiveDate = LocalDate.fromDateFields(earnCode.getEffectiveDate());
148 			LocalDate latestEndTimestampLocalDate = latestEndTimestamp.toLocalDate();
149 			 
150 			if ( !earnCode.isActive() && earnCodeEffectiveDate.isBefore(latestEndTimestampLocalDate) ){
151 				this.putFieldError("active", "earncode.earncode.inactivate", earnCode.getEarnCode());
152 				return false;
153 			}
154 		}
155 		
156 		if(!(this.validateDefaultAmountOfTime(earnCode.getDefaultAmountofTime()))) {
157 			return false;
158 		}
159 		
160 		if(earnCode.getRollupToEarnCode() != null && !StringUtils.isEmpty(earnCode.getRollupToEarnCode())) {
161 			if(!(this.validateRollupToEarnCode(earnCode.getRollupToEarnCode(), earnCode.getEffectiveLocalDate()))) {
162 				return false;
163 			}
164 		}
165 		
166 		if(!validateRecordMethod(earnCode.getRecordMethod(), earnCode.getAccrualCategory(), earnCode.getEffectiveLocalDate())) {
167 			return false;
168 		}
169 		
170 		// KPME-2628 leave plan is required if accrual category is provided
171 		if(!StringUtils.isBlank(earnCode.getAccrualCategory())){
172 			if (StringUtils.isBlank(earnCode.getLeavePlan())) {
173 				// earncode.leavePlan.required=Leave Plan is required if Accrual Category is provided.
174 				this.putFieldError("leavePlan", "earncode.leavePlan.required");
175 				return false;
176 			}
177 			
178 			//	KPME-3093: If an earn code has an accrual category, Accrual Balance Action can not be None.
179 			if (StringUtils.isBlank(earnCode.getAccrualBalanceAction())
180 					|| earnCode.getAccrualBalanceAction().equals(HrConstants.ACCRUAL_BALANCE_ACTION.NONE)) {
181 				this.putFieldError("accrualBalanceAction", "earncode.accrualBalanceAction.invalid");
182 				return false;
183 			}
184 		}
185 		
186 		return true;
187 	}
188 
189 }