001    /*
002     * Copyright 2011 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.kfs.sys.document.validation.impl;
017    
018    import java.util.Collection;
019    import java.util.Collections;
020    import java.util.HashMap;
021    import java.util.Map;
022    
023    import org.apache.commons.lang.StringUtils;
024    import org.kuali.kfs.sys.KFSKeyConstants;
025    import org.kuali.kfs.sys.KFSPropertyConstants;
026    import org.kuali.kfs.sys.businessobject.Bank;
027    import org.kuali.kfs.sys.context.SpringContext;
028    import org.kuali.kfs.sys.service.BankService;
029    import org.kuali.rice.kns.document.MaintenanceDocument;
030    import org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase;
031    
032    /**
033     * Evaluates business rules for editing or creation of a new bank record.
034     */
035    public class BankRule extends MaintenanceDocumentRuleBase {
036        protected Bank oldBank;
037        protected Bank newBank;
038    
039        /**
040         * @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#processCustomRouteDocumentBusinessRules(org.kuali.rice.kns.document.MaintenanceDocument)
041         */
042        protected boolean processCustomRouteDocumentBusinessRules(MaintenanceDocument document) {
043            // default to success
044            boolean valid = true;
045    
046            valid &= checkPartiallyFilledOutReferences();
047            valid &= validateFieldsForBankOffsetEntries();
048            valid &= validateBankAccountNumber();
049    
050            return valid;
051        }
052    
053        /**
054         * Sets the convenience objects like newAccount and oldAccount, so you have short and easy handles to the new and old objects
055         * contained in the maintenance document. It also calls the BusinessObjectBase.refresh(), which will attempt to load all
056         * sub-objects from the DB by their primary keys, if available.
057         */
058        public void setupConvenienceObjects() {
059            oldBank = (Bank) super.getOldBo();
060            newBank = (Bank) super.getNewBo();
061        }
062    
063        /**
064         * Checks for partially filled out objects.
065         * 
066         * @return true if there are no partially filled out references
067         */
068        protected boolean checkPartiallyFilledOutReferences() {
069            boolean valid = true;
070    
071            valid &= checkForPartiallyFilledOutReferenceForeignKeys(KFSPropertyConstants.CASH_OFFSET_ACCOUNT);
072            valid &= checkForPartiallyFilledOutReferenceForeignKeys(KFSPropertyConstants.CASH_OFFSET_OBJECT);
073    
074            return valid;
075        }
076    
077        /**
078         * Checks system parameter to determine if the bank code functionality is enabled. If so verifies the cash offset fields needed
079         * to create the additional bank entries were given.
080         * 
081         * @return true if all cash offset fields needed have value
082         */
083        protected boolean validateFieldsForBankOffsetEntries() {
084            boolean valid = true;
085    
086            if (SpringContext.getBean(BankService.class).isBankSpecificationEnabled()) {
087    
088                if (StringUtils.isBlank(newBank.getCashOffsetAccountNumber())) {
089                    putFieldError(KFSPropertyConstants.CASH_OFFSET_ACCOUNT_NUMBER, KFSKeyConstants.Bank.ERROR_MISSING_CASH_ACCOUNT_NUMBER);
090                    valid = false;
091                }
092        
093                if (StringUtils.isBlank(newBank.getCashOffsetObjectCode())) {
094                    putFieldError(KFSPropertyConstants.CASH_OFFSET_OBJECT_CODE, KFSKeyConstants.Bank.ERROR_MISSING_CASH_OBJECT_CODE);
095                    valid = false;
096                }
097            }
098    
099            return valid;
100        }
101        
102        /**
103         * Bank account number must be unique.
104         * 
105         * @return
106         */
107        protected boolean validateBankAccountNumber() {
108            // if the new bank is not blank *AND* has been changed
109            // (I.e, never fire this edit if the account has not been changed)
110            if ( StringUtils.isNotBlank(newBank.getBankAccountNumber() )
111                    && (oldBank == null ||
112                             !StringUtils.equals(oldBank.getBankAccountNumber(), newBank.getBankAccountNumber())) ) {
113                @SuppressWarnings("rawtypes")
114                Collection existingBanks = getBoService().findMatching(Bank.class, Collections.singletonMap(KFSPropertyConstants.BANK_ACCOUNT_NUMBER, newBank.getBankAccountNumber()));
115                if ( existingBanks != null && !existingBanks.isEmpty() ) {
116                    putFieldError(KFSPropertyConstants.BANK_ACCOUNT_NUMBER, KFSKeyConstants.Bank.ERROR_ACCOUNT_NUMBER_NOT_UNIQUE);
117                    return false;
118                }
119            }
120            return true;        
121        }
122    }