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.gl.batch.service.impl;
17  
18  import java.util.Date;
19  
20  import org.kuali.ole.gl.GeneralLedgerConstants;
21  import org.kuali.ole.gl.batch.service.AccountingCycleCachingService;
22  import org.kuali.ole.gl.batch.service.PostTransaction;
23  import org.kuali.ole.gl.businessobject.SufficientFundBalances;
24  import org.kuali.ole.gl.businessobject.Transaction;
25  import org.kuali.ole.sys.OLEConstants;
26  import org.kuali.ole.sys.service.ReportWriterService;
27  import org.kuali.rice.core.api.util.type.KualiDecimal;
28  import org.kuali.rice.krad.service.PersistenceStructureService;
29  import org.kuali.rice.krad.util.ObjectUtils;
30  import org.springframework.transaction.annotation.Transactional;
31  
32  /**
33   * An implementation of PostTransaction which posts a transaction to the appropriate sufficient funds record
34   */
35  @Transactional
36  public class PostSufficientFundBalances implements PostTransaction {
37      private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PostSufficientFundBalances.class);
38      
39      private AccountingCycleCachingService accountingCycleCachingService;
40      private PersistenceStructureService persistenceStructureService;
41      
42      /**
43       * Constructs a PostSufficientFundBalances instance
44       */
45      public PostSufficientFundBalances() {
46          super();
47      }
48  
49      /**
50       * Posts the transaction to the appropriate sufficient funds records
51       * 
52       * @param t the transaction which is being posted
53       * @param mode the mode the poster is currently running in
54       * @param postDate the date this transaction should post to
55       * @param posterReportWriterService the writer service where the poster is writing its report
56       * @return the accomplished post type
57       * @see org.kuali.ole.gl.batch.service.PostTransaction#post(org.kuali.ole.gl.businessobject.Transaction, int, java.util.Date)
58       */
59      public String post(Transaction t, int mode, Date postDate, ReportWriterService posterReportWriterService) {
60          LOG.debug("post() started");
61  
62          String returnCode = GeneralLedgerConstants.UPDATE_CODE;
63  
64          if (OLEConstants.SF_TYPE_NO_CHECKING.equals(t.getAccount().getAccountSufficientFundsCode())) {
65              // Don't need to post
66              return GeneralLedgerConstants.EMPTY_CODE;
67          }
68  
69          // Get the Sufficient funds code
70          // Sufficient Funds Code
71          String sufficientFundsObjectCode = null;
72          if (OLEConstants.SF_TYPE_OBJECT.equals(t.getAccount().getAccountSufficientFundsCode())) {
73              sufficientFundsObjectCode = t.getFinancialObjectCode();
74          }
75          else if (OLEConstants.SF_TYPE_LEVEL.equals(t.getAccount().getAccountSufficientFundsCode())) {
76              if (ObjectUtils.isNull(t.getFinancialObject())) {
77                  return "E:Could not find sufficient funds object code for " + t.toString();
78              }
79              sufficientFundsObjectCode = t.getFinancialObject().getFinancialObjectLevelCode();
80          }
81          else if (OLEConstants.SF_TYPE_CONSOLIDATION.equals(t.getAccount().getAccountSufficientFundsCode())) {
82              //sufficientFundsObjectCode = t.getFinancialObject().getFinancialObjectLevel().getFinancialConsolidationObjectCode();
83              if (ObjectUtils.isNull(t.getFinancialObject())) {
84                  return "E:Could not find sufficient funds object code for " + t.toString();
85              }
86              sufficientFundsObjectCode = accountingCycleCachingService.getObjectLevel(t.getFinancialObject().getChartOfAccountsCode(), t.getFinancialObject().getFinancialObjectLevelCode()).getFinancialConsolidationObjectCode();
87          }
88          else if (OLEConstants.SF_TYPE_CASH_AT_ACCOUNT.equals(t.getAccount().getAccountSufficientFundsCode()) || OLEConstants.SF_TYPE_ACCOUNT.equals(t.getAccount().getAccountSufficientFundsCode())) {
89              sufficientFundsObjectCode = GeneralLedgerConstants.getSpaceFinancialObjectCode();
90          }
91          else {
92              return "E:Invalid sufficient funds code (" + t.getAccount().getAccountSufficientFundsCode() + ")";
93          }
94  
95          // Look to see if there is a sufficient funds record for this
96          SufficientFundBalances sfBalance = accountingCycleCachingService.getSufficientFundBalances(t.getUniversityFiscalYear(), t.getChartOfAccountsCode(), t.getAccountNumber(), sufficientFundsObjectCode);
97          if (sfBalance == null) {
98              returnCode = GeneralLedgerConstants.INSERT_CODE;
99              sfBalance = new SufficientFundBalances();
100             sfBalance.setUniversityFiscalYear(t.getUniversityFiscalYear());
101             sfBalance.setChartOfAccountsCode(t.getChartOfAccountsCode());
102             sfBalance.setAccountNumber(t.getAccountNumber());
103             sfBalance.setFinancialObjectCode(sufficientFundsObjectCode);
104             sfBalance.setAccountActualExpenditureAmt(KualiDecimal.ZERO);
105             sfBalance.setAccountEncumbranceAmount(KualiDecimal.ZERO);
106             sfBalance.setCurrentBudgetBalanceAmount(KualiDecimal.ZERO);
107             sfBalance.setAccountSufficientFundsCode(t.getAccount().getAccountSufficientFundsCode());
108         }
109 
110         if (OLEConstants.SF_TYPE_CASH_AT_ACCOUNT.equals(t.getAccount().getAccountSufficientFundsCode())) {
111             // 2640-PROCESS-CASH
112             if (t.getFinancialBalanceTypeCode().equals(t.getOption().getActualFinancialBalanceTypeCd())) {
113                 if (t.getFinancialObjectCode().equals(t.getChart().getFinancialCashObjectCode()) || t.getFinancialObjectCode().equals(t.getChart().getFinAccountsPayableObjectCode())) {
114                     // 2641-PROCESS-CASH-ACTUAL
115                     updateBudgetAmount(t.getTransactionDebitCreditCode(), sfBalance, t.getTransactionLedgerEntryAmount());
116                 }
117                 else {
118                     // No need to post this
119                     return GeneralLedgerConstants.EMPTY_CODE;
120                 }
121             }
122             else if (t.getFinancialBalanceTypeCode().equals(t.getOption().getExtrnlEncumFinBalanceTypCd()) || t.getFinancialBalanceTypeCode().equals(t.getOption().getIntrnlEncumFinBalanceTypCd()) || t.getFinancialBalanceTypeCode().equals(t.getOption().getPreencumbranceFinBalTypeCd()) || t.getOption().getCostShareEncumbranceBalanceTypeCd().equals(t.getFinancialBalanceTypeCode())) {
123                 if (t.getFinancialObjectTypeCode().equals(t.getOption().getFinObjTypeExpenditureexpCd()) || t.getFinancialObjectTypeCode().equals(t.getOption().getFinObjTypeExpendNotExpCode()) || t.getOption().getFinancialObjectTypeTransferExpenseCd().equals(t.getFinancialObjectTypeCode()) || t.getOption().getFinObjTypeExpNotExpendCode().equals(t.getFinancialObjectTypeCode())) {
124                     // 2462-PROCESS-CASH-ENCUMBRANCE
125                     updateEncumbranceAmount(t.getTransactionDebitCreditCode(), sfBalance, t.getTransactionLedgerEntryAmount());
126                 }
127                 else {
128                     // No need to post this
129                     return GeneralLedgerConstants.EMPTY_CODE;
130                 }
131             }
132             else {
133                 // No need to post this
134                 return GeneralLedgerConstants.EMPTY_CODE;
135             }
136         }
137         else {
138             // 2630-PROCESS-OBJECT-OR-ACCOUNT
139             if (t.getFinancialObjectTypeCode().equals(t.getOption().getFinObjTypeExpenditureexpCd()) || t.getFinancialObjectTypeCode().equals(t.getOption().getFinObjTypeExpendNotExpCode()) || t.getOption().getFinancialObjectTypeTransferExpenseCd().equals(t.getFinancialObjectTypeCode()) || t.getOption().getFinObjTypeExpNotExpendCode().equals(t.getFinancialObjectTypeCode())) {
140                 if (t.getFinancialBalanceTypeCode().equals(t.getOption().getActualFinancialBalanceTypeCd())) {
141                     // 2631-PROCESS-OBJTACCT-ACTUAL
142                     updateExpendedAmount(t.getTransactionDebitCreditCode(), sfBalance, t.getTransactionLedgerEntryAmount());
143                 }
144                 else if (t.getFinancialBalanceTypeCode().equals(t.getOption().getExtrnlEncumFinBalanceTypCd()) || t.getFinancialBalanceTypeCode().equals(t.getOption().getIntrnlEncumFinBalanceTypCd()) || t.getFinancialBalanceTypeCode().equals(t.getOption().getPreencumbranceFinBalTypeCd()) || t.getFinancialBalanceTypeCode().equals(t.getOption().getCostShareEncumbranceBalanceTypeCd())) {
145                     // 2632-PROCESS-OBJTACCT-ENCMBRNC
146                     updateEncumbranceAmount(t.getTransactionDebitCreditCode(), sfBalance, t.getTransactionLedgerEntryAmount());
147                 }
148                 else if (t.getFinancialBalanceTypeCode().equals(t.getOption().getBudgetCheckingBalanceTypeCd())) {
149                     sfBalance.setCurrentBudgetBalanceAmount(sfBalance.getCurrentBudgetBalanceAmount().add(t.getTransactionLedgerEntryAmount()));
150                 }
151                 else {
152                     // No need to post this
153                     return GeneralLedgerConstants.EMPTY_CODE;
154                 }
155             }
156             else {
157                 // No need to post this
158                 return GeneralLedgerConstants.EMPTY_CODE;
159             }
160         }
161 
162         // If we get here, we need to save the balance entry
163         if (returnCode.equals(GeneralLedgerConstants.INSERT_CODE)) {
164             accountingCycleCachingService.insertSufficientFundBalances(sfBalance);
165         } else {
166             accountingCycleCachingService.updateSufficientFundBalances(sfBalance);
167         }
168 
169 
170         return returnCode;
171     }
172 
173     /**
174      * Updates the expenditure amount of a given sufficient funds balance record
175      * 
176      * @param debitCreditCode whether the the amount should be debited or credited to the SF balance
177      * @param bal a sufficient funds balance to update
178      * @param amount the amount to debit or credit
179      */
180     protected void updateExpendedAmount(String debitCreditCode, SufficientFundBalances bal, KualiDecimal amount) {
181         if (OLEConstants.GL_CREDIT_CODE.equals(debitCreditCode)) {
182             bal.setAccountActualExpenditureAmt(bal.getAccountActualExpenditureAmt().subtract(amount));
183         }
184         else if (OLEConstants.GL_DEBIT_CODE.equals(debitCreditCode) || OLEConstants.GL_BUDGET_CODE.equals(debitCreditCode)) {
185             bal.setAccountActualExpenditureAmt(bal.getAccountActualExpenditureAmt().add(amount));
186         }
187     }
188 
189     /**
190      * Updates the encumbrance amount of a given sufficient funds balance record
191      * 
192      * @param debitCreditCode whether the the amount should be debited or credited to the SF balance
193      * @param bal a sufficient funds balance to update
194      * @param amount the amount to debit or credit
195      */
196     protected void updateEncumbranceAmount(String debitCreditCode, SufficientFundBalances bal, KualiDecimal amount) {
197         if (OLEConstants.GL_CREDIT_CODE.equals(debitCreditCode)) {
198             bal.setAccountEncumbranceAmount(bal.getAccountEncumbranceAmount().subtract(amount));
199         }
200         else if (OLEConstants.GL_DEBIT_CODE.equals(debitCreditCode) || OLEConstants.GL_BUDGET_CODE.equals(debitCreditCode)) {
201             bal.setAccountEncumbranceAmount(bal.getAccountEncumbranceAmount().add(amount));
202         }
203     }
204 
205     /**
206      * Updates the budget amount of a given sufficient funds balance record
207      * 
208      * @param debitCreditCode whether the the amount should be debited or credited to the SF balance
209      * @param bal a sufficient funds balance to update
210      * @param amount the amount to debit or credit
211      */
212     protected void updateBudgetAmount(String debitCreditCode, SufficientFundBalances bal, KualiDecimal amount) {
213         if (OLEConstants.GL_CREDIT_CODE.equals(debitCreditCode)) {
214             bal.setCurrentBudgetBalanceAmount(bal.getCurrentBudgetBalanceAmount().subtract(amount));
215         }
216         else if (OLEConstants.GL_DEBIT_CODE.equals(debitCreditCode) || OLEConstants.GL_BUDGET_CODE.equals(debitCreditCode)) {
217             bal.setCurrentBudgetBalanceAmount(bal.getCurrentBudgetBalanceAmount().add(amount));
218         }
219     }
220 
221     /**
222      * @see org.kuali.ole.gl.batch.service.PostTransaction#getDestinationName()
223      */
224     public String getDestinationName() {
225         return persistenceStructureService.getTableName(SufficientFundBalances.class);
226     }
227     
228     public void setAccountingCycleCachingService(AccountingCycleCachingService accountingCycleCachingService) {
229         this.accountingCycleCachingService = accountingCycleCachingService;
230     }
231 
232     public void setPersistenceStructureService(PersistenceStructureService persistenceStructureService) {
233         this.persistenceStructureService = persistenceStructureService;
234     }
235 }