View Javadoc
1   /*
2    * Copyright 2006 The Kuali Foundation
3    * 
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    * http://www.opensource.org/licenses/ecl2.php
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.ole.coa.document.validation.impl;
17  
18  import java.sql.Date;
19  
20  import org.apache.commons.lang.StringUtils;
21  import org.joda.time.DateTime;
22  import org.kuali.ole.coa.businessobject.Account;
23  import org.kuali.ole.coa.businessobject.IndirectCostRecoveryAccount;
24  import org.kuali.ole.coa.businessobject.SubFundGroup;
25  import org.kuali.ole.coa.service.AccountService;
26  import org.kuali.ole.sys.context.SpringContext;
27  import org.kuali.rice.core.api.config.property.ConfigurationService;
28  import org.kuali.rice.kns.document.MaintenanceDocument;
29  import org.kuali.rice.krad.util.ObjectUtils;
30  import org.kuali.rice.location.api.postalcode.PostalCode;
31  import org.kuali.rice.location.api.postalcode.PostalCodeService;
32  
33  /**
34   * PreRules checks for the Account that needs to occur while still in the Struts processing. This includes defaults, confirmations,
35   * etc.
36   */
37  public class AccountPreRules extends MaintenancePreRulesBase {
38  
39      protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(AccountPreRules.class);
40  
41      protected static final String DEFAULT_STATE_CODE = "Account.Defaults.StateCode";
42      protected static final String DEFAULT_ACCOUNT_TYPE_CODE = "Account.Defaults.AccountType";
43  
44      protected ConfigurationService configService;
45      protected AccountService accountService;
46      protected PostalCodeService postalZipCodeService;
47      protected Account newAccount;
48  
49      protected static final String GENERAL_FUND_CD = "GF";
50      protected static final String RESTRICTED_FUND_CD = "RF";
51      protected static final String ENDOWMENT_FUND_CD = "EN";
52      protected static final String PLANT_FUND_CD = "PF";
53  
54      protected static final String RESTRICTED_CD_RESTRICTED = "R";
55      protected static final String RESTRICTED_CD_UNRESTRICTED = "U";
56      protected static final String RESTRICTED_CD_TEMPORARILY_RESTRICTED = "T";
57      protected static final String RESTRICTED_CD_NOT_APPLICABLE = "N";
58  
59  
60      public AccountPreRules() {
61          accountService = SpringContext.getBean(AccountService.class);
62          configService = SpringContext.getBean(ConfigurationService.class);
63          postalZipCodeService = SpringContext.getBean(PostalCodeService.class);
64      }
65  
66      /**
67       * Executes the following pre rules
68       * <ul>
69       * <li>{@link AccountPreRules#checkForContinuationAccount(String, String, String, String)}</li>
70       * <li>{@link AccountPreRules#checkForDefaultSubFundGroupStatus()}</li>
71       * <li>{@link AccountPreRules#newAccountDefaults(MaintenanceDocument)}</li>
72       * <li>{@link AccountPreRules#setStateFromZip}</li>
73       * </ul>
74       * This does not fail on rule failures
75       * @see org.kuali.ole.coa.document.validation.impl.MaintenancePreRulesBase#doCustomPreRules(org.kuali.rice.kns.document.MaintenanceDocument)
76       */
77      @Override
78      protected boolean doCustomPreRules(MaintenanceDocument document) {
79          setupConvenienceObjects(document);
80          checkForContinuationAccounts(); // run this first to avoid side effects
81          checkForDefaultSubFundGroupStatus();
82  
83          LOG.debug("done with continuation account, proceeeding with remaining pre rules");
84  
85          newAccountDefaults(document);
86          setStateFromZip(document);
87  
88          return true;
89      }
90  
91      /**
92       * This method sets a default restricted status on an account if and only if the status code in SubFundGroup has been set and
93       * the user answers in the affirmative that they definitely want to use this SubFundGroup.
94       */
95      protected void checkForDefaultSubFundGroupStatus() {
96          String restrictedStatusCode = "";
97  
98          // if subFundGroupCode was not entered, then we have nothing
99          // to do here, so exit
100         if (ObjectUtils.isNull(newAccount.getSubFundGroup()) || StringUtils.isBlank(newAccount.getSubFundGroupCode())) {
101             return;
102         }
103         SubFundGroup subFundGroup = newAccount.getSubFundGroup();
104 
105         // KULCOA-1112 : if the sub fund group has a restriction code, override whatever the user selected
106         if (StringUtils.isNotBlank(subFundGroup.getAccountRestrictedStatusCode())) {
107             restrictedStatusCode = subFundGroup.getAccountRestrictedStatusCode().trim();
108             String subFundGroupCd = subFundGroup.getSubFundGroupCode();
109             newAccount.setAccountRestrictedStatusCode(restrictedStatusCode);
110         }
111 
112     }
113 
114     /**
115      * This method checks for continuation accounts and presents the user with a question regarding their use on this account.
116      */
117     protected void checkForContinuationAccounts() {
118         LOG.debug("entering checkForContinuationAccounts()");
119 
120         if (StringUtils.isNotBlank(newAccount.getReportsToAccountNumber())) {
121             Account account = checkForContinuationAccount("Fringe Benefit Account", newAccount.getReportsToChartOfAccountsCode(), newAccount.getReportsToAccountNumber(), "");
122             if (ObjectUtils.isNotNull(account)) { // override old user inputs
123                 newAccount.setReportsToAccountNumber(account.getAccountNumber());
124                 newAccount.setReportsToChartOfAccountsCode(account.getChartOfAccountsCode());
125             }
126         }
127 
128         if (StringUtils.isNotBlank(newAccount.getEndowmentIncomeAccountNumber())) {
129             Account account = checkForContinuationAccount("Endowment Account", newAccount.getEndowmentIncomeAcctFinCoaCd(), newAccount.getEndowmentIncomeAccountNumber(), "");
130             if (ObjectUtils.isNotNull(account)) { // override old user inputs
131                 newAccount.setEndowmentIncomeAccountNumber(account.getAccountNumber());
132                 newAccount.setEndowmentIncomeAcctFinCoaCd(account.getChartOfAccountsCode());
133             }
134         }
135 
136         if (StringUtils.isNotBlank(newAccount.getIncomeStreamAccountNumber())) {
137             Account account = checkForContinuationAccount("Income Stream Account", newAccount.getIncomeStreamFinancialCoaCode(), newAccount.getIncomeStreamAccountNumber(), "");
138             if (ObjectUtils.isNotNull(account)) { // override old user inputs
139                 newAccount.setIncomeStreamAccountNumber(account.getAccountNumber());
140                 newAccount.setIncomeStreamFinancialCoaCode(account.getChartOfAccountsCode());
141             }
142         }
143 
144         if (StringUtils.isNotBlank(newAccount.getContractControlAccountNumber())) {
145             Account account = checkForContinuationAccount("Contract Control Account", newAccount.getContractControlFinCoaCode(), newAccount.getContractControlAccountNumber(), "");
146             if (ObjectUtils.isNotNull(account)) { // override old user inputs
147                 newAccount.setContractControlAccountNumber(account.getAccountNumber());
148                 newAccount.setContractControlFinCoaCode(account.getChartOfAccountsCode());
149             }
150         }
151 
152         for (IndirectCostRecoveryAccount icra : newAccount.getActiveIndirectCostRecoveryAccounts()){
153             if (StringUtils.isNotBlank(icra.getIndirectCostRecoveryAccountNumber())) {
154                 Account account = checkForContinuationAccount("Indirect Cost Recovery Account", icra.getIndirectCostRecoveryAccountNumber(), icra.getIndirectCostRecoveryFinCoaCode(), "");
155                 if (ObjectUtils.isNotNull(account)) { // override old user inputs
156                     icra.setIndirectCostRecoveryAccountNumber(account.getAccountNumber());
157                     icra.setIndirectCostRecoveryFinCoaCode(account.getChartOfAccountsCode());
158                 }
159             }
160         }
161 
162 
163     }
164 
165     /**
166      * This method sets the convenience objects like newAccount and oldAccount, so you have short and easy handles to the new and
167      * old objects contained in the maintenance document. It also calls the BusinessObjectBase.refresh(), which will attempt to load
168      * all sub-objects from the DB by their primary keys, if available.
169      * 
170      * @param document - the maintenanceDocument being evaluated
171      */
172     protected void setupConvenienceObjects(MaintenanceDocument document) {
173 
174         // setup newAccount convenience objects, make sure all possible sub-objects are populated
175         newAccount = (Account) document.getNewMaintainableObject().getBusinessObject();
176         newAccount.refreshNonUpdateableReferences();
177     }
178 
179     /**
180      * This method sets up some defaults for new Account
181      * 
182      * @param maintenanceDocument
183      */
184     protected void newAccountDefaults(MaintenanceDocument maintenanceDocument) {
185 
186 
187         /*
188          * GlobalVariables.getMessageMap().put("document.newMaintainableObject.accountEffectiveDate" ,
189          * "error.document.accountMaintenance.emptyAccountEffectiveDate", "Account Effective Date");
190          */
191 
192         // TODO: this is not needed any more, is in maintdoc xml defaults
193         DateTime ts = new DateTime(maintenanceDocument.getDocumentHeader().getWorkflowDocument().getDateCreated());
194         Date newts = new Date(ts.getMillis());
195         
196         if (ts != null) {
197             // On new Accounts AccountCreateDate is defaulted to the doc creation date
198             if (newAccount.getAccountCreateDate() == null) {
199                 newAccount.setAccountCreateDate(newts);
200             }
201             // On new Accounts acct_effect_date is defaulted to the doc creation date
202             if (newAccount.getAccountEffectiveDate() == null) {
203                 newAccount.setAccountEffectiveDate(newts);
204             }
205         }
206     }
207 
208     /**
209      * This method lookups state and city from populated zip, set the values on the form
210      * 
211      * @param maintenanceDocument
212      */
213     protected void setStateFromZip(MaintenanceDocument maintenanceDocument) {
214 
215         // acct_zip_cd, acct_state_cd, acct_city_nm all are populated by looking up
216         // the zip code and getting the state and city from that
217         if (StringUtils.isNotBlank(newAccount.getAccountZipCode()) && StringUtils.isNotBlank(newAccount.getAccountCountryCode())  ) {
218             PostalCode zip = postalZipCodeService.getPostalCode( newAccount.getAccountCountryCode(), newAccount.getAccountZipCode() );
219 
220             // If user enters a valid zip code, override city name and state code entered by user
221             if (ObjectUtils.isNotNull(zip)) { // override old user inputs
222                 newAccount.setAccountCityName(zip.getCityName());
223                 newAccount.setAccountStateCode(zip.getStateCode());
224             }
225         }
226     }
227 
228 
229 }