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;
017    
018    import java.util.Iterator;
019    import java.util.List;
020    import java.util.Map;
021    
022    import org.apache.log4j.Logger;
023    import org.kuali.kfs.coa.businessobject.Account;
024    import org.kuali.kfs.coa.service.AccountPersistenceStructureService;
025    import org.kuali.kfs.coa.service.AccountService;
026    import org.kuali.kfs.sys.KFSPropertyConstants;
027    import org.kuali.kfs.sys.context.SpringContext;
028    import org.kuali.rice.kns.bo.BusinessObject;
029    import org.kuali.rice.kns.bo.PersistableBusinessObject;
030    import org.kuali.rice.kns.document.MaintenanceDocument;
031    import org.kuali.rice.kns.maintenance.KualiMaintainableImpl;
032    import org.kuali.rice.kns.maintenance.Maintainable;
033    import org.kuali.rice.kns.util.ObjectUtils;
034    
035    /**
036     * This class...
037     */
038    public class FinancialSystemMaintainable extends KualiMaintainableImpl {
039        private static final Logger LOG = Logger.getLogger(FinancialSystemMaintainable.class);
040        
041        /**
042         * Constructs a FinancialSystemMaintainable
043         */
044        public FinancialSystemMaintainable() {
045            super();
046        }
047        
048        /**
049         * Constructs a FinancialSystemMaintainable, allowing the PersistableBusinessObject from KualiMaintainableImpl
050         * to be inherited
051         * @param businessObject a business object to set
052         */
053        public FinancialSystemMaintainable(PersistableBusinessObject businessObject) {
054            super(businessObject);
055        }
056    
057        /**
058         * 
059         * @param nodeName
060         * @return
061         * @throws UnsupportedOperationException
062         */
063        protected boolean answerSplitNodeQuestion(String nodeName) throws UnsupportedOperationException {
064            throw new UnsupportedOperationException("FinancialSystemMaintainable does not implement the answerSplitNodeQuestion method. Node name specified was: " + nodeName);
065            
066        }
067        
068        /**
069         * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#refreshReferences(String)
070         */
071        @Override
072        protected void refreshReferences(String referencesToRefresh) {
073            // if accounts can't cross charts, populate chart code fields according to corresponding account number fields
074            if (!SpringContext.getBean(AccountService.class).accountsCanCrossCharts()) {
075                populateChartOfAccountsCodeFields();            
076            }
077            
078            super.refreshReferences(referencesToRefresh);
079        }
080        
081        /**
082         * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#processAfterAddLine(String)
083         */
084        @Override
085        //public void processAfterAddLine(String colName, Class colClass) {
086        public void processBeforeAddLine(String colName, Class colClass, BusinessObject bo) {
087            //super.processAfterAddLine(colName, colClass);
088            super.processBeforeAddLine(colName, colClass, bo);
089            
090            // if accounts can't cross charts, populate chart code fields according to corresponding account number fields
091            if (!SpringContext.getBean(AccountService.class).accountsCanCrossCharts()) {
092                populateChartOfAccountsCodeFields();            
093            }
094        }
095    
096        /**
097         * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#processAfterPost(String)
098         */
099        @Override
100        public void processAfterPost(MaintenanceDocument document, Map<String, String[]> parameters) {
101            super.processAfterPost(document, parameters);
102    
103            // if accounts can't cross charts, populate chart code fields according to corresponding account number fields
104            if (!SpringContext.getBean(AccountService.class).accountsCanCrossCharts()) {
105                populateChartOfAccountsCodeFields();            
106            }
107        }
108        
109        /**
110         * Populates all chartOfAccountsCode fields according to corresponding accountNumber fields in this BO.  
111         * The chartOfAccountsCode-accountNumber pairs are (part of) the FKs for the reference accounts in this BO.    
112         */
113        protected void populateChartOfAccountsCodeFields() {
114            AccountService acctService = SpringContext.getBean(AccountService.class);
115            AccountPersistenceStructureService apsService = SpringContext.getBean(AccountPersistenceStructureService.class);
116     
117            // non-collection reference accounts 
118            PersistableBusinessObject bo = getBusinessObject();        
119            Iterator<Map.Entry<String, String>> chartAccountPairs = apsService.listChartCodeAccountNumberPairs(bo).entrySet().iterator();        
120            while (chartAccountPairs.hasNext()) {
121                Map.Entry<String, String> entry = (Map.Entry<String, String>)chartAccountPairs.next();
122                String coaCodeName = entry.getKey();            
123                String acctNumName = entry.getValue(); 
124                String accountNumber = (String)ObjectUtils.getPropertyValue(bo, acctNumName);
125                String coaCode = null;
126                Account account = acctService.getUniqueAccountForAccountNumber(accountNumber);            
127                if (ObjectUtils.isNotNull(account)) {
128                    coaCode = account.getChartOfAccountsCode();
129                }
130                try {
131                    ObjectUtils.setObjectProperty(bo, coaCodeName, coaCode); 
132                }
133                catch (Exception e) {
134                    LOG.error("Error in setting property value for " + coaCodeName,e);
135                }
136            }
137            
138            // collection reference accounts         
139            Iterator<Map.Entry<String, Class>> accountColls = apsService.listCollectionAccountFields(bo).entrySet().iterator();        
140            while (accountColls.hasNext()) {
141                Map.Entry<String, Class> entry = (Map.Entry<String, Class>)accountColls.next();
142                String accountCollName = entry.getKey();
143                PersistableBusinessObject newAccount = getNewCollectionLine(accountCollName);
144                
145                // here we can use hard-coded chartOfAccountsCode and accountNumber field name 
146                // since all reference account types do follow the standard naming pattern        
147                String accountNumber = (String)ObjectUtils.getPropertyValue(newAccount, KFSPropertyConstants.ACCOUNT_NUMBER);            
148                String coaCode = null;
149                Account account = acctService.getUniqueAccountForAccountNumber(accountNumber);            
150                if (ObjectUtils.isNotNull(account)) {
151                    coaCode = account.getChartOfAccountsCode();
152                    try {
153                        ObjectUtils.setObjectProperty(newAccount, KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, coaCode); 
154                    }
155                    catch (Exception e) {
156                        LOG.error("Error in setting chartOfAccountsCode property value in account collection " + accountCollName,e);
157                    }
158                }
159            }
160        }
161        
162        /**
163         * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#getSections(MaintenanceDocument,Maintainable)
164         *
165        @Override
166        public List getSections(MaintenanceDocument document, Maintainable oldMaintainable) {
167            // if accounts can't cross charts, populate chart code fields according to corresponding account number fields
168            if (!SpringContext.getBean(AccountService.class).accountsCanCrossCharts()) {
169                populateChartOfAccountsCodeFields();            
170            }
171            
172            return super.getSections(document, oldMaintainable);
173        }
174        */
175            
176    }