001 /** 002 * Copyright 2004-2014 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.kpme.tklm.leave.timeoff.validation; 017 018 import java.math.BigDecimal; 019 020 import org.apache.commons.lang.StringUtils; 021 import org.joda.time.LocalDate; 022 import org.kuali.kpme.core.earncode.EarnCode; 023 import org.kuali.kpme.core.service.HrServiceLocator; 024 import org.kuali.kpme.core.util.HrConstants; 025 import org.kuali.kpme.core.util.ValidationUtils; 026 import org.kuali.kpme.tklm.common.LMConstants; 027 import org.kuali.kpme.tklm.leave.timeoff.SystemScheduledTimeOff; 028 import org.kuali.rice.kns.document.MaintenanceDocument; 029 import org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase; 030 import org.kuali.rice.krad.bo.PersistableBusinessObject; 031 032 public class SystemScheduledTimeOffValidation extends MaintenanceDocumentRuleBase { 033 boolean validateEffectiveDate(LocalDate effectiveDate) { 034 boolean valid = true; 035 if (effectiveDate != null && !ValidationUtils.validateOneYearFutureDate(effectiveDate)) { 036 this.putFieldError("effectiveDate", "error.date.exceed.year", "Effective Date"); 037 valid = false; 038 } 039 return valid; 040 } 041 042 boolean validateAccruedDate(LocalDate accruedDate) { 043 boolean valid = true; 044 if (accruedDate != null && !ValidationUtils.validateFutureDate(accruedDate)) { 045 this.putFieldError("accruedDate", "error.future.date", "Accrued Date"); 046 valid = false; 047 } 048 return valid; 049 } 050 051 boolean validateLocation(String location, LocalDate asOfDate) { 052 boolean valid = true; 053 if(!StringUtils.isEmpty(location) && location.equals(HrConstants.WILDCARD_CHARACTER)) { 054 return true; 055 } 056 if (!ValidationUtils.validateLocation(location, asOfDate)) { 057 this.putFieldError("location", "error.existence", "location '" 058 + location + "'"); 059 valid = false; 060 } 061 return valid; 062 } 063 064 boolean validateScheduledTimeOffDate(LocalDate scheduledTimeOffDate) { 065 boolean valid = true; 066 if (scheduledTimeOffDate!= null && !ValidationUtils.validateFutureDate(scheduledTimeOffDate)) { 067 this.putFieldError("scheduledTimeOffDate", "error.future.date", "Scheduled Time Off Date"); 068 valid = false; 069 } 070 return valid; 071 } 072 073 boolean validateUnusedTimeForScheduledTimeOffDate(LocalDate scheduledTimeOffDate, String unusedTime) { 074 boolean valid = true; 075 if (scheduledTimeOffDate == null && (StringUtils.isEmpty(unusedTime) || StringUtils.equals("T", unusedTime) || StringUtils.equals("NUTA", unusedTime))) { 076 this.putFieldError("scheduledTimeOffDate", "error.unusedtime.bank.required", LMConstants.UNUSED_TIME_MAP.get(unusedTime)); 077 valid = false; 078 } 079 return valid; 080 } 081 082 //if no unsued time allowed is selected make sure Accrued date and Schedule Time off date are equal 083 //if not throw an error 084 boolean validateNoUnusedTimeAllowed(LocalDate scheduledTimeOffDate, LocalDate accruedDate, String unusedTime) { 085 boolean valid = true; 086 if(scheduledTimeOffDate != null) { 087 if (scheduledTimeOffDate.equals(accruedDate) == false) { 088 this.putFieldError("unusedTime", "error.nounusedtimeallowed.selected", "Unused Time"); 089 valid = false; 090 } 091 } 092 return valid; 093 094 } 095 096 boolean validateTransfertoEarnCode(String transfertoEarnCode, LocalDate localDate) { 097 boolean valid = true; 098 if (StringUtils.isEmpty(transfertoEarnCode)) { 099 this.putFieldError("transfertoEarnCode", "error.required", "Transfer to Earn Code"); 100 valid = false; 101 } 102 else { 103 valid &= this.validateEarnCode(transfertoEarnCode, localDate); 104 } 105 return valid; 106 } 107 108 boolean validateTransferConversionFactor(BigDecimal transferConversionFactor) { 109 boolean valid = true; 110 if (transferConversionFactor == null) { 111 this.putFieldError("transferConversionFactor", "error.required", "Transfer Conversion Factor"); 112 valid = false; 113 } 114 return valid; 115 } 116 117 boolean validateEarnCode(String earnCode, LocalDate asOfDate) { 118 boolean valid = true; 119 if (!ValidationUtils.validateEarnCode(earnCode, asOfDate)) { 120 this.putFieldError("earnCode", "error.existence", "earnCode '" 121 + earnCode + "'"); 122 valid = false; 123 } 124 return valid; 125 } 126 127 private boolean validateFraction(String earnCode, BigDecimal amount, LocalDate asOfDate, String fieldName) { 128 boolean valid = true; 129 if (!ValidationUtils.validateEarnCodeFraction(earnCode, amount, asOfDate)) { 130 EarnCode ec = HrServiceLocator.getEarnCodeService().getEarnCode(earnCode, asOfDate); 131 if(ec != null && ec.getFractionalTimeAllowed() != null) { 132 BigDecimal fracAllowed = new BigDecimal(ec.getFractionalTimeAllowed()); 133 String[] parameters = new String[2]; 134 parameters[0] = earnCode; 135 parameters[1] = Integer.toString(fracAllowed.scale()); 136 this.putFieldError(fieldName, "error.amount.fraction", parameters); 137 valid = false; 138 } 139 } 140 return valid; 141 } 142 143 private boolean validateUnusedTime(SystemScheduledTimeOff sysSchTimeOff) { 144 boolean valid = true; 145 if(StringUtils.isNotBlank(sysSchTimeOff.getUnusedTime())) { 146 valid &= this.validateUnusedTimeForScheduledTimeOffDate(sysSchTimeOff.getScheduledTimeOffLocalDate(), sysSchTimeOff.getUnusedTime()); 147 if(StringUtils.equals(sysSchTimeOff.getUnusedTime(),LMConstants.UNUSED_TIME.TRANSFER)) { 148 valid &= this.validateTransfertoEarnCode(sysSchTimeOff.getTransfertoEarnCode(), sysSchTimeOff.getEffectiveLocalDate()); 149 valid &= this.validateTransferConversionFactor(sysSchTimeOff.getTransferConversionFactor()); 150 if(valid) { 151 // transfer to earn code is not blank, and exists. 152 // TODO: xref earn code white[black] list? Should this earn code belong to the same leave plan? 153 } 154 } 155 else if(StringUtils.equals(sysSchTimeOff.getUnusedTime(), LMConstants.UNUSED_TIME.BANK)) { 156 //TODO: do "bank" validation 157 // can there be a value specified for scheduled time off date, or must this field be left blank? 158 } 159 else if(StringUtils.equals(sysSchTimeOff.getUnusedTime(), LMConstants.UNUSED_TIME.NO_UNUSED)) { 160 valid &= this.validateNoUnusedTimeAllowed(sysSchTimeOff.getScheduledTimeOffLocalDate(), sysSchTimeOff.getAccruedLocalDate(), sysSchTimeOff.getUnusedTime()); 161 } 162 } 163 else { 164 this.putFieldError("unusedTime", "error.required", "Unused Time"); 165 valid = false; 166 } 167 return valid; 168 } 169 170 @Override 171 protected boolean processCustomRouteDocumentBusinessRules( 172 MaintenanceDocument document) { 173 boolean valid = false; 174 LOG.debug("entering custom validation for SystemScheduledTimeOff"); 175 PersistableBusinessObject pbo = (PersistableBusinessObject) this.getNewBo(); 176 if (pbo instanceof SystemScheduledTimeOff) { 177 SystemScheduledTimeOff sysSchTimeOff = (SystemScheduledTimeOff) pbo; 178 if (sysSchTimeOff != null) { 179 valid = true; 180 valid &= this.validateEffectiveDate(sysSchTimeOff.getEffectiveLocalDate()); 181 valid &= this.validateAccruedDate(sysSchTimeOff.getAccruedLocalDate()); 182 valid &= this.validateScheduledTimeOffDate(sysSchTimeOff.getScheduledTimeOffLocalDate()); 183 valid &= this.validateFraction(sysSchTimeOff.getEarnCode(),sysSchTimeOff.getAmountofTime(),sysSchTimeOff.getEffectiveLocalDate(),"amountofTime"); 184 //valid &= this.validateUnusedTimeForScheduledTimeOffDate(sysSchTimeOff.getScheduledTimeOffLocalDate(), sysSchTimeOff.getUnusedTime()); 185 valid &= this.validateUnusedTime(sysSchTimeOff); 186 //valid &= this.validateNoUnusedTimeAllowed(sysSchTimeOff.getScheduledTimeOffLocalDate(),sysSchTimeOff.getAccruedLocalDate(),sysSchTimeOff.getUnusedTime()); 187 valid &= this.validateLocation(sysSchTimeOff.getLocation(), sysSchTimeOff.getEffectiveLocalDate()); 188 valid &= this.validateEarnCode(sysSchTimeOff.getEarnCode(), sysSchTimeOff.getEffectiveLocalDate()); 189 } 190 } 191 192 return valid; 193 } 194 195 }