Search in sources :

Example 11 with PurchaseOrderItem

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

the class PurchaseOrderDocument method getTotalTaxAmount.

/**
 * Gets the tax total amount for this Purchase Order.
 *
 * @param includeInactive indicates whether inactive items shall be included.
 * @param includeBelowTheLine indicates whether below the line items shall be included.
 * @return the total dollar amount for this Purchase Order.
 */
public KualiDecimal getTotalTaxAmount(boolean includeInactive, boolean includeBelowTheLine) {
    KualiDecimal total = new KualiDecimal(BigDecimal.ZERO);
    for (PurchaseOrderItem item : (List<PurchaseOrderItem>) getItems()) {
        ItemType it = item.getItemType();
        if ((includeBelowTheLine || it.isLineItemIndicator()) && (includeInactive || item.isItemActiveIndicator())) {
            KualiDecimal taxAmount = item.getItemTaxAmount();
            KualiDecimal itemTotal = (taxAmount != null) ? taxAmount : KualiDecimal.ZERO;
            total = total.add(itemTotal);
        }
    }
    return total;
}
Also used : PurchaseOrderItem(org.kuali.kfs.module.purap.businessobject.PurchaseOrderItem) ItemType(org.kuali.kfs.module.purap.businessobject.ItemType) KualiDecimal(org.kuali.rice.core.api.util.type.KualiDecimal) ArrayList(java.util.ArrayList) List(java.util.List)

Example 12 with PurchaseOrderItem

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

the class PurchasingActionBase method doDistribution.

/**
 * Distribute accounting line(s) to the item(s). Does not distribute the accounting line(s) to an item if there are already
 * accounting lines associated with that item, if the item is a below-the-line item and has no unit cost, or if the item is
 * inactive. Distribute commodity code to the item(s). Does not distribute the commodity code to an item if the item is not
 * above the line item, is inactive or if the commodity code fails the validation (i.e. inactive commodity code or non existence
 * commodity code).
 *
 * @param mapping An ActionMapping
 * @param form An ActionForm
 * @param request The HttpServletRequest
 * @param response The HttpServletResponse
 * @return An ActionForward
 * @throws Exception
 */
public ActionForward doDistribution(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
    PurchasingFormBase purchasingForm = (PurchasingFormBase) form;
    boolean needToDistributeCommodityCode = false;
    if (StringUtils.isNotBlank(purchasingForm.getDistributePurchasingCommodityCode())) {
        // Do the logic for distributing purchasing commodity code to all the items.
        needToDistributeCommodityCode = true;
    }
    boolean needToDistributeAccount = false;
    List<PurApAccountingLine> distributionsourceAccountingLines = purchasingForm.getAccountDistributionsourceAccountingLines();
    if (distributionsourceAccountingLines.size() > 0) {
        needToDistributeAccount = true;
    }
    if (needToDistributeAccount || needToDistributeCommodityCode) {
        PurchasingAccountsPayableDocumentBase purApDocument = (PurchasingAccountsPayableDocumentBase) purchasingForm.getDocument();
        boolean institutionNeedsDistributeAccountValidation = SpringContext.getBean(ParameterService.class).getParameterValueAsBoolean(KfsParameterConstants.PURCHASING_DOCUMENT.class, PurapParameterConstants.VALIDATE_ACCOUNT_DISTRIBUTION_IND);
        boolean foundAccountDistributionError = false;
        boolean foundCommodityCodeDistributionError = false;
        boolean performedAccountDistribution = false;
        boolean performedCommodityCodeDistribution = false;
        // do check for account percents only if distribution method not equal to "P"
        if (!PurapConstants.AccountDistributionMethodCodes.PROPORTIONAL_CODE.equalsIgnoreCase(purApDocument.getAccountDistributionMethod())) {
            // the total percentage in the distribute account list does not equal 100 % then we should display error
            if (institutionNeedsDistributeAccountValidation && needToDistributeAccount && purchasingForm.getTotalPercentageOfAccountDistributionsourceAccountingLines().compareTo(new BigDecimal(100)) != 0) {
                GlobalVariables.getMessageMap().putError(PurapConstants.ACCOUNT_DISTRIBUTION_ERROR_KEY, PurapKeyConstants.ERROR_DISTRIBUTE_ACCOUNTS_NOT_100_PERCENT);
                foundAccountDistributionError = true;
            }
        }
        // there is a validation error in the accounts to distribute then we should display an error
        if (institutionNeedsDistributeAccountValidation && needToDistributeAccount && (validateDistributeAccounts(purchasingForm.getDocument(), distributionsourceAccountingLines) == false)) {
            foundAccountDistributionError = true;
        }
        for (PurApItem item : ((PurchasingAccountsPayableDocument) purchasingForm.getDocument()).getItems()) {
            boolean itemIsActive = true;
            if (item instanceof PurchaseOrderItem) {
                // if item is PO item... only validate active items
                itemIsActive = ((PurchaseOrderItem) item).isItemActiveIndicator();
            }
            if (needToDistributeCommodityCode) {
                // only the above the line items need the commodity code.
                if (item.getItemType().isLineItemIndicator() && StringUtils.isBlank(((PurchasingItemBase) item).getPurchasingCommodityCode()) && itemIsActive) {
                    // Ideally we should invoke rules to check whether the commodity code is valid (active, not restricted,
                    // not missing, etc), probably somewhere here or invoke the rule class from here.
                    boolean rulePassed = SpringContext.getBean(KualiRuleService.class).applyRules(new AttributedCommodityCodesForDistributionEvent("", purchasingForm.getDocument(), purchasingForm.getDistributePurchasingCommodityCode()));
                    if (rulePassed) {
                        ((PurchasingItemBase) item).setPurchasingCommodityCode(purchasingForm.getDistributePurchasingCommodityCode());
                        performedCommodityCodeDistribution = true;
                    } else {
                        foundCommodityCodeDistributionError = true;
                    }
                } else if (item.getItemType().isLineItemIndicator() && !StringUtils.isBlank(((PurchasingItemBase) item).getPurchasingCommodityCode()) && itemIsActive) {
                    // could not apply to line, as it wasn't blank
                    foundCommodityCodeDistributionError = true;
                }
            }
            if (needToDistributeAccount && !foundAccountDistributionError) {
                BigDecimal zero = new BigDecimal(0);
                // We should be distributing accounting lines to above the line items all the time;
                // but only to the below the line items when there is a unit cost.
                boolean unitCostNotZeroForBelowLineItems = item.getItemType().isLineItemIndicator() ? true : item.getItemUnitPrice() != null && zero.compareTo(item.getItemUnitPrice()) < 0;
                Document document = ((PurchasingFormBase) form).getDocument();
                Class clazz = document instanceof PurchaseOrderAmendmentDocument ? PurchaseOrderDocument.class : document.getClass();
                List<String> typesNotAllowingEdit = new ArrayList<String>(SpringContext.getBean(ParameterService.class).getParameterValuesAsString(clazz, PurapParameterConstants.PURAP_ITEM_TYPES_RESTRICTING_ACCOUNT_EDIT));
                boolean itemOnExcludeList = (typesNotAllowingEdit == null) ? false : typesNotAllowingEdit.contains(item.getItemTypeCode());
                if (item.getSourceAccountingLines().size() == 0 && unitCostNotZeroForBelowLineItems && !itemOnExcludeList && itemIsActive) {
                    for (PurApAccountingLine purApAccountingLine : distributionsourceAccountingLines) {
                        item.getSourceAccountingLines().add((PurApAccountingLine) ObjectUtils.deepCopy(purApAccountingLine));
                    }
                    performedAccountDistribution = true;
                }
            }
        }
        if ((needToDistributeCommodityCode && performedCommodityCodeDistribution && !foundCommodityCodeDistributionError) || (needToDistributeAccount && performedAccountDistribution && !foundAccountDistributionError)) {
            if (needToDistributeCommodityCode && !foundCommodityCodeDistributionError && performedCommodityCodeDistribution) {
                KNSGlobalVariables.getMessageList().add(PurapKeyConstants.PUR_COMMODITY_CODE_DISTRIBUTED);
                purchasingForm.setDistributePurchasingCommodityCode(null);
            }
            if (needToDistributeAccount && !foundAccountDistributionError && performedAccountDistribution) {
                KNSGlobalVariables.getMessageList().add(PurapKeyConstants.PURAP_GENERAL_ACCOUNTS_DISTRIBUTED);
                distributionsourceAccountingLines.clear();
            }
            purchasingForm.setHideDistributeAccounts(true);
        }
        if ((needToDistributeAccount && !performedAccountDistribution && foundAccountDistributionError)) {
            GlobalVariables.getMessageMap().putError(PurapConstants.ACCOUNT_DISTRIBUTION_ERROR_KEY, PurapKeyConstants.PURAP_GENERAL_NO_ITEMS_TO_DISTRIBUTE_TO, "account numbers");
        }
        if (needToDistributeCommodityCode && !performedCommodityCodeDistribution && foundCommodityCodeDistributionError) {
            GlobalVariables.getMessageMap().putError(PurapConstants.ITEM_PURCHASING_COMMODITY_CODE, PurapKeyConstants.PURAP_GENERAL_NO_ITEMS_TO_DISTRIBUTE_TO, "commodity codes");
        }
    } else {
        GlobalVariables.getMessageMap().putError(PurapConstants.ACCOUNT_DISTRIBUTION_ERROR_KEY, PurapKeyConstants.PURAP_GENERAL_NO_ACCOUNTS_TO_DISTRIBUTE);
    }
    return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
Also used : PurchaseOrderAmendmentDocument(org.kuali.kfs.module.purap.document.PurchaseOrderAmendmentDocument) ParameterService(org.kuali.kfs.coreservice.framework.parameter.ParameterService) PurApItem(org.kuali.kfs.module.purap.businessobject.PurApItem) PurApAccountingLine(org.kuali.kfs.module.purap.businessobject.PurApAccountingLine) PurchasingAccountsPayableDocumentBase(org.kuali.kfs.module.purap.document.PurchasingAccountsPayableDocumentBase) KfsParameterConstants(org.kuali.kfs.sys.service.impl.KfsParameterConstants) ArrayList(java.util.ArrayList) PurApArrayList(org.kuali.kfs.module.purap.util.PurApArrayList) WorkflowDocument(org.kuali.rice.kew.api.WorkflowDocument) PurchaseOrderDocument(org.kuali.kfs.module.purap.document.PurchaseOrderDocument) RequisitionDocument(org.kuali.kfs.module.purap.document.RequisitionDocument) MaintenanceDocument(org.kuali.kfs.kns.document.MaintenanceDocument) PurchaseOrderAmendmentDocument(org.kuali.kfs.module.purap.document.PurchaseOrderAmendmentDocument) PurchasingDocument(org.kuali.kfs.module.purap.document.PurchasingDocument) Document(org.kuali.kfs.krad.document.Document) PurchasingAccountsPayableDocument(org.kuali.kfs.module.purap.document.PurchasingAccountsPayableDocument) BigDecimal(java.math.BigDecimal) PurchaseOrderItem(org.kuali.kfs.module.purap.businessobject.PurchaseOrderItem) KualiRuleService(org.kuali.kfs.krad.service.KualiRuleService) PurchasingItemBase(org.kuali.kfs.module.purap.businessobject.PurchasingItemBase) AttributedCommodityCodesForDistributionEvent(org.kuali.kfs.module.purap.document.validation.event.AttributedCommodityCodesForDistributionEvent) PurchasingAccountsPayableDocument(org.kuali.kfs.module.purap.document.PurchasingAccountsPayableDocument)

Example 13 with PurchaseOrderItem

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

the class CuPendingTransactionServiceImpl method getCreditMemoEncumbrance.

/**
 * Re-encumber the Encumbrance on a PO based on values in a PREQ. This is used when a PREQ is cancelled. Note: This modifies the
 * encumbrance values on the PO and saves the PO
 *
 * @param cm Credit Memo document
 * @param po Purchase Order document modify encumbrances
 * @return List of accounting lines to use to create the pending general ledger entries
 */
protected List<SourceAccountingLine> getCreditMemoEncumbrance(VendorCreditMemoDocument cm, PurchaseOrderDocument po) {
    LOG.debug("getCreditMemoEncumbrance() started");
    if (ObjectUtils.isNull(po)) {
        return null;
    }
    LOG.debug("getCreditMemoEncumbrance() Receiving items back from vendor (cancelled CM)");
    Map encumbranceAccountMap = new HashMap();
    // Get each item one by one
    for (Iterator items = cm.getItems().iterator(); items.hasNext(); ) {
        CreditMemoItem cmItem = (CreditMemoItem) items.next();
        PurchaseOrderItem poItem = getPoItem(po, cmItem.getItemLineNumber(), cmItem.getItemType());
        // Amount to disencumber for this item
        KualiDecimal itemDisEncumber = null;
        // Amount to alter the invoicedAmt on the PO item
        KualiDecimal itemAlterInvoiceAmt = null;
        String logItmNbr = "Item # " + cmItem.getItemLineNumber();
        LOG.debug("getCreditMemoEncumbrance() " + logItmNbr);
        final KualiDecimal cmItemTotalAmount = (cmItem.getTotalAmount() == null) ? KualiDecimal.ZERO : cmItem.getTotalAmount();
        ;
        // If there isn't a PO item or the total amount is 0, we don't need encumbrances
        if ((poItem == null) || (cmItemTotalAmount == null) || (cmItemTotalAmount.doubleValue() == 0)) {
            LOG.debug("getCreditMemoEncumbrance() " + logItmNbr + " No encumbrances required");
        } else {
            LOG.debug("getCreditMemoEncumbrance() " + logItmNbr + " Calculate encumbrance GL entries");
            // Do we calculate the encumbrance amount based on quantity or amount?
            if (poItem.getItemType().isQuantityBasedGeneralLedgerIndicator()) {
                LOG.debug("getCreditMemoEncumbrance() " + logItmNbr + " Calculate encumbrance based on quantity");
                // Do encumbrance calculations based on quantity
                KualiDecimal cmQuantity = cmItem.getItemQuantity() == null ? ZERO : cmItem.getItemQuantity();
                KualiDecimal encumbranceQuantityChange = calculateQuantityChange(poItem, cmQuantity);
                LOG.debug("getCreditMemoEncumbrance() " + logItmNbr + " encumbranceQtyChange " + encumbranceQuantityChange + " outstandingEncumberedQty " + poItem.getItemOutstandingEncumberedQuantity() + " invoicedTotalQuantity " + poItem.getItemInvoicedTotalQuantity());
                itemDisEncumber = encumbranceQuantityChange.multiply(new KualiDecimal(poItem.getItemUnitPrice()));
                // add tax for encumbrance
                KualiDecimal itemTaxAmount = poItem.getItemTaxAmount() == null ? ZERO : poItem.getItemTaxAmount();
                KualiDecimal encumbranceTaxAmount = encumbranceQuantityChange.divide(poItem.getItemQuantity()).multiply(itemTaxAmount);
                itemDisEncumber = itemDisEncumber.add(encumbranceTaxAmount);
                itemAlterInvoiceAmt = cmItemTotalAmount;
                itemAlterInvoiceAmt = itemAlterInvoiceAmt.multiply(new KualiDecimal("-1"));
            } else {
                LOG.debug("getCreditMemoEncumbrance() " + logItmNbr + " Calculate encumbrance based on amount");
                // Do encumbrance calculations based on amount only
                // Decrease encumbrance
                itemDisEncumber = cmItemTotalAmount.multiply(new KualiDecimal("-1"));
                if (poItem.getItemOutstandingEncumberedAmount().add(itemDisEncumber).doubleValue() < 0) {
                    LOG.debug("getCreditMemoEncumbrance() Cancel overflow");
                    itemDisEncumber = poItem.getItemOutstandingEncumberedAmount();
                }
                itemAlterInvoiceAmt = itemDisEncumber;
            }
            // alter the encumbrance based on what was originally encumbered
            poItem.setItemOutstandingEncumberedAmount(poItem.getItemOutstandingEncumberedAmount().add(itemDisEncumber));
            // alter the invoiced amt based on what was actually credited on the credit memo
            poItem.setItemInvoicedTotalAmount(poItem.getItemInvoicedTotalAmount().subtract(itemAlterInvoiceAmt));
            if (poItem.getItemInvoicedTotalAmount().compareTo(ZERO) < 0) {
                poItem.setItemInvoicedTotalAmount(ZERO);
            }
            LOG.debug("getCreditMemoEncumbrance() " + logItmNbr + " Amount to disencumber: " + itemDisEncumber);
            // Sort accounts
            Collections.sort((List) poItem.getSourceAccountingLines());
            // make the list of accounts for the disencumbrance entry
            PurchaseOrderAccount lastAccount = null;
            KualiDecimal accountTotal = ZERO;
            // Collections.sort((List)poItem.getSourceAccountingLines());
            for (Iterator accountIter = poItem.getSourceAccountingLines().iterator(); accountIter.hasNext(); ) {
                PurchaseOrderAccount account = (PurchaseOrderAccount) accountIter.next();
                if (!account.isEmpty()) {
                    KualiDecimal encumbranceAmount = null;
                    SourceAccountingLine acctString = account.generateSourceAccountingLine();
                    // amount = item disencumber * account percent / 100
                    encumbranceAmount = itemDisEncumber.multiply(new KualiDecimal(account.getAccountLinePercent().toString())).divide(new KualiDecimal(100));
                    account.setItemAccountOutstandingEncumbranceAmount(account.getItemAccountOutstandingEncumbranceAmount().add(encumbranceAmount));
                    // For rounding check at the end
                    accountTotal = accountTotal.add(encumbranceAmount);
                    lastAccount = account;
                    LOG.debug("getCreditMemoEncumbrance() " + logItmNbr + " " + acctString + " = " + encumbranceAmount);
                    if (encumbranceAccountMap.get(acctString) == null) {
                        encumbranceAccountMap.put(acctString, encumbranceAmount);
                    } else {
                        KualiDecimal amt = (KualiDecimal) encumbranceAccountMap.get(acctString);
                        encumbranceAccountMap.put(acctString, amt.add(encumbranceAmount));
                    }
                }
            }
            // account for rounding by adjusting last account as needed
            if (lastAccount != null) {
                KualiDecimal difference = itemDisEncumber.subtract(accountTotal);
                LOG.debug("getCreditMemoEncumbrance() difference: " + logItmNbr + " " + difference);
                SourceAccountingLine acctString = lastAccount.generateSourceAccountingLine();
                KualiDecimal amount = (KualiDecimal) encumbranceAccountMap.get(acctString);
                if (amount == null) {
                    encumbranceAccountMap.put(acctString, difference);
                } else {
                    encumbranceAccountMap.put(acctString, amount.add(difference));
                }
                lastAccount.setItemAccountOutstandingEncumbranceAmount(lastAccount.getItemAccountOutstandingEncumbranceAmount().add(difference));
            }
        }
    }
    List<SourceAccountingLine> encumbranceAccounts = new ArrayList();
    for (Iterator iter = encumbranceAccountMap.keySet().iterator(); iter.hasNext(); ) {
        SourceAccountingLine acctString = (SourceAccountingLine) iter.next();
        KualiDecimal amount = (KualiDecimal) encumbranceAccountMap.get(acctString);
        if (amount.doubleValue() != 0) {
            acctString.setAmount(amount);
            encumbranceAccounts.add(acctString);
        }
    }
    return encumbranceAccounts;
}
Also used : PurchaseOrderItem(org.kuali.kfs.module.purap.businessobject.PurchaseOrderItem) HashMap(java.util.HashMap) CreditMemoItem(org.kuali.kfs.module.purap.businessobject.CreditMemoItem) Iterator(java.util.Iterator) ArrayList(java.util.ArrayList) KualiDecimal(org.kuali.rice.core.api.util.type.KualiDecimal) SourceAccountingLine(org.kuali.kfs.sys.businessobject.SourceAccountingLine) Map(java.util.Map) HashMap(java.util.HashMap) PurchaseOrderAccount(org.kuali.kfs.module.purap.businessobject.PurchaseOrderAccount)

Example 14 with PurchaseOrderItem

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

the class FavoriteAccountLineBuilderTest method setUp.

@BeforeClass
public static void setUp() throws Exception {
    userProcurementProfileValidationService = new UserProcurementProfileValidationServiceImpl();
    userFavoriteAccountService = new ExtendedTestUserFavoriteAccountService();
    reqsAccounts = new ArrayList<PurApAccountingLine>();
    poAccounts = new ArrayList<PurApAccountingLine>();
    reqsItem = new RequisitionItem();
    poItem = new PurchaseOrderItem();
    reqsDoc = getMockedDocument(CuRequisitionDocument.class);
    poDoc = getMockedDocument(PurchaseOrderDocument.class);
    iwntDoc = getMockedDocument(IWantDocument.class);
    iwntDoc.setAccounts(new ArrayList<IWantAccount>());
    // Favorite Account with only some fields populated.
    testFavoriteAccount = new FavoriteAccount();
    testFavoriteAccount.setAccountLineIdentifier(TEST_FAVORITE_ACCOUNT_LINE_ID);
    testFavoriteAccount.setUserProfileId(TEST_USER_PROFILE_ID);
    testFavoriteAccount.setChartOfAccountsCode(TEST_CHART_CODE);
    testFavoriteAccount.setAccountNumber(TEST_ACCOUNT_NUMBER);
    testFavoriteAccount.setFinancialObjectCode(TEST_OBJECT_CODE);
    // Favorite Account with all fields populated (except reference objects or object ID or version number).
    testAltFavoriteAccount = new FavoriteAccount();
    testAltFavoriteAccount.setAccountLineIdentifier(TEST_ALT_FAVORITE_ACCOUNT_LINE_ID);
    testAltFavoriteAccount.setUserProfileId(TEST_ALT_USER_PROFILE_ID);
    testAltFavoriteAccount.setChartOfAccountsCode(TEST_ALT_CHART_CODE);
    testAltFavoriteAccount.setAccountNumber(TEST_ALT_ACCOUNT_NUMBER);
    testAltFavoriteAccount.setSubAccountNumber(TEST_ALT_SUB_ACCOUNT_NUMBER);
    testAltFavoriteAccount.setFinancialObjectCode(TEST_ALT_OBJECT_CODE);
    testAltFavoriteAccount.setFinancialSubObjectCode(TEST_ALT_SUB_OBJECT_CODE);
    testAltFavoriteAccount.setProjectCode(TEST_ALT_PROJECT_CODE);
    testAltFavoriteAccount.setOrganizationReferenceId(TEST_ALT_ORG_REF_ID);
    GlobalVariables.setMessageMap(new MessageMap());
}
Also used : FavoriteAccount(edu.cornell.kfs.sys.businessobject.FavoriteAccount) CuRequisitionDocument(edu.cornell.kfs.module.purap.document.CuRequisitionDocument) IWantAccount(edu.cornell.kfs.module.purap.businessobject.IWantAccount) PurApAccountingLine(org.kuali.kfs.module.purap.businessobject.PurApAccountingLine) UserProcurementProfileValidationServiceImpl(edu.cornell.kfs.sys.service.impl.UserProcurementProfileValidationServiceImpl) PurchaseOrderItem(org.kuali.kfs.module.purap.businessobject.PurchaseOrderItem) RequisitionItem(org.kuali.kfs.module.purap.businessobject.RequisitionItem) PurchaseOrderDocument(org.kuali.kfs.module.purap.document.PurchaseOrderDocument) MessageMap(org.kuali.kfs.krad.util.MessageMap) IWantDocument(edu.cornell.kfs.module.purap.document.IWantDocument) PurApFavoriteAccountLineBuilderForIWantDocument(edu.cornell.kfs.module.purap.util.PurApFavoriteAccountLineBuilderForIWantDocument) BeforeClass(org.junit.BeforeClass)

Example 15 with PurchaseOrderItem

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

the class CuElectronicInvoiceHelperServiceImpl method createPaymentRequest.

protected PaymentRequestDocument createPaymentRequest(ElectronicInvoiceOrderHolder orderHolder) {
    LOG.info("Creating Payment Request document");
    KNSGlobalVariables.getMessageList().clear();
    validateInvoiceOrderValidForPREQCreation(orderHolder);
    if (LOG.isInfoEnabled()) {
        if (orderHolder.isInvoiceRejected()) {
            LOG.info("Not possible to convert einvoice details into payment request");
        } else {
            LOG.info("Payment request document creation validation succeeded");
        }
    }
    if (orderHolder.isInvoiceRejected()) {
        return null;
    }
    PaymentRequestDocument preqDoc = null;
    try {
        preqDoc = (PaymentRequestDocument) SpringContext.getBean(DocumentService.class).getNewDocument("PREQ");
    } catch (WorkflowException e) {
        String extraDescription = "Error=" + e.getMessage();
        ElectronicInvoiceRejectReason rejectReason = matchingService.createRejectReason(PurapConstants.ElectronicInvoice.PREQ_WORKLOW_EXCEPTION, extraDescription, orderHolder.getFileName());
        orderHolder.addInvoiceOrderRejectReason(rejectReason);
        LOG.error("Error creating Payment request document - " + e.getMessage());
        return null;
    }
    PurchaseOrderDocument poDoc = orderHolder.getPurchaseOrderDocument();
    if (poDoc == null) {
        throw new RuntimeException("Purchase Order document (POId=" + poDoc.getPurapDocumentIdentifier() + ") does not exist in the system");
    }
    preqDoc.getDocumentHeader().setDocumentDescription(generatePREQDocumentDescription(poDoc));
    try {
        preqDoc.updateAndSaveAppDocStatus(PurapConstants.PaymentRequestStatuses.APPDOC_IN_PROCESS);
    } catch (WorkflowException we) {
        throw new RuntimeException("Unable to save route status data for document: " + preqDoc.getDocumentNumber(), we);
    }
    preqDoc.setInvoiceDate(orderHolder.getInvoiceDate());
    preqDoc.setInvoiceNumber(orderHolder.getInvoiceNumber());
    preqDoc.setVendorInvoiceAmount(new KualiDecimal(orderHolder.getInvoiceNetAmount()));
    preqDoc.setAccountsPayableProcessorIdentifier("E-Invoice");
    preqDoc.setVendorCustomerNumber(orderHolder.getCustomerNumber());
    preqDoc.setPaymentRequestElectronicInvoiceIndicator(true);
    if (orderHolder.getAccountsPayablePurchasingDocumentLinkIdentifier() != null) {
        preqDoc.setAccountsPayablePurchasingDocumentLinkIdentifier(orderHolder.getAccountsPayablePurchasingDocumentLinkIdentifier());
    }
    // Copied from PaymentRequestServiceImpl.populatePaymentRequest()
    // set bank code to default bank code in the system parameter
    // KFSPTS-1891
    boolean hasPaymentMethodCode = false;
    if (preqDoc instanceof PaymentRequestDocument) {
        String vendorPaymentMethodCode = ((VendorDetailExtension) poDoc.getVendorDetail().getExtension()).getDefaultB2BPaymentMethodCode();
        if (StringUtils.isNotEmpty(vendorPaymentMethodCode)) {
            ((CuPaymentRequestDocument) preqDoc).setPaymentMethodCode(vendorPaymentMethodCode);
            hasPaymentMethodCode = true;
        } else {
            ((CuPaymentRequestDocument) preqDoc).setPaymentMethodCode(DEFAULT_EINVOICE_PAYMENT_METHOD_CODE);
        }
    }
    Bank defaultBank = null;
    if (hasPaymentMethodCode) {
        defaultBank = SpringContext.getBean(CUPaymentMethodGeneralLedgerPendingEntryService.class).getBankForPaymentMethod(((CuPaymentRequestDocument) preqDoc).getPaymentMethodCode());
    } else {
        // default to baseline behavior - extended documents not in use
        // Copied from PaymentRequestServiceImpl.populatePaymentRequest()
        // set bank code to default bank code in the system parameter
        defaultBank = SpringContext.getBean(BankService.class).getDefaultBankByDocType(PaymentRequestDocument.class);
    }
    if (defaultBank != null) {
        preqDoc.setBankCode(defaultBank.getBankCode());
        preqDoc.setBank(defaultBank);
    }
    RequisitionDocument reqDoc = SpringContext.getBean(RequisitionService.class).getRequisitionById(poDoc.getRequisitionIdentifier());
    String reqDocInitiator = reqDoc.getDocumentHeader().getWorkflowDocument().getInitiatorPrincipalId();
    try {
        Person user = KimApiServiceLocator.getPersonService().getPerson(reqDocInitiator);
        setProcessingCampus(preqDoc, user.getCampusCode());
    } catch (Exception e) {
        String extraDescription = "Error setting processing campus code - " + e.getMessage();
        ElectronicInvoiceRejectReason rejectReason = matchingService.createRejectReason(PurapConstants.ElectronicInvoice.PREQ_ROUTING_VALIDATION_ERROR, extraDescription, orderHolder.getFileName());
        orderHolder.addInvoiceOrderRejectReason(rejectReason);
        return null;
    }
    HashMap<String, ExpiredOrClosedAccountEntry> expiredOrClosedAccountList = SpringContext.getBean(AccountsPayableService.class).expiredOrClosedAccountsList(poDoc);
    if (expiredOrClosedAccountList == null) {
        expiredOrClosedAccountList = new HashMap();
    }
    if (LOG.isInfoEnabled()) {
        LOG.info(expiredOrClosedAccountList.size() + " accounts has been found as Expired or Closed");
    }
    preqDoc.populatePaymentRequestFromPurchaseOrder(orderHolder.getPurchaseOrderDocument(), expiredOrClosedAccountList);
    // need to populate here for ext price.  it become per item
    // KFSPTS-1719.  convert 1st matching inv item that is qty, but po is non-qty
    checkQtyInvItemForNoQtyOrder(preqDoc, orderHolder);
    populateItemDetails(preqDoc, orderHolder);
    // KFSUPGRADE-485, KFSPTS-1719
    if (CollectionUtils.isNotEmpty(((CuElectronicInvoiceOrderHolder) orderHolder).getNonMatchItems())) {
        for (ElectronicInvoiceItemHolder invItem : ((CuElectronicInvoiceOrderHolder) orderHolder).getNonMatchItems()) {
            PurchaseOrderItem item = (PurchaseOrderItem) ObjectUtils.deepCopy((Serializable) orderHolder.getPurchaseOrderDocument().getItems().get(invItem.getInvoiceItemLineNumber() - 1));
            item.setItemLineNumber(invItem.getInvoiceItemLineNumber());
            item.setItemDescription(((CuElectronicInvoiceItemHolder) invItem).getReferenceDescription());
            // this will be populated to reqitem.poitemunitprice
            item.setItemUnitPrice(invItem.getInvoiceItemUnitPrice());
            PaymentRequestItem paymentRequestItem = new PaymentRequestItem(item, preqDoc, expiredOrClosedAccountList);
            ((CuPaymentRequestItemExtension) paymentRequestItem.getExtension()).setInvLineNumber(Integer.parseInt(((CuElectronicInvoiceItemHolder) invItem).getInvLineNumber()));
            // need following in case inv item is qty item
            paymentRequestItem.setItemQuantity(new KualiDecimal(invItem.getInvoiceItemQuantity()));
            paymentRequestItem.setItemUnitOfMeasureCode(invItem.getInvoiceItemUnitOfMeasureCode());
            paymentRequestItem.setPurchaseOrderItemUnitPrice(invItem.getInvoiceItemUnitPrice());
            // if non qty don't need this unit price set, then this need to have a check
            if (invItem.getInvoiceItemQuantity() != null && (new KualiDecimal(invItem.getInvoiceItemQuantity())).isPositive()) {
                paymentRequestItem.setItemUnitPrice(invItem.getInvoiceItemUnitPrice());
            }
            paymentRequestItem.setItemCatalogNumber(invItem.getCatalogNumberStripped());
            preqDoc.getItems().add(paymentRequestItem);
            ((CuElectronicInvoiceOrderHolder) orderHolder).setMisMatchItem((CuElectronicInvoiceItemHolder) invItem);
            populateItemDetailsForNonMatching(preqDoc, orderHolder);
            ((CuElectronicInvoiceOrderHolder) orderHolder).setMisMatchItem(null);
        }
    }
    /**
     * Validate totals,paydate
     */
    // PaymentRequestDocumentRule.processCalculateAccountsPayableBusinessRules
    SpringContext.getBean(KualiRuleService.class).applyRules(new AttributedCalculateAccountsPayableEvent(preqDoc));
    SpringContext.getBean(PaymentRequestService.class).calculatePaymentRequest(preqDoc, true);
    processItemsForDiscount(preqDoc, orderHolder);
    if (orderHolder.isInvoiceRejected()) {
        return null;
    }
    SpringContext.getBean(PaymentRequestService.class).calculatePaymentRequest(preqDoc, false);
    /**
     * PaymentRequestReview
     */
    // PaymentRequestDocumentRule.processRouteDocumentBusinessRules
    SpringContext.getBean(KualiRuleService.class).applyRules(new AttributedPaymentRequestForEInvoiceEvent(preqDoc));
    if (GlobalVariables.getMessageMap().hasErrors()) {
        if (LOG.isInfoEnabled()) {
            LOG.info("***************Error in rules processing - " + GlobalVariables.getMessageMap());
        }
        Map<String, AutoPopulatingList<ErrorMessage>> errorMessages = GlobalVariables.getMessageMap().getErrorMessages();
        String errors = errorMessages.toString();
        ElectronicInvoiceRejectReason rejectReason = matchingService.createRejectReason(PurapConstants.ElectronicInvoice.PREQ_ROUTING_VALIDATION_ERROR, errors, orderHolder.getFileName());
        orderHolder.addInvoiceOrderRejectReason(rejectReason);
        return null;
    }
    if (KNSGlobalVariables.getMessageList().size() > 0) {
        if (LOG.isInfoEnabled()) {
            LOG.info("Payment request contains " + KNSGlobalVariables.getMessageList().size() + " warning message(s)");
            for (int i = 0; i < KNSGlobalVariables.getMessageList().size(); i++) {
                LOG.info("Warning " + i + "  - " + KNSGlobalVariables.getMessageList().get(i));
            }
        }
    }
    addShipToNotes(preqDoc, orderHolder);
    try {
        // KFSUPGRADE-490: Do save-only operations for just non-EIRT-generated PREQs.
        if (orderHolder.isRejectDocumentHolder()) {
            SpringContext.getBean(DocumentService.class).routeDocument(preqDoc, null, null);
        } else {
            SpringContext.getBean(DocumentService.class).saveDocument(preqDoc, DocumentSystemSaveEvent.class);
        }
    } catch (WorkflowException e) {
        e.printStackTrace();
        ElectronicInvoiceRejectReason rejectReason = matchingService.createRejectReason(PurapConstants.ElectronicInvoice.PREQ_ROUTING_FAILURE, e.getMessage(), orderHolder.getFileName());
        orderHolder.addInvoiceOrderRejectReason(rejectReason);
        return null;
    } catch (ValidationException e) {
        String extraDescription = GlobalVariables.getMessageMap().toString();
        ElectronicInvoiceRejectReason rejectReason = matchingService.createRejectReason(PurapConstants.ElectronicInvoice.PREQ_ROUTING_VALIDATION_ERROR, extraDescription, orderHolder.getFileName());
        orderHolder.addInvoiceOrderRejectReason(rejectReason);
        return null;
    }
    return preqDoc;
}
Also used : Serializable(java.io.Serializable) Bank(org.kuali.kfs.sys.businessobject.Bank) ValidationException(org.kuali.kfs.krad.exception.ValidationException) ElectronicInvoiceItemHolder(org.kuali.kfs.module.purap.service.impl.ElectronicInvoiceItemHolder) HashMap(java.util.HashMap) RequisitionDocument(org.kuali.kfs.module.purap.document.RequisitionDocument) KualiRuleService(org.kuali.kfs.krad.service.KualiRuleService) CuPaymentRequestDocument(edu.cornell.kfs.module.purap.document.CuPaymentRequestDocument) PurchaseOrderDocument(org.kuali.kfs.module.purap.document.PurchaseOrderDocument) KualiDecimal(org.kuali.rice.core.api.util.type.KualiDecimal) VendorDetailExtension(edu.cornell.kfs.vnd.businessobject.VendorDetailExtension) RequisitionService(org.kuali.kfs.module.purap.document.service.RequisitionService) ExpiredOrClosedAccountEntry(org.kuali.kfs.module.purap.util.ExpiredOrClosedAccountEntry) CuPaymentRequestItemExtension(edu.cornell.kfs.module.purap.businessobject.CuPaymentRequestItemExtension) AttributedCalculateAccountsPayableEvent(org.kuali.kfs.module.purap.document.validation.event.AttributedCalculateAccountsPayableEvent) PaymentRequestService(org.kuali.kfs.module.purap.document.service.PaymentRequestService) WorkflowException(org.kuali.rice.kew.api.exception.WorkflowException) CuPaymentRequestDocument(edu.cornell.kfs.module.purap.document.CuPaymentRequestDocument) PaymentRequestDocument(org.kuali.kfs.module.purap.document.PaymentRequestDocument) ElectronicInvoiceRejectReason(org.kuali.kfs.module.purap.businessobject.ElectronicInvoiceRejectReason) WorkflowDocumentService(org.kuali.kfs.krad.workflow.service.WorkflowDocumentService) DocumentService(org.kuali.kfs.krad.service.DocumentService) FinancialSystemDocumentService(org.kuali.kfs.sys.document.service.FinancialSystemDocumentService) ValidationException(org.kuali.kfs.krad.exception.ValidationException) IOException(java.io.IOException) WorkflowException(org.kuali.rice.kew.api.exception.WorkflowException) FileNotFoundException(java.io.FileNotFoundException) RemoteException(java.rmi.RemoteException) CxmlParseException(org.kuali.kfs.module.purap.exception.CxmlParseException) PurchaseOrderItem(org.kuali.kfs.module.purap.businessobject.PurchaseOrderItem) PaymentRequestItem(org.kuali.kfs.module.purap.businessobject.PaymentRequestItem) AttributedPaymentRequestForEInvoiceEvent(org.kuali.kfs.module.purap.document.validation.event.AttributedPaymentRequestForEInvoiceEvent) Person(org.kuali.rice.kim.api.identity.Person) AccountsPayableService(org.kuali.kfs.module.purap.document.service.AccountsPayableService) AutoPopulatingList(org.springframework.util.AutoPopulatingList)

Aggregations

PurchaseOrderItem (org.kuali.kfs.module.purap.businessobject.PurchaseOrderItem)22 ArrayList (java.util.ArrayList)11 KualiDecimal (org.kuali.rice.core.api.util.type.KualiDecimal)9 Iterator (java.util.Iterator)8 List (java.util.List)8 PurchaseOrderDocument (org.kuali.kfs.module.purap.document.PurchaseOrderDocument)8 ElectronicInvoiceRejectReason (org.kuali.kfs.module.purap.businessobject.ElectronicInvoiceRejectReason)5 PurApAccountingLine (org.kuali.kfs.module.purap.businessobject.PurApAccountingLine)5 HashMap (java.util.HashMap)4 PaymentRequestItem (org.kuali.kfs.module.purap.businessobject.PaymentRequestItem)4 PurApItem (org.kuali.kfs.module.purap.businessobject.PurApItem)4 PurchaseOrderAccount (org.kuali.kfs.module.purap.businessobject.PurchaseOrderAccount)4 ElectronicInvoiceOrderHolder (org.kuali.kfs.module.purap.service.impl.ElectronicInvoiceOrderHolder)4 BigDecimal (java.math.BigDecimal)3 Map (java.util.Map)3 BusinessObjectService (org.kuali.kfs.krad.service.BusinessObjectService)3 CuPaymentRequestDocument (edu.cornell.kfs.module.purap.document.CuPaymentRequestDocument)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 IOException (java.io.IOException)2 ParameterService (org.kuali.kfs.coreservice.framework.parameter.ParameterService)2