Search in sources :

Example 6 with PurApAccountingLine

use of org.kuali.kfs.module.purap.businessobject.PurApAccountingLine in project cu-kfs by CU-CommunityApps.

the class PurchasingDocumentBase method isAccountingLineChanged.

/*
     * check if the accounting line of the item has been changed
     */
private boolean isAccountingLineChanged(PurchasingItemBase item, PurchasingItemBase prevItem) {
    boolean isChanged = false;
    for (PurApAccountingLine acctLine : item.getSourceAccountingLines()) {
        boolean acctLineFound = false;
        for (PurApAccountingLine prevAcctLine : prevItem.getSourceAccountingLines()) {
            boolean isMatched = true;
            isMatched &= StringUtils.equals(acctLine.getChartOfAccountsCode(), prevAcctLine.getChartOfAccountsCode());
            isMatched &= StringUtils.equals(acctLine.getAccountNumber(), prevAcctLine.getAccountNumber());
            isMatched &= StringUtils.equals(acctLine.getFinancialObjectCode(), prevAcctLine.getFinancialObjectCode());
            isMatched &= StringUtils.equals(acctLine.getFinancialSubObjectCode(), prevAcctLine.getFinancialSubObjectCode());
            isMatched &= StringUtils.equals(acctLine.getSubAccountNumber(), prevAcctLine.getSubAccountNumber());
            isMatched &= StringUtils.equals(acctLine.getOrganizationReferenceId(), prevAcctLine.getOrganizationReferenceId());
            isMatched &= StringUtils.equals(acctLine.getProjectCode(), prevAcctLine.getProjectCode());
            isMatched &= acctLine.getAccountLinePercent().equals(prevAcctLine.getAccountLinePercent());
            if (isMatched) {
                acctLineFound = true;
                break;
            }
        }
        if (!acctLineFound) {
            // no acct line matched, then it meant that something changed or this is a new line.
            isChanged = true;
            break;
        }
    }
    return isChanged;
}
Also used : PurApAccountingLine(org.kuali.kfs.module.purap.businessobject.PurApAccountingLine)

Example 7 with PurApAccountingLine

use of org.kuali.kfs.module.purap.businessobject.PurApAccountingLine in project cu-kfs by CU-CommunityApps.

the class CuPurapServiceImpl method prorateForTradeInAndFullOrderDiscount.

public void prorateForTradeInAndFullOrderDiscount(PurchasingAccountsPayableDocument purDoc) {
    if (purDoc instanceof VendorCreditMemoDocument) {
        throw new RuntimeException("This method not applicable for VCM documents");
    }
    // TODO: are we throwing sufficient errors in this method?
    PurApItem fullOrderDiscount = null;
    PurApItem tradeIn = null;
    KualiDecimal totalAmount = KualiDecimal.ZERO;
    KualiDecimal totalTaxAmount = KualiDecimal.ZERO;
    List<PurApAccountingLine> distributedAccounts = null;
    List<SourceAccountingLine> summaryAccounts = null;
    // iterate through below the line and grab FoD and TrdIn.
    for (PurApItem item : purDoc.getItems()) {
        if (item.getItemTypeCode().equals(PurapConstants.ItemTypeCodes.ITEM_TYPE_ORDER_DISCOUNT_CODE)) {
            fullOrderDiscount = item;
        } else if (item.getItemTypeCode().equals(PurapConstants.ItemTypeCodes.ITEM_TYPE_TRADE_IN_CODE)) {
            tradeIn = item;
        }
    }
    // If Discount is not null or zero get proration list for all non misc items and set (if not empty?)
    if (fullOrderDiscount != null && fullOrderDiscount.getExtendedPrice() != null && fullOrderDiscount.getExtendedPrice().isNonZero()) {
        // empty
        KNSGlobalVariables.getMessageList().add("Full order discount accounts cleared and regenerated");
        fullOrderDiscount.getSourceAccountingLines().clear();
        // total amount is pretax dollars
        totalAmount = purDoc.getTotalDollarAmountAboveLineItems().subtract(purDoc.getTotalTaxAmountAboveLineItems());
        totalTaxAmount = purDoc.getTotalTaxAmountAboveLineItems();
        // Before we generate account summary, we should update the account amounts first.
        purapAccountingService.updateAccountAmounts(purDoc);
        // calculate tax
        boolean salesTaxInd = SpringContext.getBean(ParameterService.class).getParameterValueAsBoolean(KfsParameterConstants.PURCHASING_DOCUMENT.class, PurapParameterConstants.ENABLE_SALES_TAX_IND);
        boolean useTaxIndicator = purDoc.isUseTaxIndicator();
        if (salesTaxInd == true && (ObjectUtils.isNull(fullOrderDiscount.getItemTaxAmount()) && useTaxIndicator == false)) {
            KualiDecimal discountAmount = fullOrderDiscount.getExtendedPrice();
            KualiDecimal discountTaxAmount = discountAmount.divide(totalAmount).multiply(totalTaxAmount);
            fullOrderDiscount.setItemTaxAmount(discountTaxAmount);
        }
        // generate summary
        summaryAccounts = purapAccountingService.generateSummary(PurApItemUtils.getAboveTheLineOnly(purDoc.getItems()));
        if (summaryAccounts.size() == 0) {
            if (purDoc.shouldGiveErrorForEmptyAccountsProration()) {
                GlobalVariables.getMessageMap().putError(PurapConstants.ITEM_TAB_ERROR_PROPERTY, PurapKeyConstants.ERROR_SUMMARY_ACCOUNTS_LIST_EMPTY, "full order discount");
            }
        } else {
            // prorate accounts
            distributedAccounts = purapAccountingService.generateAccountDistributionForProration(summaryAccounts, totalAmount.add(totalTaxAmount), 2, fullOrderDiscount.getAccountingLineClass());
            for (PurApAccountingLine distributedAccount : distributedAccounts) {
                // KFSPTS-2200 : set item, so it can be verified as discount when validating
                if (distributedAccount instanceof PurApAccountingLineBase) {
                    ((PurApAccountingLineBase) distributedAccount).setDiscountTradeIn(true);
                }
                BigDecimal percent = distributedAccount.getAccountLinePercent();
                BigDecimal roundedPercent = new BigDecimal(Math.round(percent.doubleValue()));
                distributedAccount.setAccountLinePercent(roundedPercent);
            }
            // update amounts on distributed accounts
            purapAccountingService.updateAccountAmountsWithTotal(distributedAccounts, totalAmount, fullOrderDiscount.getTotalAmount());
            fullOrderDiscount.setSourceAccountingLines(distributedAccounts);
        }
    } else if (fullOrderDiscount != null && (fullOrderDiscount.getExtendedPrice() == null || fullOrderDiscount.getExtendedPrice().isZero())) {
        fullOrderDiscount.getSourceAccountingLines().clear();
    }
    // If tradeIn is not null or zero get proration list for all non misc items and set (if not empty?)
    if (tradeIn != null && tradeIn.getExtendedPrice() != null && tradeIn.getExtendedPrice().isNonZero()) {
        tradeIn.getSourceAccountingLines().clear();
        totalAmount = purDoc.getTotalDollarAmountForTradeIn();
        KualiDecimal tradeInTotalAmount = tradeIn.getTotalAmount();
        // Before we generate account summary, we should update the account amounts first.
        purapAccountingService.updateAccountAmounts(purDoc);
        // Before generating the summary, lets replace the object code in a cloned accounts collection sothat we can
        // consolidate all the modified object codes during summary generation.
        List<PurApItem> clonedTradeInItems = new ArrayList<PurApItem>();
        Collection<String> objectSubTypesRequiringQty = new ArrayList<String>(SpringContext.getBean(ParameterService.class).getParameterValuesAsString(KfsParameterConstants.PURCHASING_DOCUMENT.class, PurapParameterConstants.OBJECT_SUB_TYPES_REQUIRING_QUANTITY));
        Collection<String> purchasingObjectSubTypes = new ArrayList<String>(SpringContext.getBean(ParameterService.class).getParameterValuesAsString(KfsParameterConstants.CAPITAL_ASSETS_BATCH.class, PurapParameterConstants.PURCHASING_OBJECT_SUB_TYPES));
        String tradeInCapitalObjectCode = SpringContext.getBean(ParameterService.class).getParameterValueAsString(PurapConstants.PURAP_NAMESPACE, "Document", "TRADE_IN_OBJECT_CODE_FOR_CAPITAL_ASSET");
        String tradeInCapitalLeaseObjCd = SpringContext.getBean(ParameterService.class).getParameterValueAsString(PurapConstants.PURAP_NAMESPACE, "Document", "TRADE_IN_OBJECT_CODE_FOR_CAPITAL_LEASE");
        for (PurApItem item : purDoc.getTradeInItems()) {
            PurApItem cloneItem = (PurApItem) ObjectUtils.deepCopy(item);
            List<PurApAccountingLine> sourceAccountingLines = cloneItem.getSourceAccountingLines();
            for (PurApAccountingLine accountingLine : sourceAccountingLines) {
                if (objectSubTypesRequiringQty.contains(accountingLine.getObjectCode().getFinancialObjectSubTypeCode())) {
                    accountingLine.setFinancialObjectCode(tradeInCapitalObjectCode);
                } else if (purchasingObjectSubTypes.contains(accountingLine.getObjectCode().getFinancialObjectSubTypeCode())) {
                    accountingLine.setFinancialObjectCode(tradeInCapitalLeaseObjCd);
                }
            }
            clonedTradeInItems.add(cloneItem);
        }
        summaryAccounts = purapAccountingService.generateSummary(clonedTradeInItems);
        if (summaryAccounts.size() == 0) {
            if (purDoc.shouldGiveErrorForEmptyAccountsProration()) {
                GlobalVariables.getMessageMap().putError(PurapConstants.ITEM_TAB_ERROR_PROPERTY, PurapKeyConstants.ERROR_SUMMARY_ACCOUNTS_LIST_EMPTY, "trade in");
            }
        } else {
            distributedAccounts = purapAccountingService.generateAccountDistributionForProration(summaryAccounts, totalAmount, 2, tradeIn.getAccountingLineClass());
            for (PurApAccountingLine distributedAccount : distributedAccounts) {
                // KFSPTS-2200 : set item, so it can be verified as discount when validating
                if (distributedAccount instanceof PurApAccountingLineBase) {
                    ((PurApAccountingLineBase) distributedAccount).setDiscountTradeIn(true);
                }
                BigDecimal percent = distributedAccount.getAccountLinePercent();
                BigDecimal roundedPercent = new BigDecimal(Math.round(percent.doubleValue()));
                distributedAccount.setAccountLinePercent(roundedPercent);
                // set the accountAmount same as tradeIn amount not line item's amount
                resetAccountAmount(distributedAccount, tradeInTotalAmount);
            }
            tradeIn.setSourceAccountingLines(distributedAccounts);
        }
    }
}
Also used : VendorCreditMemoDocument(org.kuali.kfs.module.purap.document.VendorCreditMemoDocument) PurApItem(org.kuali.kfs.module.purap.businessobject.PurApItem) ParameterService(org.kuali.kfs.coreservice.framework.parameter.ParameterService) PurApAccountingLine(org.kuali.kfs.module.purap.businessobject.PurApAccountingLine) KfsParameterConstants(org.kuali.kfs.sys.service.impl.KfsParameterConstants) ArrayList(java.util.ArrayList) SourceAccountingLine(org.kuali.kfs.sys.businessobject.SourceAccountingLine) PurApAccountingLineBase(org.kuali.kfs.module.purap.businessobject.PurApAccountingLineBase) BigDecimal(java.math.BigDecimal) KualiDecimal(org.kuali.rice.core.api.util.type.KualiDecimal)

Example 8 with PurApAccountingLine

use of org.kuali.kfs.module.purap.businessobject.PurApAccountingLine in project cu-kfs by CU-CommunityApps.

the class CuPurapAccountingServiceImpl method updatePreqAccountAmountsOnly.

/*
     * the calculation is based on the percentage of new total amount divided by the existing item totals.
     * The calculated percentage is high precision (20 decimal digits).
     * Then this calculated percentage is used to update each accounting line amount accordingly.
     */
private <T extends PurApAccountingLine> void updatePreqAccountAmountsOnly(List<T> sourceAccountingLines, KualiDecimal totalAmount) {
    if ((totalAmount != null) && KualiDecimal.ZERO.compareTo(totalAmount) != 0) {
        KualiDecimal accountTotal = getItemAccountTotal((List<PurApAccountingLine>) sourceAccountingLines);
        if ((!accountTotal.equals(totalAmount) || isAnyAccountLinePercentEmpty((List<PurApAccountingLine>) sourceAccountingLines)) && !accountTotal.equals(KualiDecimal.ZERO)) {
            BigDecimal tmpPercent = totalAmount.bigDecimalValue().divide(accountTotal.bigDecimalValue(), PurapConstants.CREDITMEMO_PRORATION_SCALE.intValue(), KualiDecimal.ROUND_BEHAVIOR);
            int accountNum = 0;
            accountTotal = KualiDecimal.ZERO;
            BigDecimal percentTotalRoundUp = BigDecimal.ZERO;
            for (T account : sourceAccountingLines) {
                if (accountNum++ < sourceAccountingLines.size() - 1) {
                    if (ObjectUtils.isNotNull(account.getAmount())) {
                        BigDecimal calcAmountBd = tmpPercent.multiply(account.getAmount().bigDecimalValue());
                        calcAmountBd = calcAmountBd.setScale(KualiDecimal.SCALE, KualiDecimal.ROUND_BEHAVIOR);
                        KualiDecimal calcAmount = new KualiDecimal(calcAmountBd);
                        account.setAmount(calcAmount);
                        if (ObjectUtils.isNull(account.getAccountLinePercent()) || account.getAccountLinePercent().compareTo(BigDecimal.ZERO) == 0) {
                            // Tax Item is regenerated if Treasury Manager 'calculate'
                            BigDecimal tmpAcctPercent = account.getAmount().bigDecimalValue().divide(totalAmount.bigDecimalValue(), PurapConstants.CREDITMEMO_PRORATION_SCALE.intValue(), KualiDecimal.ROUND_BEHAVIOR);
                            account.setAccountLinePercent(tmpAcctPercent.multiply(new BigDecimal(100)));
                        }
                        accountTotal = accountTotal.add(calcAmount);
                    }
                } else {
                    account.setAmount(totalAmount.subtract(accountTotal));
                    if (ObjectUtils.isNull(account.getAccountLinePercent()) || account.getAccountLinePercent().compareTo(BigDecimal.ZERO) == 0) {
                        account.setAccountLinePercent(new BigDecimal(100).subtract(percentTotalRoundUp));
                    }
                }
                percentTotalRoundUp = percentTotalRoundUp.add(account.getAccountLinePercent());
            }
        }
    } else {
        for (T account : sourceAccountingLines) {
            account.setAmount(KualiDecimal.ZERO);
        }
    }
}
Also used : PurApAccountingLine(org.kuali.kfs.module.purap.businessobject.PurApAccountingLine) KualiDecimal(org.kuali.rice.core.api.util.type.KualiDecimal) ArrayList(java.util.ArrayList) List(java.util.List) BigDecimal(java.math.BigDecimal)

Example 9 with PurApAccountingLine

use of org.kuali.kfs.module.purap.businessobject.PurApAccountingLine in project cu-kfs by CU-CommunityApps.

the class CuPurapAccountingServiceImpl method updatePreqItemAccountAmountsOnly.

/*
     * Updates PREQ accounting line amounts only when Treasury Manager is doing 'calculate'.
     * Currently, the foundation 'updateAccountAmounts' is based on the saved accounting line percentage which is rounded to 2 decimal digits.
     * If the total amount is changed by Treasury Manager, and the calculation is based on 'percentage' saved, then it will cause some amount fraction rounding issue.
     * This is reported in KFSPTS-3644.  You can see the detail explanation of the rounding issues.
     */
private void updatePreqItemAccountAmountsOnly(PurApItem item) {
    List<PurApAccountingLine> sourceAccountingLines = item.getSourceAccountingLines();
    KualiDecimal totalAmount = item.getTotalAmount();
    if (ObjectUtils.isNull(totalAmount) || totalAmount.equals(KualiDecimal.ZERO)) {
        totalAmount = getExtendedPrice(item);
    }
    if (!totalAmount.equals(KualiDecimal.ZERO) && getItemAccountTotal(sourceAccountingLines).equals(KualiDecimal.ZERO)) {
        // item.refreshReferenceObject("sourceAccountingLines"); // this is not working
        // The item account totals can become '0' if Treasury Manager set the unit price to '0 by accident and do calculate.
        // We need to refresh the accounting line amount from DB in order to continue.
        refreshAccountAmount(item);
    }
    if (StringUtils.equals(PurapConstants.ItemTypeCodes.ITEM_TYPE_MISC_CODE, item.getItemTypeCode()) || StringUtils.equals(PurapConstants.ItemTypeCodes.ITEM_TYPE_FREIGHT_CODE, item.getItemTypeCode()) || StringUtils.equals(PurapConstants.ItemTypeCodes.ITEM_TYPE_SHIP_AND_HAND_CODE, item.getItemTypeCode())) {
        if (totalAmount.isNonZero() && getItemAccountTotal(sourceAccountingLines).isZero()) {
            updateMiscFrtSphdAccountAmountsWithTotal(sourceAccountingLines, totalAmount);
        } else {
            updatePreqAccountAmountsOnly(sourceAccountingLines, totalAmount);
        }
    } else {
        updatePreqAccountAmountsOnly(sourceAccountingLines, totalAmount);
    }
}
Also used : PurApAccountingLine(org.kuali.kfs.module.purap.businessobject.PurApAccountingLine) KualiDecimal(org.kuali.rice.core.api.util.type.KualiDecimal)

Example 10 with PurApAccountingLine

use of org.kuali.kfs.module.purap.businessobject.PurApAccountingLine in project cu-kfs by CU-CommunityApps.

the class CuPurapAccountingServiceImpl method refreshAccountAmount.

private void refreshAccountAmount(PurApItem item) {
    Map fieldValues = new HashMap();
    fieldValues.put(PurapPropertyConstants.ITEM_IDENTIFIER, item.getItemIdentifier());
    PurApItem orgItem = businessObjectService.findByPrimaryKey(PaymentRequestItem.class, fieldValues);
    if (ObjectUtils.isNotNull(orgItem) && CollectionUtils.isNotEmpty(item.getSourceAccountingLines()) && CollectionUtils.isNotEmpty(orgItem.getSourceAccountingLines())) {
        for (PurApAccountingLine account : item.getSourceAccountingLines()) {
            for (PurApAccountingLine orgAccount : orgItem.getSourceAccountingLines()) {
                if (account.getAccountIdentifier().equals(orgAccount.getAccountIdentifier())) {
                    account.setAmount(orgAccount.getAmount());
                }
            }
        }
    }
}
Also used : HashMap(java.util.HashMap) PurApItem(org.kuali.kfs.module.purap.businessobject.PurApItem) PurApAccountingLine(org.kuali.kfs.module.purap.businessobject.PurApAccountingLine) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

PurApAccountingLine (org.kuali.kfs.module.purap.businessobject.PurApAccountingLine)27 PurApItem (org.kuali.kfs.module.purap.businessobject.PurApItem)17 ArrayList (java.util.ArrayList)9 List (java.util.List)7 ParameterService (org.kuali.kfs.coreservice.framework.parameter.ParameterService)7 BigDecimal (java.math.BigDecimal)6 PurchaseOrderItem (org.kuali.kfs.module.purap.businessobject.PurchaseOrderItem)5 KualiDecimal (org.kuali.rice.core.api.util.type.KualiDecimal)5 PurchaseOrderDocument (org.kuali.kfs.module.purap.document.PurchaseOrderDocument)4 IWantAccount (edu.cornell.kfs.module.purap.businessobject.IWantAccount)3 PurchaseOrderAmendmentDocument (org.kuali.kfs.module.purap.document.PurchaseOrderAmendmentDocument)3 PurchasingAccountsPayableDocument (org.kuali.kfs.module.purap.document.PurchasingAccountsPayableDocument)3 KfsParameterConstants (org.kuali.kfs.sys.service.impl.KfsParameterConstants)3 WorkflowDocument (org.kuali.rice.kew.api.WorkflowDocument)3 Account (org.kuali.kfs.coa.businessobject.Account)2 KualiRuleService (org.kuali.kfs.krad.service.KualiRuleService)2 PurchasingItemBase (org.kuali.kfs.module.purap.businessobject.PurchasingItemBase)2 RequisitionAccount (org.kuali.kfs.module.purap.businessobject.RequisitionAccount)2 PaymentRequestDocument (org.kuali.kfs.module.purap.document.PaymentRequestDocument)2 PurchasingAccountsPayableDocumentBase (org.kuali.kfs.module.purap.document.PurchasingAccountsPayableDocumentBase)2