Map<String, Object> actionResult;
try {
actionResult = dispatcher.runSync(serviceName, serviceCtx);
} catch (GenericServiceException e) {
Debug.logError("Error calling promo action service [" + serviceName + "]", module);
throw new CartItemModifyException("Error calling promo action service [" + serviceName + "]", e);
}
if (ServiceUtil.isError(actionResult)) {
Debug.logError("Error calling promo action service [" + serviceName + "], result is: " + actionResult, module);
throw new CartItemModifyException((String) actionResult.get(ModelService.ERROR_MESSAGE));
}
CartItemModifyException cartItemModifyException = (CartItemModifyException) actionResult.get("cartItemModifyException");
if (cartItemModifyException != null) {
throw cartItemModifyException;
}
} else if ("PROMO_GWP".equals(productPromoActionEnumId)) {
String productStoreId = cart.getProductStoreId();
// the code was in there for this, so even though I don't think we want to restrict this, just adding this flag to make it easy to change; could make option dynamic, but now implied by the use limit
boolean allowMultipleGwp = true;
Integer itemLoc = findPromoItem(productPromoAction, cart);
if (!allowMultipleGwp && itemLoc != null) {
if (Debug.verboseOn()) Debug.logVerbose("Not adding promo item, already there; action: " + productPromoAction, module);
actionResultInfo.ranAction = false;
} else {
BigDecimal quantity;
if (productPromoAction.get("quantity") != null) {
quantity = productPromoAction.getBigDecimal("quantity");
} else {
if ("Y".equals(productPromoAction.get("useCartQuantity"))) {
quantity = BigDecimal.ZERO;
List<ShoppingCartItem> used = getCartItemsUsed(cart, productPromoAction);
Iterator<ShoppingCartItem> usedIt = used.iterator();
while (usedIt.hasNext()) {
ShoppingCartItem item = usedIt.next();
BigDecimal available = item.getPromoQuantityAvailable();
quantity = quantity.add(available).add(item.getPromoQuantityCandidateUseActionAndAllConds(productPromoAction));
item.addPromoQuantityCandidateUse(available, productPromoAction, false);
}
} else {
quantity = BigDecimal.ZERO;
}
}
List<String> optionProductIds = FastList.newInstance();
String productId = productPromoAction.getString("productId");
GenericValue product = null;
if (UtilValidate.isNotEmpty(productId)) {
// Debug.logInfo("======== Got GWP productId [" + productId + "]", module);
product = delegator.findByPrimaryKeyCache("Product", UtilMisc.toMap("productId", productId));
if (product == null) {
String errMsg = "GWP Product not found with ID [" + productId + "] for ProductPromoAction [" + productPromoAction.get("productPromoId") + ":" + productPromoAction.get("productPromoRuleId") + ":" + productPromoAction.get("productPromoActionSeqId") + "]";
Debug.logError(errMsg, module);
throw new CartItemModifyException(errMsg);
}
if ("Y".equals(product.getString("isVirtual"))) {
List<GenericValue> productAssocs = EntityUtil.filterByDate(product.getRelatedCache("MainProductAssoc",
UtilMisc.toMap("productAssocTypeId", "PRODUCT_VARIANT"), UtilMisc.toList("sequenceNum")));
Iterator<GenericValue> productAssocIter = productAssocs.iterator();
while (productAssocIter.hasNext()) {
GenericValue productAssoc = productAssocIter.next();
optionProductIds.add(productAssoc.getString("productIdTo"));
}
productId = null;
product = null;
// Debug.logInfo("======== GWP productId [" + productId + "] is a virtual with " + productAssocs.size() + " variants", module);
} else {
// check inventory on this product, make sure it is available before going on
//NOTE: even though the store may not require inventory for purchase, we will always require inventory for gifts
try {
// get the quantity in cart for inventory check
BigDecimal quantityAlreadyInCart = BigDecimal.ZERO;
if (cart != null) {
List<ShoppingCartItem> matchingItems = cart.findAllCartItems(productId);
for (ShoppingCartItem item : matchingItems) {
quantityAlreadyInCart = quantityAlreadyInCart.add(item.getQuantity());
}
}
Map<String, Object> invReqResult = dispatcher.runSync("isStoreInventoryAvailable", UtilMisc.<String, Object>toMap("productStoreId", productStoreId, "productId", productId, "product", product, "quantity", quantity.add(quantityAlreadyInCart)));
if (ServiceUtil.isError(invReqResult)) {
Debug.logError("Error calling isStoreInventoryAvailable service, result is: " + invReqResult, module);
throw new CartItemModifyException((String) invReqResult.get(ModelService.ERROR_MESSAGE));
} else if (!"Y".equals((String) invReqResult.get("available"))) {
Debug.logWarning(UtilProperties.getMessage(resource_error,"OrderNotApplyingGwpBecauseProductIdIsOutOfStockForProductPromoAction", UtilMisc.toMap("productId", productId, "productPromoAction", productPromoAction), cart.getLocale()), module);
productId = null;
product = null;
}
} catch (GenericServiceException e) {
String errMsg = "Fatal error calling inventory checking services: " + e.toString();
Debug.logError(e, errMsg, module);
throw new CartItemModifyException(errMsg);
}
}
}
// support multiple gift options if products are attached to the action, or if the productId on the action is a virtual product
Set<String> productIds = ProductPromoWorker.getPromoRuleActionProductIds(productPromoAction, delegator, nowTimestamp);
if (productIds != null) {
optionProductIds.addAll(productIds);
}
// make sure these optionProducts have inventory...
Iterator<String> optionProductIdIter = optionProductIds.iterator();
while (optionProductIdIter.hasNext()) {
String optionProductId = optionProductIdIter.next();
try {
// get the quantity in cart for inventory check
BigDecimal quantityAlreadyInCart = BigDecimal.ZERO;
if (cart != null) {
List<ShoppingCartItem> matchingItems = cart.findAllCartItems(optionProductId);
for (ShoppingCartItem item : matchingItems) {
quantityAlreadyInCart = quantityAlreadyInCart.add(item.getQuantity());
}
}
Map<String, Object> invReqResult = dispatcher.runSync("isStoreInventoryAvailable", UtilMisc.<String, Object>toMap("productStoreId", productStoreId, "productId", optionProductId, "product", product, "quantity", quantity.add(quantityAlreadyInCart)));
if (ServiceUtil.isError(invReqResult)) {
Debug.logError("Error calling isStoreInventoryAvailable service, result is: " + invReqResult, module);
throw new CartItemModifyException((String) invReqResult.get(ModelService.ERROR_MESSAGE));
} else if (!"Y".equals((String) invReqResult.get("available"))) {
optionProductIdIter.remove();
}
} catch (GenericServiceException e) {
String errMsg = "Fatal error calling inventory checking services: " + e.toString();
Debug.logError(e, errMsg, module);
throw new CartItemModifyException(errMsg);
}
}
// check to see if any desired productIds have been selected for this promo action
String alternateGwpProductId = cart.getDesiredAlternateGiftByAction(productPromoAction.getPrimaryKey());