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.BALANCE_TYPE_ACTUAL;
019
020 import org.kuali.kfs.sys.KFSConstants;
021 import org.kuali.kfs.sys.businessobject.AccountingLine;
022 import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntry;
023 import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySourceDetail;
024 import org.kuali.kfs.sys.businessobject.SystemOptions;
025 import org.kuali.kfs.sys.context.SpringContext;
026 import org.kuali.kfs.sys.document.AccountingDocumentBase;
027 import org.kuali.kfs.sys.document.AmountTotaling;
028 import org.kuali.kfs.sys.document.Correctable;
029 import org.kuali.kfs.sys.document.service.AccountingDocumentRuleHelperService;
030 import org.kuali.kfs.sys.document.service.DebitDeterminerService;
031 import org.kuali.kfs.sys.service.OptionsService;
032 import org.kuali.rice.kns.document.Copyable;
033
034 /**
035 * The Transfer of Funds (TF) document is used to transfer funds (cash) between accounts. There are two kinds of transfer
036 * transactions, mandatory and non-mandatory. Mandatory transfers are required to meet contractual agreements. Specific object codes
037 * are used to identify these transactions. Examples of these are: moving dedicated student fees to the retirement of indebtedness
038 * fund group for principal and interest payments on bonds. Non-mandatory transfers are allocations of unrestricted cash between
039 * fund groups which are not required either by the terms of a loan or by other external agreements. These transfers are the most
040 * commonly used throughout the university.
041 */
042 public class TransferOfFundsDocument extends AccountingDocumentBase implements Copyable, Correctable, AmountTotaling {
043 protected static final long serialVersionUID = -3871133713027969492L;
044
045 /**
046 * Initializes the array lists and some basic info.
047 */
048 public TransferOfFundsDocument() {
049 super();
050 }
051
052 /**
053 * Overrides the base implementation to return "From".
054 *
055 * @see org.kuali.kfs.sys.document.AccountingDocument#getSourceAccountingLinesSectionTitle()
056 */
057 public String getSourceAccountingLinesSectionTitle() {
058 return KFSConstants.FROM;
059 }
060
061 /**
062 * Overrides the base implementation to return "To".
063 *
064 * @see org.kuali.kfs.sys.document.AccountingDocument#getTargetAccountingLinesSectionTitle()
065 */
066 public String getTargetAccountingLinesSectionTitle() {
067 return KFSConstants.TO;
068 }
069
070 /**
071 * Set attributes of an offset pending entry according to rules specific to TransferOfFundsDocument. The current rules
072 * require setting the balance type code to 'actual'.
073 *
074 * @param financialDocument The accounting document containing the general ledger pending entries being customized.
075 * @param accountingLine The accounting line the explicit general ledger pending entry was generated from.
076 * @param explicitEntry The explicit general ledger pending entry the offset entry is generated for.
077 * @param offsetEntry The offset general ledger pending entry being customized.
078 * @return This method always returns true.
079 *
080 * @see org.kuali.kfs.sys.document.validation.impl.AccountingDocumentRuleBase#customizeOffsetGeneralLedgerPendingEntry(org.kuali.rice.kns.document.FinancialDocument,
081 * org.kuali.rice.kns.bo.AccountingLine, org.kuali.module.gl.bo.GeneralLedgerPendingEntry,
082 * org.kuali.module.gl.bo.GeneralLedgerPendingEntry)
083 */
084 @Override
085 public boolean customizeOffsetGeneralLedgerPendingEntry(GeneralLedgerPendingEntrySourceDetail accountingLine, GeneralLedgerPendingEntry explicitEntry, GeneralLedgerPendingEntry offsetEntry) {
086 offsetEntry.setFinancialBalanceTypeCode(BALANCE_TYPE_ACTUAL);
087 return true;
088 }
089
090 /**
091 * Set attributes of an explicit pending entry according to rules specific to TransferOfFundsDocument.
092 *
093 * @param financialDocument The accounting document containing the general ledger pending entries being customized.
094 * @param accountingLine The accounting line the explicit general ledger pending entry was generated from.
095 * @param explicitEntry The explicit general ledger pending entry to be customized.
096 *
097 * @see org.kuali.kfs.sys.document.validation.impl.AccountingDocumentRuleBase#customizeExplicitGeneralLedgerPendingEntry(org.kuali.rice.kns.document.FinancialDocument,
098 * org.kuali.rice.kns.bo.AccountingLine, org.kuali.module.gl.bo.GeneralLedgerPendingEntry)
099 */
100 @Override
101 public void customizeExplicitGeneralLedgerPendingEntry(GeneralLedgerPendingEntrySourceDetail generalLedgerPendingEntrySourceDetail, GeneralLedgerPendingEntry explicitEntry) {
102 AccountingLine accountingLine = (AccountingLine)generalLedgerPendingEntrySourceDetail;
103 SystemOptions options = SpringContext.getBean(OptionsService.class).getCurrentYearOptions();
104
105 explicitEntry.setFinancialBalanceTypeCode(BALANCE_TYPE_ACTUAL);
106 DebitDeterminerService isDebitUtils = SpringContext.getBean(DebitDeterminerService.class);
107 if (isDebitUtils.isExpense(accountingLine)) {
108 explicitEntry.setFinancialObjectTypeCode(options.getFinancialObjectTypeTransferExpenseCd());
109 }
110 else {
111 if (isDebitUtils.isIncome(accountingLine)) {
112 explicitEntry.setFinancialObjectTypeCode(options.getFinancialObjectTypeTransferIncomeCd());
113 }
114 else {
115 AccountingDocumentRuleHelperService accountingDocumentRuleUtil = SpringContext.getBean(AccountingDocumentRuleHelperService.class);
116 explicitEntry.setFinancialObjectTypeCode(accountingDocumentRuleUtil.getObjectCodeTypeCodeWithoutSideEffects(accountingLine));
117 }
118 }
119 }
120
121 /**
122 * Adds the following restrictions in addition to those provided by <code>IsDebitUtils.isDebitConsideringNothingPositiveOnly</code>
123 * <ol>
124 * <li> Only allow income or expense object type codes
125 * <li> Target lines have the opposite debit/credit codes as the source lines
126 * </ol>
127 *
128 * @param financialDocument The document used to determine if the accounting line is a debit line.
129 * @param accountingLine The accounting line to be analyzed.
130 * @return True if the accounting line provided is a debit line, false otherwise.
131 *
132 * @see IsDebitUtils#isDebitConsideringNothingPositiveOnly(FinancialDocumentRuleBase, FinancialDocument, AccountingLine)
133 * @see org.kuali.rice.kns.rule.AccountingLineRule#isDebit(org.kuali.rice.kns.document.FinancialDocument,
134 * org.kuali.rice.kns.bo.AccountingLine)
135 */
136 public boolean isDebit(GeneralLedgerPendingEntrySourceDetail postable) {
137 AccountingLine accountingLine = (AccountingLine)postable;
138 // only allow income or expense
139 DebitDeterminerService isDebitUtils = SpringContext.getBean(DebitDeterminerService.class);
140 if (!isDebitUtils.isIncome(accountingLine) && !isDebitUtils.isExpense(accountingLine)) {
141 throw new IllegalStateException(isDebitUtils.getDebitCalculationIllegalStateExceptionMessage());
142 }
143 boolean isDebit = false;
144 if (accountingLine.isSourceAccountingLine()) {
145 isDebit = isDebitUtils.isDebitConsideringNothingPositiveOnly(this, accountingLine);
146 }
147 else if (accountingLine.isTargetAccountingLine()) {
148 isDebit = !isDebitUtils.isDebitConsideringNothingPositiveOnly(this, accountingLine);
149 }
150 else {
151 throw new IllegalStateException(isDebitUtils.getInvalidLineTypeIllegalArgumentExceptionMessage());
152 }
153
154 return isDebit;
155 }
156 }