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