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