/* * The Kuali Financial System, a comprehensive financial management system for higher education. * * Copyright 2005-2014 The Kuali Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.kuali.kfs.fp.document; import java.math.BigDecimal; import org.kuali.kfs.coa.businessobject.IndirectCostRecoveryAccount; import org.kuali.kfs.fp.document.validation.impl.IndirectCostAdjustmentDocumentRuleConstants; import org.kuali.kfs.sys.KFSConstants; import org.kuali.kfs.sys.businessobject.AccountingLine; import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySourceDetail; import org.kuali.kfs.sys.businessobject.SourceAccountingLine; import org.kuali.kfs.sys.businessobject.TargetAccountingLine; import org.kuali.kfs.sys.context.SpringContext; import org.kuali.kfs.sys.document.AccountingDocumentBase; import org.kuali.kfs.sys.document.AmountTotaling; import org.kuali.kfs.sys.document.Correctable; import org.kuali.kfs.sys.document.service.DebitDeterminerService; import org.kuali.rice.core.api.util.type.KualiDecimal; import org.kuali.rice.coreservice.framework.parameter.ParameterService; import org.kuali.rice.krad.document.Copyable; import org.kuali.rice.krad.exception.InfrastructureException; import org.kuali.rice.krad.util.GlobalVariables; import org.kuali.rice.krad.util.ObjectUtils; public class IndirectCostAdjustmentDocument extends AccountingDocumentBase implements Copyable, Correctable, AmountTotaling { /** * Constructs a IndirectCostAdjustmentDocument.java. */ public IndirectCostAdjustmentDocument() { super(); } /** * @see org.kuali.kfs.sys.document.AccountingDocument#getSourceAccountingLinesSectionTitle() */ @Override public String getSourceAccountingLinesSectionTitle() { return KFSConstants.GRANT; } /** * @see org.kuali.kfs.sys.document.AccountingDocument#getTargetAccountingLinesSectionTitle() */ @Override public String getTargetAccountingLinesSectionTitle() { return KFSConstants.ICR; } /** * per ICA specs, adds a target(receipt) line when an source(grant) line is added using the following logic to populate the * target line. * <ol> * <li>receipt line's chart = chart from grant line * <li>receipt line's account = ICR account for the account entered on the grant line * <li>receipt line's object code = Financial System Parameter APC for the document global receipt line object code (see APC * setion below) * <li>receipt line's amount = amount from grant line * </ol> * * @see org.kuali.kfs.sys.document.AccountingDocumentBase#addSourceAccountingLine(SourceAccountingLine) */ @Override public void addSourceAccountingLine(SourceAccountingLine line) { // add source super.addSourceAccountingLine(line); if (GlobalVariables.getMessageMap().hasNoMessages()) { if (line != null && ObjectUtils.isNotNull(line.getAccount()) && line.getAccount().getActiveIndirectCostRecoveryAccounts() != null && line.getAccount().getActiveIndirectCostRecoveryAccounts().size() > 0) { for (IndirectCostRecoveryAccount icrAccount : line.getAccount().getActiveIndirectCostRecoveryAccounts()) { KualiDecimal percentDecimal = new KualiDecimal(icrAccount.getAccountLinePercent().divide(new BigDecimal(100))); // create and populate target line TargetAccountingLine targetAccountingLine = null; try { targetAccountingLine = (TargetAccountingLine) getTargetAccountingLineClass().newInstance(); } catch (Exception e) { throw new InfrastructureException("unable to create a target accounting line", e); } // get apc object code value String objectCode = SpringContext.getBean(ParameterService.class).getParameterValueAsString(IndirectCostAdjustmentDocument.class, IndirectCostAdjustmentDocumentRuleConstants.RECEIPT_OBJECT_CODE); targetAccountingLine.setFinancialObjectCode(objectCode); targetAccountingLine.setAccountNumber(icrAccount.getIndirectCostRecoveryAccountNumber()); targetAccountingLine.setChartOfAccountsCode(icrAccount.getIndirectCostRecoveryFinCoaCode()); targetAccountingLine.setDocumentNumber(line.getDocumentNumber()); targetAccountingLine.setPostingYear(line.getPostingYear()); targetAccountingLine.setAmount(line.getAmount().multiply(percentDecimal)); // refresh reference objects targetAccountingLine.refresh(); // add target line addTargetAccountingLine(targetAccountingLine); } } } } /** * Same logic as <code>IsDebitUtils#isDebitConsideringType(FinancialDocumentRuleBase, FinancialDocument, AccountingLine)</code> * but has the following accounting line restrictions: * * for grant lines(source): * <ol> * <li>only allow expense object type codes * </ol> * for receipt lines(target): * <ol> * <li>only allow income object type codes * </ol> * * @param transactionDocument The document associated with the accounting line being reviewed to determine if it's a debit. * @param accountingLine The accounting line being reviewed to determine if it's a debit line. * @return True if the accounting line is a debit. See IsDebitUtils.isDebitConsideringType(). * @throws IllegalStateException Thrown if the accounting line given is a source accounting line representing an expense * or is a target accounting line representing an income. * * @see IsDebitUtils#isDebitConsideringType(FinancialDocumentRuleBase, FinancialDocument, AccountingLine) * @see org.kuali.rice.krad.rule.AccountingLineRule#isDebit(org.kuali.rice.krad.document.FinancialDocument, * org.kuali.rice.krad.bo.AccountingLine) */ @Override public boolean isDebit(GeneralLedgerPendingEntrySourceDetail postable) throws IllegalStateException { AccountingLine accountingLine = (AccountingLine)postable; DebitDeterminerService isDebitUtils = SpringContext.getBean(DebitDeterminerService.class); if (!(accountingLine.isSourceAccountingLine() && isDebitUtils.isExpense(accountingLine)) && !(accountingLine.isTargetAccountingLine() && isDebitUtils.isIncome(accountingLine))) { throw new IllegalStateException(isDebitUtils.getDebitCalculationIllegalStateExceptionMessage()); } return isDebitUtils.isDebitConsideringType(this, accountingLine); } }