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.validation.impl;
017    
018    import org.apache.commons.lang.StringUtils;
019    import org.kuali.kfs.coa.businessobject.A21SubAccount;
020    import org.kuali.kfs.coa.businessobject.Account;
021    import org.kuali.kfs.coa.businessobject.SubAccount;
022    import org.kuali.kfs.sys.KFSConstants;
023    import org.kuali.kfs.sys.context.SpringContext;
024    import org.kuali.rice.kim.bo.Person;
025    import org.kuali.rice.kns.document.MaintenanceDocument;
026    import org.kuali.rice.kns.document.authorization.MaintenanceDocumentRestrictions;
027    import org.kuali.rice.kns.service.BusinessObjectAuthorizationService;
028    import org.kuali.rice.kns.util.GlobalVariables;
029    import org.kuali.rice.kns.util.ObjectUtils;
030    
031    /**
032     * PreRules checks for the {@link SubAccount} that needs to occur while still in the Struts processing. This includes defaults, confirmations,
033     * etc.
034     */
035    public class SubAccountPreRules extends MaintenancePreRulesBase {
036    
037        protected SubAccount newSubAccount;
038    
039        // protected SubAccount copyAccount;
040    
041        public SubAccountPreRules() {
042    
043        }
044    
045        /**
046         * This checks to see if a continuation account is necessary and then copies the ICR data from the Account 
047         * associated with this SubAccount (if necessary)
048         * @see org.kuali.kfs.coa.document.validation.impl.MaintenancePreRulesBase#doCustomPreRules(org.kuali.rice.kns.document.MaintenanceDocument)
049         */
050        protected boolean doCustomPreRules(MaintenanceDocument document) {
051            setupConvenienceObjects(document);
052            checkForContinuationAccounts(document.getNewMaintainableObject().getMaintenanceAction()); // run this first to avoid side
053                                                                                                        // effects
054    
055            LOG.debug("done with continuation account, proceeeding with remaining pre rules");
056    
057            copyICRFromAccount(document);
058    
059            return true;
060        }
061    
062        /**
063         * 
064         * This looks for the SubAccount's account number and then sets the values to the continuation account value if it exists
065         * @param maintenanceAction
066         */
067        protected void checkForContinuationAccounts(String maintenanceAction) {
068            LOG.debug("entering checkForContinuationAccounts()");
069    
070            /*
071             * KULCOA-734 - The check for continuation account for main Account Number on sub-account has been modified to only occur
072             * for a New and Copy Action. This cannot happen on an Edit as the primary key will change.
073             */
074            if (KFSConstants.MAINTENANCE_NEW_ACTION.equals(maintenanceAction) || KFSConstants.MAINTENANCE_COPY_ACTION.equals(maintenanceAction)) {
075    
076                if (StringUtils.isNotBlank(newSubAccount.getAccountNumber())) {
077                    Account account = checkForContinuationAccount("Account Number", newSubAccount.getChartOfAccountsCode(), newSubAccount.getAccountNumber(), "");
078                    if (ObjectUtils.isNotNull(account)) { // override old user inputs
079                        newSubAccount.setAccountNumber(account.getAccountNumber());
080                        newSubAccount.setChartOfAccountsCode(account.getChartOfAccountsCode());
081                    }
082                }
083            }
084        }
085    
086        /**
087         * This method sets the convenience objects like newSubAccount, so you have short and easy handles to the new and
088         * old objects contained in the maintenance document. It also calls the BusinessObjectBase.refresh(), which will attempt to load
089         * all sub-objects from the DB by their primary keys, if available.
090         * @param document
091         */
092        protected void setupConvenienceObjects(MaintenanceDocument document) {
093    
094            // setup newAccount convenience objects, make sure all possible sub-objects are populated
095            newSubAccount = (SubAccount) document.getNewMaintainableObject().getBusinessObject();
096            // copyAccount = (SubAccount) ObjectUtils.deepCopy(newAccount);
097            // copyAccount.refresh();
098        }
099    
100        /**
101         * 
102         * This copies the Indirect Cost Rate (ICR) from the account if the SubAccount is a specific type - determined 
103         * as "EX" from {@link SubAccountRule#CG_A21_TYPE_ICR}
104         * <p>
105         * If it is "EX" it will then copy over the ICR information from the Account specified for this SubAccount
106         * @param document
107         */
108        protected void copyICRFromAccount(MaintenanceDocument document) {
109            Person user = GlobalVariables.getUserSession().getPerson();
110    
111            // get a new instance of MaintenanceDocumentAuthorizations for this context
112            MaintenanceDocumentRestrictions auths = SpringContext.getBean(BusinessObjectAuthorizationService.class).getMaintenanceDocumentRestrictions(document, user);
113    
114            // don't need to copy if the user does not have the authority to edit the fields
115            if (!auths.getFieldRestriction("a21SubAccount.financialIcrSeriesIdentifier").isReadOnly()) {
116                // only need to do this of the account sub type is EX
117                A21SubAccount a21SubAccount = newSubAccount.getA21SubAccount();
118                Account account = newSubAccount.getAccount();
119                if (KFSConstants.SubAccountType.EXPENSE.equals(a21SubAccount.getSubAccountTypeCode())) {
120                    if (ObjectUtils.isNull(account) || StringUtils.isBlank(account.getAccountNumber())) {
121                        account = getAccountService().getByPrimaryId(newSubAccount.getChartOfAccountsCode(), newSubAccount.getAccountNumber());
122                        if (ObjectUtils.isNotNull(account)) {
123                            if (StringUtils.isBlank(a21SubAccount.getIndirectCostRecoveryAcctNbr())) {
124                                a21SubAccount.setIndirectCostRecoveryAcctNbr(account.getIndirectCostRecoveryAcctNbr());
125                                a21SubAccount.setIndirectCostRcvyFinCoaCode(account.getIndirectCostRcvyFinCoaCode());
126                            }
127                            if (StringUtils.isBlank(a21SubAccount.getFinancialIcrSeriesIdentifier())) {
128                                a21SubAccount.setFinancialIcrSeriesIdentifier(account.getFinancialIcrSeriesIdentifier());
129                                a21SubAccount.setOffCampusCode(account.isAccountOffCampusIndicator());
130                            }
131                            if (StringUtils.isBlank(a21SubAccount.getIndirectCostRecoveryTypeCode())) {
132                                a21SubAccount.setIndirectCostRecoveryTypeCode(account.getAcctIndirectCostRcvyTypeCd());
133                            }
134                        }
135                    }
136                }
137            }
138        }
139    }