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.lm.leavecode.LeaveCode;
021    import org.kuali.hr.time.earncode.EarnCode;
022    import org.kuali.hr.time.service.base.TkServiceLocator;
023    import org.kuali.hr.time.timeblock.TimeBlock;
024    import org.kuali.hr.time.util.TkConstants;
025    import org.kuali.hr.time.util.ValidationUtils;
026    import org.kuali.rice.kns.document.MaintenanceDocument;
027    import org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase;
028    
029    import java.math.BigDecimal;
030    import java.sql.Date;
031    import java.util.List;
032    
033    public class EarnCodeValidation extends MaintenanceDocumentRuleBase{
034            
035            boolean validateRollupToEarnCode(String earnCode, Date asOfDate) {
036                    boolean valid = true;
037                    if (!StringUtils.isEmpty(earnCode) && !ValidationUtils.validateEarnCode(earnCode, asOfDate)) {
038                            this.putFieldError("rollupToEarnCode", "earncode.rollupToEarnCode.notfound", "Roll up to Earn code "
039                                            + earnCode + "'");
040                            valid = false;
041                    }
042                    return valid;
043            }
044            
045            boolean validateDefaultAmountOfTime(Long defaultAmountofTime) {
046                    boolean valid = true;
047                    if ( defaultAmountofTime != null ){
048                            if (defaultAmountofTime.compareTo(new Long(24)) > 0  || defaultAmountofTime.compareTo(new Long(0)) < 0) {
049                                    this.putFieldError("defaultAmountofTime", "error.leaveCode.hours", "Default Amount of Time '"
050                                                    + defaultAmountofTime + "'");
051                                    valid = false;
052                            }
053                    }
054                    return valid;
055            }
056            
057            boolean validateRecordMethod(String recordMethod, String accrualCategory, Date asOfDate){
058                    boolean valid = true;
059                    if(recordMethod != null) {
060                            if(StringUtils.isNotEmpty(accrualCategory)) {
061                                    valid = ValidationUtils.validateRecordMethod(recordMethod, accrualCategory, asOfDate);
062                                    if(!valid) {
063                                            this.putFieldError("recordMethod", "earncode.recordMethod.invalid", "Record Method");
064                                    }
065                            }
066                    }
067                    return valid;
068            }
069            
070            boolean validateLeavePlan(EarnCode earnCode) {
071                    
072                    boolean valid = true;
073                    
074                    if (StringUtils.isNotBlank(earnCode.getLeavePlan())) {
075    
076                            if (!ValidationUtils.validateLeavePlan(earnCode.getLeavePlan(), earnCode.getEffectiveDate())) {
077                                    this.putFieldError("leavePlan", "error.existence", "leavePlan '"
078                                                    + earnCode.getLeavePlan() + "'");
079                                    valid = false;
080                                    return valid;
081                            }
082                            
083                            if (earnCode.getEffectiveDate() != null && StringUtils.isNotBlank(earnCode.getAccrualCategory())) {
084                                    AccrualCategory myTestAccrualCategoryObj =  TkServiceLocator.getAccrualCategoryService().getAccrualCategory(earnCode.getAccrualCategory(), earnCode.getEffectiveDate());
085                                    if(myTestAccrualCategoryObj != null) {
086                                            if (!myTestAccrualCategoryObj.getLeavePlan().equals(earnCode.getLeavePlan())) {
087                                                    this.putFieldError("leavePlan", "error.leaveCode.leavePlanMismatch", myTestAccrualCategoryObj.getLeavePlan());
088                                                    valid = false;
089                                                    return valid;
090                                            }
091                                            earnCode.setLeavePlan(myTestAccrualCategoryObj.getLeavePlan());
092                                    } 
093                            }
094                    }
095                    return valid;
096            }
097            
098            @Override
099            protected boolean processCustomRouteDocumentBusinessRules(MaintenanceDocument document) {
100                    EarnCode earnCode = (EarnCode)this.getNewBo();
101                    EarnCode oldEarnCode = (EarnCode)this.getOldBo();
102                    if ((StringUtils.equals(oldEarnCode.getEarnCode(), TkConstants.LUNCH_EARN_CODE) 
103                                    || StringUtils.equals(oldEarnCode.getEarnCode(), TkConstants.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.getEffectiveDate())) {
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 = TkServiceLocator.getEarnCodeService().getNewerEarnCodeCount(earnCode.getEarnCode(), earnCode.getEffectiveDate());
137                    if(count > 0) {
138                            this.putFieldError("effectiveDate", "earncode.effectiveDate.newer.exists");
139                            return false;
140                    }
141                    
142                    // kpme-937 can not inactivation of a earn code if it used in active timeblocks
143                    List<TimeBlock> latestEndTimestampTimeBlocks =  TkServiceLocator.getTimeBlockService().getLatestEndTimestamp();
144                    
145                    if ( !earnCode.isActive() && earnCode.getEffectiveDate().before(latestEndTimestampTimeBlocks.get(0).getEndDate()) ){
146                            List<TimeBlock> activeTimeBlocks = TkServiceLocator.getTimeBlockService().getTimeBlocksWithEarnCode(earnCode.getEarnCode(), earnCode.getEffectiveDate());
147                            if(activeTimeBlocks != null && !activeTimeBlocks.isEmpty()) {
148                                    this.putFieldError("earnCode", "earncode.earncode.inactivate", earnCode.getEarnCode());
149                                    return false;
150                            }
151                    }
152                    
153                    if(!(this.validateDefaultAmountOfTime(earnCode.getDefaultAmountofTime()))) {
154                            return false;
155                    }
156                    
157                    if(earnCode.getRollupToEarnCode() != null && !StringUtils.isEmpty(earnCode.getRollupToEarnCode())) {
158                            if(!(this.validateRollupToEarnCode(earnCode.getRollupToEarnCode(), earnCode.getEffectiveDate()))) {
159                                    return false;
160                            }
161                    }
162                    
163                    if(!validateRecordMethod(earnCode.getRecordMethod(), earnCode.getAccrualCategory(), earnCode.getEffectiveDate())) {
164                            return false;
165                    }
166                    
167                    return true;
168            }
169    
170    }