Java tutorial
/******************************************************************************* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. *******************************************************************************/ package org.ofbiz.order.order; import java.math.BigDecimal; import java.lang.String; import java.sql.Timestamp; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.TimeZone; import java.util.TreeSet; import java.util.concurrent.Callable; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import javax.transaction.Transaction; import javolution.util.FastList; import javolution.util.FastMap; import javolution.util.FastSet; import org.ofbiz.order.shoppingcart.ShoppingCartEvents; import org.ofbiz.base.conversion.ConversionException; import org.ofbiz.base.conversion.DateTimeConverters; import org.ofbiz.base.util.Debug; import org.ofbiz.base.util.GeneralException; import org.ofbiz.base.util.GeneralRuntimeException; import org.ofbiz.base.util.UtilDateTime; import org.ofbiz.base.util.UtilHttp; import org.ofbiz.base.util.UtilFormatOut; import org.ofbiz.base.util.UtilGenerics; import org.ofbiz.base.util.UtilMisc; import org.ofbiz.base.util.UtilNumber; import org.ofbiz.base.util.UtilProperties; import org.ofbiz.base.util.UtilValidate; import org.ofbiz.common.DataModelConstants; import org.ofbiz.entity.Delegator; import org.ofbiz.entity.GenericEntity; import org.ofbiz.entity.GenericEntityException; import org.ofbiz.entity.GenericValue; import org.ofbiz.entity.condition.EntityCondition; import org.ofbiz.entity.condition.EntityConditionList; import org.ofbiz.entity.condition.EntityExpr; import org.ofbiz.entity.condition.EntityOperator; import org.ofbiz.entity.transaction.GenericTransactionException; import org.ofbiz.entity.transaction.TransactionUtil; import org.ofbiz.entity.util.EntityFindOptions; import org.ofbiz.entity.util.EntityListIterator; import org.ofbiz.entity.util.EntityTypeUtil; import org.ofbiz.entity.util.EntityUtil; import org.ofbiz.order.shoppingcart.CartItemModifyException; import org.ofbiz.order.shoppingcart.CheckOutHelper; import org.ofbiz.order.shoppingcart.ItemNotFoundException; import org.ofbiz.order.shoppingcart.ShoppingCart; import org.ofbiz.order.shoppingcart.ShoppingCartItem; import org.ofbiz.order.shoppingcart.product.ProductPromoWorker; import org.ofbiz.order.shoppingcart.shipping.ShippingEvents; import org.ofbiz.party.contact.ContactHelper; import org.ofbiz.party.contact.ContactMechWorker; import org.ofbiz.party.party.PartyWorker; import org.ofbiz.product.config.ProductConfigWrapper; import org.ofbiz.product.price.PriceServices; import org.ofbiz.product.product.ProductWorker; import org.ofbiz.product.store.ProductStoreWorker; import org.ofbiz.security.Security; import org.ofbiz.service.DispatchContext; import org.ofbiz.service.GeneralServiceException; import org.ofbiz.service.GenericServiceException; import org.ofbiz.service.LocalDispatcher; import org.ofbiz.service.ModelService; import org.ofbiz.service.ServiceUtil; import org.ofbiz.order.shoppingcart.ShoppingCart; import org.ofbiz.order.shoppingcart.ShoppingCartEvents; import com.ibm.icu.util.Calendar; import org.ofbiz.base.util.Debug; import org.apache.commons.lang.StringUtils; /** * Order Processing Services */ public class OrderServices { public static final String module = OrderServices.class.getName(); public static final String resource = "OrderUiLabels"; public static final String resource_error = "OrderErrorUiLabels"; public static final String resourceProduct = "ProductUiLabels"; public static Map<String, String> salesAttributeRoleMap = FastMap.newInstance(); public static Map<String, String> purchaseAttributeRoleMap = FastMap.newInstance(); static { salesAttributeRoleMap.put("placingCustomerPartyId", "PLACING_CUSTOMER"); salesAttributeRoleMap.put("billToCustomerPartyId", "BILL_TO_CUSTOMER"); salesAttributeRoleMap.put("billFromVendorPartyId", "BILL_FROM_VENDOR"); salesAttributeRoleMap.put("shipToCustomerPartyId", "SHIP_TO_CUSTOMER"); /* salesAttributeRoleMap.put("endUserCustomerPartyId", "END_USER_CUSTOMER"); */ purchaseAttributeRoleMap.put("billToCustomerPartyId", "BILL_TO_CUSTOMER"); purchaseAttributeRoleMap.put("billFromVendorPartyId", "BILL_FROM_VENDOR"); purchaseAttributeRoleMap.put("shipFromVendorPartyId", "SHIP_FROM_VENDOR"); purchaseAttributeRoleMap.put("supplierAgentPartyId", "SUPPLIER_AGENT"); purchaseAttributeRoleMap.put("shipToCustomerPartyId", "SHIP_TO_CUSTOMER"); } public static final int taxDecimals = UtilNumber.getBigDecimalScale("salestax.calc.decimals"); public static final int taxRounding = UtilNumber.getBigDecimalRoundingMode("salestax.rounding"); public static final int orderDecimals = UtilNumber.getBigDecimalScale("order.decimals"); public static final int orderRounding = UtilNumber.getBigDecimalRoundingMode("order.rounding"); public static final BigDecimal ZERO = BigDecimal.ZERO.setScale(taxDecimals, taxRounding); private static boolean hasPermission(String orderId, GenericValue userLogin, String action, Security security, Delegator delegator) { OrderReadHelper orh = new OrderReadHelper(delegator, orderId); String orderTypeId = orh.getOrderTypeId(); String partyId = null; GenericValue orderParty = orh.getEndUserParty(); if (UtilValidate.isEmpty(orderParty)) { orderParty = orh.getPlacingParty(); } if (UtilValidate.isNotEmpty(orderParty)) { partyId = orderParty.getString("partyId"); } boolean hasPermission = hasPermission(orderTypeId, partyId, userLogin, action, security); if (!hasPermission) { GenericValue placingCustomer = null; try { Map<String, Object> placingCustomerFields = UtilMisc.<String, Object>toMap("orderId", orderId, "partyId", userLogin.getString("partyId"), "roleTypeId", "PLACING_CUSTOMER"); placingCustomer = delegator.findByPrimaryKey("OrderRole", placingCustomerFields); } catch (GenericEntityException e) { Debug.logError("Could not select OrderRoles for order " + orderId + " due to " + e.getMessage(), module); } hasPermission = (placingCustomer != null); } return hasPermission; } private static boolean hasPermission(String orderTypeId, String partyId, GenericValue userLogin, String action, Security security) { boolean hasPermission = security.hasEntityPermission("ORDERMGR", "_" + action, userLogin); if (!hasPermission) { if (orderTypeId.equals("SALES_ORDER")) { if (security.hasEntityPermission("ORDERMGR", "_SALES_" + action, userLogin)) { hasPermission = true; } else { // check sales agent/customer relationship List<GenericValue> repsCustomers = new LinkedList<GenericValue>(); try { repsCustomers = EntityUtil.filterByDate(userLogin.getRelatedOne("Party") .getRelatedByAnd("FromPartyRelationship", UtilMisc.toMap("roleTypeIdFrom", "AGENT", "roleTypeIdTo", "CUSTOMER", "partyIdTo", partyId))); } catch (GenericEntityException ex) { Debug.logError( "Could not determine if " + partyId + " is a customer of user " + userLogin.getString("userLoginId") + " due to " + ex.getMessage(), module); } if ((repsCustomers != null) && (repsCustomers.size() > 0) && (security.hasEntityPermission("ORDERMGR", "_ROLE_" + action, userLogin))) { hasPermission = true; } if (!hasPermission) { // check sales sales rep/customer relationship try { repsCustomers = EntityUtil.filterByDate(userLogin.getRelatedOne("Party") .getRelatedByAnd("FromPartyRelationship", UtilMisc.toMap("roleTypeIdFrom", "SALES_REP", "roleTypeIdTo", "CUSTOMER", "partyIdTo", partyId))); } catch (GenericEntityException ex) { Debug.logError( "Could not determine if " + partyId + " is a customer of user " + userLogin.getString("userLoginId") + " due to " + ex.getMessage(), module); } if ((repsCustomers != null) && (repsCustomers.size() > 0) && (security.hasEntityPermission("ORDERMGR", "_ROLE_" + action, userLogin))) { hasPermission = true; } } } } else if ((orderTypeId.equals("PURCHASE_ORDER") && (security.hasEntityPermission("ORDERMGR", "_PURCHASE_" + action, userLogin)))) { hasPermission = true; } } return hasPermission; } /** Service for creating a new order */ public static Map<String, Object> createOrder(DispatchContext ctx, Map<String, ? extends Object> context) { Delegator delegator = ctx.getDelegator(); LocalDispatcher dispatcher = ctx.getDispatcher(); Security security = ctx.getSecurity(); List<GenericValue> toBeStored = new LinkedList<GenericValue>(); Locale locale = (Locale) context.get("locale"); Map<String, Object> successResult = ServiceUtil.returnSuccess(); GenericValue userLogin = (GenericValue) context.get("userLogin"); // get the order type String orderTypeId = (String) context.get("orderTypeId"); String partyId = (String) context.get("partyId"); String billFromVendorPartyId = (String) context.get("billFromVendorPartyId"); // check security permissions for order: // SALES ORDERS - if userLogin has ORDERMGR_SALES_CREATE or ORDERMGR_CREATE permission, or if it is same party as the partyId, or // if it is an AGENT (sales rep) creating an order for his customer // PURCHASE ORDERS - if there is a PURCHASE_ORDER permission Map<String, Object> resultSecurity = new HashMap<String, Object>(); boolean hasPermission = OrderServices.hasPermission(orderTypeId, partyId, userLogin, "CREATE", security); // final check - will pass if userLogin's partyId = partyId for order or if userLogin has ORDERMGR_CREATE permission // jacopoc: what is the meaning of this code block? FIXME if (!hasPermission) { partyId = ServiceUtil.getPartyIdCheckSecurity(userLogin, security, context, resultSecurity, "ORDERMGR", "_CREATE"); if (resultSecurity.size() > 0) { return resultSecurity; } } // get the product store for the order, but it is required only for sales orders String productStoreId = (String) context.get("productStoreId"); GenericValue productStore = null; if ((orderTypeId.equals("SALES_ORDER")) && (UtilValidate.isNotEmpty(productStoreId))) { try { productStore = delegator.findByPrimaryKeyCache("ProductStore", UtilMisc.toMap("productStoreId", productStoreId)); } catch (GenericEntityException e) { return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderErrorCouldNotFindProductStoreWithID", UtilMisc.toMap("productStoreId", productStoreId), locale) + e.toString()); } } // figure out if the order is immediately fulfilled based on product store settings boolean isImmediatelyFulfilled = false; if (productStore != null) { isImmediatelyFulfilled = "Y".equals(productStore.getString("isImmediatelyFulfilled")); } successResult.put("orderTypeId", orderTypeId); // lookup the order type entity GenericValue orderType = null; try { orderType = delegator.findByPrimaryKeyCache("OrderType", UtilMisc.toMap("orderTypeId", orderTypeId)); } catch (GenericEntityException e) { return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderErrorOrderTypeLookupFailed", locale) + e.toString()); } // make sure we have a valid order type if (orderType == null) { return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderErrorInvalidOrderTypeWithID", UtilMisc.toMap("orderTypeId", orderTypeId), locale)); } // check to make sure we have something to order List<GenericValue> orderItems = UtilGenerics.checkList(context.get("orderItems")); if (orderItems.size() < 1) { return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "items.none", locale)); } // all this marketing pkg auto stuff is deprecated in favor of MARKETING_PKG_AUTO productTypeId and a BOM of MANUF_COMPONENT assocs // these need to be retrieved now because they might be needed for exploding MARKETING_PKG_AUTO List<GenericValue> orderAdjustments = UtilGenerics.checkList(context.get("orderAdjustments")); List<GenericValue> orderItemShipGroupInfo = UtilGenerics.checkList(context.get("orderItemShipGroupInfo")); List<GenericValue> orderItemPriceInfo = UtilGenerics.checkList(context.get("orderItemPriceInfos")); // check inventory and other things for each item List<String> errorMessages = FastList.newInstance(); Map<String, BigDecimal> normalizedItemQuantities = FastMap.newInstance(); Map<String, String> normalizedItemNames = FastMap.newInstance(); Map<String, GenericValue> itemValuesBySeqId = FastMap.newInstance(); Iterator<GenericValue> itemIter = orderItems.iterator(); Timestamp nowTimestamp = UtilDateTime.nowTimestamp(); // // need to run through the items combining any cases where multiple lines refer to the // same product so the inventory check will work correctly // also count quantities ordered while going through the loop while (itemIter.hasNext()) { GenericValue orderItem = itemIter.next(); // start by putting it in the itemValuesById Map itemValuesBySeqId.put(orderItem.getString("orderItemSeqId"), orderItem); String currentProductId = orderItem.getString("productId"); if (currentProductId != null) { // only normalize items with a product associated (ignore non-product items) if (normalizedItemQuantities.get(currentProductId) == null) { normalizedItemQuantities.put(currentProductId, orderItem.getBigDecimal("quantity")); normalizedItemNames.put(currentProductId, orderItem.getString("itemDescription")); } else { BigDecimal currentQuantity = normalizedItemQuantities.get(currentProductId); normalizedItemQuantities.put(currentProductId, currentQuantity.add(orderItem.getBigDecimal("quantity"))); } /* try { // count product ordered quantities // run this synchronously so it will run in the same transaction dispatcher.runSync("countProductQuantityOrdered", UtilMisc.<String, Object>toMap("productId", currentProductId, "quantity", orderItem.getBigDecimal("quantity"), "userLogin", userLogin)); } catch (GenericServiceException e1) { Debug.logError(e1, "Error calling countProductQuantityOrdered service", module); return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderErrorCallingCountProductQuantityOrderedService",locale) + e1.toString()); }*/ } } if (!"PURCHASE_ORDER".equals(orderTypeId) && productStoreId == null) { return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderErrorTheProductStoreIdCanOnlyBeNullForPurchaseOrders", locale)); } Timestamp orderDate = (Timestamp) context.get("orderDate"); Iterator<String> normalizedIter = normalizedItemQuantities.keySet().iterator(); while (normalizedIter.hasNext()) { // lookup the product entity for each normalized item; error on products not found String currentProductId = normalizedIter.next(); BigDecimal currentQuantity = normalizedItemQuantities.get(currentProductId); String itemName = normalizedItemNames.get(currentProductId); GenericValue product = null; try { product = delegator.findByPrimaryKeyCache("Product", UtilMisc.toMap("productId", currentProductId)); } catch (GenericEntityException e) { String errMsg = UtilProperties.getMessage(resource_error, "product.not_found", new Object[] { currentProductId }, locale); Debug.logError(e, errMsg, module); errorMessages.add(errMsg); continue; } if (product == null) { String errMsg = UtilProperties.getMessage(resource_error, "product.not_found", new Object[] { currentProductId }, locale); Debug.logError(errMsg, module); errorMessages.add(errMsg); continue; } if ("SALES_ORDER".equals(orderTypeId)) { // check to see if introductionDate hasn't passed yet if (product.get("introductionDate") != null && nowTimestamp.before(product.getTimestamp("introductionDate"))) { String excMsg = UtilProperties.getMessage(resource_error, "product.not_yet_for_sale", new Object[] { getProductName(product, itemName), product.getString("productId") }, locale); Debug.logWarning(excMsg, module); errorMessages.add(excMsg); continue; } } if ("SALES_ORDER".equals(orderTypeId)) { boolean salesDiscontinuationFlag = false; // When past orders are imported, they should be imported even if sales discontinuation date is in the past but if the order date was before it if (orderDate != null && product.get("salesDiscontinuationDate") != null) { salesDiscontinuationFlag = orderDate.after(product.getTimestamp("salesDiscontinuationDate")) && nowTimestamp.after(product.getTimestamp("salesDiscontinuationDate")); } else if (product.get("salesDiscontinuationDate") != null) { salesDiscontinuationFlag = nowTimestamp.after(product.getTimestamp("salesDiscontinuationDate")); } // check to see if salesDiscontinuationDate has passed if (salesDiscontinuationFlag) { String excMsg = UtilProperties.getMessage(resource_error, "product.no_longer_for_sale", new Object[] { getProductName(product, itemName), product.getString("productId") }, locale); Debug.logWarning(excMsg, module); errorMessages.add(excMsg); continue; } } if ("SALES_ORDER".equals(orderTypeId)) { // check to see if we have inventory available try { Map<String, Object> invReqResult = dispatcher.runSync("isStoreInventoryAvailableOrNotRequired", UtilMisc.toMap("productStoreId", productStoreId, "productId", product.get("productId"), "product", product, "quantity", currentQuantity)); if (ServiceUtil.isError(invReqResult)) { errorMessages.add((String) invReqResult.get(ModelService.ERROR_MESSAGE)); List<String> errMsgList = UtilGenerics .checkList(invReqResult.get(ModelService.ERROR_MESSAGE_LIST)); errorMessages.addAll(errMsgList); } else if (!"Y".equals(invReqResult.get("availableOrNotRequired"))) { String invErrMsg = UtilProperties.getMessage(resource_error, "product.out_of_stock", new Object[] { getProductName(product, itemName), currentProductId }, locale); Debug.logWarning(invErrMsg, module); errorMessages.add(invErrMsg); continue; } } catch (GenericServiceException e) { String errMsg = "Fatal error calling inventory checking services: " + e.toString(); Debug.logError(e, errMsg, module); errorMessages.add(errMsg); } } } // add the fixedAsset id to the workefforts map by obtaining the fixed Asset number from the FixedAssetProduct table List<GenericValue> workEfforts = UtilGenerics.checkList(context.get("workEfforts")); // is an optional parameter from this service but mandatory for rental items Iterator<GenericValue> orderItemIter = orderItems.iterator(); while (orderItemIter.hasNext()) { GenericValue orderItem = orderItemIter.next(); if ("RENTAL_ORDER_ITEM".equals(orderItem.getString("orderItemTypeId"))) { // check to see if workefforts are available for this order type. if (UtilValidate.isEmpty(workEfforts)) { String errMsg = "Work Efforts missing for ordertype RENTAL_ORDER_ITEM " + "Product: " + orderItem.getString("productId"); Debug.logError(errMsg, module); errorMessages.add(errMsg); return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderRentalOrderItems", locale)); } Iterator<GenericValue> we = workEfforts.iterator(); // find the related workEffortItem (workEffortId = orderSeqId) while (we.hasNext()) { // create the entity maps required. GenericValue workEffort = we.next(); if (workEffort.getString("workEffortId").equals(orderItem.getString("orderItemSeqId"))) { List<GenericValue> selFixedAssetProduct = null; try { List<GenericValue> allFixedAssetProduct = delegator.findByAnd("FixedAssetProduct", UtilMisc.toMap("productId", orderItem.getString("productId"), "fixedAssetProductTypeId", "FAPT_USE")); selFixedAssetProduct = EntityUtil.filterByDate(allFixedAssetProduct, nowTimestamp, "fromDate", "thruDate", true); } catch (GenericEntityException e) { String excMsg = "Could not find related Fixed Asset for the product: " + orderItem.getString("productId"); Debug.logError(excMsg, module); errorMessages.add(excMsg); return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderCouldNotFindRelatedFixedAssetForTheProduct", UtilMisc.toMap("productId", orderItem.getString("productId")), locale)); } if (UtilValidate.isNotEmpty(selFixedAssetProduct)) { Iterator<GenericValue> firstOne = selFixedAssetProduct.iterator(); if (firstOne.hasNext()) { GenericValue fixedAssetProduct = delegator.makeValue("FixedAssetProduct"); fixedAssetProduct = firstOne.next(); workEffort.set("fixedAssetId", fixedAssetProduct.get("fixedAssetId")); workEffort.set("quantityToProduce", orderItem.get("quantity")); // have quantity easy available later... workEffort.set("createdByUserLogin", userLogin.get("userLoginId")); } } break; // item found, so go to next orderitem. } } } } if (errorMessages.size() > 0) { return ServiceUtil.returnError(errorMessages); } // the inital status for ALL order types String initialStatus = "ORDER_CREATED"; successResult.put("statusId", initialStatus); // create the order object String orderId = (String) context.get("orderId"); String orgPartyId = null; if (productStore != null) { orgPartyId = productStore.getString("payToPartyId"); } else if (billFromVendorPartyId != null) { orgPartyId = billFromVendorPartyId; } if (UtilValidate.isNotEmpty(orgPartyId)) { Map<String, Object> getNextOrderIdContext = FastMap.newInstance(); getNextOrderIdContext.putAll(context); getNextOrderIdContext.put("partyId", orgPartyId); getNextOrderIdContext.put("userLogin", userLogin); if ((orderTypeId.equals("SALES_ORDER")) || (productStoreId != null)) { getNextOrderIdContext.put("productStoreId", productStoreId); } if (UtilValidate.isEmpty(orderId)) { try { getNextOrderIdContext = ctx.makeValidContext("getNextOrderId", "IN", getNextOrderIdContext); Map<String, Object> getNextOrderIdResult = dispatcher.runSync("getNextOrderId", getNextOrderIdContext); if (ServiceUtil.isError(getNextOrderIdResult)) { String errMsg = UtilProperties.getMessage(resource_error, "OrderErrorGettingNextOrderIdWhileCreatingOrder", locale); return ServiceUtil.returnError(errMsg, null, null, getNextOrderIdResult); } orderId = (String) getNextOrderIdResult.get("orderId"); } catch (GenericServiceException e) { String errMsg = UtilProperties.getMessage(resource_error, "OrderCaughtGenericServiceExceptionWhileGettingOrderId", locale); Debug.logError(e, errMsg, module); return ServiceUtil.returnError(errMsg); } } } if (UtilValidate.isEmpty(orderId)) { // for purchase orders or when other orderId generation fails, a product store id should not be required to make an order orderId = delegator.getNextSeqId("OrderHeader"); } String billingAccountId = (String) context.get("billingAccountId"); if (orderDate == null) { orderDate = nowTimestamp; } Map<String, Object> orderHeaderMap = UtilMisc.<String, Object>toMap("orderId", orderId, "orderTypeId", orderTypeId, "orderDate", orderDate, "entryDate", nowTimestamp, "statusId", initialStatus, "billingAccountId", billingAccountId); orderHeaderMap.put("orderName", context.get("orderName")); orderHeaderMap.put("estimatedDeliveryDate", context.get("estimatedDeliveryDate")); orderHeaderMap.put("isEnableAcctg", context.get("isEnableAcctg")); if (isImmediatelyFulfilled) { // also flag this order as needing inventory issuance so that when it is set to complete it will be issued immediately (needsInventoryIssuance = Y) orderHeaderMap.put("needsInventoryIssuance", "Y"); } GenericValue orderHeader = delegator.makeValue("OrderHeader", orderHeaderMap); // determine the sales channel String salesChannelEnumId = (String) context.get("salesChannelEnumId"); if ((salesChannelEnumId == null) || salesChannelEnumId.equals("UNKNWN_SALES_CHANNEL")) { // try the default store sales channel if (orderTypeId.equals("SALES_ORDER") && (productStore != null)) { salesChannelEnumId = productStore.getString("defaultSalesChannelEnumId"); } // if there's still no channel, set to unknown channel if (salesChannelEnumId == null) { salesChannelEnumId = "UNKNWN_SALES_CHANNEL"; } } orderHeader.set("salesChannelEnumId", salesChannelEnumId); if (context.get("currencyUom") != null) { orderHeader.set("currencyUom", context.get("currencyUom")); } if (context.get("firstAttemptOrderId") != null) { orderHeader.set("firstAttemptOrderId", context.get("firstAttemptOrderId")); } if (context.get("grandTotal") != null) { orderHeader.set("grandTotal", context.get("grandTotal")); } if (UtilValidate.isNotEmpty(context.get("visitId"))) { orderHeader.set("visitId", context.get("visitId")); } if (UtilValidate.isNotEmpty(context.get("internalCode"))) { orderHeader.set("internalCode", context.get("internalCode")); } if (UtilValidate.isNotEmpty(context.get("externalId"))) { orderHeader.set("externalId", context.get("externalId")); } if (UtilValidate.isNotEmpty(context.get("originFacilityId"))) { orderHeader.set("originFacilityId", context.get("originFacilityId")); } if (UtilValidate.isNotEmpty(context.get("productSubscriptionTypeId"))) { orderHeader.set("productSubscriptionTypeId", context.get("productSubscriptionTypeId")); } if (UtilValidate.isNotEmpty(context.get("shipmentId"))) { orderHeader.set("shipmentId", context.get("shipmentId")); } if (UtilValidate.isNotEmpty(context.get("purposeTypeId"))) { orderHeader.set("purposeTypeId", context.get("purposeTypeId")); } if (UtilValidate.isNotEmpty(context.get("productStoreId"))) { orderHeader.set("productStoreId", context.get("productStoreId")); } if (UtilValidate.isNotEmpty(context.get("transactionId"))) { orderHeader.set("transactionId", context.get("transactionId")); } if (UtilValidate.isNotEmpty(context.get("terminalId"))) { orderHeader.set("terminalId", context.get("terminalId")); } if (UtilValidate.isNotEmpty(context.get("autoOrderShoppingListId"))) { orderHeader.set("autoOrderShoppingListId", context.get("autoOrderShoppingListId")); } if (UtilValidate.isNotEmpty(context.get("webSiteId"))) { orderHeader.set("webSiteId", context.get("webSiteId")); } if (userLogin != null && userLogin.get("userLoginId") != null) { orderHeader.set("createdBy", userLogin.getString("userLoginId")); } if (UtilValidate.isNotEmpty(context.get("orderName"))) { orderHeader.set("orderName", context.get("orderName")); } // first try to create the OrderHeader; if this does not fail, continue. try { delegator.create(orderHeader); } catch (GenericEntityException e) { Debug.logError(e, "Cannot create OrderHeader entity; problems with insert", module); return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderOrderCreationFailedPleaseNotifyCustomerService", locale)); } // create the order status record String orderStatusSeqId = delegator.getNextSeqId("OrderStatus"); GenericValue orderStatus = delegator.makeValue("OrderStatus", UtilMisc.toMap("orderStatusId", orderStatusSeqId)); orderStatus.set("orderId", orderId); orderStatus.set("statusId", orderHeader.getString("statusId")); orderStatus.set("statusDatetime", nowTimestamp); orderStatus.set("statusUserLogin", userLogin.getString("userLoginId")); toBeStored.add(orderStatus); // before processing orderItems process orderItemGroups so that they'll be in place for the foreign keys and what not List<GenericValue> orderItemGroups = UtilGenerics.checkList(context.get("orderItemGroups")); if (UtilValidate.isNotEmpty(orderItemGroups)) { Iterator<GenericValue> orderItemGroupIter = orderItemGroups.iterator(); while (orderItemGroupIter.hasNext()) { GenericValue orderItemGroup = orderItemGroupIter.next(); orderItemGroup.set("orderId", orderId); toBeStored.add(orderItemGroup); } } // set the order items Iterator<GenericValue> oi = orderItems.iterator(); while (oi.hasNext()) { GenericValue orderItem = oi.next(); orderItem.set("orderId", orderId); toBeStored.add(orderItem); // create the item status record /* String itemStatusId = delegator.getNextSeqId("OrderStatus"); GenericValue itemStatus = delegator.makeValue("OrderStatus", UtilMisc.toMap("orderStatusId", itemStatusId)); itemStatus.put("statusId", orderItem.get("statusId")); itemStatus.put("orderId", orderId); itemStatus.put("orderItemSeqId", orderItem.get("orderItemSeqId")); itemStatus.put("statusDatetime", nowTimestamp); itemStatus.set("statusUserLogin", userLogin.getString("userLoginId")); toBeStored.add(itemStatus);*/ } // set the order attributes List<GenericValue> orderAttributes = UtilGenerics.checkList(context.get("orderAttributes")); if (UtilValidate.isNotEmpty(orderAttributes)) { Iterator<GenericValue> oattr = orderAttributes.iterator(); while (oattr.hasNext()) { GenericValue oatt = oattr.next(); oatt.set("orderId", orderId); toBeStored.add(oatt); } } // set the order item attributes List<GenericValue> orderItemAttributes = UtilGenerics.checkList(context.get("orderItemAttributes")); if (UtilValidate.isNotEmpty(orderItemAttributes)) { Iterator<GenericValue> oiattr = orderItemAttributes.iterator(); while (oiattr.hasNext()) { GenericValue oiatt = oiattr.next(); oiatt.set("orderId", orderId); toBeStored.add(oiatt); } } // create the order internal notes List<String> orderInternalNotes = UtilGenerics.checkList(context.get("orderInternalNotes")); if (UtilValidate.isNotEmpty(orderInternalNotes)) { Iterator<String> orderInternalNotesIt = orderInternalNotes.iterator(); while (orderInternalNotesIt.hasNext()) { String orderInternalNote = orderInternalNotesIt.next(); try { Map<String, Object> noteOutputMap = dispatcher.runSync("createOrderNote", UtilMisc.<String, Object>toMap("orderId", orderId, "internalNote", "Y", "note", orderInternalNote, "userLogin", userLogin)); if (ServiceUtil.isError(noteOutputMap)) { return ServiceUtil .returnError( UtilProperties.getMessage(resource, "OrderOrderNoteCannotBeCreated", UtilMisc.toMap("errorString", ""), locale), null, null, noteOutputMap); } } catch (GenericServiceException e) { Debug.logError(e, "Error creating internal notes while creating order: " + e.toString(), module); return ServiceUtil.returnError(UtilProperties.getMessage(resource, "OrderOrderNoteCannotBeCreated", UtilMisc.toMap("errorString", e.toString()), locale)); } } } // create the order public notes List<String> orderNotes = UtilGenerics.checkList(context.get("orderNotes")); if (UtilValidate.isNotEmpty(orderNotes)) { Iterator<String> orderNotesIt = orderNotes.iterator(); while (orderNotesIt.hasNext()) { String orderNote = orderNotesIt.next(); try { Map<String, Object> noteOutputMap = dispatcher.runSync("createOrderNote", UtilMisc.<String, Object>toMap("orderId", orderId, "internalNote", "N", "note", orderNote, "userLogin", userLogin)); if (ServiceUtil.isError(noteOutputMap)) { return ServiceUtil .returnError( UtilProperties.getMessage(resource, "OrderOrderNoteCannotBeCreated", UtilMisc.toMap("errorString", ""), locale), null, null, noteOutputMap); } } catch (GenericServiceException e) { Debug.logError(e, "Error creating notes while creating order: " + e.toString(), module); return ServiceUtil.returnError(UtilProperties.getMessage(resource, "OrderOrderNoteCannotBeCreated", UtilMisc.toMap("errorString", e.toString()), locale)); } } } // create the workeffort records // and connect them with the orderitem over the WorkOrderItemFulfillment // create also the techData calendars to keep track of availability of the fixed asset. if (UtilValidate.isNotEmpty(workEfforts)) { List<GenericValue> tempList = new LinkedList<GenericValue>(); Iterator<GenericValue> we = workEfforts.iterator(); while (we.hasNext()) { // create the entity maps required. GenericValue workEffort = we.next(); GenericValue workOrderItemFulfillment = delegator.makeValue("WorkOrderItemFulfillment"); // find fixed asset supplied on the workeffort map GenericValue fixedAsset = null; Debug.logInfo("find the fixedAsset", module); try { fixedAsset = delegator.findByPrimaryKey("FixedAsset", UtilMisc.toMap("fixedAssetId", workEffort.get("fixedAssetId"))); } catch (GenericEntityException e) { return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderFixedAssetNotFoundFixedAssetId", UtilMisc.toMap("fixedAssetId", workEffort.get("fixedAssetId")), locale)); } if (fixedAsset == null) { return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderFixedAssetNotFoundFixedAssetId", UtilMisc.toMap("fixedAssetId", workEffort.get("fixedAssetId")), locale)); } // see if this fixed asset has a calendar, when no create one and attach to fixed asset Debug.logInfo("find the techdatacalendar", module); GenericValue techDataCalendar = null; try { techDataCalendar = fixedAsset.getRelatedOne("TechDataCalendar"); } catch (GenericEntityException e) { Debug.logInfo("TechData calendar does not exist yet so create for fixedAsset: " + fixedAsset.get("fixedAssetId"), module); } if (techDataCalendar == null) { Iterator<GenericValue> fai = tempList.iterator(); while (fai.hasNext()) { GenericValue currentValue = fai.next(); if ("FixedAsset".equals(currentValue.getEntityName()) && currentValue .getString("fixedAssetId").equals(workEffort.getString("fixedAssetId"))) { fixedAsset = currentValue; break; } } Iterator<GenericValue> tdci = tempList.iterator(); while (tdci.hasNext()) { GenericValue currentValue = tdci.next(); if ("TechDataCalendar".equals(currentValue.getEntityName()) && currentValue .getString("calendarId").equals(fixedAsset.getString("calendarId"))) { techDataCalendar = currentValue; break; } } } if (techDataCalendar == null) { techDataCalendar = delegator.makeValue("TechDataCalendar"); Debug.logInfo("create techdata calendar because it does not exist", module); String calendarId = delegator.getNextSeqId("TechDataCalendar"); techDataCalendar.set("calendarId", calendarId); tempList.add(techDataCalendar); Debug.logInfo("update fixed Asset", module); fixedAsset.set("calendarId", calendarId); tempList.add(fixedAsset); } // then create the workEffort and the workOrderItemFulfillment to connect to the order and orderItem workOrderItemFulfillment.set("orderItemSeqId", workEffort.get("workEffortId").toString()); // orderItemSeqNo is stored here so save first // workeffort String workEffortId = delegator.getNextSeqId("WorkEffort"); // find next available workEffortId workEffort.set("workEffortId", workEffortId); workEffort.set("workEffortTypeId", "ASSET_USAGE"); toBeStored.add(workEffort); // store workeffort before workOrderItemFulfillment because of workEffortId key constraint // workOrderItemFulfillment workOrderItemFulfillment.set("workEffortId", workEffortId); workOrderItemFulfillment.set("orderId", orderId); toBeStored.add(workOrderItemFulfillment); // Debug.logInfo("Workeffort "+ workEffortId + " created for asset " + workEffort.get("fixedAssetId") + " and order "+ workOrderItemFulfillment.get("orderId") + "/" + workOrderItemFulfillment.get("orderItemSeqId") + " created", module); // // now create the TechDataExcDay, when they do not exist, create otherwise update the capacity values // please note that calendarId is the same for (TechData)Calendar, CalendarExcDay and CalendarExWeek Timestamp estimatedStartDate = workEffort.getTimestamp("estimatedStartDate"); Timestamp estimatedCompletionDate = workEffort.getTimestamp("estimatedCompletionDate"); long dayCount = (estimatedCompletionDate.getTime() - estimatedStartDate.getTime()) / 86400000; while (--dayCount >= 0) { GenericValue techDataCalendarExcDay = null; // find an existing Day exception record Timestamp exceptionDateStartTime = UtilDateTime .getDayStart(new Timestamp(estimatedStartDate.getTime()), (int) dayCount); try { techDataCalendarExcDay = delegator.findByPrimaryKey("TechDataCalendarExcDay", UtilMisc.toMap("calendarId", fixedAsset.get("calendarId"), "exceptionDateStartTime", exceptionDateStartTime)); } catch (GenericEntityException e) { Debug.logInfo(" techData excday record not found so creating........", module); } if (techDataCalendarExcDay == null) { Iterator<GenericValue> tdcedi = tempList.iterator(); while (tdcedi.hasNext()) { GenericValue currentValue = tdcedi.next(); if ("TechDataCalendarExcDay".equals(currentValue.getEntityName()) && currentValue.getString("calendarId") .equals(fixedAsset.getString("calendarId")) && currentValue.getTimestamp("exceptionDateStartTime") .equals(exceptionDateStartTime)) { techDataCalendarExcDay = currentValue; break; } } } if (techDataCalendarExcDay == null) { techDataCalendarExcDay = delegator.makeValue("TechDataCalendarExcDay"); techDataCalendarExcDay.set("calendarId", fixedAsset.get("calendarId")); techDataCalendarExcDay.set("exceptionDateStartTime", exceptionDateStartTime); techDataCalendarExcDay.set("usedCapacity", BigDecimal.ZERO); // initialise to zero techDataCalendarExcDay.set("exceptionCapacity", fixedAsset.getBigDecimal("productionCapacity")); // Debug.logInfo(" techData excday record not found creating for calendarId: " + techDataCalendarExcDay.getString("calendarId") + // " and date: " + exceptionDateStartTime.toString(), module); } // add the quantity to the quantity on the date record BigDecimal newUsedCapacity = techDataCalendarExcDay.getBigDecimal("usedCapacity") .add(workEffort.getBigDecimal("quantityToProduce")); // check to see if the requested quantity is available on the requested day but only when the maximum capacity is set on the fixed asset if (fixedAsset.get("productionCapacity") != null) { // Debug.logInfo("see if maximum not reached, available: " + techDataCalendarExcDay.getString("exceptionCapacity") + // " already allocated: " + techDataCalendarExcDay.getString("usedCapacity") + // " Requested: " + workEffort.getString("quantityToProduce"), module); if (newUsedCapacity .compareTo(techDataCalendarExcDay.getBigDecimal("exceptionCapacity")) > 0) { String errMsg = "ERROR: fixed_Asset_sold_out AssetId: " + workEffort.get("fixedAssetId") + " on date: " + techDataCalendarExcDay.getString("exceptionDateStartTime"); Debug.logError(errMsg, module); errorMessages.add(errMsg); continue; } } techDataCalendarExcDay.set("usedCapacity", newUsedCapacity); tempList.add(techDataCalendarExcDay); // Debug.logInfo("Update success CalendarID: " + techDataCalendarExcDay.get("calendarId").toString() + // " and for date: " + techDataCalendarExcDay.get("exceptionDateStartTime").toString() + // " and for quantity: " + techDataCalendarExcDay.getDouble("usedCapacity").toString(), module); } } if (tempList.size() > 0) { toBeStored.addAll(tempList); } } if (errorMessages.size() > 0) { return ServiceUtil.returnError(errorMessages); } // set the orderId on all adjustments; this list will include order and // item adjustments... if (UtilValidate.isNotEmpty(orderAdjustments)) { Iterator<GenericValue> iter = orderAdjustments.iterator(); while (iter.hasNext()) { GenericValue orderAdjustment = iter.next(); try { orderAdjustment.set("orderAdjustmentId", delegator.getNextSeqId("OrderAdjustment")); } catch (IllegalArgumentException e) { return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderErrorCouldNotGetNextSequenceIdForOrderAdjustmentCannotCreateOrder", locale)); } orderAdjustment.set("orderId", orderId); orderAdjustment.set("createdDate", UtilDateTime.nowTimestamp()); orderAdjustment.set("createdByUserLogin", userLogin.getString("userLoginId")); if (UtilValidate.isEmpty(orderAdjustment.get("orderItemSeqId"))) { orderAdjustment.set("orderItemSeqId", DataModelConstants.SEQ_ID_NA); } if (UtilValidate.isEmpty(orderAdjustment.get("shipGroupSeqId"))) { orderAdjustment.set("shipGroupSeqId", DataModelConstants.SEQ_ID_NA); } toBeStored.add(orderAdjustment); } } // set the order contact mechs List<GenericValue> orderContactMechs = UtilGenerics.checkList(context.get("orderContactMechs")); if (UtilValidate.isNotEmpty(orderContactMechs)) { Iterator<GenericValue> ocmi = orderContactMechs.iterator(); while (ocmi.hasNext()) { GenericValue ocm = ocmi.next(); ocm.set("orderId", orderId); toBeStored.add(ocm); } } // set the order item contact mechs List<GenericValue> orderItemContactMechs = UtilGenerics.checkList(context.get("orderItemContactMechs")); if (UtilValidate.isNotEmpty(orderItemContactMechs)) { Iterator<GenericValue> oicmi = orderItemContactMechs.iterator(); while (oicmi.hasNext()) { GenericValue oicm = oicmi.next(); oicm.set("orderId", orderId); toBeStored.add(oicm); } } // set the order item ship groups // commented when PurchaseOrder not created without shipment List<String> dropShipGroupIds = FastList.newInstance(); // this list will contain the ids of all the ship groups for drop shipments (no reservations) if (UtilValidate.isNotEmpty(orderItemShipGroupInfo)) { Iterator<GenericValue> osiInfos = orderItemShipGroupInfo.iterator(); while (osiInfos.hasNext()) { GenericValue valueObj = osiInfos.next(); valueObj.set("orderId", orderId); /* if ("OrderItemShipGroup".equals(valueObj.getEntityName())) { // ship group if (valueObj.get("carrierRoleTypeId") == null) { valueObj.set("carrierRoleTypeId", "CARRIER"); } if (!UtilValidate.isEmpty(valueObj.getString("supplierPartyId"))) { dropShipGroupIds.add(valueObj.getString("shipGroupSeqId")); } toBeStored.add(valueObj); // from out side of if we bring here } else */ if ("OrderAdjustment".equals(valueObj.getEntityName())) { // shipping / tax adjustment(s) if (UtilValidate.isEmpty(valueObj.get("orderItemSeqId"))) { valueObj.set("orderItemSeqId", DataModelConstants.SEQ_ID_NA); } valueObj.set("orderAdjustmentId", delegator.getNextSeqId("OrderAdjustment")); valueObj.set("createdDate", UtilDateTime.nowTimestamp()); valueObj.set("createdByUserLogin", userLogin.getString("userLoginId")); toBeStored.add(valueObj); } } } // set the additional party roles Map<String, List<String>> additionalPartyRole = UtilGenerics .checkMap(context.get("orderAdditionalPartyRoleMap")); if (additionalPartyRole != null) { for (Map.Entry<String, List<String>> entry : additionalPartyRole.entrySet()) { String additionalRoleTypeId = entry.getKey(); List<String> parties = entry.getValue(); if (parties != null) { Iterator<String> apIt = parties.iterator(); while (apIt.hasNext()) { String additionalPartyId = apIt.next(); toBeStored.add(delegator.makeValue("PartyRole", UtilMisc.toMap("partyId", additionalPartyId, "roleTypeId", additionalRoleTypeId))); toBeStored.add(delegator.makeValue("OrderRole", UtilMisc.toMap("orderId", orderId, "partyId", additionalPartyId, "roleTypeId", additionalRoleTypeId))); } } } } // set the item survey responses List<GenericValue> surveyResponses = UtilGenerics.checkList(context.get("orderItemSurveyResponses")); if (UtilValidate.isNotEmpty(surveyResponses)) { Iterator<GenericValue> oisr = surveyResponses.iterator(); while (oisr.hasNext()) { GenericValue surveyResponse = oisr.next(); surveyResponse.set("orderId", orderId); toBeStored.add(surveyResponse); } } // set the item price info; NOTE: this must be after the orderItems are stored for referential integrity if (UtilValidate.isNotEmpty(orderItemPriceInfo)) { Iterator<GenericValue> oipii = orderItemPriceInfo.iterator(); while (oipii.hasNext()) { GenericValue oipi = oipii.next(); try { oipi.set("orderItemPriceInfoId", delegator.getNextSeqId("OrderItemPriceInfo")); } catch (IllegalArgumentException e) { return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderErrorCouldNotGetNextSequenceIdForOrderItemPriceInfoCannotCreateOrder", locale)); } oipi.set("orderId", orderId); toBeStored.add(oipi); } } // set the item associations List<GenericValue> orderItemAssociations = UtilGenerics.checkList(context.get("orderItemAssociations")); if (UtilValidate.isNotEmpty(orderItemAssociations)) { Iterator<GenericValue> oia = orderItemAssociations.iterator(); while (oia.hasNext()) { GenericValue orderItemAssociation = oia.next(); if (orderItemAssociation.get("toOrderId") == null) { orderItemAssociation.set("toOrderId", orderId); } else if (orderItemAssociation.get("orderId") == null) { orderItemAssociation.set("orderId", orderId); } toBeStored.add(orderItemAssociation); } } // store the orderProductPromoUseInfos List<GenericValue> orderProductPromoUses = UtilGenerics.checkList(context.get("orderProductPromoUses")); if (UtilValidate.isNotEmpty(orderProductPromoUses)) { Iterator<GenericValue> orderProductPromoUseIter = orderProductPromoUses.iterator(); while (orderProductPromoUseIter.hasNext()) { GenericValue productPromoUse = orderProductPromoUseIter.next(); productPromoUse.set("orderId", orderId); toBeStored.add(productPromoUse); } } // store the orderProductPromoCodes Set<String> orderProductPromoCodes = UtilGenerics.checkSet(context.get("orderProductPromoCodes")); if (UtilValidate.isNotEmpty(orderProductPromoCodes)) { GenericValue orderProductPromoCode = delegator.makeValue("OrderProductPromoCode"); Iterator<String> orderProductPromoCodeIter = orderProductPromoCodes.iterator(); while (orderProductPromoCodeIter.hasNext()) { orderProductPromoCode.clear(); orderProductPromoCode.set("orderId", orderId); orderProductPromoCode.set("productPromoCodeId", orderProductPromoCodeIter.next()); toBeStored.add(orderProductPromoCode); } } /* DEJ20050529 the OLD way, where a single party had all roles... no longer doing things this way... // define the roles for the order List userOrderRoleTypes = null; if ("SALES_ORDER".equals(orderTypeId)) { userOrderRoleTypes = UtilMisc.toList("END_USER_CUSTOMER", "SHIP_TO_CUSTOMER", "BILL_TO_CUSTOMER", "PLACING_CUSTOMER"); } else if ("PURCHASE_ORDER".equals(orderTypeId)) { userOrderRoleTypes = UtilMisc.toList("SHIP_FROM_VENDOR", "BILL_FROM_VENDOR", "SUPPLIER_AGENT"); } else { // TODO: some default behavior } // now add the roles if (userOrderRoleTypes != null) { Iterator i = userOrderRoleTypes.iterator(); while (i.hasNext()) { String roleType = (String) i.next(); String thisParty = partyId; if (thisParty == null) { thisParty = "_NA_"; // will always set these roles so we can query } // make sure the party is in the role before adding toBeStored.add(delegator.makeValue("PartyRole", UtilMisc.toMap("partyId", partyId, "roleTypeId", roleType))); toBeStored.add(delegator.makeValue("OrderRole", UtilMisc.toMap("orderId", orderId, "partyId", partyId, "roleTypeId", roleType))); } } */ // see the attributeRoleMap definition near the top of this file for attribute-role mappings Map<String, String> attributeRoleMap = salesAttributeRoleMap; GenericValue orderHeaderType = null; try { orderHeaderType = delegator.findOne("OrderType", UtilMisc.toMap("orderTypeId", orderTypeId), false); } catch (GenericEntityException e) { Debug.logError(e, "Problems to get orderType", module); } if (("PURCHASE_ORDER".equals(orderTypeId)) || (UtilValidate.isNotEmpty(orderHeaderType) && ("PURCHASE_ORDER".equals(orderHeaderType.getString("parentTypeId"))))) { attributeRoleMap = purchaseAttributeRoleMap; //Debug.log("===orderTypeId==beforeRole="+orderTypeId); } for (Map.Entry<String, String> attributeRoleEntry : attributeRoleMap.entrySet()) { if (UtilValidate.isNotEmpty(context.get(attributeRoleEntry.getKey()))) { // make sure the party is in the role before adding toBeStored.add(delegator.makeValue("PartyRole", UtilMisc.toMap("partyId", context.get(attributeRoleEntry.getKey()), "roleTypeId", attributeRoleEntry.getValue()))); toBeStored.add(delegator.makeValue("OrderRole", UtilMisc.toMap("orderId", orderId, "partyId", context.get(attributeRoleEntry.getKey()), "roleTypeId", attributeRoleEntry.getValue()))); } } // set the affiliate -- This is going to be removed... String affiliateId = (String) context.get("affiliateId"); if (UtilValidate.isNotEmpty(affiliateId)) { toBeStored.add(delegator.makeValue("OrderRole", UtilMisc.toMap("orderId", orderId, "partyId", affiliateId, "roleTypeId", "AFFILIATE"))); } // set the distributor String distributorId = (String) context.get("distributorId"); if (UtilValidate.isNotEmpty(distributorId)) { toBeStored.add(delegator.makeValue("OrderRole", UtilMisc.toMap("orderId", orderId, "partyId", distributorId, "roleTypeId", "DISTRIBUTOR"))); } // find all parties in role VENDOR associated with WebSite OR ProductStore (where WebSite overrides, if specified), associated first valid with the Order if (UtilValidate.isNotEmpty(context.get("productStoreId"))) { try { List<GenericValue> productStoreRoles = delegator.findByAnd("ProductStoreRole", UtilMisc.toMap("roleTypeId", "VENDOR", "productStoreId", context.get("productStoreId")), UtilMisc.toList("-fromDate")); productStoreRoles = EntityUtil.filterByDate(productStoreRoles, true); GenericValue productStoreRole = EntityUtil.getFirst(productStoreRoles); if (productStoreRole != null) { toBeStored.add(delegator.makeValue("OrderRole", UtilMisc.toMap("orderId", orderId, "partyId", productStoreRole.get("partyId"), "roleTypeId", "VENDOR"))); } } catch (GenericEntityException e) { Debug.logError(e, "Error looking up Vendor for the current Product Store", module); } } if (UtilValidate.isNotEmpty(context.get("webSiteId"))) { try { List<GenericValue> webSiteRoles = delegator.findByAnd("WebSiteRole", UtilMisc.toMap("roleTypeId", "VENDOR", "webSiteId", context.get("webSiteId")), UtilMisc.toList("-fromDate")); webSiteRoles = EntityUtil.filterByDate(webSiteRoles, true); GenericValue webSiteRole = EntityUtil.getFirst(webSiteRoles); if (webSiteRole != null) { toBeStored.add(delegator.makeValue("OrderRole", UtilMisc.toMap("orderId", orderId, "partyId", webSiteRole.get("partyId"), "roleTypeId", "VENDOR"))); } } catch (GenericEntityException e) { Debug.logError(e, "Error looking up Vendor for the current Web Site", module); } } // set the order payment info List<GenericValue> orderPaymentInfos = UtilGenerics.checkList(context.get("orderPaymentInfo")); if (UtilValidate.isNotEmpty(orderPaymentInfos)) { Iterator<GenericValue> oppIter = orderPaymentInfos.iterator(); while (oppIter.hasNext()) { GenericValue valueObj = oppIter.next(); valueObj.set("orderId", orderId); if ("OrderPaymentPreference".equals(valueObj.getEntityName())) { if (valueObj.get("orderPaymentPreferenceId") == null) { valueObj.set("orderPaymentPreferenceId", delegator.getNextSeqId("OrderPaymentPreference")); valueObj.set("createdDate", UtilDateTime.nowTimestamp()); valueObj.set("createdByUserLogin", userLogin.getString("userLoginId")); } if (valueObj.get("statusId") == null) { valueObj.set("statusId", "PAYMENT_NOT_RECEIVED"); } } toBeStored.add(valueObj); } } // store the trackingCodeOrder entities List<GenericValue> trackingCodeOrders = UtilGenerics.checkList(context.get("trackingCodeOrders")); if (UtilValidate.isNotEmpty(trackingCodeOrders)) { Iterator<GenericValue> tkcdordIter = trackingCodeOrders.iterator(); while (tkcdordIter.hasNext()) { GenericValue trackingCodeOrder = tkcdordIter.next(); trackingCodeOrder.set("orderId", orderId); toBeStored.add(trackingCodeOrder); } } // store the OrderTerm entities List<GenericValue> orderTerms = UtilGenerics.checkList(context.get("orderTerms")); if (UtilValidate.isNotEmpty(orderTerms)) { Iterator<GenericValue> orderTermIter = orderTerms.iterator(); while (orderTermIter.hasNext()) { GenericValue orderTerm = orderTermIter.next(); orderTerm.set("orderId", orderId); if (orderTerm.get("orderItemSeqId") == null) { orderTerm.set("orderItemSeqId", "_NA_"); } toBeStored.add(orderTerm); } } // if a workEffortId is passed, then prepare a OrderHeaderWorkEffort value String workEffortId = (String) context.get("workEffortId"); if (UtilValidate.isNotEmpty(workEffortId)) { GenericValue orderHeaderWorkEffort = delegator.makeValue("OrderHeaderWorkEffort"); orderHeaderWorkEffort.set("orderId", orderId); orderHeaderWorkEffort.set("workEffortId", workEffortId); toBeStored.add(orderHeaderWorkEffort); } try { // store line items, etc so that they will be there for the foreign key checks delegator.storeAll(toBeStored); // START inventory reservation // commented when PurchaseOrder not created without shipment /*List<String> resErrorMessages = new LinkedList<String>(); try { reserveInventory(delegator, dispatcher, userLogin, locale, orderItemShipGroupInfo, dropShipGroupIds, itemValuesBySeqId, orderTypeId, productStoreId, resErrorMessages); } catch (GeneralException e) { return ServiceUtil.returnError(e.getMessage()); } if (resErrorMessages.size() > 0) { return ServiceUtil.returnError(resErrorMessages); }*/ // END inventory reservation successResult.put("orderId", orderId); } catch (GenericEntityException e) { Debug.logError(e, "Problem with order storage or reservations", module); return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderErrorCouldNotCreateOrderWriteError", locale) + e.getMessage() + ")."); } return successResult; } public static void reserveInventory(Delegator delegator, LocalDispatcher dispatcher, GenericValue userLogin, Locale locale, List<GenericValue> orderItemShipGroupInfo, List<String> dropShipGroupIds, Map<String, GenericValue> itemValuesBySeqId, String orderTypeId, String productStoreId, List<String> resErrorMessages) throws GeneralException { boolean isImmediatelyFulfilled = false; GenericValue productStore = null; if (UtilValidate.isNotEmpty(productStoreId)) { try { productStore = delegator.findByPrimaryKeyCache("ProductStore", UtilMisc.toMap("productStoreId", productStoreId)); } catch (GenericEntityException e) { throw new GeneralException( UtilProperties.getMessage(resource_error, "OrderErrorCouldNotFindProductStoreWithID", UtilMisc.toMap("productStoreId", productStoreId), locale) + e.toString()); } } if (productStore != null) { isImmediatelyFulfilled = "Y".equals(productStore.getString("isImmediatelyFulfilled")); } boolean reserveInventory = ("SALES_ORDER".equals(orderTypeId)); if (reserveInventory && isImmediatelyFulfilled) { // don't reserve inventory if the product store has isImmediatelyFulfilled set, ie don't if in this store things are immediately fulfilled reserveInventory = false; } // START inventory reservation // decrement inventory available for each OrderItemShipGroupAssoc, within the same transaction if (UtilValidate.isNotEmpty(orderItemShipGroupInfo)) { Iterator<GenericValue> osiInfos = orderItemShipGroupInfo.iterator(); while (osiInfos.hasNext()) { GenericValue orderItemShipGroupAssoc = osiInfos.next(); if ("OrderItemShipGroupAssoc".equals(orderItemShipGroupAssoc.getEntityName())) { if (dropShipGroupIds != null && dropShipGroupIds.contains(orderItemShipGroupAssoc.getString("shipGroupSeqId"))) { // the items in the drop ship groups are not reserved continue; } GenericValue orderItem = itemValuesBySeqId.get(orderItemShipGroupAssoc.get("orderItemSeqId")); GenericValue orderItemShipGroup = orderItemShipGroupAssoc.getRelatedOne("OrderItemShipGroup"); String shipGroupFacilityId = orderItemShipGroup.getString("facilityId"); String itemStatus = orderItem.getString("statusId"); if ("ITEM_REJECTED".equals(itemStatus) || "ITEM_CANCELLED".equals(itemStatus) || "ITEM_COMPLETED".equals(itemStatus)) { Debug.logInfo("Order item [" + orderItem.getString("orderId") + " / " + orderItem.getString("orderItemSeqId") + "] is not in a proper status for reservation", module); continue; } if (UtilValidate.isNotEmpty(orderItem.getString("productId")) && // only reserve product items, ignore non-product items !"RENTAL_ORDER_ITEM".equals(orderItem.getString("orderItemTypeId"))) { // ignore for rental try { // get the product of the order item GenericValue product = orderItem.getRelatedOne("Product"); if (product == null) { Debug.logError("Error when looking up product in reserveInventory service", module); resErrorMessages.add("Error when looking up product in reserveInventory service"); continue; } if (reserveInventory) { // for MARKETING_PKG_PICK reserve the components if (EntityTypeUtil.hasParentType(delegator, "ProductType", "productTypeId", product.getString("productTypeId"), "parentTypeId", "MARKETING_PKG_PICK")) { Map<String, Object> componentsRes = dispatcher.runSync("getAssociatedProducts", UtilMisc.toMap("productId", orderItem.getString("productId"), "type", "PRODUCT_COMPONENT")); if (ServiceUtil.isError(componentsRes)) { resErrorMessages .add((String) componentsRes.get(ModelService.ERROR_MESSAGE)); continue; } else { List<GenericValue> assocProducts = UtilGenerics .checkList(componentsRes.get("assocProducts")); Iterator<GenericValue> assocProductsIter = assocProducts.iterator(); while (assocProductsIter.hasNext()) { GenericValue productAssoc = assocProductsIter.next(); BigDecimal quantityOrd = productAssoc.getBigDecimal("quantity"); BigDecimal quantityKit = orderItemShipGroupAssoc .getBigDecimal("quantity"); BigDecimal quantity = quantityOrd.multiply(quantityKit); Map<String, Object> reserveInput = new HashMap<String, Object>(); reserveInput.put("productStoreId", productStoreId); reserveInput.put("productId", productAssoc.getString("productIdTo")); reserveInput.put("orderId", orderItem.getString("orderId")); reserveInput.put("orderItemSeqId", orderItem.getString("orderItemSeqId")); reserveInput.put("shipGroupSeqId", orderItemShipGroupAssoc.getString("shipGroupSeqId")); reserveInput.put("quantity", quantity); reserveInput.put("userLogin", userLogin); reserveInput.put("facilityId", shipGroupFacilityId); Map<String, Object> reserveResult = dispatcher .runSync("reserveStoreInventory", reserveInput); if (ServiceUtil.isError(reserveResult)) { String invErrMsg = "The product "; if (product != null) { invErrMsg += getProductName(product, orderItem); } invErrMsg += " with ID " + orderItem.getString("productId") + " is no longer in stock. Please try reducing the quantity or removing the product from this order."; resErrorMessages.add(invErrMsg); } } } } else { // reserve the product Map<String, Object> reserveInput = new HashMap<String, Object>(); reserveInput.put("productStoreId", productStoreId); reserveInput.put("productId", orderItem.getString("productId")); reserveInput.put("orderId", orderItem.getString("orderId")); reserveInput.put("orderItemSeqId", orderItem.getString("orderItemSeqId")); reserveInput.put("shipGroupSeqId", orderItemShipGroupAssoc.getString("shipGroupSeqId")); reserveInput.put("facilityId", shipGroupFacilityId); // use the quantity from the orderItemShipGroupAssoc, NOT the orderItem, these are reserved by item-group assoc reserveInput.put("quantity", orderItemShipGroupAssoc.getBigDecimal("quantity")); reserveInput.put("userLogin", userLogin); Map<String, Object> reserveResult = dispatcher.runSync("reserveStoreInventory", reserveInput); if (ServiceUtil.isError(reserveResult)) { String invErrMsg = "The product "; if (product != null) { invErrMsg += getProductName(product, orderItem); } invErrMsg += " with ID " + orderItem.getString("productId") + " is no longer in stock. Please try reducing the quantity or removing the product from this order."; resErrorMessages.add(invErrMsg); } } } // Reserving inventory or not we still need to create a marketing package // If the product is a marketing package auto, attempt to create enough packages to bring ATP back to 0, won't necessarily create enough to cover this order. if (EntityTypeUtil.hasParentType(delegator, "ProductType", "productTypeId", product.getString("productTypeId"), "parentTypeId", "MARKETING_PKG_AUTO")) { // do something tricky here: run as the "system" user // that can actually create and run a production run GenericValue permUserLogin = delegator.findByPrimaryKeyCache("UserLogin", UtilMisc.toMap("userLoginId", "system")); Map<String, Object> inputMap = new HashMap<String, Object>(); if (UtilValidate.isNotEmpty(shipGroupFacilityId)) { inputMap.put("facilityId", shipGroupFacilityId); } else { inputMap.put("facilityId", productStore.getString("inventoryFacilityId")); } inputMap.put("orderId", orderItem.getString("orderId")); inputMap.put("orderItemSeqId", orderItem.getString("orderItemSeqId")); inputMap.put("userLogin", permUserLogin); Map<String, Object> prunResult = dispatcher.runSync("createProductionRunForMktgPkg", inputMap); if (ServiceUtil.isError(prunResult)) { Debug.logError( ServiceUtil.getErrorMessage(prunResult) + " for input:" + inputMap, module); } } } catch (GenericServiceException e) { String errMsg = "Fatal error calling reserveStoreInventory service: " + e.toString(); Debug.logError(e, errMsg, module); resErrorMessages.add(errMsg); } } } } } } public static String getProductName(GenericValue product, GenericValue orderItem) { if (UtilValidate.isNotEmpty(product.getString("productName"))) { return product.getString("productName"); } else { return orderItem.getString("itemDescription"); } } public static String getProductName(GenericValue product, String orderItemName) { if (UtilValidate.isNotEmpty(product.getString("productName"))) { return product.getString("productName"); } else { return orderItemName; } } public static String determineSingleFacilityFromOrder(GenericValue orderHeader) { if (orderHeader != null) { String productStoreId = orderHeader.getString("productStoreId"); if (productStoreId != null) { return ProductStoreWorker.determineSingleFacilityForStore(orderHeader.getDelegator(), productStoreId); } } return null; } /** Service for resetting the OrderHeader grandTotal */ public static Map<String, Object> resetGrandTotal(DispatchContext ctx, Map<String, ? extends Object> context) { Delegator delegator = ctx.getDelegator(); //appears to not be used: GenericValue userLogin = (GenericValue) context.get("userLogin"); String orderId = (String) context.get("orderId"); GenericValue orderHeader = null; try { orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId)); } catch (GenericEntityException e) { String errMsg = "ERROR: Could not set grantTotal on OrderHeader entity: " + e.toString(); Debug.logError(e, errMsg, module); return ServiceUtil.returnError(errMsg); } if (orderHeader != null) { OrderReadHelper orh = new OrderReadHelper(orderHeader); BigDecimal currentTotal = orderHeader.getBigDecimal("grandTotal"); BigDecimal currentSubTotal = orderHeader.getBigDecimal("remainingSubTotal"); // get the new grand total BigDecimal updatedTotal = orh.getOrderGrandTotal(); String productStoreId = orderHeader.getString("productStoreId"); String showPricesWithVatTax = null; if (UtilValidate.isNotEmpty(productStoreId)) { GenericValue productStore = null; try { productStore = delegator.findByPrimaryKeyCache("ProductStore", UtilMisc.toMap("productStoreId", productStoreId)); } catch (GenericEntityException e) { String errorMessage = UtilProperties.getMessage(resource_error, "OrderErrorCouldNotFindProductStoreWithID", UtilMisc.toMap("productStoreId", productStoreId), (Locale) context.get("locale")) + e.toString(); Debug.logError(e, errorMessage, module); return ServiceUtil.returnError(errorMessage + e.getMessage() + ")."); } showPricesWithVatTax = productStore.getString("showPricesWithVatTax"); } BigDecimal remainingSubTotal = ZERO; if (UtilValidate.isNotEmpty(productStoreId) && "Y".equalsIgnoreCase(showPricesWithVatTax)) { // calculate subTotal as grandTotal + taxes - (returnsTotal + shipping of all items) remainingSubTotal = updatedTotal.subtract(orh.getOrderReturnedTotal()) .subtract(orh.getShippingTotal()); } else { // calculate subTotal as grandTotal - returnsTotal - (tax + shipping of items not returned) remainingSubTotal = updatedTotal.subtract(orh.getOrderReturnedTotal()) .subtract(orh.getOrderNonReturnedTaxAndShipping()); } if (currentTotal == null || currentSubTotal == null || updatedTotal.compareTo(currentTotal) != 0 || remainingSubTotal.compareTo(currentSubTotal) != 0) { orderHeader.set("grandTotal", updatedTotal); orderHeader.set("remainingSubTotal", remainingSubTotal); try { orderHeader.store(); } catch (GenericEntityException e) { String errMsg = "ERROR: Could not set grandTotal on OrderHeader entity: " + e.toString(); Debug.logError(e, errMsg, module); return ServiceUtil.returnError(errMsg); } } } return ServiceUtil.returnSuccess(); } /** 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); } Set<String> fields = UtilMisc.toSet("orderId"); EntityListIterator eli = null; try { eli = delegator.find("OrderHeader", cond, null, fields, null, null); } catch (GenericEntityException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } 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)); } 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); } } // close the ELI try { eli.close(); } catch (GenericEntityException e) { Debug.logError(e, module); } } else { Debug.logInfo("No orders found for reset processing", module); } return ServiceUtil.returnSuccess(); } /** Service for checking and re-calc the tax amount */ public static Map<String, Object> recalcOrderTax(DispatchContext ctx, Map<String, ? extends Object> context) { LocalDispatcher dispatcher = ctx.getDispatcher(); Delegator delegator = ctx.getDelegator(); String orderId = (String) context.get("orderId"); GenericValue userLogin = (GenericValue) context.get("userLogin"); Locale locale = (Locale) context.get("locale"); // check and make sure we have permission to change the order Security security = ctx.getSecurity(); boolean hasPermission = OrderServices.hasPermission(orderId, userLogin, "UPDATE", security, delegator); if (!hasPermission) { return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderYouDoNotHavePermissionToChangeThisOrdersStatus", locale)); } // get the order header GenericValue orderHeader = null; try { orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId)); } catch (GenericEntityException e) { return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderErrorCannotGetOrderHeaderEntity", locale) + e.getMessage()); } if (orderHeader == null) { return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderErrorNoValidOrderHeaderFoundForOrderId", UtilMisc.toMap("orderId", orderId), locale)); } // don't charge tax on purchase orders, better we still do..... // if ("PURCHASE_ORDER".equals(orderHeader.getString("orderTypeId"))) { // return ServiceUtil.returnSuccess(); // } // Retrieve the order tax adjustments List<GenericValue> orderTaxAdjustments = null; try { orderTaxAdjustments = delegator.findByAnd("OrderAdjustment", UtilMisc.toMap("orderId", orderId)); orderTaxAdjustments = OrderReadHelper.fetchTaxAdjustments(orderTaxAdjustments); } catch (GenericEntityException e) { Debug.logError(e, "Unable to retrieve SALES_TAX adjustments for order : " + orderId, module); return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderUnableToRetrieveSalesTaxAdjustments", locale)); } // Accumulate the total existing tax adjustment BigDecimal totalExistingOrderTax = ZERO; Iterator<GenericValue> otait = UtilMisc.toIterator(orderTaxAdjustments); while (otait != null && otait.hasNext()) { GenericValue orderTaxAdjustment = otait.next(); if (orderTaxAdjustment.get("amount") != null) { totalExistingOrderTax = totalExistingOrderTax .add(orderTaxAdjustment.getBigDecimal("amount").setScale(taxDecimals, taxRounding)); } } // Recalculate the taxes for the order BigDecimal totalNewOrderTax = ZERO; OrderReadHelper orh = new OrderReadHelper(orderHeader); List<GenericValue> shipGroups = orh.getOrderItemShipGroups(); if (shipGroups != null) { Iterator<GenericValue> itr = shipGroups.iterator(); while (itr.hasNext()) { GenericValue shipGroup = itr.next(); String shipGroupSeqId = shipGroup.getString("shipGroupSeqId"); List<GenericValue> validOrderItems = orh.getValidOrderItems(shipGroupSeqId); if (validOrderItems != null) { // prepare the inital lists List<GenericValue> products = new ArrayList<GenericValue>(validOrderItems.size()); List<BigDecimal> amounts = new ArrayList<BigDecimal>(validOrderItems.size()); List<BigDecimal> shipAmts = new ArrayList<BigDecimal>(validOrderItems.size()); List<BigDecimal> itPrices = new ArrayList<BigDecimal>(validOrderItems.size()); List<BigDecimal> itQuantities = new ArrayList<BigDecimal>(validOrderItems.size()); // adjustments and total List<GenericValue> allAdjustments = orh.getAdjustments(); List<GenericValue> orderHeaderAdjustments = OrderReadHelper .getOrderHeaderAdjustments(allAdjustments, shipGroupSeqId); BigDecimal orderSubTotal = OrderReadHelper.getOrderItemsSubTotal(validOrderItems, allAdjustments); // shipping amount BigDecimal orderShipping = OrderReadHelper.calcOrderAdjustments(orderHeaderAdjustments, orderSubTotal, false, false, true); //promotions amount BigDecimal orderPromotions = OrderReadHelper.calcOrderPromoAdjustmentsBd(allAdjustments); // build up the list of tax calc service parameters for (int i = 0; i < validOrderItems.size(); i++) { GenericValue orderItem = validOrderItems.get(i); String productId = orderItem.getString("productId"); try { products.add(i, delegator.findByPrimaryKey("Product", UtilMisc.toMap("productId", productId))); // get the product entity amounts.add(i, OrderReadHelper.getOrderItemSubTotal(orderItem, allAdjustments, true, false)); // get the item amount shipAmts.add(i, OrderReadHelper.getOrderItemAdjustmentsTotal(orderItem, allAdjustments, false, false, true)); // get the shipping amount itPrices.add(i, orderItem.getBigDecimal("unitPrice")); itQuantities.add(i, orderItem.getBigDecimal("quantity")); } catch (GenericEntityException e) { Debug.logError(e, "Cannot read order item entity : " + orderItem, module); return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderCannotReadTheOrderItemEntity", locale)); } } GenericValue shippingAddress = orh.getShippingAddress(shipGroupSeqId); // no shipping address, try the billing address if (shippingAddress == null) { List<GenericValue> billingAddressList = orh.getBillingLocations(); if (billingAddressList.size() > 0) { shippingAddress = billingAddressList.get(0); } } // TODO and NOTE DEJ20070816: this is NOT a good way to determine if this is a face-to-face or immediatelyFulfilled order //this should be made consistent with the CheckOutHelper.makeTaxContext(int shipGroup, GenericValue shipAddress) method if (shippingAddress == null) { // face-to-face order; use the facility address String facilityId = orderHeader.getString("originFacilityId"); if (facilityId != null) { GenericValue facilityContactMech = ContactMechWorker.getFacilityContactMechByPurpose( delegator, facilityId, UtilMisc.toList("SHIP_ORIG_LOCATION", "PRIMARY_LOCATION")); if (facilityContactMech != null) { try { shippingAddress = delegator.findByPrimaryKey("PostalAddress", UtilMisc.toMap( "contactMechId", facilityContactMech.getString("contactMechId"))); } catch (GenericEntityException e) { Debug.logError(e, module); } } } } // if shippingAddress is still null then don't calculate tax; it may be an situation where no tax is applicable, or the data is bad and we don't have a way to find an address to check tax for if (shippingAddress == null) { Debug.logWarning("Not calculating tax for Order [" + orderId + "] because there is no shippingAddress, and no address on the origin facility [" + orderHeader.getString("originFacilityId") + "]", module); continue; } // prepare the service context Map<String, Object> serviceContext = UtilMisc.<String, Object>toMap("productStoreId", orh.getProductStoreId(), "itemProductList", products, "itemAmountList", amounts, "itemShippingList", shipAmts, "itemPriceList", itPrices, "itemQuantityList", itQuantities, "orderShippingAmount", orderShipping); serviceContext.put("shippingAddress", shippingAddress); serviceContext.put("orderPromotionsAmount", orderPromotions); if (orh.getBillToParty() != null) serviceContext.put("billToPartyId", orh.getBillToParty().getString("partyId")); if (orh.getBillFromParty() != null) serviceContext.put("payToPartyId", orh.getBillFromParty().getString("partyId")); // invoke the calcTax service Map<String, Object> serviceResult = null; try { serviceResult = dispatcher.runSync("calcTax", serviceContext); } catch (GenericServiceException e) { Debug.logError(e, module); return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderProblemOccurredInTaxService", locale)); } if (ServiceUtil.isError(serviceResult)) { return ServiceUtil.returnError(ServiceUtil.getErrorMessage(serviceResult)); } // the adjustments (returned in order) from the tax service List<GenericValue> orderAdj = UtilGenerics.checkList(serviceResult.get("orderAdjustments")); List<List<GenericValue>> itemAdj = UtilGenerics.checkList(serviceResult.get("itemAdjustments")); // Accumulate the new tax total from the recalculated header adjustments if (UtilValidate.isNotEmpty(orderAdj)) { Iterator<GenericValue> oai = orderAdj.iterator(); while (oai.hasNext()) { GenericValue oa = oai.next(); if (oa.get("amount") != null) { totalNewOrderTax = totalNewOrderTax .add(oa.getBigDecimal("amount").setScale(taxDecimals, taxRounding)); } } } // Accumulate the new tax total from the recalculated item adjustments if (UtilValidate.isNotEmpty(itemAdj)) { for (int i = 0; i < itemAdj.size(); i++) { List<GenericValue> itemAdjustments = itemAdj.get(i); Iterator<GenericValue> ida = itemAdjustments.iterator(); while (ida.hasNext()) { GenericValue ia = ida.next(); if (ia.get("amount") != null) { totalNewOrderTax = totalNewOrderTax .add(ia.getBigDecimal("amount").setScale(taxDecimals, taxRounding)); } } } } } } // Determine the difference between existing and new tax adjustment totals, if any BigDecimal orderTaxDifference = totalNewOrderTax.subtract(totalExistingOrderTax).setScale(taxDecimals, taxRounding); // If the total has changed, create an OrderAdjustment to reflect the fact if (orderTaxDifference.signum() != 0) { Map<String, Object> createOrderAdjContext = new HashMap<String, Object>(); createOrderAdjContext.put("orderAdjustmentTypeId", "SALES_TAX"); createOrderAdjContext.put("orderId", orderId); createOrderAdjContext.put("orderItemSeqId", "_NA_"); createOrderAdjContext.put("shipGroupSeqId", "_NA_"); createOrderAdjContext.put("description", "Tax adjustment due to order change"); createOrderAdjContext.put("amount", orderTaxDifference); createOrderAdjContext.put("userLogin", userLogin); Map<String, Object> createOrderAdjResponse = null; try { createOrderAdjResponse = dispatcher.runSync("createOrderAdjustment", createOrderAdjContext); } catch (GenericServiceException e) { String createOrderAdjErrMsg = UtilProperties.getMessage(resource_error, "OrderErrorCallingCreateOrderAdjustmentService", locale); Debug.logError(createOrderAdjErrMsg, module); return ServiceUtil.returnError(createOrderAdjErrMsg); } if (ServiceUtil.isError(createOrderAdjResponse)) { Debug.logError(ServiceUtil.getErrorMessage(createOrderAdjResponse), module); return ServiceUtil.returnError(ServiceUtil.getErrorMessage(createOrderAdjResponse)); } } } return ServiceUtil.returnSuccess(); } /** Service for checking and re-calc the shipping amount */ public static Map<String, Object> recalcOrderShipping(DispatchContext ctx, Map<String, ? extends Object> context) { LocalDispatcher dispatcher = ctx.getDispatcher(); Delegator delegator = ctx.getDelegator(); String orderId = (String) context.get("orderId"); GenericValue userLogin = (GenericValue) context.get("userLogin"); Locale locale = (Locale) context.get("locale"); // check and make sure we have permission to change the order Security security = ctx.getSecurity(); boolean hasPermission = OrderServices.hasPermission(orderId, userLogin, "UPDATE", security, delegator); if (!hasPermission) { return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderYouDoNotHavePermissionToChangeThisOrdersStatus", locale)); } // get the order header GenericValue orderHeader = null; try { orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId)); } catch (GenericEntityException e) { return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderErrorCannotGetOrderHeaderEntity", locale) + e.getMessage()); } if (orderHeader == null) { return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderErrorNoValidOrderHeaderFoundForOrderId", UtilMisc.toMap("orderId", orderId), locale)); } OrderReadHelper orh = new OrderReadHelper(orderHeader); List<GenericValue> shipGroups = orh.getOrderItemShipGroups(); if (shipGroups != null) { Iterator<GenericValue> i = shipGroups.iterator(); while (i.hasNext()) { GenericValue shipGroup = i.next(); String shipGroupSeqId = shipGroup.getString("shipGroupSeqId"); if (shipGroup.get("contactMechId") == null || shipGroup.get("shipmentMethodTypeId") == null) { // not shipped (face-to-face order) continue; } Map<String, Object> shippingEstMap = ShippingEvents.getShipEstimate(dispatcher, delegator, orh, shipGroupSeqId); BigDecimal shippingTotal = null; if (UtilValidate.isEmpty(orh.getValidOrderItems(shipGroupSeqId))) { shippingTotal = ZERO; Debug.log("No valid order items found - " + shippingTotal, module); } else { shippingTotal = UtilValidate.isEmpty(shippingEstMap.get("shippingTotal")) ? ZERO : (BigDecimal) shippingEstMap.get("shippingTotal"); shippingTotal = shippingTotal.setScale(orderDecimals, orderRounding); Debug.log("Got new shipping estimate - " + shippingTotal, module); } if (Debug.infoOn()) { Debug.log("New Shipping Total [" + orderId + " / " + shipGroupSeqId + "] : " + shippingTotal, module); } BigDecimal currentShipping = OrderReadHelper.getAllOrderItemsAdjustmentsTotal( orh.getOrderItemAndShipGroupAssoc(shipGroupSeqId), orh.getAdjustments(), false, false, true); currentShipping = currentShipping .add(OrderReadHelper.calcOrderAdjustments(orh.getOrderHeaderAdjustments(shipGroupSeqId), orh.getOrderItemsSubTotal(), false, false, true)); if (Debug.infoOn()) { Debug.log("Old Shipping Total [" + orderId + " / " + shipGroupSeqId + "] : " + currentShipping, module); } List<String> errorMessageList = UtilGenerics .checkList(shippingEstMap.get(ModelService.ERROR_MESSAGE_LIST)); if (errorMessageList != null) { Debug.logWarning("Problem finding shipping estimates for [" + orderId + "/ " + shipGroupSeqId + "] = " + errorMessageList, module); continue; } if ((shippingTotal != null) && (shippingTotal.compareTo(currentShipping) != 0)) { // place the difference as a new shipping adjustment BigDecimal adjustmentAmount = shippingTotal.subtract(currentShipping); String adjSeqId = delegator.getNextSeqId("OrderAdjustment"); GenericValue orderAdjustment = delegator.makeValue("OrderAdjustment", UtilMisc.toMap("orderAdjustmentId", adjSeqId)); orderAdjustment.set("orderAdjustmentTypeId", "SHIPPING_CHARGES"); orderAdjustment.set("amount", adjustmentAmount); orderAdjustment.set("orderId", orh.getOrderId()); orderAdjustment.set("shipGroupSeqId", shipGroupSeqId); orderAdjustment.set("orderItemSeqId", DataModelConstants.SEQ_ID_NA); orderAdjustment.set("createdDate", UtilDateTime.nowTimestamp()); orderAdjustment.set("createdByUserLogin", userLogin.getString("userLoginId")); //orderAdjustment.set("comments", "Shipping Re-Calc Adjustment"); try { orderAdjustment.create(); } catch (GenericEntityException e) { Debug.logError(e, "Problem creating shipping re-calc adjustment : " + orderAdjustment, module); return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderErrorCannotCreateAdjustment", locale)); } } // TODO: re-balance free shipping adjustment } } return ServiceUtil.returnSuccess(); } /** Service for checking to see if an order is fully completed or canceled */ public static Map<String, Object> checkItemStatus(DispatchContext ctx, Map<String, ? extends Object> context) { Delegator delegator = ctx.getDelegator(); LocalDispatcher dispatcher = ctx.getDispatcher(); Locale locale = (Locale) context.get("locale"); GenericValue userLogin = (GenericValue) context.get("userLogin"); String orderId = (String) context.get("orderId"); // check and make sure we have permission to change the order Security security = ctx.getSecurity(); boolean hasPermission = OrderServices.hasPermission(orderId, userLogin, "UPDATE", security, delegator); if (!hasPermission) { return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderYouDoNotHavePermissionToChangeThisOrdersStatus", locale)); } // get the order header GenericValue orderHeader = null; try { orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId)); } catch (GenericEntityException e) { Debug.logError(e, "Cannot get OrderHeader record", module); } if (orderHeader == null) { Debug.logError("OrderHeader came back as null", module); return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderCannotUpdateNullOrderHeader", UtilMisc.toMap("orderId", orderId), locale)); } // get the order items List<GenericValue> orderItems = null; try { orderItems = delegator.findByAnd("OrderItem", UtilMisc.toMap("orderId", orderId)); } catch (GenericEntityException e) { Debug.logError(e, "Cannot get OrderItem records", module); return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderProblemGettingOrderItemRecords", locale)); } String orderHeaderStatusId = orderHeader.getString("statusId"); String orderTypeId = orderHeader.getString("orderTypeId"); boolean allCanceled = true; boolean allComplete = true; boolean allApproved = true; if (orderItems != null) { Iterator<GenericValue> itemIter = orderItems.iterator(); while (itemIter.hasNext()) { GenericValue item = itemIter.next(); String statusId = item.getString("statusId"); //Debug.log("Item Status: " + statusId, module); if (!"ITEM_CANCELLED".equals(statusId)) { //Debug.log("Not set to cancel", module); allCanceled = false; if (!"ITEM_COMPLETED".equals(statusId)) { //Debug.log("Not set to complete", module); allComplete = false; if (!"ITEM_APPROVED".equals(statusId)) { //Debug.log("Not set to approve", module); allApproved = false; break; } } } } // find the next status to set to (if any) String newStatus = null; if (allCanceled) { if (!"PURCHASE_ORDER".equals(orderTypeId)) { newStatus = "ORDER_CANCELLED"; } } else if (allComplete) { newStatus = "ORDER_COMPLETED"; } else if (allApproved) { boolean changeToApprove = true; // NOTE DEJ20070805 I'm not sure why we would want to auto-approve the header... adding at least this one exeption so that we don't have to add processing, held, etc statuses to the item status list // NOTE2 related to the above: appears this was a weird way to set the order header status by setting all order item statuses... changing that to be less weird and more direct // this is a bit of a pain: if the current statusId = ProductStore.headerApprovedStatus and we don't have that status in the history then we don't want to change it on approving the items if (UtilValidate.isNotEmpty(orderHeader.getString("productStoreId"))) { try { GenericValue productStore = delegator.findByPrimaryKey("ProductStore", UtilMisc.toMap("productStoreId", orderHeader.getString("productStoreId"))); if (productStore != null) { String headerApprovedStatus = productStore.getString("headerApprovedStatus"); if (UtilValidate.isNotEmpty(headerApprovedStatus)) { if (headerApprovedStatus.equals(orderHeaderStatusId)) { Map<String, Object> orderStatusCheckMap = UtilMisc.<String, Object>toMap( "orderId", orderId, "statusId", headerApprovedStatus, "orderItemSeqId", null); List<GenericValue> orderStatusList = delegator.findByAnd("OrderStatus", orderStatusCheckMap); // should be 1 in the history, but just in case accept 0 too if (orderStatusList.size() <= 1) { changeToApprove = false; } } } } } catch (GenericEntityException e) { String errMsg = "Database error checking if we should change order header status to approved: " + e.toString(); Debug.logError(e, errMsg, module); return ServiceUtil.returnError(errMsg); } } if ("ORDER_SENT".equals(orderHeaderStatusId)) changeToApprove = false; if ("ORDER_COMPLETED".equals(orderHeaderStatusId)) { if ("SALES_ORDER".equals(orderTypeId)) { changeToApprove = false; } } if ("ORDER_CANCELLED".equals(orderHeaderStatusId)) changeToApprove = false; if (changeToApprove) { newStatus = "ORDER_APPROVED"; } } // now set the new order status if (newStatus != null && !newStatus.equals(orderHeaderStatusId)) { Map<String, Object> serviceContext = UtilMisc.<String, Object>toMap("orderId", orderId, "statusId", newStatus, "userLogin", userLogin); Map<String, Object> newSttsResult = null; try { newSttsResult = dispatcher.runSync("changeOrderStatus", serviceContext); } catch (GenericServiceException e) { Debug.logError(e, "Problem calling the changeOrderStatus service", module); } if (ServiceUtil.isError(newSttsResult)) { return ServiceUtil.returnError(ServiceUtil.getErrorMessage(newSttsResult)); } } } else { Debug.logWarning(UtilProperties.getMessage(resource_error, "OrderReceivedNullForOrderItemRecordsOrderId", UtilMisc.toMap("orderId", orderId), locale), module); } return ServiceUtil.returnSuccess(); } /** Service to cancel an order item quantity */ public static Map<String, Object> cancelOrderItem(DispatchContext ctx, Map<String, ? extends Object> context) { LocalDispatcher dispatcher = ctx.getDispatcher(); Delegator delegator = ctx.getDelegator(); Locale locale = (Locale) context.get("locale"); GenericValue userLogin = (GenericValue) context.get("userLogin"); BigDecimal cancelQuantity = (BigDecimal) context.get("cancelQuantity"); String orderId = (String) context.get("orderId"); String orderItemSeqId = (String) context.get("orderItemSeqId"); String shipGroupSeqId = (String) context.get("shipGroupSeqId"); Map<String, String> itemReasonMap = UtilGenerics.checkMap(context.get("itemReasonMap")); Map<String, String> itemCommentMap = UtilGenerics.checkMap(context.get("itemCommentMap")); // debugging message info String itemMsgInfo = orderId + " / " + orderItemSeqId + " / " + shipGroupSeqId; // check and make sure we have permission to change the order Security security = ctx.getSecurity(); boolean hasPermission = OrderServices.hasPermission(orderId, userLogin, "UPDATE", security, delegator); if (!hasPermission) { return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderYouDoNotHavePermissionToChangeThisOrdersStatus", locale)); } Map<String, String> fields = UtilMisc.<String, String>toMap("orderId", orderId); if (orderItemSeqId != null) { fields.put("orderItemSeqId", orderItemSeqId); } if (shipGroupSeqId != null) { fields.put("shipGroupSeqId", shipGroupSeqId); } List<GenericValue> orderItemShipGroupAssocs = null; try { orderItemShipGroupAssocs = delegator.findByAnd("OrderItemShipGroupAssoc", fields); } catch (GenericEntityException e) { Debug.logError(e, module); return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderErrorCannotGetOrderItemAssocEntity", UtilMisc.toMap("itemMsgInfo", itemMsgInfo), locale)); } if (orderItemShipGroupAssocs != null) { Iterator<GenericValue> i = orderItemShipGroupAssocs.iterator(); while (i.hasNext()) { GenericValue orderItemShipGroupAssoc = i.next(); GenericValue orderItem = null; try { orderItem = orderItemShipGroupAssoc.getRelatedOne("OrderItem"); } catch (GenericEntityException e) { Debug.logError(e, module); } if (orderItem == null) { return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderErrorCannotCancelItemItemNotFound", UtilMisc.toMap("itemMsgInfo", itemMsgInfo), locale)); } BigDecimal aisgaCancelQuantity = orderItemShipGroupAssoc.getBigDecimal("cancelQuantity"); if (aisgaCancelQuantity == null) { aisgaCancelQuantity = BigDecimal.ZERO; } BigDecimal availableQuantity = orderItemShipGroupAssoc.getBigDecimal("quantity") .subtract(aisgaCancelQuantity); BigDecimal itemCancelQuantity = orderItem.getBigDecimal("cancelQuantity"); if (itemCancelQuantity == null) { itemCancelQuantity = BigDecimal.ZERO; } BigDecimal itemQuantity = orderItem.getBigDecimal("quantity").subtract(itemCancelQuantity); if (availableQuantity == null) availableQuantity = BigDecimal.ZERO; if (itemQuantity == null) itemQuantity = BigDecimal.ZERO; BigDecimal thisCancelQty = null; if (cancelQuantity != null) { thisCancelQty = cancelQuantity; } else { thisCancelQty = availableQuantity; } if (availableQuantity.compareTo(thisCancelQty) >= 0) { if (availableQuantity.compareTo(BigDecimal.ZERO) == 0) { continue; //OrderItemShipGroupAssoc already cancelled } orderItem.set("cancelQuantity", itemCancelQuantity.add(thisCancelQty)); orderItemShipGroupAssoc.set("cancelQuantity", aisgaCancelQuantity.add(thisCancelQty)); try { List<GenericValue> toStore = UtilMisc.toList(orderItem, orderItemShipGroupAssoc); delegator.storeAll(toStore); } catch (GenericEntityException e) { Debug.logError(e, module); return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderUnableToSetCancelQuantity", UtilMisc.toMap("itemMsgInfo", itemMsgInfo), locale)); } // create order item change record if (!"Y".equals(orderItem.getString("isPromo"))) { String reasonEnumId = null; String changeComments = null; if (UtilValidate.isNotEmpty(itemReasonMap)) { reasonEnumId = itemReasonMap.get(orderItem.getString("orderItemSeqId")); } if (UtilValidate.isNotEmpty(itemCommentMap)) { changeComments = itemCommentMap.get(orderItem.getString("orderItemSeqId")); } Map<String, Object> serviceCtx = FastMap.newInstance(); serviceCtx.put("orderId", orderItem.getString("orderId")); serviceCtx.put("orderItemSeqId", orderItem.getString("orderItemSeqId")); serviceCtx.put("cancelQuantity", thisCancelQty); serviceCtx.put("changeTypeEnumId", "ODR_ITM_CANCEL"); serviceCtx.put("reasonEnumId", reasonEnumId); serviceCtx.put("changeComments", changeComments); serviceCtx.put("userLogin", userLogin); Map<String, Object> resp = null; try { resp = dispatcher.runSync("createOrderItemChange", serviceCtx); } catch (GenericServiceException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } if (ServiceUtil.isError(resp)) { return ServiceUtil.returnError((String) resp.get(ModelService.ERROR_MESSAGE)); } } // log an order note try { BigDecimal quantity = thisCancelQty.setScale(1, orderRounding); String cancelledItemToOrder = UtilProperties.getMessage(resource, "OrderCancelledItemToOrder", locale); dispatcher.runSync("createOrderNote", UtilMisc.<String, Object>toMap( "orderId", orderId, "note", cancelledItemToOrder + orderItem.getString("productId") + " (" + quantity + ")", "internalNote", "Y", "userLogin", userLogin)); } catch (GenericServiceException e) { Debug.logError(e, module); } if (thisCancelQty.compareTo(itemQuantity) >= 0) { // all items are cancelled -- mark the item as cancelled Map<String, Object> statusCtx = UtilMisc.<String, Object>toMap("orderId", orderId, "orderItemSeqId", orderItem.getString("orderItemSeqId"), "statusId", "ITEM_CANCELLED", "userLogin", userLogin); try { dispatcher.runSyncIgnore("changeOrderItemStatus", statusCtx); } catch (GenericServiceException e) { Debug.logError(e, module); return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderUnableToCancelOrderLine", UtilMisc.toMap("itemMsgInfo", itemMsgInfo), locale)); } } else { // reverse the inventory reservation Map<String, Object> invCtx = UtilMisc.<String, Object>toMap("orderId", orderId, "orderItemSeqId", orderItem.getString("orderItemSeqId"), "shipGroupSeqId", shipGroupSeqId, "cancelQuantity", thisCancelQty, "userLogin", userLogin); try { dispatcher.runSyncIgnore("cancelOrderItemInvResQty", invCtx); } catch (GenericServiceException e) { Debug.logError(e, module); return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderUnableToUpdateInventoryReservations", UtilMisc.toMap("itemMsgInfo", itemMsgInfo), locale)); } } } else { return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderInvalidCancelQuantityCannotCancel", UtilMisc.toMap("thisCancelQty", thisCancelQty), locale)); } } } else { return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderErrorCannotCancelItemItemNotFound", UtilMisc.toMap("itemMsgInfo", itemMsgInfo), locale)); } return ServiceUtil.returnSuccess(); } /** Service for changing the status on order item(s) */ public static Map<String, Object> setItemStatus(DispatchContext ctx, Map<String, ? extends Object> context) { Delegator delegator = ctx.getDelegator(); GenericValue userLogin = (GenericValue) context.get("userLogin"); String orderId = (String) context.get("orderId"); String orderItemSeqId = (String) context.get("orderItemSeqId"); String fromStatusId = (String) context.get("fromStatusId"); String statusId = (String) context.get("statusId"); Timestamp statusDateTime = (Timestamp) context.get("statusDateTime"); Locale locale = (Locale) context.get("locale"); // check and make sure we have permission to change the order Security security = ctx.getSecurity(); boolean hasPermission = OrderServices.hasPermission(orderId, userLogin, "UPDATE", security, delegator); if (!hasPermission) { return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderYouDoNotHavePermissionToChangeThisOrdersStatus", locale)); } Map<String, String> fields = UtilMisc.<String, String>toMap("orderId", orderId); if (orderItemSeqId != null) fields.put("orderItemSeqId", orderItemSeqId); if (fromStatusId != null) fields.put("statusId", fromStatusId); List<GenericValue> orderItems = null; try { orderItems = delegator.findByAnd("OrderItem", fields); } catch (GenericEntityException e) { return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderErrorCannotGetOrderItemEntity", locale) + e.getMessage()); } if (UtilValidate.isNotEmpty(orderItems)) { List<GenericValue> toBeStored = new ArrayList<GenericValue>(); Iterator<GenericValue> itemsIterator = orderItems.iterator(); while (itemsIterator.hasNext()) { GenericValue orderItem = itemsIterator.next(); if (orderItem == null) { return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderErrorCannotChangeItemStatusItemNotFound", locale)); } if (Debug.verboseOn()) Debug.logVerbose("[OrderServices.setItemStatus] : Status Change: [" + orderId + "] (" + orderItem.getString("orderItemSeqId"), module); if (Debug.verboseOn()) Debug.logVerbose( "[OrderServices.setItemStatus] : From Status : " + orderItem.getString("statusId"), module); if (Debug.verboseOn()) Debug.logVerbose("[OrderServices.setOrderStatus] : To Status : " + statusId, module); if (orderItem.getString("statusId").equals(statusId)) { continue; } try { Map<String, String> statusFields = UtilMisc.<String, String>toMap("statusId", orderItem.getString("statusId"), "statusIdTo", statusId); GenericValue statusChange = delegator.findByPrimaryKeyCache("StatusValidChange", statusFields); if (statusChange == null) { Debug.logWarning(UtilProperties.getMessage(resource_error, "OrderItemStatusNotChangedIsNotAValidChange", UtilMisc.toMap("orderStatusId", orderItem.getString("statusId"), "statusId", statusId), locale), module); continue; } } catch (GenericEntityException e) { return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderErrorCouldNotChangeItemStatus", locale) + e.getMessage()); } orderItem.set("statusId", statusId); toBeStored.add(orderItem); if (statusDateTime == null) { statusDateTime = UtilDateTime.nowTimestamp(); } // now create a status change /* Map<String, Object> changeFields = new HashMap<String, Object>(); changeFields.put("orderStatusId", delegator.getNextSeqId("OrderStatus")); changeFields.put("statusId", statusId); changeFields.put("orderId", orderId); changeFields.put("orderItemSeqId", orderItem.getString("orderItemSeqId")); changeFields.put("statusDatetime", statusDateTime); changeFields.put("statusUserLogin", userLogin.getString("userLoginId")); GenericValue orderStatus = delegator.makeValue("OrderStatus", changeFields); toBeStored.add(orderStatus);*/ } // store the changes if (toBeStored.size() > 0) { try { delegator.storeAll(toBeStored); } catch (GenericEntityException e) { return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderErrorCannotStoreStatusChanges", locale) + e.getMessage()); } } } return ServiceUtil.returnSuccess(); } /** Service for changing the status on an order header */ public static Map<String, Object> setOrderStatus(DispatchContext ctx, Map<String, ? extends Object> context) { LocalDispatcher dispatcher = ctx.getDispatcher(); Delegator delegator = ctx.getDelegator(); GenericValue userLogin = (GenericValue) context.get("userLogin"); String orderId = (String) context.get("orderId"); String statusId = (String) context.get("statusId"); String comments = (String) context.get("comments"); Map<String, Object> successResult = ServiceUtil.returnSuccess(); Locale locale = (Locale) context.get("locale"); // check and make sure we have permission to change the order Security security = ctx.getSecurity(); boolean hasPermission = OrderServices.hasPermission(orderId, userLogin, "UPDATE", security, delegator); if (!hasPermission) { return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderYouDoNotHavePermissionToChangeThisOrdersStatus", locale)); } if ("Y".equals(context.get("setItemStatus"))) { String newItemStatusId = null; if ("ORDER_APPROVED".equals(statusId)) { newItemStatusId = "ITEM_APPROVED"; } else if ("ORDER_COMPLETED".equals(statusId)) { newItemStatusId = "ITEM_COMPLETED"; } else if ("ORDER_CANCELLED".equals(statusId)) { newItemStatusId = "ITEM_CANCELLED"; } if (newItemStatusId != null) { try { Map<String, Object> resp = dispatcher.runSync("changeOrderItemStatus", UtilMisc.<String, Object>toMap("orderId", orderId, "statusId", newItemStatusId, "userLogin", userLogin)); if (ServiceUtil.isError(resp)) { return ServiceUtil .returnError( UtilProperties.getMessage(resource_error, "OrderErrorCouldNotChangeItemStatus", locale) + newItemStatusId, null, null, resp); } } catch (GenericServiceException e) { Debug.logError(e, "Error changing item status to " + newItemStatusId + ": " + e.toString(), module); return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderErrorCouldNotChangeItemStatus", locale) + newItemStatusId + ": " + e.toString()); } } } try { GenericValue orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId)); if (orderHeader == null) { return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderErrorCouldNotChangeOrderStatusOrderCannotBeFound", locale)); } // first save off the old status successResult.put("oldStatusId", orderHeader.get("statusId")); if (Debug.verboseOn()) Debug.logVerbose( "[OrderServices.setOrderStatus] : From Status : " + orderHeader.getString("statusId"), module); if (Debug.verboseOn()) Debug.logVerbose("[OrderServices.setOrderStatus] : To Status : " + statusId, module); if (orderHeader.getString("statusId").equals(statusId)) { Debug.logWarning(UtilProperties.getMessage(resource_error, "OrderTriedToSetOrderStatusWithTheSameStatusIdforOrderWithId", UtilMisc.toMap("statusId", statusId, "orderId", orderId), locale), module); return successResult; } try { Map<String, String> statusFields = UtilMisc.<String, String>toMap("statusId", orderHeader.getString("statusId"), "statusIdTo", statusId); GenericValue statusChange = delegator.findByPrimaryKeyCache("StatusValidChange", statusFields); if (statusChange == null) { return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderErrorCouldNotChangeOrderStatusStatusIsNotAValidChange", locale) + ": [" + statusFields.get("statusId") + "] -> [" + statusFields.get("statusIdTo") + "]"); } } catch (GenericEntityException e) { return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderErrorCouldNotChangeOrderStatus", locale) + e.getMessage() + ")."); } // update the current status orderHeader.set("statusId", statusId); orderHeader.set("comments", comments); // now create a status change GenericValue orderStatus = delegator.makeValue("OrderStatus"); orderStatus.put("orderStatusId", delegator.getNextSeqId("OrderStatus")); orderStatus.put("statusId", statusId); orderStatus.put("orderId", orderId); orderStatus.put("statusDatetime", UtilDateTime.nowTimestamp()); orderStatus.put("statusUserLogin", userLogin.getString("userLoginId")); orderHeader.store(); orderStatus.create(); successResult.put("needsInventoryIssuance", orderHeader.get("needsInventoryIssuance")); successResult.put("grandTotal", orderHeader.get("grandTotal")); successResult.put("orderTypeId", orderHeader.get("orderTypeId")); //Debug.logInfo("For setOrderStatus orderHeader is " + orderHeader, module); } catch (GenericEntityException e) { return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderErrorCouldNotChangeOrderStatus", locale) + e.getMessage() + ")."); } // release the inital hold if we are cancelled or approved if ("ORDER_CANCELLED".equals(statusId) || "ORDER_APPROVED".equals(statusId)) { OrderChangeHelper.releaseInitialOrderHold(ctx.getDispatcher(), orderId); // cancel any order processing if we are cancelled if ("ORDER_CANCELLED".equals(statusId)) { OrderChangeHelper.abortOrderProcessing(ctx.getDispatcher(), orderId); } } successResult.put("orderStatusId", statusId); //Debug.logInfo("For setOrderStatus successResult is " + successResult, module); return successResult; } /** Service to update the order tracking number */ public static Map<String, Object> updateTrackingNumber(DispatchContext dctx, Map<String, ? extends Object> context) { Map<String, Object> result = new HashMap<String, Object>(); Delegator delegator = dctx.getDelegator(); String orderId = (String) context.get("orderId"); String shipGroupSeqId = (String) context.get("shipGroupSeqId"); String trackingNumber = (String) context.get("trackingNumber"); //Locale locale = (Locale) context.get("locale"); try { GenericValue shipGroup = delegator.findByPrimaryKey("OrderItemShipGroup", UtilMisc.toMap("orderId", orderId, "shipGroupSeqId", shipGroupSeqId)); if (shipGroup == null) { result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR); result.put(ModelService.ERROR_MESSAGE, "ERROR: No order shipment preference found!"); } else { shipGroup.set("trackingNumber", trackingNumber); shipGroup.store(); result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS); } } catch (GenericEntityException e) { Debug.logError(e, module); result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR); result.put(ModelService.ERROR_MESSAGE, "ERROR: Could not set tracking number (" + e.getMessage() + ")."); } return result; } /** Service to add a role type to an order */ public static Map<String, Object> addRoleType(DispatchContext ctx, Map<String, ? extends Object> context) { Map<String, Object> result = new HashMap<String, Object>(); Delegator delegator = ctx.getDelegator(); String orderId = (String) context.get("orderId"); String partyId = (String) context.get("partyId"); String roleTypeId = (String) context.get("roleTypeId"); Boolean removeOld = (Boolean) context.get("removeOld"); //Locale locale = (Locale) context.get("locale"); if (removeOld != null && removeOld.booleanValue()) { try { delegator.removeByAnd("OrderRole", UtilMisc.toMap("orderId", orderId, "roleTypeId", roleTypeId)); } catch (GenericEntityException e) { result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR); result.put(ModelService.ERROR_MESSAGE, "ERROR: Could not remove old roles (" + e.getMessage() + ")."); return result; } } Map<String, String> fields = UtilMisc.<String, String>toMap("orderId", orderId, "partyId", partyId, "roleTypeId", roleTypeId); try { // first check and see if we are already there; if so, just return success GenericValue testValue = delegator.findByPrimaryKey("OrderRole", fields); if (testValue != null) { ServiceUtil.returnSuccess(); } else { GenericValue value = delegator.makeValue("OrderRole", fields); delegator.create(value); } } catch (GenericEntityException e) { result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR); result.put(ModelService.ERROR_MESSAGE, "ERROR: Could not add role to order (" + e.getMessage() + ")."); return result; } result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS); return result; } /** Service to remove a role type from an order */ public static Map<String, Object> removeRoleType(DispatchContext ctx, Map<String, ? extends Object> context) { Map<String, Object> result = new HashMap<String, Object>(); Delegator delegator = ctx.getDelegator(); String orderId = (String) context.get("orderId"); String partyId = (String) context.get("partyId"); String roleTypeId = (String) context.get("roleTypeId"); Map<String, String> fields = UtilMisc.<String, String>toMap("orderId", orderId, "partyId", partyId, "roleTypeId", roleTypeId); //Locale locale = (Locale) context.get("locale"); GenericValue testValue = null; try { testValue = delegator.findByPrimaryKey("OrderRole", fields); } catch (GenericEntityException e) { result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR); result.put(ModelService.ERROR_MESSAGE, "ERROR: Could not add role to order (" + e.getMessage() + ")."); return result; } if (testValue == null) { result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS); return result; } try { GenericValue value = delegator.findByPrimaryKey("OrderRole", fields); value.remove(); } catch (GenericEntityException e) { result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR); result.put(ModelService.ERROR_MESSAGE, "ERROR: Could not remove role from order (" + e.getMessage() + ")."); return result; } result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS); return result; } /** Service to email a customer with initial order confirmation */ public static Map<String, Object> sendOrderConfirmNotification(DispatchContext ctx, Map<String, ? extends Object> context) { return sendOrderNotificationScreen(ctx, context, "PRDS_ODR_CONFIRM"); } /** Service to email a customer with order changes */ public static Map<String, Object> sendOrderCompleteNotification(DispatchContext ctx, Map<String, ? extends Object> context) { return sendOrderNotificationScreen(ctx, context, "PRDS_ODR_COMPLETE"); } /** Service to email a customer with order changes */ public static Map<String, Object> sendOrderBackorderNotification(DispatchContext ctx, Map<String, ? extends Object> context) { return sendOrderNotificationScreen(ctx, context, "PRDS_ODR_BACKORDER"); } /** Service to email a customer with order changes */ public static Map<String, Object> sendOrderChangeNotification(DispatchContext ctx, Map<String, ? extends Object> context) { return sendOrderNotificationScreen(ctx, context, "PRDS_ODR_CHANGE"); } /** Service to email a customer with order payment retry results */ public static Map<String, Object> sendOrderPayRetryNotification(DispatchContext ctx, Map<String, ? extends Object> context) { return sendOrderNotificationScreen(ctx, context, "PRDS_ODR_PAYRETRY"); } protected static Map<String, Object> sendOrderNotificationScreen(DispatchContext dctx, Map<String, ? extends Object> context, String emailType) { LocalDispatcher dispatcher = dctx.getDispatcher(); Delegator delegator = dctx.getDelegator(); GenericValue userLogin = (GenericValue) context.get("userLogin"); String orderId = (String) context.get("orderId"); String orderItemSeqId = (String) context.get("orderItemSeqId"); String sendTo = (String) context.get("sendTo"); String sendCc = (String) context.get("sendCc"); String note = (String) context.get("note"); String screenUri = (String) context.get("screenUri"); GenericValue temporaryAnonymousUserLogin = (GenericValue) context.get("temporaryAnonymousUserLogin"); Locale localePar = (Locale) context.get("locale"); if (userLogin == null) { // this may happen during anonymous checkout, try to the special case user userLogin = temporaryAnonymousUserLogin; } // prepare the order information Map<String, Object> sendMap = FastMap.newInstance(); // get the order header and store GenericValue orderHeader = null; try { orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId)); } catch (GenericEntityException e) { Debug.logError(e, "Problem getting OrderHeader", module); } if (orderHeader == null) { return ServiceUtil.returnFailure(UtilProperties.getMessage(resource, "OrderOrderNotFound", UtilMisc.toMap("orderId", orderId), localePar)); } if (orderHeader.get("webSiteId") == null) { return ServiceUtil.returnFailure(UtilProperties.getMessage(resource, "OrderOrderWithoutWebSite", UtilMisc.toMap("orderId", orderId), localePar)); } GenericValue productStoreEmail = null; try { productStoreEmail = delegator.findByPrimaryKey("ProductStoreEmailSetting", UtilMisc.toMap("productStoreId", orderHeader.get("productStoreId"), "emailType", emailType)); } catch (GenericEntityException e) { Debug.logError(e, "Problem getting the ProductStoreEmailSetting for productStoreId=" + orderHeader.get("productStoreId") + " and emailType=" + emailType, module); } if (productStoreEmail == null) { return ServiceUtil.returnFailure(UtilProperties.getMessage(resourceProduct, "ProductProductStoreEmailSettingsNotValid", UtilMisc.toMap("productStoreId", orderHeader.get("productStoreId"), "emailType", emailType), localePar)); } // the override screenUri if (UtilValidate.isEmpty(screenUri)) { String bodyScreenLocation = productStoreEmail.getString("bodyScreenLocation"); if (UtilValidate.isEmpty(bodyScreenLocation)) { bodyScreenLocation = ProductStoreWorker.getDefaultProductStoreEmailScreenLocation(emailType); } sendMap.put("bodyScreenUri", bodyScreenLocation); String xslfoAttachScreenLocation = productStoreEmail.getString("xslfoAttachScreenLocation"); sendMap.put("xslfoAttachScreenLocation", xslfoAttachScreenLocation); } else { sendMap.put("bodyScreenUri", screenUri); } // website sendMap.put("webSiteId", orderHeader.get("webSiteId")); OrderReadHelper orh = new OrderReadHelper(orderHeader); String emailString = orh.getOrderEmailString(); if (UtilValidate.isEmpty(emailString)) { Debug.logInfo("Customer is not setup to receive emails; no address(s) found [" + orderId + "]", module); return ServiceUtil.returnFailure(UtilProperties.getMessage(resource, "OrderOrderWithoutEmailAddress", UtilMisc.toMap("orderId", orderId), localePar)); } // where to get the locale... from PLACING_CUSTOMER's UserLogin.lastLocale, // or if not available then from ProductStore.defaultLocaleString // or if not available then the system Locale Locale locale = null; GenericValue placingParty = orh.getPlacingParty(); GenericValue placingUserLogin = placingParty == null ? null : PartyWorker.findPartyLatestUserLogin(placingParty.getString("partyId"), delegator); if (locale == null && placingParty != null) { locale = PartyWorker.findPartyLastLocale(placingParty.getString("partyId"), delegator); } // for anonymous orders, use the temporaryAnonymousUserLogin as the placingUserLogin will be null if (placingUserLogin == null) { placingUserLogin = temporaryAnonymousUserLogin; } GenericValue productStore = OrderReadHelper.getProductStoreFromOrder(orderHeader); if (locale == null && productStore != null) { String localeString = productStore.getString("defaultLocaleString"); if (UtilValidate.isNotEmpty(localeString)) { locale = UtilMisc.parseLocale(localeString); } } if (locale == null) { locale = Locale.getDefault(); } Map<String, Object> bodyParameters = UtilMisc.<String, Object>toMap("orderId", orderId, "orderItemSeqId", orderItemSeqId, "userLogin", placingUserLogin, "locale", locale); if (placingParty != null) { bodyParameters.put("partyId", placingParty.get("partyId")); } bodyParameters.put("note", note); sendMap.put("bodyParameters", bodyParameters); sendMap.put("userLogin", userLogin); String subjectString = productStoreEmail.getString("subject"); sendMap.put("subject", subjectString); sendMap.put("contentType", productStoreEmail.get("contentType")); sendMap.put("sendFrom", productStoreEmail.get("fromAddress")); sendMap.put("sendCc", productStoreEmail.get("ccAddress")); sendMap.put("sendBcc", productStoreEmail.get("bccAddress")); if ((sendTo != null) && UtilValidate.isEmail(sendTo)) { sendMap.put("sendTo", sendTo); } else { sendMap.put("sendTo", emailString); } if ((sendCc != null) && UtilValidate.isEmail(sendCc)) { sendMap.put("sendCc", sendCc); } else { sendMap.put("sendCc", productStoreEmail.get("ccAddress")); } // send the notification Map<String, Object> sendResp = null; try { sendResp = dispatcher.runSync("sendMailFromScreen", sendMap); } catch (Exception e) { Debug.logError(e, module); return ServiceUtil .returnError(UtilProperties.getMessage(resource_error, "OrderServiceExceptionSeeLogs", locale)); } // check for errors if (sendResp != null && !ServiceUtil.isError(sendResp)) { sendResp.put("emailType", emailType); } if (UtilValidate.isNotEmpty(orderId)) { sendResp.put("orderId", orderId); } return sendResp; } /** Service to email order notifications for pending actions */ public static Map<String, Object> sendProcessNotification(DispatchContext ctx, Map<String, ? extends Object> context) { //appears to not be used: Map result = new HashMap(); Delegator delegator = ctx.getDelegator(); LocalDispatcher dispatcher = ctx.getDispatcher(); String adminEmailList = (String) context.get("adminEmailList"); String assignedToUser = (String) context.get("assignedPartyId"); //appears to not be used: String assignedToRole = (String) context.get("assignedRoleTypeId"); String workEffortId = (String) context.get("workEffortId"); Locale locale = (Locale) context.get("locale"); GenericValue workEffort = null; GenericValue orderHeader = null; //appears to not be used: String assignedEmail = null; // get the order/workflow info try { workEffort = delegator.findByPrimaryKey("WorkEffort", UtilMisc.toMap("workEffortId", workEffortId)); String sourceReferenceId = workEffort.getString("sourceReferenceId"); if (sourceReferenceId != null) orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", sourceReferenceId)); } catch (GenericEntityException e) { return ServiceUtil .returnError(UtilProperties.getMessage(resource_error, "OrderProblemWithEntityLookup", locale)); } // find the assigned user's email address(s) GenericValue party = null; Collection<GenericValue> assignedToEmails = null; try { party = delegator.findByPrimaryKey("Party", UtilMisc.toMap("partyId", assignedToUser)); } catch (GenericEntityException e) { return ServiceUtil .returnError(UtilProperties.getMessage(resource_error, "OrderProblemWithEntityLookup", locale)); } if (party != null) { assignedToEmails = ContactHelper.getContactMechByPurpose(party, "PRIMARY_EMAIL", false); } Map<String, Object> templateData = new HashMap<String, Object>(context); templateData.putAll(orderHeader); templateData.putAll(workEffort); /* NOTE DEJ20080609 commenting out this code because the old OFBiz Workflow Engine is being deprecated and this was only for that String omgStatusId = WfUtil.getOMGStatus(workEffort.getString("currentStatusId")); templateData.put("omgStatusId", omgStatusId); */ templateData.put("omgStatusId", workEffort.getString("currentStatusId")); // get the assignments List<GenericValue> assignments = null; if (workEffort != null) { try { assignments = workEffort.getRelated("WorkEffortPartyAssignment"); } catch (GenericEntityException e1) { Debug.logError(e1, "Problems getting assignements", module); } } templateData.put("assignments", assignments); StringBuilder emailList = new StringBuilder(); if (assignedToEmails != null) { Iterator<GenericValue> aei = assignedToEmails.iterator(); while (aei.hasNext()) { GenericValue ct = aei.next(); if (ct != null && ct.get("infoString") != null) { if (emailList.length() > 1) emailList.append(","); emailList.append(ct.getString("infoString")); } } } if (adminEmailList != null) { if (emailList.length() > 1) emailList.append(","); emailList.append(adminEmailList); } // prepare the mail info String ofbizHome = System.getProperty("ofbiz.home"); String templateName = ofbizHome + "/applications/order/email/default/emailprocessnotify.ftl"; Map<String, Object> sendMailContext = new HashMap<String, Object>(); sendMailContext.put("sendTo", emailList.toString()); sendMailContext.put("sendFrom", "workflow@ofbiz.org"); // fixme sendMailContext.put("subject", "Workflow Notification"); sendMailContext.put("templateName", templateName); sendMailContext.put("templateData", templateData); try { dispatcher.runAsync("sendGenericNotificationEmail", sendMailContext); } catch (GenericServiceException e) { return ServiceUtil .returnError(UtilProperties.getMessage(resource_error, "OrderSendMailServiceFailed", locale) + e.getMessage()); } return ServiceUtil.returnSuccess(); } /** Service to create an order payment preference */ public static Map<String, Object> createPaymentPreference(DispatchContext ctx, Map<String, ? extends Object> context) { Map<String, Object> result = new HashMap<String, Object>(); Delegator delegator = ctx.getDelegator(); String orderId = (String) context.get("orderId"); String statusId = (String) context.get("statusId"); String paymentMethodTypeId = (String) context.get("paymentMethodTypeId"); String paymentMethodId = (String) context.get("paymentMethodId"); BigDecimal maxAmount = (BigDecimal) context.get("maxAmount"); GenericValue userLogin = (GenericValue) context.get("userLogin"); Locale locale = (Locale) context.get("locale"); String prefId = null; try { prefId = delegator.getNextSeqId("OrderPaymentPreference"); } catch (IllegalArgumentException e) { return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderErrorCouldNotCreateOrderPaymentPreferenceIdGenerationFailure", locale)); } Map<String, Object> fields = UtilMisc.<String, Object>toMap("orderPaymentPreferenceId", prefId, "orderId", orderId, "paymentMethodTypeId", paymentMethodTypeId, "paymentMethodId", paymentMethodId, "maxAmount", maxAmount); if (statusId != null) { fields.put("statusId", statusId); } try { GenericValue v = delegator.makeValue("OrderPaymentPreference", fields); v.set("createdDate", UtilDateTime.nowTimestamp()); if (userLogin != null) { v.set("createdByUserLogin", userLogin.getString("userLoginId")); } delegator.create(v); } catch (GenericEntityException e) { result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR); result.put(ModelService.ERROR_MESSAGE, UtilProperties.getMessage(resource, "OrderOrderPaymentPreferencesCannotBeCreated", UtilMisc.toMap("errorString", e.getMessage()), locale)); return ServiceUtil.returnFailure(); } result.put("orderPaymentPreferenceId", prefId); result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS); return result; } /** Service to get order header information as standard results. */ public static Map<String, Object> getOrderHeaderInformation(DispatchContext dctx, Map<String, ? extends Object> context) { Delegator delegator = dctx.getDelegator(); String orderId = (String) context.get("orderId"); Locale locale = (Locale) context.get("locale"); GenericValue orderHeader = null; try { orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId)); } catch (GenericEntityException e) { Debug.logError(e, "Problem getting order header detial", module); return ServiceUtil .returnError(UtilProperties.getMessage(resource_error, "OrderCannotGetOrderHeader", locale) + e.getMessage()); } if (orderHeader != null) { Map<String, Object> result = ServiceUtil.returnSuccess(); result.putAll(orderHeader); return result; } return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderErrorGettingOrderHeaderInformationNull", locale)); } /** Service to get the total shipping for an order. */ public static Map<String, Object> getOrderShippingAmount(DispatchContext dctx, Map<String, ? extends Object> context) { Delegator delegator = dctx.getDelegator(); String orderId = (String) context.get("orderId"); Locale locale = (Locale) context.get("locale"); GenericValue orderHeader = null; try { orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId)); } catch (GenericEntityException e) { Debug.logError(e, module); return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderErrorCouldNotGetOrderInformation", locale) + e.getMessage() + ")."); } Map<String, Object> result = null; if (orderHeader != null) { OrderReadHelper orh = new OrderReadHelper(orderHeader); List<GenericValue> orderItems = orh.getValidOrderItems(); List<GenericValue> orderAdjustments = orh.getAdjustments(); List<GenericValue> orderHeaderAdjustments = orh.getOrderHeaderAdjustments(); BigDecimal orderSubTotal = orh.getOrderItemsSubTotal(); BigDecimal shippingAmount = OrderReadHelper.getAllOrderItemsAdjustmentsTotal(orderItems, orderAdjustments, false, false, true); shippingAmount = shippingAmount.add(OrderReadHelper.calcOrderAdjustments(orderHeaderAdjustments, orderSubTotal, false, false, true)); result = ServiceUtil.returnSuccess(); result.put("shippingAmount", shippingAmount); } else { result = ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderUnableToFindOrderHeaderCannotGetShippingAmount", locale)); } return result; } /** Service to get an order contact mech. */ public static Map<String, Object> getOrderAddress(DispatchContext dctx, Map<String, ? extends Object> context) { Map<String, Object> result = new HashMap<String, Object>(); Delegator delegator = dctx.getDelegator(); String orderId = (String) context.get("orderId"); Locale locale = (Locale) context.get("locale"); //appears to not be used: GenericValue v = null; String purpose[] = { "BILLING_LOCATION", "SHIPPING_LOCATION" }; String outKey[] = { "billingAddress", "shippingAddress" }; GenericValue orderHeader = null; //Locale locale = (Locale) context.get("locale"); try { orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId)); if (orderHeader != null) result.put("orderHeader", orderHeader); } catch (GenericEntityException e) { result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR); result.put(ModelService.ERROR_MESSAGE, UtilProperties.getMessage(resource, "OrderOrderNotFound", UtilMisc.toMap("orderId", orderId), locale)); return result; } if (orderHeader == null) { result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR); result.put(ModelService.ERROR_MESSAGE, UtilProperties.getMessage(resource, "OrderOrderNotFound", UtilMisc.toMap("orderId", orderId), locale)); return result; } for (int i = 0; i < purpose.length; i++) { try { GenericValue orderContactMech = EntityUtil.getFirst(orderHeader.getRelatedByAnd("OrderContactMech", UtilMisc.toMap("contactMechPurposeTypeId", purpose[i]))); GenericValue contactMech = orderContactMech.getRelatedOne("ContactMech"); if (contactMech != null) { result.put(outKey[i], contactMech.getRelatedOne("PostalAddress")); } } catch (GenericEntityException e) { result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR); result.put(ModelService.ERROR_MESSAGE, UtilProperties.getMessage(resource, "OrderOrderContachMechNotFound", UtilMisc.toMap("errorString", e.getMessage()), locale)); return result; } } result.put("orderId", orderId); return result; } /** Service to create a order header note. */ public static Map<String, Object> createOrderNote(DispatchContext dctx, Map<String, ? extends Object> context) { Delegator delegator = dctx.getDelegator(); LocalDispatcher dispatcher = dctx.getDispatcher(); GenericValue userLogin = (GenericValue) context.get("userLogin"); String noteString = (String) context.get("note"); String noteName = (String) context.get("noteName"); String orderId = (String) context.get("orderId"); String internalNote = (String) context.get("internalNote"); Map<String, Object> noteCtx = UtilMisc.<String, Object>toMap("note", noteString, "userLogin", userLogin, "noteName", noteName); Locale locale = (Locale) context.get("locale"); try { // Store the note. Map<String, Object> noteRes = dispatcher.runSync("createNote", noteCtx); if (ServiceUtil.isError(noteRes)) return noteRes; String noteId = (String) noteRes.get("noteId"); if (UtilValidate.isEmpty(noteId)) { return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderProblemCreatingTheNoteNoNoteIdReturned", locale)); } // Set the order info Map<String, String> fields = UtilMisc.<String, String>toMap("orderId", orderId, "noteId", noteId, "internalNote", internalNote); GenericValue v = delegator.makeValue("OrderHeaderNote", fields); delegator.create(v); } catch (GenericEntityException ee) { Debug.logError(ee, module); return ServiceUtil.returnError(UtilProperties.getMessage(resource, "OrderOrderNoteCannotBeCreated", UtilMisc.toMap("errorString", ee.getMessage()), locale)); } catch (GenericServiceException se) { Debug.logError(se, module); return ServiceUtil.returnError(UtilProperties.getMessage(resource, "OrderOrderNoteCannotBeCreated", UtilMisc.toMap("errorString", se.getMessage()), locale)); } return ServiceUtil.returnSuccess(); } public static Map<String, Object> allowOrderSplit(DispatchContext ctx, Map<String, ? extends Object> context) { Delegator delegator = ctx.getDelegator(); GenericValue userLogin = (GenericValue) context.get("userLogin"); String orderId = (String) context.get("orderId"); String shipGroupSeqId = (String) context.get("shipGroupSeqId"); Locale locale = (Locale) context.get("locale"); // check and make sure we have permission to change the order Security security = ctx.getSecurity(); if (!security.hasEntityPermission("ORDERMGR", "_UPDATE", userLogin)) { GenericValue placingCustomer = null; try { Map<String, Object> placingCustomerFields = UtilMisc.<String, Object>toMap("orderId", orderId, "partyId", userLogin.getString("partyId"), "roleTypeId", "PLACING_CUSTOMER"); placingCustomer = delegator.findByPrimaryKey("OrderRole", placingCustomerFields); } catch (GenericEntityException e) { return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderErrorCannotGetOrderRoleEntity", locale) + e.getMessage()); } if (placingCustomer == null) { return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderYouDoNotHavePermissionToChangeThisOrdersStatus", locale)); } } GenericValue shipGroup = null; try { Map<String, String> fields = UtilMisc.<String, String>toMap("orderId", orderId, "shipGroupSeqId", shipGroupSeqId); shipGroup = delegator.findByPrimaryKey("OrderItemShipGroup", fields); } catch (GenericEntityException e) { Debug.logError(e, "Problems getting OrderItemShipGroup for : " + orderId + " / " + shipGroupSeqId, module); return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderCannotUpdateProblemGettingOrderShipmentPreference", locale)); } if (shipGroup != null) { shipGroup.set("maySplit", "Y"); try { shipGroup.store(); } catch (GenericEntityException e) { Debug.logError("Problem saving OrderItemShipGroup for : " + orderId + " / " + shipGroupSeqId, module); return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderCannotUpdateProblemSettingOrderShipmentPreference", locale)); } } else { Debug.logError("ERROR: Got a NULL OrderItemShipGroup", module); return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderCannotUpdateNoAvailableGroupsToChange", locale)); } return ServiceUtil.returnSuccess(); } @SuppressWarnings("unchecked") public static Map<String, Object> cancelFlaggedSalesOrders(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"); List<GenericValue> ordersToCheck = null; // create the query expressions List<EntityExpr> exprs = UtilMisc.toList( EntityCondition.makeCondition("orderTypeId", EntityOperator.EQUALS, "SALES_ORDER"), EntityCondition.makeCondition("statusId", EntityOperator.NOT_EQUAL, "ORDER_COMPLETED"), EntityCondition.makeCondition("statusId", EntityOperator.NOT_EQUAL, "ORDER_CANCELLED"), EntityCondition.makeCondition("statusId", EntityOperator.NOT_EQUAL, "ORDER_REJECTED")); EntityConditionList<EntityExpr> ecl = EntityCondition.makeCondition(exprs, EntityOperator.AND); // get the orders try { ordersToCheck = delegator.findList("OrderHeader", ecl, null, UtilMisc.toList("orderDate"), null, false); } catch (GenericEntityException e) { Debug.logError(e, "Problem getting order headers", module); } if (UtilValidate.isEmpty(ordersToCheck)) { Debug.logInfo("No orders to check, finished", module); return ServiceUtil.returnSuccess(); } Timestamp nowTimestamp = UtilDateTime.nowTimestamp(); Iterator<GenericValue> i = ordersToCheck.iterator(); while (i.hasNext()) { GenericValue orderHeader = i.next(); String orderId = orderHeader.getString("orderId"); String orderStatus = orderHeader.getString("statusId"); if (orderStatus.equals("ORDER_CREATED")) { // first check for un-paid orders Timestamp orderDate = orderHeader.getTimestamp("entryDate"); // need the store for the order GenericValue productStore = null; try { productStore = orderHeader.getRelatedOne("ProductStore"); } catch (GenericEntityException e) { Debug.logError(e, "Unable to get ProductStore from OrderHeader", module); } // default days to cancel int daysTillCancel = 30; // get the value from the store if (productStore != null && productStore.get("daysToCancelNonPay") != null) { daysTillCancel = productStore.getLong("daysToCancelNonPay").intValue(); } if (daysTillCancel > 0) { // 0 days means do not auto-cancel Calendar cal = Calendar.getInstance(); cal.setTimeInMillis(orderDate.getTime()); cal.add(Calendar.DAY_OF_YEAR, daysTillCancel); Date cancelDate = cal.getTime(); Date nowDate = new Date(); //Debug.log("Cancel Date : " + cancelDate, module); //Debug.log("Current Date : " + nowDate, module); if (cancelDate.equals(nowDate) || nowDate.after(cancelDate)) { // cancel the order item(s) Map<String, Object> svcCtx = UtilMisc.<String, Object>toMap("orderId", orderId, "statusId", "ITEM_CANCELLED", "userLogin", userLogin); try { // TODO: looks like result is ignored here, but we should be looking for errors dispatcher.runSync("changeOrderItemStatus", svcCtx); } catch (GenericServiceException e) { Debug.logError(e, "Problem calling change item status service : " + svcCtx, module); } } } } else { // check for auto-cancel items List itemsExprs = new ArrayList(); // create the query expressions itemsExprs.add(EntityCondition.makeCondition("orderId", EntityOperator.EQUALS, orderId)); itemsExprs.add(EntityCondition.makeCondition( UtilMisc.toList( EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, "ITEM_CREATED"), EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, "ITEM_APPROVED")), EntityOperator.OR)); itemsExprs.add(EntityCondition.makeCondition("dontCancelSetUserLogin", EntityOperator.EQUALS, GenericEntity.NULL_FIELD)); itemsExprs.add(EntityCondition.makeCondition("dontCancelSetDate", EntityOperator.EQUALS, GenericEntity.NULL_FIELD)); itemsExprs.add(EntityCondition.makeCondition("autoCancelDate", EntityOperator.NOT_EQUAL, GenericEntity.NULL_FIELD)); ecl = EntityCondition.makeCondition(itemsExprs); List<GenericValue> orderItems = null; try { orderItems = delegator.findList("OrderItem", ecl, null, null, null, false); } catch (GenericEntityException e) { Debug.logError(e, "Problem getting order item records", module); } if (UtilValidate.isNotEmpty(orderItems)) { Iterator<GenericValue> oii = orderItems.iterator(); while (oii.hasNext()) { GenericValue orderItem = oii.next(); String orderItemSeqId = orderItem.getString("orderItemSeqId"); Timestamp autoCancelDate = orderItem.getTimestamp("autoCancelDate"); if (autoCancelDate != null) { if (nowTimestamp.equals(autoCancelDate) || nowTimestamp.after(autoCancelDate)) { // cancel the order item Map<String, Object> svcCtx = UtilMisc.<String, Object>toMap("orderId", orderId, "orderItemSeqId", orderItemSeqId, "statusId", "ITEM_CANCELLED", "userLogin", userLogin); try { // TODO: check service result for an error return dispatcher.runSync("changeOrderItemStatus", svcCtx); } catch (GenericServiceException e) { Debug.logError(e, "Problem calling change item status service : " + svcCtx, module); } } } } } } } return ServiceUtil.returnSuccess(); } public static Map<String, Object> checkDigitalItemFulfillment(DispatchContext dctx, Map<String, ? extends Object> context) { Delegator delegator = dctx.getDelegator(); LocalDispatcher dispatcher = dctx.getDispatcher(); GenericValue userLogin = (GenericValue) context.get("userLogin"); String orderId = (String) context.get("orderId"); Locale locale = (Locale) context.get("locale"); // need the order header GenericValue orderHeader = null; try { orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId)); } catch (GenericEntityException e) { Debug.logError(e, "ERROR: Unable to get OrderHeader for orderId : " + orderId, module); return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderErrorUnableToGetOrderHeaderForOrderId", UtilMisc.toMap("orderId", orderId), locale)); } // get all the items for the order List<GenericValue> orderItems = null; if (orderHeader != null) { try { orderItems = orderHeader.getRelated("OrderItem"); } catch (GenericEntityException e) { Debug.logError(e, "ERROR: Unable to get OrderItem list for orderId : " + orderId, module); return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderErrorUnableToGetOrderItemListForOrderId", UtilMisc.toMap("orderId", orderId), locale)); } } // find any digital or non-product items List<GenericValue> nonProductItems = new ArrayList<GenericValue>(); List<GenericValue> digitalItems = new ArrayList<GenericValue>(); Map<GenericValue, GenericValue> digitalProducts = new HashMap<GenericValue, GenericValue>(); if (UtilValidate.isNotEmpty(orderItems)) { Iterator<GenericValue> i = orderItems.iterator(); while (i.hasNext()) { GenericValue item = i.next(); GenericValue product = null; try { product = item.getRelatedOne("Product"); } catch (GenericEntityException e) { Debug.logError(e, "ERROR: Unable to get Product from OrderItem", module); } if (product != null) { GenericValue productType = null; try { productType = product.getRelatedOne("ProductType"); } catch (GenericEntityException e) { Debug.logError(e, "ERROR: Unable to get ProductType from Product", module); } if (productType != null) { String isPhysical = productType.getString("isPhysical"); String isDigital = productType.getString("isDigital"); // check for digital and finished/digital goods if (isDigital != null && "Y".equalsIgnoreCase(isDigital)) { // we only invoice APPROVED items if ("ITEM_APPROVED".equals(item.getString("statusId"))) { digitalItems.add(item); } if (isPhysical == null || !"Y".equalsIgnoreCase(isPhysical)) { // 100% digital goods need status change digitalProducts.put(item, product); } } } } else { String itemType = item.getString("orderItemTypeId"); if (!"PRODUCT_ORDER_ITEM".equals(itemType)) { nonProductItems.add(item); } } } } // now process the digital items if (digitalItems.size() > 0 || nonProductItems.size() > 0) { GenericValue productStore = OrderReadHelper.getProductStoreFromOrder(dispatcher.getDelegator(), orderId); boolean invoiceItems = true; if (productStore != null && productStore.get("autoInvoiceDigitalItems") != null) { invoiceItems = "Y".equalsIgnoreCase(productStore.getString("autoInvoiceDigitalItems")); } // single list with all invoice items List<GenericValue> itemsToInvoice = FastList.newInstance(); itemsToInvoice.addAll(nonProductItems); itemsToInvoice.addAll(digitalItems); if (invoiceItems) { // invoice all APPROVED digital/non-product goods // do something tricky here: run as a different user that can actually create an invoice, post transaction, etc Map<String, Object> invoiceResult = null; try { GenericValue permUserLogin = delegator.findByPrimaryKey("UserLogin", UtilMisc.toMap("userLoginId", "system")); Map<String, Object> invoiceContext = UtilMisc.<String, Object>toMap("orderId", orderId, "billItems", itemsToInvoice, "userLogin", permUserLogin); invoiceResult = dispatcher.runSync("createInvoiceForOrder", invoiceContext); } catch (GenericEntityException e) { Debug.logError(e, "ERROR: Unable to invoice digital items", module); return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderProblemWithInvoiceCreationDigitalItemsNotFulfilled", locale)); } catch (GenericServiceException e) { Debug.logError(e, "ERROR: Unable to invoice digital items", module); return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderProblemWithInvoiceCreationDigitalItemsNotFulfilled", locale)); } if (ModelService.RESPOND_ERROR.equals(invoiceResult.get(ModelService.RESPONSE_MESSAGE))) { return ServiceUtil.returnError((String) invoiceResult.get(ModelService.ERROR_MESSAGE)); } // update the status of digital goods to COMPLETED; leave physical/digital as APPROVED for pick/ship Iterator<GenericValue> dii = itemsToInvoice.iterator(); while (dii.hasNext()) { GenericValue productType = null; GenericValue item = dii.next(); GenericValue product = digitalProducts.get(item); boolean markComplete = false; if (product != null) { try { productType = product.getRelatedOne("ProductType"); } catch (GenericEntityException e) { Debug.logError(e, "ERROR: Unable to get ProductType from Product", module); } } else { String itemType = item.getString("orderItemTypeId"); if (!"PRODUCT_ORDER_ITEM".equals(itemType)) { markComplete = true; } } if (product != null && productType != null) { String isPhysical = productType.getString("isPhysical"); String isDigital = productType.getString("isDigital"); // we were set as a digital good; one more check and change status if ((isDigital != null && "Y".equalsIgnoreCase(isDigital)) && (isPhysical == null || !"Y".equalsIgnoreCase(isPhysical))) { markComplete = true; } } if (markComplete) { Map<String, Object> statusCtx = new HashMap<String, Object>(); statusCtx.put("orderId", item.getString("orderId")); statusCtx.put("orderItemSeqId", item.getString("orderItemSeqId")); statusCtx.put("statusId", "ITEM_COMPLETED"); statusCtx.put("userLogin", userLogin); try { dispatcher.runSyncIgnore("changeOrderItemStatus", statusCtx); } catch (GenericServiceException e) { Debug.logError(e, "ERROR: Problem setting the status to COMPLETED : " + item, module); } } } } // fulfill the digital goods Map<String, Object> fulfillContext = UtilMisc.<String, Object>toMap("orderId", orderId, "orderItems", digitalItems, "userLogin", userLogin); Map<String, Object> fulfillResult = null; try { // will be running in an isolated transaction to prevent rollbacks fulfillResult = dispatcher.runSync("fulfillDigitalItems", fulfillContext, 300, true); } catch (GenericServiceException e) { Debug.logError(e, "ERROR: Unable to fulfill digital items", module); } if (ModelService.RESPOND_ERROR.equals(fulfillResult.get(ModelService.RESPONSE_MESSAGE))) { // this service cannot return error at this point or we will roll back the invoice // since payments are already captured; errors should have been logged already. // the response message here will be passed as an error to the user. return ServiceUtil.returnSuccess((String) fulfillResult.get(ModelService.ERROR_MESSAGE)); } } return ServiceUtil.returnSuccess(); } 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 Iterator<GenericValue> itemsIterator = orderItems.iterator(); while (itemsIterator.hasNext()) { GenericValue orderItem = itemsIterator.next(); // 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"); if (product == null) { return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderErrorCannotCheckForFulfillmentProductNotFound", locale)); } List<GenericValue> allProductContent = product.getRelated("ProductContent"); // try looking up the parent product if the product has no content and is a variant if (UtilValidate.isEmpty(allProductContent) && ("Y".equals(product.getString("isVariant")))) { GenericValue parentProduct = ProductWorker.getParentProduct(product.getString("productId"), delegator); if (allProductContent == null) { allProductContent = FastList.newInstance(); } if (parentProduct != null) { allProductContent.addAll(parentProduct.getRelated("ProductContent")); } } 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)) { Iterator<GenericValue> prodcontentIterator = productContent.iterator(); while (prodcontentIterator.hasNext()) { GenericValue productContentItem = prodcontentIterator.next(); GenericValue content = null; try { content = productContentItem.getRelatedOne("Content"); } 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)) { // enternal service fulfillment String fulfillmentService = (String) content.get("serviceName"); 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)) { // digital email fulfillment // 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(); } /** Service to invoice service items from order*/ public static Map<String, Object> invoiceServiceItems(DispatchContext dctx, Map<String, ? extends Object> context) { Delegator delegator = dctx.getDelegator(); LocalDispatcher dispatcher = dctx.getDispatcher(); GenericValue userLogin = (GenericValue) context.get("userLogin"); String orderId = (String) context.get("orderId"); Locale locale = (Locale) context.get("locale"); OrderReadHelper orh = null; try { orh = new OrderReadHelper(delegator, orderId); } catch (IllegalArgumentException e) { Debug.logError(e, "ERROR: Unable to get OrderHeader for orderId : " + orderId, module); return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderErrorUnableToGetOrderHeaderForOrderId", UtilMisc.toMap("orderId", orderId), locale)); } // get all the approved items for the order List<GenericValue> orderItems = null; orderItems = orh.getOrderItemsByCondition(EntityCondition.makeCondition("statusId", "ITEM_APPROVED")); // find any service items List<GenericValue> serviceItems = FastList.newInstance(); if (UtilValidate.isNotEmpty(orderItems)) { for (GenericValue item : orderItems) { GenericValue product = null; try { product = item.getRelatedOne("Product"); } catch (GenericEntityException e) { Debug.logError(e, "ERROR: Unable to get Product from OrderItem", module); } if (product != null) { // check for service goods if ("SERVICE".equals(product.get("productTypeId"))) { serviceItems.add(item); } } } } // now process the service items if (UtilValidate.isNotEmpty(serviceItems)) { // Make sure there is actually something needing invoicing because createInvoiceForOrder doesn't check List<GenericValue> billItems = FastList.newInstance(); for (GenericValue item : serviceItems) { BigDecimal orderQuantity = OrderReadHelper.getOrderItemQuantity(item); BigDecimal invoiceQuantity = OrderReadHelper.getOrderItemInvoicedQuantity(item); BigDecimal outstandingQuantity = orderQuantity.subtract(invoiceQuantity); if (outstandingQuantity.compareTo(ZERO) > 0) { billItems.add(item); } } // do something tricky here: run as a different user that can actually create an invoice, post transaction, etc Map<String, Object> invoiceResult = null; try { GenericValue permUserLogin = ServiceUtil.getUserLogin(dctx, context, "system"); Map<String, Object> invoiceContext = UtilMisc.toMap("orderId", orderId, "billItems", billItems, "userLogin", permUserLogin); invoiceResult = dispatcher.runSync("createInvoiceForOrder", invoiceContext); } catch (GenericServiceException e) { Debug.logError(e, "ERROR: Unable to invoice service items", module); return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderProblemWithInvoiceCreationServiceItems", locale)); } if (ModelService.RESPOND_ERROR.equals(invoiceResult.get(ModelService.RESPONSE_MESSAGE))) { return ServiceUtil.returnError((String) invoiceResult.get(ModelService.ERROR_MESSAGE)); } // update the status of service goods to COMPLETED; for (GenericValue item : serviceItems) { Map<String, Object> statusCtx = FastMap.newInstance(); statusCtx.put("orderId", item.getString("orderId")); statusCtx.put("orderItemSeqId", item.getString("orderItemSeqId")); statusCtx.put("statusId", "ITEM_COMPLETED"); statusCtx.put("userLogin", userLogin); try { dispatcher.runSyncIgnore("changeOrderItemStatus", statusCtx); } catch (GenericServiceException e) { Debug.logError(e, "ERROR: Problem setting the status to COMPLETED : " + item, module); } } } return ServiceUtil.returnSuccess(); } public static Map<String, Object> addItemToApprovedOrder(DispatchContext dctx, Map<String, ? extends Object> context) { LocalDispatcher dispatcher = dctx.getDispatcher(); Delegator delegator = dctx.getDelegator(); GenericValue userLogin = (GenericValue) context.get("userLogin"); Locale locale = (Locale) context.get("locale"); String shipGroupSeqId = (String) context.get("shipGroupSeqId"); String orderId = (String) context.get("orderId"); String productId = (String) context.get("productId"); String prodCatalogId = (String) context.get("prodCatalogId"); BigDecimal basePrice = (BigDecimal) context.get("basePrice"); BigDecimal quantity = (BigDecimal) context.get("quantity"); BigDecimal amount = (BigDecimal) context.get("amount"); Timestamp itemDesiredDeliveryDate = (Timestamp) context.get("itemDesiredDeliveryDate"); String overridePrice = (String) context.get("overridePrice"); String reasonEnumId = (String) context.get("reasonEnumId"); String changeComments = (String) context.get("changeComments"); Boolean calcTax = (Boolean) context.get("calcTax"); if (calcTax == null) { calcTax = Boolean.TRUE; } if (amount == null) { amount = BigDecimal.ZERO; } int shipGroupIdx = -1; try { shipGroupIdx = Integer.parseInt(shipGroupSeqId); shipGroupIdx--; } catch (NumberFormatException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } if (shipGroupIdx < 0) { return ServiceUtil.returnError(UtilProperties.getMessage(resource, "OrderShipGroupSeqIdInvalid", UtilMisc.toMap("shipGroupSeqId", shipGroupSeqId), locale)); } // obtain a shopping cart object for updating ShoppingCart cart = null; try { cart = loadCartForUpdate(dispatcher, delegator, userLogin, orderId); } catch (GeneralException e) { return ServiceUtil.returnError(e.getMessage()); } if (cart == null) { return ServiceUtil.returnError(UtilProperties.getMessage(resource, "OrderShoppingCartEmpty", locale)); } // add in the new product try { if ("PURCHASE_ORDER".equals(cart.getOrderType())) { GenericValue supplierProduct = cart.getSupplierProduct(productId, quantity, dispatcher); ShoppingCartItem item = null; if (supplierProduct != null) { item = ShoppingCartItem.makePurchaseOrderItem(null, productId, null, quantity, null, null, prodCatalogId, null, null, null, dispatcher, cart, supplierProduct, itemDesiredDeliveryDate, itemDesiredDeliveryDate, null); cart.addItem(0, item); } else { throw new CartItemModifyException("No supplier information found for product [" + productId + "] and quantity quantity [" + quantity + "], cannot add to cart."); } if (basePrice != null) { item.setBasePrice(basePrice); item.setIsModifiedPrice(true); } cart.setItemShipGroupQty(item, item.getQuantity(), shipGroupIdx); } else { ShoppingCartItem item = ShoppingCartItem.makeItem(null, productId, null, quantity, null, null, null, null, null, null, null, null, prodCatalogId, null, null, null, dispatcher, cart, null, null, null, Boolean.FALSE, Boolean.FALSE); if (basePrice != null && overridePrice != null) { item.setBasePrice(basePrice); // special hack to make sure we re-calc the promos after a price change item.setQuantity(quantity.add(BigDecimal.ONE), dispatcher, cart, false); item.setQuantity(quantity, dispatcher, cart, false); item.setBasePrice(basePrice); item.setIsModifiedPrice(true); } // set the item in the selected ship group item.setShipBeforeDate(itemDesiredDeliveryDate); cart.clearItemShipInfo(item); cart.setItemShipGroupQty(item, item.getQuantity(), shipGroupIdx); } } catch (CartItemModifyException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } catch (ItemNotFoundException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } Map<String, Object> changeMap = UtilMisc.<String, Object>toMap("itemReasonMap", UtilMisc.<String, Object>toMap("reasonEnumId", reasonEnumId), "itemCommentMap", UtilMisc.<String, Object>toMap("changeComments", changeComments)); // save all the updated information try { saveUpdatedCartToOrder(dispatcher, delegator, cart, locale, userLogin, orderId, changeMap, calcTax, false); } catch (GeneralException e) { return ServiceUtil.returnError(e.getMessage()); } // log an order note try { String addedItemToOrder = UtilProperties.getMessage(resource, "OrderAddedItemToOrder", locale); dispatcher.runSync("createOrderNote", UtilMisc.<String, Object>toMap("orderId", orderId, "note", addedItemToOrder + productId + " (" + quantity + ")", "internalNote", "Y", "userLogin", userLogin)); } catch (GenericServiceException e) { Debug.logError(e, module); } Map<String, Object> result = ServiceUtil.returnSuccess(); result.put("shoppingCart", cart); result.put("orderId", orderId); return result; } public static Map<String, Object> updateApprovedOrderItems(DispatchContext dctx, Map<String, ? extends Object> context) { LocalDispatcher dispatcher = dctx.getDispatcher(); Delegator delegator = dctx.getDelegator(); GenericValue userLogin = (GenericValue) context.get("userLogin"); Locale locale = (Locale) context.get("locale"); String orderId = (String) context.get("orderId"); Map<String, String> overridePriceMap = UtilGenerics.checkMap(context.get("overridePriceMap")); Map<String, String> itemDescriptionMap = UtilGenerics.checkMap(context.get("itemDescriptionMap")); Map<String, String> itemPriceMap = UtilGenerics.checkMap(context.get("itemPriceMap")); Map<String, String> itemQtyMap = UtilGenerics.checkMap(context.get("itemQtyMap")); Map<String, String> itemReasonMap = UtilGenerics.checkMap(context.get("itemReasonMap")); Map<String, String> itemCommentMap = UtilGenerics.checkMap(context.get("itemCommentMap")); Map<String, String> itemAttributesMap = UtilGenerics.checkMap(context.get("itemAttributesMap")); Map<String, String> itemEstimatedShipDateMap = UtilGenerics.checkMap(context.get("itemShipDateMap")); Map<String, String> itemEstimatedDeliveryDateMap = UtilGenerics .checkMap(context.get("itemDeliveryDateMap")); Boolean calcTax = (Boolean) context.get("calcTax"); if (calcTax == null) { calcTax = Boolean.TRUE; } // obtain a shopping cart object for updating ShoppingCart cart = null; try { cart = loadCartForUpdate(dispatcher, delegator, userLogin, orderId); } catch (GeneralException e) { return ServiceUtil.returnError(e.getMessage()); } if (cart == null) { return ServiceUtil.returnError(UtilProperties.getMessage(resource, "OrderShoppingCartEmpty", locale)); } // go through the item attributes map once to get a list of key names Set<String> attributeNames = FastSet.newInstance(); Set<String> keys = itemAttributesMap.keySet(); for (String key : keys) { String[] attributeInfo = key.split(":"); attributeNames.add(attributeInfo[0]); } // go through the item map and obtain the totals per item Map<String, BigDecimal> itemTotals = new HashMap<String, BigDecimal>(); Iterator<String> i = itemQtyMap.keySet().iterator(); while (i.hasNext()) { String key = i.next(); String quantityStr = itemQtyMap.get(key); BigDecimal groupQty = BigDecimal.ZERO; try { groupQty = new BigDecimal(quantityStr); } catch (NumberFormatException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } if (groupQty.compareTo(BigDecimal.ZERO) == 0) { return ServiceUtil .returnError(UtilProperties.getMessage(resource, "OrderItemQtyMustBePositive", locale)); } String[] itemInfo = key.split(":"); BigDecimal tally = itemTotals.get(itemInfo[0]); if (tally == null) { tally = groupQty; } else { tally = tally.add(groupQty); } itemTotals.put(itemInfo[0], tally); } // set the items amount/price Iterator<String> iai = itemTotals.keySet().iterator(); while (iai.hasNext()) { String itemSeqId = iai.next(); ShoppingCartItem cartItem = cart.findCartItem(itemSeqId); if (cartItem != null) { BigDecimal qty = itemTotals.get(itemSeqId); BigDecimal priceSave = cartItem.getBasePrice(); // set quantity try { cartItem.setQuantity(qty, dispatcher, cart, false, false); // trigger external ops, don't reset ship groups (and update prices for both PO and SO items) } catch (CartItemModifyException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } Debug.log("Set item quantity: [" + itemSeqId + "] " + qty, module); if (cartItem.getIsModifiedPrice()) // set price cartItem.setBasePrice(priceSave); if (overridePriceMap.containsKey(itemSeqId)) { String priceStr = itemPriceMap.get(itemSeqId); if (UtilValidate.isNotEmpty(priceStr)) { BigDecimal price = new BigDecimal("-1"); price = new BigDecimal(priceStr).setScale(orderDecimals, orderRounding); cartItem.setBasePrice(price); cartItem.setIsModifiedPrice(true); Debug.log("Set item price: [" + itemSeqId + "] " + price, module); } } // Update the item description if (itemDescriptionMap != null && itemDescriptionMap.containsKey(itemSeqId)) { String description = itemDescriptionMap.get(itemSeqId); if (UtilValidate.isNotEmpty(description)) { cartItem.setName(description); Debug.log("Set item description: [" + itemSeqId + "] " + description, module); } else { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "OrderItemDescriptionCannotBeEmpty", locale)); } } // update the order item attributes if (itemAttributesMap != null) { String attrValue = null; for (String attrName : attributeNames) { attrValue = itemAttributesMap.get(attrName + ":" + itemSeqId); if (UtilValidate.isNotEmpty(attrName)) { cartItem.setOrderItemAttribute(attrName, attrValue); Debug.log("Set item attribute Name: [" + itemSeqId + "] " + attrName + " , Value:" + attrValue, module); } } } } else { Debug.logInfo("Unable to locate shopping cart item for seqId #" + itemSeqId, module); } } // Create Estimated Delivery dates for (Map.Entry<String, String> entry : itemEstimatedDeliveryDateMap.entrySet()) { String itemSeqId = entry.getKey(); String estimatedDeliveryDate = entry.getValue(); if (UtilValidate.isNotEmpty(estimatedDeliveryDate)) { Timestamp deliveryDate = Timestamp.valueOf(estimatedDeliveryDate); ShoppingCartItem cartItem = cart.findCartItem(itemSeqId); cartItem.setDesiredDeliveryDate(deliveryDate); } } // Create Estimated ship dates for (Map.Entry<String, String> entry : itemEstimatedShipDateMap.entrySet()) { String itemSeqId = entry.getKey(); String estimatedShipDate = entry.getValue(); if (UtilValidate.isNotEmpty(estimatedShipDate)) { Timestamp shipDate = Timestamp.valueOf(estimatedShipDate); ShoppingCartItem cartItem = cart.findCartItem(itemSeqId); cartItem.setEstimatedShipDate(shipDate); } } // update the group amounts Iterator<String> gai = itemQtyMap.keySet().iterator(); while (gai.hasNext()) { String key = gai.next(); String quantityStr = itemQtyMap.get(key); BigDecimal groupQty = BigDecimal.ZERO; try { groupQty = new BigDecimal(quantityStr); } catch (NumberFormatException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } String[] itemInfo = key.split(":"); int groupIdx = -1; try { groupIdx = Integer.parseInt(itemInfo[1]); } catch (NumberFormatException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } // set the group qty ShoppingCartItem cartItem = cart.findCartItem(itemInfo[0]); if (cartItem != null) { Debug.log("Shipping info (before) for group #" + (groupIdx - 1) + " [" + cart.getShipmentMethodTypeId(groupIdx - 1) + " / " + cart.getCarrierPartyId(groupIdx - 1) + "]", module); cart.setItemShipGroupQty(cartItem, groupQty, groupIdx - 1); Debug.log("Set ship group qty: [" + itemInfo[0] + " / " + itemInfo[1] + " (" + (groupIdx - 1) + ")] " + groupQty, module); Debug.log("Shipping info (after) for group #" + (groupIdx - 1) + " [" + cart.getShipmentMethodTypeId(groupIdx - 1) + " / " + cart.getCarrierPartyId(groupIdx - 1) + "]", module); } } // save all the updated information try { saveUpdatedCartToOrder(dispatcher, delegator, cart, locale, userLogin, orderId, UtilMisc .<String, Object>toMap("itemReasonMap", itemReasonMap, "itemCommentMap", itemCommentMap), calcTax, false); } catch (GeneralException e) { return ServiceUtil.returnError(e.getMessage()); } // run promotions to handle all changes in the cart ProductPromoWorker.doPromotions(cart, dispatcher); // log an order note try { dispatcher.runSync("createOrderNote", UtilMisc.<String, Object>toMap("orderId", orderId, "note", "Updated order.", "internalNote", "Y", "userLogin", userLogin)); } catch (GenericServiceException e) { Debug.logError(e, module); } Map<String, Object> result = ServiceUtil.returnSuccess(); result.put("shoppingCart", cart); result.put("orderId", orderId); return result; } public static Map<String, Object> loadCartForUpdate(DispatchContext dctx, Map<String, ? extends Object> context) { LocalDispatcher dispatcher = dctx.getDispatcher(); Delegator delegator = dctx.getDelegator(); String orderId = (String) context.get("orderId"); GenericValue userLogin = (GenericValue) context.get("userLogin"); ShoppingCart cart = null; Map<String, Object> result = null; try { cart = loadCartForUpdate(dispatcher, delegator, userLogin, orderId); result = ServiceUtil.returnSuccess(); result.put("shoppingCart", cart); } catch (GeneralException e) { Debug.logError(e, module); result = ServiceUtil.returnError(e.getMessage()); } result.put("orderId", orderId); return result; } /* * 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, "skipInventoryChecks", Boolean.TRUE, // the items are already reserved, no need to check again "skipProductChecks", Boolean.TRUE, // the products are already in the order, no need to check their validity now "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 + "]"); } else { 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 = delegator.findByAnd("OrderItemShipGroupAssoc", UtilMisc.toMap("orderId", orderId)); } catch (GenericEntityException e) { Debug.logError(e, module); throw new GeneralException(e.getMessage()); } // cancel existing inventory reservations if (shipGroupAssocs != null) { Iterator<GenericValue> iri = shipGroupAssocs.iterator(); while (iri.hasNext()) { GenericValue shipGroupAssoc = iri.next(); 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 = delegator.findByAnd("OrderItem", UtilMisc.toMap("orderId", orderId, "isPromo", "Y")); } catch (GenericEntityException e) { Debug.logError(e, module); throw new GeneralException(e.getMessage()); } if (promoItems != null) { Iterator<GenericValue> pii = promoItems.iterator(); while (pii.hasNext()) { GenericValue promoItem = pii.next(); // 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")); EntityCondition cond = EntityCondition.makeCondition(exprs, EntityOperator.AND); paymentPrefsToCancel = delegator.findList("OrderPaymentPreference", cond, null, null, null, false); } catch (GenericEntityException e) { Debug.logError(e, module); throw new GeneralException(e.getMessage()); } if (paymentPrefsToCancel != null) { Iterator<GenericValue> oppi = paymentPrefsToCancel.iterator(); while (oppi.hasNext()) { GenericValue opp = oppi.next(); 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<EntityCondition>(); adjExprs.add(EntityCondition.makeCondition("orderId", EntityOperator.EQUALS, orderId)); List<EntityCondition> exprs = new LinkedList<EntityCondition>(); 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); delegator.removeByCondition("OrderAdjustment", cond); } catch (GenericEntityException e) { Debug.logError(e, module); throw new GeneralException(e.getMessage()); } return cart; } public static Map<String, Object> saveUpdatedCartToOrder(DispatchContext dctx, Map<String, ? extends Object> context) throws GeneralException { LocalDispatcher dispatcher = dctx.getDispatcher(); Delegator delegator = dctx.getDelegator(); String orderId = (String) context.get("orderId"); GenericValue userLogin = (GenericValue) context.get("userLogin"); ShoppingCart cart = (ShoppingCart) context.get("shoppingCart"); Map<String, Object> changeMap = UtilGenerics.checkMap(context.get("changeMap")); Locale locale = (Locale) context.get("locale"); Boolean deleteItems = (Boolean) context.get("deleteItems"); Boolean calcTax = (Boolean) context.get("calcTax"); if (calcTax == null) { calcTax = Boolean.TRUE; } Map<String, Object> result = null; try { saveUpdatedCartToOrder(dispatcher, delegator, cart, locale, userLogin, orderId, changeMap, calcTax, deleteItems); result = ServiceUtil.returnSuccess(); //result.put("shoppingCart", cart); } catch (GeneralException e) { Debug.logError(e, module); result = ServiceUtil.returnError(e.getMessage()); } result.put("orderId", orderId); return result; } private static void saveUpdatedCartToOrder(LocalDispatcher dispatcher, Delegator delegator, ShoppingCart cart, Locale locale, GenericValue userLogin, String orderId, Map<String, Object> changeMap, boolean calcTax, boolean deleteItems) throws GeneralException { // get/set the shipping estimates. if it's a SALES ORDER, then return an error if there are no ship estimates int shipGroups = cart.getShipGroupSize(); for (int gi = 0; gi < shipGroups; gi++) { String shipmentMethodTypeId = cart.getShipmentMethodTypeId(gi); String carrierPartyId = cart.getCarrierPartyId(gi); Debug.log("Getting ship estimate for group #" + gi + " [" + shipmentMethodTypeId + " / " + carrierPartyId + "]", module); Map<String, Object> result = ShippingEvents.getShipGroupEstimate(dispatcher, delegator, cart, gi); if (("SALES_ORDER".equals(cart.getOrderType())) && (ServiceUtil.isError(result))) { Debug.logError(ServiceUtil.getErrorMessage(result), module); throw new GeneralException(ServiceUtil.getErrorMessage(result)); } BigDecimal shippingTotal = (BigDecimal) result.get("shippingTotal"); if (shippingTotal == null) { shippingTotal = BigDecimal.ZERO; } cart.setItemShipGroupEstimate(shippingTotal, gi); } // calc the sales tax CheckOutHelper coh = new CheckOutHelper(dispatcher, delegator, cart); if (calcTax) { try { coh.calcAndAddTax(); } catch (GeneralException e) { Debug.logError(e, module); throw new GeneralException(e.getMessage()); } } // get the new orderItems, adjustments, shipping info, payments and order item attributes from the cart List<Map<String, Object>> modifiedItems = FastList.newInstance(); List<GenericValue> toStore = new LinkedList<GenericValue>(); List<GenericValue> toAddList = new ArrayList<GenericValue>(); toAddList.addAll(cart.makeAllAdjustments()); cart.clearAllPromotionAdjustments(); ProductPromoWorker.doPromotions(cart, dispatcher); // validate the payment methods Map<String, Object> validateResp = coh.validatePaymentMethods(); if (ServiceUtil.isError(validateResp)) { throw new GeneralException(ServiceUtil.getErrorMessage(validateResp)); } // handle OrderHeader fields String billingAccountId = cart.getBillingAccountId(); if (UtilValidate.isNotEmpty(billingAccountId)) { try { GenericValue orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId)); orderHeader.set("billingAccountId", billingAccountId); toStore.add(orderHeader); } catch (GenericEntityException e) { Debug.logError(e, module); throw new GeneralException(e.getMessage()); } } toStore.addAll(cart.makeOrderItems()); toStore.addAll(cart.makeAllAdjustments()); String shipGroupSeqId = null; long groupIndex = cart.getShipInfoSize(); if (!deleteItems) { for (long itr = 1; itr <= groupIndex; itr++) { shipGroupSeqId = UtilFormatOut.formatPaddedNumber(itr, 5); List<GenericValue> removeList = new ArrayList<GenericValue>(); for (GenericValue stored : toStore) { if ("OrderAdjustment".equals(stored.getEntityName())) { if (("SHIPPING_CHARGES".equals(stored.get("orderAdjustmentTypeId")) || "SALES_TAX".equals(stored.get("orderAdjustmentTypeId"))) && stored.get("orderId").equals(orderId) && stored.get("shipGroupSeqId").equals(shipGroupSeqId)) { // Removing objects from toStore list for old Shipping and Handling Charges Adjustment and Sales Tax Adjustment. removeList.add(stored); } if (stored.get("comments") != null && ((String) stored.get("comments")).startsWith("Added manually by")) { // Removing objects from toStore list for Manually added Adjustment. removeList.add(stored); } } } toStore.removeAll(removeList); } for (GenericValue toAdd : toAddList) { if ("OrderAdjustment".equals(toAdd.getEntityName())) { if (toAdd.get("comments") != null && ((String) toAdd.get("comments")).startsWith("Added manually by") && (("PROMOTION_ADJUSTMENT".equals(toAdd.get("orderAdjustmentTypeId"))) || ("SHIPPING_CHARGES".equals(toAdd.get("orderAdjustmentTypeId"))) || ("SALES_TAX".equals(toAdd.get("orderAdjustmentTypeId"))))) { toStore.add(toAdd); } } } } else { // add all the cart adjustments toStore.addAll(toAddList); } // Creating objects for New Shipping and Handling Charges Adjustment and Sales Tax Adjustment toStore.addAll(cart.makeAllShipGroupInfos()); toStore.addAll(cart.makeAllOrderPaymentInfos(dispatcher)); toStore.addAll(cart.makeAllOrderItemAttributes(orderId, ShoppingCart.FILLED_ONLY)); List<GenericValue> toRemove = FastList.newInstance(); if (deleteItems) { // flag to delete existing order items and adjustments try { toRemove.addAll(delegator.findByAnd("OrderItemShipGroupAssoc", "orderId", orderId)); toRemove.addAll(delegator.findByAnd("OrderItemContactMech", "orderId", orderId)); toRemove.addAll(delegator.findByAnd("OrderItemPriceInfo", "orderId", orderId)); toRemove.addAll(delegator.findByAnd("OrderItemAttribute", "orderId", orderId)); toRemove.addAll(delegator.findByAnd("OrderItemBilling", "orderId", orderId)); toRemove.addAll(delegator.findByAnd("OrderItemRole", "orderId", orderId)); toRemove.addAll(delegator.findByAnd("OrderItemChange", "orderId", orderId)); toRemove.addAll(delegator.findByAnd("OrderAdjustment", "orderId", orderId)); toRemove.addAll(delegator.findByAnd("OrderItem", "orderId", orderId)); } catch (GenericEntityException e) { Debug.logError(e, module); } } else { // get the empty order item atrributes from the cart and remove them toRemove.addAll(cart.makeAllOrderItemAttributes(orderId, ShoppingCart.EMPTY_ONLY)); } // get the promo uses and codes for (String promoCodeEntered : cart.getProductPromoCodesEntered()) { GenericValue orderProductPromoCode = delegator.makeValue("OrderProductPromoCode"); orderProductPromoCode.set("orderId", orderId); orderProductPromoCode.set("productPromoCodeId", promoCodeEntered); toStore.add(orderProductPromoCode); } for (GenericValue promoUse : cart.makeProductPromoUses()) { promoUse.set("orderId", orderId); toStore.add(promoUse); } List<GenericValue> existingPromoCodes = null; List<GenericValue> existingPromoUses = null; try { existingPromoCodes = delegator.findByAnd("OrderProductPromoCode", UtilMisc.toMap("orderId", orderId)); existingPromoUses = delegator.findByAnd("ProductPromoUse", UtilMisc.toMap("orderId", orderId)); } catch (GenericEntityException e) { Debug.logError(e, module); } toRemove.addAll(existingPromoCodes); toRemove.addAll(existingPromoUses); // set the orderId & other information on all new value objects List<String> dropShipGroupIds = FastList.newInstance(); // this list will contain the ids of all the ship groups for drop shipments (no reservations) Iterator<GenericValue> tsi = toStore.iterator(); while (tsi.hasNext()) { GenericValue valueObj = tsi.next(); valueObj.set("orderId", orderId); if ("OrderItemShipGroup".equals(valueObj.getEntityName())) { // ship group if (valueObj.get("carrierRoleTypeId") == null) { valueObj.set("carrierRoleTypeId", "CARRIER"); } if (!UtilValidate.isEmpty(valueObj.get("supplierPartyId"))) { dropShipGroupIds.add(valueObj.getString("shipGroupSeqId")); } } else if ("OrderAdjustment".equals(valueObj.getEntityName())) { // shipping / tax adjustment(s) if (UtilValidate.isEmpty(valueObj.get("orderItemSeqId"))) { valueObj.set("orderItemSeqId", DataModelConstants.SEQ_ID_NA); } // in order to avoid duplicate adjustments don't set orderAdjustmentId (which is the pk) if there is already one if (UtilValidate.isEmpty(valueObj.getString("orderAdjustmentId"))) { valueObj.set("orderAdjustmentId", delegator.getNextSeqId("OrderAdjustment")); } valueObj.set("createdDate", UtilDateTime.nowTimestamp()); valueObj.set("createdByUserLogin", userLogin.getString("userLoginId")); } else if ("OrderPaymentPreference".equals(valueObj.getEntityName())) { if (valueObj.get("orderPaymentPreferenceId") == null) { valueObj.set("orderPaymentPreferenceId", delegator.getNextSeqId("OrderPaymentPreference")); valueObj.set("createdDate", UtilDateTime.nowTimestamp()); valueObj.set("createdByUserLogin", userLogin.getString("userLoginId")); } if (valueObj.get("statusId") == null) { valueObj.set("statusId", "PAYMENT_NOT_RECEIVED"); } } else if ("OrderItem".equals(valueObj.getEntityName()) && !deleteItems) { // ignore promotion items. They are added/canceled automatically if ("Y".equals(valueObj.getString("isPromo"))) { continue; } GenericValue oldOrderItem = null; try { oldOrderItem = delegator.findByPrimaryKey("OrderItem", UtilMisc.toMap("orderId", valueObj.getString("orderId"), "orderItemSeqId", valueObj.getString("orderItemSeqId"))); } catch (GenericEntityException e) { Debug.logError(e, module); throw new GeneralException(e.getMessage()); } if (UtilValidate.isNotEmpty(oldOrderItem)) { // Existing order item found. Check for modifications and store if any String oldItemDescription = oldOrderItem.getString("itemDescription") != null ? oldOrderItem.getString("itemDescription") : ""; BigDecimal oldQuantity = oldOrderItem.getBigDecimal("quantity") != null ? oldOrderItem.getBigDecimal("quantity") : BigDecimal.ZERO; BigDecimal oldUnitPrice = oldOrderItem.getBigDecimal("unitPrice") != null ? oldOrderItem.getBigDecimal("unitPrice") : BigDecimal.ZERO; boolean changeFound = false; Map<String, Object> modifiedItem = FastMap.newInstance(); if (!oldItemDescription.equals(valueObj.getString("itemDescription"))) { modifiedItem.put("itemDescription", oldItemDescription); changeFound = true; } BigDecimal quantityDif = valueObj.getBigDecimal("quantity").subtract(oldQuantity); BigDecimal unitPriceDif = valueObj.getBigDecimal("unitPrice").subtract(oldUnitPrice); if (quantityDif.compareTo(BigDecimal.ZERO) != 0) { modifiedItem.put("quantity", quantityDif); changeFound = true; } if (unitPriceDif.compareTo(BigDecimal.ZERO) != 0) { modifiedItem.put("unitPrice", unitPriceDif); changeFound = true; } if (changeFound) { // found changes to store Map<String, String> itemReasonMap = UtilGenerics.checkMap(changeMap.get("itemReasonMap")); Map<String, String> itemCommentMap = UtilGenerics.checkMap(changeMap.get("itemCommentMap")); if (UtilValidate.isNotEmpty(itemReasonMap)) { String changeReasonId = itemReasonMap.get(valueObj.getString("orderItemSeqId")); modifiedItem.put("reasonEnumId", changeReasonId); } if (UtilValidate.isNotEmpty(itemCommentMap)) { String changeComments = itemCommentMap.get(valueObj.getString("orderItemSeqId")); modifiedItem.put("changeComments", changeComments); } modifiedItem.put("orderId", valueObj.getString("orderId")); modifiedItem.put("orderItemSeqId", valueObj.getString("orderItemSeqId")); modifiedItem.put("changeTypeEnumId", "ODR_ITM_UPDATE"); modifiedItems.add(modifiedItem); } } else { // this is a new item appended to the order Map<String, String> itemReasonMap = UtilGenerics.checkMap(changeMap.get("itemReasonMap")); Map<String, String> itemCommentMap = UtilGenerics.checkMap(changeMap.get("itemCommentMap")); Map<String, Object> appendedItem = FastMap.newInstance(); if (UtilValidate.isNotEmpty(itemReasonMap)) { String changeReasonId = itemReasonMap.get("reasonEnumId"); appendedItem.put("reasonEnumId", changeReasonId); } if (UtilValidate.isNotEmpty(itemCommentMap)) { String changeComments = itemCommentMap.get("changeComments"); appendedItem.put("changeComments", changeComments); } appendedItem.put("orderId", valueObj.getString("orderId")); appendedItem.put("orderItemSeqId", valueObj.getString("orderItemSeqId")); appendedItem.put("quantity", valueObj.getBigDecimal("quantity")); appendedItem.put("changeTypeEnumId", "ODR_ITM_APPEND"); modifiedItems.add(appendedItem); } } } if (Debug.verboseOn()) Debug.logVerbose("To Store Contains: " + toStore, module); // remove any order item attributes that were set to empty try { delegator.removeAll(toRemove, true); } catch (GenericEntityException e) { Debug.logError(e, module); throw new GeneralException(e.getMessage()); } // store the new items/adjustments/order item attributes try { delegator.storeAll(toStore); } catch (GenericEntityException e) { Debug.logError(e, module); throw new GeneralException(e.getMessage()); } // store the OrderItemChange if (UtilValidate.isNotEmpty(modifiedItems)) { for (Map<String, Object> modifiendItem : modifiedItems) { Map<String, Object> serviceCtx = FastMap.newInstance(); serviceCtx.put("orderId", modifiendItem.get("orderId")); serviceCtx.put("orderItemSeqId", modifiendItem.get("orderItemSeqId")); serviceCtx.put("itemDescription", modifiendItem.get("itemDescription")); serviceCtx.put("quantity", modifiendItem.get("quantity")); serviceCtx.put("unitPrice", modifiendItem.get("unitPrice")); serviceCtx.put("changeTypeEnumId", modifiendItem.get("changeTypeEnumId")); serviceCtx.put("reasonEnumId", modifiendItem.get("reasonEnumId")); serviceCtx.put("changeComments", modifiendItem.get("changeComments")); serviceCtx.put("userLogin", userLogin); Map<String, Object> resp = null; try { resp = dispatcher.runSync("createOrderItemChange", serviceCtx); } catch (GenericServiceException e) { Debug.logError(e, module); throw new GeneralException(e.getMessage()); } if (ServiceUtil.isError(resp)) { throw new GeneralException((String) resp.get(ModelService.ERROR_MESSAGE)); } } } // make the order item object map & the ship group assoc list List<GenericValue> orderItemShipGroupAssoc = new LinkedList<GenericValue>(); Map<String, GenericValue> itemValuesBySeqId = new HashMap<String, GenericValue>(); Iterator<GenericValue> oii = toStore.iterator(); while (oii.hasNext()) { GenericValue v = oii.next(); if ("OrderItem".equals(v.getEntityName())) { itemValuesBySeqId.put(v.getString("orderItemSeqId"), v); } else if ("OrderItemShipGroupAssoc".equals(v.getEntityName())) { orderItemShipGroupAssoc.add(v); } } // reserve the inventory String productStoreId = cart.getProductStoreId(); String orderTypeId = cart.getOrderType(); List<String> resErrorMessages = new LinkedList<String>(); try { Debug.log("Calling reserve inventory...", module); reserveInventory(delegator, dispatcher, userLogin, locale, orderItemShipGroupAssoc, dropShipGroupIds, itemValuesBySeqId, orderTypeId, productStoreId, resErrorMessages); } catch (GeneralException e) { Debug.logError(e, module); throw new GeneralException(e.getMessage()); } if (resErrorMessages.size() > 0) { throw new GeneralException(ServiceUtil.getErrorMessage(ServiceUtil.returnError(resErrorMessages))); } } public static Map<String, Object> processOrderPayments(DispatchContext dctx, Map<String, ? extends Object> context) { LocalDispatcher dispatcher = dctx.getDispatcher(); Delegator delegator = dctx.getDelegator(); GenericValue userLogin = (GenericValue) context.get("userLogin"); String orderId = (String) context.get("orderId"); Locale locale = (Locale) context.get("locale"); OrderReadHelper orh = new OrderReadHelper(delegator, orderId); String productStoreId = orh.getProductStoreId(); // check if order was already cancelled / rejected GenericValue orderHeader = orh.getOrderHeader(); String orderStatus = orderHeader.getString("statusId"); if ("ORDER_CANCELLED".equals(orderStatus) || "ORDER_REJECTED".equals(orderStatus)) { return ServiceUtil.returnFailure( UtilProperties.getMessage(resource, "OrderProcessOrderPaymentsStatusInvalid", locale) + orderStatus); } // process the payments if (!"PURCHASE_ORDER".equals(orh.getOrderTypeId())) { GenericValue productStore = ProductStoreWorker.getProductStore(productStoreId, delegator); Map<String, Object> paymentResp = null; try { Debug.log("Calling process payments...", module); //Debug.set(Debug.VERBOSE, true); paymentResp = CheckOutHelper.processPayment(orderId, orh.getOrderGrandTotal(), orh.getCurrency(), productStore, userLogin, false, false, dispatcher, delegator); //Debug.set(Debug.VERBOSE, false); } catch (GeneralException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } catch (GeneralRuntimeException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } if (ServiceUtil.isError(paymentResp)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "OrderProcessOrderPayments", locale), null, null, paymentResp); } } return ServiceUtil.returnSuccess(); } // sample test services public static Map<String, Object> shoppingCartTest(DispatchContext dctx, Map<String, ? extends Object> context) { Locale locale = (Locale) context.get("locale"); ShoppingCart cart = new ShoppingCart(dctx.getDelegator(), "9000", "webStore", locale, "USD"); try { cart.addOrIncreaseItem("GZ-1005", null, BigDecimal.ONE, null, null, null, null, null, null, null, "DemoCatalog", null, null, null, null, dctx.getDispatcher()); } catch (CartItemModifyException e) { Debug.logError(e, module); } catch (ItemNotFoundException e) { Debug.logError(e, module); } try { dctx.getDispatcher().runAsync("shoppingCartRemoteTest", UtilMisc.toMap("cart", cart), true); } catch (GenericServiceException e) { Debug.logError(e, module); } return ServiceUtil.returnSuccess(); } public static Map<String, Object> shoppingCartRemoteTest(DispatchContext dctx, Map<String, ? extends Object> context) { ShoppingCart cart = (ShoppingCart) context.get("cart"); Debug.log("Product ID : " + cart.findCartItem(0).getProductId(), module); return ServiceUtil.returnSuccess(); } /** * Service to create a payment using an order payment preference. * @return Map */ public static Map<String, Object> createPaymentFromPreference(DispatchContext dctx, Map<String, ? extends Object> context) { Delegator delegator = dctx.getDelegator(); LocalDispatcher dispatcher = dctx.getDispatcher(); GenericValue userLogin = (GenericValue) context.get("userLogin"); String orderPaymentPreferenceId = (String) context.get("orderPaymentPreferenceId"); String paymentRefNum = (String) context.get("paymentRefNum"); String paymentFromId = (String) context.get("paymentFromId"); String comments = (String) context.get("comments"); Timestamp eventDate = (Timestamp) context.get("eventDate"); Locale locale = (Locale) context.get("locale"); if (UtilValidate.isEmpty(eventDate)) { eventDate = UtilDateTime.nowTimestamp(); } try { // get the order payment preference GenericValue orderPaymentPreference = delegator.findByPrimaryKey("OrderPaymentPreference", UtilMisc.toMap("orderPaymentPreferenceId", orderPaymentPreferenceId)); if (orderPaymentPreference == null) { return ServiceUtil .returnError(UtilProperties.getMessage(resource, "OrderOrderPaymentCannotBeCreated", UtilMisc.toMap("orderPaymentPreferenceId", "orderPaymentPreferenceId"), locale)); } // get the order header GenericValue orderHeader = orderPaymentPreference.getRelatedOne("OrderHeader"); if (orderHeader == null) { return ServiceUtil.returnError(UtilProperties.getMessage(resource, "OrderOrderPaymentCannotBeCreatedWithRelatedOrderHeader", locale)); } // get the store for the order. It will be used to set the currency GenericValue productStore = orderHeader.getRelatedOne("ProductStore"); if (productStore == null) { return ServiceUtil.returnError(UtilProperties.getMessage(resource, "OrderOrderPaymentCannotBeCreatedWithRelatedProductStore", locale)); } // get the partyId billed to if (paymentFromId == null) { OrderReadHelper orh = new OrderReadHelper(orderHeader); GenericValue billToParty = orh.getBillToParty(); if (billToParty != null) { paymentFromId = billToParty.getString("partyId"); } else { paymentFromId = "_NA_"; } } // set the payToPartyId String payToPartyId = productStore.getString("payToPartyId"); if (payToPartyId == null) { return ServiceUtil.returnError(UtilProperties.getMessage(resource, "OrderOrderPaymentCannotBeCreatedPayToPartyIdNotSet", locale)); } // create the payment Map<String, Object> paymentParams = new HashMap<String, Object>(); BigDecimal maxAmount = orderPaymentPreference.getBigDecimal("maxAmount"); //if (maxAmount > 0.0) { paymentParams.put("paymentTypeId", "CUSTOMER_PAYMENT"); paymentParams.put("paymentMethodTypeId", orderPaymentPreference.getString("paymentMethodTypeId")); paymentParams.put("paymentPreferenceId", orderPaymentPreference.getString("orderPaymentPreferenceId")); paymentParams.put("amount", maxAmount); paymentParams.put("statusId", "PMNT_RECEIVED"); paymentParams.put("effectiveDate", eventDate); paymentParams.put("partyIdFrom", paymentFromId); paymentParams.put("currencyUomId", productStore.getString("defaultCurrencyUomId")); paymentParams.put("partyIdTo", payToPartyId); /*} else { paymentParams.put("paymentTypeId", "CUSTOMER_REFUND"); // JLR 17/7/4 from a suggestion of Si cf. https://issues.apache.org/jira/browse/OFBIZ-828#action_12483045 paymentParams.put("paymentMethodTypeId", orderPaymentPreference.getString("paymentMethodTypeId")); // JLR 20/7/4 Finally reverted for now, I prefer to see an amount in payment, even negative paymentParams.put("paymentPreferenceId", orderPaymentPreference.getString("orderPaymentPreferenceId")); paymentParams.put("amount", Double.valueOf(Math.abs(maxAmount))); paymentParams.put("statusId", "PMNT_RECEIVED"); paymentParams.put("effectiveDate", UtilDateTime.nowTimestamp()); paymentParams.put("partyIdFrom", payToPartyId); paymentParams.put("currencyUomId", productStore.getString("defaultCurrencyUomId")); paymentParams.put("partyIdTo", billToParty.getString("partyId")); }*/ if (paymentRefNum != null) { paymentParams.put("paymentRefNum", paymentRefNum); } if (comments != null) { paymentParams.put("comments", comments); } paymentParams.put("userLogin", userLogin); return dispatcher.runSync("createPayment", paymentParams); } catch (GenericEntityException ex) { Debug.logError(ex, "Unable to create payment using payment preference.", module); return (ServiceUtil.returnError(ex.getMessage())); } catch (GenericServiceException ex) { Debug.logError(ex, "Unable to create payment using payment preference.", module); return (ServiceUtil.returnError(ex.getMessage())); } } public static Map<String, Object> massChangeApproved(DispatchContext dctx, Map<String, ? extends Object> context) { return massChangeOrderStatus(dctx, context, "ORDER_APPROVED"); } public static Map<String, Object> massCancelOrders(DispatchContext dctx, Map<String, ? extends Object> context) { return massChangeItemStatus(dctx, context, "ITEM_CANCELLED"); } public static Map<String, Object> massRejectOrders(DispatchContext dctx, Map<String, ? extends Object> context) { return massChangeItemStatus(dctx, context, "ITEM_REJECTED"); } public static Map<String, Object> massHoldOrders(DispatchContext dctx, Map<String, ? extends Object> context) { return massChangeOrderStatus(dctx, context, "ORDER_HOLD"); } public static Map<String, Object> massProcessOrders(DispatchContext dctx, Map<String, ? extends Object> context) { return massChangeOrderStatus(dctx, context, "ORDER_PROCESSING"); } public static Map<String, Object> massChangeOrderStatus(DispatchContext dctx, Map<String, ? extends Object> context, String statusId) { LocalDispatcher dispatcher = dctx.getDispatcher(); Delegator delegator = dctx.getDelegator(); GenericValue userLogin = (GenericValue) context.get("userLogin"); List<String> orderIds = UtilGenerics.checkList(context.get("orderIdList")); Locale locale = (Locale) context.get("locale"); Iterator<String> i = orderIds.iterator(); while (i.hasNext()) { String orderId = i.next(); if (UtilValidate.isEmpty(orderId)) { continue; } GenericValue orderHeader = null; try { orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId)); } catch (GenericEntityException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } if (orderHeader == null) { return ServiceUtil.returnFailure(UtilProperties.getMessage(resource, "OrderOrderNotFound", UtilMisc.toMap("orderId", orderId), locale)); } Map<String, Object> ctx = FastMap.newInstance(); ctx.put("statusId", statusId); ctx.put("orderId", orderId); ctx.put("setItemStatus", "Y"); ctx.put("userLogin", userLogin); Map<String, Object> resp = null; try { resp = dispatcher.runSync("changeOrderStatus", ctx); } catch (GenericServiceException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } if (ServiceUtil.isError(resp)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderErrorCouldNotChangeOrderStatus", locale), null, null, resp); } } return ServiceUtil.returnSuccess(); } public static Map<String, Object> massChangeItemStatus(DispatchContext dctx, Map<String, ? extends Object> context, String statusId) { LocalDispatcher dispatcher = dctx.getDispatcher(); Delegator delegator = dctx.getDelegator(); GenericValue userLogin = (GenericValue) context.get("userLogin"); List<String> orderIds = UtilGenerics.checkList(context.get("orderIdList")); Locale locale = (Locale) context.get("locale"); Iterator<String> i = orderIds.iterator(); while (i.hasNext()) { String orderId = i.next(); if (UtilValidate.isEmpty(orderId)) { continue; } GenericValue orderHeader = null; try { orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId)); } catch (GenericEntityException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } if (orderHeader == null) { return ServiceUtil.returnFailure(UtilProperties.getMessage(resource, "OrderOrderNotFound", UtilMisc.toMap("orderId", orderId), locale)); } Map<String, Object> ctx = FastMap.newInstance(); ctx.put("statusId", statusId); ctx.put("orderId", orderId); ctx.put("userLogin", userLogin); Map<String, Object> resp = null; try { resp = dispatcher.runSync("changeOrderItemStatus", ctx); } catch (GenericServiceException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } if (ServiceUtil.isError(resp)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderErrorCouldNotChangeItemStatus", locale), null, null, resp); } } return ServiceUtil.returnSuccess(); } public static Map<String, Object> massQuickShipOrders(DispatchContext dctx, Map<String, ? extends Object> context) { LocalDispatcher dispatcher = dctx.getDispatcher(); GenericValue userLogin = (GenericValue) context.get("userLogin"); List<String> orderIds = UtilGenerics.checkList(context.get("orderIdList")); Locale locale = (Locale) context.get("locale"); for (Object orderId : orderIds) { if (UtilValidate.isEmpty(orderId)) { continue; } Map<String, Object> ctx = FastMap.newInstance(); ctx.put("userLogin", userLogin); ctx.put("orderId", orderId); Map<String, Object> resp = null; try { resp = dispatcher.runSync("quickShipEntireOrder", ctx); } catch (GenericServiceException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } if (ServiceUtil.isError(resp)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "OrderOrderQuickShipEntireOrderError", locale), null, null, resp); } } return ServiceUtil.returnSuccess(); } public static Map<String, Object> massPickOrders(DispatchContext dctx, Map<String, ? extends Object> context) { LocalDispatcher dispatcher = dctx.getDispatcher(); Delegator delegator = dctx.getDelegator(); GenericValue userLogin = (GenericValue) context.get("userLogin"); Locale locale = (Locale) context.get("locale"); // grouped by facility Map<String, List<String>> facilityOrdersMap = FastMap.newInstance(); // make the list per facility List<String> orderIds = UtilGenerics.checkList(context.get("orderIdList")); Iterator<String> i = orderIds.iterator(); while (i.hasNext()) { String orderId = i.next(); if (UtilValidate.isEmpty(orderId)) { continue; } List<GenericValue> invInfo = null; try { invInfo = delegator.findByAnd("OrderItemAndShipGrpInvResAndItem", UtilMisc.toMap("orderId", orderId, "statusId", "ITEM_APPROVED")); } catch (GenericEntityException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } if (invInfo != null) { Iterator<GenericValue> ii = invInfo.iterator(); while (ii.hasNext()) { GenericValue inv = ii.next(); String facilityId = inv.getString("facilityId"); List<String> orderIdsByFacility = facilityOrdersMap.get(facilityId); if (orderIdsByFacility == null) { orderIdsByFacility = new ArrayList<String>(); } orderIdsByFacility.add(orderId); facilityOrdersMap.put(facilityId, orderIdsByFacility); } } } // now create the pick lists for each facility Iterator<String> fi = facilityOrdersMap.keySet().iterator(); while (fi.hasNext()) { String facilityId = fi.next(); List<String> orderIdList = facilityOrdersMap.get(facilityId); Map<String, Object> ctx = FastMap.newInstance(); ctx.put("userLogin", userLogin); ctx.put("orderIdList", orderIdList); ctx.put("facilityId", facilityId); Map<String, Object> resp = null; try { resp = dispatcher.runSync("createPicklistFromOrders", ctx); } catch (GenericServiceException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } if (ServiceUtil.isError(resp)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "OrderOrderPickingListCreationError", locale), null, null, resp); } } return ServiceUtil.returnSuccess(); } public static Map<String, Object> massPrintOrders(DispatchContext dctx, Map<String, ? extends Object> context) { LocalDispatcher dispatcher = dctx.getDispatcher(); GenericValue userLogin = (GenericValue) context.get("userLogin"); String screenLocation = (String) context.get("screenLocation"); String printerName = (String) context.get("printerName"); // make the list per facility List<String> orderIds = UtilGenerics.checkList(context.get("orderIdList")); Iterator<String> i = orderIds.iterator(); while (i.hasNext()) { String orderId = i.next(); if (UtilValidate.isEmpty(orderId)) { continue; } Map<String, Object> ctx = FastMap.newInstance(); ctx.put("userLogin", userLogin); ctx.put("screenLocation", screenLocation); //ctx.put("contentType", "application/postscript"); if (UtilValidate.isNotEmpty(printerName)) { ctx.put("printerName", printerName); } ctx.put("screenContext", UtilMisc.toMap("orderId", orderId)); try { dispatcher.runAsync("sendPrintFromScreen", ctx); } catch (GenericServiceException e) { Debug.logError(e, module); } } return ServiceUtil.returnSuccess(); } public static Map<String, Object> massCreateFileForOrders(DispatchContext dctx, Map<String, ? extends Object> context) { LocalDispatcher dispatcher = dctx.getDispatcher(); GenericValue userLogin = (GenericValue) context.get("userLogin"); String screenLocation = (String) context.get("screenLocation"); // make the list per facility List<String> orderIds = UtilGenerics.checkList(context.get("orderIdList")); Iterator<String> i = orderIds.iterator(); while (i.hasNext()) { String orderId = i.next(); if (UtilValidate.isEmpty(orderId)) { continue; } Map<String, Object> ctx = FastMap.newInstance(); ctx.put("userLogin", userLogin); ctx.put("screenLocation", screenLocation); //ctx.put("contentType", "application/postscript"); ctx.put("fileName", "order_" + orderId + "_"); ctx.put("screenContext", UtilMisc.toMap("orderId", orderId)); try { dispatcher.runAsync("createFileFromScreen", ctx); } catch (GenericServiceException e) { Debug.logError(e, module); } } return ServiceUtil.returnSuccess(); } public static Map<String, Object> massCancelRemainingPurchaseOrderItems(DispatchContext dctx, Map<String, ? extends Object> context) { LocalDispatcher dispatcher = dctx.getDispatcher(); GenericValue userLogin = (GenericValue) context.get("userLogin"); List<String> orderIds = UtilGenerics.checkList(context.get("orderIdList")); Locale locale = (Locale) context.get("locale"); for (Object orderId : orderIds) { if (UtilValidate.isEmpty(orderId)) { continue; } Map<String, Object> ctx = FastMap.newInstance(); ctx.put("orderId", orderId); ctx.put("userLogin", userLogin); Map<String, Object> resp = null; try { resp = dispatcher.runSync("cancelRemainingPurchaseOrderItems", ctx); } catch (GenericServiceException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } if (ServiceUtil.isError(resp)) { return ServiceUtil.returnError(UtilProperties.getMessage(resource, "OrderOrderCancelRemainingPurchaseOrderItemsError", locale), null, null, resp); } try { resp = dispatcher.runSync("checkOrderItemStatus", ctx); } catch (GenericServiceException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } if (ServiceUtil.isError(resp)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "OrderOrderCheckOrderItemStatusError", locale), null, null, resp); } } return ServiceUtil.returnSuccess(); } public static Map<String, Object> checkCreateDropShipPurchaseOrders(DispatchContext ctx, Map<String, ? extends Object> context) { Delegator delegator = ctx.getDelegator(); LocalDispatcher dispatcher = ctx.getDispatcher(); // TODO (use the "system" user) GenericValue userLogin = (GenericValue) context.get("userLogin"); String orderId = (String) context.get("orderId"); Locale locale = (Locale) context.get("locale"); OrderReadHelper orh = new OrderReadHelper(delegator, orderId); // TODO: skip this if there is already a purchase order associated with the sales order (ship group) try { // if sales order if ("SALES_ORDER".equals(orh.getOrderTypeId())) { // get the order's ship groups Iterator<GenericValue> shipGroups = orh.getOrderItemShipGroups().iterator(); while (shipGroups.hasNext()) { GenericValue shipGroup = shipGroups.next(); if (!UtilValidate.isEmpty(shipGroup.getString("supplierPartyId"))) { // This ship group is a drop shipment: we create a purchase order for it String supplierPartyId = shipGroup.getString("supplierPartyId"); // create the cart ShoppingCart cart = new ShoppingCart(delegator, orh.getProductStoreId(), null, orh.getCurrency()); cart.setOrderType("PURCHASE_ORDER"); cart.setBillToCustomerPartyId(cart.getBillFromVendorPartyId()); //Company cart.setBillFromVendorPartyId(supplierPartyId); cart.setOrderPartyId(supplierPartyId); // Get the items associated to it and create po List<GenericValue> items = orh.getValidOrderItems(shipGroup.getString("shipGroupSeqId")); if (!UtilValidate.isEmpty(items)) { Iterator<GenericValue> itemsIt = items.iterator(); while (itemsIt.hasNext()) { GenericValue item = itemsIt.next(); try { int itemIndex = cart.addOrIncreaseItem(item.getString("productId"), null, // amount item.getBigDecimal("quantity"), null, null, null, // reserv item.getTimestamp("shipBeforeDate"), item.getTimestamp("shipAfterDate"), null, null, null, null, null, null, null, dispatcher); ShoppingCartItem sci = cart.findCartItem(itemIndex); sci.setAssociatedOrderId(orderId); sci.setAssociatedOrderItemSeqId(item.getString("orderItemSeqId")); sci.setOrderItemAssocTypeId("DROP_SHIPMENT"); // TODO: we should consider also the ship group in the association between sales and purchase orders } catch (Exception e) { return ServiceUtil.returnError(UtilProperties.getMessage(resource, "OrderOrderCreatingDropShipmentsError", UtilMisc.toMap("orderId", orderId, "errorString", e.getMessage()), locale)); } } } // If there are indeed items to drop ship, then create the purchase order if (!UtilValidate.isEmpty(cart.items())) { // set checkout options cart.setDefaultCheckoutOptions(dispatcher); // the shipping address is the one of the customer cart.setShippingContactMechId(shipGroup.getString("contactMechId")); // create the order CheckOutHelper coh = new CheckOutHelper(dispatcher, delegator, cart); coh.createOrder(userLogin); // TODO: associate the new purchase order with the sales order (ship group) } else { // if there are no items to drop ship, then clear out the supplier partyId Debug.logWarning( "No drop ship items found for order [" + shipGroup.getString("orderId") + "] and ship group [" + shipGroup.getString("shipGroupSeqId") + "] and supplier party [" + shipGroup.getString("supplierPartyId") + "]. Supplier party information will be cleared for this ship group", module); shipGroup.set("supplierPartyId", null); shipGroup.store(); } } } } } catch (Exception exc) { // TODO: imporve error handling return ServiceUtil .returnError(UtilProperties.getMessage(resource, "OrderOrderCreatingDropShipmentsError", UtilMisc.toMap("orderId", orderId, "errorString", exc.getMessage()), locale)); } return ServiceUtil.returnSuccess(); } public static Map<String, Object> updateOrderPaymentPreference(DispatchContext dctx, Map<String, ? extends Object> context) { Delegator delegator = dctx.getDelegator(); String orderPaymentPreferenceId = (String) context.get("orderPaymentPreferenceId"); String checkOutPaymentId = (String) context.get("checkOutPaymentId"); String statusId = (String) context.get("statusId"); try { GenericValue opp = delegator.findByPrimaryKey("OrderPaymentPreference", UtilMisc.toMap("orderPaymentPreferenceId", orderPaymentPreferenceId)); String paymentMethodId = null; String paymentMethodTypeId = null; // The checkOutPaymentId is either a paymentMethodId or paymentMethodTypeId // the original method did a "\d+" regexp to decide which is the case, this version is more explicit with its lookup of PaymentMethodType if (checkOutPaymentId != null) { List<GenericValue> paymentMethodTypes = delegator.findList("PaymentMethodType", null, null, null, null, true); for (Iterator<GenericValue> iter = paymentMethodTypes.iterator(); iter.hasNext();) { GenericValue type = iter.next(); if (type.get("paymentMethodTypeId").equals(checkOutPaymentId)) { paymentMethodTypeId = (String) type.get("paymentMethodTypeId"); break; } } if (paymentMethodTypeId == null) { GenericValue method = delegator.findByPrimaryKey("PaymentMethod", UtilMisc.toMap("paymentMethodTypeId", paymentMethodTypeId)); paymentMethodId = checkOutPaymentId; paymentMethodTypeId = (String) method.get("paymentMethodTypeId"); } } Map<String, Object> results = ServiceUtil.returnSuccess(); if (UtilValidate.isNotEmpty(statusId) && statusId.equalsIgnoreCase("PAYMENT_CANCELLED")) { opp.set("statusId", "PAYMENT_CANCELLED"); opp.store(); results.put("orderPaymentPreferenceId", opp.get("orderPaymentPreferenceId")); } else { GenericValue newOpp = (GenericValue) opp.clone(); opp.set("statusId", "PAYMENT_CANCELLED"); opp.store(); newOpp.set("orderPaymentPreferenceId", delegator.getNextSeqId("OrderPaymentPreference")); newOpp.set("paymentMethodId", paymentMethodId); newOpp.set("paymentMethodTypeId", paymentMethodTypeId); newOpp.setNonPKFields(context); newOpp.create(); results.put("orderPaymentPreferenceId", newOpp.get("orderPaymentPreferenceId")); } return results; } catch (GenericEntityException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } } /** * Generates a product requirement for the total cancelled quantity over all order items for each product * @param dctx the dispatch context * @param context the context * @return the result of the service execution */ public static Map<String, Object> generateReqsFromCancelledPOItems(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"); String orderId = (String) context.get("orderId"); String facilityId = (String) context.get("facilityId"); try { GenericValue orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId)); if (UtilValidate.isEmpty(orderHeader)) { String errorMessage = UtilProperties.getMessage(resource_error, "OrderErrorOrderIdNotFound", UtilMisc.toMap("orderId", orderId), locale); Debug.logError(errorMessage, module); return ServiceUtil.returnError(errorMessage); } if (!"PURCHASE_ORDER".equals(orderHeader.getString("orderTypeId"))) { String errorMessage = UtilProperties.getMessage(resource_error, "ProductErrorOrderNotPurchaseOrder", UtilMisc.toMap("orderId", orderId), locale); Debug.logError(errorMessage, module); return ServiceUtil.returnError(errorMessage); } // Build a map of productId -> quantity cancelled over all order items Map<String, Object> productRequirementQuantities = new HashMap<String, Object>(); List<GenericValue> orderItems = orderHeader.getRelated("OrderItem"); Iterator<GenericValue> oiit = orderItems.iterator(); while (oiit.hasNext()) { GenericValue orderItem = oiit.next(); if (!"PRODUCT_ORDER_ITEM".equals(orderItem.getString("orderItemTypeId"))) continue; // Get the cancelled quantity for the item BigDecimal orderItemCancelQuantity = BigDecimal.ZERO; if (!UtilValidate.isEmpty(orderItem.get("cancelQuantity"))) { orderItemCancelQuantity = orderItem.getBigDecimal("cancelQuantity"); } if (orderItemCancelQuantity.compareTo(BigDecimal.ZERO) <= 0) continue; String productId = orderItem.getString("productId"); if (productRequirementQuantities.containsKey(productId)) { orderItemCancelQuantity = orderItemCancelQuantity .add((BigDecimal) productRequirementQuantities.get(productId)); } productRequirementQuantities.put(productId, orderItemCancelQuantity); } // Generate requirements for each of the product quantities Iterator<String> cqit = productRequirementQuantities.keySet().iterator(); while (cqit.hasNext()) { String productId = cqit.next(); BigDecimal requiredQuantity = (BigDecimal) productRequirementQuantities.get(productId); Map<String, Object> createRequirementResult = dispatcher.runSync("createRequirement", UtilMisc.<String, Object>toMap("requirementTypeId", "PRODUCT_REQUIREMENT", "facilityId", facilityId, "productId", productId, "quantity", requiredQuantity, "userLogin", userLogin)); if (ServiceUtil.isError(createRequirementResult)) return createRequirementResult; } } catch (GenericEntityException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } catch (GenericServiceException se) { Debug.logError(se, module); return ServiceUtil.returnError(se.getMessage()); } return ServiceUtil.returnSuccess(); } /** * Cancels remaining (unreceived) quantities for items of an order. Does not consider received-but-rejected quantities. * @param dctx the dispatch context * @param context the context * @return cancels remaining (unreceived) quantities for items of an order */ public static Map<String, Object> cancelRemainingPurchaseOrderItems(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"); String orderId = (String) context.get("orderId"); try { GenericValue orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId)); if (UtilValidate.isEmpty(orderHeader)) { String errorMessage = UtilProperties.getMessage(resource_error, "OrderErrorOrderIdNotFound", UtilMisc.toMap("orderId", orderId), locale); Debug.logError(errorMessage, module); return ServiceUtil.returnError(errorMessage); } if (!"PURCHASE_ORDER".equals(orderHeader.getString("orderTypeId"))) { String errorMessage = UtilProperties.getMessage(resource_error, "OrderErrorOrderNotPurchaseOrder", UtilMisc.toMap("orderId", orderId), locale); Debug.logError(errorMessage, module); return ServiceUtil.returnError(errorMessage); } List<GenericValue> orderItems = orderHeader.getRelated("OrderItem"); Iterator<GenericValue> oiit = orderItems.iterator(); while (oiit.hasNext()) { GenericValue orderItem = oiit.next(); if (!"PRODUCT_ORDER_ITEM".equals(orderItem.getString("orderItemTypeId"))) continue; // Get the ordered quantity for the item BigDecimal orderItemQuantity = BigDecimal.ZERO; if (!UtilValidate.isEmpty(orderItem.get("quantity"))) { orderItemQuantity = orderItem.getBigDecimal("quantity"); } BigDecimal orderItemCancelQuantity = BigDecimal.ZERO; if (!UtilValidate.isEmpty(orderItem.get("cancelQuantity"))) { orderItemCancelQuantity = orderItem.getBigDecimal("cancelQuantity"); } // Get the received quantity for the order item - ignore the quantityRejected, since rejected items should be reordered List<GenericValue> shipmentReceipts = orderItem.getRelated("ShipmentReceipt"); BigDecimal receivedQuantity = BigDecimal.ZERO; Iterator<GenericValue> srit = shipmentReceipts.iterator(); while (srit.hasNext()) { GenericValue shipmentReceipt = srit.next(); if (!UtilValidate.isEmpty(shipmentReceipt.get("quantityAccepted"))) { receivedQuantity = receivedQuantity.add(shipmentReceipt.getBigDecimal("quantityAccepted")); } } BigDecimal quantityToCancel = orderItemQuantity.subtract(orderItemCancelQuantity) .subtract(receivedQuantity); if (quantityToCancel.compareTo(BigDecimal.ZERO) > 0) { Map<String, Object> cancelOrderItemResult = dispatcher.runSync("cancelOrderItem", UtilMisc.toMap("orderId", orderId, "orderItemSeqId", orderItem.get("orderItemSeqId"), "cancelQuantity", quantityToCancel, "userLogin", userLogin)); if (ServiceUtil.isError(cancelOrderItemResult)) return cancelOrderItemResult; } // If there's nothing to cancel, the item should be set to completed, if it isn't already orderItem.refresh(); if ("ITEM_APPROVED".equals(orderItem.getString("statusId"))) { Map<String, Object> changeOrderItemStatusResult = dispatcher.runSync("changeOrderItemStatus", UtilMisc.toMap("orderId", orderId, "orderItemSeqId", orderItem.get("orderItemSeqId"), "statusId", "ITEM_COMPLETED", "userLogin", userLogin)); if (ServiceUtil.isError(changeOrderItemStatusResult)) return changeOrderItemStatusResult; } } } catch (GenericEntityException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } catch (GenericServiceException se) { Debug.logError(se, module); return ServiceUtil.returnError(se.getMessage()); } return ServiceUtil.returnSuccess(); } // create simple non-product order public static Map<String, Object> createSimpleNonProductSalesOrder(DispatchContext dctx, Map<String, ? extends Object> context) { LocalDispatcher dispatcher = dctx.getDispatcher(); Delegator delegator = dctx.getDelegator(); GenericValue userLogin = (GenericValue) context.get("userLogin"); Locale locale = (Locale) context.get("locale"); String paymentMethodId = (String) context.get("paymentMethodId"); String productStoreId = (String) context.get("productStoreId"); String currency = (String) context.get("currency"); String partyId = (String) context.get("partyId"); Map<String, BigDecimal> itemMap = UtilGenerics.checkMap(context.get("itemMap")); ShoppingCart cart = new ShoppingCart(delegator, productStoreId, null, locale, currency); try { cart.setUserLogin(userLogin, dispatcher); } catch (CartItemModifyException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } cart.setOrderType("SALES_ORDER"); cart.setOrderPartyId(partyId); Iterator<String> i = itemMap.keySet().iterator(); while (i.hasNext()) { String item = i.next(); BigDecimal price = itemMap.get(item); try { cart.addNonProductItem("BULK_ORDER_ITEM", item, null, price, BigDecimal.ONE, null, null, null, dispatcher); } catch (CartItemModifyException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } } // set the payment method try { cart.addPayment(paymentMethodId); } catch (IllegalArgumentException e) { return ServiceUtil.returnError(e.getMessage()); } // save the order (new tx) Map<String, Object> createResp; try { createResp = dispatcher.runSync("createOrderFromShoppingCart", UtilMisc.toMap("shoppingCart", cart), 90, true); } catch (GenericServiceException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } if (ServiceUtil.isError(createResp)) { return createResp; } // auth the order (new tx) Map<String, Object> authResp; try { authResp = dispatcher.runSync("callProcessOrderPayments", UtilMisc.toMap("shoppingCart", cart), 180, true); } catch (GenericServiceException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } if (ServiceUtil.isError(authResp)) { return authResp; } Map<String, Object> result = ServiceUtil.returnSuccess(); result.put("orderId", createResp.get("orderId")); return result; } // generic method for creating an order from a shopping cart public static Map<String, Object> createOrderFromShoppingCart(DispatchContext dctx, Map<String, ? extends Object> context) { LocalDispatcher dispatcher = dctx.getDispatcher(); Delegator delegator = dctx.getDelegator(); ShoppingCart cart = (ShoppingCart) context.get("shoppingCart"); GenericValue userLogin = cart.getUserLogin(); CheckOutHelper coh = new CheckOutHelper(dispatcher, delegator, cart); Map<String, Object> createOrder = coh.createOrder(userLogin); if (ServiceUtil.isError(createOrder)) { return createOrder; } String orderId = (String) createOrder.get("orderId"); Map<String, Object> result = ServiceUtil.returnSuccess(); result.put("shoppingCart", cart); result.put("orderId", orderId); return result; } // generic method for processing an order's payment(s) public static Map<String, Object> callProcessOrderPayments(DispatchContext dctx, Map<String, ? extends Object> context) { LocalDispatcher dispatcher = dctx.getDispatcher(); Delegator delegator = dctx.getDelegator(); Locale locale = (Locale) context.get("locale"); Transaction trans = null; try { // disable transaction procesing trans = TransactionUtil.suspend(); // get the cart ShoppingCart cart = (ShoppingCart) context.get("shoppingCart"); GenericValue userLogin = cart.getUserLogin(); Boolean manualHold = (Boolean) context.get("manualHold"); if (manualHold == null) { manualHold = Boolean.FALSE; } if (!"PURCHASE_ORDER".equals(cart.getOrderType())) { String productStoreId = cart.getProductStoreId(); GenericValue productStore = ProductStoreWorker.getProductStore(productStoreId, delegator); CheckOutHelper coh = new CheckOutHelper(dispatcher, delegator, cart); // process payment Map<String, Object> payResp; try { payResp = coh.processPayment(productStore, userLogin, false, manualHold.booleanValue()); } catch (GeneralException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } if (ServiceUtil.isError(payResp)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "OrderProcessOrderPayments", locale), null, null, payResp); } } return ServiceUtil.returnSuccess(); } catch (GenericTransactionException e) { return ServiceUtil.returnError(e.getMessage()); } finally { // resume transaction try { TransactionUtil.resume(trans); } catch (GenericTransactionException e) { Debug.logWarning(e, e.getMessage(), module); } } } /** * Determines the total amount invoiced for a given order item over all invoices by totalling the item subtotal (via OrderItemBilling), * any adjustments for that item (via OrderAdjustmentBilling), and the item's share of any order-level adjustments (that calculated * by applying the percentage of the items total that the item represents to the order-level adjustments total (also via * OrderAdjustmentBilling). Also returns the quantity invoiced for the item over all invoices, to aid in prorating. * @param dctx DispatchContext * @param context Map * @return Map */ public static Map<String, Object> getOrderItemInvoicedAmountAndQuantity(DispatchContext dctx, Map<String, ? extends Object> context) { Delegator delegator = dctx.getDelegator(); Locale locale = (Locale) context.get("locale"); String orderId = (String) context.get("orderId"); String orderItemSeqId = (String) context.get("orderItemSeqId"); GenericValue orderHeader = null; GenericValue orderItemToCheck = null; BigDecimal orderItemTotalValue = ZERO; BigDecimal invoicedQuantity = ZERO; // Quantity invoiced for the target order item try { orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId)); if (UtilValidate.isEmpty(orderHeader)) { String errorMessage = UtilProperties.getMessage(resource_error, "OrderErrorOrderIdNotFound", context, locale); Debug.logError(errorMessage, module); return ServiceUtil.returnError(errorMessage); } orderItemToCheck = delegator.findByPrimaryKey("OrderItem", UtilMisc.toMap("orderId", orderId, "orderItemSeqId", orderItemSeqId)); if (UtilValidate.isEmpty(orderItemToCheck)) { String errorMessage = UtilProperties.getMessage(resource_error, "OrderErrorOrderItemNotFound", context, locale); Debug.logError(errorMessage, module); return ServiceUtil.returnError(errorMessage); } BigDecimal orderItemsSubtotal = ZERO; // Aggregated value of order items, non-tax and non-shipping item-level adjustments BigDecimal invoicedTotal = ZERO; // Amount invoiced for the target order item BigDecimal itemAdjustments = ZERO; // Item-level tax- and shipping-adjustments // Aggregate the order items subtotal List<GenericValue> orderItems = orderHeader.getRelated("OrderItem", UtilMisc.toList("orderItemSeqId")); Iterator<GenericValue> oit = orderItems.iterator(); while (oit.hasNext()) { GenericValue orderItem = oit.next(); // Look at the orderItemBillings to discover the amount and quantity ever invoiced for this order item List<GenericValue> orderItemBillings = delegator.findByAnd("OrderItemBilling", UtilMisc.toMap("orderId", orderId, "orderItemSeqId", orderItem.get("orderItemSeqId"))); Iterator<GenericValue> oibit = orderItemBillings.iterator(); while (oibit.hasNext()) { GenericValue orderItemBilling = oibit.next(); BigDecimal quantity = orderItemBilling.getBigDecimal("quantity"); BigDecimal amount = orderItemBilling.getBigDecimal("amount").setScale(orderDecimals, orderRounding); if (UtilValidate.isEmpty(invoicedQuantity) || UtilValidate.isEmpty(amount)) continue; // Add the item base amount to the subtotal orderItemsSubtotal = orderItemsSubtotal.add(quantity.multiply(amount)); // If the item is the target order item, add the invoiced quantity and amount to their respective totals if (orderItemSeqId.equals(orderItem.get("orderItemSeqId"))) { invoicedQuantity = invoicedQuantity.add(quantity); invoicedTotal = invoicedTotal.add(quantity.multiply(amount)); } } // Retrieve the adjustments for this item List<GenericValue> orderAdjustments = delegator.findByAnd("OrderAdjustment", UtilMisc.toMap("orderId", orderId, "orderItemSeqId", orderItem.get("orderItemSeqId"))); Iterator<GenericValue> oait = orderAdjustments.iterator(); while (oait.hasNext()) { GenericValue orderAdjustment = oait.next(); String orderAdjustmentTypeId = orderAdjustment.getString("orderAdjustmentTypeId"); boolean includeInTax = orderAdjustment.getBoolean("includeInTax").booleanValue(); // Look at the orderAdjustmentBillings to discove the amount ever invoiced for this order adjustment List<GenericValue> orderAdjustmentBillings = delegator.findByAnd("OrderAdjustmentBilling", UtilMisc.toMap("orderAdjustmentId", orderAdjustment.get("orderAdjustmentId"))); Iterator<GenericValue> oabit = orderAdjustmentBillings.iterator(); while (oabit.hasNext()) { GenericValue orderAjustmentBilling = oabit.next(); BigDecimal amount = orderAjustmentBilling.getBigDecimal("amount").setScale(orderDecimals, orderRounding); if (UtilValidate.isEmpty(amount)) continue; if (includeInTax || "SALES_TAX".equals(orderAdjustmentTypeId) || "SHIPPING_CHARGES".equals(orderAdjustmentTypeId)) { if (orderItemSeqId.equals(orderItem.get("orderItemSeqId"))) { // Add tax- and shipping-adjustment amounts to the total adjustments for the target order item itemAdjustments = itemAdjustments.add(amount); } } else { // Add non-tax and non-shipping adjustment amounts to the order items subtotal orderItemsSubtotal = orderItemsSubtotal.add(amount); if (orderItemSeqId.equals(orderItem.get("orderItemSeqId"))) { // If the item is the target order item, add non-tax and non-shipping adjustment amounts to the invoiced total invoicedTotal = invoicedTotal.add(amount); } } } } } // Total the order-header-level adjustments for the order BigDecimal orderHeaderAdjustmentsTotalValue = ZERO; List<GenericValue> orderHeaderAdjustments = delegator.findByAnd("OrderAdjustment", UtilMisc.toMap("orderId", orderId, "orderItemSeqId", "_NA_")); Iterator<GenericValue> ohait = orderHeaderAdjustments.iterator(); while (ohait.hasNext()) { GenericValue orderHeaderAdjustment = ohait.next(); List<GenericValue> orderHeaderAdjustmentBillings = delegator.findByAnd("OrderAdjustmentBilling", UtilMisc.toMap("orderAdjustmentId", orderHeaderAdjustment.get("orderAdjustmentId"))); Iterator<GenericValue> ohabit = orderHeaderAdjustmentBillings.iterator(); while (ohabit.hasNext()) { GenericValue orderHeaderAdjustmentBilling = ohabit.next(); BigDecimal amount = orderHeaderAdjustmentBilling.getBigDecimal("amount").setScale(orderDecimals, orderRounding); if (UtilValidate.isEmpty(amount)) continue; orderHeaderAdjustmentsTotalValue = orderHeaderAdjustmentsTotalValue.add(amount); } } // How much of the order-level adjustments total does the target order item represent? The assumption is: the same // proportion of the adjustments as of the invoiced total for the item to the invoiced total for all items. These // figures don't take tax- and shipping- adjustments into account, so as to be in accordance with the code in InvoiceServices BigDecimal invoicedAmountProportion = ZERO; if (orderItemsSubtotal.signum() != 0) { invoicedAmountProportion = invoicedTotal.divide(orderItemsSubtotal, 5, orderRounding); } BigDecimal orderItemHeaderAjustmentAmount = orderHeaderAdjustmentsTotalValue .multiply(invoicedAmountProportion); orderItemTotalValue = invoicedTotal.add(orderItemHeaderAjustmentAmount); // Add back the tax- and shipping- item-level adjustments for the order item orderItemTotalValue = orderItemTotalValue.add(itemAdjustments); } catch (GenericEntityException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } Map<String, Object> result = ServiceUtil.returnSuccess(); result.put("invoicedAmount", orderItemTotalValue.setScale(orderDecimals, orderRounding)); result.put("invoicedQuantity", invoicedQuantity.setScale(orderDecimals, orderRounding)); return result; } public static Map<String, Object> setOrderPaymentStatus(DispatchContext ctx, Map<String, ? extends Object> context) { Delegator delegator = ctx.getDelegator(); String orderPaymentPreferenceId = (String) context.get("orderPaymentPreferenceId"); String changeReason = (String) context.get("changeReason"); Locale locale = (Locale) context.get("locale"); try { GenericValue orderPaymentPreference = delegator.findByPrimaryKey("OrderPaymentPreference", UtilMisc.toMap("orderPaymentPreferenceId", orderPaymentPreferenceId)); String orderId = orderPaymentPreference.getString("orderId"); String statusUserLogin = orderPaymentPreference.getString("createdByUserLogin"); GenericValue orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId)); if (orderHeader == null) { return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderErrorCouldNotChangeOrderStatusOrderCannotBeFound", locale)); } String statusId = orderPaymentPreference.getString("statusId"); if (Debug.verboseOn()) Debug.logVerbose( "[OrderServices.setOrderPaymentStatus] : Setting Order Payment Status to : " + statusId, module); // create a order payment status GenericValue orderStatus = delegator.makeValue("OrderStatus"); orderStatus.put("statusId", statusId); orderStatus.put("orderId", orderId); orderStatus.put("orderPaymentPreferenceId", orderPaymentPreferenceId); orderStatus.put("statusUserLogin", statusUserLogin); orderStatus.put("changeReason", changeReason); // Check that the status has actually changed before creating a new record List<GenericValue> previousStatusList = delegator.findByAnd("OrderStatus", UtilMisc.toMap("orderId", orderId, "orderPaymentPreferenceId", orderPaymentPreferenceId), UtilMisc.toList("-statusDatetime")); GenericValue previousStatus = EntityUtil.getFirst(previousStatusList); if (previousStatus != null) { // Temporarily set some values on the new status so that we can do an equals() check orderStatus.put("orderStatusId", previousStatus.get("orderStatusId")); orderStatus.put("statusDatetime", previousStatus.get("statusDatetime")); if (orderStatus.equals(previousStatus)) { // Status is the same, return without creating return ServiceUtil.returnSuccess(); } } orderStatus.put("orderStatusId", delegator.getNextSeqId("OrderStatus")); orderStatus.put("statusDatetime", UtilDateTime.nowTimestamp()); orderStatus.create(); } catch (GenericEntityException e) { return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderErrorCouldNotChangeOrderStatus", locale) + e.getMessage() + ")."); } return ServiceUtil.returnSuccess(); } public static Map<String, Object> runSubscriptionAutoReorders(DispatchContext dctx, Map<String, ? extends Object> context) { LocalDispatcher dispatcher = dctx.getDispatcher(); Delegator delegator = dctx.getDelegator(); GenericValue userLogin = (GenericValue) context.get("userLogin"); Locale locale = (Locale) context.get("locale"); int count = 0; Map<String, Object> result = null; boolean beganTransaction = false; try { beganTransaction = TransactionUtil.begin(); List<EntityExpr> exprs = UtilMisc.toList( EntityCondition.makeCondition("automaticExtend", EntityOperator.EQUALS, "Y"), EntityCondition.makeCondition("orderId", EntityOperator.NOT_EQUAL, null), EntityCondition.makeCondition("productId", EntityOperator.NOT_EQUAL, null)); EntityCondition cond = EntityCondition.makeCondition(exprs, EntityOperator.AND); EntityListIterator eli = null; eli = delegator.find("Subscription", cond, null, null, null, null); if (eli != null) { GenericValue subscription; while (((subscription = eli.next()) != null)) { Calendar endDate = Calendar.getInstance(); endDate.setTime(UtilDateTime.nowTimestamp()); //check if the thruedate - cancel period (if provided) is earlier than todays date int field = Calendar.MONTH; if (subscription.get("canclAutmExtTime") != null && subscription.get("canclAutmExtTimeUomId") != null) { if ("TF_day".equals(subscription.getString("canclAutmExtTimeUomId"))) { field = Calendar.DAY_OF_YEAR; } else if ("TF_wk".equals(subscription.getString("canclAutmExtTimeUomId"))) { field = Calendar.WEEK_OF_YEAR; } else if ("TF_mon".equals(subscription.getString("canclAutmExtTimeUomId"))) { field = Calendar.MONTH; } else if ("TF_yr".equals(subscription.getString("canclAutmExtTimeUomId"))) { field = Calendar.YEAR; } else { Debug.logWarning("Don't know anything about useTimeUomId [" + subscription.getString("canclAutmExtTimeUomId") + "], defaulting to month", module); } endDate.add(field, Integer.valueOf(subscription.getString("canclAutmExtTime")).intValue()); } Calendar endDateSubscription = Calendar.getInstance(); endDateSubscription.setTime(subscription.getTimestamp("thruDate")); if (endDate.before(endDateSubscription)) { // nor expired yet..... continue; } result = dispatcher.runSync("loadCartFromOrder", UtilMisc.toMap("orderId", subscription.get("orderId"), "userLogin", userLogin)); ShoppingCart cart = (ShoppingCart) result.get("shoppingCart"); // only keep the orderitem with the related product. List<ShoppingCartItem> cartItems = cart.items(); Iterator<ShoppingCartItem> ci = cartItems.iterator(); while (ci.hasNext()) { ShoppingCartItem shoppingCartItem = ci.next(); if (!subscription.get("productId").equals(shoppingCartItem.getProductId())) { cart.removeCartItem(shoppingCartItem, dispatcher); } } CheckOutHelper helper = new CheckOutHelper(dispatcher, delegator, cart); // store the order Map<String, Object> createResp = helper.createOrder(userLogin); if (createResp != null && ServiceUtil.isError(createResp)) { Debug.logError("Cannot create order for shopping list - " + subscription, module); } else { String orderId = (String) createResp.get("orderId"); // authorize the payments Map<String, Object> payRes = null; try { payRes = helper.processPayment( ProductStoreWorker.getProductStore(cart.getProductStoreId(), delegator), userLogin); } catch (GeneralException e) { Debug.logError(e, module); } if (payRes != null && ServiceUtil.isError(payRes)) { Debug.logError("Payment processing problems with shopping list - " + subscription, module); } // remove the automatic extension flag subscription.put("automaticExtend", "N"); subscription.store(); // send notification dispatcher.runAsync("sendOrderPayRetryNotification", UtilMisc.toMap("orderId", orderId)); count++; } } eli.close(); } } catch (GenericServiceException e) { Debug.logError("Could call service to create cart", module); return ServiceUtil.returnError(e.toString()); } catch (CartItemModifyException e) { Debug.logError("Could not modify cart: " + e.toString(), module); return ServiceUtil.returnError(e.toString()); } catch (GenericEntityException e) { try { // only rollback the transaction if we started one... TransactionUtil.rollback(beganTransaction, "Error creating subscription auto-reorders", e); } catch (GenericEntityException e2) { Debug.logError(e2, "[Delegator] Could not rollback transaction: " + e2.toString(), module); } Debug.logError(e, "Error while creating new shopping list based automatic reorder" + e.toString(), module); return ServiceUtil.returnError(UtilProperties.getMessage(resource, "OrderShoppingListCreationError", UtilMisc.toMap("errorString", e.toString()), locale)); } finally { try { // only commit the transaction if we started one... this will throw an exception if it fails TransactionUtil.commit(beganTransaction); } catch (GenericEntityException e) { Debug.logError(e, "Could not commit transaction for creating new shopping list based automatic reorder", module); } } return ServiceUtil.returnSuccess(UtilProperties.getMessage(resource, "OrderRunSubscriptionAutoReorders", UtilMisc.toMap("count", count), locale)); } public static Map<String, Object> setShippingInstructions(DispatchContext dctx, Map<String, ? extends Object> context) { Delegator delegator = dctx.getDelegator(); String orderId = (String) context.get("orderId"); String shipGroupSeqId = (String) context.get("shipGroupSeqId"); String shippingInstructions = (String) context.get("shippingInstructions"); try { GenericValue orderItemShipGroup = EntityUtil.getFirst(delegator.findByAnd("OrderItemShipGroup", UtilMisc.toMap("orderId", orderId, "shipGroupSeqId", shipGroupSeqId))); orderItemShipGroup.set("shippingInstructions", shippingInstructions); orderItemShipGroup.store(); } catch (GenericEntityException e) { Debug.logError(e, module); } return ServiceUtil.returnSuccess(); } public static Map<String, Object> setGiftMessage(DispatchContext dctx, Map<String, ? extends Object> context) { Delegator delegator = dctx.getDelegator(); String orderId = (String) context.get("orderId"); String shipGroupSeqId = (String) context.get("shipGroupSeqId"); String giftMessage = (String) context.get("giftMessage"); try { GenericValue orderItemShipGroup = EntityUtil.getFirst(delegator.findByAnd("OrderItemShipGroup", UtilMisc.toMap("orderId", orderId, "shipGroupSeqId", shipGroupSeqId))); orderItemShipGroup.set("giftMessage", giftMessage); orderItemShipGroup.set("isGift", "Y"); orderItemShipGroup.store(); } catch (GenericEntityException e) { Debug.logError(e, module); } return ServiceUtil.returnSuccess(); } 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 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("getSalesOrderIds", new Callable<List<String>>() { public List<String> call() throws Exception { List<String> orderIds = new LinkedList<String>(); EntityListIterator eli = null; try { eli = delegator.find("OrderHeader", cond, null, UtilMisc.toSet("orderId"), UtilMisc.toList("entryDate ASC"), null); GenericValue orderHeader; while ((orderHeader = eli.next()) != null) { orderIds.add(orderHeader.getString("orderId")); } } finally { if (eli != null) { eli.close(); } } return orderIds; } }); } catch (GenericEntityException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } for (String orderId : orderIds) { Map<String, Object> svcIn = FastMap.newInstance(); svcIn.put("userLogin", context.get("userLogin")); svcIn.put("orderId", orderId); try { dispatcher.runSync("createAlsoBoughtProductAssocsForOrder", svcIn); } catch (GenericServiceException e) { Debug.logError(e, module); } } return ServiceUtil.returnSuccess(); } public static Map<String, Object> createAlsoBoughtProductAssocsForOrder(DispatchContext dctx, Map<String, ? extends Object> context) { LocalDispatcher dispatcher = dctx.getDispatcher(); Delegator delegator = dctx.getDelegator(); String orderId = (String) context.get("orderId"); OrderReadHelper orh = new OrderReadHelper(delegator, orderId); List<GenericValue> orderItems = orh.getOrderItems(); // In order to improve efficiency a little bit, we will always create the ProductAssoc records // with productId < productIdTo when the two are compared. This way when checking for an existing // record we don't have to check both possible combinations of productIds TreeSet<String> productIdSet = new TreeSet<String>(); if (orderItems != null) { for (GenericValue orderItem : orderItems) { String productId = orderItem.getString("productId"); if (productId != null) { GenericValue parentProduct = ProductWorker.getParentProduct(productId, delegator); if (parentProduct != null) productId = parentProduct.getString("productId"); productIdSet.add(productId); } } } TreeSet<String> productIdToSet = new TreeSet<String>(productIdSet); for (String productId : productIdSet) { productIdToSet.remove(productId); for (String productIdTo : productIdToSet) { EntityCondition cond = EntityCondition .makeCondition(UtilMisc.toList(EntityCondition.makeCondition("productId", productId), EntityCondition.makeCondition("productIdTo", productIdTo), EntityCondition.makeCondition("productAssocTypeId", "ALSO_BOUGHT"), EntityCondition.makeCondition("fromDate", EntityOperator.LESS_THAN_EQUAL_TO, UtilDateTime.nowTimestamp()), EntityCondition.makeCondition("thruDate", null))); GenericValue existingProductAssoc = null; try { // No point in using the cache because of the filterByDateExpr existingProductAssoc = EntityUtil.getFirst(delegator.findList("ProductAssoc", cond, null, UtilMisc.toList("fromDate DESC"), null, false)); } catch (GenericEntityException e) { Debug.logError(e, module); } try { if (existingProductAssoc != null) { BigDecimal newQuantity = existingProductAssoc.getBigDecimal("quantity"); if (newQuantity == null || newQuantity.compareTo(BigDecimal.ZERO) < 0) { newQuantity = BigDecimal.ZERO; } newQuantity = newQuantity.add(BigDecimal.ONE); ModelService updateProductAssoc = dctx.getModelService("updateProductAssoc"); Map<String, Object> updateCtx = updateProductAssoc.makeValid(context, ModelService.IN_PARAM, true, null); updateCtx.putAll(updateProductAssoc.makeValid(existingProductAssoc, ModelService.IN_PARAM)); updateCtx.put("quantity", newQuantity); dispatcher.runSync("updateProductAssoc", updateCtx); } else { Map<String, Object> createCtx = FastMap.newInstance(); createCtx.put("userLogin", context.get("userLogin")); createCtx.put("productId", productId); createCtx.put("productIdTo", productIdTo); createCtx.put("productAssocTypeId", "ALSO_BOUGHT"); createCtx.put("fromDate", UtilDateTime.nowTimestamp()); createCtx.put("quantity", BigDecimal.ONE); dispatcher.runSync("createProductAssoc", createCtx); } } catch (GenericServiceException e) { Debug.logError(e, module); } } } return ServiceUtil.returnSuccess(); } /* public static Map<String, Object> createLMSShipment(DispatchContext dctx, Map<String, ? extends Object> context) { Delegator delegator = dctx.getDelegator(); LocalDispatcher dispatcher = dctx.getDispatcher(); GenericValue userLogin = (GenericValue) context.get("userLogin"); Map<String, Object> result = new HashMap<String, Object>(); Timestamp nowTimeStamp=UtilDateTime.nowTimestamp(); String estimatedDeliveryDateString = (String) context.get("estimatedDeliveryDate"); Timestamp estimatedDeliveryDate =null; String shipmentTypeId = (String) context.get("shipmentTypeId"); String facilityGroupId = (String) context.get("facilityGroupId"); String shipmentId = null; String subscriptionTypeId = "AM"; if(shipmentTypeId.equals("PM_SHIPMENT")){ subscriptionTypeId = "PM"; } SimpleDateFormat sdf = new SimpleDateFormat("MMMM dd, yyyy"); try { estimatedDeliveryDate = new java.sql.Timestamp(sdf.parse(estimatedDeliveryDateString).getTime()); } catch (ParseException e) { Debug.logError(e, "Cannot parse date string: "+ estimatedDeliveryDateString, module); return ServiceUtil.returnError("Failed to Generate TruckSheet ,Cannot parse date string:" + e); // effectiveDate = UtilDateTime.nowTimestamp(); } // checking if shipment exists for the specified day then return without creating orders. estimatedDeliveryDate = UtilDateTime.getDayStart(estimatedDeliveryDate); Timestamp dayBegin = UtilDateTime.getDayStart(estimatedDeliveryDate); Timestamp dayEnd = UtilDateTime.getDayEnd(estimatedDeliveryDate); List conditionList = FastList.newInstance(); List shipmentList = FastList.newInstance(); GenericValue facilityGroup = null; try{ if(UtilValidate.isNotEmpty(facilityGroupId)){ facilityGroup = delegator.findOne("FacilityGroup",UtilMisc.toMap("facilityGroupId",facilityGroupId) , false); conditionList.add(EntityCondition.makeCondition("originFacilityId", EntityOperator.EQUALS ,facilityGroup.getString("ownerFacilityId"))); } }catch (GenericEntityException e) { Debug.logError(e, module); return ServiceUtil.returnError("Failed to find FacilityGroup " + e); } conditionList.add(EntityCondition.makeCondition("statusId", EntityOperator.IN , UtilMisc.toList("GENERATED","IN_PROCESS"))); conditionList.add(EntityCondition.makeCondition("shipmentTypeId", EntityOperator.EQUALS ,shipmentTypeId)); conditionList.add(EntityCondition.makeCondition("estimatedShipDate", EntityOperator.GREATER_THAN_EQUAL_TO ,dayBegin)); conditionList.add(EntityCondition.makeCondition("estimatedShipDate", EntityOperator.LESS_THAN_EQUAL_TO ,dayEnd)); EntityCondition condition=EntityCondition.makeCondition(conditionList,EntityOperator.AND); try { shipmentList = delegator.findList("Shipment", condition, null,null, null, false); if(!UtilValidate.isEmpty(shipmentList)){ return ServiceUtil.returnError("Failed to create Trucksheet, Already Generated OR Inprocess for the specified day"); } }catch (GenericEntityException e) { Debug.logError(e, module); return ServiceUtil.returnError("Failed to find ShipmentList " + e); } // attempt to create a Shipment entity GenericValue newEntity = delegator.makeValue("Shipment"); if(UtilValidate.isNotEmpty(facilityGroup)){ newEntity.set("originFacilityId", facilityGroup.getString("ownerFacilityId")); } newEntity.set("estimatedShipDate", estimatedDeliveryDate); newEntity.set("shipmentTypeId", shipmentTypeId); newEntity.set("statusId", "IN_PROCESS"); newEntity.set("createdByUserLogin", userLogin.get("userLoginId")); newEntity.set("lastModifiedByUserLogin", userLogin.get("userLoginId")); try { delegator.createSetNextSeqId(newEntity); shipmentId = (String) newEntity.get("shipmentId"); } catch (GenericEntityException e) { Debug.logError(e, module); return ServiceUtil.returnError("Failed to create a new shipment " + e); } try { Map<String, Object> runSACOContext = UtilMisc.<String, Object>toMap("shipmentId", shipmentId, "estimatedDeliveryDate", estimatedDeliveryDate,"userLogin", userLogin); runSACOContext.put("facilityGroupId", facilityGroupId); dispatcher.runAsync("runSubscriptionAutoCreateOrders", runSACOContext); } catch (GenericServiceException e) { Debug.logError(e, "Error calling runSubscriptionAutoCreateOrders service", module); return ServiceUtil.returnError(e.getMessage()); } result.put("shipmentId", shipmentId); result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS); return result; } public static Map<String, Object> runSubscriptionAutoCreateOrders(DispatchContext dctx, Map<String, Object> context) { Delegator delegator = dctx.getDelegator(); LocalDispatcher dispatcher = dctx.getDispatcher(); GenericValue userLogin = (GenericValue) context.get("userLogin"); Locale locale = (Locale) context.get("locale"); Map<String, Object> result = ServiceUtil.returnSuccess(); List<GenericValue> subscriptionList=FastList.newInstance(); Timestamp nowTimeStamp=UtilDateTime.nowTimestamp(); Timestamp estimatedDeliveryDate = (Timestamp) context.get("estimatedDeliveryDate"); String shipmentId = (String) context.get("shipmentId"); String facilityGroupId = (String) context.get("facilityGroupId"); GenericValue shipment; boolean beganTransaction = false; try { beganTransaction = TransactionUtil.begin(72000); shipment=delegator.findOne("Shipment",UtilMisc.toMap("shipmentId", shipmentId), false); if (shipment == null) { Debug.logError("Shipment does not exist " + shipmentId, module); return ServiceUtil.returnError("Shipment does not exist " + shipmentId); } } catch (GenericEntityException e) { Debug.logError(e, "Error getting shipment " + shipmentId, module); return ServiceUtil.returnError("Error getting shipment " + shipmentId + ": " + e); } String shipmentTypeId = shipment.getString("shipmentTypeId"); String subscriptionTypeId = "AM"; if(shipmentTypeId.equals("PM_SHIPMENT")){ subscriptionTypeId = "PM"; } // ::TODO:: handle subscriptionTypeId and iSuspended List<GenericValue> subscriptionProductsList = FastList.newInstance(); try { List conditionList = UtilMisc.toList( EntityCondition.makeCondition("fromDate", EntityOperator.LESS_THAN_EQUAL_TO, estimatedDeliveryDate)); conditionList.add(EntityCondition.makeCondition(EntityCondition.makeCondition("thruDate", EntityOperator.EQUALS, null), EntityOperator.OR, EntityCondition.makeCondition("thruDate", EntityOperator.GREATER_THAN_EQUAL_TO, estimatedDeliveryDate))); conditionList.add(EntityCondition.makeCondition("quantity", EntityOperator.NOT_EQUAL, BigDecimal.ZERO)); if(subscriptionTypeId.equals("AM")){ conditionList.add(EntityCondition.makeCondition(EntityCondition.makeCondition("subscriptionTypeId", EntityOperator.EQUALS, subscriptionTypeId) ,EntityOperator.OR ,EntityCondition.makeCondition("subscriptionTypeId", EntityOperator.EQUALS, null))); }else{ conditionList.add(EntityCondition.makeCondition("subscriptionTypeId", EntityOperator.EQUALS, subscriptionTypeId)); } if(UtilValidate.isNotEmpty(facilityGroupId)){ // lets get the facility GroupMembers for given facility Map<String, Object> facilityGroupCtx = FastMap.newInstance(); facilityGroupCtx.putAll(context); facilityGroupCtx.put("fromDate", estimatedDeliveryDate); List facilityIds = (List)DeprecatedNetworkServices.getFacilityGroupMemberList(dctx, facilityGroupCtx).get("facilityIds"); conditionList.add(EntityCondition.makeCondition("facilityId", EntityOperator.IN, facilityIds)); } EntityCondition condition = EntityCondition.makeCondition(conditionList, EntityOperator.AND); List<String> orderBy = UtilMisc.toList("subscriptionId", "productSubscriptionTypeId","-productId"); subscriptionProductsList = delegator.findList("SubscriptionFacilityAndSubscriptionProduct", condition, null, orderBy, null, false); } catch (GenericEntityException e) { Debug.logError(e, "Problem getting Subscription Products", module); //::TODO:: set shipment status } // Here Getting absentee Booth list and absentee Override list Map<String, Object> stopShipCtx = FastMap.newInstance(); stopShipCtx.putAll(context); stopShipCtx.put("supplyDate", estimatedDeliveryDate); Map boothPaymentsMap = DeprecatedNetworkServices.getStopShipList(dctx ,stopShipCtx); List stopShipList =(List)boothPaymentsMap.get("boothList"); HashSet stopShipSet = new HashSet(stopShipList); Debug.logImportant("stopShipList size======"+stopShipList.size(), ""); Debug.logImportant("stopShipList ======"+stopShipList, ""); context.put("stopShipSet",stopShipSet); String tempSubId = ""; String tempTypeId = ""; String subId; String typeId; int orderCounter = 0; Timestamp startTimestamp = UtilDateTime.nowTimestamp(); double elapsedSeconds; boolean generationFailed = false; BigDecimal totalQuantity = ZERO; List<GenericValue> orderSubProdsList = FastList.newInstance(); for (int j = 0; j < subscriptionProductsList.size(); j++) { subId = subscriptionProductsList.get(j).getString("subscriptionId"); typeId = subscriptionProductsList.get(j).getString("productSubscriptionTypeId"); if (tempSubId == "") { tempSubId = subId; tempTypeId = typeId; } condition: "!(typeId.startsWith(tempTypeId))" is to generate same order for CASH_FS and CASH if (!tempSubId.equals(subId) || (!tempTypeId.equals(typeId) && !(typeId.startsWith(tempTypeId)))) { result = createSalesOrderSubscriptionProductType(dctx, context, orderSubProdsList); if (ServiceUtil.isError(result)) { Debug.logError("Unable to generate order: " + ServiceUtil.getErrorMessage(result), module); generationFailed = true; break; } BigDecimal quantity = (BigDecimal)result.get("quantity"); if (quantity != null) { totalQuantity = totalQuantity.add(quantity); } orderCounter++; if ((orderCounter % 200) == 0) { elapsedSeconds = UtilDateTime.getInterval(startTimestamp, UtilDateTime.nowTimestamp())/1000; Debug.logImportant("Completed " + orderCounter + " orders [ in " + elapsedSeconds + " seconds]", module); } orderSubProdsList.clear(); tempSubId = subId; tempTypeId = typeId; } orderSubProdsList.add(subscriptionProductsList.get(j)); } if (orderSubProdsList.size() > 0 && !generationFailed) { result = createSalesOrderSubscriptionProductType(dctx, context, orderSubProdsList); if (ServiceUtil.isError(result)) { Debug.logError("Unable to generate order: " + ServiceUtil.getErrorMessage(result), module); generationFailed = true; } BigDecimal quantity = (BigDecimal)result.get("quantity"); if (quantity != null) { totalQuantity = totalQuantity.add(quantity); } orderCounter++; } elapsedSeconds = UtilDateTime.getInterval(startTimestamp, UtilDateTime.nowTimestamp())/1000; Debug.logImportant("Completed " + orderCounter + " orders [ in " + elapsedSeconds + " seconds]", module); if (generationFailed) { try { // only rollback the transaction if we started one... TransactionUtil.rollback(); } catch (Exception e2) { Debug.logError(e2, "Could not rollback transaction: " + e2.toString(), module); } shipment.set("statusId", "GENERATION_FAIL"); } else { shipment.set("statusId", "GENERATED"); try { // Send SMS notification to list String text = "Trucksheet has been successfully generated for " + UtilDateTime.toDateString(estimatedDeliveryDate, "dd/MM/yyyy") + " [" + totalQuantity.setScale(1, UtilNumber.getBigDecimalRoundingMode("order.rounding")) + " ltrs]. Automatic message sent by Vasista Vbiz."; Map<String, Object> sendSmsContext = UtilMisc.<String, Object>toMap("contactListId", "TRCKSHT_NOTIFY_LST", "text", text, "userLogin", userLogin); dispatcher.runAsync("sendSmsToContactListNoCommEvent", sendSmsContext); } catch (GenericServiceException e) { Debug.logError(e, "Error calling sendSmsToContactListNoCommEvent service", module); } } try { //shipment.store(); Map<String, Object> updateShipmentCtx = FastMap.newInstance(); updateShipmentCtx.put("userLogin", context.get("userLogin")); updateShipmentCtx.put("shipmentId", shipmentId); updateShipmentCtx.put("statusId", shipment.getString("statusId")); dispatcher.runSync("updateLmsShipmentEntry", updateShipmentCtx); } catch (GenericServiceException e) { Debug.logError(e, "Failed to update shipment status " + shipmentId, module); return ServiceUtil.returnError("Failed to update shipment status " + shipmentId + ": " + e); } return ServiceUtil.returnSuccess(); } public static Map<String, Object> createSalesOrderSubscriptionProduct(DispatchContext dctx, Map<String, ? extends Object> context) { need to clean up this get all SubscriptionProductTypes from EnumTypeId createSalesOrderSubscriptionProductType(dctx,context,"CARD"); createSalesOrderSubscriptionProductType(dctx,context,"CASH"); createSalesOrderSubscriptionProductType(dctx,context,"CREDIT"); createSalesOrderSubscriptionProductType(dctx,context,"SPECIAL_ORDER"); return ServiceUtil.returnSuccess(); } public static Map<String, Object> createSalesOrderSubscriptionProductType(DispatchContext dctx, Map<String, ? extends Object> context,List<GenericValue> subscriptionProductsList) { LocalDispatcher dispatcher = dctx.getDispatcher(); Delegator delegator = dctx.getDelegator(); Locale locale = (Locale) context.get("locale"); GenericValue userLogin = (GenericValue) context.get("userLogin"); String currencyUomId = (String) context.get("defaultOrganizationPartyCurrencyUomId"); Timestamp estimatedDeliveryDate = (Timestamp) context.get("estimatedDeliveryDate"); String facilityGroupId = (String) context.get("facilityGroupId"); String shipmentId = (String) context.get("shipmentId"); Set stopShipSet = (HashSet) context.get("stopShipSet"); Map<String, Object> resultMap = FastMap.newInstance(); BigDecimal quantity = ZERO; String productStoreId=""; String salesChannel = (String) context.get("salesChannel"); if (UtilValidate.isEmpty(salesChannel)) { salesChannel = "LMS_SALES_CHANNEL"; } if (UtilValidate.isEmpty(subscriptionProductsList)) { //Debug.logInfo("No subscription to create orders, finished", module); return resultMap; } String productSubscriptionTypeId = subscriptionProductsList.get(0).getString("productSubscriptionTypeId"); if(productSubscriptionTypeId.equals("CASH_FS")){ productSubscriptionTypeId = "CASH"; } String partyId = subscriptionProductsList.get(0).getString("ownerPartyId"); String facilityId = subscriptionProductsList.get(0).getString("facilityId"); boolean enableStopShip = Boolean.TRUE; try{ GenericValue tenantConfigEnablePaymentSms = delegator.findOne("TenantConfiguration", UtilMisc.toMap("propertyTypeEnumId","LMS", "propertyName","enableStopShip"), false); if (UtilValidate.isNotEmpty(tenantConfigEnablePaymentSms) && (tenantConfigEnablePaymentSms.getString("propertyValue")).equals("N")) { enableStopShip = Boolean.FALSE; } }catch (GenericEntityException e) { // TODO: handle exception Debug.logError(e, module); } if(enableStopShip){ if(productSubscriptionTypeId.equals("CASH")){ if(stopShipSet.contains(facilityId)){ Debug.logImportant("booth has due amount so stop cash quota==========="+facilityId, module); return ServiceUtil.returnSuccess("booth has due amount so stop cash quote==========="+facilityId); } } } try { GenericValue product=delegator.findOne("Product",UtilMisc.toMap("productId", (String)subscriptionProductsList.get(0).getString("productId")), false); List<GenericValue> prodCatalogCategoryList = delegator.findList("ProdCatalogCategory", EntityCondition.makeCondition("productCategoryId", EntityOperator.EQUALS, product.getString("primaryProductCategoryId")), null, null, null, false); List<GenericValue> productStoreCatalogList = delegator.findList("ProductStoreCatalog", EntityCondition.makeCondition("prodCatalogId", EntityOperator.EQUALS, (String)prodCatalogCategoryList.get(0).getString("prodCatalogId")), null, null, null, false); productStoreId= (String)productStoreCatalogList.get(0).getString("productStoreId"); } catch (GenericEntityException e) { Debug.logError(e, "Problem getting product store Id", module); return ServiceUtil.returnError("Problem getting product store Id: " + e); } ShoppingCart cart = new ShoppingCart(delegator, productStoreId, locale, currencyUomId); cart.setOrderType("SALES_ORDER"); cart.setChannelType(salesChannel); cart.setProductStoreId(productStoreId); cart.setBillToCustomerPartyId(partyId); cart.setPlacingCustomerPartyId(partyId); cart.setShipToCustomerPartyId(partyId); cart.setEndUserCustomerPartyId(partyId); cart.setFacilityId(facilityId); cart.setEstimatedDeliveryDate(estimatedDeliveryDate); cart.setProductSubscriptionTypeId(productSubscriptionTypeId); cart.setShipmentId(shipmentId); try { cart.setUserLogin(userLogin, dispatcher); } catch (Exception exc) { Debug.logWarning("Error setting userLogin in the cart: " + exc.getMessage(), module); return ServiceUtil.returnError("Error setting userLogin in the cart: " + exc.getMessage()); } Iterator<GenericValue> i = subscriptionProductsList.iterator(); while (i.hasNext()) { GenericValue subscriptionProduct = i.next(); if (subscriptionProduct != null) { try { Map<String, Object> priceResult; Map<String, Object> priceContext = FastMap.newInstance(); priceContext.put("userLogin", userLogin); priceContext.put("productStoreId", productStoreId); priceContext.put("productId", subscriptionProduct.getString("productId")); priceContext.put("partyId", partyId); priceContext.put("priceDate", estimatedDeliveryDate); priceContext.put("facilityCategory", subscriptionProduct.getString("categoryTypeEnum")); if (productSubscriptionTypeId.equals("CARD")) { priceContext.put("productPriceTypeId", "CARD_PRICE"); } priceResult = PriceServices.calculateLMSProductPrice(delegator, dispatcher, priceContext); if (ServiceUtil.isError(priceResult)) { Debug.logWarning("There was an error while calculating the price: " + ServiceUtil.getErrorMessage(priceResult), module); return ServiceUtil.returnError("There was an error while calculating the price: " + ServiceUtil.getErrorMessage(priceResult)); } //Debug.logInfo("["+ subscriptionProduct.getString("productId") + "," + productSubscriptionTypeId + "," + (BigDecimal)priceResult.get("price") +"]",module); List<ShoppingCartItem> tempCartItems =cart.findAllCartItems(subscriptionProduct.getString("productId")); if(tempCartItems.size() >0){ ShoppingCartItem item = tempCartItems.get(0); item.setQuantity(item.getQuantity().add(new BigDecimal(subscriptionProduct.getString("quantity"))), dispatcher, cart); item.setBasePrice((BigDecimal)priceResult.get("price")); }else{ cart.addItem(0, ShoppingCartItem.makeItem(Integer.valueOf(0), subscriptionProduct.getString("productId"), null, new BigDecimal(subscriptionProduct.getString("quantity")), (BigDecimal)priceResult.get("price"), null, null, null, null, null, null, null, null, null, null, null, null, null, dispatcher, cart, Boolean.FALSE, Boolean.FALSE, null, Boolean.TRUE, Boolean.TRUE)); } GenericValue productDetail = delegator.findOne("Product", UtilMisc.toMap("productId", subscriptionProduct.getString("productId")), false); if (productDetail != null) { BigDecimal tempQuantity = subscriptionProduct.getBigDecimal("quantity").multiply(productDetail.getBigDecimal("quantityIncluded")); quantity = quantity.add(tempQuantity); } } catch (Exception exc) { Debug.logWarning("Error adding product with id " + subscriptionProduct.getString("productId") + " to the cart: " + exc.getMessage(), module); return ServiceUtil.returnError("Error adding product with id " + subscriptionProduct.getString("productId") + " to the cart: " + exc.getMessage()); } } } cart.setDefaultCheckoutOptions(dispatcher); CheckOutHelper checkout = new CheckOutHelper(dispatcher, delegator, cart, true); Map<String, Object> orderCreateResult = checkout.createOrder(userLogin); String orderId = (String) orderCreateResult.get("orderId"); // approve the order if (UtilValidate.isNotEmpty(orderId)) { boolean approved = OrderChangeHelper.approveOrder(dispatcher, userLogin, orderId); try{ resultMap = dispatcher.runSync("createInvoiceForOrderAllItems", UtilMisc.<String, Object>toMap("orderId", orderId,"userLogin", userLogin)); if (ServiceUtil.isError(resultMap)) { Debug.logWarning("There was an error while creating the invoice: " + ServiceUtil.getErrorMessage(resultMap), module); return ServiceUtil.returnError("There was an error while creating the invoice: " + ServiceUtil.getErrorMessage(resultMap)); } // apply invoice if any adavance payments from this party if(!productSubscriptionTypeId.equals("CARD")){ Map<String, Object> resultPaymentApp = dispatcher.runSync("settleInvoiceAndPayments", UtilMisc.<String, Object>toMap("invoiceId", (String)resultMap.get("invoiceId"),"userLogin", userLogin)); if (ServiceUtil.isError(resultPaymentApp)) { Debug.logWarning("There was an error while adjusting advance payment" + ServiceUtil.getErrorMessage(resultPaymentApp), module); return ServiceUtil.returnError("There was an error while adjusting advance payment" + ServiceUtil.getErrorMessage(resultPaymentApp)); } } //OrderChangeHelper.orderStatusChanges(dispatcher, userLogin, orderId, "ORDER_COMPLETED", "ITEM_APPROVED", "ITEM_COMPLETED", null); }catch (GenericServiceException e) { Debug.logError(e, module); } resultMap.put("orderId", orderId); resultMap.put("quantity", quantity); //Debug.logInfo("quantity=" + quantity, module); } return resultMap; } public static Map<String, Object> cancelLMSShipment(DispatchContext dctx, Map<String, ? extends Object> context) { Delegator delegator = dctx.getDelegator(); LocalDispatcher dispatcher = dctx.getDispatcher(); GenericValue userLogin = (GenericValue) context.get("userLogin"); Map<String, Object> result = new HashMap<String, Object>(); Timestamp nowTimeStamp=UtilDateTime.nowTimestamp(); Date nowDate=UtilDateTime.nowDate(); String shipmentId = (String) context.get("shipmentId"); List conditionList= FastList.newInstance(); List boothOrdersList = FastList.newInstance(); List boothOrderIdsList = FastList.newInstance(); List boothInvoiceIdsList = FastList.newInstance(); GenericValue shipment = null; Date shipDate = nowDate; try{ shipment = delegator.findOne("Shipment",UtilMisc.toMap("shipmentId", shipmentId), false); }catch (GenericEntityException e) { // TODO: handle exception Debug.logError("Unable to get Shipment record from DataBase"+e, module); return ServiceUtil.returnError("Unable to get Shipment record from DataBase "); } try{ shipDate = ((new DateTimeConverters.TimestampToSqlDate())).convert(shipment.getTimestamp("estimatedShipDate")) ; } catch(ConversionException e){ Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } boolean enableCancelAfterShipDate = Boolean.FALSE; try{ GenericValue tenantConfigEnableCancelAfterShipDate = delegator.findOne("TenantConfiguration", UtilMisc.toMap("propertyTypeEnumId","LMS", "propertyName","enableCancelAfterShipDate"), false); if (UtilValidate.isNotEmpty(tenantConfigEnableCancelAfterShipDate) && (tenantConfigEnableCancelAfterShipDate.getString("propertyValue")).equals("Y")) { enableCancelAfterShipDate = Boolean.TRUE; } } catch (GenericEntityException e) { Debug.logError(e, module); } if(!enableCancelAfterShipDate && nowDate.after(shipDate)){ Debug.logError("Truck sheet cancel not allowed after shipment date", module); return ServiceUtil.returnError("Truck sheet cancel not allowed after Shipment date"); } conditionList.add(EntityCondition.makeCondition("shipmentId", EntityOperator.EQUALS, shipmentId)); EntityCondition condition=EntityCondition.makeCondition(conditionList,EntityOperator.AND); EntityFindOptions findOptions = new EntityFindOptions(); findOptions.setDistinct(true); //Set fieldsToSelect = [, "orderDate", "productId", "quantity" ,"grandTotal" ,"productSubscriptionTypeId" ,"originFacilityId" ,"unitPrice" ,"categoryTypeEnum"] as Set; try{ dispatcher.runAsync("cancelLMSShipmentInternal", UtilMisc.toMap("shipmentId", shipmentId,"userLogin", userLogin)); }catch (GenericServiceException e) { // TODO: handle exception Debug.logError("Unable to get records from DataBase"+e, module); return ServiceUtil.returnError(e.getMessage()); } shipment.set("statusId", "CANCEL_INPROCESS"); try{ shipment.store(); }catch (Exception e) { // TODO: handle exception Debug.logError("Unable to Store Shipment Status"+e, module); return ServiceUtil.returnError("Unable to Store Shipment Status"); } return result; } public static Map<String, Object> cancelLMSShipmentInternal(DispatchContext dctx, Map<String, ? extends Object> context) { Delegator delegator = dctx.getDelegator(); LocalDispatcher dispatcher = dctx.getDispatcher(); GenericValue userLogin = (GenericValue) context.get("userLogin"); Map<String, Object> result = new HashMap<String, Object>(); Timestamp nowTimeStamp=UtilDateTime.nowTimestamp(); Date nowDate=UtilDateTime.nowDate(); String shipmentId = (String) context.get("shipmentId"); List conditionList= FastList.newInstance(); List boothOrdersList = FastList.newInstance(); List boothOrderIdsList = FastList.newInstance(); List boothInvoiceIdsList = FastList.newInstance(); GenericValue shipment = null; Date shipDate = nowDate; try{ // To change shipment status here we are getting shipment Generic Value shipment = delegator.findOne("Shipment",UtilMisc.toMap("shipmentId", shipmentId), false); }catch (GenericEntityException e) { // TODO: handle exception Debug.logError("Unable to get Shipment record from DataBase"+e, module); return ServiceUtil.returnError("Unable to get Shipment record from DataBase "); } conditionList.add(EntityCondition.makeCondition("shipmentId", EntityOperator.EQUALS, shipmentId)); EntityCondition condition=EntityCondition.makeCondition(conditionList,EntityOperator.AND); EntityFindOptions findOptions = new EntityFindOptions(); findOptions.setDistinct(true); try{ List boothOrderItemsList = delegator.findList("OrderHeaderItemProductShipmentAndFacility", condition, UtilMisc.toSet("orderId") , null, null, false); Set orderIdsSet= new HashSet( EntityUtil.getFieldListFromEntityList(boothOrderItemsList, "orderId", true)); boothOrderIdsList = new ArrayList(orderIdsSet); //to get all invoices for the shipment boothOrdersList = delegator.findList("OrderHeaderFacAndItemBillingInv", condition, UtilMisc.toSet("orderId","originFacilityId","invoiceId") , UtilMisc.toList("originFacilityId"), findOptions , false); Set invoiceIdsSet= new HashSet(EntityUtil.getFieldListFromEntityList(boothOrdersList, "invoiceId", true)); boothInvoiceIdsList = new ArrayList(invoiceIdsSet); }catch (GenericEntityException e) { // TODO: handle exception Debug.logError("Unable to get records from DataBase"+e, module); return ServiceUtil.returnError("Unable to get records from DataBase "); } try{ result = dispatcher.runSync("massCancelOrders", UtilMisc.<String, Object>toMap("orderIdList", boothOrderIdsList,"userLogin", userLogin)); if (ServiceUtil.isError(result)) { Debug.logWarning("There was an error while Cancel the Orders: " + ServiceUtil.getErrorMessage(result), module); return ServiceUtil.returnError("There was an error while Cancel the Orders: "); } result = dispatcher.runSync("massChangeInvoiceStatus", UtilMisc.toMap("invoiceIds", boothInvoiceIdsList, "statusId","INVOICE_CANCELLED","userLogin", userLogin)); if (ServiceUtil.isError(result)) { Debug.logWarning("There was an error while Cancel the invoices: " + ServiceUtil.getErrorMessage(result), module); return ServiceUtil.returnError("There was an error while Cancel the invoices: "); } }catch (GenericServiceException e) { // TODO: handle exception Debug.logError("Unable to Cancel bulk orders"+e, module); return ServiceUtil.returnError("Unable to Cancel bulk order"); } shipment.set("statusId", "SHIPMENT_CANCELLED"); try{ shipment.store(); }catch (Exception e) { // TODO: handle exception Debug.logError("Unable to Store Shipment Status"+e, module); return ServiceUtil.returnError("Unable to Store Shipment Status"); } return result; } */ /*public static String createGatePassIndent(HttpServletRequest request,HttpServletResponse response) { Delegator delegator = (Delegator) request.getAttribute("delegator"); LocalDispatcher dispatcher = (LocalDispatcher) request.getAttribute("dispatcher"); Locale locale = UtilHttp.getLocale(request); HttpSession session = request.getSession(); GenericValue userLogin = (GenericValue) session.getAttribute("userLogin"); String boothId = (String) request.getParameter("boothId"); try{ Map faclityResult = dispatcher.runSync("isFacilityAcitve", UtilMisc.<String, Object>toMap("facilityId", boothId,"userLogin", userLogin)); if (ServiceUtil.isError(faclityResult)) { String errMsg = ServiceUtil.getErrorMessage(faclityResult); Debug.logError(errMsg , module); request.setAttribute("_ERROR_MESSAGE_",errMsg); return "error"; } }catch (GenericServiceException e) { // TODO: handle exception Debug.logError(e.toString(), module); } String salesChannel = "LMS_SALES_CHANNEL"; String facilityId; String partyId = ""; String approveOrder=""; Date estimatedDeliveryDate; String effectiveDateStr = (String) request.getParameter("effectiveDate"); String shipmentTypeId = (String) request.getParameter("shipmentTypeId"); String currencyUomId = UtilHttp.getCurrencyUom(request); String productSubscriptionTypeId = (String) request.getParameter("productSubscriptionTypeId"); String productId = null; String quantityStr = null; String productStoreId = ""; Timestamp effectiveDate = null; Timestamp nowTimeStamp = UtilDateTime.nowTimestamp(); BigDecimal quantity = BigDecimal.ZERO; List<GenericValue> subscriptionList = FastList.newInstance(); Map<String, Object> result = ServiceUtil.returnSuccess(); Map<String, Object> resultMap = FastMap.newInstance(); GenericValue subscription = null; boolean beganTransaction = false; try { beganTransaction = TransactionUtil.begin(); if (UtilValidate.isNotEmpty(effectiveDateStr)) { // April 02, 2013 SimpleDateFormat sdf = new SimpleDateFormat("MMMMM dd, yyyy"); try { effectiveDate = new java.sql.Timestamp(sdf.parse(effectiveDateStr).getTime()); effectiveDate = UtilDateTime.getDayStart(effectiveDate, TimeZone.getDefault(), locale); } catch (ParseException e) { Debug.logError(e, "Cannot parse date string: "+ effectiveDateStr, module); request.setAttribute("_ERROR_MESSAGE_", e.getMessage()); return "error"; // effectiveDate = UtilDateTime.nowTimestamp(); } catch (NullPointerException e) { Debug.logError(e, "Cannot parse date string: "+ effectiveDateStr, module); request.setAttribute("_ERROR_MESSAGE_", e.getMessage()); return "error"; // effectiveDate = UtilDateTime.nowTimestamp(); } } if (boothId == "") { request.setAttribute("_ERROR_MESSAGE_","Booth Id is empty"); return "error"; } // Get the parameters as a MAP, remove the productId and quantity // params. Map<String, Object> paramMap = UtilHttp.getParameterMap(request); int rowCount = UtilHttp.getMultiFormRowCount(paramMap); if (rowCount < 1) { Debug.logError("Nothing has been selected for = " + rowCount, module); request.setAttribute("_ERROR_MESSAGE_","No selection has been made" ); return "error"; } //attempt modify shipdate for PM Gate Pass // lets check the tenant configuration for enableSameDayPmEntry Boolean enableSameDayPmEntry = Boolean.FALSE; try{ GenericValue tenantConfigEnableSameDayPmEntry = delegator.findOne("TenantConfiguration", UtilMisc.toMap("propertyTypeEnumId","LMS", "propertyName","enableSameDayPmEntry"), false); if (UtilValidate.isNotEmpty(tenantConfigEnableSameDayPmEntry) && (tenantConfigEnableSameDayPmEntry.getString("propertyValue")).equals("Y")) { enableSameDayPmEntry = Boolean.TRUE; } }catch (GenericEntityException e) { // TODO: handle exception Debug.logError(e, module); } if(!enableSameDayPmEntry){ if(shipmentTypeId.equals("PM_SHIPMENT_SUPPL")){ effectiveDate = UtilDateTime.addDaysToTimestamp(effectiveDate,-1); } } // attempt to create a Shipment entity String shipmentId = ""; Timestamp dayBegin = UtilDateTime.getDayStart(effectiveDate, TimeZone.getDefault(), locale); Timestamp dayEnd = UtilDateTime.getDayEnd(effectiveDate, TimeZone.getDefault(), locale); List conditionList = FastList.newInstance(); List shipmentList = FastList.newInstance(); conditionList.add(EntityCondition.makeCondition("statusId", EntityOperator.EQUALS , "GENERATED")); conditionList.add(EntityCondition.makeCondition("shipmentTypeId", EntityOperator.EQUALS ,shipmentTypeId)); conditionList.add(EntityCondition.makeCondition("estimatedShipDate", EntityOperator.GREATER_THAN_EQUAL_TO ,dayBegin)); conditionList.add(EntityCondition.makeCondition("estimatedShipDate", EntityOperator.LESS_THAN_EQUAL_TO ,dayEnd)); EntityCondition condition=EntityCondition.makeCondition(conditionList,EntityOperator.AND); try { shipmentList = delegator.findList("Shipment", condition, null,null, null, false); }catch (GenericEntityException e) { Debug.logError(e, module); request.setAttribute("_ERROR_MESSAGE_", "un able to create shipment id."); return "error"; } if(UtilValidate.isEmpty(shipmentList)){ GenericValue newEntity = delegator.makeValue("Shipment"); newEntity.set("estimatedShipDate", effectiveDate); newEntity.set("shipmentTypeId", shipmentTypeId); newEntity.set("statusId", "GENERATED"); newEntity.set("createdByUserLogin", userLogin.get("userLoginId")); newEntity.set("lastModifiedByUserLogin", userLogin.get("userLoginId")); try { delegator.createSetNextSeqId(newEntity); shipmentId = (String) newEntity.get("shipmentId"); } catch (GenericEntityException e) { Debug.logError(e, module); request.setAttribute("_ERROR_MESSAGE_", "un able to create shipment id."); return "error"; } }else{ shipmentId = EntityUtil.getFirst(shipmentList).getString("shipmentId"); } request.setAttribute("shipmentId",shipmentId); GenericValue facility; try { facility = delegator.findOne("Facility",UtilMisc.toMap("facilityId", boothId), false); if(UtilValidate.isEmpty(facility)){ request.setAttribute("_ERROR_MESSAGE_", "Booth"+"'"+boothId+"'"+" does not exist"); return "error"; } partyId = facility.getString("ownerPartyId"); GenericValue product = delegator.findOne("Product",UtilMisc.toMap("productId",paramMap.get("productId"+ UtilHttp.MULTI_ROW_DELIMITER + "0")),false); List<GenericValue> prodCatalogCategoryList = delegator.findList("ProdCatalogCategory", EntityCondition.makeCondition("productCategoryId", EntityOperator.EQUALS,product.getString("primaryProductCategoryId")),null, null, null, false); List<GenericValue> productStoreCatalogList = delegator.findList("ProductStoreCatalog", EntityCondition.makeCondition("prodCatalogId",EntityOperator.EQUALS,(String) prodCatalogCategoryList.get(0).getString("prodCatalogId")), null, null, null, false); productStoreId = (String) productStoreCatalogList.get(0).getString("productStoreId"); } catch (Exception e) { Debug.logWarning(e, "Problems parsing quantity string: "+ quantityStr, module); request.setAttribute("_ERROR_MESSAGE_", e.getMessage()); return "error"; } ShoppingCart cart = new ShoppingCart(delegator, productStoreId, locale,currencyUomId); cart.setOrderType("SALES_ORDER"); cart.setChannelType(salesChannel); cart.setFacilityId(boothId); cart.setBillToCustomerPartyId(partyId); cart.setPlacingCustomerPartyId(partyId); cart.setShipToCustomerPartyId(partyId); cart.setShipmentId(shipmentId); cart.setEndUserCustomerPartyId(partyId); cart.setEstimatedDeliveryDate(effectiveDate); cart.setProductSubscriptionTypeId(productSubscriptionTypeId); try { cart.setUserLogin(userLogin, dispatcher); } catch (Exception e) { Debug.logWarning(e, "Unable to create user login", module); request.setAttribute("_ERROR_MESSAGE_","Unable to create user login"); return "error"; } for (int i = 0; i < rowCount; i++) { List<GenericValue> subscriptionProductsList = FastList.newInstance(); String thisSuffix = UtilHttp.MULTI_ROW_DELIMITER + i; if (paramMap.containsKey("productId" + thisSuffix)) { productId = (String) paramMap.remove("productId" + thisSuffix); } if (paramMap.containsKey("quantity" + thisSuffix)) { quantityStr = (String) paramMap.remove("quantity" + thisSuffix); } if ((quantityStr == null) || (quantityStr.equals(""))) { continue; } try { quantity = new BigDecimal(quantityStr); } catch (Exception e) { Debug.logWarning(e, "Problems parsing quantity string: "+ quantityStr, module); request.setAttribute("_ERROR_MESSAGE_", e.getMessage()); return "error"; } try { Map<String, Object> priceResult; Map<String, Object> priceContext = FastMap.newInstance(); priceContext.put("userLogin", userLogin); priceContext.put("shipmentTypeId", shipmentTypeId); priceContext.put("productStoreId", productStoreId); priceContext.put("productId", productId); priceContext.put("partyId", partyId); priceContext.put("priceDate", effectiveDate); priceContext.put("facilityCategory", facility.getString("categoryTypeEnum")); if (productSubscriptionTypeId.equals("CARD")) { priceContext.put("productPriceTypeId", "CARD_PRICE"); } priceResult = PriceServices.calculateLMSProductPrice(delegator, dispatcher, priceContext); if (ServiceUtil.isError(priceResult)) { TransactionUtil.rollback(); Debug.logWarning("There was an error while calculating the price: " + ServiceUtil.getErrorMessage(priceResult), module); request.setAttribute("_ERROR_MESSAGE_", "There was an error while calculating the price: " + ServiceUtil.getErrorMessage(priceResult)); return "error"; } //Debug.logInfo("["+ subscriptionProduct.getString("productId") + "," + productSubscriptionTypeId + "," + (BigDecimal)priceResult.get("price") +"]",module); cart.addItem(0, ShoppingCartItem.makeItem(Integer.valueOf(0), productId, null, new BigDecimal(quantityStr), (BigDecimal)priceResult.get("price"), null, null, null, null, null, null, null, null, null, null, null, null, null, dispatcher, cart, Boolean.FALSE, Boolean.FALSE, null, Boolean.TRUE, Boolean.TRUE)); } catch (Exception exc) { TransactionUtil.rollback(); Debug.logWarning("Error adding product with id " + productId + " to the cart: " + exc.getMessage(), module); request.setAttribute("_ERROR_MESSAGE_", "Error adding product with id " + productId + " to the cart: " + exc.getMessage()); return "error"; } } cart.setDefaultCheckoutOptions(dispatcher); CheckOutHelper checkout = new CheckOutHelper(dispatcher, delegator,cart); Map<String, Object> orderCreateResult = checkout.createOrder(userLogin); String orderId = (String) orderCreateResult.get("orderId"); // approve the order if (UtilValidate.isNotEmpty(orderId)) { Debug.logInfo("Created test order with id: " + orderId, module); boolean approved = OrderChangeHelper.approveOrder(dispatcher,userLogin, orderId); if (!approved) { request.setAttribute("_ERROR_MESSAGE_","Order approval failed"); return "error"; } try{ resultMap = dispatcher.runSync("createInvoiceForOrderAllItems", UtilMisc.<String, Object>toMap("orderId", orderId,"userLogin", userLogin)); if (ServiceUtil.isError(resultMap)) { Debug.logWarning("There was an error while creating the invoice: " + ServiceUtil.getErrorMessage(resultMap), module); request.setAttribute("_ERROR_MESSAGE_","There was an error while creating the invoice: " + ServiceUtil.getErrorMessage(resultMap)); return "error"; } // apply invoice if any adavance payments from this party if(!productSubscriptionTypeId.equals("CARD")){ Map<String, Object> resultPaymentApp = dispatcher.runSync("settleInvoiceAndPayments", UtilMisc.<String, Object>toMap("invoiceId", (String)resultMap.get("invoiceId"),"userLogin", userLogin)); if (ServiceUtil.isError(resultPaymentApp)) { TransactionUtil.rollback(); Debug.logWarning("There was an error while adjusting advance payment" + ServiceUtil.getErrorMessage(resultPaymentApp), module); request.setAttribute("_ERROR_MESSAGE_","There was an error while adjusting advance payment " + ServiceUtil.getErrorMessage(resultPaymentApp)); return "error"; } } }catch (GenericServiceException e) { Debug.logError(e, module); TransactionUtil.rollback(); } resultMap.put("orderId", orderId); } } catch (GenericEntityException e) { try { // only rollback the transaction if we started one... TransactionUtil.rollback(beganTransaction, "Error saving gate pass", e); } catch (GenericEntityException e2) { Debug.logError(e2, "Could not rollback transaction: " + e2.toString(), module); } Debug.logError(e, "An entity engine error occurred while saving gate pass order", module); } finally { // only commit the transaction if we started one... this will throw an exception if it fails try { TransactionUtil.commit(beganTransaction); } catch (GenericEntityException e) { Debug.logError(e, "Could not commit transaction for entity engine error occurred while saving gate pass order", module); } } return "success"; } public static String processTruckSheetCorrection(HttpServletRequest request, HttpServletResponse response) { Delegator delegator = (Delegator) request.getAttribute("delegator"); LocalDispatcher dispatcher = (LocalDispatcher) request.getAttribute("dispatcher"); Locale locale = UtilHttp.getLocale(request); String boothId = (String) request.getParameter("boothId"); String effectiveDateStr = (String) request.getParameter("effectiveDate"); String productSubscriptionTypeId = (String) request.getParameter("productSubscriptionTypeId"); String shipmentTypeId = (String) request.getParameter("shipmentTypeId"); String productId = null; String quantityStr = null; Timestamp effectiveDate=null; Timestamp nowTimeStamp = UtilDateTime.nowTimestamp(); BigDecimal quantity = BigDecimal.ZERO; List orderList = FastList.newInstance(); List orderItemListToUpdate = FastList.newInstance(); List invoiceItemListToUpdate = FastList.newInstance(); List conditionList = FastList.newInstance(); Map<String, Object> result = ServiceUtil.returnSuccess(); HttpSession session = request.getSession(); GenericValue userLogin = (GenericValue) session.getAttribute("userLogin"); GenericValue orderInfo = null; GenericValue facility = null; // String productStoreId=""; Boolean newItemFlag = false; boolean beganTransaction = false; try { beganTransaction = TransactionUtil.begin(); if (UtilValidate.isNotEmpty(effectiveDateStr)) { //April 02, 2013 SimpleDateFormat sdf = new SimpleDateFormat("MMMMM dd, yyyy"); try { effectiveDate = new java.sql.Timestamp(sdf.parse(effectiveDateStr).getTime()); effectiveDate = UtilDateTime.getDayStart(effectiveDate, TimeZone.getDefault(), locale); } catch (ParseException e) { Debug.logError(e, "Cannot parse date string: " + effectiveDateStr, module); // effectiveDate = UtilDateTime.nowTimestamp(); } catch (NullPointerException e) { Debug.logError(e, "Cannot parse date string: " + effectiveDateStr, module); //effectiveDate = UtilDateTime.nowTimestamp(); } } if (boothId == "") { request.setAttribute("_ERROR_MESSAGE_","Booth Id is empty"); TransactionUtil.rollback(); return "error"; }else{ try { facility = delegator.findOne("Facility",UtilMisc.toMap("facilityId", boothId), false); if(UtilValidate.isEmpty(facility)){ request.setAttribute("_ERROR_MESSAGE_", "Booth"+"'"+boothId+"'"+" does not exist"); TransactionUtil.rollback(); return "error"; } GenericValue product = delegator.findOne("Product",UtilMisc.toMap("productId",productId),false); List<GenericValue> prodCatalogCategoryList = delegator.findList("ProdCatalogCategory", EntityCondition.makeCondition("productCategoryId", EntityOperator.EQUALS,product.getString("primaryProductCategoryId")),null, null, null, false); List<GenericValue> productStoreCatalogList = delegator.findList("ProductStoreCatalog", EntityCondition.makeCondition("prodCatalogId",EntityOperator.EQUALS,(String) prodCatalogCategoryList.get(0).getString("prodCatalogId")), null, null, null, false); productStoreId = (String) productStoreCatalogList.get(0).getString("productStoreId"); } catch (Exception e) { Debug.logError(e, "Cannot parse date string: " + e.getMessage(), module); // effectiveDate = UtilDateTime.nowTimestamp(); } } // Get the parameters as a MAP, remove the productId and quantity params. Map<String, Object> paramMap = UtilHttp.getParameterMap(request); int rowCount = UtilHttp.getMultiFormRowCount(paramMap); if (rowCount < 1) { Debug.logWarning("No rows to process, as rowCount = " + rowCount, module); request.setAttribute("_ERROR_MESSAGE_","No rows to process"); return "success"; } try { //String shipmentId = ""; Timestamp dayBegin = UtilDateTime.getDayStart(effectiveDate, TimeZone.getDefault(), locale); Timestamp dayEnd = UtilDateTime.getDayEnd(effectiveDate, TimeZone.getDefault(), locale); // lets check the tenant configuration for enableSameDayPmEntry Boolean enableSameDayPmEntry = Boolean.FALSE; try{ GenericValue tenantConfigEnableSameDayPmEntry = delegator.findOne("TenantConfiguration", UtilMisc.toMap("propertyTypeEnumId","LMS", "propertyName","enableSameDayPmEntry"), false); if (UtilValidate.isNotEmpty(tenantConfigEnableSameDayPmEntry) && (tenantConfigEnableSameDayPmEntry.getString("propertyValue")).equals("Y")) { enableSameDayPmEntry = Boolean.TRUE; } }catch (GenericEntityException e) { // TODO: handle exception Debug.logError(e, module); } if(!enableSameDayPmEntry){ if(shipmentTypeId.indexOf("PM_") != -1 ){ dayBegin = UtilDateTime.getDayStart(effectiveDate ,-1); dayEnd = UtilDateTime.getDayEnd(dayBegin, TimeZone.getDefault(), locale); } } List shipmentList = FastList.newInstance(); conditionList.add(EntityCondition.makeCondition("statusId", EntityOperator.EQUALS , "GENERATED")); conditionList.add(EntityCondition.makeCondition("shipmentTypeId", EntityOperator.EQUALS ,shipmentTypeId)); conditionList.add(EntityCondition.makeCondition("estimatedShipDate", EntityOperator.GREATER_THAN_EQUAL_TO ,dayBegin)); conditionList.add(EntityCondition.makeCondition("estimatedShipDate", EntityOperator.LESS_THAN_EQUAL_TO ,dayEnd)); EntityCondition condition=EntityCondition.makeCondition(conditionList,EntityOperator.AND); try { shipmentList = delegator.findList("Shipment", condition, null,null, null, false); }catch (GenericEntityException e) { Debug.logError(e, module); request.setAttribute("_ERROR_MESSAGE_", "un able to get shipment id."); TransactionUtil.rollback(); return "error"; } if(UtilValidate.isEmpty(shipmentList)){ request.setAttribute("_ERROR_MESSAGE_", "no shipment done for the specified day."); TransactionUtil.rollback(); return "error"; } //shipmentId = EntityUtil.getFirst(shipmentList).getString("shipmentId"); conditionList.clear(); conditionList = UtilMisc.toList( EntityCondition.makeCondition("productSubscriptionTypeId", EntityOperator.EQUALS, productSubscriptionTypeId)); conditionList.add(EntityCondition.makeCondition("shipmentId", EntityOperator.IN, EntityUtil.getFieldListFromEntityList(shipmentList, "shipmentId", true))); conditionList.add(EntityCondition.makeCondition("originFacilityId", EntityOperator.EQUALS, boothId)); conditionList.add(EntityCondition.makeCondition("orderStatusId", EntityOperator.NOT_EQUAL, "ORDER_CANCELLED")); EntityCondition ohCondition = EntityCondition.makeCondition(conditionList, EntityOperator.AND); orderList=delegator.findList("OrderHeaderFacAndItemBillingInv", ohCondition, null, UtilMisc.toList("-orderId"), null, false); if(UtilValidate.isEmpty(orderList)){ request.setAttribute("_ERROR_MESSAGE_", "Quantity Not Disptched to the Booth Vendor"); TransactionUtil.rollback(); return "error"; } orderInfo = EntityUtil.getFirst(orderList); } catch (GenericEntityException e) { Debug.logError(e, "Problem getting Booth orderInfo", module); request.setAttribute("_ERROR_MESSAGE_", "Problem getting Booth orderInfo"); TransactionUtil.rollback(); return "error"; } String orderId = (String)orderInfo.getString("orderId"); for (int i = 0; i < rowCount; i++) { List<GenericValue> orderItemList = FastList.newInstance(); GenericValue orderItem = null; List<GenericValue> invoiceItemList = FastList.newInstance(); GenericValue invoiceItem = null; String thisSuffix = UtilHttp.MULTI_ROW_DELIMITER + i; if (paramMap.containsKey("productId" + thisSuffix)) { productId = (String) paramMap.remove("productId" + thisSuffix); } if (paramMap.containsKey("quantity" + thisSuffix)) { quantityStr = (String) paramMap.remove("quantity" + thisSuffix); } if ((quantityStr == null) || (quantityStr.equals(""))) { continue; } try { quantity = new BigDecimal(quantityStr); } catch (Exception e) { Debug.logWarning(e, "Problems parsing quantity string: " + quantityStr, module); quantity = BigDecimal.ZERO; } try{ conditionList = UtilMisc.toList(EntityCondition.makeCondition("orderId", EntityOperator.EQUALS, orderId)); conditionList.add(EntityCondition.makeCondition("productId", EntityOperator.EQUALS, productId)); EntityCondition condition = EntityCondition.makeCondition(conditionList, EntityOperator.AND); orderItemList = delegator.findList("OrderItem", condition, null, null, null, false); if(UtilValidate.isEmpty(orderItemList)){ // adding new item to the order if not newItemFlag= true; Map<String, Object> priceResult; try { Map<String, Object> priceContext = FastMap.newInstance(); priceContext.put("userLogin", userLogin); priceContext.put("shipmentTypeId", shipmentTypeId); priceContext.put("productStoreId", orderInfo.getString("productStoreId")); priceContext.put("productId", productId); priceContext.put("priceDate", effectiveDate); priceContext.put("partyId", facility.getString("ownerPartyId")); priceContext.put("facilityCategory", facility.getString("categoryTypeEnum")); if (productSubscriptionTypeId.equals("CARD")) { priceContext.put("productPriceTypeId", "CARD_PRICE"); } priceResult = PriceServices.calculateLMSProductPrice(delegator, dispatcher, priceContext); if (ServiceUtil.isError(priceResult)) { Debug.logWarning("There was an error while calculating the price: " + ServiceUtil.getErrorMessage(priceResult), module); request.setAttribute("_ERROR_MESSAGE_", "There was an error while calculating the price: " + ServiceUtil.getErrorMessage(priceResult)); TransactionUtil.rollback(); return "error"; } } catch (Exception exc) { Debug.logWarning("Error adding product with id " + productId + " to the cart: " + exc.getMessage(), module); request.setAttribute("_ERROR_MESSAGE_", "Error adding product with id " + productId + " to the cart: " + exc.getMessage()); TransactionUtil.rollback(); return "error"; } //GenericValue userLogin = (GenericValue) context.get("userLogin"); GenericValue newOrderItemMap = delegator.makeValue("OrderItem"); newOrderItemMap.put("orderId", orderId); newOrderItemMap.put("orderItemTypeId", "PRODUCT_ORDER_ITEM"); newOrderItemMap.put("productId", productId); newOrderItemMap.put("quantity", quantity); newOrderItemMap.put("unitPrice", (BigDecimal)priceResult.get("price")); newOrderItemMap.put("statusId", "ITEM_CREATED"); newOrderItemMap.put("isPromo", "N"); newOrderItemMap.put("isModifiedPrice", "N"); newOrderItemMap.put("changeByUserLoginId", userLogin.get("userLoginId")); newOrderItemMap.put("changeDatetime", UtilDateTime.nowTimestamp()); try { delegator.setNextSubSeqId(newOrderItemMap, "orderItemSeqId", 5, 1); delegator.create(newOrderItemMap); } catch (Exception e) { request.setAttribute("_ERROR_MESSAGE_", "Error adding item " + productId + " to the cart: " + e.getMessage()); TransactionUtil.rollback(); return e.getMessage(); } }else{ conditionList.clear(); condition.reset(); conditionList = UtilMisc.toList(EntityCondition.makeCondition("invoiceId", EntityOperator.EQUALS, (String)orderInfo.getString("invoiceId"))); conditionList.add(EntityCondition.makeCondition("productId", EntityOperator.EQUALS, productId)); condition = EntityCondition.makeCondition(conditionList, EntityOperator.AND); invoiceItemList = delegator.findList("InvoiceItem", condition, null, null, null, false); orderItem = EntityUtil.getFirst(orderItemList); orderItem.put("quantity", quantity); orderItem.put("changeByUserLoginId", userLogin.get("userLoginId")); orderItem.put("changeDatetime", UtilDateTime.nowTimestamp()); orderItemListToUpdate.add(orderItem); } }catch (GenericEntityException e) { // TODO: handle exception Debug.logError("unable to correct Truck sheet " + orderId + " due to " + e.getMessage(), module); } }//end row count for loop try{ delegator.storeAll(orderItemListToUpdate); //delegator.storeAll(invoiceItemListToUpdate); }catch (GenericEntityException e) { // TODO: handle exception request.setAttribute("_ERROR_MESSAGE_", "unable to correct Truck sheet" + orderId + " due to "); TransactionUtil.rollback(); return "error"; } try{ result = dispatcher.runSync("resetGrandTotal", UtilMisc.<String, Object>toMap("orderId", orderId, "userLogin", userLogin)); GenericValue orderDetail= delegator.findOne("OrderHeader", UtilMisc.toMap("orderId", orderId), false); if((orderDetail.getBigDecimal("grandTotal")).compareTo(BigDecimal.ZERO) == 0 && !newItemFlag){ result = dispatcher.runSync("massCancelOrders", UtilMisc.<String, Object>toMap("orderIdList", UtilMisc.toList(orderId),"userLogin", userLogin)); if (ServiceUtil.isError(result)) { request.setAttribute("_ERROR_MESSAGE_", "unable to correct Truck sheet" + orderId); TransactionUtil.rollback(); return "error"; } result = dispatcher.runSync("massChangeInvoiceStatus", UtilMisc.toMap("invoiceIds", UtilMisc.toList((String)orderInfo.getString("invoiceId")), "statusId","INVOICE_CANCELLED","userLogin", userLogin)); if (ServiceUtil.isError(result)) { request.setAttribute("_ERROR_MESSAGE_", "unable to correct Truck sheet" + orderId); TransactionUtil.rollback(); return "error"; } // if the order grandTotal Zero then return from here no need to create invoice with zero amount return "success"; } // lets remove payment applications and cancel the earlier invoice and creating new invoice Map<String, Object> setInvoiceStatusResult = dispatcher.runSync("setInvoiceStatus", UtilMisc.<String, Object>toMap("invoiceId", (String)orderInfo.getString("invoiceId"), "statusId", "INVOICE_CANCELLED", "userLogin", userLogin)); conditionList.clear(); conditionList.add(EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, "ITEM_CREATED")); conditionList.add(EntityCondition.makeCondition("orderId", EntityOperator.EQUALS,orderId)); EntityCondition condition = EntityCondition.makeCondition(conditionList, EntityOperator.AND); //Approveing new order items which are created earlier Map<String, Object> resp = dispatcher.runSync("changeOrderItemStatus", UtilMisc.<String, Object>toMap("orderId", orderId, "statusId", "ITEM_APPROVED", "userLogin", userLogin)); if (ServiceUtil.isError(resp)) { request.setAttribute("_ERROR_MESSAGE_", "unable to correct Truck sheet" + orderId + " due to "); TransactionUtil.rollback(); return "error"; } List billItems = delegator.findList("OrderItemBilling", EntityCondition.makeCondition("orderId" , EntityOperator.EQUALS , orderId), null, null, null, false); delegator.removeAll(billItems); Map<String, Object> orderContext = UtilMisc.<String, Object>toMap("orderId", (String)orderId, "userLogin", userLogin); Map<String, Object> invoiceResult = dispatcher.runSync("createInvoiceForOrderAllItems", orderContext); // apply invoice if any adavance payments from this party if(!productSubscriptionTypeId.equals("CARD")){ try{ Map<String, Object> resultPaymentApp = dispatcher.runSync("settleInvoiceAndPayments", UtilMisc.<String, Object>toMap("invoiceId", (String)invoiceResult.get("invoiceId"),"userLogin", userLogin)); if (ServiceUtil.isError(resultPaymentApp)) { TransactionUtil.rollback(); Debug.logWarning("There was an error while adjusting advance payment" + ServiceUtil.getErrorMessage(resultPaymentApp), module); request.setAttribute("_ERROR_MESSAGE_","There was an error while adjusting advance payment " + ServiceUtil.getErrorMessage(resultPaymentApp)); return "error"; } }catch (GenericServiceException e) { Debug.logError(e, module); TransactionUtil.rollback(); } } }catch (Exception e) { // TODO: handle exception Debug.logError("unable to correct Truck sheet" + (String)orderInfo.getString("orderId") + " due to " + e.getMessage(), module); request.setAttribute("_ERROR_MESSAGE_", "unable to correct Truck sheet" + orderId + " due to " + e.getMessage()); TransactionUtil.rollback(); return e.getMessage(); } } catch (GenericEntityException e) { try { // only rollback the transaction if we started one... TransactionUtil.rollback(beganTransaction, "Error saving gate pass", e); } catch (GenericEntityException e2) { Debug.logError(e2, "Could not rollback transaction: " + e2.toString(), module); } Debug.logError(e, "An entity engine error occurred while saving gate pass order", module); } finally { // only commit the transaction if we started one... this will throw an exception if it fails try { TransactionUtil.commit(beganTransaction); } catch (GenericEntityException e) { Debug.logError(e, "Could not commit transaction for entity engine error occurred while saving gate pass order", module); } } return "success"; } */ public static String nameTrim(String str, int n) { int strlen = str.length(); if (strlen < n) { return StringUtils.rightPad(str, n); } if (strlen > n) { return str.substring(0, n); } return str; } public static Map<String, Object> adjustRoundingDiffForOrder(DispatchContext dctx, Map<String, ? extends Object> context) { Delegator delegator = dctx.getDelegator(); LocalDispatcher dispatcher = dctx.getDispatcher(); GenericValue userLogin = (GenericValue) context.get("userLogin"); String orderId = (String) context.get("orderId"); Locale locale = (Locale) context.get("locale"); Map result = ServiceUtil.returnSuccess(); BigDecimal roundingAmount = BigDecimal.ZERO; try { GenericValue orderHeader = delegator.findOne("OrderHeader", UtilMisc.toMap("orderId", orderId), false); OrderReadHelper orh = new OrderReadHelper(delegator, orderId); BigDecimal orderAmount = orh.getOrderGrandTotal(); roundingAmount = (orderAmount.setScale(0, orderRounding)).subtract(orderAmount); // add rounding adjustment "ROUNDING_ADJUSTMENT" String orderAdjustmentTypeId = "ROUNDING_ADJUSTMENT"; Map createOrderAdjustmentCtx = UtilMisc.toMap("userLogin", userLogin); createOrderAdjustmentCtx.put("orderId", orderId); createOrderAdjustmentCtx.put("orderAdjustmentTypeId", orderAdjustmentTypeId); createOrderAdjustmentCtx.put("amount", roundingAmount); result = dispatcher.runSync("createOrderAdjustment", createOrderAdjustmentCtx); if (ServiceUtil.isError(result)) { Debug.logWarning( "There was an error while creating the adjustment: " + ServiceUtil.getErrorMessage(result), module); return ServiceUtil.returnError( "There was an error while creating the adjustment: " + ServiceUtil.getErrorMessage(result)); } } catch (Exception e) { Debug.logError(e, module); return ServiceUtil.returnError(e.toString()); } result = ServiceUtil.returnSuccess("Successfully added the adjustment!!"); result.put("orderId", orderId); return result; } //calculate purchase order term values public static BigDecimal calculatePurchaseOrderTermValue(DispatchContext ctx, Map<String, ? extends Object> context) { BigDecimal termAmount = BigDecimal.ZERO; BigDecimal basicAmount = (BigDecimal) context.get("basicAmount"); BigDecimal poValue = (BigDecimal) context.get("poValue"); BigDecimal exciseDuty = (BigDecimal) context.get("exciseDuty"); String termTypeId = (String) context.get("termTypeId"); String uomId = (String) context.get("uomId"); BigDecimal termValue = (BigDecimal) context.get("termValue"); if (UtilValidate.isEmpty(termTypeId)) { return termAmount; } //this to handle non derived terms termAmount = termValue; //Discount Before ED if (termTypeId.equals("COGS_DISC")) { if (UtilValidate.isNotEmpty(uomId) && uomId.equals("PERCENT")) { termAmount = ((basicAmount.add(exciseDuty)).multiply(termValue)).divide(new BigDecimal("100"), taxRounding); termAmount = termAmount.negate(); } else { termAmount = termValue.negate(); } } //Discount After Tax if (termTypeId.equals("COGS_DISC_ATR")) { if (UtilValidate.isNotEmpty(uomId) && uomId.equals("PERCENT")) { Debug.log("poValue========" + poValue); termAmount = (poValue.multiply(termValue)).divide(new BigDecimal("100"), taxRounding); termAmount = termAmount.negate(); } else { termAmount = termValue.negate(); } } //Packing And Forwarding Charges Before Tax if (termTypeId.equals("COGS_PCK_FWD")) { if (UtilValidate.isNotEmpty(uomId) && uomId.equals("PERCENT")) { termAmount = ((basicAmount.add(exciseDuty)).multiply(termValue)).divide(new BigDecimal("100"), taxRounding); } else { termAmount = termValue; } } //Packing And Forwarding Charges After Tax if (termTypeId.equals("COGS_PCK_FWD_ATR")) { if (UtilValidate.isNotEmpty(uomId) && uomId.equals("PERCENT")) { Debug.log("poValue========" + poValue); termAmount = (poValue.multiply(termValue)).divide(new BigDecimal("100"), taxRounding); } else { termAmount = termValue; } } if (termTypeId.equals("COGS_INSURANCE")) { if (UtilValidate.isNotEmpty(uomId) && uomId.equals("PERCENT")) { termAmount = ((basicAmount.add(exciseDuty)).multiply(termValue)).divide(new BigDecimal("100"), taxRounding); } else { termAmount = termValue; } } return termAmount; } /** Service for editing a old order. Here we are assuming only orderItems and orderAdjustment only change for old orderId */ public static Map<String, Object> editOrder(DispatchContext ctx, Map<String, ? extends Object> context) { Delegator delegator = ctx.getDelegator(); LocalDispatcher dispatcher = ctx.getDispatcher(); Security security = ctx.getSecurity(); List<GenericValue> toBeStored = new LinkedList<GenericValue>(); Locale locale = (Locale) context.get("locale"); Map<String, Object> successResult = ServiceUtil.returnSuccess(); GenericValue userLogin = (GenericValue) context.get("userLogin"); // get the order type String orderTypeId = (String) context.get("orderTypeId"); String partyId = (String) context.get("partyId"); String billFromVendorPartyId = (String) context.get("billFromVendorPartyId"); // check security permissions for order: // SALES ORDERS - if userLogin has ORDERMGR_SALES_CREATE or ORDERMGR_CREATE permission, or if it is same party as the partyId, or // if it is an AGENT (sales rep) creating an order for his customer // PURCHASE ORDERS - if there is a PURCHASE_ORDER permission Map<String, Object> resultSecurity = new HashMap<String, Object>(); boolean hasPermission = OrderServices.hasPermission(orderTypeId, partyId, userLogin, "CREATE", security); // final check - will pass if userLogin's partyId = partyId for order or if userLogin has ORDERMGR_CREATE permission // jacopoc: what is the meaning of this code block? FIXME if (!hasPermission) { partyId = ServiceUtil.getPartyIdCheckSecurity(userLogin, security, context, resultSecurity, "ORDERMGR", "_CREATE"); if (resultSecurity.size() > 0) { return resultSecurity; } } // get the product store for the order, but it is required only for sales orders String productStoreId = (String) context.get("productStoreId"); GenericValue productStore = null; if ((orderTypeId.equals("SALES_ORDER")) && (UtilValidate.isNotEmpty(productStoreId))) { try { productStore = delegator.findByPrimaryKeyCache("ProductStore", UtilMisc.toMap("productStoreId", productStoreId)); } catch (GenericEntityException e) { return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderErrorCouldNotFindProductStoreWithID", UtilMisc.toMap("productStoreId", productStoreId), locale) + e.toString()); } } // figure out if the order is immediately fulfilled based on product store settings boolean isImmediatelyFulfilled = false; if (productStore != null) { isImmediatelyFulfilled = "Y".equals(productStore.getString("isImmediatelyFulfilled")); } successResult.put("orderTypeId", orderTypeId); // lookup the order type entity GenericValue orderType = null; try { orderType = delegator.findByPrimaryKeyCache("OrderType", UtilMisc.toMap("orderTypeId", orderTypeId)); } catch (GenericEntityException e) { return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderErrorOrderTypeLookupFailed", locale) + e.toString()); } // make sure we have a valid order type if (orderType == null) { return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderErrorInvalidOrderTypeWithID", UtilMisc.toMap("orderTypeId", orderTypeId), locale)); } // check to make sure we have something to order List<GenericValue> orderItems = UtilGenerics.checkList(context.get("orderItems")); if (orderItems.size() < 1) { return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "items.none", locale)); } // all this marketing pkg auto stuff is deprecated in favor of MARKETING_PKG_AUTO productTypeId and a BOM of MANUF_COMPONENT assocs // these need to be retrieved now because they might be needed for exploding MARKETING_PKG_AUTO List<GenericValue> orderAdjustments = UtilGenerics.checkList(context.get("orderAdjustments")); List<GenericValue> orderItemShipGroupInfo = UtilGenerics.checkList(context.get("orderItemShipGroupInfo")); List<GenericValue> orderItemPriceInfo = UtilGenerics.checkList(context.get("orderItemPriceInfos")); // check inventory and other things for each item List<String> errorMessages = FastList.newInstance(); Map<String, BigDecimal> normalizedItemQuantities = FastMap.newInstance(); Map<String, String> normalizedItemNames = FastMap.newInstance(); Map<String, GenericValue> itemValuesBySeqId = FastMap.newInstance(); Iterator<GenericValue> itemIter = orderItems.iterator(); Timestamp nowTimestamp = UtilDateTime.nowTimestamp(); // // need to run through the items combining any cases where multiple lines refer to the // same product so the inventory check will work correctly // also count quantities ordered while going through the loop while (itemIter.hasNext()) { GenericValue orderItem = itemIter.next(); // start by putting it in the itemValuesById Map itemValuesBySeqId.put(orderItem.getString("orderItemSeqId"), orderItem); String currentProductId = orderItem.getString("productId"); if (currentProductId != null) { // only normalize items with a product associated (ignore non-product items) if (normalizedItemQuantities.get(currentProductId) == null) { normalizedItemQuantities.put(currentProductId, orderItem.getBigDecimal("quantity")); normalizedItemNames.put(currentProductId, orderItem.getString("itemDescription")); } else { BigDecimal currentQuantity = normalizedItemQuantities.get(currentProductId); normalizedItemQuantities.put(currentProductId, currentQuantity.add(orderItem.getBigDecimal("quantity"))); } /* try { // count product ordered quantities // run this synchronously so it will run in the same transaction dispatcher.runSync("countProductQuantityOrdered", UtilMisc.<String, Object>toMap("productId", currentProductId, "quantity", orderItem.getBigDecimal("quantity"), "userLogin", userLogin)); } catch (GenericServiceException e1) { Debug.logError(e1, "Error calling countProductQuantityOrdered service", module); return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderErrorCallingCountProductQuantityOrderedService",locale) + e1.toString()); }*/ } } if (!"PURCHASE_ORDER".equals(orderTypeId) && productStoreId == null) { return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderErrorTheProductStoreIdCanOnlyBeNullForPurchaseOrders", locale)); } Timestamp orderDate = (Timestamp) context.get("orderDate"); Iterator<String> normalizedIter = normalizedItemQuantities.keySet().iterator(); while (normalizedIter.hasNext()) { // lookup the product entity for each normalized item; error on products not found String currentProductId = normalizedIter.next(); BigDecimal currentQuantity = normalizedItemQuantities.get(currentProductId); String itemName = normalizedItemNames.get(currentProductId); GenericValue product = null; try { product = delegator.findByPrimaryKeyCache("Product", UtilMisc.toMap("productId", currentProductId)); } catch (GenericEntityException e) { String errMsg = UtilProperties.getMessage(resource_error, "product.not_found", new Object[] { currentProductId }, locale); Debug.logError(e, errMsg, module); errorMessages.add(errMsg); continue; } if (product == null) { String errMsg = UtilProperties.getMessage(resource_error, "product.not_found", new Object[] { currentProductId }, locale); Debug.logError(errMsg, module); errorMessages.add(errMsg); continue; } if ("SALES_ORDER".equals(orderTypeId)) { // check to see if introductionDate hasn't passed yet if (product.get("introductionDate") != null && nowTimestamp.before(product.getTimestamp("introductionDate"))) { String excMsg = UtilProperties.getMessage(resource_error, "product.not_yet_for_sale", new Object[] { getProductName(product, itemName), product.getString("productId") }, locale); Debug.logWarning(excMsg, module); errorMessages.add(excMsg); continue; } } if ("SALES_ORDER".equals(orderTypeId)) { boolean salesDiscontinuationFlag = false; // When past orders are imported, they should be imported even if sales discontinuation date is in the past but if the order date was before it if (orderDate != null && product.get("salesDiscontinuationDate") != null) { salesDiscontinuationFlag = orderDate.after(product.getTimestamp("salesDiscontinuationDate")) && nowTimestamp.after(product.getTimestamp("salesDiscontinuationDate")); } else if (product.get("salesDiscontinuationDate") != null) { salesDiscontinuationFlag = nowTimestamp.after(product.getTimestamp("salesDiscontinuationDate")); } // check to see if salesDiscontinuationDate has passed if (salesDiscontinuationFlag) { String excMsg = UtilProperties.getMessage(resource_error, "product.no_longer_for_sale", new Object[] { getProductName(product, itemName), product.getString("productId") }, locale); Debug.logWarning(excMsg, module); errorMessages.add(excMsg); continue; } } } // the inital status for ALL order types String initialStatus = "ORDER_CREATED"; successResult.put("statusId", initialStatus); // create the order object String orderId = (String) context.get("orderId"); String orgPartyId = null; if (productStore != null) { orgPartyId = productStore.getString("payToPartyId"); } else if (billFromVendorPartyId != null) { orgPartyId = billFromVendorPartyId; } if (UtilValidate.isNotEmpty(orgPartyId)) { Map<String, Object> getNextOrderIdContext = FastMap.newInstance(); getNextOrderIdContext.putAll(context); getNextOrderIdContext.put("partyId", orgPartyId); getNextOrderIdContext.put("userLogin", userLogin); if ((orderTypeId.equals("SALES_ORDER")) || (productStoreId != null)) { getNextOrderIdContext.put("productStoreId", productStoreId); } if (UtilValidate.isEmpty(orderId)) { try { getNextOrderIdContext = ctx.makeValidContext("getNextOrderId", "IN", getNextOrderIdContext); Map<String, Object> getNextOrderIdResult = dispatcher.runSync("getNextOrderId", getNextOrderIdContext); if (ServiceUtil.isError(getNextOrderIdResult)) { String errMsg = UtilProperties.getMessage(resource_error, "OrderErrorGettingNextOrderIdWhileCreatingOrder", locale); return ServiceUtil.returnError(errMsg, null, null, getNextOrderIdResult); } orderId = (String) getNextOrderIdResult.get("orderId"); } catch (GenericServiceException e) { String errMsg = UtilProperties.getMessage(resource_error, "OrderCaughtGenericServiceExceptionWhileGettingOrderId", locale); Debug.logError(e, errMsg, module); return ServiceUtil.returnError(errMsg); } } } if (UtilValidate.isEmpty(orderId)) { // for purchase orders or when other orderId generation fails, a product store id should not be required to make an order orderId = delegator.getNextSeqId("OrderHeader"); } String billingAccountId = (String) context.get("billingAccountId"); if (orderDate == null) { orderDate = nowTimestamp; } Map<String, Object> orderHeaderMap = UtilMisc.<String, Object>toMap("orderId", orderId, "orderTypeId", orderTypeId, "orderDate", orderDate, "entryDate", nowTimestamp, "statusId", initialStatus, "billingAccountId", billingAccountId); orderHeaderMap.put("orderName", context.get("orderName")); orderHeaderMap.put("estimatedDeliveryDate", context.get("estimatedDeliveryDate")); orderHeaderMap.put("isEnableAcctg", context.get("isEnableAcctg")); if (isImmediatelyFulfilled) { // also flag this order as needing inventory issuance so that when it is set to complete it will be issued immediately (needsInventoryIssuance = Y) orderHeaderMap.put("needsInventoryIssuance", "Y"); } GenericValue orderHeader = delegator.makeValue("OrderHeader", orderHeaderMap); //if Already there get that order only if (UtilValidate.isNotEmpty(orderId)) { try { orderHeader = delegator.findOne("OrderHeader", UtilMisc.toMap("orderId", orderId), false); } catch (GenericEntityException e) { Debug.logError(e, "Problem while finding order", module); return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderErrorCouldNotCreateOrderWriteError", locale) + e.getMessage() + ")."); } } if (context.get("grandTotal") != null) { orderHeader.set("grandTotal", context.get("grandTotal")); } if (UtilValidate.isNotEmpty(context.get("visitId"))) { orderHeader.set("visitId", context.get("visitId")); } if (userLogin != null && userLogin.get("userLoginId") != null) { orderHeader.set("createdBy", userLogin.getString("userLoginId")); } if (UtilValidate.isNotEmpty(context.get("orderName"))) { orderHeader.set("orderName", context.get("orderName")); } // first try to create the OrderHeader; if this does not fail, continue. try { delegator.createOrStore(orderHeader); } catch (GenericEntityException e) { Debug.logError(e, "Cannot create OrderHeader entity; problems with insert", module); return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderOrderCreationFailedPleaseNotifyCustomerService", locale)); } // before processing orderItems process orderItemGroups so that they'll be in place for the foreign keys and what not List<GenericValue> orderItemGroups = UtilGenerics.checkList(context.get("orderItemGroups")); if (UtilValidate.isNotEmpty(orderItemGroups)) { Iterator<GenericValue> orderItemGroupIter = orderItemGroups.iterator(); while (orderItemGroupIter.hasNext()) { GenericValue orderItemGroup = orderItemGroupIter.next(); orderItemGroup.set("orderId", orderId); toBeStored.add(orderItemGroup); } } // set the order items Iterator<GenericValue> oi = orderItems.iterator(); while (oi.hasNext()) { GenericValue orderItem = oi.next(); orderItem.set("orderId", orderId); toBeStored.add(orderItem); // create the item status record /* String itemStatusId = delegator.getNextSeqId("OrderStatus"); GenericValue itemStatus = delegator.makeValue("OrderStatus", UtilMisc.toMap("orderStatusId", itemStatusId)); itemStatus.put("statusId", orderItem.get("statusId")); itemStatus.put("orderId", orderId); itemStatus.put("orderItemSeqId", orderItem.get("orderItemSeqId")); itemStatus.put("statusDatetime", nowTimestamp); itemStatus.set("statusUserLogin", userLogin.getString("userLoginId")); toBeStored.add(itemStatus);*/ } /* // set the order attributes List<GenericValue> orderAttributes = UtilGenerics.checkList(context.get("orderAttributes")); if (UtilValidate.isNotEmpty(orderAttributes)) { Iterator<GenericValue> oattr = orderAttributes.iterator(); while (oattr.hasNext()) { GenericValue oatt = oattr.next(); oatt.set("orderId", orderId); toBeStored.add(oatt); } }*/ // set the order item attributes /* List<GenericValue> orderItemAttributes = UtilGenerics.checkList(context.get("orderItemAttributes")); if (UtilValidate.isNotEmpty(orderItemAttributes)) { Iterator<GenericValue> oiattr = orderItemAttributes.iterator(); while (oiattr.hasNext()) { GenericValue oiatt = oiattr.next(); oiatt.set("orderId", orderId); toBeStored.add(oiatt); } }*/ //Here it is edit order always remove old adjustments try { List<GenericValue> oldOrderAdjustments = delegator.findList("OrderAdjustment", EntityCondition.makeCondition("orderId", EntityOperator.EQUALS, orderId), null, null, null, false); //Debug.log("==oldOrderAdjustments===Before=Deletion========="+oldOrderAdjustments); delegator.removeAll(oldOrderAdjustments); } catch (GenericEntityException e) { Debug.logError(e, "Problem with order storage or reservations", module); return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderErrorCouldNotCreateOrderWriteError", locale) + e.getMessage() + ")."); } // set the orderId on all adjustments; this list will include order and // item adjustments... if (UtilValidate.isNotEmpty(orderAdjustments)) { Iterator<GenericValue> iter = orderAdjustments.iterator(); while (iter.hasNext()) { GenericValue orderAdjustment = iter.next(); try { orderAdjustment.set("orderAdjustmentId", delegator.getNextSeqId("OrderAdjustment")); } catch (IllegalArgumentException e) { return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderErrorCouldNotGetNextSequenceIdForOrderAdjustmentCannotCreateOrder", locale)); } orderAdjustment.set("orderId", orderId); orderAdjustment.set("createdDate", UtilDateTime.nowTimestamp()); orderAdjustment.set("createdByUserLogin", userLogin.getString("userLoginId")); if (UtilValidate.isEmpty(orderAdjustment.get("orderItemSeqId"))) { orderAdjustment.set("orderItemSeqId", DataModelConstants.SEQ_ID_NA); } if (UtilValidate.isEmpty(orderAdjustment.get("shipGroupSeqId"))) { orderAdjustment.set("shipGroupSeqId", DataModelConstants.SEQ_ID_NA); } toBeStored.add(orderAdjustment); } } // set the order item ship groups // commented when PurchaseOrder not created without shipment List<String> dropShipGroupIds = FastList.newInstance(); // this list will contain the ids of all the ship groups for drop shipments (no reservations) if (UtilValidate.isNotEmpty(orderItemShipGroupInfo)) { Iterator<GenericValue> osiInfos = orderItemShipGroupInfo.iterator(); while (osiInfos.hasNext()) { GenericValue valueObj = osiInfos.next(); valueObj.set("orderId", orderId); /* if ("OrderItemShipGroup".equals(valueObj.getEntityName())) { // ship group if (valueObj.get("carrierRoleTypeId") == null) { valueObj.set("carrierRoleTypeId", "CARRIER"); } if (!UtilValidate.isEmpty(valueObj.getString("supplierPartyId"))) { dropShipGroupIds.add(valueObj.getString("shipGroupSeqId")); } toBeStored.add(valueObj); // from out side of if we bring here } else */ if ("OrderAdjustment".equals(valueObj.getEntityName())) { // shipping / tax adjustment(s) if (UtilValidate.isEmpty(valueObj.get("orderItemSeqId"))) { valueObj.set("orderItemSeqId", DataModelConstants.SEQ_ID_NA); } valueObj.set("orderAdjustmentId", delegator.getNextSeqId("OrderAdjustment")); valueObj.set("createdDate", UtilDateTime.nowTimestamp()); valueObj.set("createdByUserLogin", userLogin.getString("userLoginId")); toBeStored.add(valueObj); } } } // set the item price info; NOTE: this must be after the orderItems are stored for referential integrity if (UtilValidate.isNotEmpty(orderItemPriceInfo)) { Iterator<GenericValue> oipii = orderItemPriceInfo.iterator(); while (oipii.hasNext()) { GenericValue oipi = oipii.next(); try { oipi.set("orderItemPriceInfoId", delegator.getNextSeqId("OrderItemPriceInfo")); } catch (IllegalArgumentException e) { return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderErrorCouldNotGetNextSequenceIdForOrderItemPriceInfoCannotCreateOrder", locale)); } oipi.set("orderId", orderId); toBeStored.add(oipi); } } // store the orderProductPromoUseInfos List<GenericValue> orderProductPromoUses = UtilGenerics.checkList(context.get("orderProductPromoUses")); if (UtilValidate.isNotEmpty(orderProductPromoUses)) { Iterator<GenericValue> orderProductPromoUseIter = orderProductPromoUses.iterator(); while (orderProductPromoUseIter.hasNext()) { GenericValue productPromoUse = orderProductPromoUseIter.next(); productPromoUse.set("orderId", orderId); toBeStored.add(productPromoUse); } } // store the orderProductPromoCodes Set<String> orderProductPromoCodes = UtilGenerics.checkSet(context.get("orderProductPromoCodes")); if (UtilValidate.isNotEmpty(orderProductPromoCodes)) { GenericValue orderProductPromoCode = delegator.makeValue("OrderProductPromoCode"); Iterator<String> orderProductPromoCodeIter = orderProductPromoCodes.iterator(); while (orderProductPromoCodeIter.hasNext()) { orderProductPromoCode.clear(); orderProductPromoCode.set("orderId", orderId); orderProductPromoCode.set("productPromoCodeId", orderProductPromoCodeIter.next()); toBeStored.add(orderProductPromoCode); } } try { // store line items, etc so that they will be there for the foreign key checks delegator.storeAll(toBeStored); successResult.put("orderId", orderId); } catch (GenericEntityException e) { Debug.logError(e, "Problem with order storage or reservations", module); return ServiceUtil.returnError( UtilProperties.getMessage(resource_error, "OrderErrorCouldNotCreateOrderWriteError", locale) + e.getMessage() + ")."); } return successResult; } public static Map<String, Object> createCustPaymentFromPreference(DispatchContext dctx, Map<String, ? extends Object> context) { Delegator delegator = dctx.getDelegator(); LocalDispatcher dispatcher = dctx.getDispatcher(); GenericValue userLogin = (GenericValue) context.get("userLogin"); String orderPaymentPreferenceId = (String) context.get("orderPaymentPreferenceId"); String paymentRefNum = (String) context.get("paymentRefNum"); String paymentFromId = (String) context.get("paymentFromId"); String comments = (String) context.get("comments"); String amountStr = (String) context.get("amount"); String issuingAuthority = (String) context.get("issuingAuthority"); String inFavourOf = (String) context.get("inFavourOf"); String purposeTypeId = (String) context.get("purposeTypeId"); Timestamp eventDate = (Timestamp) context.get("eventDate"); Timestamp instrumentDate = (Timestamp) context.get("instrumentDate"); Locale locale = (Locale) context.get("locale"); BigDecimal amount = new BigDecimal(amountStr); if (UtilValidate.isEmpty(eventDate)) { eventDate = UtilDateTime.nowTimestamp(); } if (UtilValidate.isEmpty(instrumentDate)) { instrumentDate = UtilDateTime.nowTimestamp(); } try { // get the order payment preference GenericValue orderPaymentPreference = delegator.findByPrimaryKey("OrderPaymentPreference", UtilMisc.toMap("orderPaymentPreferenceId", orderPaymentPreferenceId)); if (orderPaymentPreference == null) { return ServiceUtil .returnError(UtilProperties.getMessage(resource, "OrderOrderPaymentCannotBeCreated", UtilMisc.toMap("orderPaymentPreferenceId", "orderPaymentPreferenceId"), locale)); } // get the order header GenericValue orderHeader = orderPaymentPreference.getRelatedOne("OrderHeader"); Timestamp orderDate = orderHeader.getTimestamp("orderDate"); if (orderHeader == null) { return ServiceUtil.returnError(UtilProperties.getMessage(resource, "OrderOrderPaymentCannotBeCreatedWithRelatedOrderHeader", locale)); } // get the store for the order. It will be used to set the currency GenericValue productStore = orderHeader.getRelatedOne("ProductStore"); if (productStore == null) { return ServiceUtil.returnError(UtilProperties.getMessage(resource, "OrderOrderPaymentCannotBeCreatedWithRelatedProductStore", locale)); } // get the partyId billed to if (paymentFromId == null) { OrderReadHelper orh = new OrderReadHelper(orderHeader); GenericValue billToParty = orh.getBillToParty(); if (billToParty != null) { paymentFromId = billToParty.getString("partyId"); } else { paymentFromId = "_NA_"; } } // set the payToPartyId String payToPartyId = productStore.getString("payToPartyId"); if (payToPartyId == null) { return ServiceUtil.returnError(UtilProperties.getMessage(resource, "OrderOrderPaymentCannotBeCreatedPayToPartyIdNotSet", locale)); } String roFroBranch = ""; if (payToPartyId != null) { List conditionList = FastList.newInstance(); conditionList.add(EntityCondition.makeCondition("partyIdTo", EntityOperator.EQUALS, payToPartyId)); conditionList.add( EntityCondition.makeCondition("roleTypeIdTo", EntityOperator.EQUALS, "ORGANIZATION_UNIT")); conditionList.add(EntityCondition.makeCondition("roleTypeIdFrom", EntityOperator.EQUALS, "PARENT_ORGANIZATION")); conditionList.add(EntityCondition.makeCondition("fromDate", EntityOperator.LESS_THAN_EQUAL_TO, UtilDateTime.getDayEnd(orderDate))); conditionList.add(EntityCondition.makeCondition( EntityCondition.makeCondition("thruDate", EntityOperator.EQUALS, null), EntityOperator.OR, EntityCondition.makeCondition("thruDate", EntityOperator.GREATER_THAN_EQUAL_TO, UtilDateTime.getDayStart(orderDate)))); EntityCondition condition = EntityCondition.makeCondition(conditionList, EntityOperator.AND); try { List<GenericValue> orgsListS = delegator.findList("PartyRelationship", condition, null, UtilMisc.toList("partyIdFrom"), null, false); GenericValue orgsList = EntityUtil.getFirst(orgsListS); roFroBranch = orgsList.getString("partyIdFrom"); } catch (GenericEntityException e) { // TODO: handle exception Debug.logError(e, module); } } // create the payment Map<String, Object> paymentParams = new HashMap<String, Object>(); BigDecimal maxAmount = orderPaymentPreference.getBigDecimal("maxAmount"); //if (maxAmount > 0.0) { paymentParams.put("paymentPurposeType", purposeTypeId); paymentParams.put("paymentTypeId", "INDENTADV_PAYIN"); paymentParams.put("paymentMethodTypeId", orderPaymentPreference.getString("paymentMethodTypeId")); paymentParams.put("paymentPreferenceId", orderPaymentPreference.getString("orderPaymentPreferenceId")); paymentParams.put("amount", amount); paymentParams.put("statusId", "PMNT_RECEIVED"); paymentParams.put("paymentDate", eventDate); paymentParams.put("instrumentDate", instrumentDate); paymentParams.put("partyIdFrom", paymentFromId); paymentParams.put("currencyUomId", productStore.getString("defaultCurrencyUomId")); paymentParams.put("partyIdTo", roFroBranch); /*} else { paymentParams.put("paymentTypeId", "CUSTOMER_REFUND"); // JLR 17/7/4 from a suggestion of Si cf. https://issues.apache.org/jira/browse/OFBIZ-828#action_12483045 paymentParams.put("paymentMethodTypeId", orderPaymentPreference.getString("paymentMethodTypeId")); // JLR 20/7/4 Finally reverted for now, I prefer to see an amount in payment, even negative paymentParams.put("paymentPreferenceId", orderPaymentPreference.getString("orderPaymentPreferenceId")); paymentParams.put("amount", Double.valueOf(Math.abs(maxAmount))); paymentParams.put("statusId", "PMNT_RECEIVED"); paymentParams.put("effectiveDate", UtilDateTime.nowTimestamp()); paymentParams.put("partyIdFrom", payToPartyId); paymentParams.put("currencyUomId", productStore.getString("defaultCurrencyUomId")); paymentParams.put("partyIdTo", billToParty.getString("partyId")); }*/ if (paymentRefNum != null) { paymentParams.put("paymentRefNum", paymentRefNum); } if (issuingAuthority != null) { paymentParams.put("issuingAuthority", issuingAuthority); } if (comments != null) { paymentParams.put("comments", comments); } paymentParams.put("userLogin", userLogin); Map<String, Object> paymentDetailsMap = dispatcher.runSync("createPayment", paymentParams); String paymentId = ""; if (UtilValidate.isNotEmpty(paymentDetailsMap)) { paymentId = (String) paymentDetailsMap.get("paymentId"); GenericValue paymentAttribute = delegator.makeValue("PaymentAttribute", UtilMisc.toMap("paymentId", paymentId, "attrName", "INFAVOUR_OF")); paymentAttribute.put("attrValue", inFavourOf); paymentAttribute.create(); } Map<String, Object> result = new HashMap<String, Object>(); Map<String, Object> createRoleContext = FastMap.newInstance(); if (UtilValidate.isNotEmpty(payToPartyId)) { createRoleContext.put("userLogin", userLogin); createRoleContext.put("paymentId", paymentId); createRoleContext.put("partyId", payToPartyId); //Debug.log("payment Party--------"+payToPartyId); createRoleContext.put("roleTypeId", "BRANCH_ROLE"); Map<String, Object> createPaymentRoleResult = dispatcher.runSync("createPaymentRole", createRoleContext); if (ServiceUtil.isError(createPaymentRoleResult)) { return ServiceUtil.returnError("Problem in creation of Accounting role", null, null, createPaymentRoleResult); } } result.put("paymentId", paymentId); return result; } catch (GenericEntityException ex) { Debug.logError(ex, "Unable to create payment using payment preference.", module); return (ServiceUtil.returnError(ex.getMessage())); } catch (GenericServiceException ex) { Debug.logError(ex, "Unable to create payment using payment preference.", module); return (ServiceUtil.returnError(ex.getMessage())); } } }