Search in sources :

Example 21 with GenericEntityException

use of org.apache.ofbiz.entity.GenericEntityException in project ofbiz-framework by apache.

the class InventoryServices method checkInventoryAvailability.

/**
 * In spite of the generic name this does the very specific task of checking availability of all back-ordered items and sends notices, etc
 */
public static Map<String, Object> checkInventoryAvailability(DispatchContext dctx, Map<String, ? extends Object> context) {
    Delegator delegator = dctx.getDelegator();
    LocalDispatcher dispatcher = dctx.getDispatcher();
    GenericValue userLogin = (GenericValue) context.get("userLogin");
    Locale locale = (Locale) context.get("locale");
    Map<String, Map<String, Timestamp>> ordersToUpdate = new HashMap<>();
    Map<String, Map<String, Timestamp>> ordersToCancel = new HashMap<>();
    // find all inventory items w/ a negative ATP
    List<GenericValue> inventoryItems = null;
    try {
        inventoryItems = EntityQuery.use(delegator).from("InventoryItem").where(EntityCondition.makeCondition("availableToPromiseTotal", EntityOperator.LESS_THAN, BigDecimal.ZERO)).queryList();
    } catch (GenericEntityException e) {
        Debug.logError(e, "Trouble getting inventory items", module);
        return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ProductPriceCannotRetrieveInventoryItem", locale));
    }
    if (inventoryItems == null) {
        Debug.logInfo("No items out of stock; no backorders to worry about", module);
        return ServiceUtil.returnSuccess();
    }
    Debug.logInfo("OOS Inventory Items: " + inventoryItems.size(), module);
    for (GenericValue inventoryItem : inventoryItems) {
        // get the incomming shipment information for the item
        List<GenericValue> shipmentAndItems = null;
        try {
            List<EntityExpr> exprs = new ArrayList<>();
            exprs.add(EntityCondition.makeCondition("productId", EntityOperator.EQUALS, inventoryItem.get("productId")));
            exprs.add(EntityCondition.makeCondition("destinationFacilityId", EntityOperator.EQUALS, inventoryItem.get("facilityId")));
            exprs.add(EntityCondition.makeCondition("statusId", EntityOperator.NOT_EQUAL, "SHIPMENT_DELIVERED"));
            exprs.add(EntityCondition.makeCondition("statusId", EntityOperator.NOT_EQUAL, "SHIPMENT_CANCELLED"));
            shipmentAndItems = EntityQuery.use(delegator).from("ShipmentAndItem").where(EntityCondition.makeCondition(exprs, EntityOperator.AND)).orderBy("estimatedArrivalDate").queryList();
        } catch (GenericEntityException e) {
            Debug.logError(e, "Problem getting ShipmentAndItem records", module);
            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ProductPriceCannotRetrieveShipmentAndItem", locale));
        }
        // get the reservations in order of newest first
        List<GenericValue> reservations = null;
        try {
            reservations = inventoryItem.getRelated("OrderItemShipGrpInvRes", null, UtilMisc.toList("-reservedDatetime"), false);
        } catch (GenericEntityException e) {
            Debug.logError(e, "Problem getting related reservations", module);
            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ProductPriceCannotRetrieveRelativeReservation", locale));
        }
        if (reservations == null) {
            Debug.logWarning("No outstanding reservations for this inventory item, why is it negative then?", module);
            continue;
        }
        Debug.logInfo("Reservations for item: " + reservations.size(), module);
        // available at the time of order
        BigDecimal availableBeforeReserved = inventoryItem.getBigDecimal("availableToPromiseTotal");
        // go through all the reservations in order
        for (GenericValue reservation : reservations) {
            String orderId = reservation.getString("orderId");
            String orderItemSeqId = reservation.getString("orderItemSeqId");
            Timestamp promisedDate = reservation.getTimestamp("promisedDatetime");
            Timestamp currentPromiseDate = reservation.getTimestamp("currentPromisedDate");
            Timestamp actualPromiseDate = currentPromiseDate;
            if (actualPromiseDate == null) {
                if (promisedDate != null) {
                    actualPromiseDate = promisedDate;
                } else {
                    // fall back if there is no promised date stored
                    actualPromiseDate = reservation.getTimestamp("reservedDatetime");
                }
            }
            Debug.logInfo("Promised Date: " + actualPromiseDate, module);
            // find the next possible ship date
            Timestamp nextShipDate = null;
            BigDecimal availableAtTime = BigDecimal.ZERO;
            for (GenericValue shipmentItem : shipmentAndItems) {
                availableAtTime = availableAtTime.add(shipmentItem.getBigDecimal("quantity"));
                if (availableAtTime.compareTo(availableBeforeReserved) >= 0) {
                    nextShipDate = shipmentItem.getTimestamp("estimatedArrivalDate");
                    break;
                }
            }
            Debug.logInfo("Next Ship Date: " + nextShipDate, module);
            // create a modified promise date (promise date - 1 day)
            Calendar pCal = Calendar.getInstance();
            pCal.setTimeInMillis(actualPromiseDate.getTime());
            pCal.add(Calendar.DAY_OF_YEAR, -1);
            Timestamp modifiedPromisedDate = new Timestamp(pCal.getTimeInMillis());
            Timestamp now = UtilDateTime.nowTimestamp();
            Debug.logInfo("Promised Date + 1: " + modifiedPromisedDate, module);
            Debug.logInfo("Now: " + now, module);
            // check the promised date vs the next ship date
            if (nextShipDate == null || nextShipDate.after(actualPromiseDate)) {
                if (nextShipDate == null && modifiedPromisedDate.after(now)) {
                    // do nothing; we are okay to assume it will be shipped on time
                    Debug.logInfo("No ship date known yet, but promised date hasn't approached, assuming it will be here on time", module);
                } else {
                    // we cannot ship by the promised date; need to notify the customer
                    Debug.logInfo("We won't ship on time, getting notification info", module);
                    Map<String, Timestamp> notifyItems = ordersToUpdate.get(orderId);
                    if (notifyItems == null) {
                        notifyItems = new HashMap<>();
                    }
                    notifyItems.put(orderItemSeqId, nextShipDate);
                    ordersToUpdate.put(orderId, notifyItems);
                    // need to know if nextShipDate is more then 30 days after promised
                    Calendar sCal = Calendar.getInstance();
                    sCal.setTimeInMillis(actualPromiseDate.getTime());
                    sCal.add(Calendar.DAY_OF_YEAR, 30);
                    Timestamp farPastPromised = new Timestamp(sCal.getTimeInMillis());
                    // check to see if this is >30 days or second run, if so flag to cancel
                    boolean needToCancel = false;
                    if (nextShipDate == null || nextShipDate.after(farPastPromised)) {
                        // we cannot ship until >30 days after promised; using cancel rule
                        Debug.logInfo("Ship date is >30 past the promised date", module);
                        needToCancel = true;
                    } else if (currentPromiseDate != null && actualPromiseDate.equals(currentPromiseDate)) {
                        // this is the second notification; using cancel rule
                        needToCancel = true;
                    }
                    // add the info to the cancel map if we need to schedule a cancel
                    if (needToCancel) {
                        // queue the item to be cancelled
                        Debug.logInfo("Flagging the item to auto-cancel", module);
                        Map<String, Timestamp> cancelItems = ordersToCancel.get(orderId);
                        if (cancelItems == null) {
                            cancelItems = new HashMap<>();
                        }
                        cancelItems.put(orderItemSeqId, farPastPromised);
                        ordersToCancel.put(orderId, cancelItems);
                    }
                    // store the updated promiseDate as the nextShipDate
                    try {
                        reservation.set("currentPromisedDate", nextShipDate);
                        reservation.store();
                    } catch (GenericEntityException e) {
                        Debug.logError(e, "Problem storing reservation : " + reservation, module);
                    }
                }
            }
            // subtract our qty from reserved to get the next value
            availableBeforeReserved = availableBeforeReserved.subtract(reservation.getBigDecimal("quantity"));
        }
    }
    // all items to cancel will also be in the notify list so start with that
    List<String> ordersToNotify = new LinkedList<>();
    for (Map.Entry<String, Map<String, Timestamp>> entry : ordersToUpdate.entrySet()) {
        String orderId = entry.getKey();
        Map<String, Timestamp> backOrderedItems = entry.getValue();
        Map<String, Timestamp> cancelItems = ordersToCancel.get(orderId);
        boolean cancelAll = false;
        Timestamp cancelAllTime = null;
        List<GenericValue> orderItemShipGroups = null;
        try {
            orderItemShipGroups = EntityQuery.use(delegator).from("OrderItemShipGroup").where("orderId", orderId).queryList();
        } catch (GenericEntityException e) {
            Debug.logError(e, "Cannot get OrderItemShipGroups from orderId" + orderId, module);
        }
        for (GenericValue orderItemShipGroup : orderItemShipGroups) {
            List<GenericValue> orderItems = new LinkedList<>();
            List<GenericValue> orderItemShipGroupAssoc = null;
            try {
                orderItemShipGroupAssoc = EntityQuery.use(delegator).from("OrderItemShipGroupAssoc").where("shipGroupSeqId", orderItemShipGroup.get("shipGroupSeqId"), "orderId", orderId).queryList();
                for (GenericValue assoc : orderItemShipGroupAssoc) {
                    GenericValue orderItem = assoc.getRelatedOne("OrderItem", false);
                    if (orderItem != null) {
                        orderItems.add(orderItem);
                    }
                }
            } catch (GenericEntityException e) {
                Debug.logError(e, "Problem fetching OrderItemShipGroupAssoc", module);
            }
            /* Check the split preference. */
            boolean maySplit = false;
            if (orderItemShipGroup.get("maySplit") != null) {
                maySplit = orderItemShipGroup.getBoolean("maySplit").booleanValue();
            }
            /* Figure out if we must cancel all items. */
            if (!maySplit && cancelItems != null) {
                cancelAll = true;
                Set<String> cancelSet = cancelItems.keySet();
                cancelAllTime = cancelItems.get(cancelSet.iterator().next());
            }
            // if there are none to cancel just create an empty map
            if (cancelItems == null) {
                cancelItems = new HashMap<>();
            }
            List<GenericValue> toBeStored = new LinkedList<>();
            for (GenericValue orderItem : orderItems) {
                String orderItemSeqId = orderItem.getString("orderItemSeqId");
                Timestamp shipDate = backOrderedItems.get(orderItemSeqId);
                Timestamp cancelDate = cancelItems.get(orderItemSeqId);
                Timestamp currentCancelDate = orderItem.getTimestamp("autoCancelDate");
                Debug.logInfo("OI: " + orderId + " SEQID: " + orderItemSeqId + " cancelAll: " + cancelAll + " cancelDate: " + cancelDate, module);
                if (backOrderedItems.containsKey(orderItemSeqId)) {
                    orderItem.set("estimatedShipDate", shipDate);
                    if (currentCancelDate == null) {
                        if (cancelAll || cancelDate != null) {
                            if (orderItem.get("dontCancelSetUserLogin") == null && orderItem.get("dontCancelSetDate") == null) {
                                if (cancelAllTime != null) {
                                    orderItem.set("autoCancelDate", cancelAllTime);
                                } else {
                                    orderItem.set("autoCancelDate", cancelDate);
                                }
                            }
                        }
                        // only notify orders which have not already sent the final notice
                        ordersToNotify.add(orderId);
                    }
                    toBeStored.add(orderItem);
                }
                if (toBeStored.size() > 0) {
                    try {
                        delegator.storeAll(toBeStored);
                    } catch (GenericEntityException e) {
                        Debug.logError(e, "Problem storing order items", module);
                    }
                }
            }
        }
    }
    // send off a notification for each order
    for (String orderId : ordersToNotify) {
        try {
            dispatcher.runAsync("sendOrderBackorderNotification", UtilMisc.<String, Object>toMap("orderId", orderId, "userLogin", userLogin));
        } catch (GenericServiceException e) {
            Debug.logError(e, "Problems sending off the notification", module);
            continue;
        }
    }
    return ServiceUtil.returnSuccess();
}
Also used : Locale(java.util.Locale) GenericValue(org.apache.ofbiz.entity.GenericValue) LocalDispatcher(org.apache.ofbiz.service.LocalDispatcher) HashMap(java.util.HashMap) Calendar(com.ibm.icu.util.Calendar) ArrayList(java.util.ArrayList) Timestamp(java.sql.Timestamp) BigDecimal(java.math.BigDecimal) LinkedList(java.util.LinkedList) Delegator(org.apache.ofbiz.entity.Delegator) GenericEntityException(org.apache.ofbiz.entity.GenericEntityException) GenericServiceException(org.apache.ofbiz.service.GenericServiceException) HashMap(java.util.HashMap) Map(java.util.Map) ModelKeyMap(org.apache.ofbiz.entity.model.ModelKeyMap) EntityExpr(org.apache.ofbiz.entity.condition.EntityExpr)

Example 22 with GenericEntityException

use of org.apache.ofbiz.entity.GenericEntityException in project ofbiz-framework by apache.

the class InventoryServices method cancelInventoryTransfer.

public static Map<String, Object> cancelInventoryTransfer(DispatchContext dctx, Map<String, ? extends Object> context) {
    Delegator delegator = dctx.getDelegator();
    String inventoryTransferId = (String) context.get("inventoryTransferId");
    GenericValue inventoryTransfer = null;
    GenericValue inventoryItem = null;
    GenericValue userLogin = (GenericValue) context.get("userLogin");
    Locale locale = (Locale) context.get("locale");
    try {
        inventoryTransfer = EntityQuery.use(delegator).from("InventoryTransfer").where("inventoryTransferId", inventoryTransferId).queryOne();
        if (UtilValidate.isEmpty(inventoryTransfer)) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ProductInventoryItemTransferNotFound", UtilMisc.toMap("inventoryTransferId", inventoryTransferId), locale));
        }
        inventoryItem = inventoryTransfer.getRelatedOne("InventoryItem", false);
    } catch (GenericEntityException e) {
        return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ProductInventoryItemLookupProblem", UtilMisc.toMap("errorString", e.getMessage()), locale));
    }
    if (inventoryItem == null) {
        return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ProductInventoryItemLookupProblem", UtilMisc.toMap("errorString", ""), locale));
    }
    String inventoryType = inventoryItem.getString("inventoryItemTypeId");
    // re-set the fields on the item
    if ("NON_SERIAL_INV_ITEM".equals(inventoryType)) {
        // add an adjusting InventoryItemDetail so set ATP back to QOH: ATP = ATP + (QOH - ATP), diff = QOH - ATP
        BigDecimal atp = inventoryItem.get("availableToPromiseTotal") == null ? BigDecimal.ZERO : inventoryItem.getBigDecimal("availableToPromiseTotal");
        BigDecimal qoh = inventoryItem.get("quantityOnHandTotal") == null ? BigDecimal.ZERO : inventoryItem.getBigDecimal("quantityOnHandTotal");
        Map<String, Object> createDetailMap = UtilMisc.toMap("availableToPromiseDiff", qoh.subtract(atp), "inventoryItemId", inventoryItem.get("inventoryItemId"), "userLogin", userLogin);
        try {
            Map<String, Object> result = dctx.getDispatcher().runSync("createInventoryItemDetail", createDetailMap);
            if (ServiceUtil.isError(result)) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ProductInventoryItemDetailCreateProblem", UtilMisc.toMap("errorString", ""), locale), null, null, result);
            }
        } catch (GenericServiceException e1) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ProductInventoryItemDetailCreateProblem", UtilMisc.toMap("errorString", e1.getMessage()), locale));
        }
    } else if ("SERIALIZED_INV_ITEM".equals(inventoryType)) {
        inventoryItem.set("statusId", "INV_AVAILABLE");
        // store the entity
        try {
            inventoryItem.store();
        } catch (GenericEntityException e) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ProductInventoryItemStoreProblem", UtilMisc.toMap("errorString", e.getMessage()), locale));
        }
    }
    // set the inventory transfer record to complete
    inventoryTransfer.set("statusId", "IXF_CANCELLED");
    // store the entities
    try {
        inventoryTransfer.store();
    } catch (GenericEntityException e) {
        return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ProductInventoryItemStoreProblem", UtilMisc.toMap("errorString", e.getMessage()), locale));
    }
    return ServiceUtil.returnSuccess();
}
Also used : Locale(java.util.Locale) GenericValue(org.apache.ofbiz.entity.GenericValue) Delegator(org.apache.ofbiz.entity.Delegator) GenericEntityException(org.apache.ofbiz.entity.GenericEntityException) GenericServiceException(org.apache.ofbiz.service.GenericServiceException) BigDecimal(java.math.BigDecimal)

Example 23 with GenericEntityException

use of org.apache.ofbiz.entity.GenericEntityException in project ofbiz-framework by apache.

the class PriceServices method calculateProductPrice.

/**
 * <p>Calculates the price of a product from pricing rules given the following input, and of course access to the database:</p>
 * <ul>
 *   <li>productId
 *   <li>partyId
 *   <li>prodCatalogId
 *   <li>webSiteId
 *   <li>productStoreId
 *   <li>productStoreGroupId
 *   <li>agreementId
 *   <li>quantity
 *   <li>currencyUomId
 *   <li>checkIncludeVat
 * </ul>
 */
public static Map<String, Object> calculateProductPrice(DispatchContext dctx, Map<String, ? extends Object> context) {
    Delegator delegator = dctx.getDelegator();
    LocalDispatcher dispatcher = dctx.getDispatcher();
    Map<String, Object> result = new HashMap<String, Object>();
    Timestamp nowTimestamp = UtilDateTime.nowTimestamp();
    GenericValue product = (GenericValue) context.get("product");
    String productId = product.getString("productId");
    String prodCatalogId = (String) context.get("prodCatalogId");
    String webSiteId = (String) context.get("webSiteId");
    String checkIncludeVat = (String) context.get("checkIncludeVat");
    String surveyResponseId = (String) context.get("surveyResponseId");
    Map<String, Object> customAttributes = UtilGenerics.checkMap(context.get("customAttributes"));
    String findAllQuantityPricesStr = (String) context.get("findAllQuantityPrices");
    boolean findAllQuantityPrices = "Y".equals(findAllQuantityPricesStr);
    boolean optimizeForLargeRuleSet = "Y".equals(context.get("optimizeForLargeRuleSet"));
    String agreementId = (String) context.get("agreementId");
    String productStoreId = (String) context.get("productStoreId");
    String productStoreGroupId = (String) context.get("productStoreGroupId");
    Locale locale = (Locale) context.get("locale");
    GenericValue productStore = null;
    try {
        // we have a productStoreId, if the corresponding ProductStore.primaryStoreGroupId is not empty, use that
        productStore = EntityQuery.use(delegator).from("ProductStore").where("productStoreId", productStoreId).cache().queryOne();
    } catch (GenericEntityException e) {
        Debug.logError(e, "Error getting product store info from the database while calculating price" + e.toString(), module);
        return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ProductPriceCannotRetrieveProductStore", UtilMisc.toMap("errorString", e.toString()), locale));
    }
    if (UtilValidate.isEmpty(productStoreGroupId)) {
        if (productStore != null) {
            try {
                if (UtilValidate.isNotEmpty(productStore.getString("primaryStoreGroupId"))) {
                    productStoreGroupId = productStore.getString("primaryStoreGroupId");
                } else {
                    // no ProductStore.primaryStoreGroupId, try ProductStoreGroupMember
                    List<GenericValue> productStoreGroupMemberList = EntityQuery.use(delegator).from("ProductStoreGroupMember").where("productStoreId", productStoreId).orderBy("sequenceNum", "-fromDate").cache(true).queryList();
                    productStoreGroupMemberList = EntityUtil.filterByDate(productStoreGroupMemberList, true);
                    if (productStoreGroupMemberList.size() > 0) {
                        GenericValue productStoreGroupMember = EntityUtil.getFirst(productStoreGroupMemberList);
                        productStoreGroupId = productStoreGroupMember.getString("productStoreGroupId");
                    }
                }
            } catch (GenericEntityException e) {
                Debug.logError(e, "Error getting product store info from the database while calculating price" + e.toString(), module);
                return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ProductPriceCannotRetrieveProductStore", UtilMisc.toMap("errorString", e.toString()), locale));
            }
        }
        // still empty, default to _NA_
        if (UtilValidate.isEmpty(productStoreGroupId)) {
            productStoreGroupId = "_NA_";
        }
    }
    // if currencyUomId is null get from properties file, if nothing there assume USD (USD: American Dollar) for now
    String currencyDefaultUomId = (String) context.get("currencyUomId");
    String currencyUomIdTo = (String) context.get("currencyUomIdTo");
    if (UtilValidate.isEmpty(currencyDefaultUomId)) {
        if (productStore != null && UtilValidate.isNotEmpty(productStore.getString("defaultCurrencyUomId"))) {
            currencyDefaultUomId = productStore.getString("defaultCurrencyUomId");
        } else {
            currencyDefaultUomId = EntityUtilProperties.getPropertyValue("general", "currency.uom.id.default", "USD", delegator);
        }
    }
    // productPricePurposeId is null assume "PURCHASE", which is equivalent to what prices were before the purpose concept
    String productPricePurposeId = (String) context.get("productPricePurposeId");
    if (UtilValidate.isEmpty(productPricePurposeId)) {
        productPricePurposeId = "PURCHASE";
    }
    // termUomId, for things like recurring prices specifies the term (time/frequency measure for example) of the recurrence
    // if this is empty it will simply not be used to constrain the selection
    String termUomId = (String) context.get("termUomId");
    // if this product is variant, find the virtual product and apply checks to it as well
    String virtualProductId = null;
    if ("Y".equals(product.getString("isVariant"))) {
        try {
            virtualProductId = ProductWorker.getVariantVirtualId(product);
        } catch (GenericEntityException e) {
            Debug.logError(e, "Error getting virtual product id from the database while calculating price" + e.toString(), module);
            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ProductPriceCannotRetrieveVirtualProductId", UtilMisc.toMap("errorString", e.toString()), locale));
        }
    }
    // get prices for virtual product if one is found; get all ProductPrice entities for this productId and currencyUomId
    List<GenericValue> virtualProductPrices = null;
    if (virtualProductId != null) {
        try {
            virtualProductPrices = EntityQuery.use(delegator).from("ProductPrice").where("productId", virtualProductId, "currencyUomId", currencyDefaultUomId, "productStoreGroupId", productStoreGroupId).orderBy("-fromDate").cache(true).queryList();
        } catch (GenericEntityException e) {
            Debug.logError(e, "An error occurred while getting the product prices", module);
        }
        virtualProductPrices = EntityUtil.filterByDate(virtualProductPrices, true);
    }
    // NOTE: partyId CAN be null
    String partyId = (String) context.get("partyId");
    if (UtilValidate.isEmpty(partyId) && context.get("userLogin") != null) {
        GenericValue userLogin = (GenericValue) context.get("userLogin");
        partyId = userLogin.getString("partyId");
    }
    // check for auto-userlogin for price rules
    if (UtilValidate.isEmpty(partyId) && context.get("autoUserLogin") != null) {
        GenericValue userLogin = (GenericValue) context.get("autoUserLogin");
        partyId = userLogin.getString("partyId");
    }
    BigDecimal quantity = (BigDecimal) context.get("quantity");
    if (quantity == null)
        quantity = BigDecimal.ONE;
    BigDecimal amount = (BigDecimal) context.get("amount");
    List<EntityCondition> productPriceEcList = new LinkedList<EntityCondition>();
    productPriceEcList.add(EntityCondition.makeCondition("productId", EntityOperator.EQUALS, productId));
    // this funny statement is for backward compatibility purposes; the productPricePurposeId is a new pk field on the ProductPrice entity and in order databases may not be populated, until the pk is updated and such; this will ease the transition somewhat
    if ("PURCHASE".equals(productPricePurposeId)) {
        productPriceEcList.add(EntityCondition.makeCondition(EntityCondition.makeCondition("productPricePurposeId", EntityOperator.EQUALS, productPricePurposeId), EntityOperator.OR, EntityCondition.makeCondition("productPricePurposeId", EntityOperator.EQUALS, null)));
    } else {
        productPriceEcList.add(EntityCondition.makeCondition("productPricePurposeId", EntityOperator.EQUALS, productPricePurposeId));
    }
    productPriceEcList.add(EntityCondition.makeCondition("currencyUomId", EntityOperator.EQUALS, currencyDefaultUomId));
    productPriceEcList.add(EntityCondition.makeCondition("productStoreGroupId", EntityOperator.EQUALS, productStoreGroupId));
    if (UtilValidate.isNotEmpty(termUomId)) {
        productPriceEcList.add(EntityCondition.makeCondition("termUomId", EntityOperator.EQUALS, termUomId));
    }
    EntityCondition productPriceEc = EntityCondition.makeCondition(productPriceEcList, EntityOperator.AND);
    // for prices, get all ProductPrice entities for this productId and currencyUomId
    List<GenericValue> productPrices = null;
    try {
        productPrices = EntityQuery.use(delegator).from("ProductPrice").where(productPriceEc).orderBy("-fromDate").cache(true).queryList();
    } catch (GenericEntityException e) {
        Debug.logError(e, "An error occurred while getting the product prices", module);
    }
    productPrices = EntityUtil.filterByDate(productPrices, true);
    // ===== get the prices we need: list, default, average cost, promo, min, max =====
    // if any of these prices is missing and this product is a variant, default to the corresponding price on the virtual product
    GenericValue listPriceValue = getPriceValueForType("LIST_PRICE", productPrices, virtualProductPrices);
    GenericValue defaultPriceValue = getPriceValueForType("DEFAULT_PRICE", productPrices, virtualProductPrices);
    // ProductPrice entity.
    if (UtilValidate.isNotEmpty(agreementId)) {
        try {
            GenericValue agreementPriceValue = EntityQuery.use(delegator).from("AgreementItemAndProductAppl").where("agreementId", agreementId, "productId", productId, "currencyUomId", currencyDefaultUomId).queryFirst();
            if (agreementPriceValue != null && agreementPriceValue.get("price") != null) {
                defaultPriceValue = agreementPriceValue;
            }
        } catch (GenericEntityException e) {
            Debug.logError(e, "Error getting agreement info from the database while calculating price" + e.toString(), module);
            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ProductPriceCannotRetrieveAgreementInfo", UtilMisc.toMap("errorString", e.toString()), locale));
        }
    }
    GenericValue competitivePriceValue = getPriceValueForType("COMPETITIVE_PRICE", productPrices, virtualProductPrices);
    GenericValue averageCostValue = getPriceValueForType("AVERAGE_COST", productPrices, virtualProductPrices);
    GenericValue promoPriceValue = getPriceValueForType("PROMO_PRICE", productPrices, virtualProductPrices);
    GenericValue minimumPriceValue = getPriceValueForType("MINIMUM_PRICE", productPrices, virtualProductPrices);
    GenericValue maximumPriceValue = getPriceValueForType("MAXIMUM_PRICE", productPrices, virtualProductPrices);
    GenericValue wholesalePriceValue = getPriceValueForType("WHOLESALE_PRICE", productPrices, virtualProductPrices);
    GenericValue specialPromoPriceValue = getPriceValueForType("SPECIAL_PROMO_PRICE", productPrices, virtualProductPrices);
    // now if this is a virtual product check each price type, if doesn't exist get from variant with lowest DEFAULT_PRICE
    if ("Y".equals(product.getString("isVirtual"))) {
        // only do this if there is no default price, consider the others optional for performance reasons
        if (defaultPriceValue == null) {
            // use the cache to find the variant with the lowest default price
            try {
                List<GenericValue> variantAssocList = EntityQuery.use(delegator).from("ProductAssoc").where("productId", product.get("productId"), "productAssocTypeId", "PRODUCT_VARIANT").orderBy("-fromDate").cache(true).filterByDate().queryList();
                BigDecimal minDefaultPrice = null;
                List<GenericValue> variantProductPrices = null;
                for (GenericValue variantAssoc : variantAssocList) {
                    String curVariantProductId = variantAssoc.getString("productIdTo");
                    List<GenericValue> curVariantPriceList = EntityQuery.use(delegator).from("ProductPrice").where("productId", curVariantProductId).orderBy("-fromDate").cache(true).filterByDate(nowTimestamp).queryList();
                    List<GenericValue> tempDefaultPriceList = EntityUtil.filterByAnd(curVariantPriceList, UtilMisc.toMap("productPriceTypeId", "DEFAULT_PRICE"));
                    GenericValue curDefaultPriceValue = EntityUtil.getFirst(tempDefaultPriceList);
                    if (curDefaultPriceValue != null) {
                        BigDecimal curDefaultPrice = curDefaultPriceValue.getBigDecimal("price");
                        if (minDefaultPrice == null || curDefaultPrice.compareTo(minDefaultPrice) < 0) {
                            // check to see if the product is discontinued for sale before considering it the lowest price
                            GenericValue curVariantProduct = EntityQuery.use(delegator).from("Product").where("productId", curVariantProductId).cache().queryOne();
                            if (curVariantProduct != null) {
                                Timestamp salesDiscontinuationDate = curVariantProduct.getTimestamp("salesDiscontinuationDate");
                                if (salesDiscontinuationDate == null || salesDiscontinuationDate.after(nowTimestamp)) {
                                    minDefaultPrice = curDefaultPrice;
                                    variantProductPrices = curVariantPriceList;
                                }
                            }
                        }
                    }
                }
                if (variantProductPrices != null) {
                    // we have some other options, give 'em a go...
                    if (listPriceValue == null) {
                        listPriceValue = getPriceValueForType("LIST_PRICE", variantProductPrices, null);
                    }
                    if (competitivePriceValue == null) {
                        competitivePriceValue = getPriceValueForType("COMPETITIVE_PRICE", variantProductPrices, null);
                    }
                    if (averageCostValue == null) {
                        averageCostValue = getPriceValueForType("AVERAGE_COST", variantProductPrices, null);
                    }
                    if (promoPriceValue == null) {
                        promoPriceValue = getPriceValueForType("PROMO_PRICE", variantProductPrices, null);
                    }
                    if (minimumPriceValue == null) {
                        minimumPriceValue = getPriceValueForType("MINIMUM_PRICE", variantProductPrices, null);
                    }
                    if (maximumPriceValue == null) {
                        maximumPriceValue = getPriceValueForType("MAXIMUM_PRICE", variantProductPrices, null);
                    }
                    if (wholesalePriceValue == null) {
                        wholesalePriceValue = getPriceValueForType("WHOLESALE_PRICE", variantProductPrices, null);
                    }
                    if (specialPromoPriceValue == null) {
                        specialPromoPriceValue = getPriceValueForType("SPECIAL_PROMO_PRICE", variantProductPrices, null);
                    }
                    defaultPriceValue = getPriceValueForType("DEFAULT_PRICE", variantProductPrices, null);
                }
            } catch (GenericEntityException e) {
                Debug.logError(e, "An error occurred while getting the product prices", module);
            }
        }
    }
    BigDecimal promoPrice = BigDecimal.ZERO;
    if (promoPriceValue != null && promoPriceValue.get("price") != null) {
        promoPrice = promoPriceValue.getBigDecimal("price");
    }
    BigDecimal wholesalePrice = BigDecimal.ZERO;
    if (wholesalePriceValue != null && wholesalePriceValue.get("price") != null) {
        wholesalePrice = wholesalePriceValue.getBigDecimal("price");
    }
    boolean validPriceFound = false;
    BigDecimal defaultPrice = BigDecimal.ZERO;
    List<GenericValue> orderItemPriceInfos = new LinkedList<GenericValue>();
    if (defaultPriceValue != null) {
        // If a price calc formula (service) is specified, then use it to get the unit price
        if ("ProductPrice".equals(defaultPriceValue.getEntityName()) && UtilValidate.isNotEmpty(defaultPriceValue.getString("customPriceCalcService"))) {
            GenericValue customMethod = null;
            try {
                customMethod = defaultPriceValue.getRelatedOne("CustomMethod", false);
            } catch (GenericEntityException gee) {
                Debug.logError(gee, "An error occurred while getting the customPriceCalcService", module);
            }
            if (customMethod != null && UtilValidate.isNotEmpty(customMethod.getString("customMethodName"))) {
                Map<String, Object> inMap = UtilMisc.toMap("userLogin", context.get("userLogin"), "product", product);
                inMap.put("initialPrice", defaultPriceValue.getBigDecimal("price"));
                inMap.put("currencyUomId", currencyDefaultUomId);
                inMap.put("quantity", quantity);
                inMap.put("amount", amount);
                if (UtilValidate.isNotEmpty(surveyResponseId)) {
                    inMap.put("surveyResponseId", surveyResponseId);
                }
                if (UtilValidate.isNotEmpty(customAttributes)) {
                    inMap.put("customAttributes", customAttributes);
                }
                try {
                    Map<String, Object> outMap = dispatcher.runSync(customMethod.getString("customMethodName"), inMap);
                    if (ServiceUtil.isSuccess(outMap)) {
                        BigDecimal calculatedDefaultPrice = (BigDecimal) outMap.get("price");
                        orderItemPriceInfos = UtilGenerics.checkList(outMap.get("orderItemPriceInfos"));
                        if (UtilValidate.isNotEmpty(calculatedDefaultPrice)) {
                            defaultPrice = calculatedDefaultPrice;
                            validPriceFound = true;
                        }
                    }
                } catch (GenericServiceException gse) {
                    Debug.logError(gse, "An error occurred while running the customPriceCalcService [" + customMethod.getString("customMethodName") + "]", module);
                }
            }
        }
        if (!validPriceFound && defaultPriceValue.get("price") != null) {
            defaultPrice = defaultPriceValue.getBigDecimal("price");
            validPriceFound = true;
        }
    }
    BigDecimal listPrice = listPriceValue != null ? listPriceValue.getBigDecimal("price") : null;
    if (listPrice == null) {
        // no list price, use defaultPrice for the final price
        // ========= ensure calculated price is not below minSalePrice or above maxSalePrice =========
        BigDecimal maxSellPrice = maximumPriceValue != null ? maximumPriceValue.getBigDecimal("price") : null;
        if (maxSellPrice != null && defaultPrice.compareTo(maxSellPrice) > 0) {
            defaultPrice = maxSellPrice;
        }
        // min price second to override max price, safety net
        BigDecimal minSellPrice = minimumPriceValue != null ? minimumPriceValue.getBigDecimal("price") : null;
        if (minSellPrice != null && defaultPrice.compareTo(minSellPrice) < 0) {
            defaultPrice = minSellPrice;
            // since we have found a minimum price that has overriden a the defaultPrice, even if no valid one was found, we will consider it as if one had been...
            validPriceFound = true;
        }
        result.put("basePrice", defaultPrice);
        result.put("price", defaultPrice);
        result.put("defaultPrice", defaultPrice);
        result.put("competitivePrice", competitivePriceValue != null ? competitivePriceValue.getBigDecimal("price") : null);
        result.put("averageCost", averageCostValue != null ? averageCostValue.getBigDecimal("price") : null);
        result.put("promoPrice", promoPriceValue != null ? promoPriceValue.getBigDecimal("price") : null);
        result.put("specialPromoPrice", specialPromoPriceValue != null ? specialPromoPriceValue.getBigDecimal("price") : null);
        result.put("validPriceFound", Boolean.valueOf(validPriceFound));
        result.put("isSale", Boolean.FALSE);
        result.put("orderItemPriceInfos", orderItemPriceInfos);
        Map<String, Object> errorResult = addGeneralResults(result, competitivePriceValue, specialPromoPriceValue, productStore, checkIncludeVat, currencyDefaultUomId, productId, quantity, partyId, dispatcher, locale);
        if (errorResult != null)
            return errorResult;
    } else {
        try {
            List<GenericValue> allProductPriceRules = makeProducePriceRuleList(delegator, optimizeForLargeRuleSet, productId, virtualProductId, prodCatalogId, productStoreGroupId, webSiteId, partyId, currencyDefaultUomId);
            allProductPriceRules = EntityUtil.filterByDate(allProductPriceRules, true);
            List<GenericValue> quantityProductPriceRules = null;
            List<GenericValue> nonQuantityProductPriceRules = null;
            if (findAllQuantityPrices) {
                // split into list with quantity conditions and list without, then iterate through each quantity cond one
                quantityProductPriceRules = new LinkedList<GenericValue>();
                nonQuantityProductPriceRules = new LinkedList<GenericValue>();
                for (GenericValue productPriceRule : allProductPriceRules) {
                    List<GenericValue> productPriceCondList = EntityQuery.use(delegator).from("ProductPriceCond").where("productPriceRuleId", productPriceRule.get("productPriceRuleId")).cache(true).queryList();
                    boolean foundQuantityInputParam = false;
                    // only consider a rule if all conditions except the quantity condition are true
                    boolean allExceptQuantTrue = true;
                    for (GenericValue productPriceCond : productPriceCondList) {
                        if ("PRIP_QUANTITY".equals(productPriceCond.getString("inputParamEnumId"))) {
                            foundQuantityInputParam = true;
                        } else {
                            if (!checkPriceCondition(productPriceCond, productId, virtualProductId, prodCatalogId, productStoreGroupId, webSiteId, partyId, quantity, listPrice, currencyDefaultUomId, delegator, nowTimestamp)) {
                                allExceptQuantTrue = false;
                            }
                        }
                    }
                    if (foundQuantityInputParam && allExceptQuantTrue) {
                        quantityProductPriceRules.add(productPriceRule);
                    } else {
                        nonQuantityProductPriceRules.add(productPriceRule);
                    }
                }
            }
            if (findAllQuantityPrices) {
                List<Map<String, Object>> allQuantityPrices = new LinkedList<Map<String, Object>>();
                // foreach create an entry in the out list and eval that rule and all nonQuantityProductPriceRules rather than a single rule
                for (GenericValue quantityProductPriceRule : quantityProductPriceRules) {
                    List<GenericValue> ruleListToUse = new LinkedList<GenericValue>();
                    ruleListToUse.add(quantityProductPriceRule);
                    ruleListToUse.addAll(nonQuantityProductPriceRules);
                    Map<String, Object> quantCalcResults = calcPriceResultFromRules(ruleListToUse, listPrice, defaultPrice, promoPrice, wholesalePrice, maximumPriceValue, minimumPriceValue, validPriceFound, averageCostValue, productId, virtualProductId, prodCatalogId, productStoreGroupId, webSiteId, partyId, null, currencyDefaultUomId, delegator, nowTimestamp, locale);
                    Map<String, Object> quantErrorResult = addGeneralResults(quantCalcResults, competitivePriceValue, specialPromoPriceValue, productStore, checkIncludeVat, currencyDefaultUomId, productId, quantity, partyId, dispatcher, locale);
                    if (quantErrorResult != null)
                        return quantErrorResult;
                    // also add the quantityProductPriceRule to the Map so it can be used for quantity break information
                    quantCalcResults.put("quantityProductPriceRule", quantityProductPriceRule);
                    allQuantityPrices.add(quantCalcResults);
                }
                result.put("allQuantityPrices", allQuantityPrices);
                // use a quantity 1 to get the main price, then fill in the quantity break prices
                Map<String, Object> calcResults = calcPriceResultFromRules(allProductPriceRules, listPrice, defaultPrice, promoPrice, wholesalePrice, maximumPriceValue, minimumPriceValue, validPriceFound, averageCostValue, productId, virtualProductId, prodCatalogId, productStoreGroupId, webSiteId, partyId, BigDecimal.ONE, currencyDefaultUomId, delegator, nowTimestamp, locale);
                result.putAll(calcResults);
                // The orderItemPriceInfos out parameter requires a special treatment:
                // the list of OrderItemPriceInfos generated by the price rule is appended to
                // the existing orderItemPriceInfos list and the aggregated list is returned.
                List<GenericValue> orderItemPriceInfosFromRule = UtilGenerics.checkList(calcResults.get("orderItemPriceInfos"));
                if (UtilValidate.isNotEmpty(orderItemPriceInfosFromRule)) {
                    orderItemPriceInfos.addAll(orderItemPriceInfosFromRule);
                }
                result.put("orderItemPriceInfos", orderItemPriceInfos);
                Map<String, Object> errorResult = addGeneralResults(result, competitivePriceValue, specialPromoPriceValue, productStore, checkIncludeVat, currencyDefaultUomId, productId, quantity, partyId, dispatcher, locale);
                if (errorResult != null)
                    return errorResult;
            } else {
                Map<String, Object> calcResults = calcPriceResultFromRules(allProductPriceRules, listPrice, defaultPrice, promoPrice, wholesalePrice, maximumPriceValue, minimumPriceValue, validPriceFound, averageCostValue, productId, virtualProductId, prodCatalogId, productStoreGroupId, webSiteId, partyId, quantity, currencyDefaultUomId, delegator, nowTimestamp, locale);
                result.putAll(calcResults);
                // The orderItemPriceInfos out parameter requires a special treatment:
                // the list of OrderItemPriceInfos generated by the price rule is appended to
                // the existing orderItemPriceInfos list and the aggregated list is returned.
                List<GenericValue> orderItemPriceInfosFromRule = UtilGenerics.checkList(calcResults.get("orderItemPriceInfos"));
                if (UtilValidate.isNotEmpty(orderItemPriceInfosFromRule)) {
                    orderItemPriceInfos.addAll(orderItemPriceInfosFromRule);
                }
                result.put("orderItemPriceInfos", orderItemPriceInfos);
                Map<String, Object> errorResult = addGeneralResults(result, competitivePriceValue, specialPromoPriceValue, productStore, checkIncludeVat, currencyDefaultUomId, productId, quantity, partyId, dispatcher, locale);
                if (errorResult != null)
                    return errorResult;
            }
        } catch (GenericEntityException e) {
            Debug.logError(e, "Error getting rules from the database while calculating price", module);
            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ProductPriceCannotRetrievePriceRules", UtilMisc.toMap("errorString", e.toString()), locale));
        }
    }
    // Convert the value to the price currency, if required
    if ("true".equals(EntityUtilProperties.getPropertyValue("catalog", "convertProductPriceCurrency", delegator))) {
        if (UtilValidate.isNotEmpty(currencyDefaultUomId) && UtilValidate.isNotEmpty(currencyUomIdTo) && !currencyDefaultUomId.equals(currencyUomIdTo)) {
            if (UtilValidate.isNotEmpty(result)) {
                Map<String, Object> convertPriceMap = new HashMap<String, Object>();
                for (Map.Entry<String, Object> entry : result.entrySet()) {
                    BigDecimal tempPrice = BigDecimal.ZERO;
                    switch(entry.getKey()) {
                        case "basePrice":
                            tempPrice = (BigDecimal) entry.getValue();
                        case "price":
                            tempPrice = (BigDecimal) entry.getValue();
                        case "defaultPrice":
                            tempPrice = (BigDecimal) entry.getValue();
                        case "competitivePrice":
                            tempPrice = (BigDecimal) entry.getValue();
                        case "averageCost":
                            tempPrice = (BigDecimal) entry.getValue();
                        case "promoPrice":
                            tempPrice = (BigDecimal) entry.getValue();
                        case "specialPromoPrice":
                            tempPrice = (BigDecimal) entry.getValue();
                        case "listPrice":
                            tempPrice = (BigDecimal) entry.getValue();
                    }
                    if (tempPrice != null && tempPrice != BigDecimal.ZERO) {
                        Map<String, Object> priceResults = new HashMap<String, Object>();
                        try {
                            priceResults = dispatcher.runSync("convertUom", UtilMisc.<String, Object>toMap("uomId", currencyDefaultUomId, "uomIdTo", currencyUomIdTo, "originalValue", tempPrice, "defaultDecimalScale", Long.valueOf(2), "defaultRoundingMode", "HalfUp"));
                            if (ServiceUtil.isError(priceResults) || (priceResults.get("convertedValue") == null)) {
                                Debug.logWarning("Unable to convert " + entry.getKey() + " for product  " + productId, module);
                            }
                        } catch (GenericServiceException e) {
                            Debug.logError(e, module);
                        }
                        convertPriceMap.put(entry.getKey(), priceResults.get("convertedValue"));
                    } else {
                        convertPriceMap.put(entry.getKey(), entry.getValue());
                    }
                }
                if (UtilValidate.isNotEmpty(convertPriceMap)) {
                    convertPriceMap.put("currencyUsed", currencyUomIdTo);
                    result = convertPriceMap;
                }
            }
        }
    }
    return result;
}
Also used : Locale(java.util.Locale) GenericValue(org.apache.ofbiz.entity.GenericValue) LocalDispatcher(org.apache.ofbiz.service.LocalDispatcher) HashMap(java.util.HashMap) EntityCondition(org.apache.ofbiz.entity.condition.EntityCondition) Timestamp(java.sql.Timestamp) BigDecimal(java.math.BigDecimal) LinkedList(java.util.LinkedList) Delegator(org.apache.ofbiz.entity.Delegator) GenericEntityException(org.apache.ofbiz.entity.GenericEntityException) GenericServiceException(org.apache.ofbiz.service.GenericServiceException) HashMap(java.util.HashMap) Map(java.util.Map)

Example 24 with GenericEntityException

use of org.apache.ofbiz.entity.GenericEntityException in project ofbiz-framework by apache.

the class PriceServices method calculatePurchasePrice.

/**
 * Calculates the purchase price of a product
 */
public static Map<String, Object> calculatePurchasePrice(DispatchContext dctx, Map<String, ? extends Object> context) {
    Delegator delegator = dctx.getDelegator();
    LocalDispatcher dispatcher = dctx.getDispatcher();
    Map<String, Object> result = new HashMap<String, Object>();
    List<GenericValue> orderItemPriceInfos = new LinkedList<GenericValue>();
    boolean validPriceFound = false;
    BigDecimal price = BigDecimal.ZERO;
    GenericValue product = (GenericValue) context.get("product");
    String productId = product.getString("productId");
    String agreementId = (String) context.get("agreementId");
    String currencyUomId = (String) context.get("currencyUomId");
    String partyId = (String) context.get("partyId");
    BigDecimal quantity = (BigDecimal) context.get("quantity");
    Locale locale = (Locale) context.get("locale");
    // a) Get the Price from the Agreement* data model
    if (Debug.infoOn())
        Debug.logInfo("Try to resolve purchase price from agreement " + agreementId, module);
    if (UtilValidate.isNotEmpty(agreementId)) {
        // TODO Search before if agreement is associate to SupplierProduct.
        // confirm that agreement is price application on purchase type and contains a value for the product
        EntityCondition cond = EntityCondition.makeCondition(UtilMisc.toList(EntityExpr.makeCondition("agreementId", agreementId), EntityExpr.makeCondition("agreementItemTypeId", "AGREEMENT_PRICING_PR"), EntityExpr.makeCondition("agreementTypeId", "PURCHASE_AGREEMENT"), EntityExpr.makeCondition("productId", productId)));
        try {
            List<GenericValue> agreementPrices = delegator.findList("AgreementItemAndProductAppl", cond, UtilMisc.toSet("price", "currencyUomId"), null, null, true);
            if (UtilValidate.isNotEmpty(agreementPrices)) {
                GenericValue priceFound = null;
                // resolve price on given currency. If not define, try to convert a present price
                priceFound = EntityUtil.getFirst(EntityUtil.filterByAnd(agreementPrices, UtilMisc.toMap("currencyUomId", currencyUomId)));
                if (Debug.infoOn()) {
                    Debug.logInfo("             AgreementItem " + agreementPrices, module);
                    Debug.logInfo("             currencyUomId " + currencyUomId, module);
                    Debug.logInfo("             priceFound " + priceFound, module);
                }
                if (priceFound == null) {
                    priceFound = EntityUtil.getFirst(agreementPrices);
                    try {
                        Map<String, Object> priceConvertMap = UtilMisc.toMap("uomId", priceFound.getString("currencyUomId"), "uomIdTo", currencyUomId, "originalValue", priceFound.getBigDecimal("price"), "defaultDecimalScale", Long.valueOf(2), "defaultRoundingMode", "HalfUp");
                        Map<String, Object> priceResults = dispatcher.runSync("convertUom", priceConvertMap);
                        if (ServiceUtil.isError(priceResults) || (priceResults.get("convertedValue") == null)) {
                            Debug.logWarning("Unable to convert " + priceFound + " for product  " + productId, module);
                        } else {
                            price = (BigDecimal) priceResults.get("convertedValue");
                            validPriceFound = true;
                        }
                    } catch (GenericServiceException e) {
                        Debug.logError(e, module);
                    }
                } else {
                    price = priceFound.getBigDecimal("price");
                    validPriceFound = true;
                }
            }
            if (validPriceFound) {
                GenericValue agreement = delegator.findOne("Agreement", true, UtilMisc.toMap("agreementId", agreementId));
                StringBuilder priceInfoDescription = new StringBuilder();
                priceInfoDescription.append(UtilProperties.getMessage(resource, "ProductAgreementUse", locale));
                priceInfoDescription.append("[");
                priceInfoDescription.append(agreementId);
                priceInfoDescription.append("] ");
                priceInfoDescription.append(agreement.get("description"));
                GenericValue orderItemPriceInfo = delegator.makeValue("OrderItemPriceInfo");
                // make sure description is <= than 250 chars
                String priceInfoDescriptionString = priceInfoDescription.toString();
                if (priceInfoDescriptionString.length() > 250) {
                    priceInfoDescriptionString = priceInfoDescriptionString.substring(0, 250);
                }
                orderItemPriceInfo.set("description", priceInfoDescriptionString);
                orderItemPriceInfos.add(orderItemPriceInfo);
            }
        } catch (GenericEntityException gee) {
            Debug.logError(gee, module);
            return ServiceUtil.returnError(gee.getMessage());
        }
    }
    // b) If no price can be found, get the lastPrice from the SupplierProduct entity
    if (!validPriceFound) {
        Map<String, Object> priceContext = UtilMisc.toMap("currencyUomId", currencyUomId, "partyId", partyId, "productId", productId, "quantity", quantity);
        List<GenericValue> productSuppliers = null;
        try {
            Map<String, Object> priceResult = dispatcher.runSync("getSuppliersForProduct", priceContext);
            if (ServiceUtil.isError(priceResult)) {
                String errMsg = ServiceUtil.getErrorMessage(priceResult);
                Debug.logError(errMsg, module);
                return ServiceUtil.returnError(errMsg);
            }
            productSuppliers = UtilGenerics.checkList(priceResult.get("supplierProducts"));
        } catch (GenericServiceException gse) {
            Debug.logError(gse, module);
            return ServiceUtil.returnError(gse.getMessage());
        }
        if (productSuppliers != null) {
            for (GenericValue productSupplier : productSuppliers) {
                if (!validPriceFound) {
                    price = ((BigDecimal) productSupplier.get("lastPrice"));
                    validPriceFound = true;
                }
                // add a orderItemPriceInfo element too, without orderId or orderItemId
                StringBuilder priceInfoDescription = new StringBuilder();
                priceInfoDescription.append(UtilProperties.getMessage(resource, "ProductSupplier", locale));
                priceInfoDescription.append(" [");
                priceInfoDescription.append(UtilProperties.getMessage(resource, "ProductSupplierMinimumOrderQuantity", locale));
                priceInfoDescription.append(productSupplier.getBigDecimal("minimumOrderQuantity"));
                priceInfoDescription.append(UtilProperties.getMessage(resource, "ProductSupplierLastPrice", locale));
                priceInfoDescription.append(productSupplier.getBigDecimal("lastPrice"));
                priceInfoDescription.append("]");
                GenericValue orderItemPriceInfo = delegator.makeValue("OrderItemPriceInfo");
                // make sure description is <= than 250 chars
                String priceInfoDescriptionString = priceInfoDescription.toString();
                if (priceInfoDescriptionString.length() > 250) {
                    priceInfoDescriptionString = priceInfoDescriptionString.substring(0, 250);
                }
                orderItemPriceInfo.set("description", priceInfoDescriptionString);
                orderItemPriceInfos.add(orderItemPriceInfo);
            }
        }
    }
    // c) If no price can be found, get the averageCost from the ProductPrice entity
    if (!validPriceFound) {
        List<GenericValue> prices = null;
        try {
            prices = EntityQuery.use(delegator).from("ProductPrice").where("productId", productId, "productPricePurposeId", "PURCHASE").orderBy("-fromDate").queryList();
            // if no prices are found; find the prices of the parent product
            if (UtilValidate.isEmpty(prices)) {
                GenericValue parentProduct = ProductWorker.getParentProduct(productId, delegator);
                if (parentProduct != null) {
                    String parentProductId = parentProduct.getString("productId");
                    prices = EntityQuery.use(delegator).from("ProductPrice").where("productId", parentProductId, "productPricePurposeId", "PURCHASE").orderBy("-fromDate").queryList();
                }
            }
        } catch (GenericEntityException e) {
            Debug.logError(e, module);
            return ServiceUtil.returnError(e.getMessage());
        }
        // filter out the old prices
        prices = EntityUtil.filterByDate(prices);
        // first check for the AVERAGE_COST price type
        List<GenericValue> pricesToUse = EntityUtil.filterByAnd(prices, UtilMisc.toMap("productPriceTypeId", "AVERAGE_COST"));
        if (UtilValidate.isEmpty(pricesToUse)) {
            // next go with default price
            pricesToUse = EntityUtil.filterByAnd(prices, UtilMisc.toMap("productPriceTypeId", "DEFAULT_PRICE"));
            if (UtilValidate.isEmpty(pricesToUse)) {
                // finally use list price
                pricesToUse = EntityUtil.filterByAnd(prices, UtilMisc.toMap("productPriceTypeId", "LIST_PRICE"));
            }
        }
        // use the most current price
        GenericValue thisPrice = EntityUtil.getFirst(pricesToUse);
        if (thisPrice != null) {
            price = thisPrice.getBigDecimal("price");
            validPriceFound = true;
        }
    }
    result.put("price", price);
    result.put("validPriceFound", Boolean.valueOf(validPriceFound));
    result.put("orderItemPriceInfos", orderItemPriceInfos);
    return result;
}
Also used : Locale(java.util.Locale) GenericValue(org.apache.ofbiz.entity.GenericValue) LocalDispatcher(org.apache.ofbiz.service.LocalDispatcher) HashMap(java.util.HashMap) EntityCondition(org.apache.ofbiz.entity.condition.EntityCondition) LinkedList(java.util.LinkedList) BigDecimal(java.math.BigDecimal) Delegator(org.apache.ofbiz.entity.Delegator) GenericEntityException(org.apache.ofbiz.entity.GenericEntityException) GenericServiceException(org.apache.ofbiz.service.GenericServiceException)

Example 25 with GenericEntityException

use of org.apache.ofbiz.entity.GenericEntityException in project ofbiz-framework by apache.

the class InventoryWorker method getOutstandingProductQuantities.

/**
 * Gets the quanitty of each product in the order that is outstanding across all orders of the given input type.
 * Uses the OrderItemQuantityReportGroupByProduct view entity.
 *
 * @param   productIds  Collection of disticnt productIds in an order. Use OrderReadHelper.getOrderProductIds()
 * @param   orderTypeId Either "SALES_ORDER" or "PURCHASE_ORDER"
 * @param   delegator   The delegator to use
 * @return  Map of productIds to quantities outstanding.
 */
public static Map<String, BigDecimal> getOutstandingProductQuantities(Collection<String> productIds, String orderTypeId, Delegator delegator) {
    Set<String> fieldsToSelect = UtilMisc.toSet("productId", "quantityOpen");
    List<EntityCondition> condList = UtilMisc.<EntityCondition>toList(EntityCondition.makeCondition("orderTypeId", EntityOperator.EQUALS, orderTypeId), EntityCondition.makeCondition("orderStatusId", EntityOperator.NOT_EQUAL, "ORDER_COMPLETED"), EntityCondition.makeCondition("orderStatusId", EntityOperator.NOT_EQUAL, "ORDER_REJECTED"), EntityCondition.makeCondition("orderStatusId", EntityOperator.NOT_EQUAL, "ORDER_CANCELLED"));
    if (productIds.size() > 0) {
        condList.add(EntityCondition.makeCondition("productId", EntityOperator.IN, productIds));
    }
    condList.add(EntityCondition.makeCondition("orderItemStatusId", EntityOperator.NOT_EQUAL, "ITEM_COMPLETED"));
    condList.add(EntityCondition.makeCondition("orderItemStatusId", EntityOperator.NOT_EQUAL, "ITEM_REJECTED"));
    condList.add(EntityCondition.makeCondition("orderItemStatusId", EntityOperator.NOT_EQUAL, "ITEM_CANCELLED"));
    EntityConditionList<EntityCondition> conditions = EntityCondition.makeCondition(condList, EntityOperator.AND);
    Map<String, BigDecimal> results = new HashMap<>();
    try {
        List<GenericValue> orderedProducts = EntityQuery.use(delegator).select(fieldsToSelect).from("OrderItemQuantityReportGroupByProduct").where(conditions).queryList();
        for (GenericValue value : orderedProducts) {
            results.put(value.getString("productId"), value.getBigDecimal("quantityOpen"));
        }
    } catch (GenericEntityException e) {
        Debug.logError(e, module);
    }
    return results;
}
Also used : GenericValue(org.apache.ofbiz.entity.GenericValue) HashMap(java.util.HashMap) GenericEntityException(org.apache.ofbiz.entity.GenericEntityException) EntityCondition(org.apache.ofbiz.entity.condition.EntityCondition) BigDecimal(java.math.BigDecimal)

Aggregations

GenericEntityException (org.apache.ofbiz.entity.GenericEntityException)913 GenericValue (org.apache.ofbiz.entity.GenericValue)847 Delegator (org.apache.ofbiz.entity.Delegator)599 Locale (java.util.Locale)384 HashMap (java.util.HashMap)336 GenericServiceException (org.apache.ofbiz.service.GenericServiceException)270 LocalDispatcher (org.apache.ofbiz.service.LocalDispatcher)259 LinkedList (java.util.LinkedList)231 BigDecimal (java.math.BigDecimal)213 Timestamp (java.sql.Timestamp)171 Map (java.util.Map)109 GeneralException (org.apache.ofbiz.base.util.GeneralException)95 EntityCondition (org.apache.ofbiz.entity.condition.EntityCondition)78 IOException (java.io.IOException)75 EntityListIterator (org.apache.ofbiz.entity.util.EntityListIterator)57 Security (org.apache.ofbiz.security.Security)54 ArrayList (java.util.ArrayList)48 EntityExpr (org.apache.ofbiz.entity.condition.EntityExpr)47 GenericTransactionException (org.apache.ofbiz.entity.transaction.GenericTransactionException)39 LinkedHashMap (java.util.LinkedHashMap)37