Search in sources :

Example 81 with KualiDecimal

use of org.kuali.kfs.core.api.util.type.KualiDecimal 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 82 with KualiDecimal

use of org.kuali.kfs.core.api.util.type.KualiDecimal 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 83 with KualiDecimal

use of org.kuali.kfs.core.api.util.type.KualiDecimal in project cu-kfs by CU-CommunityApps.

the class ContractsGrantsInvoiceDocumentServiceImpl method prorateBill.

@Override
public void prorateBill(ContractsGrantsInvoiceDocument contractsGrantsInvoiceDocument) {
    // Amount to be billed on this invoice
    KualiDecimal totalCost = new KualiDecimal(0);
    // must iterate through the invoice details because the user might have manually changed the value
    for (ContractsGrantsInvoiceDetail invD : contractsGrantsInvoiceDocument.getInvoiceDetails()) {
        totalCost = totalCost.add(invD.getInvoiceAmount());
    }
    // Total Billed so far
    KualiDecimal billedTotalCost = contractsGrantsInvoiceDocument.getInvoiceGeneralDetail().getTotalPreviouslyBilled();
    // AwardTotal
    KualiDecimal accountAwardTotal = contractsGrantsInvoiceDocument.getInvoiceGeneralDetail().getAwardTotal();
    if (accountAwardTotal.subtract(billedTotalCost).isGreaterEqual(new KualiDecimal(0))) {
        KualiDecimal amountEligibleForBilling = accountAwardTotal.subtract(billedTotalCost);
        if (totalCost.isGreaterThan(amountEligibleForBilling)) {
            // use BigDecimal because percentage should not have only a scale of 2, we need more for accuracy
            BigDecimal percentage = amountEligibleForBilling.bigDecimalValue().divide(totalCost.bigDecimalValue(), 10, RoundingMode.HALF_DOWN);
            // use to check if rounding has left a few cents off
            KualiDecimal amountToBill = new KualiDecimal(0);
            ContractsGrantsInvoiceDetail largestCostCategory = null;
            BigDecimal largestAmount = BigDecimal.ZERO;
            for (ContractsGrantsInvoiceDetail invD : contractsGrantsInvoiceDocument.getInvoiceDetails()) {
                BigDecimal newValue = invD.getInvoiceAmount().bigDecimalValue().multiply(percentage);
                KualiDecimal newKualiDecimalValue = new KualiDecimal(newValue.setScale(2, RoundingMode.DOWN));
                invD.setInvoiceAmount(newKualiDecimalValue);
                amountToBill = amountToBill.add(newKualiDecimalValue);
                if (newValue.compareTo(largestAmount) > 0) {
                    largestAmount = newKualiDecimalValue.bigDecimalValue();
                    largestCostCategory = invD;
                }
            }
            if (!amountToBill.equals(amountEligibleForBilling)) {
                KualiDecimal remaining = amountEligibleForBilling.subtract(amountToBill);
                if (ObjectUtils.isNull(largestCostCategory) && CollectionUtils.isNotEmpty(contractsGrantsInvoiceDocument.getInvoiceDetails())) {
                    largestCostCategory = contractsGrantsInvoiceDocument.getInvoiceDetails().get(0);
                }
                if (ObjectUtils.isNotNull(largestCostCategory)) {
                    largestCostCategory.setInvoiceAmount(largestCostCategory.getInvoiceAmount().add(remaining));
                }
            }
            recalculateTotalAmountBilledToDate(contractsGrantsInvoiceDocument);
        }
    }
}
Also used : ContractsGrantsInvoiceDetail(org.kuali.kfs.module.ar.businessobject.ContractsGrantsInvoiceDetail) AbstractKualiDecimal(org.kuali.kfs.core.api.util.type.AbstractKualiDecimal) KualiDecimal(org.kuali.kfs.core.api.util.type.KualiDecimal) BigDecimal(java.math.BigDecimal)

Example 84 with KualiDecimal

use of org.kuali.kfs.core.api.util.type.KualiDecimal in project cu-kfs by CU-CommunityApps.

the class ContractsGrantsInvoiceDocumentServiceImpl method createSourceAccountingLinesByAward.

/**
 * Generates the source accounting lines for a Contracts & Grants Invoice from the award accounts associated with
 * an award (in the form of the pre-generated invoice account details)
 *
 * @param contractsGrantsInvoiceDocument the Contracts & Grants Invoice to create invoice details for
 * @return a List of generated accounting lines
 */
protected List<CustomerInvoiceDetail> createSourceAccountingLinesByAward(ContractsGrantsInvoiceDocument contractsGrantsInvoiceDocument) {
    List<CustomerInvoiceDetail> awardAccountingLines = new ArrayList<>();
    if (!CollectionUtils.isEmpty(contractsGrantsInvoiceDocument.getAccountDetails())) {
        final Map<String, KualiDecimal> accountExpenditureAmounts = getCategoryExpenditureAmountsForInvoiceAccountDetail(contractsGrantsInvoiceDocument);
        final Map<String, KualiDecimal> accountTotalBilledAmounts = getCategoryTotalBilledAmountsForInvoiceAccountDetail(contractsGrantsInvoiceDocument);
        for (InvoiceAccountDetail invAcctD : contractsGrantsInvoiceDocument.getAccountDetails()) {
            final String proposalNumber = invAcctD.getProposalNumber();
            final String chartOfAccountsCode = invAcctD.getChartOfAccountsCode();
            final String accountNumber = invAcctD.getAccountNumber();
            if (invAcctD.getAccount() == null) {
                invAcctD.refreshReferenceObject(KFSPropertyConstants.ACCOUNT);
            }
            final SubFundGroup subFundGroup = invAcctD.getAccount().getSubFundGroup();
            final Integer sequenceNumber = contractsGrantsInvoiceDocument.getAccountDetails().indexOf(invAcctD) + 1;
            final String accountKey = StringUtils.join(new String[] { chartOfAccountsCode, accountNumber }, "-");
            KualiDecimal totalAmount = accountExpenditureAmounts.getOrDefault(accountKey, KualiDecimal.ZERO);
            if (invAcctD.getTotalPreviouslyBilled().isZero()) {
                KualiDecimal previouslyBilledAmount = getPredeterminedBillingBilledToDateAmount(proposalNumber, chartOfAccountsCode, accountNumber);
                previouslyBilledAmount = previouslyBilledAmount.add(getMilestonesBilledToDateAmount(proposalNumber, chartOfAccountsCode, accountNumber));
                KualiDecimal totalBilledAmount = accountTotalBilledAmounts.getOrDefault(accountKey, KualiDecimal.ZERO);
                previouslyBilledAmount = previouslyBilledAmount.subtract(totalBilledAmount);
                if (previouslyBilledAmount.isGreaterThan(KualiDecimal.ZERO)) {
                    totalAmount = totalAmount.subtract(previouslyBilledAmount);
                }
            }
            CustomerInvoiceDetail cide = createSourceAccountingLine(contractsGrantsInvoiceDocument.getDocumentNumber(), chartOfAccountsCode, accountNumber, subFundGroup, totalAmount, sequenceNumber);
            awardAccountingLines.add(cide);
        }
    }
    return awardAccountingLines;
}
Also used : SubFundGroup(org.kuali.kfs.coa.businessobject.SubFundGroup) ArrayList(java.util.ArrayList) CustomerInvoiceDetail(org.kuali.kfs.module.ar.businessobject.CustomerInvoiceDetail) 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)

Example 85 with KualiDecimal

use of org.kuali.kfs.core.api.util.type.KualiDecimal in project cu-kfs by CU-CommunityApps.

the class CustomerInvoiceDetailServiceImpl method recalculateCustomerInvoiceDetail.

@Override
public void recalculateCustomerInvoiceDetail(CustomerInvoiceDocument customerInvoiceDocument, CustomerInvoiceDetail customerInvoiceDetail) {
    // make sure amounts are negative when they are supposed to be
    if (!customerInvoiceDocument.isInvoiceReversal() && customerInvoiceDetail.isDiscountLine()) {
        customerInvoiceDetail.setInvoiceItemUnitPriceToNegative();
    } else if (customerInvoiceDocument.isInvoiceReversal() && !customerInvoiceDetail.isDiscountLine()) {
        customerInvoiceDetail.setInvoiceItemUnitPriceToNegative();
    }
    KualiDecimal pretaxAmount = customerInvoiceDetail.getInvoiceItemPreTaxAmount();
    KualiDecimal taxAmount = KualiDecimal.ZERO;
    if (accountsReceivableTaxService.isCustomerInvoiceDetailTaxable(customerInvoiceDocument, customerInvoiceDetail)) {
        String postalCode = accountsReceivableTaxService.getPostalCodeForTaxation(customerInvoiceDocument);
        taxAmount = taxService.getTotalSalesTaxAmount(dateTimeService.getCurrentSqlDate(), postalCode, pretaxAmount);
    }
    customerInvoiceDetail.setInvoiceItemTaxAmount(taxAmount);
    customerInvoiceDetail.setAmount(taxAmount.add(pretaxAmount));
}
Also used : KualiDecimal(org.kuali.kfs.core.api.util.type.KualiDecimal)

Aggregations

KualiDecimal (org.kuali.kfs.core.api.util.type.KualiDecimal)280 ArrayList (java.util.ArrayList)46 HashMap (java.util.HashMap)36 Test (org.junit.Test)28 AbstractKualiDecimal (org.kuali.kfs.core.api.util.type.AbstractKualiDecimal)21 BigDecimal (java.math.BigDecimal)18 List (java.util.List)18 SourceAccountingLine (org.kuali.kfs.sys.businessobject.SourceAccountingLine)15 Date (java.sql.Date)14 CapitalAssetInformation (org.kuali.kfs.fp.businessobject.CapitalAssetInformation)14 PrepareForTest (org.powermock.core.classloader.annotations.PrepareForTest)14 ConcurStandardAccountingExtractDetailLine (edu.cornell.kfs.concur.batch.businessobject.ConcurStandardAccountingExtractDetailLine)11 KualiInteger (org.kuali.kfs.core.api.util.type.KualiInteger)11 ParameterService (org.kuali.kfs.coreservice.framework.parameter.ParameterService)11 IOException (java.io.IOException)10 InvoiceDetailAccountObjectCode (org.kuali.kfs.module.ar.businessobject.InvoiceDetailAccountObjectCode)10 Map (java.util.Map)9 ParameterEvaluator (org.kuali.kfs.core.api.parameter.ParameterEvaluator)9 CapitalAccountingLines (org.kuali.kfs.fp.businessobject.CapitalAccountingLines)9 PurchaseOrderItem (org.kuali.kfs.module.purap.businessobject.PurchaseOrderItem)8