/* * The Kuali Financial System, a comprehensive financial management system for higher education. * * Copyright 2005-2014 The Kuali Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.kuali.kfs.module.tem.document.validation.impl; import java.math.BigDecimal; import java.util.Calendar; import org.apache.commons.lang.StringUtils; import org.kuali.kfs.module.tem.TemConstants; import org.kuali.kfs.module.tem.TemKeyConstants; import org.kuali.kfs.module.tem.TemPropertyConstants; import org.kuali.kfs.module.tem.businessobject.MileageRate; import org.kuali.kfs.module.tem.document.service.MileageRateService; import org.kuali.kfs.sys.context.SpringContext; import org.kuali.kfs.sys.util.KfsDateUtils; import org.kuali.rice.core.api.datetime.DateTimeService; import org.kuali.rice.kns.document.MaintenanceDocument; import org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase; import org.kuali.rice.krad.util.ObjectUtils; /** * Rules for the mileage rate maintenance document */ public class MileageRateRule extends MaintenanceDocumentRuleBase { /** * Performs extra checks on the rate and expense type but only ever succeeds * @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#processCustomSaveDocumentBusinessRules(org.kuali.rice.kns.document.MaintenanceDocument) */ @Override protected boolean processCustomSaveDocumentBusinessRules(MaintenanceDocument document) { super.processCustomSaveDocumentBusinessRules(document); final MileageRate mileageRate = (MileageRate)document.getNewMaintainableObject().getBusinessObject(); checkRate(mileageRate); checkDuplicateMileageRate(mileageRate); checkExpenseType(mileageRate); checkActiveToDate(mileageRate); return true; } /** * Performs extra checks on the rate and expense type, which will help determine the result * @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#processCustomRouteDocumentBusinessRules(org.kuali.rice.kns.document.MaintenanceDocument) */ @Override protected boolean processCustomRouteDocumentBusinessRules(MaintenanceDocument document) { boolean result = super.processCustomRouteDocumentBusinessRules(document); final MileageRate mileageRate = (MileageRate)document.getNewMaintainableObject().getBusinessObject(); result &= checkRate(mileageRate); checkDuplicateMileageRate(mileageRate); result &= checkExpenseType(mileageRate); result &= checkActiveToDate(mileageRate); return result; } /** * Checks that the rate on the proposed record is positive * @param mileageRate the mileage rate to check * @return true if the rate rules were passed, false if errors were found */ protected boolean checkRate(MileageRate mileageRate) { boolean success = true; if (mileageRate.getRate() != null) { if (mileageRate.getRate().compareTo(BigDecimal.ZERO) < 0) { putFieldError(TemPropertyConstants.RATE, TemKeyConstants.ERROR_DOCUMENT_MILEAGE_RATE_INVALID_RATE); success = false; } } return success; } /** * Checks that the expense type on the proposed record has mileage as the metacategory * @param mileageRate the mileage rate to check * @return true if the expense type rules were passed, false if errors were found */ protected boolean checkExpenseType(MileageRate mileageRate) { boolean success = true; if (!StringUtils.isBlank(mileageRate.getExpenseTypeCode())) { mileageRate.refreshReferenceObject(TemPropertyConstants.EXPENSE_TYPE); if (!ObjectUtils.isNull(mileageRate.getExpenseType()) && !TemConstants.ExpenseTypeMetaCategory.MILEAGE.getCode().equals(mileageRate.getExpenseType().getExpenseTypeMetaCategoryCode())) { putFieldError(TemPropertyConstants.EXPENSE_TYPE_CODE, TemKeyConstants.ERROR_DOCUMENT_MILEAGE_RATE_INVALID_EXPENSE_TYPE, new String[] { mileageRate.getExpenseTypeCode() }); success = false; } } return success; } /** * Checks that the mileage rates with effective dates overlap with existing mileage rate record for the same mileage code type * * @param mileageRate * @return true if the overlap rule were passed , false otherwise. */ protected boolean checkDuplicateMileageRate(MileageRate mileageRate) { mileageRate.getActiveFromDate(); mileageRate.getActiveToDate(); MileageRate matchedRecord = SpringContext.getBean(MileageRateService.class).getMileageRateByExpenseTypeCode(mileageRate); if(ObjectUtils.isNotNull(matchedRecord)) { String fromDate = SpringContext.getBean(DateTimeService.class).toDateString(matchedRecord.getActiveFromDate()); String toDate = SpringContext.getBean(DateTimeService.class).toDateString(matchedRecord.getActiveToDate()); putFieldError(TemPropertyConstants.ACTIVE_FROM_DATE, TemKeyConstants.ERROR_DOCUMENT_MILEAGE_RATE_INVALID_EFFECTIVE_DATE, new String[] { mileageRate.getExpenseTypeCode(),fromDate, toDate }); return false; } return true; } /** * Verifies that the effective to date on the mileage rate is not set to any day earlier than today * @param mileageRate the mileage rate to check * @return true if the effective date is null or set to today or in the future; false otherwise */ protected boolean checkActiveToDate(MileageRate mileageRate) { if (mileageRate.getActiveToDate() == null) { return true; } final DateTimeService dateTimeService = SpringContext.getBean(DateTimeService.class); final Calendar today = dateTimeService.getCurrentCalendar(); Calendar activeToDate = Calendar.getInstance(); activeToDate.setTimeInMillis(mileageRate.getActiveToDate().getTime()); if (!KfsDateUtils.isSameDay(today, activeToDate) && activeToDate.compareTo(today) < 0) { putFieldError(TemPropertyConstants.ACTIVE_TO_DATE, TemKeyConstants.ERROR_DOCUMENT_MILEAGE_RATE_INVALID_ACTIVE_TO_DATE, new String[] {dateTimeService.toDateString(mileageRate.getActiveToDate())}); return false; } return true; } }