View Javadoc
1   /*
2    * Copyright 2005 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.fp.document;
17  
18  import static org.kuali.ole.sys.OLEConstants.EMPTY_STRING;
19  
20  import org.apache.commons.lang.StringUtils;
21  import org.kuali.ole.sys.OLEConstants;
22  import org.kuali.ole.sys.OLEKeyConstants;
23  import org.kuali.ole.sys.OLEPropertyConstants;
24  import org.kuali.ole.sys.businessobject.AccountingLine;
25  import org.kuali.ole.sys.businessobject.Bank;
26  import org.kuali.ole.sys.businessobject.GeneralLedgerPendingEntry;
27  import org.kuali.ole.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper;
28  import org.kuali.ole.sys.businessobject.GeneralLedgerPendingEntrySourceDetail;
29  import org.kuali.ole.sys.context.SpringContext;
30  import org.kuali.ole.sys.document.AccountingDocumentBase;
31  import org.kuali.ole.sys.document.AmountTotaling;
32  import org.kuali.ole.sys.document.Correctable;
33  import org.kuali.ole.sys.document.service.AccountingDocumentRuleHelperService;
34  import org.kuali.ole.sys.document.service.DebitDeterminerService;
35  import org.kuali.ole.sys.document.validation.impl.AccountingDocumentRuleBaseConstants.GENERAL_LEDGER_PENDING_ENTRY_CODE;
36  import org.kuali.ole.sys.service.BankService;
37  import org.kuali.ole.sys.service.GeneralLedgerPendingEntryService;
38  import org.kuali.rice.core.api.util.type.KualiDecimal;
39  import org.kuali.rice.krad.document.Copyable;
40  import org.kuali.rice.krad.util.KRADConstants;
41  import org.kuali.rice.krad.util.ObjectUtils;
42  
43  /**
44   * This is the business object that represents the NonCheckDisbursementDocument in Kuali. The "Non-Check Disbursement" document is
45   * used to record charges or credits directly assessed to university bank accounts. It is used primarily by the Tax and Treasury
46   * Accounting office to record wire transfers, foreign drafts, etc.
47   */
48  public class NonCheckDisbursementDocument extends AccountingDocumentBase implements Copyable, Correctable, AmountTotaling {
49      protected String financialDocumentBankCode;
50  
51      protected Bank bank;
52  
53      /**
54       * Constructs a NonCheckDisbursementDocument instance.
55       */
56      public NonCheckDisbursementDocument() {
57          bank = new Bank();
58      }
59  
60      /**
61       * Sets the bank code for a new document to the setup default for the Non Check Disbursement document.
62       */
63      public void setDefaultBankCode() {
64          Bank defaultBank = SpringContext.getBean(BankService.class).getDefaultBankByDocType(this.getClass());
65          if (defaultBank != null) {
66              this.financialDocumentBankCode = defaultBank.getBankCode();
67              this.bank = defaultBank;
68          }
69      }
70  
71      /**
72       * Gets the financialDocumentBankCode attribute.
73       * 
74       * @return Returns the financialDocumentBankCode.
75       */
76      public String getFinancialDocumentBankCode() {
77          return financialDocumentBankCode;
78      }
79  
80      /**
81       * Sets the financialDocumentBankCode attribute value.
82       * 
83       * @param financialDocumentBankCode The financialDocumentBankCode to set.
84       */
85      public void setFinancialDocumentBankCode(String financialDocumentBankCode) {
86          this.financialDocumentBankCode = financialDocumentBankCode;
87      }
88  
89      /**
90       * Gets the bank attribute.
91       * 
92       * @return Returns the bank.
93       */
94      public Bank getBank() {
95          return bank;
96      }
97  
98      /**
99       * Sets the bank attribute value.
100      * 
101      * @param bank The bank to set.
102      */
103     public void setBank(Bank bank) {
104         this.bank = bank;
105     }
106 
107     /**
108      * Overrides the base implementation to return "From".
109      * 
110      * @see org.kuali.ole.sys.document.AccountingDocument#getSourceAccountingLinesSectionTitle()
111      */
112     @Override
113     public String getSourceAccountingLinesSectionTitle() {
114         return EMPTY_STRING;
115     }
116 
117     /**
118      * This method determines if a given accounting line is a debit accounting line. This is done by calling
119      * IsDebitUtiles.isDebitConsideringNothingPositiveOnly(). An IllegalStateException will be thrown if the accounting line passed
120      * in is not an expense, is an error correction with a positive dollar amount or is not an error correction and has a negative
121      * amount.
122      * 
123      * @param transactionalDocument The document the accounting line being checked is located in.
124      * @param accountingLine The accounting line being analyzed.
125      * @return True if the accounting line given is a debit accounting line, false otherwise.
126      * @throws IllegalStateException Thrown if accounting line attributes are invalid.
127      * @see IsDebitUtils#isDebitConsideringNothingPositiveOnly(FinancialDocumentRuleBase, FinancialDocument, AccountingLine)
128      * @see org.kuali.rice.krad.rule.AccountingLineRule#isDebit(org.kuali.rice.krad.document.FinancialDocument,
129      *      org.kuali.rice.krad.bo.AccountingLine)
130      */
131     public boolean isDebit(GeneralLedgerPendingEntrySourceDetail postable) throws IllegalStateException {
132         DebitDeterminerService isDebitUtils = SpringContext.getBean(DebitDeterminerService.class);
133         return isDebitUtils.isDebitConsideringNothingPositiveOnly(this, (AccountingLine) postable);
134     }
135 
136     /**
137      * This method sets attributes on the explicitly general ledger pending entry specific to NonCheckDisbursement documents. This
138      * includes setting the transaction ledger entry description and blanking out the reference financial document number, the
139      * reference financial system origin code and the reference financial document type code. These values must be nullified because
140      * they don't belong in general ledger pending entries and if they aren't null, the general error corrections won't post
141      * properly.
142      * 
143      * @param financialDocument The document which contains the general ledger pending entry being modified.
144      * @param accountingLine The accounting line the explicit entry was generated from.
145      * @param explicitEntry The explicit entry being updated.
146      * @see FinancialDocumentRuleBase#customizeExplicitGeneralLedgerPendingEntry(FinancialDocument, AccountingLine,
147      *      GeneralLedgerPendingEntry)
148      */
149     @Override
150     public void customizeExplicitGeneralLedgerPendingEntry(GeneralLedgerPendingEntrySourceDetail postable, GeneralLedgerPendingEntry explicitEntry) {
151         explicitEntry.setTransactionLedgerEntryDescription(buildTransactionLedgerEntryDescriptionUsingRefOriginAndRefDocNumber(postable));
152 
153         // Clearing fields that are already handled by the parent algorithm - we don't actually want
154         // these to copy over from the accounting lines b/c they don't belong in the GLPEs
155         // if they aren't nulled, then GECs fail to post
156         explicitEntry.setReferenceFinancialDocumentNumber(null);
157         explicitEntry.setReferenceFinancialSystemOriginationCode(null);
158         explicitEntry.setReferenceFinancialDocumentTypeCode(null);
159     }
160 
161     /**
162      * @see org.kuali.ole.sys.document.AccountingDocumentBase#generateDocumentGeneralLedgerPendingEntries(org.kuali.ole.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper)
163      */
164     @Override
165     public boolean generateDocumentGeneralLedgerPendingEntries(GeneralLedgerPendingEntrySequenceHelper sequenceHelper) {
166         boolean success = true;
167 
168         if (!SpringContext.getBean(BankService.class).isBankSpecificationEnabled()) {
169             return success;
170         }
171         
172         this.refreshReferenceObject(OLEPropertyConstants.BANK);
173 
174         if (!ObjectUtils.isNull(getBank())) {
175 
176         GeneralLedgerPendingEntryService glpeService = SpringContext.getBean(GeneralLedgerPendingEntryService.class);
177 
178         final KualiDecimal bankOffsetAmount = glpeService.getOffsetToCashAmount(this).negated();
179         GeneralLedgerPendingEntry bankOffsetEntry = new GeneralLedgerPendingEntry();
180             success &= glpeService.populateBankOffsetGeneralLedgerPendingEntry(getBank(), bankOffsetAmount, this, getPostingYear(), sequenceHelper, bankOffsetEntry, KRADConstants.DOCUMENT_PROPERTY_NAME + "." + OLEPropertyConstants.FINANCIAL_DOCUMENT_BANK_CODE);
181 
182         if (success) {
183             AccountingDocumentRuleHelperService accountingDocumentRuleUtil = SpringContext.getBean(AccountingDocumentRuleHelperService.class);
184             bankOffsetEntry.setTransactionLedgerEntryDescription(accountingDocumentRuleUtil.formatProperty(OLEKeyConstants.Bank.DESCRIPTION_GLPE_BANK_OFFSET));
185             getGeneralLedgerPendingEntries().add(bankOffsetEntry);
186             sequenceHelper.increment();
187 
188             GeneralLedgerPendingEntry offsetEntry = new GeneralLedgerPendingEntry(bankOffsetEntry);
189             success &= glpeService.populateOffsetGeneralLedgerPendingEntry(getPostingYear(), bankOffsetEntry, sequenceHelper, offsetEntry);
190             getGeneralLedgerPendingEntries().add(offsetEntry);
191             sequenceHelper.increment();
192         }
193         }
194 
195         return success;
196     }
197 
198     /**
199      * Builds an appropriately formatted string to be used for the <code>transactionLedgerEntryDescription</code>. It is built
200      * using information from the <code>{@link AccountingLine}</code>. Format is "01-12345: blah blah blah".
201      * 
202      * @param financialDocument The document the description will be pulled from, if the accounting line description is blank.
203      * @param line The accounting line that will be used for populating the transaction ledger entry description.
204      * @return The description to be applied to the transaction ledger entry.
205      */
206     protected String buildTransactionLedgerEntryDescriptionUsingRefOriginAndRefDocNumber(GeneralLedgerPendingEntrySourceDetail postable) {
207         String description = "";
208         if (StringUtils.isBlank(postable.getReferenceNumber())) {
209             throw new IllegalStateException("Reference Document Number is required and should be validated before this point.");
210         }
211 
212         description = OLEConstants.ORIGIN_CODE_KUALI + "-" + postable.getReferenceNumber();
213 
214         if (StringUtils.isNotBlank(postable.getFinancialDocumentLineDescription())) {
215             description += ": " + postable.getFinancialDocumentLineDescription();
216         }
217         else {
218             description += ": " + getDocumentHeader().getDocumentDescription();
219         }
220 
221         if (description.length() > GENERAL_LEDGER_PENDING_ENTRY_CODE.GLPE_DESCRIPTION_MAX_LENGTH) {
222             description = description.substring(0, GENERAL_LEDGER_PENDING_ENTRY_CODE.GLPE_DESCRIPTION_MAX_LENGTH - 3) + "...";
223         }
224 
225         return description;
226     }
227 }