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