001: /*
002: * Copyright 2005-2007 The Kuali Foundation.
003: *
004: * Licensed under the Educational Community License, Version 1.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/ecl1.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.module.financial.document;
017:
018: import static org.kuali.kfs.KFSConstants.EMPTY_STRING;
019: import static org.kuali.kfs.KFSConstants.GL_CREDIT_CODE;
020: import static org.kuali.kfs.KFSConstants.GL_DEBIT_CODE;
021: import static org.kuali.kfs.KFSPropertyConstants.BALANCE_TYPE;
022:
023: import java.util.ArrayList;
024: import java.util.Iterator;
025: import java.util.List;
026:
027: import org.apache.commons.lang.StringUtils;
028: import org.kuali.core.document.AmountTotaling;
029: import org.kuali.core.document.Copyable;
030: import org.kuali.core.document.Correctable;
031: import org.kuali.core.util.KualiDecimal;
032: import org.kuali.kfs.bo.AccountingLineBase;
033: import org.kuali.kfs.bo.AccountingLineParser;
034: import org.kuali.kfs.bo.SourceAccountingLine;
035: import org.kuali.kfs.document.AccountingDocumentBase;
036: import org.kuali.module.chart.bo.codes.BalanceTyp;
037: import org.kuali.module.financial.bo.JournalVoucherAccountingLineParser;
038: import org.kuali.module.financial.bo.VoucherSourceAccountingLine;
039: import org.kuali.module.gl.util.SufficientFundsItem;
040:
041: import edu.iu.uis.eden.exception.WorkflowException;
042:
043: /**
044: * This is the business object that represents the JournalVoucherDocument in Kuali. This is a transactional document that will
045: * eventually post transactions to the G/L. It integrates with workflow and contains a single group of accounting lines. The Journal
046: * Voucher is unique in that we only make use of one accounting line list: the source accounting lines seeing as a JV only records
047: * accounting lines as debits or credits.
048: */
049: public class JournalVoucherDocument extends AccountingDocumentBase
050: implements VoucherDocument, Copyable, Correctable,
051: AmountTotaling {
052: private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger
053: .getLogger(JournalVoucherDocument.class);
054:
055: // document specific attributes
056: private String balanceTypeCode; // balanceType key
057: private BalanceTyp balanceType;
058: private java.sql.Date reversalDate;
059:
060: /**
061: * Constructs a JournalVoucherDocument instance.
062: */
063: public JournalVoucherDocument() {
064: super ();
065: this .balanceType = new BalanceTyp();
066: }
067:
068: /**
069: * @see org.kuali.kfs.document.AccountingDocumentBase#checkSufficientFunds()
070: */
071: @Override
072: public List<SufficientFundsItem> checkSufficientFunds() {
073: LOG.debug("checkSufficientFunds() started");
074:
075: // This document does not do sufficient funds checking
076: return new ArrayList<SufficientFundsItem>();
077: }
078:
079: /**
080: * @see org.kuali.kfs.document.AccountingDocumentBase#getSourceAccountingLineClass()
081: */
082: @Override
083: public Class getSourceAccountingLineClass() {
084: return VoucherSourceAccountingLine.class;
085: }
086:
087: /**
088: * This method retrieves the balance typ associated with this document.
089: *
090: * @return BalanceTyp
091: */
092: public BalanceTyp getBalanceType() {
093: return balanceType;
094: }
095:
096: /**
097: * This method sets the balance type associated with this document.
098: *
099: * @param balanceType
100: * @deprecated
101: */
102: @Deprecated
103: public void setBalanceType(BalanceTyp balanceType) {
104: this .balanceType = balanceType;
105: }
106:
107: /**
108: * Gets the balanceTypeCode attribute.
109: *
110: * @return Returns the balanceTypeCode.
111: */
112: public String getBalanceTypeCode() {
113: return balanceTypeCode;
114: }
115:
116: /**
117: * Sets the balanceTypeCode attribute value.
118: *
119: * @param balanceTypeCode The balanceTypeCode to set.
120: */
121: public void setBalanceTypeCode(String balanceTypeCode) {
122: this .balanceTypeCode = balanceTypeCode;
123: }
124:
125: /**
126: * This method retrieves the reversal date associated with this document.
127: *
128: * @return java.sql.Date
129: */
130: public java.sql.Date getReversalDate() {
131: return reversalDate;
132: }
133:
134: /**
135: * This method sets the reversal date associated with this document.
136: *
137: * @param reversalDate
138: */
139: public void setReversalDate(java.sql.Date reversalDate) {
140: this .reversalDate = reversalDate;
141: }
142:
143: /**
144: * Overrides the base implementation to return an empty string.
145: *
146: * @return String
147: */
148: @Override
149: public String getSourceAccountingLinesSectionTitle() {
150: return EMPTY_STRING;
151: }
152:
153: /**
154: * Overrides the base implementation to return an empty string.
155: *
156: * @return String
157: */
158: @Override
159: public String getTargetAccountingLinesSectionTitle() {
160: return EMPTY_STRING;
161: }
162:
163: /**
164: * This method calculates the debit total for a JV document keying off of the debit/debit code, only summing the accounting
165: * lines with a debitDebitCode that matched the debit constant, and returns the results.
166: *
167: * @return KualiDecimal
168: */
169: public KualiDecimal getDebitTotal() {
170: KualiDecimal debitTotal = new KualiDecimal(0);
171: AccountingLineBase al = null;
172: Iterator iter = sourceAccountingLines.iterator();
173: while (iter.hasNext()) {
174: al = (AccountingLineBase) iter.next();
175: if (StringUtils.isNotBlank(al.getDebitCreditCode())
176: && al.getDebitCreditCode().equals(GL_DEBIT_CODE)) {
177: debitTotal = debitTotal.add(al.getAmount());
178: }
179: }
180:
181: return debitTotal;
182: }
183:
184: /**
185: * This method calculates the credit total for a JV document keying off of the debit/credit code, only summing the accounting
186: * lines with a debitCreditCode that matched the debit constant, and returns the results.
187: *
188: * @return KualiDecimal
189: */
190: public KualiDecimal getCreditTotal() {
191: KualiDecimal creditTotal = new KualiDecimal(0);
192: AccountingLineBase al = null;
193: Iterator iter = sourceAccountingLines.iterator();
194: while (iter.hasNext()) {
195: al = (AccountingLineBase) iter.next();
196: if (StringUtils.isNotBlank(al.getDebitCreditCode())
197: && al.getDebitCreditCode().equals(GL_CREDIT_CODE)) {
198: creditTotal = creditTotal.add(al.getAmount());
199: }
200: }
201: return creditTotal;
202: }
203:
204: /**
205: * This method determines the "total" for the JV document. If the selected balance type is an offset generation, then the method
206: * returns the total debits amount when it is greater than the total credit amount. otherwise, it returns total credit amount.
207: * When selected balance type is not an offset generation, the method returns the sum of all accounting line debit amounts.
208: *
209: * @return KualiDecimal the total of the JV document.
210: */
211: public KualiDecimal getTotalDollarAmount() {
212:
213: KualiDecimal total = new KualiDecimal(0);
214:
215: this .refreshReferenceObject("balanceType");
216:
217: if (this .balanceType.isFinancialOffsetGenerationIndicator()) {
218: if (getCreditTotal().isGreaterThan(getDebitTotal())) {
219: total = getCreditTotal();
220: } else {
221: total = getDebitTotal();
222: }
223: } else {
224: total = getDebitTotal();
225: }
226: return total;
227: }
228:
229: /**
230: * Used to get the appropriate <code>{@link AccountingLineParser}</code> for the <code>Document</code>
231: *
232: * @return AccountingLineParser
233: */
234: @Override
235: public AccountingLineParser getAccountingLineParser() {
236: return new JournalVoucherAccountingLineParser(
237: getBalanceTypeCode());
238: }
239:
240: /**
241: * @see org.kuali.kfs.document.AccountingDocumentBase#toErrorCorrection()
242: */
243: @Override
244: public void toErrorCorrection() throws WorkflowException {
245: super .toErrorCorrection();
246: processJournalVoucherErrorCorrections();
247: }
248:
249: /**
250: * This method checks to make sure that the JV that we are dealing with was one that was created in debit/credit mode, not
251: * single amount entry mode. If this is a debit/credit JV, then iterate over each source line and flip the sign on the amount to
252: * nullify the super's effect, then flip the debit/credit code b/c an error corrected JV flips the debit/credit code.
253: */
254: private void processJournalVoucherErrorCorrections() {
255: Iterator i = getSourceAccountingLines().iterator();
256:
257: this .refreshReferenceObject(BALANCE_TYPE);
258:
259: if (this .getBalanceType()
260: .isFinancialOffsetGenerationIndicator()) { // make sure this is not a single amount entered JV
261: int index = 0;
262: while (i.hasNext()) {
263: SourceAccountingLine sLine = (SourceAccountingLine) i
264: .next();
265:
266: String debitCreditCode = sLine.getDebitCreditCode();
267:
268: if (StringUtils.isNotBlank(debitCreditCode)) {
269: // negate the amount to to nullify the effects of the super, b/c super flipped it the first time through
270: sLine.setAmount(sLine.getAmount().negated()); // offsets the effect the super
271:
272: // now just flip the debit/credit code
273: if (GL_DEBIT_CODE.equals(debitCreditCode)) {
274: sLine.setDebitCreditCode(GL_CREDIT_CODE);
275: } else if (GL_CREDIT_CODE.equals(debitCreditCode)) {
276: sLine.setDebitCreditCode(GL_DEBIT_CODE);
277: } else {
278: throw new IllegalStateException(
279: "SourceAccountingLine at index "
280: + index
281: + " does not have a debit/credit "
282: + "code associated with it. This should never have occured. Please contact your system administrator.");
283:
284: }
285: index++;
286: }
287: }
288: }
289: }
290: }
|