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.time.earncode.validation;
017    
018    import org.apache.commons.lang.StringUtils;
019    import org.kuali.hr.lm.accrual.AccrualCategory;
020    import org.kuali.hr.time.earncode.EarnCode;
021    import org.kuali.hr.time.service.base.TkServiceLocator;
022    import org.kuali.hr.time.timeblock.TimeBlock;
023    import org.kuali.hr.time.util.TkConstants;
024    import org.kuali.hr.time.util.ValidationUtils;
025    import org.kuali.rice.kns.document.MaintenanceDocument;
026    import org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase;
027    
028    import java.math.BigDecimal;
029    import java.sql.Date;
030    import java.util.List;
031    
032    public class EarnCodeValidation extends MaintenanceDocumentRuleBase{
033            
034            boolean validateRollupToEarnCode(String earnCode, Date asOfDate) {
035                    boolean valid = true;
036                    if (!StringUtils.isEmpty(earnCode) && !ValidationUtils.validateEarnCode(earnCode, asOfDate)) {
037                            this.putFieldError("rollupToEarnCode", "earncode.rollupToEarnCode.notfound", "Roll up to Earn code "
038                                            + earnCode + "'");
039                            valid = false;
040                    }
041                    return valid;
042            }
043            
044            boolean validateDefaultAmountOfTime(Long defaultAmountofTime) {
045                    boolean valid = true;
046                    if ( defaultAmountofTime != null ){
047                            if (defaultAmountofTime.compareTo(24L) > 0  || defaultAmountofTime.compareTo(0L) < 0) {
048                                    this.putFieldError("defaultAmountofTime", "error.leaveCode.hours", "Default Amount of Time '"
049                                                    + defaultAmountofTime + "'");
050                                    valid = false;
051                            }
052                    }
053                    return valid;
054            }
055            
056            boolean validateRecordMethod(String recordMethod, String accrualCategory, Date asOfDate){
057                    boolean valid = true;
058                    if(recordMethod != null) {
059                            if(StringUtils.isNotEmpty(accrualCategory)) {
060                                    valid = ValidationUtils.validateRecordMethod(recordMethod, accrualCategory, asOfDate);
061                                    if(!valid) {
062                                            this.putFieldError("recordMethod", "earncode.recordMethod.invalid", "Record Method");
063                                    }
064                            }
065                    }
066                    return valid;
067            }
068            
069            boolean validateLeavePlan(EarnCode earnCode) {
070                    
071                    boolean valid = true;
072                    
073                    if (StringUtils.isNotBlank(earnCode.getLeavePlan())) {
074    
075                            if (!ValidationUtils.validateLeavePlan(earnCode.getLeavePlan(), earnCode.getEffectiveDate())) {
076                                    this.putFieldError("leavePlan", "error.existence", "leavePlan '"
077                                                    + earnCode.getLeavePlan() + "'");
078                                    valid = false;
079                                    return valid;
080                            }
081                            
082                            if (earnCode.getEffectiveDate() != null && StringUtils.isNotBlank(earnCode.getAccrualCategory())) {
083                                    AccrualCategory myTestAccrualCategoryObj =  TkServiceLocator.getAccrualCategoryService().getAccrualCategory(earnCode.getAccrualCategory(), earnCode.getEffectiveDate());
084                                    if(myTestAccrualCategoryObj != null) {
085                                            if (!myTestAccrualCategoryObj.getLeavePlan().equals(earnCode.getLeavePlan())) {
086                                                    this.putFieldError("leavePlan", "error.leaveCode.leavePlanMismatch", myTestAccrualCategoryObj.getLeavePlan());
087                                                    valid = false;
088                                                    return valid;
089                                            }
090                                            earnCode.setLeavePlan(myTestAccrualCategoryObj.getLeavePlan());
091                                    } 
092                            }
093                    }
094                    return valid;
095            }
096            
097            @Override
098            protected boolean processCustomRouteDocumentBusinessRules(MaintenanceDocument document) {
099                    EarnCode earnCode = (EarnCode)this.getNewBo();
100                    EarnCode oldEarnCode = (EarnCode)this.getOldBo();
101                    if ((StringUtils.equals(oldEarnCode.getEarnCode(), TkConstants.LUNCH_EARN_CODE) 
102                                    || StringUtils.equals(oldEarnCode.getEarnCode(), TkConstants.HOLIDAY_EARN_CODE))
103                                            && !earnCode.isActive()) {
104                            this.putFieldError("active", "earncode.inactivate.locked", earnCode
105                                            .getEarnCode());
106                    }
107                    //if earn code is not designated how to record then throw error
108                    if (earnCode.getHrEarnCodeId() == null) {
109                            if (ValidationUtils.validateEarnCode(earnCode.getEarnCode(), null)) {
110                                    // If there IS an earn code, ie, it is valid, we need to report
111                                    // an error as earn codes must be unique.                       
112                                    this.putFieldError("earnCode", "earncode.earncode.unique");
113                                    return false;
114                            }
115                    }
116                    
117                     //check if the effective date of the leave plan is prior to effective date of the earn code 
118                     //accrual category is an optional field
119                    if(StringUtils.isNotEmpty(earnCode.getLeavePlan())){
120                            boolean valid = validateLeavePlan(earnCode);
121                            if(!valid) {
122                                    return false;
123                            }
124                    }
125                    //check if the effective date of the accrual category is prior to effective date of the earn code 
126                    //accrual category is an optional field
127                    if(StringUtils.isNotEmpty(earnCode.getAccrualCategory())){
128                            if (!ValidationUtils.validateAccrualCategory(earnCode.getAccrualCategory(), earnCode.getEffectiveDate())) {
129                                    this.putFieldError("accrualCategory", "earncode.accrualCategory.invalid", new String[]{earnCode.getAccrualCategory(),earnCode.getLeavePlan()});
130                                    return false;
131                            }
132                    }
133                    
134                    // check if there's a newer version of the Earn Code
135                    int count = TkServiceLocator.getEarnCodeService().getNewerEarnCodeCount(earnCode.getEarnCode(), earnCode.getEffectiveDate());
136                    if(count > 0) {
137                            this.putFieldError("effectiveDate", "earncode.effectiveDate.newer.exists");
138                            return false;
139                    }
140                    
141                    // kpme-937 can not deactivate an earn code if it used in active timeblocks
142                    List<TimeBlock> latestEndTimestampTimeBlocks =  TkServiceLocator.getTimeBlockService().getLatestEndTimestampForEarnCode(earnCode.getEarnCode());
143                    if ( !earnCode.isActive() && !latestEndTimestampTimeBlocks.isEmpty() && earnCode.getEffectiveDate().before(latestEndTimestampTimeBlocks.get(0).getEndDate()) ){
144                            this.putFieldError("earnCode", "earncode.earncode.inactivate", earnCode.getEarnCode());
145                            return false;
146                    }
147                    
148                    if(!(this.validateDefaultAmountOfTime(earnCode.getDefaultAmountofTime()))) {
149                            return false;
150                    }
151                    
152                    if(earnCode.getRollupToEarnCode() != null && !StringUtils.isEmpty(earnCode.getRollupToEarnCode())) {
153                            if(!(this.validateRollupToEarnCode(earnCode.getRollupToEarnCode(), earnCode.getEffectiveDate()))) {
154                                    return false;
155                            }
156                    }
157                    
158                    if(!validateRecordMethod(earnCode.getRecordMethod(), earnCode.getAccrualCategory(), earnCode.getEffectiveDate())) {
159                            return false;
160                    }
161                    
162                    return true;
163            }
164    
165    }