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.sql.Date;
19  import java.util.ArrayList;
20  import java.util.Collection;
21  import java.util.HashMap;
22  import java.util.Iterator;
23  import java.util.List;
24  import java.util.Map;
25  
26  import org.kuali.ole.coa.businessobject.Account;
27  import org.kuali.ole.coa.service.AccountService;
28  import org.kuali.ole.gl.GeneralLedgerConstants;
29  import org.kuali.ole.gl.batch.SufficientFundsAccountUpdateStep;
30  import org.kuali.ole.gl.batch.service.SufficientFundsAccountUpdateService;
31  import org.kuali.ole.gl.businessobject.Balance;
32  import org.kuali.ole.gl.businessobject.SufficientFundBalances;
33  import org.kuali.ole.gl.businessobject.SufficientFundRebuild;
34  import org.kuali.ole.gl.dataaccess.BalanceDao;
35  import org.kuali.ole.gl.dataaccess.SufficientFundBalancesDao;
36  import org.kuali.ole.gl.dataaccess.SufficientFundRebuildDao;
37  import org.kuali.ole.gl.service.SufficientFundsService;
38  import org.kuali.ole.sys.Message;
39  import org.kuali.ole.sys.OLEConstants;
40  import org.kuali.ole.sys.OLEKeyConstants;
41  import org.kuali.ole.sys.OLEPropertyConstants;
42  import org.kuali.ole.sys.businessobject.SystemOptions;
43  import org.kuali.ole.sys.context.SpringContext;
44  import org.kuali.ole.sys.service.ReportWriterService;
45  import org.kuali.rice.core.api.config.property.ConfigurationService;
46  import org.kuali.rice.core.api.datetime.DateTimeService;
47  import org.kuali.rice.core.api.util.type.KualiDecimal;
48  import org.kuali.rice.coreservice.framework.parameter.ParameterService;
49  import org.kuali.rice.krad.service.BusinessObjectService;
50  import org.springframework.transaction.annotation.Transactional;
51  
52  /**
53   * The default implementation of SufficientFundsAccountUpdateService
54   */
55  @Transactional
56  public class SufficientFundsAccountUpdateServiceImpl implements SufficientFundsAccountUpdateService {
57      private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(SufficientFundsAccountUpdateServiceImpl.class);
58  
59      private DateTimeService dateTimeService;
60      private ConfigurationService kualiConfigurationService;
61      private BalanceDao balanceDao;
62      private SufficientFundBalancesDao sufficientFundBalancesDao;
63      private SufficientFundRebuildDao sufficientFundRebuildDao;
64      private SufficientFundsService sufficientFundsService;
65      private AccountService accountService;
66      private ReportWriterService reportWriterService;
67      private BusinessObjectService boService;
68  
69      private Date runDate;
70      private SystemOptions options;
71  
72      Map batchError;
73      List reportSummary;
74      List<Message> transactionErrors;
75  
76      private Integer universityFiscalYear;
77      private int sfrbRecordsConvertedCount = 0;
78      private int sfrbRecordsReadCount = 0;
79      private int sfrbRecordsDeletedCount = 0;
80      private int sfrbNotDeletedCount = 0;
81      private int sfblDeletedCount = 0;
82      private int sfblInsertedCount = 0;
83      private int sfblUpdatedCount = 0;
84      private int warningCount = 0;
85  
86  
87      private SufficientFundBalances currentSfbl = null;
88  
89      /**
90       * Constructs a SufficientFundsAccountUpdateServiceImpl instance
91       */
92      public SufficientFundsAccountUpdateServiceImpl() {
93          super();
94      }
95  
96      /**
97       * Returns the fiscal year, set in a parameter, of sufficient funds to rebuild
98       *
99       * @return the fiscal year
100      */
101     protected Integer getFiscalYear() {
102         String val = SpringContext.getBean(ParameterService.class).getParameterValueAsString(SufficientFundsAccountUpdateStep.class, GeneralLedgerConstants.FISCAL_YEAR_PARM);
103         return Integer.parseInt(val);
104     }
105 
106     /**
107      * Rebuilds all necessary sufficient funds balances.
108      * @see org.kuali.ole.gl.batch.service.SufficientFundsAccountUpdateService#rebuildSufficientFunds()
109      */
110     @Override
111     public void rebuildSufficientFunds() { // driver
112         List <SufficientFundRebuild> rebuildSfrbList = new ArrayList<SufficientFundRebuild>();
113 
114         universityFiscalYear = getFiscalYear();
115         if ( LOG.isInfoEnabled() ) {
116             LOG.info( "Rebuilding sufficient funds for fiscal year: " + universityFiscalYear );
117         }
118         initService();
119 
120         //need to add time info - batch util?
121         runDate = dateTimeService.getCurrentSqlDate();
122 
123         // Get all the O types and convert them to A types
124         LOG.info("rebuildSufficientFunds() Converting O types to A types");
125         Map criteria = new HashMap();
126         criteria.put(OLEPropertyConstants.ACCOUNT_FINANCIAL_OBJECT_TYPE_CODE, OLEConstants.SF_TYPE_OBJECT);
127 
128         for (Iterator iter = boService.findMatching(SufficientFundRebuild.class, criteria).iterator(); iter.hasNext();) {
129             SufficientFundRebuild sfrb = (SufficientFundRebuild) iter.next();
130             ++sfrbRecordsReadCount;
131 
132             transactionErrors = new ArrayList<Message>();
133 
134             convertOtypeToAtypes(sfrb);
135 
136             if (transactionErrors.size() > 0) {
137                 reportWriterService.writeError(sfrb, transactionErrors);
138                 rebuildSfrbList.add(sfrb);
139             }
140           }
141         criteria.clear();
142 
143         // Get all the A types and process them
144         LOG.info("rebuildSufficientFunds() Calculating SF balances for all A types");
145 
146         criteria.put(OLEPropertyConstants.ACCOUNT_FINANCIAL_OBJECT_TYPE_CODE, OLEConstants.SF_TYPE_ACCOUNT);
147 
148         for (Iterator iter = boService.findMatching(SufficientFundRebuild.class, criteria).iterator(); iter.hasNext();) {
149             SufficientFundRebuild sfrb = (SufficientFundRebuild) iter.next();
150             ++sfrbRecordsReadCount;
151 
152             transactionErrors = new ArrayList<Message>();
153 
154             calculateSufficientFundsByAccount(sfrb);
155 
156             if (transactionErrors.size() > 0) {
157                 reportWriterService.writeError(sfrb, transactionErrors);
158                 rebuildSfrbList.add(sfrb);
159             }
160 
161         }
162         sufficientFundRebuildDao.purgeSufficientFundRebuild();
163         boService.save( rebuildSfrbList);
164 
165         // Look at all the left over rows. There shouldn't be any left if all are O's and A's without error.
166         // Write out error messages for any that aren't A or O
167         // JHK: commented this out - the above purge deletes everything from the table and the rebuildSfrbList will only have O and A records which the code below ignored
168 //        LOG.info("rebuildSufficientFunds() Handle any non-A and non-O types");
169 //        for (Iterator iter = boService.findAll(SufficientFundRebuild.class).iterator(); iter.hasNext();) {
170 //            SufficientFundRebuild sfrb = (SufficientFundRebuild) iter.next();
171 //
172 //            if ((!OLEConstants.SF_TYPE_ACCOUNT.equals(sfrb.getAccountFinancialObjectTypeCode())) && (!OLEConstants.SF_TYPE_OBJECT.equals(sfrb.getAccountFinancialObjectTypeCode()))) {
173 //                ++sfrbRecordsReadCount;
174 //                transactionErrors = new ArrayList<Message>();
175 //                addTransactionError(kualiConfigurationService.getPropertyString(OLEKeyConstants.ERROR_INVALID_SF_OBJECT_TYPE_CODE));
176 //                ++warningCount;
177 //                ++sfrbNotDeletedCount;
178 //                reportWriterService.writeError(sfrb, transactionErrors);
179 //            }
180 //        }
181 
182         // write out report and errors
183         LOG.info("rebuildSufficientFunds() Create report");
184 
185         // write out statistics
186         reportWriterService.writeStatisticLine("                                   SFRB RECORDS CONVERTED FROM OBJECT TO ACCOUNT  %,9d\n", sfrbRecordsConvertedCount);
187         reportWriterService.writeStatisticLine("                                   POST CONVERSION SFRB RECORDS READ              %,9d\n", sfrbRecordsReadCount);
188         reportWriterService.writeStatisticLine("                                   SFRB RECORDS DELETED                           %,9d\n", sfrbRecordsDeletedCount);
189         reportWriterService.writeStatisticLine("                                   SFRB RECORDS KEPT DUE TO ERRORS                %,9d\n", sfrbNotDeletedCount);
190         reportWriterService.writeStatisticLine("                                   SFBL RECORDS DELETED                           %,9d\n", sfblDeletedCount);
191         reportWriterService.writeStatisticLine("                                   SFBL RECORDS ADDED                             %,9d\n", sfblInsertedCount);
192         reportWriterService.writeStatisticLine("                                   SFBL RECORDS UDPATED                           %,9d\n", sfblUpdatedCount);
193     }
194 
195     /**
196      * Initializes the process at the beginning of a run.
197      */
198     protected void initService() {
199         batchError = new HashMap();
200         reportSummary = new ArrayList();
201 
202         runDate = new Date(dateTimeService.getCurrentDate().getTime());
203 
204         options = (SystemOptions)boService.findBySinglePrimaryKey(SystemOptions.class, universityFiscalYear);
205 
206         if (options == null) {
207             throw new IllegalStateException(kualiConfigurationService.getPropertyValueAsString(OLEKeyConstants.ERROR_UNIV_DATE_NOT_FOUND));
208         }
209     }
210 
211     /**
212      * Given an O SF rebuild type, it will look up all of the matching balances in the table and add each account it finds as an A
213      * SF rebuild type.
214      *
215      * @param sfrb the sufficient fund rebuild record to convert
216      */
217     @Override
218     public void convertOtypeToAtypes(SufficientFundRebuild sfrb) {
219         ++sfrbRecordsConvertedCount;
220         Collection fundBalances = sufficientFundBalancesDao.getByObjectCode(universityFiscalYear, sfrb.getChartOfAccountsCode(), sfrb.getAccountNumberFinancialObjectCode());
221         Map criteria = new HashMap();
222 
223         for (Iterator fundBalancesIter = fundBalances.iterator(); fundBalancesIter.hasNext();) {
224             SufficientFundBalances sfbl = (SufficientFundBalances) fundBalancesIter.next();
225             criteria.put(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, sfbl.getChartOfAccountsCode());
226             criteria.put(OLEPropertyConstants.ACCOUNT_FINANCIAL_OBJECT_TYPE_CODE, OLEConstants.SF_TYPE_ACCOUNT);
227             criteria.put(OLEPropertyConstants.ACCOUNT_NUMBER_FINANCIAL_OBJECT_CODE, sfbl.getAccountNumber());
228 
229             SufficientFundRebuild altSfrb = (SufficientFundRebuild)boService.findByPrimaryKey(SufficientFundRebuild.class, criteria);
230             if (altSfrb == null) {
231                 altSfrb = new SufficientFundRebuild();
232                 altSfrb.setAccountFinancialObjectTypeCode(OLEConstants.SF_TYPE_ACCOUNT);
233                 altSfrb.setAccountNumberFinancialObjectCode(sfbl.getAccountNumber());
234                 altSfrb.setChartOfAccountsCode(sfbl.getChartOfAccountsCode());
235                 boService.save(altSfrb);
236             }
237             criteria.clear();
238         }
239     }
240 
241     /**
242      * Updates sufficient funds balances for the given account
243      *
244      * @param sfrb the sufficient fund rebuild record, with a chart and account number
245      */
246     @Override
247     public void calculateSufficientFundsByAccount(SufficientFundRebuild sfrb) {
248         Account sfrbAccount = accountService.getByPrimaryId(sfrb.getChartOfAccountsCode(), sfrb.getAccountNumberFinancialObjectCode());
249         if (sfrbAccount == null) {
250             String msg = "Account found in SufficientFundsRebuild table that is not in Accounts table [" + sfrb.getChartOfAccountsCode() + "-" + sfrb.getAccountNumberFinancialObjectCode() + "].";
251             LOG.error(msg);
252             throw new RuntimeException(msg);
253         }
254         if ((sfrbAccount.getAccountSufficientFundsCode() != null)
255                 && (OLEConstants.SF_TYPE_ACCOUNT.equals(sfrbAccount.getAccountSufficientFundsCode())
256                         || OLEConstants.SF_TYPE_CASH_AT_ACCOUNT.equals(sfrbAccount.getAccountSufficientFundsCode())
257                         || OLEConstants.SF_TYPE_CONSOLIDATION.equals(sfrbAccount.getAccountSufficientFundsCode())
258                         || OLEConstants.SF_TYPE_LEVEL.equals(sfrbAccount.getAccountSufficientFundsCode())
259                         || OLEConstants.SF_TYPE_OBJECT.equals(sfrbAccount.getAccountSufficientFundsCode())
260                         || OLEConstants.SF_TYPE_NO_CHECKING.equals(sfrbAccount.getAccountSufficientFundsCode()))) {
261             ++sfrbRecordsDeletedCount;
262              sfblDeletedCount += sufficientFundBalancesDao.deleteByAccountNumber(universityFiscalYear, sfrb.getChartOfAccountsCode(), sfrbAccount.getAccountNumber());
263 
264             if (OLEConstants.SF_TYPE_NO_CHECKING.equalsIgnoreCase(sfrbAccount.getAccountSufficientFundsCode())) {
265                 // nothing to do here, no errors either, just return
266                 return;
267             }
268 
269             Iterator balancesIterator = balanceDao.findAccountBalances(universityFiscalYear, sfrb.getChartOfAccountsCode(), sfrb.getAccountNumberFinancialObjectCode(), sfrbAccount.getAccountSufficientFundsCode());
270 
271             if (balancesIterator == null) {
272                 addTransactionError(kualiConfigurationService.getPropertyValueAsString(OLEKeyConstants.ERROR_BALANCE_NOT_FOUND_FOR) + universityFiscalYear + ")");
273                 ++warningCount;
274                 ++sfrbNotDeletedCount;
275                 return;
276             }
277 
278             String currentFinObjectCd = "";
279             while (balancesIterator.hasNext()) {
280                 Balance balance = (Balance) balancesIterator.next();
281                 if ( LOG.isDebugEnabled() ) {
282                     LOG.debug("Processing Balance for SF: " + balance.getChartOfAccountsCode() + " / " + balance.getAccountNumber() + " / " + balance.getObjectCode() );
283                 }
284                 String tempFinObjectCd = sufficientFundsService.getSufficientFundsObjectCode(balance.getFinancialObject(), sfrbAccount.getAccountSufficientFundsCode());
285                 if ( LOG.isDebugEnabled() ) {
286                     LOG.debug("SF Code: " + sfrbAccount.getAccountSufficientFundsCode() + " / Using SF Object Code: '" + tempFinObjectCd + "'" );
287                 }
288                 if (!tempFinObjectCd.equals(currentFinObjectCd)) {
289                     // we have a change or are on the last record, write out the data if there is any
290                     currentFinObjectCd = tempFinObjectCd;
291 
292                     if (currentSfbl != null && amountsAreNonZero(currentSfbl)) {
293                         boService.save(currentSfbl);
294                         ++sfblInsertedCount;
295                     }
296 
297                     currentSfbl = new SufficientFundBalances();
298                     currentSfbl.setUniversityFiscalYear(universityFiscalYear);
299                     currentSfbl.setChartOfAccountsCode(sfrb.getChartOfAccountsCode());
300                     currentSfbl.setAccountNumber(sfrbAccount.getAccountNumber());
301                     currentSfbl.setFinancialObjectCode(currentFinObjectCd);
302                     currentSfbl.setAccountSufficientFundsCode(sfrbAccount.getAccountSufficientFundsCode());
303                     currentSfbl.setAccountActualExpenditureAmt(KualiDecimal.ZERO);
304                     currentSfbl.setAccountEncumbranceAmount(KualiDecimal.ZERO);
305                     currentSfbl.setCurrentBudgetBalanceAmount(KualiDecimal.ZERO);
306                 }
307 
308                 if (sfrbAccount.isForContractsAndGrants()) {
309                     if ( LOG.isDebugEnabled() ) {
310                         LOG.debug("Account is C&G.  Adding C&G beginning balance amount (" + balance.getContractsGrantsBeginningBalanceAmount() + ") to the annual balance amount.");
311                     }
312                     balance.setAccountLineAnnualBalanceAmount(balance.getAccountLineAnnualBalanceAmount().add(balance.getContractsGrantsBeginningBalanceAmount()));
313                 }
314 
315                 if (OLEConstants.SF_TYPE_CASH_AT_ACCOUNT.equals(sfrbAccount.getAccountSufficientFundsCode())) {
316                     if ( LOG.isDebugEnabled() ) {
317                         LOG.debug("SF type is Cash at account");
318                     }
319                     processCash(sfrbAccount, balance);
320                  }
321                 else {
322                     processObjectOrAccount(sfrbAccount, balance);
323                  }
324             }
325 
326             // save the last one
327             if (currentSfbl != null && amountsAreNonZero(currentSfbl)) {
328                 boService.save(currentSfbl);
329                 ++sfblInsertedCount;
330             }
331          }
332         else {
333             addTransactionError(kualiConfigurationService.getPropertyValueAsString(OLEKeyConstants.ERROR_INVALID_ACCOUNT_SF_CODE_FOR));
334             ++warningCount;
335             ++sfrbNotDeletedCount;
336             return;
337         }
338     }
339 
340     /**
341      * Determines if all sums associated with a sufficient funds balance are zero
342      *
343      * @param sfbl the sufficient funds balance to check
344      * @return true if all sums in the balance are zero, false otherwise
345      */
346     protected boolean amountsAreNonZero(SufficientFundBalances sfbl) {
347         boolean zero = true;
348         zero &= KualiDecimal.ZERO.equals(sfbl.getAccountActualExpenditureAmt());
349         zero &= KualiDecimal.ZERO.equals(sfbl.getAccountEncumbranceAmount());
350         zero &= KualiDecimal.ZERO.equals(sfbl.getCurrentBudgetBalanceAmount());
351         return !zero;
352     }
353 
354     /**
355      * Determines how best to process the given balance
356      *
357      * @param sfrbAccount the account of the current sufficient funds balance rebuild record
358      * @param balance the cash encumbrance balance to update the sufficient funds balance with
359      */
360     protected void processObjectOrAccount(Account sfrbAccount, Balance balance) {
361         if (options.getFinObjTypeExpenditureexpCd().equals(balance.getObjectTypeCode()) || options.getFinObjTypeExpendNotExpCode().equals(balance.getObjectTypeCode()) || options.getFinObjTypeExpNotExpendCode().equals(balance.getObjectTypeCode()) || options.getFinancialObjectTypeTransferExpenseCd().equals(balance.getObjectTypeCode())) {
362             if (options.getActualFinancialBalanceTypeCd().equals(balance.getBalanceTypeCode())) {
363                 processObjtAcctActual(balance);
364             }
365             else if (options.getExtrnlEncumFinBalanceTypCd().equals(balance.getBalanceTypeCode()) || options.getIntrnlEncumFinBalanceTypCd().equals(balance.getBalanceTypeCode()) || options.getPreencumbranceFinBalTypeCd().equals(balance.getBalanceTypeCode()) || options.getCostShareEncumbranceBalanceTypeCd().equals(balance.getBalanceTypeCode())) {
366                 processObjtAcctEncmbrnc(balance);
367             }
368             else if (options.getBudgetCheckingBalanceTypeCd().equals(balance.getBalanceTypeCode())) {
369                 processObjtAcctBudget(balance);
370             }
371         } else {
372             if ( LOG.isDebugEnabled() ) {
373                 LOG.debug("Skipped balance record.  Object Type did not match.");
374                 LOG.debug( balance.getObjectTypeCode() + " NOT IN ( " + options.getFinObjTypeExpenditureexpCd() + "," + options.getFinObjTypeExpendNotExpCode() + "," + options.getFinObjTypeExpNotExpendCode() + "," + options.getFinancialObjectTypeTransferExpenseCd() );
375             }
376         }
377     }
378 
379     /**
380      * Updates the current sufficient fund balance record with a non-cash actual balance
381      *
382      * @param balance the cash encumbrance balance to update the sufficient funds balance with
383      */
384     protected void processObjtAcctActual(Balance balance) {
385         currentSfbl.setAccountActualExpenditureAmt(currentSfbl.getAccountActualExpenditureAmt().add(balance.getAccountLineAnnualBalanceAmount()));
386     }
387 
388     /**
389      * Updates the current sufficient fund balance record with a non-cash encumbrance balance
390      *
391      * @param balance the cash encumbrance balance to update the sufficient funds balance with
392      */
393     protected void processObjtAcctEncmbrnc(Balance balance) {
394         currentSfbl.setAccountEncumbranceAmount(currentSfbl.getAccountEncumbranceAmount().add(balance.getAccountLineAnnualBalanceAmount()));
395         currentSfbl.setAccountEncumbranceAmount(currentSfbl.getAccountEncumbranceAmount().add(balance.getBeginningBalanceLineAmount()));
396     }
397 
398     /**
399      * Updates the current sufficient fund balance record with a non-cash budget balance
400      *
401      * @param balance the cash encumbrance balance to update the sufficient funds balance with
402      */
403     protected void processObjtAcctBudget(Balance balance) {
404         currentSfbl.setCurrentBudgetBalanceAmount(currentSfbl.getCurrentBudgetBalanceAmount().add(balance.getAccountLineAnnualBalanceAmount()));
405         currentSfbl.setCurrentBudgetBalanceAmount(currentSfbl.getCurrentBudgetBalanceAmount().add(balance.getBeginningBalanceLineAmount()));
406     }
407 
408     /**
409      * Determines how best to process a cash balance
410      *
411      * @param sfrbAccount the account of the current sufficient funds balance record
412      * @param balance the cash encumbrance balance to update the sufficient funds balance with
413      */
414     protected void processCash(Account sfrbAccount, Balance balance) {
415         if (balance.getBalanceTypeCode().equals(options.getActualFinancialBalanceTypeCd())) {
416             if (balance.getObjectCode().equals(sfrbAccount.getChartOfAccounts().getFinancialCashObjectCode()) || balance.getObjectCode().equals(sfrbAccount.getChartOfAccounts().getFinAccountsPayableObjectCode())) {
417                 processCashActual(sfrbAccount, balance);
418             }
419         }
420         else if (balance.getBalanceTypeCode().equals(options.getExtrnlEncumFinBalanceTypCd()) || balance.getBalanceTypeCode().equals(options.getIntrnlEncumFinBalanceTypCd()) || balance.getBalanceTypeCode().equals(options.getPreencumbranceFinBalTypeCd()) || options.getCostShareEncumbranceBalanceTypeCd().equals(balance.getBalanceTypeCode())) {
421             if (balance.getObjectTypeCode().equals(options.getFinObjTypeExpenditureexpCd()) || balance.getObjectTypeCode().equals(options.getFinObjTypeExpendNotExpCode()) || options.getFinancialObjectTypeTransferExpenseCd().equals(balance.getObjectTypeCode()) || options.getFinObjTypeExpNotExpendCode().equals(balance.getObjectTypeCode())) {
422                 processCashEncumbrance(balance);
423             }
424         }
425     }
426 
427     /**
428      * Updates the current sufficient fund balance record with a cash actual balance
429      *
430      * @param sfrbAccount the account of the current sufficient funds balance record
431      * @param balance the cash encumbrance balance to update the sufficient funds balance with
432      */
433     protected void processCashActual(Account sfrbAccount, Balance balance) {
434         if (balance.getObjectCode().equals(sfrbAccount.getChartOfAccounts().getFinancialCashObjectCode())) {
435             currentSfbl.setCurrentBudgetBalanceAmount(currentSfbl.getCurrentBudgetBalanceAmount().add(balance.getAccountLineAnnualBalanceAmount()));
436             currentSfbl.setCurrentBudgetBalanceAmount(currentSfbl.getCurrentBudgetBalanceAmount().add(balance.getBeginningBalanceLineAmount()));
437         }
438         if (balance.getObjectCode().equals(sfrbAccount.getChartOfAccounts().getFinAccountsPayableObjectCode())) {
439             currentSfbl.setCurrentBudgetBalanceAmount(currentSfbl.getCurrentBudgetBalanceAmount().subtract(balance.getAccountLineAnnualBalanceAmount()));
440             currentSfbl.setCurrentBudgetBalanceAmount(currentSfbl.getCurrentBudgetBalanceAmount().subtract(balance.getBeginningBalanceLineAmount()));
441         }
442     }
443 
444     /**
445      * Updates the current sufficient funds balance with a cash encumbrance balance
446      *
447      * @param balance the cash encumbrance balance to update the sufficient funds balance with
448      */
449     protected void processCashEncumbrance(Balance balance) {
450         currentSfbl.setAccountEncumbranceAmount(currentSfbl.getAccountEncumbranceAmount().add(balance.getAccountLineAnnualBalanceAmount()));
451         currentSfbl.setAccountEncumbranceAmount(currentSfbl.getAccountEncumbranceAmount().add(balance.getBeginningBalanceLineAmount()));
452     }
453 
454     /**
455      * Adds an error message to this instance's List of error messages
456      * @param errorMessage the error message to keep
457      */
458     protected void addTransactionError(String errorMessage) {
459         transactionErrors.add(new Message(errorMessage, Message.TYPE_WARNING));
460     }
461 
462     public void setDateTimeService(DateTimeService dateTimeService) {
463         this.dateTimeService = dateTimeService;
464     }
465 
466     public void setConfigurationService(ConfigurationService kualiConfigurationService) {
467         this.kualiConfigurationService = kualiConfigurationService;
468     }
469 
470     public void setBalanceDao(BalanceDao balanceDao) {
471         this.balanceDao = balanceDao;
472     }
473 
474     public void setSufficientFundBalancesDao(SufficientFundBalancesDao sufficientFundBalancesDao) {
475         this.sufficientFundBalancesDao = sufficientFundBalancesDao;
476     }
477 
478     public void setReportWriterService(ReportWriterService sfrs) {
479         reportWriterService = sfrs;
480     }
481 
482     public void setAccountService(AccountService accountService) {
483         this.accountService = accountService;
484     }
485 
486     public void setSufficientFundsService(SufficientFundsService sfs) {
487         sufficientFundsService = sfs;
488     }
489 
490     public void setBusinessObjectService(BusinessObjectService bos) {
491         boService = bos;
492     }
493 
494     public void setSufficientFundRebuildDao(SufficientFundRebuildDao sufficientFundRebuildDao) {
495         this.sufficientFundRebuildDao = sufficientFundRebuildDao;
496     }
497 }