use of org.apache.ofbiz.entity.condition.EntityExpr in project ofbiz-framework by apache.
the class OrderServices method loadCartForUpdate.
/*
* Warning: loadCartForUpdate(...) and saveUpdatedCartToOrder(...) must always
* be used together in this sequence.
* In fact loadCartForUpdate(...) will remove or cancel data associated to the order,
* before returning the ShoppingCart object; for this reason, the cart
* must be stored back using the method saveUpdatedCartToOrder(...),
* because that method will recreate the data.
*/
private static ShoppingCart loadCartForUpdate(LocalDispatcher dispatcher, Delegator delegator, GenericValue userLogin, String orderId) throws GeneralException {
// load the order into a shopping cart
Map<String, Object> loadCartResp = null;
try {
loadCartResp = dispatcher.runSync("loadCartFromOrder", UtilMisc.<String, Object>toMap("orderId", orderId, // the items are already reserved, no need to check again
"skipInventoryChecks", // the items are already reserved, no need to check again
Boolean.TRUE, // the products are already in the order, no need to check their validity now
"skipProductChecks", // the products are already in the order, no need to check their validity now
Boolean.TRUE, "userLogin", userLogin));
} catch (GenericServiceException e) {
Debug.logError(e, module);
throw new GeneralException(e.getMessage());
}
if (ServiceUtil.isError(loadCartResp)) {
throw new GeneralException(ServiceUtil.getErrorMessage(loadCartResp));
}
ShoppingCart cart = (ShoppingCart) loadCartResp.get("shoppingCart");
if (cart == null) {
throw new GeneralException("Error loading shopping cart from order [" + orderId + "]");
}
cart.setOrderId(orderId);
// Now that the cart is loaded, all the data that will be re-created
// when the method saveUpdatedCartToOrder(...) will be called, are
// removed and cancelled:
// - inventory reservations are cancelled
// - promotional items are cancelled
// - order payments are released (cancelled)
// - offline non received payments are cancelled
// - promotional, shipping and tax adjustments are removed
// Inventory reservations
// find ship group associations
List<GenericValue> shipGroupAssocs = null;
try {
shipGroupAssocs = EntityQuery.use(delegator).from("OrderItemShipGroupAssoc").where("orderId", orderId).queryList();
} catch (GenericEntityException e) {
Debug.logError(e, module);
throw new GeneralException(e.getMessage());
}
// cancel existing inventory reservations
if (shipGroupAssocs != null) {
for (GenericValue shipGroupAssoc : shipGroupAssocs) {
String orderItemSeqId = shipGroupAssoc.getString("orderItemSeqId");
String shipGroupSeqId = shipGroupAssoc.getString("shipGroupSeqId");
Map<String, Object> cancelCtx = UtilMisc.<String, Object>toMap("userLogin", userLogin, "orderId", orderId);
cancelCtx.put("orderItemSeqId", orderItemSeqId);
cancelCtx.put("shipGroupSeqId", shipGroupSeqId);
Map<String, Object> cancelResp = null;
try {
cancelResp = dispatcher.runSync("cancelOrderInventoryReservation", cancelCtx);
} catch (GenericServiceException e) {
Debug.logError(e, module);
throw new GeneralException(e.getMessage());
}
if (ServiceUtil.isError(cancelResp)) {
throw new GeneralException(ServiceUtil.getErrorMessage(cancelResp));
}
}
}
// cancel promo items -- if the promo still qualifies it will be added by the cart
List<GenericValue> promoItems = null;
try {
promoItems = EntityQuery.use(delegator).from("OrderItem").where("orderId", orderId, "isPromo", "Y").queryList();
} catch (GenericEntityException e) {
Debug.logError(e, module);
throw new GeneralException(e.getMessage());
}
if (promoItems != null) {
for (GenericValue promoItem : promoItems) {
// Skip if the promo is already cancelled
if ("ITEM_CANCELLED".equals(promoItem.get("statusId"))) {
continue;
}
Map<String, Object> cancelPromoCtx = UtilMisc.<String, Object>toMap("orderId", orderId);
cancelPromoCtx.put("orderItemSeqId", promoItem.getString("orderItemSeqId"));
cancelPromoCtx.put("userLogin", userLogin);
Map<String, Object> cancelResp = null;
try {
cancelResp = dispatcher.runSync("cancelOrderItemNoActions", cancelPromoCtx);
} catch (GenericServiceException e) {
Debug.logError(e, module);
throw new GeneralException(e.getMessage());
}
if (ServiceUtil.isError(cancelResp)) {
throw new GeneralException(ServiceUtil.getErrorMessage(cancelResp));
}
}
}
// cancel exiting authorizations
Map<String, Object> releaseResp = null;
try {
releaseResp = dispatcher.runSync("releaseOrderPayments", UtilMisc.<String, Object>toMap("orderId", orderId, "userLogin", userLogin));
} catch (GenericServiceException e) {
Debug.logError(e, module);
throw new GeneralException(e.getMessage());
}
if (ServiceUtil.isError(releaseResp)) {
throw new GeneralException(ServiceUtil.getErrorMessage(releaseResp));
}
// cancel other (non-completed and non-cancelled) payments
List<GenericValue> paymentPrefsToCancel = null;
try {
List<EntityExpr> exprs = UtilMisc.toList(EntityCondition.makeCondition("orderId", EntityOperator.EQUALS, orderId));
exprs.add(EntityCondition.makeCondition("statusId", EntityOperator.NOT_EQUAL, "PAYMENT_RECEIVED"));
exprs.add(EntityCondition.makeCondition("statusId", EntityOperator.NOT_EQUAL, "PAYMENT_CANCELLED"));
exprs.add(EntityCondition.makeCondition("statusId", EntityOperator.NOT_EQUAL, "PAYMENT_DECLINED"));
exprs.add(EntityCondition.makeCondition("statusId", EntityOperator.NOT_EQUAL, "PAYMENT_SETTLED"));
exprs.add(EntityCondition.makeCondition("statusId", EntityOperator.NOT_EQUAL, "PAYMENT_REFUNDED"));
paymentPrefsToCancel = EntityQuery.use(delegator).from("OrderPaymentPreference").where(exprs).queryList();
} catch (GenericEntityException e) {
Debug.logError(e, module);
throw new GeneralException(e.getMessage());
}
if (paymentPrefsToCancel != null) {
for (GenericValue opp : paymentPrefsToCancel) {
try {
opp.set("statusId", "PAYMENT_CANCELLED");
opp.store();
} catch (GenericEntityException e) {
Debug.logError(e, module);
throw new GeneralException(e.getMessage());
}
}
}
// remove the adjustments
try {
List<EntityCondition> adjExprs = new LinkedList<>();
adjExprs.add(EntityCondition.makeCondition("orderId", EntityOperator.EQUALS, orderId));
List<EntityCondition> exprs = new LinkedList<>();
exprs.add(EntityCondition.makeCondition("orderAdjustmentTypeId", EntityOperator.EQUALS, "PROMOTION_ADJUSTMENT"));
exprs.add(EntityCondition.makeCondition("orderAdjustmentTypeId", EntityOperator.EQUALS, "SHIPPING_CHARGES"));
exprs.add(EntityCondition.makeCondition("orderAdjustmentTypeId", EntityOperator.EQUALS, "SALES_TAX"));
exprs.add(EntityCondition.makeCondition("orderAdjustmentTypeId", EntityOperator.EQUALS, "VAT_TAX"));
exprs.add(EntityCondition.makeCondition("orderAdjustmentTypeId", EntityOperator.EQUALS, "VAT_PRICE_CORRECT"));
adjExprs.add(EntityCondition.makeCondition(exprs, EntityOperator.OR));
EntityCondition cond = EntityCondition.makeCondition(adjExprs, EntityOperator.AND);
List<GenericValue> orderAdjustmentsToDelete = EntityQuery.use(delegator).from("OrderAdjustment").where(cond).queryList();
List<GenericValue> orderAdjustmentsToStore = new LinkedList<>();
List<GenericValue> orderAdjustmentsToRemove = new LinkedList<>();
if (UtilValidate.isNotEmpty(orderAdjustmentsToDelete)) {
for (GenericValue orderAdjustment : orderAdjustmentsToDelete) {
// check if the adjustment has a related entry in entity OrderAdjustmentBilling
List<GenericValue> oaBilling = orderAdjustment.getRelated("OrderAdjustmentBilling", null, null, false);
if (UtilValidate.isNotEmpty(oaBilling)) {
orderAdjustmentsToRemove.add(orderAdjustment);
if ("SALES_TAX".equals(orderAdjustment.get("orderAdjustmentTypeId"))) {
// if the orderAdjustment is a sale tax, set the amount to 0 to avoid amount addition
orderAdjustmentsToStore.add(orderAdjustment);
}
}
}
}
// then remove order Adjustment of the list
if (UtilValidate.isNotEmpty(orderAdjustmentsToDelete)) {
orderAdjustmentsToDelete.removeAll(orderAdjustmentsToRemove);
delegator.removeAll(orderAdjustmentsToDelete);
}
if (UtilValidate.isNotEmpty(orderAdjustmentsToStore)) {
for (GenericValue orderAdjustment : orderAdjustmentsToStore) {
orderAdjustment.set("amount", BigDecimal.ZERO);
}
delegator.storeAll(orderAdjustmentsToStore);
}
} catch (GenericEntityException e) {
Debug.logError(e, module);
throw new GeneralException(e.getMessage());
}
return cart;
}
use of org.apache.ofbiz.entity.condition.EntityExpr in project ofbiz-framework by apache.
the class OrderServices method fulfillDigitalItems.
public static Map<String, Object> fulfillDigitalItems(DispatchContext ctx, Map<String, ? extends Object> context) {
Delegator delegator = ctx.getDelegator();
LocalDispatcher dispatcher = ctx.getDispatcher();
// appears to not be used: String orderId = (String) context.get("orderId");
List<GenericValue> orderItems = UtilGenerics.checkList(context.get("orderItems"));
GenericValue userLogin = (GenericValue) context.get("userLogin");
Locale locale = (Locale) context.get("locale");
if (UtilValidate.isNotEmpty(orderItems)) {
// loop through the digital items to fulfill
for (GenericValue orderItem : orderItems) {
// make sure we have a valid item
if (orderItem == null) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderErrorCannotCheckForFulfillmentItemNotFound", locale));
}
// locate the Product & ProductContent records
GenericValue product = null;
List<GenericValue> productContent = null;
try {
product = orderItem.getRelatedOne("Product", false);
if (product == null) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderErrorCannotCheckForFulfillmentProductNotFound", locale));
}
List<EntityExpr> exprs = new ArrayList<>();
exprs.add(EntityCondition.makeCondition("productContentTypeId", EntityOperator.IN, UtilMisc.toList("FULFILLMENT_EXTASYNC", "FULFILLMENT_EXTSYNC", "FULFILLMENT_EMAIL", "DIGITAL_DOWNLOAD")));
exprs.add(EntityCondition.makeCondition("productId", EntityOperator.EQUALS, product.getString("productId")));
// try looking up the parent product if the product has no content and is a variant
List<GenericValue> allProductContent = EntityQuery.use(delegator).from("ProductContent").where(exprs).queryList();
if (UtilValidate.isEmpty(allProductContent) && ("Y".equals(product.getString("isVariant")))) {
GenericValue parentProduct = ProductWorker.getParentProduct(product.getString("productId"), delegator);
if (allProductContent == null) {
allProductContent = new LinkedList<>();
}
if (parentProduct != null) {
allProductContent.addAll(parentProduct.getRelated("ProductContent", null, null, false));
}
}
if (UtilValidate.isNotEmpty(allProductContent)) {
// only keep ones with valid dates
productContent = EntityUtil.filterByDate(allProductContent, UtilDateTime.nowTimestamp(), "fromDate", "thruDate", true);
Debug.logInfo("Product has " + allProductContent.size() + " associations, " + (productContent == null ? "0" : "" + productContent.size()) + " has valid from/thru dates", module);
}
} catch (GenericEntityException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderErrorCannotGetProductEntity", locale) + e.getMessage());
}
// now use the ProductContent to fulfill the item
if (UtilValidate.isNotEmpty(productContent)) {
for (GenericValue productContentItem : productContent) {
GenericValue content = null;
try {
content = productContentItem.getRelatedOne("Content", false);
} catch (GenericEntityException e) {
Debug.logError(e, "ERROR: Cannot get Content entity: " + e.getMessage(), module);
continue;
}
String fulfillmentType = productContentItem.getString("productContentTypeId");
if ("FULFILLMENT_EXTASYNC".equals(fulfillmentType) || "FULFILLMENT_EXTSYNC".equals(fulfillmentType)) {
// external service fulfillment
// Kept for backward compatibility
String fulfillmentService = (String) content.get("serviceName");
GenericValue custMethod = null;
if (UtilValidate.isNotEmpty(content.getString("customMethodId"))) {
try {
custMethod = EntityQuery.use(delegator).from("CustomMethod").where("customMethodId", content.get("customMethodId")).cache().queryOne();
} catch (GenericEntityException e) {
Debug.logError(e, "ERROR: Cannot get CustomMethod associate to Content entity: " + e.getMessage(), module);
continue;
}
}
if (custMethod != null) {
fulfillmentService = custMethod.getString("customMethodName");
}
if (fulfillmentService == null) {
Debug.logError("ProductContent of type FULFILLMENT_EXTERNAL had Content with empty serviceName, can not run fulfillment", module);
}
Map<String, Object> serviceCtx = UtilMisc.<String, Object>toMap("userLogin", userLogin, "orderItem", orderItem);
serviceCtx.putAll(productContentItem.getPrimaryKey());
try {
Debug.logInfo("Running external fulfillment '" + fulfillmentService + "'", module);
if ("FULFILLMENT_EXTASYNC".equals(fulfillmentType)) {
dispatcher.runAsync(fulfillmentService, serviceCtx, true);
} else if ("FULFILLMENT_EXTSYNC".equals(fulfillmentType)) {
Map<String, Object> resp = dispatcher.runSync(fulfillmentService, serviceCtx);
if (ServiceUtil.isError(resp)) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "OrderOrderExternalFulfillmentError", locale), null, null, resp);
}
}
} catch (GenericServiceException e) {
Debug.logError(e, "ERROR: Could not run external fulfillment service '" + fulfillmentService + "'; " + e.getMessage(), module);
}
} else if ("FULFILLMENT_EMAIL".equals(fulfillmentType)) {
// TODO: Add support for fulfillment email
return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderEmailFulfillmentTypeNotYetImplemented", locale));
} else if ("DIGITAL_DOWNLOAD".equals(fulfillmentType)) {
// digital download fulfillment
// Nothing to do for here. Downloads are made available to the user
// though a query of OrderItems with related ProductContent.
} else {
Debug.logError("Invalid fulfillment type : " + fulfillmentType + " not supported.", module);
}
}
}
}
}
return ServiceUtil.returnSuccess();
}
use of org.apache.ofbiz.entity.condition.EntityExpr in project ofbiz-framework by apache.
the class OrderServices method setEmptyGrandTotals.
/**
* Service for setting the OrderHeader grandTotal for all OrderHeaders with no grandTotal
*/
public static Map<String, Object> setEmptyGrandTotals(DispatchContext ctx, Map<String, ? extends Object> context) {
Delegator delegator = ctx.getDelegator();
LocalDispatcher dispatcher = ctx.getDispatcher();
GenericValue userLogin = (GenericValue) context.get("userLogin");
Boolean forceAll = (Boolean) context.get("forceAll");
Locale locale = (Locale) context.get("locale");
if (forceAll == null) {
forceAll = Boolean.FALSE;
}
EntityCondition cond = null;
if (!forceAll.booleanValue()) {
List<EntityExpr> exprs = UtilMisc.toList(EntityCondition.makeCondition("grandTotal", EntityOperator.EQUALS, null), EntityCondition.makeCondition("remainingSubTotal", EntityOperator.EQUALS, null));
cond = EntityCondition.makeCondition(exprs, EntityOperator.OR);
}
try (EntityListIterator eli = EntityQuery.use(delegator).select("orderId").from("OrderHeader").where(cond).queryIterator()) {
if (eli != null) {
// reset each order
GenericValue orderHeader = null;
while ((orderHeader = eli.next()) != null) {
String orderId = orderHeader.getString("orderId");
Map<String, Object> resetResult = null;
try {
resetResult = dispatcher.runSync("resetGrandTotal", UtilMisc.<String, Object>toMap("orderId", orderId, "userLogin", userLogin));
if (ServiceUtil.isError(resetResult)) {
return ServiceUtil.returnError(ServiceUtil.getErrorMessage(resetResult));
}
} catch (GenericServiceException e) {
Debug.logError(e, "ERROR: Cannot reset order totals - " + orderId, module);
}
if (resetResult != null && ServiceUtil.isError(resetResult)) {
Debug.logWarning(UtilProperties.getMessage(resource_error, "OrderErrorCannotResetOrderTotals", UtilMisc.toMap("orderId", orderId, "resetResult", ServiceUtil.getErrorMessage(resetResult)), locale), module);
} else {
Debug.logInfo("No orders found for reset processing", module);
}
}
}
} catch (GenericEntityException e) {
Debug.logError(e, module);
}
return ServiceUtil.returnSuccess();
}
use of org.apache.ofbiz.entity.condition.EntityExpr in project ofbiz-framework by apache.
the class OrderServices method createAlsoBoughtProductAssocs.
public static Map<String, Object> createAlsoBoughtProductAssocs(DispatchContext dctx, Map<String, ? extends Object> context) {
final Delegator delegator = dctx.getDelegator();
LocalDispatcher dispatcher = dctx.getDispatcher();
// All orders with an entryDate > orderEntryFromDateTime will be processed
Timestamp orderEntryFromDateTime = (Timestamp) context.get("orderEntryFromDateTime");
// If true all orders ever created will be processed and any pre-existing ALSO_BOUGHT ProductAssocs will be expired
boolean processAllOrders = context.get("processAllOrders") == null ? false : (Boolean) context.get("processAllOrders");
if (orderEntryFromDateTime == null && !processAllOrders) {
// No from date supplied, check to see when this service last ran and use the startDateTime
// FIXME: This code is unreliable - the JobSandbox value might have been purged. Use another mechanism to persist orderEntryFromDateTime.
EntityCondition cond = EntityCondition.makeCondition(UtilMisc.toMap("statusId", "SERVICE_FINISHED", "serviceName", "createAlsoBoughtProductAssocs"));
EntityFindOptions efo = new EntityFindOptions();
efo.setMaxRows(1);
try {
GenericValue lastRunJobSandbox = EntityUtil.getFirst(delegator.findList("JobSandbox", cond, null, UtilMisc.toList("startDateTime DESC"), efo, false));
if (lastRunJobSandbox != null) {
orderEntryFromDateTime = lastRunJobSandbox.getTimestamp("startDateTime");
}
} catch (GenericEntityException e) {
Debug.logError(e, module);
}
if (orderEntryFromDateTime == null) {
// Still null, process all orders
processAllOrders = true;
}
}
if (processAllOrders) {
// Expire any pre-existing ALSO_BOUGHT ProductAssocs in preparation for reprocessing
EntityCondition cond = EntityCondition.makeCondition(UtilMisc.toList(EntityCondition.makeCondition("productAssocTypeId", "ALSO_BOUGHT"), EntityCondition.makeConditionDate("fromDate", "thruDate")));
try {
delegator.storeByCondition("ProductAssoc", UtilMisc.toMap("thruDate", UtilDateTime.nowTimestamp()), cond);
} catch (GenericEntityException e) {
Debug.logError(e, module);
}
}
List<EntityExpr> orderCondList = UtilMisc.toList(EntityCondition.makeCondition("orderTypeId", "SALES_ORDER"));
if (!processAllOrders && orderEntryFromDateTime != null) {
orderCondList.add(EntityCondition.makeCondition("entryDate", EntityOperator.GREATER_THAN, orderEntryFromDateTime));
}
final EntityCondition cond = EntityCondition.makeCondition(orderCondList);
List<String> orderIds;
try {
orderIds = TransactionUtil.doNewTransaction(new Callable<List<String>>() {
@Override
public List<String> call() throws Exception {
List<String> orderIds = new LinkedList<>();
EntityQuery eq = EntityQuery.use(delegator).select("orderId").from("OrderHeader").where(cond).orderBy("entryDate ASC");
try (EntityListIterator eli = eq.queryIterator()) {
GenericValue orderHeader;
while ((orderHeader = eli.next()) != null) {
orderIds.add(orderHeader.getString("orderId"));
}
}
return orderIds;
}
}, "getSalesOrderIds", 0, true);
} catch (GenericEntityException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(e.getMessage());
}
for (String orderId : orderIds) {
Map<String, Object> svcIn = new HashMap<>();
svcIn.put("userLogin", context.get("userLogin"));
svcIn.put("orderId", orderId);
try {
Map<String, Object> serviceResult = dispatcher.runSync("createAlsoBoughtProductAssocsForOrder", svcIn);
if (ServiceUtil.isError(serviceResult)) {
return ServiceUtil.returnError(ServiceUtil.getErrorMessage(serviceResult));
}
} catch (GenericServiceException e) {
Debug.logError(e, module);
}
}
return ServiceUtil.returnSuccess();
}
use of org.apache.ofbiz.entity.condition.EntityExpr in project ofbiz-framework by apache.
the class RequirementServices method createATPRequirementsForOrder.
// note that this service is designed to work only when a sales order status changes from CREATED -> APPROVED because HOLD -> APPROVED is too complex
public static Map<String, Object> createATPRequirementsForOrder(DispatchContext ctx, Map<String, ? extends Object> context) {
Delegator delegator = ctx.getDelegator();
LocalDispatcher dispatcher = ctx.getDispatcher();
GenericValue userLogin = (GenericValue) context.get("userLogin");
/*
* The strategy in this service is to begin making requirements when the product falls below the
* ProductFacility.minimumStock. Because the minimumStock is an upper bound, the quantity to be required
* is either that required to bring the ATP back up to the minimumStock level or the amount ordered,
* whichever is less.
*
* If there is a way to support reorderQuantity without losing the order item -> requirement association data,
* then this service should be updated.
*
* The result is that this service generates many small requirements when stock levels are low for a product,
* which is perfectly fine since the system is capable of creating POs in bulk from aggregate requirements.
* The only concern would be a UI to manage numerous requirements with ease, preferrably by aggregating
* on productId.
*/
String orderId = (String) context.get("orderId");
try {
GenericValue order = EntityQuery.use(delegator).from("OrderHeader").where("orderId", orderId).queryOne();
GenericValue productStore = order.getRelatedOne("ProductStore", true);
if (productStore == null) {
Debug.logInfo("ProductStore for order ID " + orderId + " not found, ATP requirements not created", module);
return ServiceUtil.returnSuccess();
}
String facilityId = productStore.getString("inventoryFacilityId");
List<GenericValue> orderItems = order.getRelated("OrderItem", null, null, false);
for (GenericValue item : orderItems) {
GenericValue product = item.getRelatedOne("Product", false);
if (product == null)
continue;
if (!("PRODRQM_ATP".equals(product.get("requirementMethodEnumId")) || ("PRODRQM_ATP".equals(productStore.get("requirementMethodEnumId")) && product.get("requirementMethodEnumId") == null)))
continue;
BigDecimal quantity = item.getBigDecimal("quantity");
BigDecimal cancelQuantity = item.getBigDecimal("cancelQuantity");
BigDecimal ordered = quantity.subtract(cancelQuantity == null ? BigDecimal.ZERO : cancelQuantity);
if (ordered.compareTo(BigDecimal.ZERO) <= 0)
continue;
// get the minimum stock for this facility (if not configured assume a minimum of zero, ie create requirements when it goes into backorder)
GenericValue productFacility = EntityQuery.use(delegator).from("ProductFacility").where("facilityId", facilityId, "productId", product.get("productId")).queryOne();
BigDecimal minimumStock = BigDecimal.ZERO;
if (productFacility != null && productFacility.get("minimumStock") != null) {
minimumStock = productFacility.getBigDecimal("minimumStock");
}
// get the facility ATP for product, which should be updated for this item's reservation
Map<String, Object> results = dispatcher.runSync("getInventoryAvailableByFacility", UtilMisc.toMap("userLogin", userLogin, "productId", product.get("productId"), "facilityId", facilityId));
if (ServiceUtil.isError(results)) {
return ServiceUtil.returnError(ServiceUtil.getErrorMessage(results));
}
// safe since this is a required OUT param
BigDecimal atp = ((BigDecimal) results.get("availableToPromiseTotal"));
// count all current requirements for this product
BigDecimal pendingRequirements = BigDecimal.ZERO;
EntityConditionList<EntityExpr> ecl = EntityCondition.makeCondition(UtilMisc.toList(EntityCondition.makeCondition("facilityId", EntityOperator.EQUALS, facilityId), EntityCondition.makeCondition("productId", EntityOperator.EQUALS, product.get("productId")), EntityCondition.makeCondition("requirementTypeId", EntityOperator.EQUALS, "PRODUCT_REQUIREMENT"), EntityCondition.makeCondition("statusId", EntityOperator.NOT_EQUAL, "REQ_ORDERED"), EntityCondition.makeCondition("statusId", EntityOperator.NOT_EQUAL, "REQ_REJECTED")), EntityOperator.AND);
List<GenericValue> requirements = EntityQuery.use(delegator).from("Requirement").where(ecl).queryList();
for (GenericValue requirement : requirements) {
pendingRequirements = pendingRequirements.add(requirement.get("quantity") == null ? BigDecimal.ZERO : requirement.getBigDecimal("quantity"));
}
// the minimum stock is an upper bound, therefore we either require up to the minimum stock or the input required quantity, whichever is less
BigDecimal shortfall = minimumStock.subtract(atp).subtract(pendingRequirements);
BigDecimal required = ordered.compareTo(shortfall) < 0 ? ordered : shortfall;
if (required.compareTo(BigDecimal.ZERO) <= 0)
continue;
Map<String, Object> input = UtilMisc.toMap("userLogin", userLogin, "facilityId", facilityId, "productId", product.get("productId"), "quantity", required, "requirementTypeId", "PRODUCT_REQUIREMENT");
results = dispatcher.runSync("createRequirement", input);
if (ServiceUtil.isError(results)) {
return ServiceUtil.returnError(ServiceUtil.getErrorMessage(results));
}
String requirementId = (String) results.get("requirementId");
input = UtilMisc.toMap("userLogin", userLogin, "orderId", order.get("orderId"), "orderItemSeqId", item.get("orderItemSeqId"), "requirementId", requirementId, "quantity", required);
results = dispatcher.runSync("createOrderRequirementCommitment", input);
if (ServiceUtil.isError(results)) {
return ServiceUtil.returnError(ServiceUtil.getErrorMessage(results));
}
}
} catch (GenericEntityException e) {
Debug.logError(e, module);
} catch (GenericServiceException e) {
Debug.logError(e, module);
}
return ServiceUtil.returnSuccess();
}
Aggregations