001/*
002 * Copyright 2005 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.math.BigDecimal;
019
020import org.kuali.ole.coa.businessobject.IndirectCostRecoveryAccount;
021import org.kuali.ole.fp.document.validation.impl.IndirectCostAdjustmentDocumentRuleConstants;
022import org.kuali.ole.sys.OLEConstants;
023import org.kuali.ole.sys.businessobject.AccountingLine;
024import org.kuali.ole.sys.businessobject.GeneralLedgerPendingEntrySourceDetail;
025import org.kuali.ole.sys.businessobject.SourceAccountingLine;
026import org.kuali.ole.sys.businessobject.TargetAccountingLine;
027import org.kuali.ole.sys.context.SpringContext;
028import org.kuali.ole.sys.document.AccountingDocumentBase;
029import org.kuali.ole.sys.document.AmountTotaling;
030import org.kuali.ole.sys.document.Correctable;
031import org.kuali.ole.sys.document.service.DebitDeterminerService;
032import org.kuali.rice.core.api.util.type.KualiDecimal;
033import org.kuali.rice.coreservice.framework.parameter.ParameterService;
034import org.kuali.rice.krad.document.Copyable;
035
036public class IndirectCostAdjustmentDocument extends AccountingDocumentBase implements Copyable, Correctable, AmountTotaling {
037
038    /**
039     * Constructs a IndirectCostAdjustmentDocument.java.
040     */
041    public IndirectCostAdjustmentDocument() {
042        super();
043    }
044
045    /**
046     * @see org.kuali.ole.sys.document.AccountingDocument#getSourceAccountingLinesSectionTitle()
047     */
048    @Override
049    public String getSourceAccountingLinesSectionTitle() {
050        return OLEConstants.GRANT;
051    }
052
053    /**
054     * @see org.kuali.ole.sys.document.AccountingDocument#getTargetAccountingLinesSectionTitle()
055     */
056    @Override
057    public String getTargetAccountingLinesSectionTitle() {
058        return OLEConstants.ICR;
059    }
060
061    /**
062     * per ICA specs, adds a target(receipt) line when an source(grant) line is added using the following logic to populate the
063     * target line.
064     * <ol>
065     * <li>receipt line's chart = chart from grant line
066     * <li>receipt line's account = ICR account for the account entered on the grant line
067     * <li>receipt line's object code = Financial System Parameter APC for the document global receipt line object code (see APC
068     * setion below)
069     * <li>receipt line's amount = amount from grant line
070     * </ol>
071     * 
072     * @see org.kuali.ole.sys.document.AccountingDocumentBase#addSourceAccountingLine(SourceAccountingLine)
073     */
074    @Override
075    public void addSourceAccountingLine(SourceAccountingLine line) {
076        // add source
077        super.addSourceAccountingLine(line);
078        
079        for (IndirectCostRecoveryAccount icrAccount : line.getAccount().getActiveIndirectCostRecoveryAccounts()){
080            
081            KualiDecimal percentDecimal = new KualiDecimal(icrAccount.getAccountLinePercent().divide(new BigDecimal(100)));
082            
083            // create and populate target line
084            TargetAccountingLine targetAccountingLine = null;
085            try {
086                targetAccountingLine = (TargetAccountingLine) getTargetAccountingLineClass().newInstance();
087            }
088            catch (Exception e) {
089                throw new IllegalArgumentException("unable to create a target accounting line", e);
090            }
091            // get apc object code value
092            String objectCode = SpringContext.getBean(ParameterService.class).getParameterValueAsString(IndirectCostAdjustmentDocument.class, IndirectCostAdjustmentDocumentRuleConstants.RECEIPT_OBJECT_CODE);
093            targetAccountingLine.setFinancialObjectCode(objectCode);
094            targetAccountingLine.setAccountNumber(icrAccount.getIndirectCostRecoveryAccountNumber());
095            targetAccountingLine.setChartOfAccountsCode(icrAccount.getIndirectCostRecoveryFinCoaCode());
096            targetAccountingLine.setDocumentNumber(line.getDocumentNumber());
097            targetAccountingLine.setPostingYear(line.getPostingYear());
098            targetAccountingLine.setAmount(line.getAmount().multiply(percentDecimal));
099            // refresh reference objects
100    
101            targetAccountingLine.refresh();
102            // add target line
103            addTargetAccountingLine(targetAccountingLine);
104        }
105    }
106    
107    /**
108     * Same logic as <code>IsDebitUtils#isDebitConsideringType(FinancialDocumentRuleBase, FinancialDocument, AccountingLine)</code>
109     * but has the following accounting line restrictions: 
110     * 
111     * for grant lines(source):
112     * <ol>
113     * <li>only allow expense object type codes
114     * </ol>
115     * for receipt lines(target):
116     * <ol>
117     * <li>only allow income object type codes
118     * </ol>
119     * 
120     * @param transactionDocument The document associated with the accounting line being reviewed to determine if it's a debit.
121     * @param accountingLine The accounting line being reviewed to determine if it's a debit line.
122     * @return True if the accounting line is a debit.  See IsDebitUtils.isDebitConsideringType().
123     * @throws IllegalStateException Thrown if the accounting line given is a source accounting line representing an expense
124     * or is a target accounting line representing an income.
125     * 
126     * @see IsDebitUtils#isDebitConsideringType(FinancialDocumentRuleBase, FinancialDocument, AccountingLine)
127     * @see org.kuali.rice.krad.rule.AccountingLineRule#isDebit(org.kuali.rice.krad.document.FinancialDocument,
128     *      org.kuali.rice.krad.bo.AccountingLine)
129     */
130    public boolean isDebit(GeneralLedgerPendingEntrySourceDetail postable) throws IllegalStateException {
131        AccountingLine accountingLine = (AccountingLine)postable;
132        DebitDeterminerService isDebitUtils = SpringContext.getBean(DebitDeterminerService.class);
133        if (!(accountingLine.isSourceAccountingLine() && isDebitUtils.isExpense(accountingLine)) && !(accountingLine.isTargetAccountingLine() && isDebitUtils.isIncome(accountingLine))) {
134            throw new IllegalStateException(isDebitUtils.getDebitCalculationIllegalStateExceptionMessage());
135        }
136
137        return isDebitUtils.isDebitConsideringType(this, accountingLine);
138    }
139}