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;
17  
18  import java.io.PrintStream;
19  import java.sql.Date;
20  import java.util.HashMap;
21  import java.util.Map;
22  
23  import org.kuali.ole.coa.businessobject.BalanceType;
24  import org.kuali.ole.coa.businessobject.PriorYearAccount;
25  import org.kuali.ole.coa.service.BalanceTypeService;
26  import org.kuali.ole.coa.service.PriorYearAccountService;
27  import org.kuali.ole.coa.service.SubFundGroupService;
28  import org.kuali.ole.gl.ObjectHelper;
29  import org.kuali.ole.gl.batch.service.impl.exception.NonFatalErrorException;
30  import org.kuali.ole.gl.businessobject.Balance;
31  import org.kuali.ole.gl.businessobject.OriginEntryFull;
32  import org.kuali.ole.gl.report.LedgerSummaryReport;
33  import org.kuali.ole.gl.service.OriginEntryService;
34  import org.kuali.ole.sys.OLEConstants;
35  import org.kuali.ole.sys.businessobject.SystemOptions;
36  import org.kuali.ole.sys.context.SpringContext;
37  import org.kuali.ole.sys.exception.InvalidFlexibleOffsetException;
38  import org.kuali.ole.sys.service.FlexibleOffsetAccountService;
39  import org.kuali.ole.sys.service.OptionsService;
40  import org.kuali.ole.sys.service.ReportWriterService;
41  import org.kuali.ole.sys.service.impl.OleParameterConstants;
42  import org.kuali.rice.core.api.util.type.KualiDecimal;
43  import org.kuali.rice.coreservice.framework.parameter.ParameterService;
44  import org.kuali.rice.krad.util.ObjectUtils;
45  
46  /**
47   * A class to hold significant state for a balance forward job; it also has the methods that actually accomplish the job
48   */
49  public class BalanceForwardRuleHelper {
50      private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(BalanceForwardRuleHelper.class);
51      private FlexibleOffsetAccountService flexibleOffsetAccountService;
52  
53      /**
54       * A container for the state of the balance forward process. The way state is handled is heavily dependent upon the way in which
55       * YearEndServiceImpl.forwardBalancesForFiscalYear works.
56       */
57      public static class BalanceForwardProcessState {
58          private int globalReadCount;
59          private int globalSelectCount;
60          private int sequenceNumber;
61          private int sequenceClosedCount;
62          private int sequenceWriteCount;
63          private String accountNumberHold;
64          private int nonFatalCount;
65  
66          public String getAccountNumberHold() {
67              return accountNumberHold;
68          }
69  
70          public void setAccountNumberHold(String accountNumberHold) {
71              this.accountNumberHold = accountNumberHold;
72          }
73  
74          public void incrementGlobalReadCount() {
75              globalReadCount++;
76          }
77  
78          public void incrementGlobalSelectCount() {
79              globalSelectCount++;
80          }
81  
82          public void incrementSequenceNumber() {
83              sequenceNumber++;
84          }
85  
86          public void incrementSequenceClosedCount() {
87              sequenceClosedCount++;
88          }
89  
90          public void incrementSequenceWriteCount() {
91              sequenceWriteCount++;
92          }
93  
94          public void incrementNonFatalCount() {
95              nonFatalCount += 1;
96          }
97  
98          public int getGlobalReadCount() {
99              return globalReadCount;
100         }
101 
102         public void setGlobalReadCount(int globalReadCount) {
103             this.globalReadCount = globalReadCount;
104         }
105 
106         public int getGlobalSelectCount() {
107             return globalSelectCount;
108         }
109 
110         public void setGlobalSelectCount(int globalSelectCount) {
111             this.globalSelectCount = globalSelectCount;
112         }
113 
114         public int getSequenceClosedCount() {
115             return sequenceClosedCount;
116         }
117 
118         public int getNonFatalCount() {
119             return nonFatalCount;
120         }
121 
122         public void setSequenceClosedCount(int sequenceClosedCount) {
123             this.sequenceClosedCount = sequenceClosedCount;
124         }
125 
126         public int getSequenceNumber() {
127             return sequenceNumber;
128         }
129 
130         public void setSequenceNumber(int sequenceNumber) {
131             this.sequenceNumber = sequenceNumber;
132         }
133 
134         public int getSequenceWriteCount() {
135             return sequenceWriteCount;
136         }
137 
138         public void setSequenceWriteCount(int sequenceWriteCount) {
139             this.sequenceWriteCount = sequenceWriteCount;
140         }
141 
142         public void setNonFatalCount(int nonFatalCount) {
143             this.nonFatalCount = nonFatalCount;
144         }
145     }
146 
147     private Integer closingFiscalYear;
148     private Date transactionDate;
149     
150     private String balanceForwardsUnclosedFileName; 
151     private String balanceForwardsclosedFileName;
152     
153     private PriorYearAccountService priorYearAccountService;
154     private SubFundGroupService subFundGroupService;
155     private OriginEntryService originEntryService;
156     private ParameterService parameterService;
157     private SystemOptions currentYearOptions;
158     private LedgerSummaryReport openAccountForwardBalanceLedgerReport;
159     private LedgerSummaryReport closedAccountForwardBalanceLedgerReport;
160     private String[] priorYearAccountObjectTypes;
161     private String[] generalSwObjectTypes;
162     private String annualClosingDocType;
163     private String glOriginationCode;
164     private Map<String, Boolean> balanceTypeEncumbranceIndicators;
165 
166     private BalanceForwardProcessState state;
167 
168     /**
169      * Constructs a BalanceForwardRuleHelper
170      */
171     public BalanceForwardRuleHelper() {
172         super();
173         state = new BalanceForwardProcessState();
174         flexibleOffsetAccountService = SpringContext.getBean(FlexibleOffsetAccountService.class);
175         parameterService = SpringContext.getBean(ParameterService.class);
176         annualClosingDocType = parameterService.getParameterValueAsString(OleParameterConstants.GENERAL_LEDGER_BATCH.class, OLEConstants.SystemGroupParameterNames.GL_ANNUAL_CLOSING_DOC_TYPE);
177         glOriginationCode = parameterService.getParameterValueAsString(OleParameterConstants.GENERAL_LEDGER_BATCH.class, OLEConstants.SystemGroupParameterNames.GL_ORIGINATION_CODE);
178         openAccountForwardBalanceLedgerReport = new LedgerSummaryReport();
179         closedAccountForwardBalanceLedgerReport = new LedgerSummaryReport();
180     }
181 
182     /**
183      * Constructs a BalanceForwardRuleHelper, using a fiscal year. This also initializes object type arrays based on the options of
184      * the closing fiscal year
185      * 
186      * @param closingFiscalYear the fiscal year that is closing out
187      */
188     public BalanceForwardRuleHelper(Integer closingFiscalYear) {
189         this();
190         setClosingFiscalYear(closingFiscalYear);
191 
192         SystemOptions jobYearRunOptions = SpringContext.getBean(OptionsService.class).getOptions(closingFiscalYear);
193 
194         generalSwObjectTypes = new String[3];
195         generalSwObjectTypes[0] = jobYearRunOptions.getFinancialObjectTypeAssetsCd();
196         generalSwObjectTypes[1] = jobYearRunOptions.getFinObjectTypeLiabilitiesCode();
197         generalSwObjectTypes[2] = jobYearRunOptions.getFinObjectTypeFundBalanceCd();
198 
199         // "EE", "ES", "EX", "IC", "TE", "TI", "IN", "CH"
200         priorYearAccountObjectTypes = new String[8];
201         priorYearAccountObjectTypes[0] = jobYearRunOptions.getFinObjTypeExpendNotExpCode();
202         priorYearAccountObjectTypes[1] = jobYearRunOptions.getFinObjTypeExpNotExpendCode();
203         priorYearAccountObjectTypes[2] = jobYearRunOptions.getFinObjTypeExpenditureexpCd();
204         priorYearAccountObjectTypes[3] = jobYearRunOptions.getFinObjTypeIncomeNotCashCd();
205         priorYearAccountObjectTypes[4] = jobYearRunOptions.getFinancialObjectTypeTransferExpenseCd();
206         priorYearAccountObjectTypes[5] = jobYearRunOptions.getFinancialObjectTypeTransferIncomeCd();
207         priorYearAccountObjectTypes[6] = jobYearRunOptions.getFinObjectTypeIncomecashCode();
208         priorYearAccountObjectTypes[7] = jobYearRunOptions.getFinObjTypeCshNotIncomeCd();
209     }
210 
211     /**
212      * Constructs a BalanceForwardRuleHelper, but this one goes whole hog: initializes all of the relevant parameters and the
213      * balance types to process
214      * 
215      * @param closingFiscalYear the fiscal year to close
216      * @param transactionDate the date this job is being run
217      * @param closedPriorYearAccountGroup the group to put balance forwarding origin entries with closed accounts into
218      * @param unclosedPriorYearAccountGroup the group to put balance forwarding origin entries with open accounts into
219      */
220     public BalanceForwardRuleHelper(Integer closingFiscalYear, Date transactionDate, String balanceForwardsclosedFileName, String balanceForwardsUnclosedFileName) {
221         this(closingFiscalYear);
222         setTransactionDate(transactionDate);
223         setClosingFiscalYear(closingFiscalYear);
224         
225         setBalanceForwardsclosedFileName(balanceForwardsclosedFileName);
226         setBalanceForwardsUnclosedFileName(balanceForwardsUnclosedFileName);
227         currentYearOptions = SpringContext.getBean(OptionsService.class).getCurrentYearOptions();
228 
229         balanceTypeEncumbranceIndicators = new HashMap<String, Boolean>();
230         for (Object balanceTypAsObj : SpringContext.getBean(BalanceTypeService.class).getAllBalanceTypes()) {
231             BalanceType balanceType = (BalanceType) balanceTypAsObj;
232             balanceTypeEncumbranceIndicators.put(balanceType.getCode(), (balanceType.isFinBalanceTypeEncumIndicator() ? Boolean.TRUE : Boolean.FALSE));
233         }
234     }
235 
236 
237     /**
238      * The balance to create a general balance forward origin entry for
239      * 
240      * @param balance a balance to create an origin entry for
241      * @param closedPriorYearAccountGroup the group to put balance forwarding origin entries with closed accounts into
242      * @param unclosedPriorYearAccountGroup the group to put balance forwarding origin entries with open accounts into
243      * @throws FatalErrorException
244      */
245     public void processGeneralForwardBalance(Balance balance, PrintStream closedPs, PrintStream unclosedPs) {
246         if (ObjectUtils.isNull(balance.getPriorYearAccount())) {
247             LOG.info(("COULD NOT RETRIEVE INFORMATION ON ACCOUNT " + balance.getChartOfAccountsCode() + "-" + balance.getAccountNumber()));
248         } 
249         else {
250             if ((null == balance.getAccountNumber() && null == state.getAccountNumberHold()) || (null != balance.getAccountNumber() && balance.getAccountNumber().equals(state.getAccountNumberHold()))) {
251                 state.incrementSequenceNumber();
252             }
253             else {
254                 state.setSequenceNumber(1);
255             }
256             state.incrementGlobalSelectCount();
257             OriginEntryFull entry = generateGeneralForwardOriginEntry(balance);
258             saveForwardingEntry(balance, entry, closedPs, unclosedPs);
259         }
260     }
261 
262     /**
263      * This method creates an origin entry for a cumulative balance forward and saves it in its proper origin entry group
264      * 
265      * @param balance a balance which needs to have a cumulative origin entry generated for it
266      * @param closedPriorYearAccountGroup the origin entry group where forwarding origin entries with closed prior year accounts go
267      * @param unclosedPriorYearAcocuntGroup the origin entry group where forwarding origin entries with open prior year accounts go
268      */
269     public void processCumulativeForwardBalance(Balance balance, PrintStream closedPs, PrintStream unclosedPs) {
270         if ((null == balance.getAccountNumber() && null == state.getAccountNumberHold()) || (null != balance.getAccountNumber() && balance.getAccountNumber().equals(state.getAccountNumberHold()))) {
271             state.incrementSequenceNumber();
272         }
273         else {
274             state.setSequenceNumber(1);
275         }
276         state.incrementGlobalSelectCount();
277         OriginEntryFull activeEntry = generateCumulativeForwardOriginEntry(balance);
278         saveForwardingEntry(balance, activeEntry, closedPs, unclosedPs);
279     }
280 
281     /**
282      * This method generates an origin entry for a given cumulative balance forward balance
283      * 
284      * @param balance a balance to foward, cumulative style
285      * @return an OriginEntryFull to forward the given balance
286      */
287     public OriginEntryFull generateCumulativeForwardOriginEntry(Balance balance) {
288         OriginEntryFull activeEntry = new OriginEntryFull();
289         activeEntry.setUniversityFiscalYear(new Integer(closingFiscalYear.intValue() + 1));
290         activeEntry.setChartOfAccountsCode(balance.getChartOfAccountsCode());
291         activeEntry.setAccountNumber(balance.getAccountNumber());
292         activeEntry.setSubAccountNumber(balance.getSubAccountNumber());
293         activeEntry.setFinancialObjectCode(balance.getObjectCode());
294         activeEntry.setFinancialSubObjectCode(balance.getSubObjectCode());
295         activeEntry.setFinancialBalanceTypeCode(balance.getBalanceTypeCode());
296         activeEntry.setFinancialObjectTypeCode(balance.getObjectTypeCode());
297 
298         try {
299             flexibleOffsetAccountService.updateOffset(activeEntry);
300         }
301         catch (InvalidFlexibleOffsetException e) {
302             if (LOG.isDebugEnabled()) {
303                 LOG.debug("processBalance() Balance Forward Flexible Offset Error: " + e.getMessage());    
304             }
305         }
306         activeEntry.setUniversityFiscalPeriodCode(OLEConstants.PERIOD_CODE_CG_BEGINNING_BALANCE);
307         activeEntry.setFinancialDocumentTypeCode(this.annualClosingDocType);
308         activeEntry.setFinancialSystemOriginationCode(this.glOriginationCode);
309         activeEntry.setDocumentNumber(new StringBuffer(OLEConstants.BALANCE_TYPE_ACTUAL).append(balance.getAccountNumber()).toString());
310         activeEntry.setTransactionLedgerEntrySequenceNumber(new Integer(state.getSequenceNumber()));
311         activeEntry.setTransactionLedgerEntryDescription(new StringBuffer("BEG C & G BAL BROUGHT FORWARD FROM ").append(closingFiscalYear).toString());
312         activeEntry.setTransactionLedgerEntryAmount(balance.getAccountLineAnnualBalanceAmount().add(balance.getContractsGrantsBeginningBalanceAmount()));
313         if (OLEConstants.BALANCE_TYPE_CURRENT_BUDGET.equals(balance.getBalanceTypeCode()) 
314                 || OLEConstants.BALANCE_TYPE_BASE_BUDGET.equals(balance.getBalanceTypeCode())  ) {
315             activeEntry.setTransactionDebitCreditCode(null);
316         }
317         else {
318 
319             String wsFinancialObjectTypeDebitCreditCode = null;
320 
321             try {
322                 wsFinancialObjectTypeDebitCreditCode = getFinancialObjectTypeDebitCreditCode(balance);
323             }
324             catch (NonFatalErrorException nfee) {
325                 getState().incrementNonFatalCount();
326                 wsFinancialObjectTypeDebitCreditCode = OLEConstants.GL_CREDIT_CODE;
327                 LOG.info(nfee.getMessage());
328             }
329             if (activeEntry.getTransactionLedgerEntryAmount().isNegative()) {
330                 if (OLEConstants.GL_CREDIT_CODE.equals(wsFinancialObjectTypeDebitCreditCode)) {
331                     activeEntry.setTransactionDebitCreditCode(OLEConstants.GL_DEBIT_CODE);
332                 }
333                 else {
334                     activeEntry.setTransactionDebitCreditCode(OLEConstants.GL_CREDIT_CODE);
335                 }
336             }
337             else {
338                 activeEntry.setTransactionDebitCreditCode(wsFinancialObjectTypeDebitCreditCode);
339             }
340 
341         }
342         activeEntry.setTransactionDate(transactionDate);
343         activeEntry.setOrganizationDocumentNumber(null);
344         activeEntry.setProjectCode(OLEConstants.getDashProjectCode());
345         activeEntry.setOrganizationReferenceId(null);
346         activeEntry.setReferenceFinancialDocumentNumber(null);
347         activeEntry.setReferenceFinancialSystemOriginationCode(null);
348         activeEntry.setReferenceFinancialDocumentNumber(null);
349         activeEntry.setReversalDate(null);
350         String transactionEncumbranceUpdateCode = null;
351         try {
352             transactionEncumbranceUpdateCode = getTransactionEncumbranceUpdateCode(balance);
353         }
354         catch (NonFatalErrorException nfee) {
355             getState().incrementNonFatalCount();
356             LOG.info(nfee.getMessage());
357         }
358 
359         activeEntry.setTransactionEncumbranceUpdateCode(transactionEncumbranceUpdateCode);
360         if (OLEConstants.BALANCE_TYPE_AUDIT_TRAIL.equals(balance.getBalanceTypeCode())) {
361             activeEntry.setFinancialBalanceTypeCode(OLEConstants.BALANCE_TYPE_ACTUAL);
362         }
363         if (activeEntry.getTransactionLedgerEntryAmount().isNegative()) {
364             if (OLEConstants.BALANCE_TYPE_ACTUAL.equals(activeEntry.getFinancialBalanceTypeCode())) {
365                 activeEntry.setTransactionLedgerEntryAmount(activeEntry.getTransactionLedgerEntryAmount().negated());
366             }
367         }
368 
369         return activeEntry;
370     }
371 
372     /**
373      * Creates an origin entry that will forward this "general" balance
374      * 
375      * @param balance the balance to create a general origin entry for
376      * @return the generated origin entry
377      */
378     public OriginEntryFull generateGeneralForwardOriginEntry(Balance balance) {
379 
380         OriginEntryFull entry = new OriginEntryFull();
381         entry.setUniversityFiscalYear(new Integer(closingFiscalYear.intValue() + 1));
382         entry.setChartOfAccountsCode(balance.getChartOfAccountsCode());
383         entry.setAccountNumber(balance.getAccountNumber());
384         entry.setSubAccountNumber(balance.getSubAccountNumber());
385         entry.setFinancialObjectCode(balance.getObjectCode());
386         entry.setFinancialSubObjectCode(balance.getSubObjectCode());
387         entry.setFinancialBalanceTypeCode(balance.getBalanceTypeCode());
388         if (currentYearOptions.getFinObjTypeExpendNotExpCode().equals(balance.getObjectTypeCode())) {
389             entry.setFinancialObjectTypeCode(currentYearOptions.getFinancialObjectTypeAssetsCd());
390         }
391         else {
392             entry.setFinancialObjectTypeCode(balance.getObjectTypeCode());
393         }
394         entry.setUniversityFiscalPeriodCode(OLEConstants.PERIOD_CODE_BEGINNING_BALANCE);
395         entry.setFinancialDocumentTypeCode(this.annualClosingDocType);
396         entry.setFinancialSystemOriginationCode(this.glOriginationCode);
397 
398         // FIXME Once tests are running properly uncomment the code to include the
399         // chartOfAccountsCode in the document number. It will cause the tests to
400         // break given the current framework but is desired as an enhancement for Kuali.
401         entry.setDocumentNumber(new StringBuffer(OLEConstants.BALANCE_TYPE_ACTUAL).append(balance.getAccountNumber())/* .append(balance.getChartOfAccountsCode()) */.toString());
402         entry.setTransactionLedgerEntrySequenceNumber(new Integer(state.getSequenceNumber()));
403         entry.setTransactionLedgerEntryDescription(new StringBuffer("BEG BAL BROUGHT FORWARD FROM ").append(closingFiscalYear).toString());
404 
405         String transactionEncumbranceUpdateCode = null;
406         try {
407             transactionEncumbranceUpdateCode = getTransactionEncumbranceUpdateCode(balance);
408         }
409         catch (NonFatalErrorException nfee) {
410             getState().incrementNonFatalCount();
411             LOG.info(nfee.getMessage());
412         }
413         entry.setTransactionEncumbranceUpdateCode(transactionEncumbranceUpdateCode);
414         KualiDecimal transactionLedgerEntryAmount = KualiDecimal.ZERO;
415         transactionLedgerEntryAmount = transactionLedgerEntryAmount.add(balance.getAccountLineAnnualBalanceAmount()).add(balance.getBeginningBalanceLineAmount()).add(balance.getContractsGrantsBeginningBalanceAmount());
416 
417         String wsFinancialObjectTypeDebitCreditCode = null;
418         try {
419             wsFinancialObjectTypeDebitCreditCode = getFinancialObjectTypeDebitCreditCode(balance);
420         }
421         catch (NonFatalErrorException nfee) {
422             getState().incrementNonFatalCount();
423             wsFinancialObjectTypeDebitCreditCode = OLEConstants.GL_CREDIT_CODE;
424             LOG.info(nfee.getMessage());
425         }
426 
427         if (transactionLedgerEntryAmount.isNegative()) {
428             if (OLEConstants.GL_DEBIT_CODE.equals(wsFinancialObjectTypeDebitCreditCode)) {
429                 entry.setTransactionDebitCreditCode(OLEConstants.GL_CREDIT_CODE);
430             }
431             else {
432                 entry.setTransactionDebitCreditCode(OLEConstants.GL_DEBIT_CODE);
433             }
434         }
435         else {
436             entry.setTransactionDebitCreditCode(wsFinancialObjectTypeDebitCreditCode);
437         }
438         entry.setTransactionDate(transactionDate);
439         entry.setOrganizationDocumentNumber(null);
440         entry.setProjectCode(OLEConstants.getDashProjectCode());
441         entry.setOrganizationReferenceId(null);
442         entry.setReferenceFinancialDocumentTypeCode(null);
443         entry.setReferenceFinancialSystemOriginationCode(null);
444         entry.setReferenceFinancialDocumentNumber(null);
445         entry.setFinancialDocumentReversalDate(null);
446         if (OLEConstants.BALANCE_TYPE_AUDIT_TRAIL.equals(entry.getFinancialBalanceTypeCode())) {
447             entry.setFinancialBalanceTypeCode(OLEConstants.BALANCE_TYPE_ACTUAL);
448         }
449         if (transactionLedgerEntryAmount.isNegative()) {
450             if (OLEConstants.BALANCE_TYPE_ACTUAL.equals(entry.getFinancialBalanceTypeCode())) {
451                 transactionLedgerEntryAmount = transactionLedgerEntryAmount.negated();
452             }
453         }
454         entry.setTransactionLedgerEntryAmount(transactionLedgerEntryAmount);
455         return entry;
456     }
457 
458     /**
459      * Retrieves the transaction encumbrance update code, based on the balance type code of the balance. These codes are cached,
460      * based off a cache generated in the big constructor
461      * 
462      * @param balance the balance to find the encumbrance update code for
463      * @return the transaction update code
464      * @throws NonFatalErrorException if an encumbrance update code cannot be found for this balance
465      */
466     private String getTransactionEncumbranceUpdateCode(Balance balance) throws NonFatalErrorException {
467         String updateCode = null;
468         Boolean encumIndicator = this.balanceTypeEncumbranceIndicators.get(balance.getBalanceTypeCode());
469         if (encumIndicator == null) {
470             throw new NonFatalErrorException(new StringBuffer(" ERROR ").append(balance.getBalanceTypeCode()).append(" NOT ON TABLE ").toString());
471         }
472         else if (encumIndicator.booleanValue()) {
473             updateCode = OLEConstants.ENCUMB_UPDT_NO_ENCUMBRANCE_CD;
474         }
475 
476         return updateCode;
477     }
478 
479     /**
480      * This method attempts to determine the debit/credit code of a given balance based on the object type
481      * 
482      * @param balance the balance to determin the debit/credit code for
483      * @return the debit or credit code
484      */
485     private String getFinancialObjectTypeDebitCreditCode(Balance balance) throws NonFatalErrorException {
486         String balanceObjectTypeDebitCreditCode = null != balance.getObjectType() ? balance.getObjectType().getFinObjectTypeDebitcreditCd() : null;
487 
488         String wsFinancialObjectTypeDebitCreditCode = null;
489 
490         if (null != balanceObjectTypeDebitCreditCode) {
491             if (ObjectHelper.isOneOf(balanceObjectTypeDebitCreditCode, new String[] { OLEConstants.GL_CREDIT_CODE, OLEConstants.GL_DEBIT_CODE })) {
492                 wsFinancialObjectTypeDebitCreditCode = balanceObjectTypeDebitCreditCode;
493             }
494             else {
495                 wsFinancialObjectTypeDebitCreditCode = OLEConstants.GL_CREDIT_CODE;
496             }
497         }
498         else {
499             throw new NonFatalErrorException(new StringBuffer("FIN OBJ TYP CODE ").append(balance.getObjectTypeCode()).append(" NOT IN TABLE").toString());
500         }
501         return wsFinancialObjectTypeDebitCreditCode;
502     }
503 
504     /**
505      * Saves a generated origin entry to the database, within the proper group
506      * 
507      * @param balance the original balance, which still has the account to check if it is closed or not
508      * @param entry the origin entry to save
509      * @param closedPriorYearAccountGroup the group to put balance forwarding origin entries with closed accounts into
510      * @param unclosedPriorYearAccountGroup the group to put balance forwarding origin entries with open accounts into
511      */
512     private void saveForwardingEntry(Balance balance, OriginEntryFull entry, PrintStream closedPs, PrintStream unclosedPs) {
513         final PriorYearAccount account = priorYearAccountService.getByPrimaryKey(balance.getChartOfAccountsCode(), balance.getAccountNumber());
514         if (ObjectUtils.isNotNull(account) && !account.isClosed()) {
515             if (LOG.isDebugEnabled()) {
516                 LOG.debug("Prior Year Account "+account.getChartOfAccountsCode()+"-"+account.getAccountNumber()+" is not closed");
517             }
518             originEntryService.createEntry(entry, unclosedPs);
519             state.incrementSequenceWriteCount();
520             openAccountForwardBalanceLedgerReport.summarizeEntry(entry);
521 
522             if (0 == state.getSequenceWriteCount() % 1000) {
523                 LOG.info("  SEQUENTIAL RECORDS WRITTEN = " + state.getSequenceWriteCount());
524             }
525         }
526         else {
527             if (LOG.isDebugEnabled()) {
528                 if (ObjectUtils.isNull(account)) {
529                     LOG.debug("Prior Year Account for "+balance.getChartOfAccountsCode()+"-"+balance.getAccountNumber()+" cannot be found");
530                 } else {
531                     LOG.debug("Prior Year Account "+account.getChartOfAccountsCode()+"-"+account.getAccountNumber()+" is closed");
532                 }
533             }
534             originEntryService.createEntry(entry, closedPs);
535             state.incrementSequenceClosedCount();
536             closedAccountForwardBalanceLedgerReport.summarizeEntry(entry);
537             if (0 == state.getSequenceClosedCount() % 1000) {
538                 LOG.info("  CLOSED SEQUENTIAL RECORDS WRITTEN = " + state.getSequenceClosedCount());
539             }
540         }
541     }
542 
543     /**
544      * Writes the ledger report for general balance forward entries to the given reportWriterService
545      * @param reportWriteService the reportWriterService to write to
546      */
547     public void writeOpenAccountBalanceForwardLedgerSummaryReport(ReportWriterService reportWriterService) {
548         openAccountForwardBalanceLedgerReport.writeReport(reportWriterService);
549     }
550     
551     /**
552      * Writes the ledger report for cumulative balance forward entries to the given reportWriterService
553      * @param reportWriteService the reportWriterService to write to
554      */
555     public void writeClosedAccountBalanceForwardLedgerSummaryReport(ReportWriterService reportWriterService) {
556         closedAccountForwardBalanceLedgerReport.writeReport(reportWriterService);
557     }
558     
559     /**
560      * @param priorYearAccountService The priorYearAccountService to set.
561      */
562     public void setPriorYearAccountService(PriorYearAccountService priorYearAccountService) {
563         this.priorYearAccountService = priorYearAccountService;
564     }
565 
566     /**
567      * @param subFundGroupService The subFundGroupService to set.
568      */
569     public void setSubFundGroupService(SubFundGroupService subFundGroupService) {
570         this.subFundGroupService = subFundGroupService;
571     }
572 
573     /**
574      * @param originEntryService The originEntryService to set.
575      */
576     public void setOriginEntryService(OriginEntryService originEntryService) {
577         this.originEntryService = originEntryService;
578     }
579 
580     public Integer getClosingFiscalYear() {
581         return closingFiscalYear;
582     }
583 
584     public void setClosingFiscalYear(Integer fiscalYear) {
585         this.closingFiscalYear = fiscalYear;
586     }
587 
588     public Date getTransactionDate() {
589         return transactionDate;
590     }
591 
592     public void setTransactionDate(Date transactionDate) {
593         this.transactionDate = transactionDate;
594     }
595 
596     public String getBalanceForwardsUnclosedFileName() {
597         return balanceForwardsUnclosedFileName;
598     }
599 
600     public void setBalanceForwardsUnclosedFileName(String balanceForwardsUnclosedFileName) {
601         this.balanceForwardsUnclosedFileName = balanceForwardsUnclosedFileName;
602     }
603 
604     public String getBalanceForwardsclosedFileName() {
605         return balanceForwardsclosedFileName;
606     }
607 
608     public void setBalanceForwardsclosedFileName(String balanceForwardsclosedFileName) {
609         this.balanceForwardsclosedFileName = balanceForwardsclosedFileName;
610     }
611 
612     public BalanceForwardProcessState getState() {
613         return state;
614     }
615 
616     /**
617      * Gets the glOriginationCode attribute. 
618      * @return Returns the glOriginationCode.
619      */
620     public String getGlOriginationCode() {
621         return glOriginationCode;
622     }
623 
624     /**
625      * Gets the annualClosingDocType attribute. 
626      * @return Returns the annualClosingDocType.
627      */
628     public String getAnnualClosingDocType() {
629         return annualClosingDocType;
630     }
631 }