001 /* 002 * Copyright 2011 The Kuali Foundation. 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.kuali.kfs.fp.document; 017 018 import static org.kuali.kfs.sys.KFSConstants.EMPTY_STRING; 019 020 import org.apache.commons.lang.StringUtils; 021 import org.kuali.kfs.fp.businessobject.NonCheckDisbursementDocumentAccountingLineParser; 022 import org.kuali.kfs.sys.KFSConstants; 023 import org.kuali.kfs.sys.KFSKeyConstants; 024 import org.kuali.kfs.sys.KFSPropertyConstants; 025 import org.kuali.kfs.sys.businessobject.AccountingLine; 026 import org.kuali.kfs.sys.businessobject.AccountingLineParser; 027 import org.kuali.kfs.sys.businessobject.Bank; 028 import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntry; 029 import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper; 030 import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySourceDetail; 031 import org.kuali.kfs.sys.context.SpringContext; 032 import org.kuali.kfs.sys.document.AccountingDocumentBase; 033 import org.kuali.kfs.sys.document.AmountTotaling; 034 import org.kuali.kfs.sys.document.Correctable; 035 import org.kuali.kfs.sys.document.service.AccountingDocumentRuleHelperService; 036 import org.kuali.kfs.sys.document.service.DebitDeterminerService; 037 import org.kuali.kfs.sys.document.validation.impl.AccountingDocumentRuleBaseConstants.GENERAL_LEDGER_PENDING_ENTRY_CODE; 038 import org.kuali.kfs.sys.service.BankService; 039 import org.kuali.kfs.sys.service.GeneralLedgerPendingEntryService; 040 import org.kuali.rice.kns.document.Copyable; 041 import org.kuali.rice.kns.util.KNSConstants; 042 import org.kuali.rice.kns.util.KualiDecimal; 043 044 /** 045 * This is the business object that represents the NonCheckDisbursementDocument in Kuali. The "Non-Check Disbursement" document is 046 * used to record charges or credits directly assessed to university bank accounts. It is used primarily by the Tax and Treasury 047 * Accounting office to record wire transfers, foreign drafts, etc. 048 */ 049 public class NonCheckDisbursementDocument extends AccountingDocumentBase implements Copyable, Correctable, AmountTotaling { 050 protected String financialDocumentBankCode; 051 052 protected Bank bank; 053 054 /** 055 * Constructs a NonCheckDisbursementDocument instance. 056 */ 057 public NonCheckDisbursementDocument() { 058 bank = new Bank(); 059 } 060 061 /** 062 * Sets the bank code for a new document to the setup default for the Non Check Disbursement document. 063 */ 064 public void setDefautBankCode() { 065 Bank defaultBank = SpringContext.getBean(BankService.class).getDefaultBankByDocType(this.getClass()); 066 if (defaultBank != null) { 067 this.financialDocumentBankCode = defaultBank.getBankCode(); 068 this.bank = defaultBank; 069 } 070 } 071 072 /** 073 * Gets the financialDocumentBankCode attribute. 074 * 075 * @return Returns the financialDocumentBankCode. 076 */ 077 public String getFinancialDocumentBankCode() { 078 return financialDocumentBankCode; 079 } 080 081 /** 082 * Sets the financialDocumentBankCode attribute value. 083 * 084 * @param financialDocumentBankCode The financialDocumentBankCode to set. 085 */ 086 public void setFinancialDocumentBankCode(String financialDocumentBankCode) { 087 this.financialDocumentBankCode = financialDocumentBankCode; 088 } 089 090 /** 091 * Gets the bank attribute. 092 * 093 * @return Returns the bank. 094 */ 095 public Bank getBank() { 096 return bank; 097 } 098 099 /** 100 * Sets the bank attribute value. 101 * 102 * @param bank The bank to set. 103 */ 104 public void setBank(Bank bank) { 105 this.bank = bank; 106 } 107 108 /** 109 * Overrides the base implementation to return "From". 110 * 111 * @see org.kuali.kfs.sys.document.AccountingDocument#getSourceAccountingLinesSectionTitle() 112 */ 113 @Override 114 public String getSourceAccountingLinesSectionTitle() { 115 return EMPTY_STRING; 116 } 117 118 /** 119 * This method determines if a given accounting line is a debit accounting line. This is done by calling 120 * IsDebitUtiles.isDebitConsideringNothingPositiveOnly(). An IllegalStateException will be thrown if the accounting line passed 121 * in is not an expense, is an error correction with a positive dollar amount or is not an error correction and has a negative 122 * amount. 123 * 124 * @param transactionalDocument The document the accounting line being checked is located in. 125 * @param accountingLine The accounting line being analyzed. 126 * @return True if the accounting line given is a debit accounting line, false otherwise. 127 * @throws IllegalStateException Thrown if accounting line attributes are invalid. 128 * @see IsDebitUtils#isDebitConsideringNothingPositiveOnly(FinancialDocumentRuleBase, FinancialDocument, AccountingLine) 129 * @see org.kuali.rice.kns.rule.AccountingLineRule#isDebit(org.kuali.rice.kns.document.FinancialDocument, 130 * org.kuali.rice.kns.bo.AccountingLine) 131 */ 132 public boolean isDebit(GeneralLedgerPendingEntrySourceDetail postable) throws IllegalStateException { 133 DebitDeterminerService isDebitUtils = SpringContext.getBean(DebitDeterminerService.class); 134 return isDebitUtils.isDebitConsideringNothingPositiveOnly(this, (AccountingLine) postable); 135 } 136 137 /** 138 * This method sets attributes on the explicitly general ledger pending entry specific to NonCheckDisbursement documents. This 139 * includes setting the transaction ledger entry description and blanking out the reference financial document number, the 140 * reference financial system origin code and the reference financial document type code. These values must be nullified because 141 * they don't belong in general ledger pending entries and if they aren't null, the general error corrections won't post 142 * properly. 143 * 144 * @param financialDocument The document which contains the general ledger pending entry being modified. 145 * @param accountingLine The accounting line the explicit entry was generated from. 146 * @param explicitEntry The explicit entry being updated. 147 * @see FinancialDocumentRuleBase#customizeExplicitGeneralLedgerPendingEntry(FinancialDocument, AccountingLine, 148 * GeneralLedgerPendingEntry) 149 */ 150 @Override 151 public void customizeExplicitGeneralLedgerPendingEntry(GeneralLedgerPendingEntrySourceDetail postable, GeneralLedgerPendingEntry explicitEntry) { 152 explicitEntry.setTransactionLedgerEntryDescription(buildTransactionLedgerEntryDescriptionUsingRefOriginAndRefDocNumber(postable)); 153 154 // Clearing fields that are already handled by the parent algorithm - we don't actually want 155 // these to copy over from the accounting lines b/c they don't belong in the GLPEs 156 // if they aren't nulled, then GECs fail to post 157 explicitEntry.setReferenceFinancialDocumentNumber(null); 158 explicitEntry.setReferenceFinancialSystemOriginationCode(null); 159 explicitEntry.setReferenceFinancialDocumentTypeCode(null); 160 } 161 162 /** 163 * @see org.kuali.kfs.sys.document.AccountingDocumentBase#generateDocumentGeneralLedgerPendingEntries(org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper) 164 */ 165 @Override 166 public boolean generateDocumentGeneralLedgerPendingEntries(GeneralLedgerPendingEntrySequenceHelper sequenceHelper) { 167 boolean success = true; 168 169 if (!SpringContext.getBean(BankService.class).isBankSpecificationEnabled()) { 170 return success; 171 } 172 173 this.refreshReferenceObject(KFSPropertyConstants.BANK); 174 175 GeneralLedgerPendingEntryService glpeService = SpringContext.getBean(GeneralLedgerPendingEntryService.class); 176 177 final KualiDecimal bankOffsetAmount = glpeService.getOffsetToCashAmount(this).negated(); 178 GeneralLedgerPendingEntry bankOffsetEntry = new GeneralLedgerPendingEntry(); 179 success &= glpeService.populateBankOffsetGeneralLedgerPendingEntry(getBank(), bankOffsetAmount, this, getPostingYear(), sequenceHelper, bankOffsetEntry, KNSConstants.DOCUMENT_PROPERTY_NAME + "." + KFSPropertyConstants.FINANCIAL_DOCUMENT_BANK_CODE); 180 181 if (success) { 182 AccountingDocumentRuleHelperService accountingDocumentRuleUtil = SpringContext.getBean(AccountingDocumentRuleHelperService.class); 183 bankOffsetEntry.setTransactionLedgerEntryDescription(accountingDocumentRuleUtil.formatProperty(KFSKeyConstants.Bank.DESCRIPTION_GLPE_BANK_OFFSET)); 184 getGeneralLedgerPendingEntries().add(bankOffsetEntry); 185 sequenceHelper.increment(); 186 187 GeneralLedgerPendingEntry offsetEntry = new GeneralLedgerPendingEntry(bankOffsetEntry); 188 success &= glpeService.populateOffsetGeneralLedgerPendingEntry(getPostingYear(), bankOffsetEntry, sequenceHelper, offsetEntry); 189 getGeneralLedgerPendingEntries().add(offsetEntry); 190 sequenceHelper.increment(); 191 } 192 193 return success; 194 } 195 196 /** 197 * Builds an appropriately formatted string to be used for the <code>transactionLedgerEntryDescription</code>. It is built 198 * using information from the <code>{@link AccountingLine}</code>. Format is "01-12345: blah blah blah". 199 * 200 * @param financialDocument The document the description will be pulled from, if the accounting line description is blank. 201 * @param line The accounting line that will be used for populating the transaction ledger entry description. 202 * @return The description to be applied to the transaction ledger entry. 203 */ 204 protected String buildTransactionLedgerEntryDescriptionUsingRefOriginAndRefDocNumber(GeneralLedgerPendingEntrySourceDetail postable) { 205 String description = ""; 206 if (StringUtils.isBlank(postable.getReferenceNumber())) { 207 throw new IllegalStateException("Reference Document Number is required and should be validated before this point."); 208 } 209 210 description = KFSConstants.ORIGIN_CODE_KUALI + "-" + postable.getReferenceNumber(); 211 212 if (StringUtils.isNotBlank(postable.getFinancialDocumentLineDescription())) { 213 description += ": " + postable.getFinancialDocumentLineDescription(); 214 } 215 else { 216 description += ": " + getDocumentHeader().getDocumentDescription(); 217 } 218 219 if (description.length() > GENERAL_LEDGER_PENDING_ENTRY_CODE.GLPE_DESCRIPTION_MAX_LENGTH) { 220 description = description.substring(0, GENERAL_LEDGER_PENDING_ENTRY_CODE.GLPE_DESCRIPTION_MAX_LENGTH - 3) + "..."; 221 } 222 223 return description; 224 } 225 }