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.coa.document;
017    
018    import java.util.Map;
019    
020    import org.apache.commons.lang.StringUtils;
021    import org.apache.log4j.Logger;
022    import org.kuali.kfs.coa.businessobject.A21SubAccount;
023    import org.kuali.kfs.coa.businessobject.Account;
024    import org.kuali.kfs.coa.businessobject.SubAccount;
025    import org.kuali.kfs.coa.service.A21SubAccountService;
026    import org.kuali.kfs.coa.service.AccountService;
027    import org.kuali.kfs.sys.KFSConstants;
028    import org.kuali.kfs.sys.KFSPropertyConstants;
029    import org.kuali.kfs.sys.context.SpringContext;
030    import org.kuali.kfs.sys.document.FinancialSystemMaintainable;
031    import org.kuali.rice.kim.bo.Person;
032    import org.kuali.rice.kns.bo.PersistableBusinessObject;
033    import org.kuali.rice.kns.document.MaintenanceDocument;
034    import org.kuali.rice.kns.document.authorization.MaintenanceDocumentRestrictions;
035    import org.kuali.rice.kns.util.GlobalVariables;
036    import org.kuali.rice.kns.util.ObjectUtils;
037    
038    /**
039     * This class...
040     */
041    public class SubAccountMaintainableImpl extends FinancialSystemMaintainable {
042        private static final Logger LOG = Logger.getLogger(SubAccountMaintainableImpl.class);
043    
044        // account fields that are PKs of nested reference accounts but don't exist in the Sub-Account BO as FKs.
045        public static final String[] COA_CODE_NAMES = {        
046            KFSPropertyConstants.A21_SUB_ACCOUNT + "." + KFSPropertyConstants.COST_SHARE_SOURCE_CHART_OF_ACCOUNTS_CODE, 
047            KFSPropertyConstants.A21_SUB_ACCOUNT + "." + KFSPropertyConstants.INDIRECT_COST_RECOVERY_CHART_OF_ACCOUNTS_CODE,
048        };
049        public static final String[] ACCOUNT_NUMBER_NAMES = {        
050            KFSPropertyConstants.A21_SUB_ACCOUNT + "." + KFSPropertyConstants.COST_SHARE_SOURCE_ACCOUNT_NUMBER, 
051            KFSPropertyConstants.A21_SUB_ACCOUNT + "." + KFSPropertyConstants.INDIRECT_COST_RECOVERY_ACCOUNT_NUMBER,
052        };
053    
054        /**
055         * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#refresh(java.lang.String, java.util.Map,
056         *      org.kuali.rice.kns.document.MaintenanceDocument)
057         */
058        @Override
059        public void refresh(String refreshCaller, Map fieldValues, MaintenanceDocument document) {
060            super.refresh(refreshCaller, fieldValues, document);
061    
062            Person person = GlobalVariables.getUserSession().getPerson();
063            MaintenanceDocumentRestrictions restrictions = getBusinessObjectAuthorizationService().getMaintenanceDocumentRestrictions(document, person);
064            boolean canEdit = !restrictions.isHiddenSectionId(KFSConstants.SUB_ACCOUNT_EDIT_CG_ICR_SECTION_ID) && !restrictions.isReadOnlySectionId(KFSConstants.SUB_ACCOUNT_EDIT_CG_ICR_SECTION_ID);
065            
066            // after account lookup, refresh the CG ICR account fields
067            if (StringUtils.equals(refreshCaller, "accountLookupable") && fieldValues.containsKey("document.newMaintainableObject.accountNumber") && canEdit) {
068                SubAccount subAccount = (SubAccount) this.getBusinessObject();
069                this.populateCGIcrFields(subAccount);
070            }
071        }
072    
073        // populate the CG ICR fields if any
074        private void populateCGIcrFields(SubAccount subAccount) {
075            A21SubAccount a21SubAccount = subAccount.getA21SubAccount();
076            String chartOfAccountsCode = subAccount.getChartOfAccountsCode();
077            String accountNumber = subAccount.getAccountNumber();
078            
079            if (ObjectUtils.isNotNull(a21SubAccount) && (!StringUtils.equals(chartOfAccountsCode, a21SubAccount.getChartOfAccountsCode()) || !StringUtils.equals(accountNumber, a21SubAccount.getAccountNumber()))) {                  
080                A21SubAccountService a21SubAccountService = SpringContext.getBean(A21SubAccountService.class);
081                a21SubAccountService.populateCgIcrAccount(a21SubAccount, chartOfAccountsCode, accountNumber);
082            }
083        }
084        
085        /**
086         * @see org.kuali.kfs.sys.document.FinancialSystemMaintainable#populateChartOfAccountsCodeFields()
087         * 
088         * Special treatment is needed to populate chart code fields from account number fields 
089         * in nested reference accounts a21SubAccount.costShareAccount and a21SubAccount.indirectCostRecoveryAcct
090         * when accounts can't cross charts.
091         */
092        @Override
093        protected void populateChartOfAccountsCodeFields() {
094            super.populateChartOfAccountsCodeFields();
095            PersistableBusinessObject bo = getBusinessObject();        
096            AccountService acctService = SpringContext.getBean(AccountService.class);
097    
098            for (int i=0; i<COA_CODE_NAMES.length; i++) {
099                String coaCodeName = COA_CODE_NAMES[i];            
100                String acctNumName = ACCOUNT_NUMBER_NAMES[i];        
101                String accountNumber = (String)ObjectUtils.getPropertyValue(bo, acctNumName);
102                String coaCode = null;
103                Account account = acctService.getUniqueAccountForAccountNumber(accountNumber);            
104                if (ObjectUtils.isNotNull(account)) {
105                    coaCode = account.getChartOfAccountsCode();
106                }
107                try {
108                    ObjectUtils.setObjectProperty(bo, coaCodeName, coaCode); 
109                }
110                catch (Exception e) {
111                    LOG.error("Error in setting property value for " + coaCodeName);
112                } 
113            }
114        }
115        
116    }