001/*
002 * Copyright 2006 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 */
016package org.kuali.ole.fp.document;
017
018import java.sql.Date;
019import java.util.Iterator;
020import java.util.List;
021
022import org.apache.commons.lang.StringUtils;
023import org.kuali.ole.fp.businessobject.CapitalAssetInformation;
024import org.kuali.ole.integration.cam.CapitalAssetManagementModuleService;
025import org.kuali.ole.sys.OLEConstants;
026import org.kuali.ole.sys.OLEPropertyConstants;
027import org.kuali.ole.sys.businessobject.AccountingLine;
028import org.kuali.ole.sys.businessobject.AccountingLineBase;
029import org.kuali.ole.sys.businessobject.GeneralLedgerPendingEntry;
030import org.kuali.ole.sys.businessobject.GeneralLedgerPendingEntrySourceDetail;
031import org.kuali.ole.sys.context.SpringContext;
032import org.kuali.ole.sys.document.service.DebitDeterminerService;
033import org.kuali.rice.core.api.util.type.KualiDecimal;
034import org.kuali.rice.krad.util.ObjectUtils;
035
036/**
037 * Abstract class which defines behavior common to CashReceipt-like documents.
038 */
039abstract public class CashReceiptFamilyBase extends CapitalAccountingLinesDocumentBase implements CapitalAssetEditable {
040    protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(CashReceiptFamilyBase.class);
041    protected String campusLocationCode; // TODO Needs to be an actual object - also need to clarify this
042    protected Date depositDate;
043
044    /**
045     * Constructs a CashReceiptFamilyBase
046     */
047    public CashReceiptFamilyBase() {
048        setCampusLocationCode(OLEConstants.CashReceiptConstants.DEFAULT_CASH_RECEIPT_CAMPUS_LOCATION_CODE);
049    }
050
051    /**
052     * Documents in the CashReceiptFamily do not perform Sufficient Funds checking
053     * 
054     * @see org.kuali.ole.sys.document.AccountingDocumentBase#documentPerformsSufficientFundsCheck()
055     */
056    @Override
057    public boolean documentPerformsSufficientFundsCheck() {
058        return false;
059    }
060
061    /**
062     * Gets the campusLocationCode attribute.
063     * 
064     * @return Returns the campusLocationCode.
065     */
066    public String getCampusLocationCode() {
067        return campusLocationCode;
068    }
069
070    /**
071     * Sets the campusLocationCode attribute value.
072     * 
073     * @param campusLocationCode The campusLocationCode to set.
074     */
075    public void setCampusLocationCode(String campusLocationCode) {
076        this.campusLocationCode = campusLocationCode;
077    }
078
079    /**
080     * Gets the depositDate attribute.
081     * 
082     * @return Returns the depositDate.
083     */
084    public Date getDepositDate() {
085        return depositDate;
086    }
087
088    /**
089     * Sets the depositDate attribute value.
090     * 
091     * @param depositDate The depositDate to set.
092     */
093    public void setDepositDate(Date depositDate) {
094        this.depositDate = depositDate;
095    }
096
097
098    /**
099     * Total for a Cash Receipt according to the spec should be the sum of the amounts on accounting lines belonging to object codes
100     * having the 'income' object type, less the sum of the amounts on accounting lines belonging to object codes having the
101     * 'expense' object type.
102     * 
103     * @see org.kuali.ole.sys.document.AccountingDocument#getSourceTotal()
104     */
105    @Override
106    public KualiDecimal getSourceTotal() {
107        KualiDecimal total = KualiDecimal.ZERO;
108        AccountingLineBase al = null;
109        if (ObjectUtils.isNull(getSourceAccountingLines()) || getSourceAccountingLines().isEmpty()) {
110            refreshReferenceObject(OLEPropertyConstants.SOURCE_ACCOUNTING_LINES);
111        }
112        Iterator iter = getSourceAccountingLines().iterator();
113        while (iter.hasNext()) {
114            al = (AccountingLineBase) iter.next();
115            try {
116                KualiDecimal amount = al.getAmount().abs();
117                if (amount != null && amount.isNonZero()) {
118                    if (isDebit(al)) {
119                        total = total.subtract(amount);
120                    }
121                    else { // in this context, if it's not a debit, it's a credit
122                        total = total.add(amount);
123                    }
124                }
125            }
126            catch (Exception e) {
127                // Possibly caused by accounting lines w/ bad data
128                LOG.error("Error occured trying to compute Cash receipt total, returning 0", e);
129                return KualiDecimal.ZERO;
130            }
131        }
132        return total;
133    }
134
135    /**
136     * Cash Receipts only have source lines, so this should always return 0.
137     * 
138     * @see org.kuali.ole.sys.document.AccountingDocument#getTargetTotal()
139     */
140    @Override
141    public KualiDecimal getTargetTotal() {
142        return KualiDecimal.ZERO;
143    }
144
145    /**
146     * Overrides the base implementation to return an empty string.
147     * 
148     * @see org.kuali.ole.sys.document.AccountingDocument#getSourceAccountingLinesSectionTitle()
149     */
150    @Override
151    public String getSourceAccountingLinesSectionTitle() {
152        return OLEConstants.EMPTY_STRING;
153    }
154
155    /**
156     * Overrides the base implementation to return an empty string.
157     * 
158     * @see org.kuali.ole.sys.document.AccountingDocument#getTargetAccountingLinesSectionTitle()
159     */
160    @Override
161    public String getTargetAccountingLinesSectionTitle() {
162        return OLEConstants.EMPTY_STRING;
163    }
164
165    /**
166     * Returns true if accounting line is debit
167     * 
168     * @param financialDocument
169     * @param accountingLine
170     * @param true if accountline line
171     * @see IsDebitUtils#isDebitConsideringType(FinancialDocumentRuleBase, FinancialDocument, AccountingLine)
172     * @see org.kuali.rice.krad.rule.AccountingLineRule#isDebit(org.kuali.rice.krad.document.FinancialDocument,
173     *      org.kuali.rice.krad.bo.AccountingLine)
174     */
175    public boolean isDebit(GeneralLedgerPendingEntrySourceDetail postable) {
176        // error corrections are not allowed
177        DebitDeterminerService isDebitUtils = SpringContext.getBean(DebitDeterminerService.class);
178        isDebitUtils.disallowErrorCorrectionDocumentCheck(this);
179        return isDebitUtils.isDebitConsideringType(this, (AccountingLine) postable);
180    }
181
182    /**
183     * Overrides to set the entry's description to the description from the accounting line, if a value exists.
184     * 
185     * @param financialDocument submitted accounting document
186     * @param accountingLine accounting line in accounting document
187     * @param explicitEntry general ledger pending entry
188     * @see org.kuali.module.financial.rules.FinancialDocumentRuleBase#customizeExplicitGeneralLedgerPendingEntry(org.kuali.rice.krad.document.FinancialDocument,
189     *      org.kuali.rice.krad.bo.AccountingLine, org.kuali.module.gl.bo.GeneralLedgerPendingEntry)
190     */
191    @Override
192    public void customizeExplicitGeneralLedgerPendingEntry(GeneralLedgerPendingEntrySourceDetail postable, GeneralLedgerPendingEntry explicitEntry) {
193        String accountingLineDescription = postable.getFinancialDocumentLineDescription();
194        if (StringUtils.isNotBlank(accountingLineDescription)) {
195            explicitEntry.setTransactionLedgerEntryDescription(accountingLineDescription);
196        }
197    }
198
199    /**
200     * @see org.kuali.ole.fp.document.CapitalAssetEditable#getCapitalAssetInformation()
201     */
202    public List<CapitalAssetInformation> getCapitalAssetInformation() {
203        return ObjectUtils.isNull(capitalAssetInformation) ? null : capitalAssetInformation;
204    }
205
206    /**
207     * @see org.kuali.ole.fp.document.CapitalAssetEditable#setCapitalAssetInformation(org.kuali.ole.fp.businessobject.CapitalAssetInformation)
208     */
209    public void setCapitalAssetInformation(List<CapitalAssetInformation> capitalAssetInformation) {
210        this.capitalAssetInformation = capitalAssetInformation;
211    }
212
213    protected CapitalAssetManagementModuleService getCapitalAssetManagementModuleService() {
214        return SpringContext.getBean(CapitalAssetManagementModuleService.class);
215    }
216}