/* * The Kuali Financial System, a comprehensive financial management system for higher education. * * Copyright 2005-2014 The Kuali Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.kuali.kfs.fp.document; import static org.kuali.kfs.sys.KFSConstants.EMPTY_STRING; import org.apache.commons.lang.StringUtils; import org.kuali.kfs.sys.KFSConstants; import org.kuali.kfs.sys.KFSKeyConstants; import org.kuali.kfs.sys.KFSPropertyConstants; import org.kuali.kfs.sys.businessobject.Bank; import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntry; import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper; import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySourceDetail; import org.kuali.kfs.sys.context.SpringContext; import org.kuali.kfs.sys.document.AccountingDocumentBase; import org.kuali.kfs.sys.document.AmountTotaling; import org.kuali.kfs.sys.document.Correctable; import org.kuali.kfs.sys.document.service.AccountingDocumentRuleHelperService; import org.kuali.kfs.sys.document.service.DebitDeterminerService; import org.kuali.kfs.sys.document.validation.impl.AccountingDocumentRuleBaseConstants.GENERAL_LEDGER_PENDING_ENTRY_CODE; import org.kuali.kfs.sys.service.BankService; import org.kuali.kfs.sys.service.GeneralLedgerPendingEntryService; import org.kuali.rice.core.api.util.type.KualiDecimal; import org.kuali.rice.krad.document.Copyable; import org.kuali.rice.krad.util.KRADConstants; import org.kuali.rice.krad.util.ObjectUtils; /** * This is the business object that represents the NonCheckDisbursementDocument in Kuali. The "Non-Check Disbursement" document is * used to record charges or credits directly assessed to university bank accounts. It is used primarily by the Tax and Treasury * Accounting office to record wire transfers, foreign drafts, etc. */ public class NonCheckDisbursementDocument extends AccountingDocumentBase implements Copyable, Correctable, AmountTotaling { protected String financialDocumentBankCode; protected Bank bank; /** * Constructs a NonCheckDisbursementDocument instance. */ public NonCheckDisbursementDocument() { bank = new Bank(); } /** * Sets the bank code for a new document to the setup default for the Non Check Disbursement document. */ public void setDefaultBankCode() { Bank defaultBank = SpringContext.getBean(BankService.class).getDefaultBankByDocType(this.getClass()); if (defaultBank != null) { this.financialDocumentBankCode = defaultBank.getBankCode(); this.bank = defaultBank; } } /** * Gets the financialDocumentBankCode attribute. * * @return Returns the financialDocumentBankCode. */ public String getFinancialDocumentBankCode() { return financialDocumentBankCode; } /** * Sets the financialDocumentBankCode attribute value. * * @param financialDocumentBankCode The financialDocumentBankCode to set. */ public void setFinancialDocumentBankCode(String financialDocumentBankCode) { this.financialDocumentBankCode = financialDocumentBankCode; } /** * Gets the bank attribute. * * @return Returns the bank. */ public Bank getBank() { return bank; } /** * Sets the bank attribute value. * * @param bank The bank to set. */ public void setBank(Bank bank) { this.bank = bank; } /** * Overrides the base implementation to return "From". * * @see org.kuali.kfs.sys.document.AccountingDocument#getSourceAccountingLinesSectionTitle() */ @Override public String getSourceAccountingLinesSectionTitle() { return EMPTY_STRING; } /** * This method determines if a given accounting line is a debit accounting line. This is done by calling * IsDebitUtiles.isDebitConsideringNothingPositiveOnly(). An IllegalStateException will be thrown if the accounting line passed * in is not an expense, is an error correction with a positive dollar amount or is not an error correction and has a negative * amount. * * @param transactionalDocument The document the accounting line being checked is located in. * @param accountingLine The accounting line being analyzed. * @return True if the accounting line given is a debit accounting line, false otherwise. * @throws IllegalStateException Thrown if accounting line attributes are invalid. * @see IsDebitUtils#isDebitConsideringNothingPositiveOnly(FinancialDocumentRuleBase, FinancialDocument, AccountingLine) * @see org.kuali.rice.krad.rule.AccountingLineRule#isDebit(org.kuali.rice.krad.document.FinancialDocument, * org.kuali.rice.krad.bo.AccountingLine) */ @Override public boolean isDebit(GeneralLedgerPendingEntrySourceDetail postable) throws IllegalStateException { DebitDeterminerService isDebitUtils = SpringContext.getBean(DebitDeterminerService.class); return isDebitUtils.isDebitConsideringNothingPositiveOnly(this, postable); } /** * This method sets attributes on the explicitly general ledger pending entry specific to NonCheckDisbursement documents. This * includes setting the transaction ledger entry description and blanking out the reference financial document number, the * reference financial system origin code and the reference financial document type code. These values must be nullified because * they don't belong in general ledger pending entries and if they aren't null, the general error corrections won't post * properly. * * @param financialDocument The document which contains the general ledger pending entry being modified. * @param accountingLine The accounting line the explicit entry was generated from. * @param explicitEntry The explicit entry being updated. * @see FinancialDocumentRuleBase#customizeExplicitGeneralLedgerPendingEntry(FinancialDocument, AccountingLine, * GeneralLedgerPendingEntry) */ @Override public void customizeExplicitGeneralLedgerPendingEntry(GeneralLedgerPendingEntrySourceDetail postable, GeneralLedgerPendingEntry explicitEntry) { explicitEntry.setTransactionLedgerEntryDescription(buildTransactionLedgerEntryDescriptionUsingRefOriginAndRefDocNumber(postable)); // Clearing fields that are already handled by the parent algorithm - we don't actually want // these to copy over from the accounting lines b/c they don't belong in the GLPEs // if they aren't nulled, then GECs fail to post explicitEntry.setReferenceFinancialDocumentNumber(null); explicitEntry.setReferenceFinancialSystemOriginationCode(null); explicitEntry.setReferenceFinancialDocumentTypeCode(null); } /** * @see org.kuali.kfs.sys.document.AccountingDocumentBase#generateDocumentGeneralLedgerPendingEntries(org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper) */ @Override public boolean generateDocumentGeneralLedgerPendingEntries(GeneralLedgerPendingEntrySequenceHelper sequenceHelper) { boolean success = true; if (!SpringContext.getBean(BankService.class).isBankSpecificationEnabled()) { return success; } this.refreshReferenceObject(KFSPropertyConstants.BANK); if (!ObjectUtils.isNull(getBank())) { GeneralLedgerPendingEntryService glpeService = SpringContext.getBean(GeneralLedgerPendingEntryService.class); final KualiDecimal bankOffsetAmount = glpeService.getOffsetToCashAmount(this).negated(); GeneralLedgerPendingEntry bankOffsetEntry = new GeneralLedgerPendingEntry(); success &= glpeService.populateBankOffsetGeneralLedgerPendingEntry(getBank(), bankOffsetAmount, this, getPostingYear(), sequenceHelper, bankOffsetEntry, KRADConstants.DOCUMENT_PROPERTY_NAME + "." + KFSPropertyConstants.FINANCIAL_DOCUMENT_BANK_CODE); if (success) { AccountingDocumentRuleHelperService accountingDocumentRuleUtil = SpringContext.getBean(AccountingDocumentRuleHelperService.class); bankOffsetEntry.setTransactionLedgerEntryDescription(accountingDocumentRuleUtil.formatProperty(KFSKeyConstants.Bank.DESCRIPTION_GLPE_BANK_OFFSET)); getGeneralLedgerPendingEntries().add(bankOffsetEntry); sequenceHelper.increment(); GeneralLedgerPendingEntry offsetEntry = new GeneralLedgerPendingEntry(bankOffsetEntry); success &= glpeService.populateOffsetGeneralLedgerPendingEntry(getPostingYear(), bankOffsetEntry, sequenceHelper, offsetEntry); getGeneralLedgerPendingEntries().add(offsetEntry); sequenceHelper.increment(); } } return success; } /** * Builds an appropriately formatted string to be used for the <code>transactionLedgerEntryDescription</code>. It is built * using information from the <code>{@link AccountingLine}</code>. Format is "01-12345: blah blah blah". * * @param financialDocument The document the description will be pulled from, if the accounting line description is blank. * @param line The accounting line that will be used for populating the transaction ledger entry description. * @return The description to be applied to the transaction ledger entry. */ protected String buildTransactionLedgerEntryDescriptionUsingRefOriginAndRefDocNumber(GeneralLedgerPendingEntrySourceDetail postable) { String description = ""; if (StringUtils.isBlank(postable.getReferenceNumber())) { throw new IllegalStateException("Reference Document Number is required and should be validated before this point."); } description = KFSConstants.ORIGIN_CODE_KUALI + "-" + postable.getReferenceNumber(); if (StringUtils.isNotBlank(postable.getFinancialDocumentLineDescription())) { description += ": " + postable.getFinancialDocumentLineDescription(); } else { description += ": " + getDocumentHeader().getDocumentDescription(); } if (description.length() > GENERAL_LEDGER_PENDING_ENTRY_CODE.GLPE_DESCRIPTION_MAX_LENGTH) { description = description.substring(0, GENERAL_LEDGER_PENDING_ENTRY_CODE.GLPE_DESCRIPTION_MAX_LENGTH - 3) + "..."; } return description; } }