/* * 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.cam.document.validation.impl; import java.sql.Date; import java.util.ArrayList; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.List; import org.apache.commons.lang.StringUtils; import org.kuali.kfs.module.cam.CamsConstants; import org.kuali.kfs.module.cam.CamsKeyConstants; import org.kuali.kfs.module.cam.CamsPropertyConstants; import org.kuali.kfs.module.cam.businessobject.Asset; import org.kuali.kfs.module.cam.document.EquipmentLoanOrReturnDocument; import org.kuali.kfs.module.cam.service.AssetLockService; import org.kuali.kfs.sys.KFSConstants; import org.kuali.kfs.sys.context.SpringContext; import org.kuali.kfs.sys.util.KfsDateUtils; import org.kuali.rice.kns.rules.TransactionalDocumentRuleBase; import org.kuali.rice.krad.document.Document; import org.kuali.rice.krad.service.BusinessObjectService; import org.kuali.rice.krad.util.GlobalVariables; import org.kuali.rice.krad.util.ObjectUtils; import org.kuali.rice.location.api.state.StateContract; public class EquipmentLoanOrReturnDocumentRule extends TransactionalDocumentRuleBase { private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(EquipmentLoanOrReturnDocumentRule.class); private AssetLockService assetLockService; /** * Retrieve asset number need to be locked. * * @param document * @return */ protected List<Long> retrieveAssetNumberForLocking(Document document) { EquipmentLoanOrReturnDocument equipmentLoanOrReturnDocument = (EquipmentLoanOrReturnDocument) document; List<Long> assetNumbers = new ArrayList<Long>(); if (equipmentLoanOrReturnDocument.getCapitalAssetNumber() != null) { assetNumbers.add(equipmentLoanOrReturnDocument.getCapitalAssetNumber()); } return assetNumbers; } /** * @see org.kuali.rice.krad.rules.DocumentRuleBase#processCustomRouteDocumentBusinessRules(org.kuali.rice.krad.document.Document) */ @Override protected boolean processCustomRouteDocumentBusinessRules(Document document) { if (!super.processCustomRouteDocumentBusinessRules(document)) { return false; } EquipmentLoanOrReturnDocument equipmentLoanOrReturnDocument = (EquipmentLoanOrReturnDocument) document; boolean valid = processValidation(equipmentLoanOrReturnDocument); // check if asset is locked by other document and display error message when save valid &= !getAssetLockService().isAssetLocked(retrieveAssetNumberForLocking(document), CamsConstants.DocumentTypeName.ASSET_EQUIPMENT_LOAN_OR_RETURN, document.getDocumentNumber()); return valid; } /** * This method applies business rules * * @param document equipmentLoanOrReturnDocument Document * @return true if all rules are pass */ protected boolean processValidation(EquipmentLoanOrReturnDocument equipmentLoanOrReturnDocument) { boolean valid = true; if (equipmentLoanOrReturnDocument.getBorrowerPerson() == null) { valid &= false; GlobalVariables.getMessageMap().putError(KFSConstants.DOCUMENT_PROPERTY_NAME + "." + CamsPropertyConstants.EquipmentLoanOrReturnDocument.BORROWER_PRINCIPAL_NAME, CamsKeyConstants.EquipmentLoanOrReturn.ERROR_INVALID_BORROWER_ID); } // validate campus tag number valid &= validateTagNumber(equipmentLoanOrReturnDocument); // validate both loan return date and expected loan return date valid &= validateLoanDate(equipmentLoanOrReturnDocument); // validate borrower and storage state codes valid &= validStateZipCode(equipmentLoanOrReturnDocument); return valid; } /** * Validate that the campus tag number exists prior to submitting a loan. * * @param equipmentLoanOrReturnDocument * @return boolean false if the campus tag number does not exist */ protected boolean validateTagNumber(EquipmentLoanOrReturnDocument equipmentLoanOrReturnDocument) { boolean valid = true; HashMap<String, Long> map = new HashMap<String, Long>(); map.put(CamsPropertyConstants.EquipmentLoanOrReturnDocument.CAPITAL_ASSET_NUMBER, equipmentLoanOrReturnDocument.getCapitalAssetNumber()); Asset asset = SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(Asset.class, map); if (asset.getCampusTagNumber() == null) { valid &= false; GlobalVariables.getMessageMap().putError(KFSConstants.DOCUMENT_PROPERTY_NAME + "." + CamsPropertyConstants.Asset.CAMPUS_TAG_NUMBER, CamsKeyConstants.EquipmentLoanOrReturn.ERROR_CAMPUS_TAG_NUMBER_REQUIRED); } return valid; } /** * Implementation of the rule that if a document has a valid expect loan date and loan return date, the both dates should come * before the 2 years limit. * * @param equipmentLoanOrReturnDocument the equipmentLoanOrReturn document to be validated * @return boolean false if the expect loan date or loan return date is not before the 2 years limit. */ protected boolean validateLoanDate(EquipmentLoanOrReturnDocument equipmentLoanOrReturnDocument) { boolean valid = true; Date loanDate = KfsDateUtils.clearTimeFields(equipmentLoanOrReturnDocument.getLoanDate()); Calendar cal = GregorianCalendar.getInstance(); cal.setTime(loanDate); cal.add(Calendar.YEAR, 2); Date maxDate = new Date(cal.getTime().getTime()); // Loan can not be before today Date loanReturnDate = equipmentLoanOrReturnDocument.getLoanReturnDate(); if (equipmentLoanOrReturnDocument.isNewLoan() && loanDate.before(KfsDateUtils.clearTimeFields(new java.util.Date()))) { GlobalVariables.getMessageMap().putError(KFSConstants.DOCUMENT_PROPERTY_NAME + "." + CamsPropertyConstants.EquipmentLoanOrReturnDocument.LOAN_DATE, CamsKeyConstants.EquipmentLoanOrReturn.ERROR_INVALID_LOAN_DATE); } // expect return date must be >= loan date and within 2 years limit Date expectReturnDate = equipmentLoanOrReturnDocument.getExpectedReturnDate(); if (expectReturnDate != null) { KfsDateUtils.clearTimeFields(expectReturnDate); if (expectReturnDate.before(loanDate)) { valid &= false; GlobalVariables.getMessageMap().putError(KFSConstants.DOCUMENT_PROPERTY_NAME + "." + CamsPropertyConstants.EquipmentLoanOrReturnDocument.EXPECTED_RETURN_DATE, CamsKeyConstants.EquipmentLoanOrReturn.ERROR_INVALID_EXPECTED_RETURN_DATE); } if (maxDate.before(expectReturnDate)) { valid &= false; GlobalVariables.getMessageMap().putError(KFSConstants.DOCUMENT_PROPERTY_NAME + "." + CamsPropertyConstants.EquipmentLoanOrReturnDocument.EXPECTED_RETURN_DATE, CamsKeyConstants.EquipmentLoanOrReturn.ERROR_INVALID_EXPECTED_MAX_DATE); } } // loan return date must be >= loan date and within 2 years limit if (loanReturnDate != null) { KfsDateUtils.clearTimeFields(loanReturnDate); if (loanDate.after(loanReturnDate) || maxDate.before(loanReturnDate)) { valid &= false; GlobalVariables.getMessageMap().putError(KFSConstants.DOCUMENT_PROPERTY_NAME + "." + CamsPropertyConstants.EquipmentLoanOrReturnDocument.LOAN_RETURN_DATE, CamsKeyConstants.EquipmentLoanOrReturn.ERROR_INVALID_LOAN_RETURN_DATE); } } return valid; } /** * Implementation of the rule that if borrower and storage state codes are valid * * @param equipmentLoanOrReturnDocument the equipmentLoanOrReturn document to be validated * @return boolean false if the borrower or storage state code is not valid */ protected boolean validStateZipCode(EquipmentLoanOrReturnDocument equipmentLoanOrReturnDocument) { boolean valid = true; // validate borrower state and postal zip code if (StringUtils.isBlank(equipmentLoanOrReturnDocument.getBorrowerCountryCode())) { equipmentLoanOrReturnDocument.setBorrowerCountryCode(KFSConstants.COUNTRY_CODE_UNITED_STATES); } if (equipmentLoanOrReturnDocument.getBorrowerCountryCode().equals(KFSConstants.COUNTRY_CODE_UNITED_STATES)) { StateContract borrowStateCode = equipmentLoanOrReturnDocument.getBorrowerState(); if (ObjectUtils.isNull(borrowStateCode)) { GlobalVariables.getMessageMap().putError(KFSConstants.DOCUMENT_PROPERTY_NAME + "." + CamsPropertyConstants.EquipmentLoanOrReturnDocument.BORROWER_STATE_CODE, CamsKeyConstants.EquipmentLoanOrReturn.ERROR_INVALID_BORROWER_STATE, equipmentLoanOrReturnDocument.getBorrowerStateCode()); valid &= false; } } // validate borrower storage state and postal zip code if (StringUtils.isNotBlank(equipmentLoanOrReturnDocument.getBorrowerStorageStateCode())) { if (StringUtils.isBlank(equipmentLoanOrReturnDocument.getBorrowerStorageCountryCode())) { equipmentLoanOrReturnDocument.setBorrowerStorageCountryCode(KFSConstants.COUNTRY_CODE_UNITED_STATES); } } String storageCountryCode = equipmentLoanOrReturnDocument.getBorrowerStorageCountryCode(); String storageAddress = equipmentLoanOrReturnDocument.getBorrowerStorageAddress(); if (StringUtils.isNotBlank(storageAddress)&& StringUtils.isNotBlank(storageCountryCode) && storageCountryCode.equals(KFSConstants.COUNTRY_CODE_UNITED_STATES)){ if (StringUtils.isBlank(equipmentLoanOrReturnDocument.getBorrowerStorageStateCode())) { GlobalVariables.getMessageMap().putError(KFSConstants.DOCUMENT_PROPERTY_NAME + "." + CamsPropertyConstants.EquipmentLoanOrReturnDocument.BORROWER_STAORAGE_STATE_CODE, CamsKeyConstants.EquipmentLoanOrReturn.ERROR_BORROWER_STORAGE_STATE_REQUIRED, equipmentLoanOrReturnDocument.getBorrowerCountryCode()); valid = false; } else { StateContract borrowStorageStateCode = equipmentLoanOrReturnDocument.getBorrowerStorageState(); if (ObjectUtils.isNull(borrowStorageStateCode)) { GlobalVariables.getMessageMap().putError(KFSConstants.DOCUMENT_PROPERTY_NAME + "." + CamsPropertyConstants.EquipmentLoanOrReturnDocument.BORROWER_STAORAGE_STATE_CODE, CamsKeyConstants.EquipmentLoanOrReturn.ERROR_INVALID_BORROWER_STORAGE_STATE, equipmentLoanOrReturnDocument.getBorrowerStorageStateCode()); valid = false; } } if (StringUtils.isBlank(equipmentLoanOrReturnDocument.getBorrowerStorageZipCode())) { GlobalVariables.getMessageMap().putError(KFSConstants.DOCUMENT_PROPERTY_NAME + "." + CamsPropertyConstants.EquipmentLoanOrReturnDocument.BORROWER_STORAGE_ZIP_CODE, CamsKeyConstants.EquipmentLoanOrReturn.ERROR_BORROWER_STORAGE_ZIP_REQUIRED, equipmentLoanOrReturnDocument.getBorrowerCountryCode()); valid = false; } } return valid; } public AssetLockService getAssetLockService() { if (this.assetLockService == null) { this.assetLockService = SpringContext.getBean(AssetLockService.class); } return assetLockService; } }