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.pdp.document.validation.impl;
017    
018    import java.util.Collection;
019    import java.util.HashMap;
020    import java.util.Map;
021    
022    import org.apache.commons.lang.StringUtils;
023    import org.apache.log4j.Logger;
024    import org.kuali.kfs.pdp.PdpConstants;
025    import org.kuali.kfs.pdp.PdpKeyConstants;
026    import org.kuali.kfs.pdp.PdpPropertyConstants;
027    import org.kuali.kfs.pdp.businessobject.CustomerBank;
028    import org.kuali.kfs.pdp.businessobject.CustomerProfile;
029    import org.kuali.kfs.sys.context.SpringContext;
030    import org.kuali.rice.kns.bo.PersistableBusinessObject;
031    import org.kuali.rice.kns.document.MaintenanceDocument;
032    import org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase;
033    import org.kuali.rice.kns.service.BusinessObjectService;
034    import org.kuali.rice.kns.util.GlobalVariables;
035    import org.kuali.rice.kns.util.KNSConstants;
036    import org.kuali.rice.kns.util.MessageMap;
037    
038    public class CustomerProfileRule extends MaintenanceDocumentRuleBase {
039        protected static Logger LOG = org.apache.log4j.Logger.getLogger(CustomerProfileRule.class);
040    
041        /**
042         * @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#processCustomAddCollectionLineBusinessRules(org.kuali.rice.kns.document.MaintenanceDocument, java.lang.String, org.kuali.rice.kns.bo.PersistableBusinessObject)
043         */
044        @Override
045        public boolean processCustomAddCollectionLineBusinessRules(MaintenanceDocument document, String collectionName, PersistableBusinessObject line) {
046            boolean isValid = true;
047            isValid &= super.processCustomAddCollectionLineBusinessRules(document, collectionName, line);
048            MessageMap errorMap = GlobalVariables.getMessageMap();
049            isValid &= errorMap.isEmpty();
050    
051            if (isValid) {
052                if (collectionName.equals(PdpPropertyConstants.CustomerProfile.CUSTOMER_PROFILE_BANKS)) {
053                    CustomerBank newCustomerBank = (CustomerBank) line;
054    
055                    CustomerProfile customerProfile = (CustomerProfile) document.getNewMaintainableObject().getBusinessObject();
056                    for (CustomerBank bank : customerProfile.getCustomerBanks()) {
057                        if (bank.getDisbursementTypeCode().equalsIgnoreCase(newCustomerBank.getDisbursementTypeCode())) {
058                            errorMap.putError( PdpPropertyConstants.DISBURSEMENT_TYPE_CODE, PdpKeyConstants.ERROR_ONE_BANK_PER_DISBURSEMENT_TYPE_CODE);
059                            isValid = false;
060                        }
061                    }
062                }
063            }
064            return isValid;
065        }
066        
067        /**
068         * KFSMI-3771
069         * This method checks if the Disbursement Bank information is provided in the Customer profile.
070         * If Bank information is provided; It's required that a Check bank is present.
071         * If the Customer profile has ACH disbursement type information provided, it should have an ACH bank Information as well.
072         * @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#processCustomRouteDocumentBusinessRules(org.kuali.rice.kns.document.MaintenanceDocument)
073         * @param MaintenanceDocument  - CustomerProfileMaintenanceDocument
074         * @return boolean - true if business rules are satisfied; false otherwise.
075         */    
076        @Override
077        protected boolean processCustomRouteDocumentBusinessRules(MaintenanceDocument document) {
078            boolean isValid =true;
079            isValid &= super.processCustomRouteDocumentBusinessRules(document);
080            
081            CustomerProfile customerProfile = (CustomerProfile) document.getNewMaintainableObject().getBusinessObject();
082            
083            boolean checkBankPresent = false;
084            boolean ACHBankPresent = false;
085            
086            //Check if the customer profile has ACH transaction type information present.
087            boolean customerHasACHType = customerProfile.getAchTransactionType() != null ? true : false;       
088            
089            //Check if customer profile has bank information
090            if (customerProfile.getCustomerBanks().isEmpty()){
091                putFieldError(KNSConstants.MAINTENANCE_ADD_PREFIX+"customerBanks."+PdpPropertyConstants.DISBURSEMENT_TYPE_CODE, PdpKeyConstants.Format.ErrorMessages.ERROR_FORMAT_BANK_MISSING, customerProfile.getId().toString());
092                
093                isValid = false;
094            }else{
095                for (CustomerBank bank : customerProfile.getCustomerBanks()){
096                    
097                    //Check if customer profile has Check type Bank information
098                    if(bank.getDisbursementTypeCode().equalsIgnoreCase(PdpConstants.DisbursementTypeCodes.CHECK)){
099                        checkBankPresent = true;
100                    }                 
101                    //Check if customer profile has ACH type Bank information 
102                    if(bank.getDisbursementTypeCode().equalsIgnoreCase(PdpConstants.DisbursementTypeCodes.ACH)){
103                            ACHBankPresent = true;
104                     }                 
105                    if(checkBankPresent && ACHBankPresent){
106                        break;
107                    }            
108                }
109                
110                //Generate error message if check bank is not present.
111                if(!checkBankPresent){
112                    isValid = false;
113                    putFieldError(KNSConstants.MAINTENANCE_ADD_PREFIX+"customerBanks."+PdpPropertyConstants.DISBURSEMENT_TYPE_CODE, PdpKeyConstants.ERROR_PDP_CHECK_BANK_REQUIRED);
114                }
115                
116                //Generate error message if ACH bank is not present for profile with ACH disbursement type.
117                if(customerHasACHType && !ACHBankPresent){
118                    isValid = false;
119                    putFieldError(KNSConstants.MAINTENANCE_ADD_PREFIX+"customerBanks."+PdpPropertyConstants.DISBURSEMENT_TYPE_CODE, PdpKeyConstants.ERROR_PDP_ACH_BANK_REQUIRED); 
120                }
121                
122            }
123            
124            // KFSMI-5158 Uniqueness check only for new Customer Profiles 
125            if (document.isNew()) { 
126                isValid &= verifyChartUnitSubUnitIsUnique(customerProfile); 
127            }
128            
129            return isValid;
130        } 
131        
132        /**
133         * Verifies that the chart/unit/sub-unit combination on this customer profile is unique
134         * @param customerProfile the customer profile to check
135         * @return true if the chart/unit/sub-unit is unique, false otherwise
136         */
137        protected boolean verifyChartUnitSubUnitIsUnique(CustomerProfile customerProfile) {
138            boolean result = true;
139            
140            if (!StringUtils.isBlank(customerProfile.getChartCode()) && !StringUtils.isBlank(customerProfile.getUnitCode()) && !StringUtils.isBlank(customerProfile.getSubUnitCode())) {
141                final BusinessObjectService businessObjectService = SpringContext.getBean(BusinessObjectService.class);
142                Map<String, Object> searchKeys = new HashMap<String, Object>();
143                searchKeys.put(PdpPropertyConstants.CustomerProfile.CUSTOMER_PROFILE_CHART_CODE, customerProfile.getChartCode());
144                searchKeys.put(PdpPropertyConstants.CustomerProfile.CUSTOMER_PROFILE_UNIT_CODE, customerProfile.getUnitCode());
145                searchKeys.put(PdpPropertyConstants.CustomerProfile.CUSTOMER_PROFILE_SUB_UNIT_CODE, customerProfile.getSubUnitCode());
146                
147                final Collection foundCustomerProfiles = businessObjectService.findMatching(CustomerProfile.class, searchKeys);
148                if (foundCustomerProfiles != null && foundCustomerProfiles.size() > 0) {
149                    result = false;
150                    putFieldError(PdpPropertyConstants.CustomerProfile.CUSTOMER_PROFILE_UNIT_CODE, PdpKeyConstants.ERROR_CUSTOMER_PROFILE_CHART_UNIT_SUB_UNIT_NOT_UNIQUE, new String[] { customerProfile.getChartCode(), customerProfile.getUnitCode(), customerProfile.getSubUnitCode()});
151                }
152            }
153            
154            return result;
155        }
156        
157    }