Search in sources :

Example 1 with ElectronicInvoiceOrderHolder

use of org.kuali.kfs.module.purap.service.impl.ElectronicInvoiceOrderHolder in project cu-kfs by CU-CommunityApps.

the class CuElectronicInvoiceMatchingServiceImpl method validateUnitPrice.

protected void validateUnitPrice(ElectronicInvoiceItemHolder itemHolder) {
    PurchaseOrderCostSource costSource = itemHolder.getInvoiceOrderHolder().getPurchaseOrderDocument().getPurchaseOrderCostSource();
    PurchaseOrderItem poItem = itemHolder.getPurchaseOrderItem();
    ElectronicInvoiceOrderHolder orderHolder = itemHolder.getInvoiceOrderHolder();
    String extraDescription = "Invoice Item Line Number:" + itemHolder.getInvoiceItemLineNumber();
    BigDecimal actualVariance = itemHolder.getInvoiceItemUnitPrice().subtract(poItem.getItemUnitPrice());
    BigDecimal lowerPercentage = null;
    if (costSource.getItemUnitPriceLowerVariancePercent() != null) {
        // Checking for lower variance
        lowerPercentage = costSource.getItemUnitPriceLowerVariancePercent();
    } else {
        // If the cost source itemUnitPriceLowerVariancePercent is null then
        // we'll use the exact match (100%).
        lowerPercentage = new BigDecimal(100);
    }
    BigDecimal lowerAcceptableVariance = (lowerPercentage.divide(new BigDecimal(100))).multiply(poItem.getItemUnitPrice()).negate();
    // KFSUPGRADE-485
    if (!poItem.isNoQtyItem() && lowerAcceptableVariance.compareTo(actualVariance) > 0) {
        ElectronicInvoiceRejectReason rejectReason = createRejectReason(PurapConstants.ElectronicInvoice.INVOICE_AMT_LESSER_THAN_LOWER_VARIANCE, extraDescription, orderHolder.getFileName());
        orderHolder.addInvoiceOrderRejectReason(rejectReason, PurapConstants.ElectronicInvoice.RejectDocumentFields.INVOICE_ITEM_UNIT_PRICE, PurapKeyConstants.ERROR_REJECT_UNITPRICE_LOWERVARIANCE);
    }
    BigDecimal upperPercentage = null;
    if (costSource.getItemUnitPriceUpperVariancePercent() != null) {
        // Checking for upper variance
        upperPercentage = costSource.getItemUnitPriceUpperVariancePercent();
    } else {
        // If the cost source itemUnitPriceLowerVariancePercent is null then
        // we'll use the exact match (100%).
        upperPercentage = new BigDecimal(100);
    }
    BigDecimal upperAcceptableVariance = (upperPercentage.divide(new BigDecimal(100))).multiply(poItem.getItemUnitPrice());
    if (upperAcceptableVariance.compareTo(actualVariance) < 0) {
        ElectronicInvoiceRejectReason rejectReason = createRejectReason(PurapConstants.ElectronicInvoice.INVOICE_AMT_GREATER_THAN_UPPER_VARIANCE, extraDescription, orderHolder.getFileName());
        orderHolder.addInvoiceOrderRejectReason(rejectReason, PurapConstants.ElectronicInvoice.RejectDocumentFields.INVOICE_ITEM_UNIT_PRICE, PurapKeyConstants.ERROR_REJECT_UNITPRICE_UPPERVARIANCE);
    }
}
Also used : PurchaseOrderCostSource(org.kuali.kfs.vnd.businessobject.PurchaseOrderCostSource) PurchaseOrderItem(org.kuali.kfs.module.purap.businessobject.PurchaseOrderItem) ElectronicInvoiceRejectReason(org.kuali.kfs.module.purap.businessobject.ElectronicInvoiceRejectReason) BigDecimal(java.math.BigDecimal) ElectronicInvoiceOrderHolder(org.kuali.kfs.module.purap.service.impl.ElectronicInvoiceOrderHolder)

Example 2 with ElectronicInvoiceOrderHolder

use of org.kuali.kfs.module.purap.service.impl.ElectronicInvoiceOrderHolder in project cu-kfs by CU-CommunityApps.

the class CuElectronicInvoiceMatchingServiceImpl method validateCatalogNumber.

protected void validateCatalogNumber(ElectronicInvoiceItemHolder itemHolder) {
    PurchaseOrderItem poItem = itemHolder.getPurchaseOrderItem();
    ElectronicInvoiceOrderHolder orderHolder = itemHolder.getInvoiceOrderHolder();
    String invoiceCatalogNumberStripped = itemHolder.getCatalogNumberStripped();
    String poCatalogNumberStripped = ElectronicInvoiceUtils.stripSplChars(poItem.getItemCatalogNumber());
    /**
     * If Catalog number in invoice and po are not empty, create reject reason if it doesn't match
     */
    if (StringUtils.isNotBlank(invoiceCatalogNumberStripped) && StringUtils.isNotBlank(poCatalogNumberStripped)) {
        if (!StringUtils.equalsIgnoreCase(poCatalogNumberStripped, invoiceCatalogNumberStripped)) {
            String extraDescription = "Invoice Catalog No:" + invoiceCatalogNumberStripped + ", PO Catalog No:" + poCatalogNumberStripped;
            ElectronicInvoiceRejectReason rejectReason = createRejectReason(PurapConstants.ElectronicInvoice.CATALOG_NUMBER_MISMATCH, extraDescription, orderHolder.getFileName());
            orderHolder.addInvoiceOrderRejectReason(rejectReason, PurapConstants.ElectronicInvoice.RejectDocumentFields.INVOICE_ITEM_CATALOG_NUMBER, PurapKeyConstants.ERROR_REJECT_CATALOG_MISMATCH);
        }
    } else {
        /**
         * If catalog number is empty in PO/&Invoice, check whether the catalog check is required for the requisition source.
         * If exists in param, create reject reason.
         * If not exists, continue with UOM and unit price match.
         */
        String reqSourceRequiringCatalogMatch = SpringContext.getBean(ParameterService.class).getParameterValueAsString(ElectronicInvoiceStep.class, PurapParameterConstants.ElectronicInvoiceParameters.REQUISITION_SOURCES_REQUIRING_CATALOG_MATCHING);
        String requisitionSourceCodeInPO = orderHolder.getPurchaseOrderDocument().getRequisitionSourceCode();
        if (StringUtils.isNotEmpty(reqSourceRequiringCatalogMatch)) {
            String[] requisitionSourcesFromParam = StringUtils.split(reqSourceRequiringCatalogMatch, ';');
            if (ArrayUtils.contains(requisitionSourcesFromParam, requisitionSourceCodeInPO)) {
                String extraDescription = "Invoice Catalog No:" + invoiceCatalogNumberStripped + ", PO Catalog No:" + poItem.getItemCatalogNumber();
                ElectronicInvoiceRejectReason rejectReason = createRejectReason(PurapConstants.ElectronicInvoice.CATALOG_NUMBER_MISMATCH, extraDescription, orderHolder.getFileName());
                orderHolder.addInvoiceOrderRejectReason(rejectReason, PurapConstants.ElectronicInvoice.RejectDocumentFields.INVOICE_ITEM_CATALOG_NUMBER, PurapKeyConstants.ERROR_REJECT_CATALOG_MISMATCH);
            }
        }
    }
}
Also used : PurchaseOrderItem(org.kuali.kfs.module.purap.businessobject.PurchaseOrderItem) ParameterService(org.kuali.kfs.coreservice.framework.parameter.ParameterService) ElectronicInvoiceRejectReason(org.kuali.kfs.module.purap.businessobject.ElectronicInvoiceRejectReason) ElectronicInvoiceOrderHolder(org.kuali.kfs.module.purap.service.impl.ElectronicInvoiceOrderHolder)

Example 3 with ElectronicInvoiceOrderHolder

use of org.kuali.kfs.module.purap.service.impl.ElectronicInvoiceOrderHolder in project cu-kfs by CU-CommunityApps.

the class CuElectronicInvoiceMatchingServiceImpl method validateInvoiceItem.

protected void validateInvoiceItem(ElectronicInvoiceItemHolder itemHolder, Set poLineNumbers, Set invLineNumbers) {
    PurchaseOrderItem poItem = itemHolder.getPurchaseOrderItem();
    ElectronicInvoiceOrderHolder orderHolder = itemHolder.getInvoiceOrderHolder();
    boolean isNonMatching = false;
    if (poItem == null) {
        // investigating.  this should stay because the inv line should have the correcrt invitemline# set up
        String extraDescription = "Invoice Item Line Number:" + itemHolder.getInvoiceItemLineNumber();
        ElectronicInvoiceRejectReason rejectReason = createRejectReason(PurapConstants.ElectronicInvoice.NO_MATCHING_PO_ITEM, extraDescription, orderHolder.getFileName());
        orderHolder.addInvoiceOrderRejectReason(rejectReason, PurapConstants.ElectronicInvoice.RejectDocumentFields.INVOICE_ITEM_LINE_NUMBER, PurapKeyConstants.ERROR_REJECT_INVOICE__ITEM_NOMATCH);
        return;
    }
    // only noqty item.  the old behavior for qty item does not check the duplicate inv line#
    if (invLineNumbers.contains(((CuElectronicInvoiceItemHolder) itemHolder).getInvLineNumber()) && poItem.isNoQtyItem()) {
        String extraDescription = "Invoice Item Line Number:" + itemHolder.getInvoiceItemLineNumber();
        ElectronicInvoiceRejectReason rejectReason = createRejectReason(PurapConstants.ElectronicInvoice.DUPLIATE_INVOICE_LINE_ITEM, extraDescription, orderHolder.getFileName());
        orderHolder.addInvoiceOrderRejectReason(rejectReason, PurapConstants.ElectronicInvoice.RejectDocumentFields.INVOICE_ITEM_LINE_NUMBER, PurapKeyConstants.ERROR_REJECT_PO_ITEM_DUPLICATE);
        return;
    } else {
        invLineNumbers.add(((CuElectronicInvoiceItemHolder) itemHolder).getInvLineNumber());
    }
    if (poLineNumbers.contains(itemHolder.getInvoiceItemLineNumber())) {
        // TODO : investigating Do NOT commit.  Duplicate is not OK for qty item
        if (!poItem.isNoQtyItem()) {
            String extraDescription = "Invoice Item Line Number:" + itemHolder.getInvoiceItemLineNumber();
            ElectronicInvoiceRejectReason rejectReason = createRejectReason(PurapConstants.ElectronicInvoice.DUPLIATE_INVOICE_LINE_ITEM, extraDescription, orderHolder.getFileName());
            orderHolder.addInvoiceOrderRejectReason(rejectReason, PurapConstants.ElectronicInvoice.RejectDocumentFields.INVOICE_ITEM_LINE_NUMBER, PurapKeyConstants.ERROR_REJECT_PO_ITEM_DUPLICATE);
            return;
        } else {
            ((CuElectronicInvoiceOrderHolder) orderHolder).getNonMatchItems().add((CuElectronicInvoiceItemHolder) itemHolder);
            isNonMatching = true;
        }
    } else {
        poLineNumbers.add(itemHolder.getInvoiceItemLineNumber());
    }
    if (!poItem.isItemActiveIndicator()) {
        String extraDescription = "PO Item Line Number:" + poItem.getItemLineNumber();
        ElectronicInvoiceRejectReason rejectReason = createRejectReason(PurapConstants.ElectronicInvoice.INACTIVE_LINE_ITEM, extraDescription, orderHolder.getFileName());
        orderHolder.addInvoiceOrderRejectReason(rejectReason, PurapConstants.ElectronicInvoice.RejectDocumentFields.INVOICE_ITEM_LINE_NUMBER, PurapKeyConstants.ERROR_REJECT_PO_ITEM_INACTIVE);
        return;
    }
    // KFSPTS-1719 skip this if po is noqty item
    if (!itemHolder.isCatalogNumberAcceptIndicatorEnabled() && !poItem.isNoQtyItem()) {
        validateCatalogNumber(itemHolder);
        if (orderHolder.isInvoiceRejected()) {
            return;
        }
    }
    if (!itemHolder.isUnitOfMeasureAcceptIndicatorEnabled()) {
        // KFSUPGRADE-485 : if po is no qty but inv is qty, then is it necessary to check here ?  should not matter
        if (!poItem.isNoQtyItem() && !StringUtils.equalsIgnoreCase(poItem.getItemUnitOfMeasureCode(), itemHolder.getInvoiceItemUnitOfMeasureCode())) {
            String extraDescription = "Invoice UOM:" + itemHolder.getInvoiceItemUnitOfMeasureCode() + ", PO UOM:" + poItem.getItemUnitOfMeasureCode();
            ElectronicInvoiceRejectReason rejectReason = createRejectReason(PurapConstants.ElectronicInvoice.UNIT_OF_MEASURE_MISMATCH, extraDescription, orderHolder.getFileName());
            orderHolder.addInvoiceOrderRejectReason(rejectReason, PurapConstants.ElectronicInvoice.RejectDocumentFields.INVOICE_ITEM_UOM, PurapKeyConstants.ERROR_REJECT_UOM_MISMATCH);
            return;
        }
    }
    validateUnitPrice(itemHolder);
    if (orderHolder.isInvoiceRejected()) {
        return;
    }
    validateSalesTax(itemHolder);
    if (orderHolder.isInvoiceRejected()) {
        return;
    }
    // KFSPTS-1719, KFSUPGRADE-485 : this is more appropriate to check if item is non-qty.  because user can potentially enter qty for non-qty item
    if (!poItem.isNoQtyItem()) {
        // if (poItem.getItemQuantity() != null) {
        validateQtyBasedItem(itemHolder);
    } else {
        validateNonQtyBasedItem(itemHolder);
    }
}
Also used : PurchaseOrderItem(org.kuali.kfs.module.purap.businessobject.PurchaseOrderItem) ElectronicInvoiceRejectReason(org.kuali.kfs.module.purap.businessobject.ElectronicInvoiceRejectReason) ElectronicInvoiceOrderHolder(org.kuali.kfs.module.purap.service.impl.ElectronicInvoiceOrderHolder)

Example 4 with ElectronicInvoiceOrderHolder

use of org.kuali.kfs.module.purap.service.impl.ElectronicInvoiceOrderHolder in project cu-kfs by CU-CommunityApps.

the class CuElectronicInvoiceMatchingServiceImpl method validateNonQtyBasedItem.

protected void validateNonQtyBasedItem(ElectronicInvoiceItemHolder itemHolder) {
    PurchaseOrderItem poItem = itemHolder.getPurchaseOrderItem();
    String fileName = itemHolder.getInvoiceOrderHolder().getFileName();
    ElectronicInvoiceOrderHolder orderHolder = itemHolder.getInvoiceOrderHolder();
    // Only validation is that the invoice amount (amount of PayReq) can not be greater than the extended cost minus amount paid
    if (itemHolder.getInvoiceItemSubTotalAmount().setScale(KualiDecimal.SCALE, KualiDecimal.ROUND_BEHAVIOR).compareTo(poItem.getExtendedPrice().subtract(poItem.getItemInvoicedTotalAmount()).bigDecimalValue()) > 0) {
        String extraDescription = "Invoice Item Line Number:" + itemHolder.getInvoiceItemLineNumber();
        ElectronicInvoiceRejectReason rejectReason = createRejectReason(PurapConstants.ElectronicInvoice.PO_ITEM_AMT_LESSTHAN_INVOICE_ITEM_AMT, extraDescription, orderHolder.getFileName());
        orderHolder.addInvoiceOrderRejectReason(rejectReason, PurapConstants.ElectronicInvoice.RejectDocumentFields.INVOICE_ITEM_LINE_NUMBER, PurapKeyConstants.ERROR_REJECT_POITEM_LESS_OUTSTANDING_EMCUMBERED_AMOUNT);
        return;
    }
    if ((KualiDecimal.ZERO.compareTo(poItem.getItemOutstandingEncumberedAmount())) >= 0) {
        // we have no dollars left encumbered on the po item
        String extraDescription = "Invoice Item Line Number:" + itemHolder.getInvoiceItemLineNumber();
        ElectronicInvoiceRejectReason rejectReason = createRejectReason(PurapConstants.ElectronicInvoice.OUTSTANDING_ENCUMBERED_AMT_AVAILABLE, extraDescription, orderHolder.getFileName());
        orderHolder.addInvoiceOrderRejectReason(rejectReason, PurapConstants.ElectronicInvoice.RejectDocumentFields.INVOICE_ITEM_LINE_NUMBER, PurapKeyConstants.ERROR_REJECT_POITEM_OUTSTANDING_EMCUMBERED_AMOUNT);
        return;
    } else {
        // KFSUPGRADE-485
        if (((itemHolder.getInvoiceItemSubTotalAmount().setScale(KualiDecimal.SCALE, KualiDecimal.ROUND_BEHAVIOR)).compareTo(poItem.getItemOutstandingEncumberedAmount().bigDecimalValue())) > 0 || ((getItemTotalAmount(itemHolder).setScale(KualiDecimal.SCALE, KualiDecimal.ROUND_BEHAVIOR)).compareTo(poItem.getItemOutstandingEncumberedAmount().bigDecimalValue())) > 0) {
            String extraDescription = "Invoice Item Line Number:" + itemHolder.getInvoiceItemLineNumber();
            ElectronicInvoiceRejectReason rejectReason = createRejectReason(PurapConstants.ElectronicInvoice.PO_ITEM_AMT_LESSTHAN_INVOICE_ITEM_AMT, extraDescription, orderHolder.getFileName());
            orderHolder.addInvoiceOrderRejectReason(rejectReason, PurapConstants.ElectronicInvoice.RejectDocumentFields.INVOICE_ITEM_LINE_NUMBER, PurapKeyConstants.ERROR_REJECT_POITEM_LESS_OUTSTANDING_EMCUMBERED_AMOUNT);
            return;
        }
    }
}
Also used : PurchaseOrderItem(org.kuali.kfs.module.purap.businessobject.PurchaseOrderItem) ElectronicInvoiceRejectReason(org.kuali.kfs.module.purap.businessobject.ElectronicInvoiceRejectReason) ElectronicInvoiceOrderHolder(org.kuali.kfs.module.purap.service.impl.ElectronicInvoiceOrderHolder)

Aggregations

ElectronicInvoiceRejectReason (org.kuali.kfs.module.purap.businessobject.ElectronicInvoiceRejectReason)4 PurchaseOrderItem (org.kuali.kfs.module.purap.businessobject.PurchaseOrderItem)4 ElectronicInvoiceOrderHolder (org.kuali.kfs.module.purap.service.impl.ElectronicInvoiceOrderHolder)4 BigDecimal (java.math.BigDecimal)1 ParameterService (org.kuali.kfs.coreservice.framework.parameter.ParameterService)1 PurchaseOrderCostSource (org.kuali.kfs.vnd.businessobject.PurchaseOrderCostSource)1