Search in sources :

Example 1 with InvoiceDetailAccountObjectCode

use of org.kuali.kfs.module.ar.businessobject.InvoiceDetailAccountObjectCode in project cu-kfs by CU-CommunityApps.

the class ContractsGrantsInvoiceDocumentServiceImpl method adjustObjectCodeAmountsIfChanged.

/**
 * If any of the current expenditures for the cost categories on the Contracts & Grants Invoice Document have
 * changed, recalculate the Object Code amounts.
 *
 * @param contractsGrantsInvoiceDocument document containing cost categories to review
 * @return true if expenditure value changed, false otherwise
 */
protected boolean adjustObjectCodeAmountsIfChanged(ContractsGrantsInvoiceDocument contractsGrantsInvoiceDocument) {
    boolean isExpenditureValueChanged = false;
    // put the invoiceDetailAccountObjectCode into a map based on category
    List<InvoiceDetailAccountObjectCode> invoiceDetailAccountObjectCodes = contractsGrantsInvoiceDocument.getInvoiceDetailAccountObjectCodes();
    Map<String, List<InvoiceDetailAccountObjectCode>> invoiceDetailAccountObjectCodeMap = new HashMap<>();
    for (InvoiceDetailAccountObjectCode invoiceDetailAccountObjectCode : invoiceDetailAccountObjectCodes) {
        String categoryCode = invoiceDetailAccountObjectCode.getCategoryCode();
        List<InvoiceDetailAccountObjectCode> invoiceDetailAccountObjectCodeList = invoiceDetailAccountObjectCodeMap.get(categoryCode);
        // if new category, create new list to put into map
        if (invoiceDetailAccountObjectCodeList == null) {
            List<InvoiceDetailAccountObjectCode> newInvoiceDetailAccountObjectCodeList = new ArrayList<>();
            newInvoiceDetailAccountObjectCodeList.add(invoiceDetailAccountObjectCode);
            invoiceDetailAccountObjectCodeMap.put(categoryCode, newInvoiceDetailAccountObjectCodeList);
        } else {
            // else, if list is found, add it to existing list
            invoiceDetailAccountObjectCodeMap.get(categoryCode).add(invoiceDetailAccountObjectCode);
        }
    }
    // invoiceDetailObjectCode and update account details
    for (ContractsGrantsInvoiceDetail invoiceDetail : contractsGrantsInvoiceDocument.getInvoiceDetails()) {
        KualiDecimal total = getSumOfExpendituresOfCategory(invoiceDetailAccountObjectCodeMap.get(invoiceDetail.getCategoryCode()));
        // To set expenditures to zero if its blank - to avoid exceptions.
        if (ObjectUtils.isNull(invoiceDetail.getInvoiceAmount())) {
            invoiceDetail.setInvoiceAmount(KualiDecimal.ZERO);
        }
        if (invoiceDetail.getInvoiceAmount().compareTo(total) != 0) {
            recalculateObjectCodeByCategory(contractsGrantsInvoiceDocument, invoiceDetail, total, invoiceDetailAccountObjectCodeMap.get(invoiceDetail.getCategoryCode()));
            isExpenditureValueChanged = true;
        }
    }
    return isExpenditureValueChanged;
}
Also used : ContractsGrantsInvoiceDetail(org.kuali.kfs.module.ar.businessobject.ContractsGrantsInvoiceDetail) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) AbstractKualiDecimal(org.kuali.kfs.core.api.util.type.AbstractKualiDecimal) KualiDecimal(org.kuali.kfs.core.api.util.type.KualiDecimal) ArrayList(java.util.ArrayList) List(java.util.List) InvoiceDetailAccountObjectCode(org.kuali.kfs.module.ar.businessobject.InvoiceDetailAccountObjectCode)

Example 2 with InvoiceDetailAccountObjectCode

use of org.kuali.kfs.module.ar.businessobject.InvoiceDetailAccountObjectCode in project cu-kfs by CU-CommunityApps.

the class ContractsGrantsInvoiceDocumentServiceImpl method assignCurrentExpenditureToNonExistingAccountObjectCode.

protected void assignCurrentExpenditureToNonExistingAccountObjectCode(ContractsGrantsInvoiceDocument contractsGrantsInvoiceDocument, ContractsGrantsInvoiceDetail invoiceDetail) {
    String categoryCode = invoiceDetail.getCategoryCode();
    if (StringUtils.isBlank(categoryCode)) {
        throw new IllegalArgumentException("Category Code can not be null during recalculation of account object code for Contracts & Grants Invoice Document.");
    }
    // get the category that matches this category code.
    final CostCategory category = businessObjectService.findBySinglePrimaryKey(CostCategory.class, categoryCode);
    // got the category now.
    if (!ObjectUtils.isNull(category)) {
        final KualiDecimal oneCent = new KualiDecimal(0.01);
        int size = contractsGrantsInvoiceDocument.getAccountDetails().size();
        KualiDecimal amount = new KualiDecimal(invoiceDetail.getInvoiceAmount().bigDecimalValue().divide(new BigDecimal(size), 2, RoundingMode.HALF_UP));
        KualiDecimal remainder = invoiceDetail.getInvoiceAmount().subtract(amount.multiply(new KualiDecimal(size)));
        for (InvoiceAccountDetail invoiceAccountDetail : contractsGrantsInvoiceDocument.getAccountDetails()) {
            InvoiceDetailAccountObjectCode invoiceDetailAccountObjectCode = new InvoiceDetailAccountObjectCode();
            invoiceDetailAccountObjectCode.setDocumentNumber(contractsGrantsInvoiceDocument.getDocumentNumber());
            invoiceDetailAccountObjectCode.setProposalNumber(contractsGrantsInvoiceDocument.getInvoiceGeneralDetail().getProposalNumber());
            invoiceDetailAccountObjectCode.setCategoryCode(categoryCode);
            invoiceDetailAccountObjectCode.setAccountNumber(invoiceAccountDetail.getAccountNumber());
            invoiceDetailAccountObjectCode.setChartOfAccountsCode(invoiceAccountDetail.getChartOfAccountsCode());
            // it's 0.00 that's why we are in this section to begin with.
            invoiceDetailAccountObjectCode.setCumulativeExpenditures(KualiDecimal.ZERO);
            // this is also 0.00 because it has never been billed before
            invoiceDetailAccountObjectCode.setTotalBilled(KualiDecimal.ZERO);
            final ObjectCodeCurrent objectCode = getCostCategoryService().findObjectCodeForChartAndCategory(invoiceAccountDetail.getChartOfAccountsCode(), categoryCode);
            if (!ObjectUtils.isNull(objectCode)) {
                invoiceDetailAccountObjectCode.setFinancialObjectCode(objectCode.getFinancialObjectCode());
            }
            // tack on or remove one penny until the remainder is 0 - take a penny, leave a penny!
            if (remainder.isGreaterThan(KualiDecimal.ZERO)) {
                amount = amount.add(oneCent);
                remainder = remainder.subtract(oneCent);
            } else if (remainder.isLessThan(KualiDecimal.ZERO)) {
                amount = amount.subtract(oneCent);
                remainder = remainder.add(oneCent);
            }
            invoiceDetailAccountObjectCode.setCurrentExpenditures(amount);
            List<InvoiceDetailAccountObjectCode> invoiceDetailAccountObjectCodes = contractsGrantsInvoiceDocument.getInvoiceDetailAccountObjectCodes();
            if (invoiceDetailAccountObjectCodes.contains(invoiceDetailAccountObjectCode)) {
                // update existing code
                InvoiceDetailAccountObjectCode original = invoiceDetailAccountObjectCodes.get(invoiceDetailAccountObjectCodes.indexOf(invoiceDetailAccountObjectCode));
                original.setCurrentExpenditures(amount);
                original.setCategoryCode(categoryCode);
            } else {
                // add this single account object code item to the list in the Map
                contractsGrantsInvoiceDocument.getInvoiceDetailAccountObjectCodes().add(invoiceDetailAccountObjectCode);
            }
        }
    } else {
        LOG.error("Category Code cannot be found from the category list during recalculation of account object " + "code for Contracts & Grants Invoice Document.");
    }
}
Also used : AbstractKualiDecimal(org.kuali.kfs.core.api.util.type.AbstractKualiDecimal) KualiDecimal(org.kuali.kfs.core.api.util.type.KualiDecimal) InvoiceAccountDetail(org.kuali.kfs.module.ar.businessobject.InvoiceAccountDetail) ObjectCodeCurrent(org.kuali.kfs.coa.businessobject.ObjectCodeCurrent) CostCategory(org.kuali.kfs.module.ar.businessobject.CostCategory) BigDecimal(java.math.BigDecimal) InvoiceDetailAccountObjectCode(org.kuali.kfs.module.ar.businessobject.InvoiceDetailAccountObjectCode)

Example 3 with InvoiceDetailAccountObjectCode

use of org.kuali.kfs.module.ar.businessobject.InvoiceDetailAccountObjectCode in project cu-kfs by CU-CommunityApps.

the class ContractsGrantsInvoiceDocumentServiceImpl method getCategoryTotalBilledAmountsForInvoiceAccountDetail.

/**
 * Totals the total billed amounts of any invoice detail account object codes on the document which have set
 * categories by account numbers
 *
 * @param contractsGrantsInvoiceDocument the document holding invoice detail account object codes
 * @return a Map where the key is the concatenation of chartOfAccountsCode-accountNumber and the value is the
 * total billed amount on that account
 */
protected Map<String, KualiDecimal> getCategoryTotalBilledAmountsForInvoiceAccountDetail(ContractsGrantsInvoiceDocument contractsGrantsInvoiceDocument) {
    Map<String, KualiDecimal> totalBilledAmounts = new HashMap<>();
    for (InvoiceDetailAccountObjectCode invoiceDetailAccountObjectCode : contractsGrantsInvoiceDocument.getInvoiceDetailAccountObjectCodes()) {
        final String accountKey = StringUtils.join(new String[] { invoiceDetailAccountObjectCode.getChartOfAccountsCode(), invoiceDetailAccountObjectCode.getAccountNumber() }, "-");
        if (StringUtils.isNotBlank(invoiceDetailAccountObjectCode.getCategoryCode())) {
            KualiDecimal total = totalBilledAmounts.get(accountKey);
            if (ObjectUtils.isNull(total)) {
                total = KualiDecimal.ZERO;
            }
            totalBilledAmounts.put(accountKey, total.add(invoiceDetailAccountObjectCode.getTotalBilled()));
        }
    }
    return totalBilledAmounts;
}
Also used : HashMap(java.util.HashMap) AbstractKualiDecimal(org.kuali.kfs.core.api.util.type.AbstractKualiDecimal) KualiDecimal(org.kuali.kfs.core.api.util.type.KualiDecimal) InvoiceDetailAccountObjectCode(org.kuali.kfs.module.ar.businessobject.InvoiceDetailAccountObjectCode)

Example 4 with InvoiceDetailAccountObjectCode

use of org.kuali.kfs.module.ar.businessobject.InvoiceDetailAccountObjectCode in project cu-kfs by CU-CommunityApps.

the class ContractsGrantsInvoiceCreateDocumentServiceImpl method updateCategoryActualAmountsByBalance.

/**
 * Updates the appropriate amounts for the InvoiceDetailAccountObjectCode matching the given balance
 *
 * @param document                        the CINV document we're generating
 * @param balance                         the balance to update amounts by
 * @param award                           the award on the CINV document we're generating
 * @param invoiceDetailAccountObjectCodes the List of invoiceDetailObjectCodes to update one of
 * @param firstFiscalPeriod               whether we're generating the CINV document in the fiscal fiscal period
 *                                        or not
 */
protected void updateCategoryActualAmountsByBalance(ContractsGrantsInvoiceDocument document, Balance balance, ContractsAndGrantsBillingAward award, List<InvoiceDetailAccountObjectCode> invoiceDetailAccountObjectCodes, boolean firstFiscalPeriod) {
    final CostCategory category = getCostCategoryService().getCostCategoryForObjectCode(balance.getUniversityFiscalYear(), balance.getChartOfAccountsCode(), balance.getObjectCode());
    if (!ObjectUtils.isNull(category)) {
        final InvoiceDetailAccountObjectCode invoiceDetailAccountObjectCode = getInvoiceDetailAccountObjectCodeByBalanceAndCategory(invoiceDetailAccountObjectCodes, balance, document.getDocumentNumber(), document.getInvoiceGeneralDetail().getProposalNumber(), category);
        if (ArConstants.BillingFrequencyValues.isTimeBased(document.getInvoiceGeneralDetail())) {
            if (firstFiscalPeriod) {
                invoiceDetailAccountObjectCode.setCumulativeExpenditures(cleanAmount(invoiceDetailAccountObjectCode.getCumulativeExpenditures()).add(cleanAmount(balance.getContractsGrantsBeginningBalanceAmount())).add(cleanAmount(balance.getAccountLineAnnualBalanceAmount())));
                if (!includePeriod13InPeriod01Calculations()) {
                    invoiceDetailAccountObjectCode.setCumulativeExpenditures(cleanAmount(invoiceDetailAccountObjectCode.getCumulativeExpenditures()).subtract(cleanAmount(balance.getMonth13Amount())));
                }
            } else {
                invoiceDetailAccountObjectCode.setCumulativeExpenditures(cleanAmount(invoiceDetailAccountObjectCode.getCumulativeExpenditures()).add(calculateBalanceAmountWithoutLastBilledPeriod(document.getInvoiceGeneralDetail().getLastBilledDate(), balance)));
            }
        } else {
            // For other billing frequencies
            cleanAmount(balance.getContractsGrantsBeginningBalanceAmount()).add(cleanAmount(balance.getAccountLineAnnualBalanceAmount()));
            invoiceDetailAccountObjectCode.setCumulativeExpenditures(cleanAmount(invoiceDetailAccountObjectCode.getCumulativeExpenditures()).add(cleanAmount(balance.getContractsGrantsBeginningBalanceAmount()).add(cleanAmount(balance.getAccountLineAnnualBalanceAmount()))));
        }
    }
}
Also used : CostCategory(org.kuali.kfs.module.ar.businessobject.CostCategory) InvoiceDetailAccountObjectCode(org.kuali.kfs.module.ar.businessobject.InvoiceDetailAccountObjectCode)

Example 5 with InvoiceDetailAccountObjectCode

use of org.kuali.kfs.module.ar.businessobject.InvoiceDetailAccountObjectCode in project cu-kfs by CU-CommunityApps.

the class ContractsGrantsInvoiceCreateDocumentServiceImpl method generateValuesForCategories.

/**
 * 1. This method is responsible to populate categories column for the ContractsGrantsInvoice Document. 2. The
 * categories are retrieved from the Maintenance document as a collection and then a logic with conditions to
 * handle ranges of Object Codes. 3. Once the object codes are retrieved and categories are set the
 * performAccountingCalculations method of InvoiceDetail BO will do all the accounting calculations.
 *
 * @param documentNumber                     the number of the document we want to add invoice details to
 * @param invoiceDetailAccountObjectCodes    the List of InvoiceDetailAccountObjectCodes containing amounts to
 *                                           sum into our invoice details
 * @param budgetAmountsByCostCategory        the budget amounts, sorted by cost category
 * @param awardAccountObjectCodeTotalBilleds the business objects containing what has been billed from the
 *                                           document's award accounts already
 */
public List<ContractsGrantsInvoiceDetail> generateValuesForCategories(String documentNumber, List<InvoiceDetailAccountObjectCode> invoiceDetailAccountObjectCodes, Map<String, KualiDecimal> budgetAmountsByCostCategory, List<AwardAccountObjectCodeTotalBilled> awardAccountObjectCodeTotalBilleds) {
    Collection<CostCategory> costCategories = retrieveAllBillingCategories();
    List<ContractsGrantsInvoiceDetail> invoiceDetails = new ArrayList<>();
    Map<String, List<InvoiceDetailAccountObjectCode>> invoiceDetailAccountObjectCodesMap = mapInvoiceDetailAccountObjectCodesByCategoryCode(invoiceDetailAccountObjectCodes);
    Map<String, List<AwardAccountObjectCodeTotalBilled>> billedsMap = mapAwardAccountObjectCodeTotalBilledsByCategoryCode(awardAccountObjectCodeTotalBilleds);
    for (CostCategory category : costCategories) {
        ContractsGrantsInvoiceDetail invDetail = new ContractsGrantsInvoiceDetail();
        invDetail.setDocumentNumber(documentNumber);
        invDetail.setCategoryCode(category.getCategoryCode());
        invDetail.setCostCategory(category);
        invDetail.setIndirectCostIndicator(category.isIndirectCostIndicator());
        // calculate total billed first
        invDetail.setCumulativeExpenditures(KualiDecimal.ZERO);
        invDetail.setInvoiceAmount(KualiDecimal.ZERO);
        invDetail.setTotalPreviouslyBilled(KualiDecimal.ZERO);
        List<InvoiceDetailAccountObjectCode> invoiceDetailAccountObjectCodesForCategory = invoiceDetailAccountObjectCodesMap.get(category.getCategoryCode());
        if (!CollectionUtils.isEmpty(invoiceDetailAccountObjectCodesForCategory)) {
            for (InvoiceDetailAccountObjectCode invoiceDetailAccountObjectCode : invoiceDetailAccountObjectCodesForCategory) {
                invDetail.setCumulativeExpenditures(invDetail.getCumulativeExpenditures().add(invoiceDetailAccountObjectCode.getCumulativeExpenditures()));
                invDetail.setInvoiceAmount(invDetail.getInvoiceAmount().add(invoiceDetailAccountObjectCode.getCurrentExpenditures()));
            }
        }
        List<AwardAccountObjectCodeTotalBilled> billedForCategory = billedsMap.get(category.getCategoryCode());
        if (!CollectionUtils.isEmpty(billedForCategory)) {
            for (AwardAccountObjectCodeTotalBilled accountObjectCodeTotalBilled : billedForCategory) {
                // this adds up all the total billed based on object code into categories; sum for this category.
                invDetail.setTotalPreviouslyBilled(invDetail.getTotalPreviouslyBilled().add(accountObjectCodeTotalBilled.getTotalBilled()));
            }
        }
        // calculate the rest using billed to date
        if (!ObjectUtils.isNull(budgetAmountsByCostCategory.get(category.getCategoryCode()))) {
            invDetail.setTotalBudget(budgetAmountsByCostCategory.get(category.getCategoryCode()));
        } else {
            invDetail.setTotalBudget(KualiDecimal.ZERO);
        }
        invoiceDetails.add(invDetail);
    }
    return invoiceDetails;
}
Also used : ContractsGrantsInvoiceDetail(org.kuali.kfs.module.ar.businessobject.ContractsGrantsInvoiceDetail) ArrayList(java.util.ArrayList) AwardAccountObjectCodeTotalBilled(org.kuali.kfs.module.ar.businessobject.AwardAccountObjectCodeTotalBilled) CostCategory(org.kuali.kfs.module.ar.businessobject.CostCategory) ArrayList(java.util.ArrayList) List(java.util.List) InvoiceDetailAccountObjectCode(org.kuali.kfs.module.ar.businessobject.InvoiceDetailAccountObjectCode)

Aggregations

InvoiceDetailAccountObjectCode (org.kuali.kfs.module.ar.businessobject.InvoiceDetailAccountObjectCode)16 KualiDecimal (org.kuali.kfs.core.api.util.type.KualiDecimal)10 HashMap (java.util.HashMap)8 AbstractKualiDecimal (org.kuali.kfs.core.api.util.type.AbstractKualiDecimal)7 ArrayList (java.util.ArrayList)5 List (java.util.List)5 InvoiceAccountDetail (org.kuali.kfs.module.ar.businessobject.InvoiceAccountDetail)5 ContractsGrantsInvoiceDetail (org.kuali.kfs.module.ar.businessobject.ContractsGrantsInvoiceDetail)4 AwardAccountObjectCodeTotalBilled (org.kuali.kfs.module.ar.businessobject.AwardAccountObjectCodeTotalBilled)3 CostCategory (org.kuali.kfs.module.ar.businessobject.CostCategory)3 BigDecimal (java.math.BigDecimal)2 ContractsAndGrantsBillingAwardAccount (org.kuali.kfs.integration.cg.ContractsAndGrantsBillingAwardAccount)2 ContractsGrantsLetterOfCreditReviewDetail (org.kuali.kfs.module.ar.businessobject.ContractsGrantsLetterOfCreditReviewDetail)2 InvoiceAddressDetail (org.kuali.kfs.module.ar.businessobject.InvoiceAddressDetail)2 InvoiceMilestone (org.kuali.kfs.module.ar.businessobject.InvoiceMilestone)2 Date (java.sql.Date)1 Timestamp (java.sql.Timestamp)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 AccountingPeriod (org.kuali.kfs.coa.businessobject.AccountingPeriod)1 ObjectCodeCurrent (org.kuali.kfs.coa.businessobject.ObjectCodeCurrent)1