KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ofbiz > order > order > OrderServices


1 /*
2  * $Id: OrderServices.java 7189 2006-04-04 18:57:49Z sichen $
3  *
4  * Copyright (c) 2001-2005 The Open For Business Project - www.ofbiz.org
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
21  * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
22  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */

24 package org.ofbiz.order.order;
25
26 import java.math.BigDecimal JavaDoc;
27 import java.sql.Timestamp JavaDoc;
28 import java.text.NumberFormat JavaDoc;
29 import java.text.ParseException JavaDoc;
30 import java.util.*;
31
32 import javolution.util.FastMap;
33
34 import org.ofbiz.base.util.*;
35 import org.ofbiz.base.util.collections.ResourceBundleMapWrapper;
36 import org.ofbiz.common.DataModelConstants;
37 import org.ofbiz.entity.GenericDelegator;
38 import org.ofbiz.entity.GenericEntityException;
39 import org.ofbiz.entity.GenericValue;
40 import org.ofbiz.entity.condition.EntityCondition;
41 import org.ofbiz.entity.condition.EntityConditionList;
42 import org.ofbiz.entity.condition.EntityExpr;
43 import org.ofbiz.entity.condition.EntityOperator;
44 import org.ofbiz.entity.util.EntityListIterator;
45 import org.ofbiz.entity.util.EntityUtil;
46 import org.ofbiz.order.shoppingcart.CartItemModifyException;
47 import org.ofbiz.order.shoppingcart.CheckOutHelper;
48 import org.ofbiz.order.shoppingcart.ItemNotFoundException;
49 import org.ofbiz.order.shoppingcart.ShoppingCart;
50 import org.ofbiz.order.shoppingcart.ShoppingCartItem;
51 import org.ofbiz.order.shoppingcart.shipping.ShippingEvents;
52 import org.ofbiz.party.contact.ContactHelper;
53 import org.ofbiz.party.party.PartyWorker;
54 import org.ofbiz.product.catalog.CatalogWorker;
55 import org.ofbiz.product.product.ProductContentWrapper;
56 import org.ofbiz.product.product.ProductWorker;
57 import org.ofbiz.product.store.ProductStoreWorker;
58 import org.ofbiz.security.Security;
59 import org.ofbiz.service.DispatchContext;
60 import org.ofbiz.service.GenericServiceException;
61 import org.ofbiz.service.LocalDispatcher;
62 import org.ofbiz.service.ModelService;
63 import org.ofbiz.service.ServiceUtil;
64 import org.ofbiz.workflow.WfUtil;
65
66 /**
67  * Order Processing Services
68  *
69  * @author <a HREF="mailto:jaz@ofbiz.org">Andy Zeneski</a>
70  * @author <a HREF="mailto:cnelson@einnovation.com">Chris Nelson</a>
71  * @author <a HREF="mailto:jonesde@ofbiz.org">David E. Jones</a>
72  * @version $Rev: 7189 $
73  * @since 2.0
74  */

75
76 public class OrderServices {
77
78     public static final String JavaDoc module = OrderServices.class.getName();
79     public static final String JavaDoc resource = "OrderUiLabels";
80     public static final String JavaDoc resource_error = "OrderErrorUiLabels";
81
82     public static Map salesAttributeRoleMap = FastMap.newInstance();
83     public static Map purchaseAttributeRoleMap = FastMap.newInstance();
84     static {
85         salesAttributeRoleMap.put("placingCustomerPartyId", "PLACING_CUSTOMER");
86         salesAttributeRoleMap.put("billToCustomerPartyId", "BILL_TO_CUSTOMER");
87         salesAttributeRoleMap.put("billFromVendorPartyId", "BILL_FROM_VENDOR");
88         salesAttributeRoleMap.put("shipToCustomerPartyId", "SHIP_TO_CUSTOMER");
89         salesAttributeRoleMap.put("endUserCustomerPartyId", "END_USER_CUSTOMER");
90
91         purchaseAttributeRoleMap.put("billToCustomerPartyId", "BILL_TO_CUSTOMER");
92         purchaseAttributeRoleMap.put("billFromVendorPartyId", "BILL_FROM_VENDOR");
93         purchaseAttributeRoleMap.put("shipFromVendorPartyId", "SHIP_FROM_VENDOR");
94         purchaseAttributeRoleMap.put("supplierAgentPartyId", "SUPPLIER_AGENT");
95     }
96     public static final int taxDecimals = UtilNumber.getBigDecimalScale("salestax.calc.decimals");
97     public static final int taxRounding = UtilNumber.getBigDecimalRoundingMode("salestax.rounding");
98     public static final BigDecimal JavaDoc ZERO = (new BigDecimal JavaDoc("0")).setScale(taxDecimals, taxRounding);
99
100     /** Service for creating a new order */
101     public static Map createOrder(DispatchContext ctx, Map context) {
102         GenericDelegator delegator = ctx.getDelegator();
103         LocalDispatcher dispatcher = ctx.getDispatcher();
104         Security security = ctx.getSecurity();
105         List toBeStored = new LinkedList();
106         Locale locale = (Locale) context.get("locale");
107         Map successResult = ServiceUtil.returnSuccess();
108
109         GenericValue userLogin = (GenericValue) context.get("userLogin");
110         // get the order type
111
String JavaDoc orderTypeId = (String JavaDoc) context.get("orderTypeId");
112         String JavaDoc partyId = (String JavaDoc) context.get("partyId");
113         String JavaDoc billFromVendorPartyId = (String JavaDoc) context.get("billFromVendorPartyId");
114
115         // check security permissions for order:
116
// SALES ORDERS - if userLogin has ORDERMGR_SALES_CREATE or ORDERMGR_CREATE permission, or if it is same party as the partyId, or
117
// if it is an AGENT (sales rep) creating an order for his customer
118
// PURCHASE ORDERS - if there is a PURCHASE_ORDER permission
119
Map resultSecurity = new HashMap();
120         boolean hasPermission = false;
121         if (orderTypeId.equals("SALES_ORDER")) {
122             if (security.hasEntityPermission("ORDERMGR", "_SALES_CREATE", userLogin)) {
123                 hasPermission = true;
124             } else {
125                 // check sales agent/customer relationship
126
List repsCustomers = new LinkedList();
127                 try {
128                     repsCustomers = EntityUtil.filterByDate(userLogin.getRelatedOne("Party").getRelatedByAnd("FromPartyRelationship",
129                             UtilMisc.toMap("roleTypeIdFrom", "AGENT", "roleTypeIdTo", "CUSTOMER", "partyIdTo", partyId)));
130                 } catch (GenericEntityException ex) {
131                     Debug.logError("Could not determine if " + partyId + " is a customer of user " + userLogin.getString("userLoginId") + " due to " + ex.getMessage(), module);
132                 }
133                 if ((repsCustomers != null) && (repsCustomers.size() > 0) && (security.hasEntityPermission("SALESREP", "_ORDER_CREATE", userLogin))) {
134                     hasPermission = true;
135                 }
136             }
137         } else if ((orderTypeId.equals("PURCHASE_ORDER") && (security.hasEntityPermission("ORDERMGR", "_PURCHASE_CREATE", userLogin)))) {
138             hasPermission = true;
139         }
140         // final check - will pass if userLogin's partyId = partyId for order or if userLogin has ORDERMGR_CREATE permission
141
if (!hasPermission) {
142             partyId = ServiceUtil.getPartyIdCheckSecurity(userLogin, security, context, resultSecurity, "ORDERMGR", "_CREATE");
143             if (resultSecurity.size() > 0) {
144                 return resultSecurity;
145             }
146         }
147
148         // get the product store for the order, but it is required only for sales orders
149
String JavaDoc productStoreId = (String JavaDoc) context.get("productStoreId");
150         GenericValue productStore = null;
151         if ((orderTypeId.equals("SALES_ORDER")) && (UtilValidate.isNotEmpty(productStoreId))) {
152             try {
153                 productStore = delegator.findByPrimaryKeyCache("ProductStore", UtilMisc.toMap("productStoreId", productStoreId));
154             } catch (GenericEntityException e) {
155                 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorCouldNotFindProductStoreWithID",UtilMisc.toMap("productStoreId",productStoreId),locale) + e.toString());
156             }
157         }
158
159         // figure out if the order is immediately fulfilled based on product store settings
160
boolean isImmediatelyFulfilled = false;
161         if (productStore != null) {
162             isImmediatelyFulfilled = "Y".equals(productStore.getString("isImmediatelyFulfilled"));
163         }
164
165         successResult.put("orderTypeId", orderTypeId);
166
167         // lookup the order type entity
168
GenericValue orderType = null;
169         try {
170             orderType = delegator.findByPrimaryKeyCache("OrderType", UtilMisc.toMap("orderTypeId", orderTypeId));
171         } catch (GenericEntityException e) {
172             return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorOrderTypeLookupFailed",locale) + e.toString());
173         }
174
175         // make sure we have a valid order type
176
if (orderType == null) {
177             return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorInvalidOrderTypeWithID", UtilMisc.toMap("orderTypeId",orderTypeId), locale));
178         }
179
180         // check to make sure we have something to order
181
List orderItems = (List) context.get("orderItems");
182         if (orderItems.size() < 1) {
183             return ServiceUtil.returnError(UtilProperties.getMessage(resource, "items.none", locale));
184         }
185
186         // these need to be retrieved now because they might be needed for exploding MARKETING_PKG_AUTO
187
List orderAdjustments = (List) context.get("orderAdjustments");
188         List orderItemShipGroupInfo = (List) context.get("orderItemShipGroupInfo");
189         List orderItemPriceInfo = (List) context.get("orderItemPriceInfos");
190
191         // explode items which are MARKETINGG_PKG_AUTO
192
if (!orderTypeId.equals("PURCHASE_ORDER")) {
193             try {
194                 explodeMarketingPkgAutoItem(orderItems, orderAdjustments, orderItemShipGroupInfo, orderItemPriceInfo, orderTypeId, delegator, dispatcher, locale);
195             } catch (Exception JavaDoc e) {
196                Debug.logError(e, "Error calling explodeMarketingPkgAutoItem " + e.getMessage(), module);
197                return ServiceUtil.returnError("Error on exploding marketing_pkg_auto item.[" + e.toString() + "]");
198             }
199         }
200
201         // check inventory and other things for each item
202
List errorMessages = new LinkedList();
203         Map normalizedItemQuantities = new HashMap();
204         Map normalizedItemNames = new HashMap();
205         Map itemValuesBySeqId = new HashMap();
206         Iterator itemIter = orderItems.iterator();
207         java.sql.Timestamp JavaDoc nowTimestamp = UtilDateTime.nowTimestamp();
208
209         //
210
// need to run through the items combining any cases where multiple lines refer to the
211
// same product so the inventory check will work correctly
212
// also count quantities ordered while going through the loop
213
while (itemIter.hasNext()) {
214             GenericValue orderItem = (GenericValue) itemIter.next();
215
216             // start by putting it in the itemValuesById Map
217
itemValuesBySeqId.put(orderItem.getString("orderItemSeqId"), orderItem);
218
219             String JavaDoc currentProductId = (String JavaDoc) orderItem.get("productId");
220             if (currentProductId != null) {
221                 // only normalize items with a product associated (ignore non-product items)
222
if (normalizedItemQuantities.get(currentProductId) == null) {
223                     normalizedItemQuantities.put(currentProductId, new Double JavaDoc(orderItem.getDouble("quantity").doubleValue()));
224                     normalizedItemNames.put(currentProductId, new String JavaDoc(orderItem.getString("itemDescription")));
225                 } else {
226                     Double JavaDoc currentQuantity = (Double JavaDoc) normalizedItemQuantities.get(currentProductId);
227                     normalizedItemQuantities.put(currentProductId, new Double JavaDoc(currentQuantity.doubleValue() + orderItem.getDouble("quantity").doubleValue()));
228                 }
229
230                 try {
231                     // count product ordered quantities
232
// run this synchronously so it will run in the same transaction
233
dispatcher.runSync("countProductQuantityOrdered", UtilMisc.toMap("productId", currentProductId, "quantity", orderItem.getDouble("quantity"), "userLogin", userLogin));
234                 } catch (GenericServiceException e1) {
235                     Debug.logError(e1, "Error calling countProductQuantityOrdered service", module);
236                     return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorCallingCountProductQuantityOrderedService",locale) + e1.toString());
237                 }
238             }
239         }
240
241         if (!"PURCHASE_ORDER".equals(orderTypeId) && productStoreId == null) {
242             return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorTheProductStoreIdCanOnlyBeNullForPurchaseOrders",locale));
243         }
244
245         Iterator normalizedIter = normalizedItemQuantities.keySet().iterator();
246         while (normalizedIter.hasNext()) {
247             // lookup the product entity for each normalized item; error on products not found
248
String JavaDoc currentProductId = (String JavaDoc) normalizedIter.next();
249             Double JavaDoc currentQuantity = (Double JavaDoc) normalizedItemQuantities.get(currentProductId);
250             String JavaDoc itemName = (String JavaDoc) normalizedItemNames.get(currentProductId);
251             GenericValue product = null;
252
253             try {
254                 product = delegator.findByPrimaryKeyCache("Product", UtilMisc.toMap("productId", currentProductId));
255             } catch (GenericEntityException e) {
256                 String JavaDoc errMsg = UtilProperties.getMessage(resource, "product.not_found", new Object JavaDoc[] { currentProductId }, locale);
257                 Debug.logError(e, errMsg, module);
258                 errorMessages.add(errMsg);
259                 continue;
260             }
261
262             if (product == null) {
263                 String JavaDoc errMsg = UtilProperties.getMessage(resource, "product.not_found", new Object JavaDoc[] { currentProductId }, locale);
264                 Debug.logError(errMsg, module);
265                 errorMessages.add(errMsg);
266                 continue;
267             }
268
269             if ("SALES_ORDER".equals(orderTypeId)) {
270                 // check to see if introductionDate hasn't passed yet
271
if (product.get("introductionDate") != null && nowTimestamp.before(product.getTimestamp("introductionDate"))) {
272                     String JavaDoc excMsg = UtilProperties.getMessage(resource, "product.not_yet_for_sale",
273                             new Object JavaDoc[] { getProductName(product, itemName), product.getString("productId") }, locale);
274                     Debug.logWarning(excMsg, module);
275                     errorMessages.add(excMsg);
276                     continue;
277                 }
278             }
279
280             if ("SALES_ORDER".equals(orderTypeId)) {
281                 // check to see if salesDiscontinuationDate has passed
282
if (product.get("salesDiscontinuationDate") != null && nowTimestamp.after(product.getTimestamp("salesDiscontinuationDate"))) {
283                     String JavaDoc excMsg = UtilProperties.getMessage(resource, "product.no_longer_for_sale",
284                             new Object JavaDoc[] { getProductName(product, itemName), product.getString("productId") }, locale);
285                     Debug.logWarning(excMsg, module);
286                     errorMessages.add(excMsg);
287                     continue;
288                 }
289             }
290
291             if ("SALES_ORDER".equals(orderTypeId)) {
292                 // check to see if we have inventory available
293
try {
294                     Map invReqResult = dispatcher.runSync("isStoreInventoryAvailableOrNotRequired", UtilMisc.toMap("productStoreId", productStoreId, "productId", product.get("productId"), "product", product, "quantity", currentQuantity));
295                     if (ServiceUtil.isError(invReqResult)) {
296                         errorMessages.add(invReqResult.get(ModelService.ERROR_MESSAGE));
297                         errorMessages.addAll((List) invReqResult.get(ModelService.ERROR_MESSAGE_LIST));
298                     } else if (!"Y".equals((String JavaDoc) invReqResult.get("availableOrNotRequired"))) {
299                         String JavaDoc invErrMsg = UtilProperties.getMessage(resource, "product.out_of_stock",
300                                 new Object JavaDoc[] { getProductName(product, itemName), currentProductId }, locale);
301                         Debug.logWarning(invErrMsg, module);
302                         errorMessages.add(invErrMsg);
303                         continue;
304                     }
305                 } catch (GenericServiceException e) {
306                     String JavaDoc errMsg = "Fatal error calling inventory checking services: " + e.toString();
307                     Debug.logError(e, errMsg, module);
308                     errorMessages.add(errMsg);
309                 }
310             }
311         }
312
313         // add the fixedAsset id to the workefforts map by obtaining the fixed Asset number from the FixedAssetProduct table
314
List workEfforts = (List) context.get("workEfforts"); // is an optional parameter from this service but mandatory for rental items
315
Iterator orderItemIter = orderItems.iterator();
316         while (orderItemIter.hasNext()) {
317             GenericValue orderItem = (GenericValue) orderItemIter.next();
318             if ("RENTAL_ORDER_ITEM".equals(orderItem.getString("orderItemTypeId"))) {
319                 // check to see if workefforts are available for this order type.
320
if (workEfforts == null || workEfforts.size() == 0) {
321                     String JavaDoc errMsg = "Work Efforts missing for ordertype RENTAL_ORDER_ITEM " + "Product: " + orderItem.getString("productId");
322                     Debug.logError(errMsg, module);
323                     errorMessages.add(errMsg);
324                     return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderRentalOrderItems",locale));
325                 }
326                 Iterator we = workEfforts.iterator(); // find the related workEffortItem (workEffortId = orderSeqId)
327
while (we.hasNext()) {
328                     // create the entity maps required.
329
GenericValue workEffort = (GenericValue) we.next();
330                     if (workEffort.getString("workEffortId").equals(orderItem.getString("orderItemSeqId"))) {
331                         List selFixedAssetProduct = null;
332                         try {
333                             List allFixedAssetProduct = delegator.findByAnd("FixedAssetProduct",UtilMisc.toMap("productId",orderItem.getString("productId"),"fixedAssetProductTypeId", "FAPT_USE"));
334                             selFixedAssetProduct = EntityUtil.filterByDate(allFixedAssetProduct, nowTimestamp, "fromDate", "thruDate", true);
335                         } catch (GenericEntityException e) {
336                             String JavaDoc excMsg = "Could not find related Fixed Asset for the product: " + orderItem.getString("productId");
337                             Debug.logError(excMsg, module);
338                             errorMessages.add(excMsg);
339                             return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderCouldNotFindRelatedFixedAssetForTheProduct",UtilMisc.toMap("productId",orderItem.getString("productId")), locale ));
340                         }
341                         if (selFixedAssetProduct != null && selFixedAssetProduct.size() > 0) {
342                             Iterator firstOne = selFixedAssetProduct.iterator();
343                             if(firstOne.hasNext()) {
344                                 GenericValue fixedAssetProduct = delegator.makeValue("FixedAssetProduct", null);
345                                 fixedAssetProduct = (GenericValue) firstOne.next();
346                                 workEffort.set("fixedAssetId",fixedAssetProduct.get("fixedAssetId"));
347                                 workEffort.set("quantityToProduce",orderItem.get("quantity")); // have quantity easy available later...
348
}
349                         }
350                         break; // item found, so go to next orderitem.
351
}
352                 }
353             }
354         }
355
356         if (errorMessages.size() > 0) {
357             return ServiceUtil.returnError(errorMessages);
358         }
359
360         // the inital status for ALL order types
361
String JavaDoc initialStatus = "ORDER_CREATED";
362         successResult.put("statusId", initialStatus);
363
364         // create the order object
365
String JavaDoc orderId = null;
366         String JavaDoc orgPartyId = null;
367         if (productStore != null) {
368             orgPartyId = productStore.getString("payToPartyId");
369         } else if (billFromVendorPartyId != null) {
370             orgPartyId = billFromVendorPartyId;
371         }
372         
373         if (UtilValidate.isNotEmpty(orgPartyId)) {
374             Map getNextOrderIdContext = UtilMisc.toMap("partyId", orgPartyId, "userLogin", userLogin);
375
376             if ((orderTypeId.equals("SALES_ORDER")) || (productStoreId != null)) {
377                 getNextOrderIdContext.put("productStoreId", productStoreId);
378             }
379             
380             try {
381                 Map getNextOrderIdResult = dispatcher.runSync("getNextOrderId", getNextOrderIdContext);
382                 if (ServiceUtil.isError(getNextOrderIdResult)) {
383                     return ServiceUtil.returnError("Error getting next orderId while creating order", null, null, getNextOrderIdResult);
384                 }
385                 
386                 orderId = (String JavaDoc) getNextOrderIdResult.get("orderId");
387             } catch (GenericServiceException e) {
388                 String JavaDoc errMsg = "Error creating order while getting orderId: " + e.toString();
389                 Debug.logError(e, errMsg, module);
390                 return ServiceUtil.returnError(errMsg);
391             }
392         }
393
394         if (UtilValidate.isEmpty(orderId)) {
395             // for purchase orders or when other orderId generation fails, a product store id should not be required to make an order
396
orderId = delegator.getNextSeqId("OrderHeader");
397         }
398         
399         String JavaDoc billingAccountId = (String JavaDoc) context.get("billingAccountId");
400         Timestamp JavaDoc orderDate = (Timestamp JavaDoc) context.get("orderDate");
401         if (orderDate == null) {
402             orderDate = nowTimestamp;
403         }
404
405         Map orderHeaderMap = UtilMisc.toMap("orderId", orderId, "orderTypeId", orderTypeId,
406                 "orderDate", orderDate, "entryDate", nowTimestamp,
407                 "statusId", initialStatus, "billingAccountId", billingAccountId);
408         if (isImmediatelyFulfilled) {
409             // also flag this order as needing inventory issuance so that when it is set to complete it will be issued immediately (needsInventoryIssuance = Y)
410
orderHeaderMap.put("needsInventoryIssuance", "Y");
411         }
412         GenericValue orderHeader = delegator.makeValue("OrderHeader", orderHeaderMap);
413
414         // determine the sales channel
415
String JavaDoc salesChannelEnumId = (String JavaDoc) context.get("salesChannelEnumId");
416         if ((salesChannelEnumId == null) || salesChannelEnumId.equals("UNKNWN_SALES_CHANNEL")) {
417             // try the default store sales channel
418
if (orderTypeId.equals("SALES_ORDER") && (productStore != null)) {
419                 salesChannelEnumId = productStore.getString("defaultSalesChannelEnumId");
420             }
421             // if there's still no channel, set to unknown channel
422
if (salesChannelEnumId == null) {
423                 salesChannelEnumId = "UNKNWN_SALES_CHANNEL";
424             }
425         }
426         orderHeader.set("salesChannelEnumId", salesChannelEnumId);
427
428         if (context.get("currencyUom") != null) {
429             orderHeader.set("currencyUom", context.get("currencyUom"));
430         }
431
432         if (context.get("firstAttemptOrderId") != null) {
433             orderHeader.set("firstAttemptOrderId", context.get("firstAttemptOrderId"));
434         }
435
436         if (context.get("grandTotal") != null) {
437             orderHeader.set("grandTotal", context.get("grandTotal"));
438         }
439
440         if (UtilValidate.isNotEmpty((String JavaDoc) context.get("visitId"))) {
441             orderHeader.set("visitId", context.get("visitId"));
442         }
443
444         if (UtilValidate.isNotEmpty((String JavaDoc) context.get("internalCode"))) {
445             orderHeader.set("internalCode", context.get("internalCode"));
446         }
447
448         if (UtilValidate.isNotEmpty((String JavaDoc) context.get("externalId"))) {
449             orderHeader.set("externalId", context.get("externalId"));
450         }
451
452         if (UtilValidate.isNotEmpty((String JavaDoc) context.get("originFacilityId"))) {
453             orderHeader.set("originFacilityId", context.get("originFacilityId"));
454         }
455
456         if (UtilValidate.isNotEmpty((String JavaDoc) context.get("productStoreId"))) {
457             orderHeader.set("productStoreId", context.get("productStoreId"));
458         }
459
460         if (UtilValidate.isNotEmpty((String JavaDoc) context.get("transactionId"))) {
461             orderHeader.set("transactionId", context.get("transactionId"));
462         }
463
464         if (UtilValidate.isNotEmpty((String JavaDoc) context.get("terminalId"))) {
465             orderHeader.set("terminalId", context.get("terminalId"));
466         }
467
468         if (UtilValidate.isNotEmpty((String JavaDoc) context.get("webSiteId"))) {
469             orderHeader.set("webSiteId", context.get("webSiteId"));
470         }
471
472         if (userLogin != null && userLogin.get("userLoginId") != null) {
473             orderHeader.set("createdBy", userLogin.getString("userLoginId"));
474         }
475
476         // first try to create the OrderHeader; if this does not fail, continue.
477
try {
478             delegator.create(orderHeader);
479         } catch (GenericEntityException e) {
480             Debug.logError(e, "Cannot create OrderHeader entity; problems with insert", module);
481             return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderOrderCreationFailedPleaseNotifyCustomerService",locale));
482         }
483
484         // create the order status record
485
String JavaDoc orderStatusSeqId = delegator.getNextSeqId("OrderStatus");
486         GenericValue orderStatus = delegator.makeValue("OrderStatus", UtilMisc.toMap("orderStatusId", orderStatusSeqId));
487         orderStatus.set("orderId", orderId);
488         orderStatus.set("statusId", orderHeader.getString("statusId"));
489         orderStatus.set("statusDatetime", nowTimestamp);
490         orderStatus.set("statusUserLogin", userLogin.getString("userLoginId"));
491         toBeStored.add(orderStatus);
492
493         // set the order items
494
Iterator oi = orderItems.iterator();
495         while (oi.hasNext()) {
496             GenericValue orderItem = (GenericValue) oi.next();
497             orderItem.set("orderId", orderId);
498             toBeStored.add(orderItem);
499
500             // create the item status record
501
String JavaDoc itemStatusId = delegator.getNextSeqId("OrderStatus");
502             GenericValue itemStatus = delegator.makeValue("OrderStatus", UtilMisc.toMap("orderStatusId", itemStatusId));
503             itemStatus.put("statusId", orderItem.get("statusId"));
504             itemStatus.put("orderId", orderId);
505             itemStatus.put("orderItemSeqId", orderItem.get("orderItemSeqId"));
506             itemStatus.put("statusDatetime", nowTimestamp);
507             itemStatus.set("statusUserLogin", userLogin.getString("userLoginId"));
508             toBeStored.add(itemStatus);
509         }
510
511         // set the order attributes
512
List orderAttributes = (List) context.get("orderAttributes");
513         if (orderAttributes != null && orderAttributes.size() > 0) {
514             Iterator oattr = orderAttributes.iterator();
515             while (oattr.hasNext()) {
516                 GenericValue oatt = (GenericValue) oattr.next();
517                 oatt.set("orderId", orderId);
518                 toBeStored.add(oatt);
519             }
520         }
521
522         // set the order item attributes
523
List orderItemAttributes = (List) context.get("orderItemAttributes");
524         if (orderItemAttributes != null && orderItemAttributes.size() > 0) {
525             Iterator oiattr = orderItemAttributes.iterator();
526             while (oiattr.hasNext()) {
527                 GenericValue oiatt = (GenericValue) oiattr.next();
528                 oiatt.set("orderId", orderId);
529                 toBeStored.add(oiatt);
530             }
531         }
532
533         // create the workeffort records
534
// and connect them with the orderitem over the WorkOrderItemFulfillment
535
// create also the techData calendars to keep track of availability of the fixed asset.
536
if (workEfforts != null && workEfforts.size() > 0) {
537             Iterator we = workEfforts.iterator();
538             while (we.hasNext()) {
539                 // create the entity maps required.
540
GenericValue workEffort = (GenericValue) we.next();
541                 GenericValue workOrderItemFulfillment = delegator.makeValue("WorkOrderItemFulfillment", null);
542                 // find fixed asset supplied on the workeffort map
543
GenericValue fixedAsset = null;
544                 Debug.logInfo("find the fixedAsset",module);
545                 try { fixedAsset = delegator.findByPrimaryKey("FixedAsset",
546                         UtilMisc.toMap("fixedAssetId", workEffort.get("fixedAssetId")));
547                 }
548                 catch (GenericEntityException e) {
549                     return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderFixedAssetNotFoundFixedAssetId ", UtilMisc.toMap("fixedAssetId",workEffort.get("fixedAssetId")), locale));
550                 }
551                 if (fixedAsset == null) {
552                     return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderFixedAssetNotFoundFixedAssetId ", UtilMisc.toMap("fixedAssetId",workEffort.get("fixedAssetId")), locale));
553                 }
554                 // see if this fixed asset has a calendar, when no create one and attach to fixed asset
555
Debug.logInfo("find the techdatacalendar",module);
556                 GenericValue techDataCalendar = null;
557                 try { techDataCalendar = fixedAsset.getRelatedOne("TechDataCalendar");
558                 }
559                 catch (GenericEntityException e) {
560                     Debug.logInfo("TechData calendar does not exist yet so create for fixedAsset: " + fixedAsset.get("fixedAssetId") ,module);
561                 }
562                 if(techDataCalendar == null ) {
563                     techDataCalendar = delegator.makeValue("TechDataCalendar", null);
564                     Debug.logInfo("create techdata calendar because it does not exist",module);
565                     String JavaDoc calendarId = delegator.getNextSeqId("techDataCalendar").toString();
566                     techDataCalendar.set("calendarId", calendarId);
567                     toBeStored.add(techDataCalendar);
568                     Debug.logInfo("update fixed Asset",module);
569                     fixedAsset.set("calendarId",calendarId);
570                     toBeStored.add(fixedAsset);
571                 }
572                 // then create the workEffort and the workOrderItemFulfillment to connect to the order and orderItem
573
workOrderItemFulfillment.set("orderItemSeqId", workEffort.get("workEffortId").toString()); // orderItemSeqNo is stored here so save first
574
// workeffort
575
String JavaDoc workEffortId = delegator.getNextSeqId("WorkEffort").toString(); // find next available workEffortId
576
workEffort.set("workEffortId", workEffortId);
577                 workEffort.set("workEffortTypeId", "ASSET_USAGE");
578                 toBeStored.add(workEffort); // store workeffort before workOrderItemFulfillment because of workEffortId key constraint
579
// workOrderItemFulfillment
580
workOrderItemFulfillment.set("workEffortId", workEffortId);
581                 workOrderItemFulfillment.set("orderId", orderId);
582                 toBeStored.add(workOrderItemFulfillment);
583 // Debug.logInfo("Workeffort "+ workEffortId + " created for asset " + workEffort.get("fixedAssetId") + " and order "+ workOrderItemFulfillment.get("orderId") + "/" + workOrderItemFulfillment.get("orderItemSeqId") + " created", module);
584
//
585
// now create the TechDataExcDay, when they do not exist, create otherwise update the capacity values
586
// please note that calendarId is the same for (TechData)Calendar, CalendarExcDay and CalendarExWeek
587
Timestamp JavaDoc estimatedStartDate = workEffort.getTimestamp("estimatedStartDate");
588                 Timestamp JavaDoc estimatedCompletionDate = workEffort.getTimestamp("estimatedCompletionDate");
589                 long dayCount = (estimatedCompletionDate.getTime() - estimatedStartDate.getTime())/86400000;
590                 while (--dayCount >= 0) {
591                     GenericValue techDataCalendarExcDay = null;
592                     // find an existing Day exception record
593
Timestamp JavaDoc exceptionDateStartTime = new Timestamp JavaDoc((long)(estimatedStartDate.getTime() + (dayCount * 86400000)));
594                     try { techDataCalendarExcDay = delegator.findByPrimaryKey("TechDataCalendarExcDay",
595                             UtilMisc.toMap("calendarId", fixedAsset.get("calendarId"), "exceptionDateStartTime", exceptionDateStartTime));
596                     }
597                     catch (GenericEntityException e) {
598                         Debug.logInfo(" techData excday record not found so creating........", module);
599                     }
600                     if (techDataCalendarExcDay == null) {
601                         techDataCalendarExcDay = delegator.makeValue("TechDataCalendarExcDay", null);
602                         techDataCalendarExcDay.set("calendarId", fixedAsset.get("calendarId"));
603                         techDataCalendarExcDay.set("exceptionDateStartTime", exceptionDateStartTime);
604                         techDataCalendarExcDay.set("usedCapacity",new Double JavaDoc(00.00)); // initialise to zero
605
techDataCalendarExcDay.set("exceptionCapacity", fixedAsset.getDouble("productionCapacity"));
606 // Debug.logInfo(" techData excday record not found creating for calendarId: " + techDataCalendarExcDay.getString("calendarId") +
607
// " and date: " + exceptionDateStartTime.toString(), module);
608
}
609                     // add the quantity to the quantity on the date record
610
Double JavaDoc newUsedCapacity = new Double JavaDoc(techDataCalendarExcDay.getDouble("usedCapacity").doubleValue() +
611                             workEffort.getDouble("quantityToProduce").doubleValue());
612                     // 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
613
if (fixedAsset.get("productionCapacity") != null) {
614 // Debug.logInfo("see if maximum not reached, available: " + techDataCalendarExcDay.getString("exceptionCapacity") +
615
// " already allocated: " + techDataCalendarExcDay.getString("usedCapacity") +
616
// " Requested: " + workEffort.getString("quantityToProduce"), module);
617
if (newUsedCapacity.compareTo(techDataCalendarExcDay.getDouble("exceptionCapacity")) > 0) {
618                             String JavaDoc errMsg = "ERROR: fixed_Asset_sold_out AssetId: " + workEffort.get("fixedAssetId") + " on date: " + techDataCalendarExcDay.getString("exceptionDateStartTime");
619                             Debug.logError(errMsg, module);
620                             errorMessages.add(errMsg);
621                             continue;
622                         }
623                     }
624                     techDataCalendarExcDay.set("usedCapacity", newUsedCapacity);
625                     toBeStored.add(techDataCalendarExcDay);
626 // Debug.logInfo("Update success CalendarID: " + techDataCalendarExcDay.get("calendarId").toString() +
627
// " and for date: " + techDataCalendarExcDay.get("exceptionDateStartTime").toString() +
628
// " and for quantity: " + techDataCalendarExcDay.getDouble("usedCapacity").toString(), module);
629
}
630             }
631         }
632         if (errorMessages.size() > 0) {
633             return ServiceUtil.returnError(errorMessages);
634         }
635
636         // set the orderId on all adjustments; this list will include order and
637
// item adjustments...
638
if (orderAdjustments != null && orderAdjustments.size() > 0) {
639             Iterator iter = orderAdjustments.iterator();
640
641             while (iter.hasNext()) {
642                 GenericValue orderAdjustment = (GenericValue) iter.next();
643                 try {
644                     orderAdjustment.set("orderAdjustmentId", delegator.getNextSeqId("OrderAdjustment"));
645                 } catch (IllegalArgumentException JavaDoc e) {
646                     return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorCouldNotGetNextSequenceIdForOrderAdjustmentCannotCreateOrder",locale));
647                 }
648
649                 orderAdjustment.set("orderId", orderId);
650                 orderAdjustment.set("createdDate", UtilDateTime.nowTimestamp());
651                 orderAdjustment.set("createdByUserLogin", userLogin.getString("userLoginId"));
652
653                 if (orderAdjustment.get("orderItemSeqId") == null || orderAdjustment.getString("orderItemSeqId").length() == 0) {
654                     orderAdjustment.set("orderItemSeqId", DataModelConstants.SEQ_ID_NA);
655                 }
656                 if (orderAdjustment.get("shipGroupSeqId") == null || orderAdjustment.getString("shipGroupSeqId").length() == 0) {
657                     orderAdjustment.set("shipGroupSeqId", DataModelConstants.SEQ_ID_NA);
658                 }
659                 toBeStored.add(orderAdjustment);
660             }
661         }
662
663         // set the order contact mechs
664
List orderContactMechs = (List) context.get("orderContactMechs");
665         if (orderContactMechs != null && orderContactMechs.size() > 0) {
666             Iterator ocmi = orderContactMechs.iterator();
667
668             while (ocmi.hasNext()) {
669                 GenericValue ocm = (GenericValue) ocmi.next();
670                 ocm.set("orderId", orderId);
671                 toBeStored.add(ocm);
672             }
673         }
674
675         // set the order item contact mechs
676
List orderItemContactMechs = (List) context.get("orderItemContactMechs");
677         if (orderItemContactMechs != null && orderItemContactMechs.size() > 0) {
678             Iterator oicmi = orderItemContactMechs.iterator();
679
680             while (oicmi.hasNext()) {
681                 GenericValue oicm = (GenericValue) oicmi.next();
682                 oicm.set("orderId", orderId);
683                 toBeStored.add(oicm);
684             }
685         }
686
687         // set the order item ship groups
688
if (orderItemShipGroupInfo != null && orderItemShipGroupInfo.size() > 0) {
689             Iterator osiInfos = orderItemShipGroupInfo.iterator();
690             while (osiInfos.hasNext()) {
691                 GenericValue valueObj = (GenericValue) osiInfos.next();
692                 valueObj.set("orderId", orderId);
693                 if ("OrderItemShipGroup".equals(valueObj.getEntityName())) {
694                     // ship group
695
if (valueObj.get("carrierRoleTypeId") == null) {
696                         valueObj.set("carrierRoleTypeId", "CARRIER");
697                     }
698                 } else if ("OrderAdjustment".equals(valueObj.getEntityName())) {
699                     // shipping / tax adjustment(s)
700
if (valueObj.get("orderItemSeqId") == null || valueObj.getString("orderItemSeqId").length() == 0) {
701                         valueObj.set("orderItemSeqId", DataModelConstants.SEQ_ID_NA);
702                     }
703                     valueObj.set("orderAdjustmentId", delegator.getNextSeqId("OrderAdjustment"));
704                     valueObj.set("createdDate", UtilDateTime.nowTimestamp());
705                     valueObj.set("createdByUserLogin", userLogin.getString("userLoginId"));
706                 }
707                 toBeStored.add(valueObj);
708             }
709         }
710
711         // set the additional party roles
712
Map additionalPartyRole = (Map) context.get("orderAdditionalPartyRoleMap");
713         if (additionalPartyRole != null) {
714             Iterator aprIt = additionalPartyRole.entrySet().iterator();
715             while (aprIt.hasNext()) {
716                 Map.Entry entry = (Map.Entry) aprIt.next();
717                 String JavaDoc additionalRoleTypeId = (String JavaDoc) entry.getKey();
718                 List parties = (List) entry.getValue();
719                 if (parties != null) {
720                     Iterator apIt = parties.iterator();
721                     while (apIt.hasNext()) {
722                         String JavaDoc additionalPartyId = (String JavaDoc) apIt.next();
723                         toBeStored.add(delegator.makeValue("PartyRole", UtilMisc.toMap("partyId", additionalPartyId, "roleTypeId", additionalRoleTypeId)));
724                         toBeStored.add(delegator.makeValue("OrderRole", UtilMisc.toMap("orderId", orderId, "partyId", additionalPartyId, "roleTypeId", additionalRoleTypeId)));
725                     }
726                 }
727             }
728         }
729
730         // set the item survey responses
731
List surveyResponses = (List) context.get("orderItemSurveyResponses");
732         if (surveyResponses != null && surveyResponses.size() > 0) {
733             Iterator oisr = surveyResponses.iterator();
734             while (oisr.hasNext()) {
735                 GenericValue surveyResponse = (GenericValue) oisr.next();
736                 surveyResponse.set("orderId", orderId);
737                 toBeStored.add(surveyResponse);
738             }
739         }
740
741         // set the item price info; NOTE: this must be after the orderItems are stored for referential integrity
742
if (orderItemPriceInfo != null && orderItemPriceInfo.size() > 0) {
743             Iterator oipii = orderItemPriceInfo.iterator();
744
745             while (oipii.hasNext()) {
746                 GenericValue oipi = (GenericValue) oipii.next();
747                 try {
748                     oipi.set("orderItemPriceInfoId", delegator.getNextSeqId("OrderItemPriceInfo"));
749                 } catch (IllegalArgumentException JavaDoc e) {
750                     return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorCouldNotGetNextSequenceIdForOrderItemPriceInfoCannotCreateOrder",locale));
751                 }
752
753                 oipi.set("orderId", orderId);
754                 toBeStored.add(oipi);
755             }
756         }
757
758         // set the item associations
759
List orderItemAssociations = (List) context.get("orderItemAssociations");
760         if (orderItemAssociations != null && orderItemAssociations.size() > 0) {
761             Iterator oia = orderItemAssociations.iterator();
762             while (oia.hasNext()) {
763                 GenericValue orderItemAssociation = (GenericValue) oia.next();
764                 orderItemAssociation.set("purchaseOrderId", orderId);
765                 toBeStored.add(orderItemAssociation);
766             }
767         }
768
769         // store the orderProductPromoUseInfos
770
List orderProductPromoUses = (List) context.get("orderProductPromoUses");
771         if (orderProductPromoUses != null && orderProductPromoUses.size() > 0) {
772             Iterator orderProductPromoUseIter = orderProductPromoUses.iterator();
773             while (orderProductPromoUseIter.hasNext()) {
774                 GenericValue productPromoUse = (GenericValue) orderProductPromoUseIter.next();
775                 productPromoUse.set("orderId", orderId);
776                 toBeStored.add(productPromoUse);
777             }
778         }
779
780         /* DEJ20050529 the OLD way, where a single party had all roles... no longer doing things this way...
781         // define the roles for the order
782         List userOrderRoleTypes = null;
783         if ("SALES_ORDER".equals(orderTypeId)) {
784             userOrderRoleTypes = UtilMisc.toList("END_USER_CUSTOMER", "SHIP_TO_CUSTOMER", "BILL_TO_CUSTOMER", "PLACING_CUSTOMER");
785         } else if ("PURCHASE_ORDER".equals(orderTypeId)) {
786             userOrderRoleTypes = UtilMisc.toList("SHIP_FROM_VENDOR", "BILL_FROM_VENDOR", "SUPPLIER_AGENT");
787         } else {
788             // TODO: some default behavior
789         }
790
791         // now add the roles
792         if (userOrderRoleTypes != null) {
793             Iterator i = userOrderRoleTypes.iterator();
794             while (i.hasNext()) {
795                 String roleType = (String) i.next();
796                 String thisParty = partyId;
797                 if (thisParty == null) {
798                     thisParty = "_NA_"; // will always set these roles so we can query
799                 }
800                 // make sure the party is in the role before adding
801                 toBeStored.add(delegator.makeValue("PartyRole", UtilMisc.toMap("partyId", partyId, "roleTypeId", roleType)));
802                 toBeStored.add(delegator.makeValue("OrderRole", UtilMisc.toMap("orderId", orderId, "partyId", partyId, "roleTypeId", roleType)));
803             }
804         }
805         */

806
807         // see the attributeRoleMap definition near the top of this file for attribute-role mappings
808
Map attributeRoleMap = salesAttributeRoleMap;
809         if ("PURCHASE_ORDER".equals(orderTypeId)) {
810             attributeRoleMap = purchaseAttributeRoleMap;
811         }
812         Iterator attributeRoleEntryIter = attributeRoleMap.entrySet().iterator();
813         while (attributeRoleEntryIter.hasNext()) {
814             Map.Entry attributeRoleEntry = (Map.Entry) attributeRoleEntryIter.next();
815
816             if (UtilValidate.isNotEmpty((String JavaDoc) context.get(attributeRoleEntry.getKey()))) {
817                 // make sure the party is in the role before adding
818
toBeStored.add(delegator.makeValue("PartyRole", UtilMisc.toMap("partyId", context.get(attributeRoleEntry.getKey()), "roleTypeId", attributeRoleEntry.getValue())));
819                 toBeStored.add(delegator.makeValue("OrderRole", UtilMisc.toMap("orderId", orderId, "partyId", context.get(attributeRoleEntry.getKey()), "roleTypeId", attributeRoleEntry.getValue())));
820             }
821         }
822
823
824         // set the affiliate -- This is going to be removed...
825
String JavaDoc affiliateId = (String JavaDoc) context.get("affiliateId");
826         if (UtilValidate.isNotEmpty(affiliateId)) {
827             toBeStored.add(delegator.makeValue("OrderRole",
828                     UtilMisc.toMap("orderId", orderId, "partyId", affiliateId, "roleTypeId", "AFFILIATE")));
829         }
830
831         // set the distributor
832
String JavaDoc distributorId = (String JavaDoc) context.get("distributorId");
833         if (UtilValidate.isNotEmpty(distributorId)) {
834             toBeStored.add(delegator.makeValue("OrderRole",
835                     UtilMisc.toMap("orderId", orderId, "partyId", distributorId, "roleTypeId", "DISTRIBUTOR")));
836         }
837
838         // find all parties in role VENDOR associated with WebSite OR ProductStore (where WebSite overrides, if specified), associated first valid with the Order
839
if (UtilValidate.isNotEmpty((String JavaDoc) context.get("productStoreId"))) {
840             try {
841                 List productStoreRoles = delegator.findByAnd("ProductStoreRole", UtilMisc.toMap("roleTypeId", "VENDOR", "productStoreId", context.get("productStoreId")), UtilMisc.toList("-fromDate"));
842                 productStoreRoles = EntityUtil.filterByDate(productStoreRoles, true);
843                 GenericValue productStoreRole = EntityUtil.getFirst(productStoreRoles);
844                 if (productStoreRole != null) {
845                     toBeStored.add(delegator.makeValue("OrderRole",
846                             UtilMisc.toMap("orderId", orderId, "partyId", productStoreRole.get("partyId"), "roleTypeId", "VENDOR")));
847                 }
848             } catch (GenericEntityException e) {
849                 Debug.logError(e, "Error looking up Vendor for the current Product Store", module);
850             }
851
852         }
853         if (UtilValidate.isNotEmpty((String JavaDoc) context.get("webSiteId"))) {
854             try {
855                 List webSiteRoles = delegator.findByAnd("WebSiteRole", UtilMisc.toMap("roleTypeId", "VENDOR", "webSiteId", context.get("webSiteId")), UtilMisc.toList("-fromDate"));
856                 webSiteRoles = EntityUtil.filterByDate(webSiteRoles, true);
857                 GenericValue webSiteRole = EntityUtil.getFirst(webSiteRoles);
858                 if (webSiteRole != null) {
859                     toBeStored.add(delegator.makeValue("OrderRole",
860                             UtilMisc.toMap("orderId", orderId, "partyId", webSiteRole.get("partyId"), "roleTypeId", "VENDOR")));
861                 }
862             } catch (GenericEntityException e) {
863                 Debug.logError(e, "Error looking up Vendor for the current Web Site", module);
864             }
865
866         }
867
868         // set the order payment info
869
List orderPaymentInfos = (List) context.get("orderPaymentInfo");
870         if (orderPaymentInfos != null && orderPaymentInfos.size() > 0) {
871             Iterator oppIter = orderPaymentInfos.iterator();
872             while (oppIter.hasNext()) {
873                 GenericValue valueObj = (GenericValue) oppIter.next();
874                 valueObj.set("orderId", orderId);
875                 if ("OrderPaymentPreference".equals(valueObj.getEntityName())) {
876                     if (valueObj.get("orderPaymentPreferenceId") == null) {
877                         valueObj.set("orderPaymentPreferenceId", delegator.getNextSeqId("OrderPaymentPreference").toString());
878                         valueObj.set("createdDate", UtilDateTime.nowTimestamp());
879                         valueObj.set("createdByUserLogin", userLogin.getString("userLoginId"));
880                     }
881                     if (valueObj.get("statusId") == null) {
882                         valueObj.set("statusId", "PAYMENT_NOT_RECEIVED");
883                     }
884                 }
885                 toBeStored.add(valueObj);
886             }
887         }
888
889         // store the trackingCodeOrder entities
890
List trackingCodeOrders = (List) context.get("trackingCodeOrders");
891         if (trackingCodeOrders != null && trackingCodeOrders.size() > 0) {
892             Iterator tkcdordIter = trackingCodeOrders.iterator();
893             while (tkcdordIter.hasNext()) {
894                 GenericValue trackingCodeOrder = (GenericValue) tkcdordIter.next();
895                 trackingCodeOrder.set("orderId", orderId);
896                 toBeStored.add(trackingCodeOrder);
897             }
898         }
899
900        // store the OrderTerm entities
901

902        List orderTerms = (List) context.get("orderTerms");
903        if (orderTerms != null && orderTerms.size() > 0) {
904            Iterator orderTermIter = orderTerms.iterator();
905            while (orderTermIter.hasNext()) {
906                GenericValue orderTerm = (GenericValue) orderTermIter.next();
907                orderTerm.set("orderId", orderId);
908                orderTerm.set("orderItemSeqId","_NA_");
909                toBeStored.add(orderTerm);
910            }
911        }
912
913         try {
914             // store line items, etc so that they will be there for the foreign key checks
915
delegator.storeAll(toBeStored);
916
917             // START inventory reservation
918
List resErrorMessages = new LinkedList();
919             try {
920                 reserveInventory(delegator, dispatcher, userLogin, locale, orderItemShipGroupInfo, itemValuesBySeqId,
921                         orderTypeId, productStoreId, resErrorMessages);
922             } catch (GeneralException e) {
923                 return ServiceUtil.returnError(e.getMessage());
924             }
925
926             if (resErrorMessages.size() > 0) {
927                 return ServiceUtil.returnError(resErrorMessages);
928             }
929             // END inventory reservation
930

931             successResult.put("orderId", orderId);
932         } catch (GenericEntityException e) {
933             Debug.logError(e, "Problem with order storage or reservations", module);
934             return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorCouldNotCreateOrderWriteError",locale) + e.getMessage() + ").");
935         }
936
937         return successResult;
938     }
939
940     public static void reserveInventory(GenericDelegator delegator, LocalDispatcher dispatcher, GenericValue userLogin, Locale locale, List orderItemShipGroupInfo, Map itemValuesBySeqId, String JavaDoc orderTypeId, String JavaDoc productStoreId, List resErrorMessages) throws GeneralException {
941         boolean isImmediatelyFulfilled = false;
942         GenericValue productStore = null;
943         if (UtilValidate.isNotEmpty(productStoreId)) {
944             try {
945                 productStore = delegator.findByPrimaryKeyCache("ProductStore", UtilMisc.toMap("productStoreId", productStoreId));
946             } catch (GenericEntityException e) {
947                 throw new GeneralException(UtilProperties.getMessage(resource_error, "OrderErrorCouldNotFindProductStoreWithID", UtilMisc.toMap("productStoreId", productStoreId), locale) + e.toString());
948             }
949         }
950         if (productStore != null) {
951             isImmediatelyFulfilled = "Y".equals(productStore.getString("isImmediatelyFulfilled"));
952         }
953
954         boolean reserveInventory = ("SALES_ORDER".equals(orderTypeId));
955         if (reserveInventory && isImmediatelyFulfilled) {
956             // don't reserve inventory if the product store has isImmediatelyFulfilled set, ie don't if in this store things are immediately fulfilled
957
reserveInventory = false;
958         }
959
960         if (reserveInventory) {
961             // START inventory reservation
962
// decrement inventory available for each OrderItemShipGroupAssoc, within the same transaction
963
if (orderItemShipGroupInfo != null && orderItemShipGroupInfo.size() > 0) {
964                 Iterator osiInfos = orderItemShipGroupInfo.iterator();
965                 while (osiInfos.hasNext()) {
966                     GenericValue orderItemShipGroupAssoc = (GenericValue) osiInfos.next();
967                     if ("OrderItemShipGroupAssoc".equals(orderItemShipGroupAssoc.getEntityName())) {
968                         GenericValue orderItem = (GenericValue) itemValuesBySeqId.get(orderItemShipGroupAssoc.get("orderItemSeqId"));
969                         String JavaDoc itemStatus = orderItem.getString("statusId");
970                         if ("ITEM_REJECTED".equals(itemStatus) || "ITEM_CANCELLED".equals(itemStatus) || "ITEM_COMPLETED".equals(itemStatus)) {
971                             Debug.logInfo("Order item [" + orderItem.getString("orderId") + " / " + orderItem.getString("orderItemSeqId") + "] is not in a proper status for reservation", module);
972                             continue;
973                         }
974                         if (UtilValidate.isNotEmpty(orderItem.getString("productId")) && !"RENTAL_ORDER_ITEM".equals(orderItem.getString("orderItemTypeId")))
975                         { // ignore for rental
976
// only reserve product items; ignore non-product items
977
try {
978                                 Map reserveInput = new HashMap();
979                                 reserveInput.put("productStoreId", productStoreId);
980                                 reserveInput.put("productId", orderItem.getString("productId"));
981                                 reserveInput.put("orderId", orderItem.getString("orderId"));
982                                 reserveInput.put("orderItemSeqId", orderItem.getString("orderItemSeqId"));
983                                 reserveInput.put("shipGroupSeqId", orderItemShipGroupAssoc.getString("shipGroupSeqId"));
984                                 // use the quantity from the orderItemShipGroupAssoc, NOT the orderItem, these are reserved by item-group assoc
985
reserveInput.put("quantity", orderItemShipGroupAssoc.getDouble("quantity"));
986                                 reserveInput.put("userLogin", userLogin);
987                                 Map reserveResult = dispatcher.runSync("reserveStoreInventory", reserveInput);
988
989                                 if (ServiceUtil.isError(reserveResult)) {
990                                     GenericValue product = null;
991                                     try {
992                                         product = delegator.findByPrimaryKeyCache("Product", UtilMisc.toMap("productId", orderItem.getString("productId")));
993                                     } catch (GenericEntityException e) {
994                                         Debug.logError(e, "Error when looking up product in createOrder service, product failed inventory reservation", module);
995                                     }
996
997                                     String JavaDoc invErrMsg = "The product ";
998                                     if (product != null) {
999                                         invErrMsg += getProductName(product, orderItem);
1000                                    }
1001                                    invErrMsg += " with ID " + orderItem.getString("productId") + " is no longer in stock. Please try reducing the quantity or removing the product from this order.";
1002                                    resErrorMessages.add(invErrMsg);
1003                                }
1004                            } catch (GenericServiceException e) {
1005                                String JavaDoc errMsg = "Fatal error calling reserveStoreInventory service: " + e.toString();
1006                                Debug.logError(e, errMsg, module);
1007                                resErrorMessages.add(errMsg);
1008                            }
1009                        }
1010                    }
1011                }
1012            }
1013        }
1014    }
1015
1016    public static String JavaDoc getProductName(GenericValue product, GenericValue orderItem) {
1017        if (UtilValidate.isNotEmpty(product.getString("productName"))) {
1018            return product.getString("productName");
1019        } else {
1020            return orderItem.getString("itemDescription");
1021        }
1022    }
1023
1024    public static String JavaDoc getProductName(GenericValue product, String JavaDoc orderItemName) {
1025        if (UtilValidate.isNotEmpty(product.getString("productName"))) {
1026            return product.getString("productName");
1027        } else {
1028            return orderItemName;
1029        }
1030    }
1031
1032    public static String JavaDoc determineSingleFacilityFromOrder(GenericValue orderHeader) {
1033        if (orderHeader != null) {
1034            String JavaDoc productStoreId = orderHeader.getString("productStoreId");
1035            if (productStoreId != null) {
1036                return ProductStoreWorker.determineSingleFacilityForStore(orderHeader.getDelegator(), productStoreId);
1037            }
1038        }
1039        return null;
1040    }
1041
1042    /** Service for resetting the OrderHeader grandTotal */
1043    public static Map resetGrandTotal(DispatchContext ctx, Map context) {
1044        GenericDelegator delegator = ctx.getDelegator();
1045        //appears to not be used: GenericValue userLogin = (GenericValue) context.get("userLogin");
1046
String JavaDoc orderId = (String JavaDoc) context.get("orderId");
1047
1048        GenericValue orderHeader = null;
1049        try {
1050            orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId));
1051        } catch (GenericEntityException e) {
1052            String JavaDoc errMsg = "ERROR: Could not set grantTotal on OrderHeader entity: " + e.toString();
1053            Debug.logError(e, errMsg, module);
1054            return ServiceUtil.returnError(errMsg);
1055        }
1056
1057        if (orderHeader != null) {
1058            OrderReadHelper orh = new OrderReadHelper(orderHeader);
1059            Double JavaDoc currentTotal = orderHeader.getDouble("grandTotal");
1060            Double JavaDoc currentSubTotal = orderHeader.getDouble("remainingSubTotal");
1061
1062            // get the new grand total
1063
double updatedTotal = orh.getOrderGrandTotal();
1064
1065            // calculate subTotal as grandTotal - returnsTotal - (tax + shipping of items not returned)
1066
double remainingSubTotal = updatedTotal - orh.getOrderReturnedTotal() - orh.getOrderNonReturnedTaxAndShipping();
1067
1068            if (currentTotal == null || currentSubTotal == null || updatedTotal != currentTotal.doubleValue() ||
1069                    remainingSubTotal != currentSubTotal.doubleValue()) {
1070                orderHeader.set("grandTotal", UtilFormatOut.formatPriceNumber(updatedTotal));
1071                orderHeader.set("remainingSubTotal", UtilFormatOut.formatPriceNumber(remainingSubTotal));
1072                try {
1073                    orderHeader.store();
1074                } catch (GenericEntityException e) {
1075                    String JavaDoc errMsg = "ERROR: Could not set grandTotal on OrderHeader entity: " + e.toString();
1076                    Debug.logError(e, errMsg, module);
1077                    return ServiceUtil.returnError(errMsg);
1078                }
1079            }
1080        }
1081
1082        return ServiceUtil.returnSuccess();
1083    }
1084
1085    /** Service for setting the OrderHeader grandTotal for all OrderHeaders with no grandTotal */
1086    public static Map setEmptyGrandTotals(DispatchContext ctx, Map context) {
1087        GenericDelegator delegator = ctx.getDelegator();
1088        LocalDispatcher dispatcher = ctx.getDispatcher();
1089        GenericValue userLogin = (GenericValue) context.get("userLogin");
1090        Boolean JavaDoc forceAll = (Boolean JavaDoc) context.get("forceAll");
1091        Locale locale = (Locale) context.get("locale");
1092        if (forceAll == null) {
1093            forceAll = new Boolean JavaDoc(false);
1094        }
1095
1096        EntityCondition cond = null;
1097        if (!forceAll.booleanValue()) {
1098            List exprs = UtilMisc.toList(new EntityExpr("grandTotal", EntityOperator.EQUALS, null),
1099                    new EntityExpr("remainingSubTotal", EntityOperator.EQUALS, null));
1100            cond = new EntityConditionList(exprs, EntityOperator.OR);
1101        }
1102        List fields = UtilMisc.toList("orderId");
1103
1104        EntityListIterator eli = null;
1105        try {
1106            eli = delegator.findListIteratorByCondition("OrderHeader", cond, fields, null);
1107        } catch (GenericEntityException e) {
1108            Debug.logError(e, module);
1109            return ServiceUtil.returnError(e.getMessage());
1110        }
1111
1112        if (eli != null) {
1113            // reset each order
1114
GenericValue orderHeader = null;
1115            while ((orderHeader = (GenericValue) eli.next()) != null) {
1116                String JavaDoc orderId = orderHeader.getString("orderId");
1117                Map resetResult = null;
1118                try {
1119                    resetResult = dispatcher.runSync("resetGrandTotal", UtilMisc.toMap("orderId", orderId, "userLogin", userLogin));
1120                } catch (GenericServiceException e) {
1121                    Debug.logError(e, "ERROR: Cannot reset order totals - " + orderId, module);
1122                }
1123
1124                if (resetResult != null && ServiceUtil.isError(resetResult)) {
1125                    Debug.logWarning(UtilProperties.getMessage(resource_error,"OrderErrorCannotResetOrderTotals", UtilMisc.toMap("orderId",orderId,"resetResult",ServiceUtil.getErrorMessage(resetResult)), locale), module);
1126                }
1127            }
1128
1129            // close the ELI
1130
try {
1131                eli.close();
1132            } catch (GenericEntityException e) {
1133                Debug.logError(e, module);
1134            }
1135        } else {
1136            Debug.logInfo("No orders found for reset processing", module);
1137        }
1138
1139        return ServiceUtil.returnSuccess();
1140    }
1141
1142    /** Service for checking and re-calc the tax amount */
1143    public static Map recalcOrderTax(DispatchContext ctx, Map context) {
1144        LocalDispatcher dispatcher = ctx.getDispatcher();
1145        GenericDelegator delegator = ctx.getDelegator();
1146        String JavaDoc orderId = (String JavaDoc) context.get("orderId");
1147        GenericValue userLogin = (GenericValue) context.get("userLogin");
1148        Locale locale = (Locale) context.get("locale");
1149
1150        // check and make sure we have permission to change the order
1151
Security security = ctx.getSecurity();
1152        if (!security.hasEntityPermission("ORDERMGR", "_UPDATE", userLogin)) {
1153            GenericValue placingCustomer = null;
1154            try {
1155                Map placingCustomerFields = UtilMisc.toMap("orderId", orderId, "partyId", userLogin.getString("partyId"), "roleTypeId", "PLACING_CUSTOMER");
1156                placingCustomer = delegator.findByPrimaryKey("OrderRole", placingCustomerFields);
1157            } catch (GenericEntityException e) {
1158                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorCannotGetOrderRoleEntity ",locale) + e.getMessage());
1159            }
1160            if (placingCustomer == null)
1161                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderYouDoNotHavePermissionToChangeThisOrdersStatus",locale));
1162        }
1163
1164        // get the order header
1165
GenericValue orderHeader = null;
1166        try {
1167            orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId));
1168        } catch (GenericEntityException e) {
1169            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorCannotGetOrderHeaderEntity",locale) + e.getMessage());
1170        }
1171
1172        if (orderHeader == null) {
1173            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorNoValidOrderHeaderFoundForOrderId", UtilMisc.toMap("orderId",orderId), locale));
1174        }
1175
1176        // don't charge tax on purchase orders
1177
if ("PURCHASE_ORDER".equals(orderHeader.getString("orderTypeId"))) {
1178            return ServiceUtil.returnSuccess();
1179        }
1180
1181        // Retrieve the order tax adjustments
1182
List orderTaxAdjustments = null;
1183        try {
1184            orderTaxAdjustments = delegator.findByAnd("OrderAdjustment", UtilMisc.toMap("orderId", orderId, "orderAdjustmentTypeId", "SALES_TAX"));
1185        } catch( GenericEntityException e ) {
1186            Debug.logError(e, "Unable to retrieve SALES_TAX adjustments for order : " + orderId, module);
1187            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderUnableToRetrieveSalesTaxAdjustments",locale));
1188        }
1189
1190        // Accumulate the total existing tax adjustment
1191
BigDecimal JavaDoc totalExistingOrderTax = ZERO;
1192        Iterator otait = UtilMisc.toIterator(orderTaxAdjustments);
1193        while (otait != null && otait.hasNext()) {
1194            GenericValue orderTaxAdjustment = (GenericValue) otait.next();
1195            if( orderTaxAdjustment.get("amount") != null) {
1196                totalExistingOrderTax = totalExistingOrderTax.add(orderTaxAdjustment.getBigDecimal("amount").setScale(taxDecimals, taxRounding));
1197            }
1198        }
1199
1200        // Recalculate the taxes for the order
1201
BigDecimal JavaDoc totalNewOrderTax = ZERO;
1202        OrderReadHelper orh = new OrderReadHelper(orderHeader);
1203        List shipGroups = orh.getOrderItemShipGroups();
1204        if (shipGroups != null) {
1205            Iterator itr = shipGroups.iterator();
1206            while (itr.hasNext()) {
1207                GenericValue shipGroup = (GenericValue) itr.next();
1208                String JavaDoc shipGroupSeqId = shipGroup.getString("shipGroupSeqId");
1209
1210                List validOrderItems = orh.getValidOrderItems(shipGroupSeqId);
1211                if (validOrderItems != null) {
1212                    // prepare the inital lists
1213
List products = new ArrayList(validOrderItems.size());
1214                    List amounts = new ArrayList(validOrderItems.size());
1215                    List shipAmts = new ArrayList(validOrderItems.size());
1216                    List itPrices = new ArrayList(validOrderItems.size());
1217
1218                    // adjustments and total
1219
List allAdjustments = orh.getAdjustments();
1220                    List orderHeaderAdjustments = OrderReadHelper.getOrderHeaderAdjustments(allAdjustments, shipGroupSeqId);
1221                    double orderSubTotal = OrderReadHelper.getOrderItemsSubTotal(validOrderItems, allAdjustments);
1222
1223                    // shipping amount
1224
BigDecimal JavaDoc orderShipping = new BigDecimal JavaDoc(OrderReadHelper.calcOrderAdjustments(orderHeaderAdjustments, orderSubTotal, false, false, true));
1225
1226                    // build up the list of tax calc service parameters
1227
for (int i = 0; i < validOrderItems.size(); i++) {
1228                        GenericValue orderItem = (GenericValue) validOrderItems.get(i);
1229                        String JavaDoc productId = orderItem.getString("productId");
1230                        try {
1231                            products.add(i, delegator.findByPrimaryKey("Product", UtilMisc.toMap("productId", productId))); // get the product entity
1232
amounts.add(i, new BigDecimal JavaDoc(OrderReadHelper.getOrderItemSubTotal(orderItem, allAdjustments, true, false))); // get the item amount
1233
shipAmts.add(i, new BigDecimal JavaDoc(OrderReadHelper.getOrderItemAdjustmentsTotal(orderItem, allAdjustments, false, false, true))); // get the shipping amount
1234
itPrices.add(i, orderItem.getBigDecimal("unitPrice"));
1235                        } catch (GenericEntityException e) {
1236                            Debug.logError(e, "Cannot read order item entity : " + orderItem, module);
1237                            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderCannotReadTheOrderItemEntity",locale));
1238                        }
1239                    }
1240
1241                    GenericValue shippingAddress = orh.getShippingAddress(shipGroupSeqId);
1242                    if (shippingAddress == null) {
1243                        // face-to-face order; use the facility address
1244
String JavaDoc facilityId = orderHeader.getString("originFacilityId");
1245                        if (facilityId != null) {
1246                            List fcp = null;
1247                            try {
1248                                fcp = delegator.findByAnd("FacilityContactMechPurpose", UtilMisc.toMap("facilityId",
1249                                        facilityId, "contactMechPurposeTypeId", "SHIP_ORIG_LOCATION"));
1250                            } catch (GenericEntityException e) {
1251                                Debug.logError(e, module);
1252                            }
1253                            fcp = EntityUtil.filterByDate(fcp);
1254                            GenericValue purp = EntityUtil.getFirst(fcp);
1255                            if (purp != null) {
1256                                try {
1257                                    shippingAddress = delegator.findByPrimaryKey("PostalAddress",
1258                                            UtilMisc.toMap("contactMechId", purp.getString("contactMechId")));
1259                                } catch (GenericEntityException e) {
1260                                    Debug.logError(e, module);
1261                                }
1262                            }
1263                        }
1264                    }
1265
1266                    // prepare the service context
1267
// pass in BigDecimal values instead of Double
1268
Map serviceContext = UtilMisc.toMap("productStoreId", orh.getProductStoreId(), "itemProductList", products, "itemAmountList", amounts,
1269                        "itemShippingList", shipAmts, "itemPriceList", itPrices, "orderShippingAmount", orderShipping);
1270                    serviceContext.put("shippingAddress", shippingAddress);
1271                    if (orh.getBillToParty() != null) serviceContext.put("billToPartyId", orh.getBillToParty().getString("partyId"));
1272
1273                    // invoke the calcTax service
1274
Map serviceResult = null;
1275                    try {
1276                        serviceResult = dispatcher.runSync("calcTax", serviceContext);
1277                    } catch (GenericServiceException e) {
1278                        Debug.logError(e, module);
1279                        return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemOccurredInTaxService",locale));
1280                    }
1281
1282                    if (ServiceUtil.isError(serviceResult)) {
1283                        return ServiceUtil.returnError(ServiceUtil.getErrorMessage(serviceResult));
1284                    }
1285
1286                    // the adjustments (returned in order) from the tax service
1287
List orderAdj = (List) serviceResult.get("orderAdjustments");
1288                    List itemAdj = (List) serviceResult.get("itemAdjustments");
1289
1290                    // Accumulate the new tax total from the recalculated header adjustments
1291
if (orderAdj != null && orderAdj.size() > 0) {
1292                        Iterator oai = orderAdj.iterator();
1293                        while (oai.hasNext()) {
1294                            GenericValue oa = (GenericValue) oai.next();
1295                            if( oa.get("amount") != null) {
1296                                totalNewOrderTax = totalNewOrderTax.add(oa.getBigDecimal("amount").setScale(taxDecimals, taxRounding));
1297                            }
1298                        }
1299                    }
1300
1301                    // Accumulate the new tax total from the recalculated item adjustments
1302
if (itemAdj != null && itemAdj.size() > 0) {
1303                        for (int i = 0; i < itemAdj.size(); i++) {
1304                            GenericValue orderItem = (GenericValue) validOrderItems.get(i);
1305                            List itemAdjustments = (List) itemAdj.get(i);
1306                            Iterator ida = itemAdjustments.iterator();
1307                            while (ida.hasNext()) {
1308                                GenericValue ia = (GenericValue) ida.next();
1309                                if( ia.get("amount") != null) {
1310                                    totalNewOrderTax = totalNewOrderTax.add(ia.getBigDecimal("amount").setScale(taxDecimals, taxRounding));
1311                                }
1312                            }
1313                        }
1314                    }
1315                }
1316            }
1317
1318            // Determine the difference between existing and new tax adjustment totals, if any
1319
BigDecimal JavaDoc orderTaxDifference = totalNewOrderTax.subtract(totalExistingOrderTax).setScale(taxDecimals, taxRounding);
1320
1321            // If the total has changed, create an OrderAdjustment to reflect the fact
1322
if (orderTaxDifference.signum() != 0) {
1323                Map createOrderAdjContext = new HashMap();
1324                createOrderAdjContext.put("orderAdjustmentTypeId", "SALES_TAX");
1325                createOrderAdjContext.put("orderId", orderId);
1326                createOrderAdjContext.put("orderItemSeqId", "_NA_");
1327                createOrderAdjContext.put("shipGroupSeqId", "_NA_");
1328                createOrderAdjContext.put("description", "Tax adjustment due to order change");
1329                createOrderAdjContext.put("amount", new Double JavaDoc(orderTaxDifference.doubleValue()));
1330                createOrderAdjContext.put("amount", new Double JavaDoc(orderTaxDifference.doubleValue()));
1331                createOrderAdjContext.put("userLogin", userLogin);
1332                Map createOrderAdjResponse = null;
1333                try {
1334                    createOrderAdjResponse = dispatcher.runSync("createOrderAdjustment", createOrderAdjContext);
1335                } catch( GenericServiceException e ) {
1336                    String JavaDoc createOrderAdjErrMsg = UtilProperties.getMessage(resource_error, "OrderErrorCallingCreateOrderAdjustmentService", locale);
1337                    Debug.logError(createOrderAdjErrMsg, module);
1338                    return ServiceUtil.returnError(createOrderAdjErrMsg);
1339                }
1340                if (ServiceUtil.isError(createOrderAdjResponse)) {
1341                    Debug.logError(ServiceUtil.getErrorMessage(createOrderAdjResponse), module);
1342                    return ServiceUtil.returnError(ServiceUtil.getErrorMessage(createOrderAdjResponse));
1343                }
1344            }
1345        }
1346
1347        return ServiceUtil.returnSuccess();
1348    }
1349
1350    /** Service for checking and re-calc the shipping amount */
1351    public static Map recalcOrderShipping(DispatchContext ctx, Map context) {
1352        LocalDispatcher dispatcher = ctx.getDispatcher();
1353        GenericDelegator delegator = ctx.getDelegator();
1354        String JavaDoc orderId = (String JavaDoc) context.get("orderId");
1355        GenericValue userLogin = (GenericValue) context.get("userLogin");
1356        Locale locale = (Locale) context.get("locale");
1357
1358        // check and make sure we have permission to change the order
1359
Security security = ctx.getSecurity();
1360        if (!security.hasEntityPermission("ORDERMGR", "_UPDATE", userLogin)) {
1361            GenericValue placingCustomer = null;
1362            try {
1363                Map placingCustomerFields = UtilMisc.toMap("orderId", orderId, "partyId", userLogin.getString("partyId"), "roleTypeId", "PLACING_CUSTOMER");
1364                placingCustomer = delegator.findByPrimaryKey("OrderRole", placingCustomerFields);
1365            } catch (GenericEntityException e) {
1366                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorCannotGetOrderRoleEntity",locale) + e.getMessage());
1367            }
1368            if (placingCustomer == null)
1369                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderYouDoNotHavePermissionToChangeThisOrdersStatus",locale));
1370        }
1371
1372        // get the order header
1373
GenericValue orderHeader = null;
1374        try {
1375            orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId));
1376        } catch (GenericEntityException e) {
1377            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorCannotGetOrderHeaderEntity",locale) + e.getMessage());
1378        }
1379
1380        if (orderHeader == null) {
1381            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorNoValidOrderHeaderFoundForOrderId", UtilMisc.toMap("orderId",orderId), locale));
1382        }
1383
1384        OrderReadHelper orh = new OrderReadHelper(orderHeader);
1385        List shipGroups = orh.getOrderItemShipGroups();
1386        if (shipGroups != null) {
1387            Iterator i = shipGroups.iterator();
1388            while (i.hasNext()) {
1389                GenericValue shipGroup = (GenericValue) i.next();
1390                String JavaDoc shipGroupSeqId = shipGroup.getString("shipGroupSeqId");
1391
1392                if (shipGroup.get("contactMechId") == null || shipGroup.get("shipmentMethodTypeId") == null) {
1393                    // not shipped (face-to-face order)
1394
continue;
1395                }
1396
1397                Map shippingEstMap = ShippingEvents.getShipEstimate(dispatcher, delegator, orh, shipGroupSeqId);
1398                Double JavaDoc shippingTotal = null;
1399                if (orh.getValidOrderItems(shipGroupSeqId) == null || orh.getValidOrderItems(shipGroupSeqId).size() == 0) {
1400                    shippingTotal = new Double JavaDoc(0.00);
1401                    Debug.log("No valid order items found - " + shippingTotal, module);
1402                } else {
1403                    shippingTotal = (Double JavaDoc) shippingEstMap.get("shippingTotal");
1404                    Debug.log("Got new shipping estimate - " + shippingTotal, module);
1405                }
1406                if (Debug.infoOn()) {
1407                    Debug.log("New Shipping Total [" + orderId + " / " + shipGroupSeqId + "] : " + shippingTotal, module);
1408                }
1409
1410                double currentShipping = OrderReadHelper.getAllOrderItemsAdjustmentsTotal(orh.getOrderItemAndShipGroupAssoc(shipGroupSeqId), orh.getAdjustments(), false, false, true);
1411                currentShipping += OrderReadHelper.calcOrderAdjustments(orh.getOrderHeaderAdjustments(shipGroupSeqId), orh.getOrderItemsSubTotal(), false, false, true);
1412
1413                if (Debug.infoOn()) {
1414                    Debug.log("Old Shipping Total [" + orderId + " / " + shipGroupSeqId + "] : " + currentShipping, module);
1415                }
1416
1417                List errorMessageList = (List) shippingEstMap.get(ModelService.ERROR_MESSAGE_LIST);
1418                if (errorMessageList != null) {
1419                    return ServiceUtil.returnError(errorMessageList);
1420                }
1421
1422                if (shippingTotal.doubleValue() != currentShipping) {
1423                    // place the difference as a new shipping adjustment
1424
Double JavaDoc adjustmentAmount = new Double JavaDoc(shippingTotal.doubleValue() - currentShipping);
1425                    String JavaDoc adjSeqId = delegator.getNextSeqId("OrderAdjustment").toString();
1426                    GenericValue orderAdjustment = delegator.makeValue("OrderAdjustment", UtilMisc.toMap("orderAdjustmentId", adjSeqId));
1427                    orderAdjustment.set("orderAdjustmentTypeId", "SHIPPING_CHARGES");
1428                    orderAdjustment.set("amount", adjustmentAmount);
1429                    orderAdjustment.set("orderId", orh.getOrderId());
1430                    orderAdjustment.set("shipGroupSeqId", shipGroupSeqId);
1431                    orderAdjustment.set("orderItemSeqId", DataModelConstants.SEQ_ID_NA);
1432                    orderAdjustment.set("createdDate", UtilDateTime.nowTimestamp());
1433                    orderAdjustment.set("createdByUserLogin", userLogin.getString("userLoginId"));
1434                    //orderAdjustment.set("comments", "Shipping Re-Calc Adjustment");
1435
try {
1436                        orderAdjustment.create();
1437                    } catch (GenericEntityException e) {
1438                        Debug.logError(e, "Problem creating shipping re-calc adjustment : " + orderAdjustment, module);
1439                        return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorCannotCreateAdjustment",locale));
1440                    }
1441                }
1442
1443                // TODO: re-balance free shipping adjustment
1444
}
1445        }
1446
1447        return ServiceUtil.returnSuccess();
1448
1449    }
1450
1451    /** Service for checking to see if an order is fully completed or canceled */
1452    public static Map checkItemStatus(DispatchContext ctx, Map context) {
1453        GenericDelegator delegator = ctx.getDelegator();
1454        LocalDispatcher dispatcher = ctx.getDispatcher();
1455        Locale locale = (Locale) context.get("locale");
1456
1457        GenericValue userLogin = (GenericValue) context.get("userLogin");
1458        String JavaDoc orderId = (String JavaDoc) context.get("orderId");
1459
1460        // check and make sure we have permission to change the order
1461
Security security = ctx.getSecurity();
1462        if (!security.hasEntityPermission("ORDERMGR", "_UPDATE", userLogin)) {
1463            GenericValue placingCustomer = null;
1464            try {
1465                Map placingCustomerFields = UtilMisc.toMap("orderId", orderId, "partyId", userLogin.getString("partyId"), "roleTypeId", "PLACING_CUSTOMER");
1466                placingCustomer = delegator.findByPrimaryKey("OrderRole", placingCustomerFields);
1467            } catch (GenericEntityException e) {
1468                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorCannotGetOrderRoleEntity",locale) + e.getMessage());
1469            }
1470            if (placingCustomer == null) {
1471                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderYouDoNotHavePermissionToChangeThisOrdersStatus",locale));
1472            }
1473        }
1474
1475        // get the order header
1476
GenericValue orderHeader = null;
1477        try {
1478            orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId));
1479        } catch (GenericEntityException e) {
1480            Debug.logError(e, "Cannot get OrderHeader record", module);
1481        }
1482        if (orderHeader == null) {
1483            Debug.logError("OrderHeader came back as null", module);
1484            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderCannotUpdateNullOrderHeader",UtilMisc.toMap("orderId",orderId),locale));
1485        }
1486
1487        // get the order items
1488
List orderItems = null;
1489        try {
1490            orderItems = delegator.findByAnd("OrderItem", UtilMisc.toMap("orderId", orderId));
1491        } catch (GenericEntityException e) {
1492            Debug.logError(e, "Cannot get OrderItem records", module);
1493            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemGettingOrderItemRecords", locale));
1494        }
1495
1496        boolean allCanceled = true;
1497        boolean allComplete = true;
1498        boolean allApproved = true;
1499        if (orderItems != null) {
1500            Iterator itemIter = orderItems.iterator();
1501            while (itemIter.hasNext()) {
1502                GenericValue item = (GenericValue) itemIter.next();
1503                String JavaDoc statusId = item.getString("statusId");
1504                //Debug.log("Item Status: " + statusId, module);
1505
if (!"ITEM_CANCELLED".equals(statusId)) {
1506                    //Debug.log("Not set to cancel", module);
1507
allCanceled = false;
1508                    if (!"ITEM_COMPLETED".equals(statusId)) {
1509                        //Debug.log("Not set to complete", module);
1510
allComplete = false;
1511                        if (!"ITEM_APPROVED".equals(statusId)) {
1512                            //Debug.log("Not set to approve", module);
1513
allApproved = false;
1514                            break;
1515                        }
1516                    }
1517                }
1518            }
1519
1520            // find the next status to set to (if any)
1521
String JavaDoc newStatus = null;
1522            if (allCanceled) {
1523                newStatus = "ORDER_CANCELLED";
1524            } else if (allComplete) {
1525                newStatus = "ORDER_COMPLETED";
1526            } else if (allApproved) {
1527                if (!"ORDER_SENT".equals(orderHeader.getString("statusId"))) {
1528                    newStatus = "ORDER_APPROVED";
1529                }
1530            }
1531
1532            // now set the new order status
1533
if (newStatus != null) {
1534                Map serviceContext = UtilMisc.toMap("orderId", orderId, "statusId", newStatus, "userLogin", userLogin);
1535                Map newSttsResult = null;
1536                try {
1537                    newSttsResult = dispatcher.runSync("changeOrderStatus", serviceContext);
1538                } catch (GenericServiceException e) {
1539                    Debug.logError(e, "Problem calling the changeOrderStatus service", module);
1540                }
1541                if (ServiceUtil.isError(newSttsResult)) {
1542                    return ServiceUtil.returnError(ServiceUtil.getErrorMessage(newSttsResult));
1543                }
1544            }
1545        } else {
1546            Debug.logWarning(UtilProperties.getMessage(resource_error,"OrderReceivedNullForOrderItemRecordsOrderId", UtilMisc.toMap("orderId",orderId),locale), module);
1547        }
1548
1549        return ServiceUtil.returnSuccess();
1550    }
1551
1552    /** Service to cancel an order item quantity */
1553    public static Map cancelOrderItem(DispatchContext ctx, Map context) {
1554        LocalDispatcher dispatcher = ctx.getDispatcher();
1555        GenericDelegator delegator = ctx.getDelegator();
1556        Locale locale = (Locale) context.get("locale");
1557
1558        GenericValue userLogin = (GenericValue) context.get("userLogin");
1559        Double JavaDoc cancelQuantity = (Double JavaDoc) context.get("cancelQuantity");
1560        String JavaDoc orderId = (String JavaDoc) context.get("orderId");
1561        String JavaDoc orderItemSeqId = (String JavaDoc) context.get("orderItemSeqId");
1562        String JavaDoc shipGroupSeqId = (String JavaDoc) context.get("shipGroupSeqId");
1563
1564        // debugging message info
1565
String JavaDoc itemMsgInfo = orderId + " / " + orderItemSeqId + " / " + shipGroupSeqId;
1566
1567        // check and make sure we have permission to change the order
1568
Security security = ctx.getSecurity();
1569        if (!security.hasEntityPermission("ORDERMGR", "_UPDATE", userLogin)) {
1570            GenericValue placingCustomer = null;
1571            try {
1572                Map placingCustomerFields = UtilMisc.toMap("orderId", orderId, "partyId", userLogin.getString("partyId"), "roleTypeId", "PLACING_CUSTOMER");
1573                placingCustomer = delegator.findByPrimaryKey("OrderRole", placingCustomerFields);
1574            } catch (GenericEntityException e) {
1575                Debug.logError(e, module);
1576                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorCannotGetOrderRoleEntity", UtilMisc.toMap("itemMsgInfo",itemMsgInfo),locale));
1577            }
1578            if (placingCustomer == null)
1579                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderYouDoNotHavePermissionToChangeThisOrdersStatus",locale));
1580        }
1581
1582        Map fields = UtilMisc.toMap("orderId", orderId);
1583        if (orderItemSeqId != null) {
1584            fields.put("orderItemSeqId", orderItemSeqId);
1585        }
1586        if (shipGroupSeqId != null) {
1587            fields.put("shipGroupSeqId", shipGroupSeqId);
1588        }
1589
1590        List orderItemShipGroupAssocs = null;
1591        try {
1592            orderItemShipGroupAssocs = delegator.findByAnd("OrderItemShipGroupAssoc", fields);
1593        } catch (GenericEntityException e) {
1594            Debug.logError(e, module);
1595            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorCannotGetOrderItemAssocEntity", UtilMisc.toMap("itemMsgInfo",itemMsgInfo), locale));
1596        }
1597
1598        if (orderItemShipGroupAssocs != null) {
1599            if (orderItemShipGroupAssocs == null) {
1600                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorCannotCancelItemItemNotFound", UtilMisc.toMap("itemMsgInfo",itemMsgInfo), locale));
1601            }
1602
1603            Iterator i = orderItemShipGroupAssocs.iterator();
1604            while (i.hasNext()) {
1605                GenericValue orderItemShipGroupAssoc = (GenericValue) i.next();
1606                GenericValue orderItem = null;
1607                try {
1608                    orderItem = orderItemShipGroupAssoc.getRelatedOne("OrderItem");
1609                } catch (GenericEntityException e) {
1610                    Debug.logError(e, module);
1611                }
1612
1613                if (orderItem == null) {
1614                    return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorCannotCancelItemItemNotFound", UtilMisc.toMap("itemMsgInfo",itemMsgInfo), locale));
1615                }
1616
1617                Double JavaDoc availableQuantity = orderItemShipGroupAssoc.getDouble("quantity");
1618                Double JavaDoc itemQuantity = orderItem.getDouble("quantity");
1619                if (availableQuantity == null) availableQuantity = new Double JavaDoc(0.0);
1620                if (itemQuantity == null) itemQuantity = new Double JavaDoc(0.0);
1621
1622                Double JavaDoc thisCancelQty = null;
1623                if (cancelQuantity != null) {
1624                    thisCancelQty = new Double JavaDoc(cancelQuantity.doubleValue());
1625                } else {
1626                    thisCancelQty = new Double JavaDoc(availableQuantity.doubleValue());
1627                }
1628
1629                if (availableQuantity.doubleValue() >= thisCancelQty.doubleValue()) {
1630                    orderItem.set("cancelQuantity", thisCancelQty);
1631                    orderItemShipGroupAssoc.set("cancelQuantity", thisCancelQty);
1632
1633                    try {
1634                        List toStore = UtilMisc.toList(orderItem, orderItemShipGroupAssoc);
1635                        delegator.storeAll(toStore);
1636                    } catch (GenericEntityException e) {
1637                        Debug.logError(e, module);
1638                        return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderUnableToSetCancelQuantity", UtilMisc.toMap("itemMsgInfo",itemMsgInfo), locale));
1639                    }
1640
1641                    if (thisCancelQty.doubleValue() >= itemQuantity.doubleValue()) {
1642                        // all items are cancelled -- mark the item as cancelled
1643
Map statusCtx = UtilMisc.toMap("orderId", orderId, "orderItemSeqId", orderItemSeqId, "statusId", "ITEM_CANCELLED", "userLogin", userLogin);
1644                        try {
1645                            dispatcher.runSyncIgnore("changeOrderItemStatus", statusCtx);
1646                        } catch (GenericServiceException e) {
1647                            Debug.logError(e, module);
1648                            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderUnableToCancelOrderLine", UtilMisc.toMap("itemMsgInfo",itemMsgInfo), locale));
1649                        }
1650                    } else {
1651                        // reverse the inventory reservation
1652
Map invCtx = UtilMisc.toMap("orderId", orderId, "orderItemSeqId", orderItemSeqId, "shipGroupSeqId",
1653                                shipGroupSeqId, "cancelQuantity", thisCancelQty, "userLogin", userLogin);
1654                        try {
1655                            dispatcher.runSyncIgnore("cancelOrderItemInvResQty", invCtx);
1656                        } catch (GenericServiceException e) {
1657                            Debug.logError(e, module);
1658                            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderUnableToUpdateInventoryReservations", UtilMisc.toMap("itemMsgInfo",itemMsgInfo), locale));
1659                        }
1660                    }
1661                } else {
1662                    return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderInvalidCancelQuantityCannotCancel", UtilMisc.toMap("thisCancelQty",thisCancelQty), locale));
1663                }
1664            }
1665        }
1666
1667        return ServiceUtil.returnSuccess();
1668    }
1669
1670    /** Service for changing the status on order item(s) */
1671    public static Map setItemStatus(DispatchContext ctx, Map context) {
1672        GenericDelegator delegator = ctx.getDelegator();
1673
1674        GenericValue userLogin = (GenericValue) context.get("userLogin");
1675        String JavaDoc orderId = (String JavaDoc) context.get("orderId");
1676        String JavaDoc orderItemSeqId = (String JavaDoc) context.get("orderItemSeqId");
1677        String JavaDoc fromStatusId = (String JavaDoc) context.get("fromStatusId");
1678        String JavaDoc statusId = (String JavaDoc) context.get("statusId");
1679        Locale locale = (Locale) context.get("locale");
1680
1681        // check and make sure we have permission to change the order
1682
Security security = ctx.getSecurity();
1683        if (!security.hasEntityPermission("ORDERMGR", "_UPDATE", userLogin)) {
1684            GenericValue placingCustomer = null;
1685            try {
1686                Map placingCustomerFields = UtilMisc.toMap("orderId", orderId, "partyId", userLogin.getString("partyId"), "roleTypeId", "PLACING_CUSTOMER");
1687                placingCustomer = delegator.findByPrimaryKey("OrderRole", placingCustomerFields);
1688            } catch (GenericEntityException e) {
1689                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorCannotGetOrderRoleEntity",locale) + e.getMessage());
1690            }
1691            if (placingCustomer == null)
1692                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderYouDoNotHavePermissionToChangeThisOrdersStatus",locale));
1693        }
1694
1695        Map fields = UtilMisc.toMap("orderId", orderId);
1696        if (orderItemSeqId != null)
1697            fields.put("orderItemSeqId", orderItemSeqId);
1698        if (fromStatusId != null)
1699            fields.put("statusId", fromStatusId);
1700
1701        List orderItems = null;
1702        try {
1703            orderItems = delegator.findByAnd("OrderItem", fields);
1704        } catch (GenericEntityException e) {
1705            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorCannotGetOrderItemEntity ",locale) + e.getMessage());
1706        }
1707
1708        if (orderItems != null && orderItems.size() > 0) {
1709            List toBeStored = new ArrayList();
1710            Iterator itemsIterator = orderItems.iterator();
1711            while (itemsIterator.hasNext()) {
1712                GenericValue orderItem = (GenericValue) itemsIterator.next();
1713                if (orderItem == null) {
1714                    return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorCannotChangeItemStatusItemNotFound", locale));
1715                }
1716                if (Debug.verboseOn()) Debug.logVerbose("[OrderServices.setItemStatus] : Status Change: [" + orderId + "] (" + orderItem.getString("orderItemSeqId"), module);
1717                if (Debug.verboseOn()) Debug.logVerbose("[OrderServices.setItemStatus] : From Status : " + orderItem.getString("statusId"), module);
1718                if (Debug.verboseOn()) Debug.logVerbose("[OrderServices.setOrderStatus] : To Status : " + statusId, module);
1719
1720                if (orderItem.getString("statusId").equals(statusId)) {
1721                    continue;
1722                }
1723
1724                try {
1725                    Map statusFields = UtilMisc.toMap("statusId", orderItem.getString("statusId"), "statusIdTo", statusId);
1726                    GenericValue statusChange = delegator.findByPrimaryKeyCache("StatusValidChange", statusFields);
1727
1728                    if (statusChange == null) {
1729                        Debug.logWarning(UtilProperties.getMessage(resource_error,"OrderItemStatusNotChangedIsNotAValidChange", UtilMisc.toMap("orderStatusId",orderItem.getString("statusId"),"statusId",statusId), locale), module);
1730                        continue;
1731                    }
1732                } catch (GenericEntityException e) {
1733                    return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorCouldNotChangeItemStatus",locale) + e.getMessage());
1734                }
1735
1736                orderItem.set("statusId", statusId);
1737                toBeStored.add(orderItem);
1738
1739                // now create a status change
1740
Map changeFields = new HashMap();
1741                changeFields.put("orderStatusId", delegator.getNextSeqId("OrderStatus").toString());
1742                changeFields.put("statusId", statusId);
1743                changeFields.put("orderId", orderId);
1744                changeFields.put("orderItemSeqId", orderItem.getString("orderItemSeqId"));
1745                changeFields.put("statusDatetime", UtilDateTime.nowTimestamp());
1746                changeFields.put("statusUserLogin", userLogin.getString("userLoginId"));
1747                GenericValue orderStatus = delegator.makeValue("OrderStatus", changeFields);
1748                toBeStored.add(orderStatus);
1749            }
1750
1751            // store the changes
1752
if (toBeStored.size() > 0) {
1753                try {
1754                    delegator.storeAll(toBeStored);
1755                } catch (GenericEntityException e) {
1756                    return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorCannotStoreStatusChanges", locale) + e.getMessage());
1757                }
1758            }
1759
1760        }
1761
1762        return ServiceUtil.returnSuccess();
1763    }
1764
1765    /** Service for changing the status on an order header */
1766    public static Map setOrderStatus(DispatchContext ctx, Map context) {
1767        GenericDelegator delegator = ctx.getDelegator();
1768        GenericValue userLogin = (GenericValue) context.get("userLogin");
1769        String JavaDoc orderId = (String JavaDoc) context.get("orderId");
1770        String JavaDoc statusId = (String JavaDoc) context.get("statusId");
1771        Map successResult = ServiceUtil.returnSuccess();
1772        Locale locale = (Locale) context.get("locale");
1773
1774        // check and make sure we have permission to change the order
1775
Security security = ctx.getSecurity();
1776        if (!security.hasEntityPermission("ORDERMGR", "_UPDATE", userLogin)) {
1777            GenericValue placingCustomer = null;
1778            try {
1779                Map placingCustomerFields = UtilMisc.toMap("orderId", orderId, "partyId", userLogin.getString("partyId"), "roleTypeId", "PLACING_CUSTOMER");
1780                placingCustomer = delegator.findByPrimaryKey("OrderRole", placingCustomerFields);
1781            } catch (GenericEntityException e) {
1782                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorCannotGetOrderRoleEntity", locale) + e.getMessage());
1783            }
1784            if (placingCustomer == null)
1785                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderYouDoNotHavePermissionToChangeThisOrdersStatus",locale));
1786        }
1787
1788        try {
1789            GenericValue orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId));
1790
1791            if (orderHeader == null) {
1792                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorCouldNotChangeOrderStatusOrderCannotBeFound",locale));
1793            }
1794            // first save off the old status
1795
successResult.put("oldStatusId", orderHeader.get("statusId"));
1796
1797            if (Debug.verboseOn()) Debug.logVerbose("[OrderServices.setOrderStatus] : From Status : " + orderHeader.getString("statusId"), module);
1798            if (Debug.verboseOn()) Debug.logVerbose("[OrderServices.setOrderStatus] : To Status : " + statusId, module);
1799
1800            if (orderHeader.getString("statusId").equals(statusId)) {
1801                Debug.logWarning(UtilProperties.getMessage(resource_error,"OrderTriedToSetOrderStatusWithTheSameStatusIdforOrderWithId", UtilMisc.toMap("statusId",statusId,"orderId",orderId),locale),module);
1802                return successResult;
1803            }
1804            try {
1805                Map statusFields = UtilMisc.toMap("statusId", orderHeader.getString("statusId"), "statusIdTo", statusId);
1806                GenericValue statusChange = delegator.findByPrimaryKeyCache("StatusValidChange", statusFields);
1807                if (statusChange == null) {
1808                    return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorCouldNotChangeOrderStatusStatusIsNotAValidChange",locale));
1809                }
1810            } catch (GenericEntityException e) {
1811                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorCouldNotChangeOrderStatus",locale) + e.getMessage() + ").");
1812            }
1813
1814            // update the current status
1815
orderHeader.set("statusId", statusId);
1816
1817            // now create a status change
1818
GenericValue orderStatus = delegator.makeValue("OrderStatus", null);
1819            orderStatus.put("orderStatusId", delegator.getNextSeqId("OrderStatus"));
1820            orderStatus.put("statusId", statusId);
1821            orderStatus.put("orderId", orderId);
1822            orderStatus.put("statusDatetime", UtilDateTime.nowTimestamp());
1823            orderStatus.put("statusUserLogin", userLogin.getString("userLoginId"));
1824
1825            orderHeader.store();
1826            orderStatus.create();
1827
1828            successResult.put("needsInventoryIssuance", orderHeader.get("needsInventoryIssuance"));
1829            successResult.put("grandTotal", orderHeader.get("grandTotal"));
1830            successResult.put("orderTypeId", orderHeader.get("orderTypeId"));
1831            //Debug.logInfo("For setOrderStatus orderHeader is " + orderHeader, module);
1832
} catch (GenericEntityException e) {
1833            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorCouldNotChangeOrderStatus",locale) + e.getMessage() + ").");
1834        }
1835
1836        // release the inital hold if we are cancelled or approved
1837
if ("ORDER_CANCELLED".equals(statusId) || "ORDER_APPROVED".equals(statusId)) {
1838            OrderChangeHelper.releaseInitialOrderHold(ctx.getDispatcher(), orderId);
1839
1840            // cancel any order processing if we are cancelled
1841
if ("ORDER_CANCELLED".equals(statusId)) {
1842                OrderChangeHelper.abortOrderProcessing(ctx.getDispatcher(), orderId);
1843            }
1844        }
1845
1846        successResult.put("orderStatusId", statusId);
1847        //Debug.logInfo("For setOrderStatus successResult is " + successResult, module);
1848
return successResult;
1849    }
1850
1851    /** Service to update the order tracking number */
1852    public static Map updateTrackingNumber(DispatchContext dctx, Map context) {
1853        Map result = new HashMap();
1854        GenericDelegator delegator = dctx.getDelegator();
1855        String JavaDoc orderId = (String JavaDoc) context.get("orderId");
1856        String JavaDoc shipGroupSeqId = (String JavaDoc) context.get("shipGroupSeqId");
1857        String JavaDoc trackingNumber = (String JavaDoc) context.get("trackingNumber");
1858        //Locale locale = (Locale) context.get("locale");
1859

1860        try {
1861            GenericValue shipGroup = delegator.findByPrimaryKey("OrderItemShipGroup", UtilMisc.toMap("orderId", orderId, "shipGroupSeqId", shipGroupSeqId));
1862
1863            if (shipGroup == null) {
1864                result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
1865                result.put(ModelService.ERROR_MESSAGE, "ERROR: No order shipment preference found!");
1866            } else {
1867                shipGroup.set("trackingNumber", trackingNumber);
1868                shipGroup.store();
1869                result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS);
1870            }
1871        } catch (GenericEntityException e) {
1872            Debug.logError(e, module);
1873            result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
1874            result.put(ModelService.ERROR_MESSAGE, "ERROR: Could not set tracking number (" + e.getMessage() + ").");
1875        }
1876        return result;
1877    }
1878
1879    /** Service to add a role type to an order */
1880    public static Map addRoleType(DispatchContext ctx, Map context) {
1881        Map result = new HashMap();
1882        GenericDelegator delegator = ctx.getDelegator();
1883        String JavaDoc orderId = (String JavaDoc) context.get("orderId");
1884        String JavaDoc partyId = (String JavaDoc) context.get("partyId");
1885        String JavaDoc roleTypeId = (String JavaDoc) context.get("roleTypeId");
1886        Boolean JavaDoc removeOld = (Boolean JavaDoc) context.get("removeOld");
1887        //Locale locale = (Locale) context.get("locale");
1888

1889        if (removeOld != null && removeOld.booleanValue()) {
1890            try {
1891                delegator.removeByAnd("OrderRole", UtilMisc.toMap("orderId", orderId, "roleTypeId", roleTypeId));
1892            } catch (GenericEntityException e) {
1893                result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
1894                result.put(ModelService.ERROR_MESSAGE, "ERROR: Could not remove old roles (" + e.getMessage() + ").");
1895                return result;
1896            }
1897        }
1898
1899        Map fields = UtilMisc.toMap("orderId", orderId, "partyId", partyId, "roleTypeId", roleTypeId);
1900
1901        try {
1902            // first check and see if we are already there; if so, just return success
1903
GenericValue testValue = delegator.findByPrimaryKey("OrderRole", fields);
1904            if (testValue != null) {
1905                ServiceUtil.returnSuccess();
1906            } else {
1907                GenericValue value = delegator.makeValue("OrderRole", fields);
1908                delegator.create(value);
1909            }
1910        } catch (GenericEntityException e) {
1911            result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
1912            result.put(ModelService.ERROR_MESSAGE, "ERROR: Could not add role to order (" + e.getMessage() + ").");
1913            return result;
1914        }
1915        result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS);
1916        return result;
1917    }
1918
1919    /** Service to remove a role type from an order */
1920    public static Map removeRoleType(DispatchContext ctx, Map context) {
1921        Map result = new HashMap();
1922        GenericDelegator delegator = ctx.getDelegator();
1923        String JavaDoc orderId = (String JavaDoc) context.get("orderId");
1924        String JavaDoc partyId = (String JavaDoc) context.get("partyId");
1925        String JavaDoc roleTypeId = (String JavaDoc) context.get("roleTypeId");
1926        Map fields = UtilMisc.toMap("orderId", orderId, "partyId", partyId, "roleTypeId", roleTypeId);
1927        //Locale locale = (Locale) context.get("locale");
1928

1929        GenericValue testValue = null;
1930
1931        try {
1932            testValue = delegator.findByPrimaryKey("OrderRole", fields);
1933        } catch (GenericEntityException e) {
1934            result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
1935            result.put(ModelService.ERROR_MESSAGE, "ERROR: Could not add role to order (" + e.getMessage() + ").");
1936            return result;
1937        }
1938
1939        if (testValue == null) {
1940            result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS);
1941            return result;
1942        }
1943
1944        try {
1945            GenericValue value = delegator.findByPrimaryKey("OrderRole", fields);
1946
1947            value.remove();
1948        } catch (GenericEntityException e) {
1949            result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
1950            result.put(ModelService.ERROR_MESSAGE, "ERROR: Could not remove role from order (" + e.getMessage() + ").");
1951            return result;
1952        }
1953        result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS);
1954        return result;
1955    }
1956
1957    /** Service to email a customer with initial order confirmation */
1958    public static Map sendOrderConfirmNotification(DispatchContext ctx, Map context) {
1959        return sendOrderNotificationScreen(ctx, context, "PRDS_ODR_CONFIRM");
1960    }
1961
1962    /** Service to email a customer with order changes */
1963    public static Map sendOrderCompleteNotification(DispatchContext ctx, Map context) {
1964        return sendOrderNotificationScreen(ctx, context, "PRDS_ODR_COMPLETE");
1965    }
1966
1967    /** Service to email a customer with order changes */
1968    public static Map sendOrderBackorderNotification(DispatchContext ctx, Map context) {
1969        return sendOrderNotificationScreen(ctx, context, "PRDS_ODR_BACKORDER");
1970    }
1971
1972    /** Service to email a customer with order changes */
1973    public static Map sendOrderChangeNotification(DispatchContext ctx, Map context) {
1974        return sendOrderNotificationScreen(ctx, context, "PRDS_ODR_CHANGE");
1975    }
1976
1977    /** Service to email a customer with order payment retry results */
1978    public static Map sendOrderPayRetryNotification(DispatchContext ctx, Map context) {
1979        return sendOrderNotificationScreen(ctx, context, "PRDS_ODR_PAYRETRY");
1980    }
1981
1982    protected static Map sendOrderNotificationScreen(DispatchContext dctx, Map context, String JavaDoc emailType) {
1983        LocalDispatcher dispatcher = dctx.getDispatcher();
1984        GenericDelegator delegator = dctx.getDelegator();
1985        GenericValue userLogin = (GenericValue) context.get("userLogin");
1986        String JavaDoc orderId = (String JavaDoc) context.get("orderId");
1987        String JavaDoc orderItemSeqId = (String JavaDoc) context.get("orderItemSeqId");
1988        String JavaDoc sendTo = (String JavaDoc) context.get("sendTo");
1989        String JavaDoc sendCc = (String JavaDoc) context.get("sendCc");
1990        String JavaDoc note = (String JavaDoc) context.get("note");
1991        String JavaDoc screenUri = (String JavaDoc) context.get("screenUri");
1992
1993        // prepare the order information
1994
Map sendMap = FastMap.newInstance();
1995
1996        // get the order header and store
1997
GenericValue orderHeader = null;
1998        try {
1999            orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId));
2000        } catch (GenericEntityException e) {
2001            Debug.logError(e, "Problem getting OrderHeader", module);
2002        }
2003
2004        if (orderHeader == null) {
2005            return ServiceUtil.returnFailure("Could not find OrderHeader with ID [" + orderId + "]");
2006        }
2007
2008        GenericValue productStoreEmail = null;
2009        try {
2010            productStoreEmail = delegator.findByPrimaryKey("ProductStoreEmailSetting", UtilMisc.toMap("productStoreId", orderHeader.get("productStoreId"), "emailType", emailType));
2011        } catch (GenericEntityException e) {
2012            Debug.logError(e, "Problem getting the ProductStoreEmailSetting for productStoreId=" + orderHeader.get("productStoreId") + " and emailType=" + emailType, module);
2013        }
2014        if (productStoreEmail == null) {
2015            return ServiceUtil.returnFailure("No valid email setting for store with productStoreId=" + orderHeader.get("productStoreId") + " and emailType=" + emailType);
2016        }
2017
2018        // the override screenUri
2019
if (UtilValidate.isEmpty(screenUri)) {
2020            String JavaDoc bodyScreenLocation = productStoreEmail.getString("bodyScreenLocation");
2021            if (UtilValidate.isEmpty(bodyScreenLocation)) {
2022                bodyScreenLocation = ProductStoreWorker.getDefaultProductStoreEmailScreenLocation(emailType);
2023            }
2024            sendMap.put("bodyScreenUri", bodyScreenLocation);
2025            String JavaDoc xslfoAttachScreenLocation = productStoreEmail.getString("xslfoAttachScreenLocation");
2026            sendMap.put("xslfoAttachScreenLocation", xslfoAttachScreenLocation);
2027        } else {
2028            sendMap.put("bodyScreenUri", screenUri);
2029        }
2030
2031        // website
2032
sendMap.put("webSiteId", orderHeader.get("webSiteId"));
2033
2034        OrderReadHelper orh = new OrderReadHelper(orderHeader);
2035        String JavaDoc emailString = orh.getOrderEmailString();
2036        if (UtilValidate.isEmpty(emailString)) {
2037            Debug.logInfo("Customer is not setup to receive emails; no address(s) found [" + orderId + "]", module);
2038            return ServiceUtil.returnError("No sendTo email address found");
2039        }
2040
2041        // where to get the locale... from PLACING_CUSTOMER's UserLogin.lastLocale,
2042
// or if not available then from ProductStore.defaultLocaleString
2043
// or if not available then the system Locale
2044
Locale locale = null;
2045        GenericValue placingParty = orh.getPlacingParty();
2046        GenericValue placingUserLogin = placingParty == null ? null : PartyWorker.findPartyLatestUserLogin(placingParty.getString("partyId"), delegator);
2047        if (locale == null && placingParty != null) {
2048            locale = PartyWorker.findPartyLastLocale(placingParty.getString("partyId"), delegator);
2049        }
2050        GenericValue productStore = OrderReadHelper.getProductStoreFromOrder(orderHeader);
2051        if (locale == null && productStore != null) {
2052            String JavaDoc localeString = productStore.getString("defaultLocaleString");
2053            if (UtilValidate.isNotEmpty(localeString)) {
2054                locale = UtilMisc.parseLocale(localeString);
2055            }
2056        }
2057        if (locale == null) {
2058            locale = Locale.getDefault();
2059        }
2060
2061        ResourceBundleMapWrapper uiLabelMap = (ResourceBundleMapWrapper) UtilProperties.getResourceBundleMap("EcommerceUiLabels", locale);
2062        uiLabelMap.addBottomResourceBundle("OrderUiLabels");
2063        uiLabelMap.addBottomResourceBundle("CommonUiLabels");
2064
2065        Map bodyParameters = UtilMisc.toMap("orderId", orderId, "orderItemSeqId", orderItemSeqId, "userLogin", placingUserLogin, "uiLabelMap", uiLabelMap, "locale", locale);
2066        if( placingParty!= null) {
2067            bodyParameters.put("partyId", placingParty.get("partyId"));
2068        }
2069        bodyParameters.put("note", note);
2070        sendMap.put("bodyParameters", bodyParameters);
2071        sendMap.put("userLogin",userLogin);
2072
2073        String JavaDoc subjectString = productStoreEmail.getString("subject");
2074        sendMap.put("subject", subjectString);
2075
2076        sendMap.put("contentType", productStoreEmail.get("contentType"));
2077        sendMap.put("sendFrom", productStoreEmail.get("fromAddress"));
2078        sendMap.put("sendCc", productStoreEmail.get("ccAddress"));
2079        sendMap.put("sendBcc", productStoreEmail.get("bccAddress"));
2080        if ((sendTo != null) && UtilValidate.isEmail(sendTo)) {
2081            sendMap.put("sendTo", sendTo);
2082        } else {
2083            sendMap.put("sendTo", emailString);
2084        }
2085        if ((sendCc != null) && UtilValidate.isEmail(sendCc)) {
2086            sendMap.put("sendCc", sendCc);
2087        } else {
2088            sendMap.put("sendCc", productStoreEmail.get("ccAddress"));
2089        }
2090
2091        // send the notification
2092
Map sendResp = null;
2093        try {
2094            sendResp = dispatcher.runSync("sendMailFromScreen", sendMap);
2095        } catch (Exception JavaDoc e) {
2096            Debug.logError(e, module);
2097            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderServiceExceptionSeeLogs",locale));
2098        }
2099
2100        // check for errors
2101
if (sendResp != null && !ServiceUtil.isError(sendResp)) {
2102            sendResp.put("emailType", emailType);
2103        }
2104        return sendResp;
2105    }
2106
2107    /** Service to email order notifications for pending actions */
2108    public static Map sendProcessNotification(DispatchContext ctx, Map context) {
2109        //appears to not be used: Map result = new HashMap();
2110
GenericDelegator delegator = ctx.getDelegator();
2111        LocalDispatcher dispatcher = ctx.getDispatcher();
2112        String JavaDoc adminEmailList = (String JavaDoc) context.get("adminEmailList");
2113        String JavaDoc assignedToUser = (String JavaDoc) context.get("assignedPartyId");
2114        //appears to not be used: String assignedToRole = (String) context.get("assignedRoleTypeId");
2115
String JavaDoc workEffortId = (String JavaDoc) context.get("workEffortId");
2116        Locale locale = (Locale) context.get("locale");
2117
2118        GenericValue workEffort = null;
2119        GenericValue orderHeader = null;
2120        //appears to not be used: String assignedEmail = null;
2121

2122        // get the order/workflow info
2123
try {
2124            workEffort = delegator.findByPrimaryKey("WorkEffort", UtilMisc.toMap("workEffortId", workEffortId));
2125            String JavaDoc sourceReferenceId = workEffort.getString("sourceReferenceId");
2126            if (sourceReferenceId != null)
2127                orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", sourceReferenceId));
2128        } catch (GenericEntityException e) {
2129            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemWithEntityLookup", locale));
2130        }
2131
2132        // find the assigned user's email address(s)
2133
GenericValue party = null;
2134        Collection assignedToEmails = null;
2135        try {
2136            party = delegator.findByPrimaryKey("Party", UtilMisc.toMap("partyId", assignedToUser));
2137        } catch (GenericEntityException e) {
2138            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemWithEntityLookup", locale));
2139        }
2140        if (party != null)
2141            assignedToEmails = ContactHelper.getContactMechByPurpose(party, "PRIMARY_EMAIL", false);
2142
2143        Map templateData = new HashMap(context);
2144        String JavaDoc omgStatusId = WfUtil.getOMGStatus(workEffort.getString("currentStatusId"));
2145        templateData.putAll(orderHeader);
2146        templateData.putAll(workEffort);
2147        templateData.put("omgStatusId", omgStatusId);
2148
2149        // get the assignments
2150
List assignments = null;
2151        if (workEffort != null) {
2152            try {
2153                assignments = workEffort.getRelated("WorkEffortPartyAssignment");
2154            } catch (GenericEntityException e1) {
2155                Debug.logError(e1, "Problems getting assignements", module);
2156            }
2157        }
2158        templateData.put("assignments", assignments);
2159
2160        StringBuffer JavaDoc emailList = new StringBuffer JavaDoc();
2161        if (assignedToEmails != null) {
2162            Iterator aei = assignedToEmails.iterator();
2163            while (aei.hasNext()) {
2164                GenericValue ct = (GenericValue) aei.next();
2165                if (ct != null && ct.get("infoString") != null) {
2166                    if (emailList.length() > 1)
2167                        emailList.append(",");
2168                    emailList.append(ct.getString("infoString"));
2169                }
2170            }
2171        }
2172        if (adminEmailList != null) {
2173            if (emailList.length() > 1)
2174                emailList.append(",");
2175            emailList.append(adminEmailList);
2176        }
2177
2178        // prepare the mail info
2179
String JavaDoc ofbizHome = System.getProperty("ofbiz.home");
2180        String JavaDoc templateName = ofbizHome + "/applications/order/email/default/emailprocessnotify.ftl";
2181
2182        Map sendMailContext = new HashMap();
2183        sendMailContext.put("sendTo", emailList.toString());
2184        sendMailContext.put("sendFrom", "workflow@ofbiz.org"); // fixme
2185
sendMailContext.put("subject", "Workflow Notification");
2186        sendMailContext.put("templateName", templateName);
2187        sendMailContext.put("templateData", templateData);
2188
2189        try {
2190            dispatcher.runAsync("sendGenericNotificationEmail", sendMailContext);
2191        } catch (GenericServiceException e) {
2192            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderSendMailServiceFailed", locale) + e.getMessage());
2193        }
2194        return ServiceUtil.returnSuccess();
2195    }
2196
2197    /** Service to create an order payment preference */
2198    public static Map createPaymentPreference(DispatchContext ctx, Map context) {
2199        Map result = new HashMap();
2200        GenericDelegator delegator = ctx.getDelegator();
2201        String JavaDoc orderId = (String JavaDoc) context.get("orderId");
2202        String JavaDoc paymentMethodTypeId = (String JavaDoc) context.get("paymentMethodTypeId");
2203        String JavaDoc paymentMethodId = (String JavaDoc) context.get("paymentMethodId");
2204        Double JavaDoc maxAmount = (Double JavaDoc) context.get("maxAmount");
2205        GenericValue userLogin = (GenericValue) context.get("userLogin");
2206        Locale locale = (Locale) context.get("locale");
2207
2208        String JavaDoc prefId = null;
2209
2210        try {
2211            prefId = delegator.getNextSeqId("OrderPaymentPreference");
2212        } catch (IllegalArgumentException JavaDoc e) {
2213            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorCouldNotCreateOrderPaymentPreferenceIdGenerationFailure", locale));
2214        }
2215
2216        Map fields = UtilMisc.toMap("orderPaymentPreferenceId", prefId, "orderId", orderId, "paymentMethodTypeId",
2217                paymentMethodTypeId, "paymentMethodId", paymentMethodId, "maxAmount", maxAmount);
2218
2219        try {
2220            GenericValue v = delegator.makeValue("OrderPaymentPreference", fields);
2221            v.set("createdDate", UtilDateTime.nowTimestamp());
2222            if (userLogin != null) {
2223                v.set("createdByUserLogin", userLogin.getString("userLoginId"));
2224            }
2225            delegator.create(v);
2226        } catch (GenericEntityException e) {
2227            result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
2228            result.put(ModelService.ERROR_MESSAGE, "ERROR: Could not create OrderPaymentPreference (" + e.getMessage() + ").");
2229            return result;
2230        }
2231        result.put("orderPaymentPreferenceId", prefId);
2232        result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS);
2233        return result;
2234    }
2235
2236    /** Service to get order header information as standard results. */
2237    public static Map getOrderHeaderInformation(DispatchContext dctx, Map context) {
2238        GenericDelegator delegator = dctx.getDelegator();
2239        String JavaDoc orderId = (String JavaDoc) context.get("orderId");
2240        Locale locale = (Locale) context.get("locale");
2241
2242        GenericValue orderHeader = null;
2243        try {
2244            orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId));
2245        } catch (GenericEntityException e) {
2246            Debug.logError(e, "Problem getting order header detial", module);
2247            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderCannotGetOrderHeader ", locale) + e.getMessage());
2248        }
2249        if (orderHeader != null) {
2250            Map result = ServiceUtil.returnSuccess();
2251            result.putAll(orderHeader);
2252            return result;
2253        }
2254        return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorGettingOrderHeaderInformationNull", locale));
2255    }
2256
2257    /** Service to get the total shipping for an order. */
2258    public static Map getOrderShippingAmount(DispatchContext dctx, Map context) {
2259        GenericDelegator delegator = dctx.getDelegator();
2260        String JavaDoc orderId = (String JavaDoc) context.get("orderId");
2261        Locale locale = (Locale) context.get("locale");
2262
2263        GenericValue orderHeader = null;
2264        try {
2265            orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId));
2266        } catch (GenericEntityException e) {
2267            Debug.logError(e, module);
2268            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorCouldNotGetOrderInformation", locale) + e.getMessage() + ").");
2269        }
2270
2271        Map result = null;
2272        if (orderHeader != null) {
2273            OrderReadHelper orh = new OrderReadHelper(orderHeader);
2274            List orderItems = orh.getValidOrderItems();
2275            List orderAdjustments = orh.getAdjustments();
2276            List orderHeaderAdjustments = orh.getOrderHeaderAdjustments();
2277            double orderSubTotal = orh.getOrderItemsSubTotal();
2278
2279            double shippingAmount = OrderReadHelper.getAllOrderItemsAdjustmentsTotal(orderItems, orderAdjustments, false, false, true);
2280            shippingAmount += OrderReadHelper.calcOrderAdjustments(orderHeaderAdjustments, orderSubTotal, false, false, true);
2281
2282            result = ServiceUtil.returnSuccess();
2283            result.put("shippingAmount", new Double JavaDoc(shippingAmount));
2284        } else {
2285            result = ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderUnableToFindOrderHeaderCannotGetShippingAmount", locale));
2286        }
2287        return result;
2288    }
2289
2290    /** Service to get an order contact mech. */
2291    public static Map getOrderAddress(DispatchContext dctx, Map context) {
2292        Map result = new HashMap();
2293        GenericDelegator delegator = dctx.getDelegator();
2294
2295        String JavaDoc orderId = (String JavaDoc) context.get("orderId");
2296        //appears to not be used: GenericValue v = null;
2297
String JavaDoc purpose[] = { "BILLING_LOCATION", "SHIPPING_LOCATION" };
2298        String JavaDoc outKey[] = { "billingAddress", "shippingAddress" };
2299        GenericValue orderHeader = null;
2300        //Locale locale = (Locale) context.get("locale");
2301

2302        try {
2303            orderHeader = delegator.findByPrimaryKeyCache("OrderHeader", UtilMisc.toMap("orderId", orderId));
2304            if (orderHeader != null)
2305                result.put("orderHeader", orderHeader);
2306        } catch (GenericEntityException e) {
2307            result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
2308            result.put(ModelService.ERROR_MESSAGE, "ERROR: Could not get OrderHeader (" + e.getMessage() + ").");
2309            return result;
2310        }
2311        if (orderHeader == null) {
2312            result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
2313            result.put(ModelService.ERROR_MESSAGE, "ERROR: Could get the OrderHeader.");
2314            return result;
2315        }
2316        for (int i = 0; i < purpose.length; i++) {
2317            try {
2318                GenericValue orderContactMech = EntityUtil.getFirst(orderHeader.getRelatedByAnd("OrderContactMech",
2319                            UtilMisc.toMap("contactMechPurposeTypeId", purpose[i])));
2320                GenericValue contactMech = orderContactMech.getRelatedOne("ContactMech");
2321
2322                if (contactMech != null) {
2323                    result.put(outKey[i], contactMech.getRelatedOne("PostalAddress"));
2324                }
2325            } catch (GenericEntityException e) {
2326                result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
2327                result.put(ModelService.ERROR_MESSAGE, "ERROR: Problems getting contact mech (" + e.getMessage() + ").");
2328                return result;
2329            }
2330        }
2331
2332        result.put("orderId", orderId);
2333        return result;
2334    }
2335
2336    /** Service to create a order header note. */
2337    public static Map createOrderNote(DispatchContext dctx, Map context) {
2338        Map result = new HashMap();
2339        GenericDelegator delegator = dctx.getDelegator();
2340        LocalDispatcher dispatcher = dctx.getDispatcher();
2341        GenericValue userLogin = (GenericValue) context.get("userLogin");
2342        String JavaDoc noteString = (String JavaDoc) context.get("note");
2343        String JavaDoc orderId = (String JavaDoc) context.get("orderId");
2344        String JavaDoc internalNote = (String JavaDoc) context.get("internalNote");
2345        Map noteCtx = UtilMisc.toMap("note", noteString, "userLogin", userLogin);
2346        Locale locale = (Locale) context.get("locale");
2347
2348        try {
2349            // Store the note.
2350
Map noteRes = dispatcher.runSync("createNote", noteCtx);
2351
2352            if (ServiceUtil.isError(noteRes))
2353                return noteRes;
2354
2355            String JavaDoc noteId = (String JavaDoc) noteRes.get("noteId");
2356
2357            if (noteId == null || noteId.length() == 0) {
2358                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemCreatingTheNoteNoNoteIdReturned", locale));
2359            }
2360
2361            // Set the order info
2362
Map fields = UtilMisc.toMap("orderId", orderId, "noteId", noteId, "internalNote", internalNote);
2363            GenericValue v = delegator.makeValue("OrderHeaderNote", fields);
2364
2365            delegator.create(v);
2366        } catch (GenericEntityException ee) {
2367            Debug.logError(ee, module);
2368            result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
2369            result.put(ModelService.ERROR_MESSAGE, "Problem associating note with order (" + ee.getMessage() + ").");
2370        } catch (GenericServiceException se) {
2371            Debug.logError(se, module);
2372            result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
2373            result.put(ModelService.ERROR_MESSAGE, "Problem associating note with order (" + se.getMessage() + ").");
2374        }
2375                
2376        return result;
2377    }
2378
2379    public static Map allowOrderSplit(DispatchContext ctx, Map context) {
2380        GenericDelegator delegator = ctx.getDelegator();
2381        GenericValue userLogin = (GenericValue) context.get("userLogin");
2382        String JavaDoc orderId = (String JavaDoc) context.get("orderId");
2383        String JavaDoc shipGroupSeqId = (String JavaDoc) context.get("shipGroupSeqId");
2384        Locale locale = (Locale) context.get("locale");
2385
2386        // check and make sure we have permission to change the order
2387
Security security = ctx.getSecurity();
2388        if (!security.hasEntityPermission("ORDERMGR", "_UPDATE", userLogin)) {
2389            GenericValue placingCustomer = null;
2390            try {
2391                Map placingCustomerFields = UtilMisc.toMap("orderId", orderId, "partyId", userLogin.getString("partyId"), "roleTypeId", "PLACING_CUSTOMER");
2392                placingCustomer = delegator.findByPrimaryKey("OrderRole", placingCustomerFields);
2393            } catch (GenericEntityException e) {
2394                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorCannotGetOrderRoleEntity", locale) + e.getMessage());
2395            }
2396            if (placingCustomer == null) {
2397                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderYouDoNotHavePermissionToChangeThisOrdersStatus", locale));
2398            }
2399        }
2400
2401        GenericValue shipGroup = null;
2402        try {
2403            Map fields = UtilMisc.toMap("orderId", orderId, "shipGroupSeqId", shipGroupSeqId);
2404            shipGroup = delegator.findByPrimaryKey("OrderItemShipGroup", fields);
2405        } catch (GenericEntityException e) {
2406            Debug.logError(e, "Problems getting OrderItemShipGroup for : " + orderId + " / " + shipGroupSeqId, module);
2407            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderCannotUpdateProblemGettingOrderShipmentPreference", locale));
2408        }
2409
2410        if (shipGroup != null) {
2411            shipGroup.set("maySplit", "Y");
2412            try {
2413                shipGroup.store();
2414            } catch (GenericEntityException e) {
2415                Debug.logError("Problem saving OrderItemShipGroup for : " + orderId + " / " + shipGroupSeqId, module);
2416                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderCannotUpdateProblemSettingOrderShipmentPreference", locale));
2417            }
2418        } else {
2419            Debug.logError("ERROR: Got a NULL OrderItemShipGroup", module);
2420            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderCannotUpdateNoAvailableGroupsToChange", locale));
2421        }
2422        return ServiceUtil.returnSuccess();
2423    }
2424
2425    public static Map cancelFlaggedSalesOrders(DispatchContext dctx, Map context) {
2426        GenericDelegator delegator = dctx.getDelegator();
2427        LocalDispatcher dispatcher = dctx.getDispatcher();
2428        GenericValue userLogin = (GenericValue) context.get("userLogin");
2429        //Locale locale = (Locale) context.get("locale");
2430

2431        List ordersToCheck = null;
2432        List exprs = new ArrayList();
2433
2434        // create the query expressions
2435
exprs.add(new EntityExpr("orderTypeId", EntityOperator.EQUALS, "SALES_ORDER"));
2436        exprs.add(new EntityExpr("statusId", EntityOperator.NOT_EQUAL, "ORDER_COMPLETED"));
2437        exprs.add(new EntityExpr("statusId", EntityOperator.NOT_EQUAL, "ORDER_CANCELLED"));
2438        exprs.add(new EntityExpr("statusId", EntityOperator.NOT_EQUAL, "ORDER_REJECTED"));
2439
2440        // get the orders
2441
try {
2442            ordersToCheck = delegator.findByAnd("OrderHeader", exprs, UtilMisc.toList("orderDate"));
2443        } catch (GenericEntityException e) {
2444            Debug.logError(e, "Problem getting order headers", module);
2445        }
2446
2447        if (ordersToCheck == null || ordersToCheck.size() == 0) {
2448            Debug.logInfo("No orders to check, finished", module);
2449            return ServiceUtil.returnSuccess();
2450        }
2451
2452        Iterator i = ordersToCheck.iterator();
2453        while (i.hasNext()) {
2454            GenericValue orderHeader = (GenericValue) i.next();
2455            String JavaDoc orderId = orderHeader.getString("orderId");
2456            String JavaDoc orderStatus = orderHeader.getString("statusId");
2457
2458            if (orderStatus.equals("ORDER_CREATED")) {
2459                // first check for un-paid orders
2460
Timestamp JavaDoc orderDate = orderHeader.getTimestamp("entryDate");
2461
2462                // need the store for the order
2463
GenericValue productStore = null;
2464                try {
2465                    productStore = orderHeader.getRelatedOne("ProductStore");
2466                } catch (GenericEntityException e) {
2467                    Debug.logError(e, "Unable to get ProductStore from OrderHeader", module);
2468                }
2469
2470                // default days to cancel
2471
int daysTillCancel = 30;
2472
2473                // get the value from the store
2474
if (productStore != null && productStore.get("daysToCancelNonPay") != null) {
2475                    daysTillCancel = productStore.getLong("daysToCancelNonPay").intValue();
2476                }
2477
2478                if (daysTillCancel > 0) {
2479                    // 0 days means do not auto-cancel
2480
Calendar cal = Calendar.getInstance();
2481                    cal.setTimeInMillis(orderDate.getTime());
2482                    cal.add(Calendar.DAY_OF_YEAR, daysTillCancel);
2483                    Date cancelDate = cal.getTime();
2484                    Date nowDate = new Date();
2485                    //Debug.log("Cancel Date : " + cancelDate, module);
2486
//Debug.log("Current Date : " + nowDate, module);
2487
if (cancelDate.equals(nowDate) || nowDate.after(cancelDate)) {
2488                        // cancel the order item(s)
2489
Map svcCtx = UtilMisc.toMap("orderId", orderId, "statusId", "ITEM_CANCELLED", "userLogin", userLogin);
2490                        try {
2491                            // TODO: looks like result is ignored here, but we should be looking for errors
2492
Map ores = dispatcher.runSync("changeOrderItemStatus", svcCtx);
2493                        } catch (GenericServiceException e) {
2494                            Debug.logError(e, "Problem calling change item status service : " + svcCtx, module);
2495                        }
2496                    }
2497                }
2498            } else {
2499                // check for auto-cancel items
2500
List orderItems = null;
2501                try {
2502                    orderItems = orderHeader.getRelated("OrderItem");
2503                } catch (GenericEntityException e) {
2504                    Debug.logError(e, "Problem getting order item records", module);
2505                }
2506                if (orderItems != null && orderItems.size() > 0) {
2507                    Iterator oii = orderItems.iterator();
2508                    while (oii.hasNext()) {
2509                        GenericValue orderItem = (GenericValue) oii.next();
2510                        String JavaDoc orderItemSeqId = orderItem.getString("orderItemSeqId");
2511                        Timestamp JavaDoc nowTimestamp = UtilDateTime.nowTimestamp();
2512                        Timestamp JavaDoc autoCancelDate = orderItem.getTimestamp("autoCancelDate");
2513                        Timestamp JavaDoc dontCancelDate = orderItem.getTimestamp("dontCancelSetDate");
2514                        String JavaDoc dontCancelUserLogin = orderItem.getString("dontCancelSetUserLogin");
2515
2516                        if (dontCancelUserLogin == null && dontCancelDate == null && autoCancelDate != null) {
2517                            if (nowTimestamp.equals(autoCancelDate) || nowTimestamp.after(autoCancelDate)) {
2518                                // cancel the order item
2519
Map svcCtx = UtilMisc.toMap("orderId", orderId, "orderItemSeqId", orderItemSeqId, "statusId", "ITEM_CANCELLED", "userLogin", userLogin);
2520                                try {
2521                                    // TODO: check service result for an error return
2522
Map res = dispatcher.runSync("changeOrderItemStatus", svcCtx);
2523                                } catch (GenericServiceException e) {
2524                                    Debug.logError(e, "Problem calling change item status service : " + svcCtx, module);
2525                                }
2526                            }
2527                        }
2528                    }
2529                }
2530            }
2531        }
2532        return ServiceUtil.returnSuccess();
2533    }
2534
2535    public static Map checkDigitalItemFulfillment(DispatchContext dctx, Map context) {
2536        GenericDelegator delegator = dctx.getDelegator();
2537        LocalDispatcher dispatcher = dctx.getDispatcher();
2538        GenericValue userLogin = (GenericValue) context.get("userLogin");
2539        String JavaDoc orderId = (String JavaDoc) context.get("orderId");
2540        Locale locale = (Locale) context.get("locale");
2541
2542        // need the order header
2543
GenericValue orderHeader = null;
2544        try {
2545            orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId));
2546        } catch (GenericEntityException e) {
2547            Debug.logError(e, "ERROR: Unable to get OrderHeader for orderId : " + orderId, module);
2548            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorUnableToGetOrderHeaderForOrderId", UtilMisc.toMap("orderId",orderId), locale));
2549        }
2550
2551        // get all the items for the order
2552
List orderItems = null;
2553        if (orderHeader != null) {
2554            try {
2555                orderItems = orderHeader.getRelated("OrderItem");
2556            } catch (GenericEntityException e) {
2557                Debug.logError(e, "ERROR: Unable to get OrderItem list for orderId : " + orderId, module);
2558                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorUnableToGetOrderItemListForOrderId", UtilMisc.toMap("orderId",orderId), locale));
2559            }
2560        }
2561
2562        // find any digital goods
2563
Map digitalProducts = new HashMap();
2564        List digitalItems = new ArrayList();
2565        if (orderItems != null && orderItems.size() > 0) {
2566            Iterator i = orderItems.iterator();
2567            while (i.hasNext()) {
2568                GenericValue item = (GenericValue) i.next();
2569                GenericValue product = null;
2570                try {
2571                    product = item.getRelatedOne("Product");
2572                } catch (GenericEntityException e) {
2573                    Debug.logError(e, "ERROR: Unable to get Product from OrderItem", module);
2574                }
2575                if (product != null) {
2576                    GenericValue productType = null;
2577                    try {
2578                        productType = product.getRelatedOne("ProductType");
2579                    } catch (GenericEntityException e) {
2580                        Debug.logError(e, "ERROR: Unable to get ProductType from Product", module);
2581                    }
2582
2583                    if (productType != null) {
2584                        String JavaDoc isPhysical = productType.getString("isPhysical");
2585                        String JavaDoc isDigital = productType.getString("isDigital");
2586
2587                        // check for digital and finished/digital goods
2588
if (isDigital != null && "Y".equalsIgnoreCase(isDigital)) {
2589                            // we only invoice APPROVED items
2590
if ("ITEM_APPROVED".equals(item.getString("statusId"))) {
2591                                digitalItems.add(item);
2592                            }
2593                            if (isPhysical == null || !"Y".equalsIgnoreCase(isPhysical)) {
2594                                // 100% digital goods need status change
2595
digitalProducts.put(item, product);
2596                            }
2597                        }
2598                    }
2599                }
2600            }
2601        }
2602
2603        // now process the digital items
2604
if (digitalItems.size() > 0) {
2605            GenericValue productStore = OrderReadHelper.getProductStoreFromOrder(dispatcher.getDelegator(), orderId);
2606            boolean invoiceItems = true;
2607            if (productStore != null && productStore.get("autoInvoiceDigitalItems") != null) {
2608                invoiceItems = "Y".equalsIgnoreCase(productStore.getString("autoInvoiceDigitalItems"));
2609            }
2610
2611            if (invoiceItems) {
2612                // invoice all APPROVED digital goods
2613

2614                // do something tricky here: run as a different user that can actually create an invoice, post transaction, etc
2615
Map invoiceResult = null;
2616                try {
2617                    GenericValue permUserLogin = delegator.findByPrimaryKey("UserLogin", UtilMisc.toMap("userLoginId", "system"));
2618                    Map invoiceContext = UtilMisc.toMap("orderId", orderId, "billItems", digitalItems, "userLogin", permUserLogin);
2619                    invoiceResult = dispatcher.runSync("createInvoiceForOrder", invoiceContext);
2620                } catch (GenericEntityException e) {
2621                    Debug.logError(e, "ERROR: Unable to invoice digital items", module);
2622                    return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemWithInvoiceCreationDigitalItemsNotFulfilled", locale));
2623                } catch (GenericServiceException e) {
2624                    Debug.logError(e, "ERROR: Unable to invoice digital items", module);
2625                    return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemWithInvoiceCreationDigitalItemsNotFulfilled", locale));
2626                }
2627                if (ModelService.RESPOND_ERROR.equals(invoiceResult.get(ModelService.RESPONSE_MESSAGE))) {
2628                    return ServiceUtil.returnError((String JavaDoc) invoiceResult.get(ModelService.ERROR_MESSAGE));
2629                }
2630
2631                // update the status of digital goods to COMPLETED; leave physical/digital as APPROVED for pick/ship
2632
Iterator dii = digitalItems.iterator();
2633                while (dii.hasNext()) {
2634                    GenericValue productType = null;
2635                    GenericValue item = (GenericValue) dii.next();
2636                    GenericValue product = (GenericValue) digitalProducts.get(item);
2637
2638                    if (product != null) {
2639                        try {
2640                            productType = product.getRelatedOne("ProductType");
2641                        } catch (GenericEntityException e) {
2642                            Debug.logError(e, "ERROR: Unable to get ProductType from Product", module);
2643                        }
2644                    }
2645
2646                    if (product != null && productType != null) {
2647                        String JavaDoc isPhysical = productType.getString("isPhysical");
2648                        String JavaDoc isDigital = productType.getString("isDigital");
2649
2650                        // we were set as a digital good; one more check and change status
2651
if ((isDigital != null && "Y".equalsIgnoreCase(isDigital)) && (
2652                                isPhysical == null || !"Y".equalsIgnoreCase(isPhysical))) {
2653                            Map statusCtx = new HashMap();
2654                            statusCtx.put("orderId", item.getString("orderId"));
2655                            statusCtx.put("orderItemSeqId", item.getString("orderItemSeqId"));
2656                            statusCtx.put("statusId", "ITEM_COMPLETED");
2657                            statusCtx.put("userLogin", userLogin);
2658                            try {
2659                                dispatcher.runSyncIgnore("changeOrderItemStatus", statusCtx);
2660                            } catch (GenericServiceException e) {
2661                                Debug.logError(e, "ERROR: Problem setting the status to COMPLETED : " + item, module);
2662                            }
2663                        }
2664                    }
2665                }
2666            }
2667
2668            // fulfill the digital goods
2669
Map fulfillContext = UtilMisc.toMap("orderId", orderId, "orderItems", digitalItems, "userLogin", userLogin);
2670            Map fulfillResult = null;
2671            try {
2672                // will be running in an isolated transaction to prevent rollbacks
2673
fulfillResult = dispatcher.runSync("fulfillDigitalItems", fulfillContext, 300, true);
2674            } catch (GenericServiceException e) {
2675                Debug.logError(e, "ERROR: Unable to fulfill digital items", module);
2676            }
2677            if (ModelService.RESPOND_ERROR.equals(fulfillResult.get(ModelService.RESPONSE_MESSAGE))) {
2678                // this service cannot return error at this point or we will roll back the invoice
2679
// since payments are already captured; errors should have been logged already.
2680
// the response message here will be passed as an error to the user.
2681
return ServiceUtil.returnSuccess((String JavaDoc)fulfillResult.get(ModelService.ERROR_MESSAGE));
2682            }
2683        }
2684
2685        return ServiceUtil.returnSuccess();
2686    }
2687
2688    public static Map fulfillDigitalItems(DispatchContext ctx, Map context) {
2689        GenericDelegator delegator = ctx.getDelegator();
2690        LocalDispatcher dispatcher = ctx.getDispatcher();
2691        //appears to not be used: String orderId = (String) context.get("orderId");
2692
List orderItems = (List) context.get("orderItems");
2693        GenericValue userLogin = (GenericValue) context.get("userLogin");
2694        Locale locale = (Locale) context.get("locale");
2695
2696        if (orderItems != null && orderItems.size() > 0) {
2697            // loop through the digital items to fulfill
2698
Iterator itemsIterator = orderItems.iterator();
2699            while (itemsIterator.hasNext()) {
2700                GenericValue orderItem = (GenericValue) itemsIterator.next();
2701
2702                // make sure we have a valid item
2703
if (orderItem == null) {
2704                    return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorCannotCheckForFulfillmentItemNotFound", locale));
2705                }
2706
2707                // locate the Product & ProductContent records
2708
GenericValue product = null;
2709                List productContent = null;
2710                try {
2711                    product = orderItem.getRelatedOne("Product");
2712                    if (product == null) {
2713                        return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorCannotCheckForFulfillmentProductNotFound", locale));
2714                    }
2715
2716                    List allProductContent = product.getRelated("ProductContent");
2717                    
2718                    // try looking up the parent product if the product has no content and is a variant
2719
if (((allProductContent == null) || allProductContent.size() == 0) && ("Y".equals(product.getString("isVariant")))) {
2720                        GenericValue parentProduct = ProductWorker.getParentProduct(product.getString("productId"), delegator);
2721                        allProductContent.addAll(parentProduct.getRelated("ProductContent"));
2722                    }
2723                    
2724                    if (allProductContent != null && allProductContent.size() > 0) {
2725                        // only keep ones with valid dates
2726
productContent = EntityUtil.filterByDate(allProductContent, UtilDateTime.nowTimestamp(), "fromDate", "thruDate", true);
2727                        Debug.logInfo("Product has " + allProductContent.size() + " associations, " +
2728                                (productContent == null ? "0" : "" + productContent.size()) + " has valid from/thru dates", module);
2729                    }
2730                } catch (GenericEntityException e) {
2731                    return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorCannotGetProductEntity", locale) + e.getMessage());
2732                }
2733
2734                // now use the ProductContent to fulfill the item
2735
if (productContent != null && productContent.size() > 0) {
2736                    Iterator prodcontentIterator = productContent.iterator();
2737                    while (prodcontentIterator.hasNext()) {
2738                        GenericValue productContentItem = (GenericValue) prodcontentIterator.next();
2739                        GenericValue content = null;
2740                        try {
2741                            content = productContentItem.getRelatedOne("Content");
2742                        } catch (GenericEntityException e) {
2743                            Debug.logError(e,"ERROR: Cannot get Content entity: " + e.getMessage(),module);
2744                            continue;
2745                        }
2746
2747                        String JavaDoc fulfillmentType = productContentItem.getString("productContentTypeId");
2748                        if ("FULFILLMENT_EXTASYNC".equals(fulfillmentType) || "FULFILLMENT_EXTSYNC".equals(fulfillmentType)) {
2749                            // enternal service fulfillment
2750
String JavaDoc fulfillmentService = (String JavaDoc) content.get("serviceName");
2751                            if (fulfillmentService == null) {
2752                                Debug.logError("ProductContent of type FULFILLMENT_EXTERNAL had Content with empty serviceName, can not run fulfillment", module);
2753                            }
2754                            Map serviceCtx = UtilMisc.toMap("userLogin", userLogin, "orderItem", orderItem);
2755                            serviceCtx.putAll(productContentItem.getPrimaryKey());
2756                            try {
2757                                Debug.logInfo("Running external fulfillment '" + fulfillmentService + "'", module);
2758                                if ("FULFILLMENT_EXTASYNC".equals(fulfillmentType)) {
2759                                    dispatcher.runAsync(fulfillmentService, serviceCtx, true);
2760                                } else if ("FULFILLMENT_EXTSYNC".equals(fulfillmentType)) {
2761                                    Map resp = dispatcher.runSync(fulfillmentService, serviceCtx);
2762                                    if (ServiceUtil.isError(resp)) {
2763                                        return ServiceUtil.returnError(ServiceUtil.getErrorMessage(resp));
2764                                    }
2765                                }
2766                            } catch (GenericServiceException e) {
2767                                Debug.logError(e, "ERROR: Could not run external fulfillment service '" + fulfillmentService + "'; " + e.getMessage(), module);
2768                            }
2769                        } else if("FULFILLMENT_EMAIL".equals(fulfillmentType)) {
2770                            // digital email fulfillment
2771
// TODO: Add support for fulfillment email
2772
return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderEmailFulfillmentTypeNotYetImplemented", locale));
2773                        } else if("DIGITAL_DOWNLOAD".equals(fulfillmentType)) {
2774                            // digital download fulfillment
2775

2776                            // Nothing to do for here. Downloads are made available to the user
2777
// though a query of OrderItems with related ProductContent.
2778
} else {
2779                            Debug.logError("Invalid fulfillment type : " + fulfillmentType + " not supported.", module);
2780                        }
2781                    }
2782                }
2783            }
2784        }
2785        return ServiceUtil.returnSuccess();
2786    }
2787
2788    public static Map addItemToApprovedOrder(DispatchContext dctx, Map context) {
2789        LocalDispatcher dispatcher = dctx.getDispatcher();
2790        GenericDelegator delegator = dctx.getDelegator();
2791        GenericValue userLogin = (GenericValue) context.get("userLogin");
2792        Locale locale = (Locale) context.get("locale");
2793        String JavaDoc shipGroupSeqId = (String JavaDoc) context.get("shipGroupSeqId");
2794        String JavaDoc orderId = (String JavaDoc) context.get("orderId");
2795        String JavaDoc productId = (String JavaDoc) context.get("productId");
2796        String JavaDoc prodCatalogId = (String JavaDoc) context.get("prodCatalogId");
2797        Double JavaDoc basePrice = (Double JavaDoc) context.get("basePrice");
2798        Double JavaDoc quantity = (Double JavaDoc) context.get("quantity");
2799        Double JavaDoc amount = (Double JavaDoc) context.get("amount");
2800        String JavaDoc overridePrice = (String JavaDoc) context.get("overridePrice");
2801
2802        if (amount == null) {
2803            amount = new Double JavaDoc(0.00);
2804        }
2805
2806        int shipGroupIdx = -1;
2807        try {
2808            shipGroupIdx = Integer.parseInt(shipGroupSeqId);
2809            shipGroupIdx--;
2810        } catch (NumberFormatException JavaDoc e) {
2811            Debug.logError(e, module);
2812            return ServiceUtil.returnError(e.getMessage());
2813        }
2814        if (shipGroupIdx < 0) {
2815            return ServiceUtil.returnError("Invalid shipGroupSeqId [" + shipGroupSeqId + "]");
2816        }
2817
2818        // obtain a shopping cart object for updating
2819
ShoppingCart cart = null;
2820        try {
2821            cart = loadCartForUpdate(dispatcher, delegator, userLogin, orderId);
2822        } catch (GeneralException e) {
2823            return ServiceUtil.returnError(e.getMessage());
2824        }
2825        if (cart == null) {
2826            return ServiceUtil.returnError("ERROR: Null shopping cart object returned!");
2827        }
2828        // add in the new product
2829
try {
2830            ShoppingCartItem item = ShoppingCartItem.makeItem(null, productId, 0.00, quantity.doubleValue(), 0.0, null, 0.00, 0.00, null, null, null, null, prodCatalogId, null, dispatcher, cart, true, true);
2831            if (basePrice != null&&overridePrice!=null) {
2832                item.setBasePrice(basePrice.doubleValue());
2833                // special hack to make sure we re-calc the promos after a price change
2834
item.setQuantity(quantity.doubleValue() + 1, dispatcher, cart, false);
2835                item.setQuantity(quantity.doubleValue(), dispatcher, cart, false);
2836                item.setBasePrice(basePrice.doubleValue());
2837                item.setIsModifiedPrice(true);
2838            }
2839
2840
2841            // set the item in the selected ship group
2842
cart.setItemShipGroupQty(item, item.getQuantity(), shipGroupIdx);
2843        } catch (CartItemModifyException e) {
2844            Debug.logError(e, module);
2845            return ServiceUtil.returnError(e.getMessage());
2846        } catch (ItemNotFoundException e) {
2847            Debug.logError(e, module);
2848            return ServiceUtil.returnError(e.getMessage());
2849        }
2850
2851        // save all the updated information
2852
try {
2853            saveUpdatedCartToOrder(dispatcher, delegator, cart, locale, userLogin, orderId);
2854        } catch (GeneralException e) {
2855            return ServiceUtil.returnError(e.getMessage());
2856        }
2857
2858        Map result = ServiceUtil.returnSuccess();
2859        result.put("shoppingCart", cart);
2860        result.put("orderId", orderId);
2861        return result;
2862    }
2863
2864    public static Map updateApprovedOrderItems(DispatchContext dctx, Map context) {
2865        LocalDispatcher dispatcher = dctx.getDispatcher();
2866        GenericDelegator delegator = dctx.getDelegator();
2867        GenericValue userLogin = (GenericValue) context.get("userLogin");
2868        Locale locale = (Locale) context.get("locale");
2869        String JavaDoc orderId = (String JavaDoc) context.get("orderId");
2870        Map overridePriceMap = (Map) context.get("overridePriceMap");
2871        Map itemDescriptionMap = (Map) context.get("itemDescriptionMap");
2872        Map itemPriceMap = (Map) context.get("itemPriceMap");
2873        Map itemQtyMap = (Map) context.get("itemQtyMap");
2874
2875        // obtain a shopping cart object for updating
2876
ShoppingCart cart = null;
2877        try {
2878            cart = loadCartForUpdate(dispatcher, delegator, userLogin, orderId);
2879        } catch (GeneralException e) {
2880            return ServiceUtil.returnError(e.getMessage());
2881        }
2882        if (cart == null) {
2883            return ServiceUtil.returnError("ERROR: Null shopping cart object returned!");
2884        }
2885
2886        // go through the item map and obtain the totals per item
2887
Map itemTotals = new HashMap();
2888        Iterator i = itemQtyMap.keySet().iterator();
2889        while (i.hasNext()) {
2890            String JavaDoc key = (String JavaDoc) i.next();
2891            String JavaDoc quantityStr = (String JavaDoc) itemQtyMap.get(key);
2892            double groupQty = 0.0;
2893            try {
2894                groupQty = Double.parseDouble(quantityStr);
2895            } catch (NumberFormatException JavaDoc e) {
2896                Debug.logError(e, module);
2897                return ServiceUtil.returnError(e.getMessage());
2898            }
2899
2900            if (groupQty == 0) {
2901                return ServiceUtil.returnError("Quantity must be >0, use cancel item to cancel completely!");
2902            }
2903
2904            String JavaDoc[] itemInfo = key.split(":");
2905            Double JavaDoc tally = (Double JavaDoc) itemTotals.get(itemInfo[0]);
2906            if (tally == null) {
2907                tally = new Double JavaDoc(groupQty);
2908            } else {
2909                tally = new Double JavaDoc(tally.doubleValue() + groupQty);
2910            }
2911            itemTotals.put(itemInfo[0], tally);
2912        }
2913
2914        // set the items amount/price
2915
Iterator iai = itemTotals.keySet().iterator();
2916        while (iai.hasNext()) {
2917            String JavaDoc itemSeqId = (String JavaDoc) iai.next();
2918            ShoppingCartItem cartItem = cart.findCartItem(itemSeqId);
2919
2920            if (cartItem != null) {
2921                Double JavaDoc qty = (Double JavaDoc) itemTotals.get(itemSeqId);
2922                double priceSave = cartItem.getBasePrice();
2923
2924                // set quantity
2925
try {
2926                    cartItem.setQuantity(qty.doubleValue(), dispatcher, cart, true, false); // trigger external ops, don't reset ship groups (and update prices for both PO and SO items)
2927
} catch (CartItemModifyException e) {
2928                    Debug.logError(e, module);
2929                    return ServiceUtil.returnError(e.getMessage());
2930                }
2931                Debug.log("Set item quantity: [" + itemSeqId + "] " + qty, module);
2932
2933                if(cartItem.getIsModifiedPrice())
2934                    cartItem.setBasePrice(priceSave);
2935                // set price
2936

2937                if (overridePriceMap.containsKey(itemSeqId)) {
2938                    String JavaDoc priceStr = (String JavaDoc) itemPriceMap.get(itemSeqId);
2939                    if (UtilValidate.isNotEmpty(priceStr)) {
2940                        double price = -1;
2941                        //parse the price
2942
NumberFormat JavaDoc nf = null;
2943                        if (locale != null) {
2944                            nf = NumberFormat.getNumberInstance(locale);
2945                        } else {
2946                            nf = NumberFormat.getNumberInstance();
2947                        }
2948                        try {
2949                            price = nf.parse(priceStr).doubleValue();
2950                        } catch (ParseException JavaDoc e) {
2951                            Debug.logError(e, module);
2952                            return ServiceUtil.returnError(e.getMessage());
2953                        }
2954                        cartItem.setBasePrice(price);
2955                        cartItem.setIsModifiedPrice(true);
2956                        Debug.log("Set item price: [" + itemSeqId + "] " + price, module);
2957                    }
2958
2959                }
2960
2961                // Update the item description
2962
if (itemDescriptionMap != null && itemDescriptionMap.containsKey(itemSeqId)) {
2963                    String JavaDoc description = (String JavaDoc) itemDescriptionMap.get(itemSeqId);
2964                    if (UtilValidate.isNotEmpty(description)) {
2965                        cartItem.setName(description);
2966                        Debug.log("Set item description: [" + itemSeqId + "] " + description, module);
2967                    } else {
2968                        return ServiceUtil.returnError("Item description must not be empty");
2969                    }
2970                }
2971            } else {
2972                Debug.logInfo("Unable to locate shopping cart item for seqId #" + itemSeqId, module);
2973            }
2974        }
2975
2976        // update the group amounts
2977
Iterator gai = itemQtyMap.keySet().iterator();
2978        while (gai.hasNext()) {
2979            String JavaDoc key = (String JavaDoc) gai.next();
2980            String JavaDoc quantityStr = (String JavaDoc) itemQtyMap.get(key);
2981            double groupQty = 0.0;
2982            try {
2983                groupQty = Double.parseDouble(quantityStr);
2984            } catch (NumberFormatException JavaDoc e) {
2985                Debug.logError(e, module);
2986                return ServiceUtil.returnError(e.getMessage());
2987            }
2988
2989            String JavaDoc[] itemInfo = key.split(":");
2990            int groupIdx = -1;
2991            try {
2992                groupIdx = Integer.parseInt(itemInfo[1]);
2993            } catch (NumberFormatException JavaDoc e) {
2994                Debug.logError(e, module);
2995                return ServiceUtil.returnError(e.getMessage());
2996            }
2997
2998            // set the group qty
2999
ShoppingCartItem cartItem = cart.findCartItem(itemInfo[0]);
3000            if (cartItem != null) {
3001                Debug.log("Shipping info (before) for group #" + (groupIdx-1) + " [" + cart.getShipmentMethodTypeId(groupIdx-1) + " / " + cart.getCarrierPartyId(groupIdx-1) + "]", module);
3002                cart.setItemShipGroupQty(cartItem, groupQty, groupIdx - 1);
3003                Debug.log("Set ship group qty: [" + itemInfo[0] + " / " + itemInfo[1] + " (" + (groupIdx-1) + ")] " + groupQty, module);
3004                Debug.log("Shipping info (after) for group #" + (groupIdx-1) + " [" + cart.getShipmentMethodTypeId(groupIdx-1) + " / " + cart.getCarrierPartyId(groupIdx-1) + "]", module);
3005            }
3006        }
3007
3008        // save all the updated information
3009
try {
3010            saveUpdatedCartToOrder(dispatcher, delegator, cart, locale, userLogin, orderId);
3011        } catch (GeneralException e) {
3012            return ServiceUtil.returnError(e.getMessage());
3013        }
3014
3015        Map result = ServiceUtil.returnSuccess();
3016        result.put("shoppingCart", cart);
3017        result.put("orderId", orderId);
3018        return result;
3019    }
3020
3021    private static ShoppingCart loadCartForUpdate(LocalDispatcher dispatcher, GenericDelegator delegator, GenericValue userLogin, String JavaDoc orderId) throws GeneralException {
3022        // find ship group associations
3023
List shipGroupAssocs = null;
3024        try {
3025            shipGroupAssocs = delegator.findByAnd("OrderItemShipGroupAssoc", UtilMisc.toMap("orderId", orderId));
3026        } catch (GenericEntityException e) {
3027            Debug.logError(e, module);
3028            throw new GeneralException(e.getMessage());
3029        }
3030
3031        // cancel existing inventory reservations
3032
if (shipGroupAssocs != null) {
3033            Iterator iri = shipGroupAssocs.iterator();
3034            while (iri.hasNext()) {
3035                GenericValue shipGroupAssoc = (GenericValue) iri.next();
3036                String JavaDoc orderItemSeqId = shipGroupAssoc.getString("orderItemSeqId");
3037                String JavaDoc shipGroupSeqId = shipGroupAssoc.getString("shipGroupSeqId");
3038
3039                Map cancelCtx = UtilMisc.toMap("userLogin", userLogin, "orderId", orderId);
3040                cancelCtx.put("orderItemSeqId", orderItemSeqId);
3041                cancelCtx.put("shipGroupSeqId", shipGroupSeqId);
3042
3043                Map cancelResp = null;
3044                try {
3045                    cancelResp = dispatcher.runSync("cancelOrderInventoryReservation", cancelCtx);
3046                } catch (GenericServiceException e) {
3047                    Debug.logError(e, module);
3048                    throw new GeneralException(e.getMessage());
3049                }
3050                if (ServiceUtil.isError(cancelResp)) {
3051                    throw new GeneralException(ServiceUtil.getErrorMessage(cancelResp));
3052                }
3053            }
3054        }
3055
3056        // load the order into a shopping cart
3057
Map loadCartResp = null;
3058        try {
3059            loadCartResp = dispatcher.runSync("loadCartFromOrder", UtilMisc.toMap("orderId", orderId, "userLogin", userLogin));
3060        } catch (GenericServiceException e) {
3061            Debug.logError(e, module);
3062            throw new GeneralException(e.getMessage());
3063        }
3064        if (ServiceUtil.isError(loadCartResp)) {
3065            throw new GeneralException(ServiceUtil.getErrorMessage(loadCartResp));
3066        }
3067
3068        ShoppingCart cart = (ShoppingCart) loadCartResp.get("shoppingCart");
3069        if (cart == null) {
3070            throw new GeneralException("Error loading shopping cart from order [" + orderId + "]");
3071        } else {
3072            cart.setOrderId(orderId);
3073        }
3074
3075        return cart;
3076    }
3077
3078    private static void saveUpdatedCartToOrder(LocalDispatcher dispatcher, GenericDelegator delegator, ShoppingCart cart, Locale locale, GenericValue userLogin, String JavaDoc orderId) throws GeneralException {
3079        // get/set the shipping estimates. if it's a SALES ORDER, then return an error if there are no ship estimates
3080
int shipGroups = cart.getShipGroupSize();
3081        for (int gi = 0; gi < shipGroups; gi++) {
3082            String JavaDoc shipmentMethodTypeId = cart.getShipmentMethodTypeId(gi);
3083            String JavaDoc carrierPartyId = cart.getCarrierPartyId(gi);
3084            Debug.log("Getting ship estimate for group #" + gi + " [" + shipmentMethodTypeId + " / " + carrierPartyId + "]", module);
3085            Map result = ShippingEvents.getShipGroupEstimate(dispatcher, delegator, cart, gi);
3086            if (("SALES_ORDER".equals(cart.getOrderType())) && (ServiceUtil.isError(result))) {
3087                Debug.logError(ServiceUtil.getErrorMessage(result), module);
3088                throw new GeneralException(ServiceUtil.getErrorMessage(result));
3089            }
3090
3091            Double JavaDoc shippingTotal = (Double JavaDoc) result.get("shippingTotal");
3092            if (shippingTotal == null) {
3093                shippingTotal = new Double JavaDoc(0.00);
3094            }
3095            cart.setItemShipGroupEstimate(shippingTotal.doubleValue(), gi);
3096        }
3097        
3098        // calc the sales tax
3099
CheckOutHelper coh = new CheckOutHelper(dispatcher, delegator, cart);
3100        try {
3101            coh.calcAndAddTax();
3102        } catch (GeneralException e) {
3103            Debug.logError(e, module);
3104            throw new GeneralException(e.getMessage());
3105        }
3106
3107        // validate the payment methods
3108
Map validateResp = coh.validatePaymentMethods();
3109        if (ServiceUtil.isError(validateResp)) {
3110            throw new GeneralException(ServiceUtil.getErrorMessage(validateResp));
3111        }
3112
3113        // get the new orderItems, adjustments, shipping info and payments from the cart
3114
List toStore = new LinkedList();
3115        toStore.addAll(cart.makeOrderItems());
3116        toStore.addAll(cart.makeAllAdjustments());
3117        toStore.addAll(cart.makeAllShipGroupInfos());
3118        toStore.addAll(cart.makeAllOrderPaymentInfos());
3119
3120        // set the orderId & other information on all new value objects
3121
Iterator tsi = toStore.iterator();
3122        while (tsi.hasNext()) {
3123            GenericValue valueObj = (GenericValue) tsi.next();
3124            valueObj.set("orderId", orderId);
3125            if ("OrderItemShipGroup".equals(valueObj.getEntityName())) {
3126                // ship group
3127
if (valueObj.get("carrierRoleTypeId") == null) {
3128                    valueObj.set("carrierRoleTypeId", "CARRIER");
3129                }
3130            } else if ("OrderAdjustment".equals(valueObj.getEntityName())) {
3131                // shipping / tax adjustment(s)
3132
if (valueObj.get("orderItemSeqId") == null || valueObj.getString("orderItemSeqId").length() == 0) {
3133                    valueObj.set("orderItemSeqId", DataModelConstants.SEQ_ID_NA);
3134                }
3135                valueObj.set("orderAdjustmentId", delegator.getNextSeqId("OrderAdjustment"));
3136                valueObj.set("createdDate", UtilDateTime.nowTimestamp());
3137                valueObj.set("createdByUserLogin", userLogin.getString("userLoginId"));
3138            } else if ("OrderPaymentPreference".equals(valueObj.getEntityName())) {
3139                if (valueObj.get("orderPaymentPreferenceId") == null) {
3140                    valueObj.set("orderPaymentPreferenceId", delegator.getNextSeqId("OrderPaymentPreference"));
3141                    valueObj.set("createdDate", UtilDateTime.nowTimestamp());
3142                    valueObj.set("createdByUserLogin", userLogin.getString("userLoginId"));
3143                }
3144                if (valueObj.get("statusId") == null) {
3145                    valueObj.set("statusId", "PAYMENT_NOT_RECEIVED");
3146                }
3147            }
3148        }
3149        Debug.log("To Store Contains: " + toStore, module);
3150
3151        // cancel promo items -- if the promo still qualifies it will be added by the cart
3152
List promoItems = null;
3153        try {
3154            promoItems = delegator.findByAnd("OrderItem", UtilMisc.toMap("orderId", orderId, "isPromo", "Y"));
3155        } catch (GenericEntityException e) {
3156            Debug.logError(e, module);
3157            throw new GeneralException(e.getMessage());
3158        }
3159        if (promoItems != null) {
3160            Iterator pii = promoItems.iterator();
3161            while (pii.hasNext()) {
3162                GenericValue promoItem = (GenericValue) pii.next();
3163                Map cancelPromoCtx = UtilMisc.toMap("orderId", orderId);
3164                cancelPromoCtx.put("orderItemSeqId", promoItem.getString("orderItemSeqId"));
3165                cancelPromoCtx.put("userLogin", userLogin);
3166                Map cancelResp = null;
3167                try {
3168                    cancelResp = dispatcher.runSync("cancelOrderItem", cancelPromoCtx);
3169                } catch (GenericServiceException e) {
3170                    Debug.logError(e, module);
3171                    throw new GeneralException(e.getMessage());
3172                }
3173                if (ServiceUtil.isError(cancelResp)) {
3174                    throw new GeneralException(ServiceUtil.getErrorMessage(cancelResp));
3175                }
3176            }
3177        }
3178
3179        // cancel exiting authorizations
3180
Map releaseResp = null;
3181        try {
3182            releaseResp = dispatcher.runSync("releaseOrderPayments", UtilMisc.toMap("orderId", orderId, "userLogin", userLogin));
3183        } catch (GenericServiceException e) {
3184            Debug.logError(e, module);
3185            throw new GeneralException(e.getMessage());
3186        }
3187        if (ServiceUtil.isError(releaseResp)) {
3188            throw new GeneralException(ServiceUtil.getErrorMessage(releaseResp));
3189        }
3190
3191        // cancel other (non-completed and non-cancelled) payments
3192
List paymentPrefsToCancel = null;
3193        try {
3194            List exprs = UtilMisc.toList(new EntityExpr("orderId", EntityOperator.EQUALS, orderId));
3195            exprs.add(new EntityExpr("statusId", EntityOperator.NOT_EQUAL, "PAYMENT_RECEIVED"));
3196            exprs.add(new EntityExpr("statusId", EntityOperator.NOT_EQUAL, "PAYMENT_CANCELLED"));
3197            exprs.add(new EntityExpr("statusId", EntityOperator.NOT_EQUAL, "PAYMENT_DECLINED"));
3198            exprs.add(new EntityExpr("statusId", EntityOperator.NOT_EQUAL, "PAYMENT_SETTLED"));
3199            EntityCondition cond = new EntityConditionList(exprs, EntityOperator.AND);
3200            paymentPrefsToCancel = delegator.findByCondition("OrderPaymentPreference", cond, null, null);
3201        } catch (GenericEntityException e) {
3202            Debug.logError(e, module);
3203            throw new GeneralException(e.getMessage());
3204        }
3205        if (paymentPrefsToCancel != null) {
3206            Iterator oppi = paymentPrefsToCancel.iterator();
3207            while (oppi.hasNext()) {
3208                GenericValue opp = (GenericValue) oppi.next();
3209                try {
3210                    opp.set("statusId", "PAYMENT_CANCELLED");
3211                    opp.store();
3212                } catch (GenericEntityException e) {
3213                    Debug.logError(e, module);
3214                    throw new GeneralException(e.getMessage());
3215                }
3216            }
3217        }
3218
3219        // remove the adjustments
3220
try {
3221            List adjExprs = new LinkedList();
3222            adjExprs.add(new EntityExpr("orderId", EntityOperator.EQUALS, orderId));
3223            List exprs = new LinkedList();
3224            exprs.add(new EntityExpr("orderAdjustmentTypeId", EntityOperator.EQUALS, "PROMOTION_ADJUSTMENT"));
3225            exprs.add(new EntityExpr("orderAdjustmentTypeId", EntityOperator.EQUALS, "SHIPPING_CHARGES"));
3226            exprs.add(new EntityExpr("orderAdjustmentTypeId", EntityOperator.EQUALS, "SALES_TAX"));
3227            adjExprs.add(new EntityConditionList(exprs, EntityOperator.OR));
3228            EntityCondition cond = new EntityConditionList(adjExprs, EntityOperator.AND);
3229            delegator.removeByCondition("OrderAdjustment", cond);
3230        } catch (GenericEntityException e) {
3231            Debug.logError(e, module);
3232            throw new GeneralException(e.getMessage());
3233        }
3234
3235        // store the new items/adjustments
3236
try {
3237            delegator.storeAll(toStore);
3238        } catch (GenericEntityException e) {
3239            Debug.logError(e, module);
3240            throw new GeneralException(e.getMessage());
3241        }
3242
3243        // make the order item object map & the ship group assoc list
3244
List orderItemShipGroupAssoc = new LinkedList();
3245        Map itemValuesBySeqId = new HashMap();
3246        Iterator oii = toStore.iterator();
3247        while (oii.hasNext()) {
3248            GenericValue v = (GenericValue) oii.next();
3249            if ("OrderItem".equals(v.getEntityName())) {
3250                itemValuesBySeqId.put(v.getString("orderItemSeqId"), v);
3251            } else if ("OrderItemShipGroupAssoc".equals(v.getEntityName())) {
3252                orderItemShipGroupAssoc.add(v);
3253            }
3254        }
3255
3256        // reserve the inventory
3257
String JavaDoc productStoreId = cart.getProductStoreId();
3258        String JavaDoc orderTypeId = cart.getOrderType();
3259        List resErrorMessages = new LinkedList();
3260        try {
3261            Debug.log("Calling reserve inventory...", module);
3262            reserveInventory(delegator, dispatcher, userLogin, locale, orderItemShipGroupAssoc, itemValuesBySeqId,
3263                    orderTypeId, productStoreId, resErrorMessages);
3264        } catch (GeneralException e) {
3265            Debug.logError(e, module);
3266            throw new GeneralException(e.getMessage());
3267        }
3268
3269        if (resErrorMessages.size() > 0) {
3270            throw new GeneralException(ServiceUtil.getErrorMessage(ServiceUtil.returnError(resErrorMessages)));
3271        }
3272    }
3273
3274    public static Map processOrderPayments(DispatchContext dctx, Map context) {
3275        LocalDispatcher dispatcher = dctx.getDispatcher();
3276        GenericDelegator delegator = dctx.getDelegator();
3277        GenericValue userLogin = (GenericValue) context.get("userLogin");
3278        ShoppingCart cart = (ShoppingCart) context.get("shoppingCart");
3279        String JavaDoc orderId = (String JavaDoc) context.get("orderId");
3280
3281        OrderReadHelper orh = new OrderReadHelper(delegator, orderId);
3282        String JavaDoc productStoreId = orh.getProductStoreId();
3283
3284        CheckOutHelper coh = new CheckOutHelper(dispatcher, delegator, cart);
3285        // process the payments
3286
if (!"PURCHASE_ORDER".equals(cart.getOrderType())) {
3287            GenericValue productStore = ProductStoreWorker.getProductStore(productStoreId, delegator);
3288            Map paymentResp = null;
3289            try {
3290                Debug.log("Calling process payments...", module);
3291                //Debug.set(Debug.VERBOSE, true);
3292
paymentResp = coh.processPayment(productStore, userLogin);
3293                //Debug.set(Debug.VERBOSE, false);
3294
} catch (GeneralException e) {
3295                Debug.logError(e, module);
3296                return ServiceUtil.returnError(e.getMessage());
3297            } catch (GeneralRuntimeException e) {
3298                Debug.logError(e, module);
3299                return ServiceUtil.returnError(e.getMessage());
3300            }
3301
3302            if (ServiceUtil.isError(paymentResp)) {
3303                return ServiceUtil.returnError(ServiceUtil.getErrorMessage(paymentResp));
3304            }
3305        }
3306        return ServiceUtil.returnSuccess();
3307    }
3308
3309    // sample test services
3310
public static Map shoppingCartTest(DispatchContext dctx, Map context) {
3311        Locale locale = (Locale) context.get("locale");
3312        ShoppingCart cart = new ShoppingCart(dctx.getDelegator(), "9000", "webStore", locale, "USD");
3313        try {
3314            cart.addOrIncreaseItem("GZ-1005", 1, null, null, "DemoCatalog", dctx.getDispatcher());
3315            } catch (CartItemModifyException e) {
3316            Debug.logError(e, module);
3317        } catch (ItemNotFoundException e) {
3318            Debug.logError(e, module);
3319        }
3320
3321        try {
3322            dctx.getDispatcher().runAsync("shoppingCartRemoteTest", UtilMisc.toMap("cart", cart), true);
3323        } catch (GenericServiceException e) {
3324            Debug.logError(e, module);
3325        }
3326
3327        return ServiceUtil.returnSuccess();
3328    }
3329
3330    public static Map shoppingCartRemoteTest(DispatchContext dctx, Map context) {
3331        ShoppingCart cart = (ShoppingCart) context.get("cart");
3332        Debug.log("Product ID : " + cart.findCartItem(0).getProductId(), module);
3333        return ServiceUtil.returnSuccess();
3334    }
3335
3336    /**
3337     * Service to create a payment using an order payment preference.
3338     * @return Map
3339     */

3340    public static Map createPaymentFromPreference(DispatchContext dctx, Map context) {
3341        GenericDelegator delegator = dctx.getDelegator();
3342        LocalDispatcher dispatcher = dctx.getDispatcher();
3343        GenericValue userLogin = (GenericValue) context.get("userLogin");
3344
3345        String JavaDoc orderPaymentPreferenceId = (String JavaDoc) context.get("orderPaymentPreferenceId");
3346        String JavaDoc paymentRefNum = (String JavaDoc) context.get("paymentRefNum");
3347        String JavaDoc paymentFromId = (String JavaDoc) context.get("paymentFromId");
3348        String JavaDoc comments = (String JavaDoc) context.get("comments");
3349        try {
3350            // get the order payment preference
3351
GenericValue orderPaymentPreference = delegator.findByPrimaryKey("OrderPaymentPreference", UtilMisc.toMap("orderPaymentPreferenceId", orderPaymentPreferenceId));
3352            if (orderPaymentPreference == null) {
3353                return ServiceUtil.returnError("Failed to create Payment: Cannot find OrderPaymentPreference with orderPaymentPreferenceId " + orderPaymentPreferenceId);
3354            }
3355
3356            // get the order header
3357
GenericValue orderHeader = orderPaymentPreference.getRelatedOne("OrderHeader");
3358            if (orderHeader == null) {
3359                return ServiceUtil.returnError("Failed to create Payment: Cannot get related OrderHeader from payment preference");
3360            }
3361
3362            // get the store for the order
3363
GenericValue productStore = orderHeader.getRelatedOne("ProductStore");
3364            if (productStore == null) {
3365                return ServiceUtil.returnError("Failed to create Payment: Cannot get the ProductStore for the order header");
3366            }
3367
3368            // set the payToPartyId
3369
String JavaDoc payToPartyId = productStore.getString("payToPartyId");
3370            if (payToPartyId == null) {
3371                return ServiceUtil.returnError("Failed to create Payment: Cannot get the ProductStore for the order header");
3372            }
3373
3374            // create the payment
3375
Map paymentParams = new HashMap();
3376            paymentParams.put("paymentTypeId", "CUSTOMER_PAYMENT");
3377            paymentParams.put("paymentMethodTypeId", orderPaymentPreference.getString("paymentMethodTypeId"));
3378            paymentParams.put("paymentPreferenceId", orderPaymentPreference.getString("orderPaymentPreferenceId"));
3379            paymentParams.put("amount", orderPaymentPreference.getDouble("maxAmount"));
3380            paymentParams.put("statusId", "PMNT_RECEIVED");
3381            paymentParams.put("effectiveDate", UtilDateTime.nowTimestamp());
3382            paymentParams.put("partyIdTo", payToPartyId);
3383            if (paymentRefNum != null) {
3384                paymentParams.put("paymentRefNum", paymentRefNum);
3385            }
3386            if (paymentFromId != null) {
3387                paymentParams.put("partyIdFrom", paymentFromId);
3388            } else {
3389                paymentParams.put("partyIdFrom", "_NA_");
3390            }
3391            if (comments != null) {
3392                paymentParams.put("comments", comments);
3393            }
3394            paymentParams.put("userLogin", userLogin);
3395
3396            return dispatcher.runSync("createPayment", paymentParams);
3397
3398        } catch (GenericEntityException ex) {
3399            Debug.logError(ex, "Unable to create payment using payment preference.", module);
3400            return(ServiceUtil.returnError(ex.getMessage()));
3401        } catch (GenericServiceException ex) {
3402            Debug.logError(ex, "Unable to create payment using payment preference.", module);
3403            return(ServiceUtil.returnError(ex.getMessage()));
3404        }
3405    }
3406
3407
3408    /**
3409     * Explodes MARKET_PKG_AUTO item by replacing it with the underlying items (productIdTo in ProductAssoc.)
3410     * Also pro-rates the adjustments (sales tax, promotions, etc.) among the underlying items.
3411     * If there is a price difference between the MARKET_PKG_AUTO parent item and the sum of the underlying items,
3412     * a new OrderAdjustment, "MKTG_PKG_AUTO_ADJUST" is created, to record the difference.
3413     *
3414     * @param orderItems
3415     * @param orderAdjustments
3416     * @param orderItemShipGroupInfo
3417     * @param orderItemPriceInfo
3418     * @param orderTypeId
3419     * @param delegator
3420     * @param dispatcher
3421     * @param locale
3422     */

3423    public static void explodeMarketingPkgAutoItem(List orderItems, List orderAdjustments, List orderItemShipGroupInfo, List orderItemPriceInfo, String JavaDoc orderTypeId,
3424        GenericDelegator delegator, LocalDispatcher dispatcher, Locale locale) throws Exception JavaDoc {
3425
3426        List newOrderItems = new ArrayList();
3427        List newOrderAdjustments = new ArrayList();
3428        List newOrderItemShipGroupInfo = new ArrayList();
3429        Iterator itemIter = orderItems.iterator();
3430
3431        // loop through all order items to see if the need to be "exploded"
3432
while (itemIter.hasNext()) {
3433            GenericValue orderItem = (GenericValue) itemIter.next();
3434            String JavaDoc productId = orderItem.getString("productId");
3435            Double JavaDoc quantity = orderItem.getDouble("quantity");
3436            Double JavaDoc unitPrice = orderItem.getDouble("unitPrice");
3437            String JavaDoc orderItemSeqId = orderItem.getString("orderItemSeqId");
3438            String JavaDoc prodCatalogId = orderItem.getString("prodCatalogId");
3439
3440            // ignore order items which are not products
3441
if (productId == null || "".equals(productId)) {
3442                continue;
3443            }
3444
3445            // if an order item does not have a quantity, skip it
3446
if (quantity == null) {
3447                Debug.logWarning("Order item seq [" + orderItemSeqId + "] has a null quantity, so it cannot be exploded" , module);
3448                continue;
3449            }
3450            
3451            try {
3452                //deal with the order adjustment without orderItemSeqId. These are adjustments of the order, and we just keep them.
3453
if (orderAdjustments != null && orderAdjustments.size() > 0) {
3454                    for (int a = 0; orderAdjustments.size() > a; a++) {
3455                        GenericValue orderAdjustment = (GenericValue) orderAdjustments.get(a);
3456                        if (UtilValidate.isEmpty(orderAdjustment.getString("orderItemSeqId"))) {
3457                            newOrderAdjustments.add(orderAdjustment);
3458                        }//if
3459
}//for
3460
}//if
3461

3462                //deal with the item ship group without orderItemSeqId. Similarly, just keep these
3463
if (orderItemShipGroupInfo != null && orderItemShipGroupInfo.size() > 0) {
3464                    Iterator osiInfos = orderItemShipGroupInfo.iterator();
3465                    while (osiInfos.hasNext()) {
3466                        GenericValue valueObj = (GenericValue) osiInfos.next();
3467                        if ("OrderAdjustment".equals(valueObj.getEntityName()) || "OrderItemShipGroupAssoc".equals(valueObj.getEntityName())) {
3468                            if (UtilValidate.isEmpty(valueObj.getString("orderItemSeqId"))) {
3469                                newOrderItemShipGroupInfo.add(valueObj);
3470                            }//if
3471
} else {
3472                            newOrderItemShipGroupInfo.add(valueObj);
3473                        }//if
3474
}//while
3475
}//if
3476

3477                // find the products which are components of a MARKETING_PKG_AUTO, if any, for this product
3478
List productAssocList = null;
3479                Map tmpResult = dispatcher.runSync("getAssociatedProducts", UtilMisc.toMap("productId", productId, "type", "MARKETING_PKG_AUTO"));
3480                if (tmpResult.get("assocProducts") != null) {
3481                    productAssocList = (List) tmpResult.get("assocProducts");
3482                }
3483                
3484                if (productAssocList != null && productAssocList.size() > 0) {
3485                    Debug.logInfo("The product [" + productId + "] explodes to [" + productAssocList.toString() + "]", module);
3486                    // now add the associated products to the order
3487
List assocOrderItems = new ArrayList();
3488                    double sumSubItemsPrice = 0;
3489                    double sumAssocQty = 0;
3490                    for (int i = 0; productAssocList.size() > i; i++) {
3491                        GenericValue productAssoc = (GenericValue) productAssocList.get(i);
3492                        GenericValue productTo = productAssoc.getRelatedOne("AssocProduct");
3493                        String JavaDoc productIdTo = productTo.getString("productId");
3494                        String JavaDoc itemDescription = "";
3495                        
3496                        Double JavaDoc productToQuantity = productAssoc.getDouble("quantity");
3497                        
3498                        if (productToQuantity == null) {
3499                            productToQuantity = new Double JavaDoc(1.0);
3500                            Debug.logWarning("For order item [" + orderItemSeqId + "] Product association [" + productAssoc + "] had a null quantity, assuming 1", module);
3501                        }
3502                        
3503                        Double JavaDoc newQuantity = new Double JavaDoc(productToQuantity.doubleValue() * quantity.doubleValue());
3504
3505                        Double JavaDoc listPrice = new Double JavaDoc(0);
3506                        Double JavaDoc basePrice = new Double JavaDoc(0);
3507
3508                        // get the product name
3509
if (productTo != null) {
3510                           itemDescription = ProductContentWrapper.getProductContentAsText(productTo, "PRODUCT_NAME", locale);
3511                           // if the product name is null or empty, see if there is an associated virtual product and get the productName of that product
3512
if (UtilValidate.isEmpty(itemDescription)) {
3513                              GenericValue parentProduct = ProductWorker.getParentProduct(productIdTo, delegator);
3514                              if (parentProduct != null) {
3515                                itemDescription = ProductContentWrapper.getProductContentAsText(parentProduct, "PRODUCT_NAME", locale);
3516                              }//if
3517
}//if
3518
}//if
3519

3520                        // calculate price of the associated (component) product using calculateProductPrice
3521
try {
3522                            Map priceContext = new HashMap();
3523                            priceContext.put("product", productTo);
3524                            priceContext.put("prodCatalogId", prodCatalogId);
3525                            priceContext.put("quantity", newQuantity);
3526                            Map priceResult = dispatcher.runSync("calculateProductPrice", priceContext);
3527                            if (ModelService.RESPOND_ERROR.equals(priceResult.get(ModelService.RESPONSE_MESSAGE))) {
3528                                Debug.logWarning("There was an error while calculating the price: " + priceResult.get(ModelService.ERROR_MESSAGE), module);
3529                            }// if
3530

3531                            Boolean JavaDoc validPriceFound = (Boolean JavaDoc) priceResult.get("validPriceFound");
3532                            if (!validPriceFound.booleanValue()) {
3533                                Debug.logWarning("Could not find a valid price for the product with ID [" + productIdTo + "], not adding to cart.", module);
3534                            }// if
3535

3536                            if (priceResult.get("listPrice") != null) {
3537                                listPrice = (Double JavaDoc) priceResult.get("listPrice");
3538                            }// if
3539
if (priceResult.get("price") != null) {
3540                                basePrice = (Double JavaDoc) priceResult.get("price");
3541                            }// if
3542
} catch (Exception JavaDoc e) {
3543                            Debug.logWarning(e, "There was an error while calculating the price", module);
3544                            throw e;
3545                        }// try
3546
Debug.logInfo("The product [" + productIdTo + "] Price [" + basePrice + "]", module);
3547
3548                        // used to tally up total price of component items, so as to calculate correct adjustment later
3549
sumSubItemsPrice = sumSubItemsPrice + newQuantity.doubleValue() * basePrice.doubleValue();
3550                        sumAssocQty = sumAssocQty + productToQuantity.intValue();
3551
3552                        // now create the new order item
3553
GenericValue newOrderItem = GenericValue.create(orderItem);
3554                        newOrderItem.set("productId", productIdTo);
3555                        newOrderItem.set("quantity", newQuantity);
3556                        newOrderItem.set("unitPrice", basePrice);
3557                        newOrderItem.set("unitListPrice", listPrice);
3558                        newOrderItem.set("orderItemSeqId", orderItemSeqId + "-" + i);
3559                        newOrderItem.set("cancelQuantity", productToQuantity);
3560                        newOrderItem.set("itemDescription", itemDescription);
3561                        assocOrderItems.add(newOrderItem);
3562                        Debug.logInfo("explode OrderItem [" + orderItem.toString() + "] to [" + newOrderItem + "]", module);
3563                    }// for
3564

3565                    // If there were a difference between the price of the parent item and the sum of the prices of the marketing package components,
3566
// then create an OrderAdjustment for each new order item and pro-rate the difference based on its quantity and the total quantity of all
3567
// the component items.
3568
double originalItemPrice = quantity.doubleValue() * unitPrice.doubleValue();
3569                    double adjustmentPrice = originalItemPrice - sumSubItemsPrice;
3570                    if (adjustmentPrice != 0) {
3571                        for (int a = 0; assocOrderItems.size() > a; a++) {
3572                            GenericValue assocOrderItem = (GenericValue) assocOrderItems.get(a);
3573                            String JavaDoc assocOrderItemSeqId = assocOrderItem.getString("orderItemSeqId");
3574                            Double JavaDoc productToQuantity = assocOrderItem.getDouble("cancelQuantity");
3575
3576                            Double JavaDoc percentage = new Double JavaDoc(productToQuantity.doubleValue() / sumAssocQty);
3577                            Double JavaDoc amount = new Double JavaDoc(adjustmentPrice * percentage.doubleValue());
3578                            GenericValue newOrderAdjustment = delegator.makeValue("OrderAdjustment", UtilMisc.toMap("orderAdjustmentTypeId", "MKTG_PKG_AUTO_ADJUST"));
3579                            newOrderAdjustment.put("orderItemSeqId", assocOrderItemSeqId);
3580                            newOrderAdjustment.put("amount", new Double JavaDoc(amount.doubleValue()));
3581                            newOrderAdjustments.add(newOrderAdjustment);
3582                            Debug.logInfo("Add new Order Adjustment [" + newOrderAdjustment.toString() + "] for Order Item [" + assocOrderItem.toString() + "]", module);
3583                        }//for
3584
}//if
3585

3586                    // similarly prop-rate each order adjustment for the parent item to all the marketing package components
3587
if (orderAdjustments != null && orderAdjustments.size() > 0) {
3588                        for (int a = 0; orderAdjustments.size() > a; a++) {
3589                            GenericValue orderAdjustment = (GenericValue) orderAdjustments.get(a);
3590                            if (orderItemSeqId.equals(orderAdjustment.getString("orderItemSeqId"))) {
3591                                Debug.log("Explode Order Adjustment [" + orderAdjustment.toString() + "]", module);
3592                                for (int b = 0; assocOrderItems.size() > b; b++) {
3593                                    GenericValue assocOrderItem = (GenericValue) assocOrderItems.get(b);
3594                                    String JavaDoc assocOrderItemSeqId = assocOrderItem.getString("orderItemSeqId");
3595                                    Double JavaDoc productToQuantity = assocOrderItem.getDouble("cancelQuantity");
3596                                    Double JavaDoc amount = orderAdjustment.getDouble("amount");
3597
3598                                    Double JavaDoc percentage = new Double JavaDoc(productToQuantity.doubleValue() / sumAssocQty);
3599                                    amount = new Double JavaDoc(amount.doubleValue() * percentage.doubleValue());
3600                                    GenericValue newOrderAdjustment = GenericValue.create(orderAdjustment);
3601                                    newOrderAdjustment.put("orderItemSeqId", assocOrderItemSeqId);
3602                                    newOrderAdjustment.put("amount", amount);
3603                                    newOrderAdjustments.add(newOrderAdjustment);
3604                                    Debug.logInfo("Add new Order Adjustment [" + newOrderAdjustment.toString() + "]", module);
3605                                }//for
3606
}//if
3607
}//for
3608
}//if
3609

3610                    // assign the new order items to the same ship group as the parent item
3611
if (orderItemShipGroupInfo != null && orderItemShipGroupInfo.size() > 0) {
3612                        Iterator osiInfos = orderItemShipGroupInfo.iterator();
3613                        while (osiInfos.hasNext()) {
3614                            GenericValue valueObj = (GenericValue) osiInfos.next();
3615                            if ("OrderItemShipGroupAssoc".equals(valueObj.getEntityName())) {
3616                                // assign the ship group
3617
if (orderItemSeqId.equals(valueObj.getString("orderItemSeqId"))) {
3618                                    Debug.log("Explode OrderItemShipGroupAssoc [" + valueObj.toString() + "]", module);
3619                                    for (int a = 0; assocOrderItems.size() > a; a++) {
3620                                        GenericValue assocOrderItem = (GenericValue) assocOrderItems.get(a);
3621                                        String JavaDoc assocOrderItemSeqId = assocOrderItem.getString("orderItemSeqId");
3622                                        GenericValue newValueObj = GenericValue.create(valueObj);
3623                                        newValueObj.put("orderItemSeqId", assocOrderItemSeqId);
3624                                        newValueObj.put("quantity", assocOrderItem.getDouble("quantity"));
3625                                        newOrderItemShipGroupInfo.add(newValueObj);
3626                                        Debug.log("Create new OrderItemShipGroupAssoc [" + newValueObj.toString() + "]", module);
3627                                    }//for
3628
}//if
3629
} else if ("OrderAdjustment".equals(valueObj.getEntityName())) {
3630                                // orderItemShipGroupInfo might also contain an order adjustment for tax adjustments to this ship group. In that case,
3631
// pro-rate it as well.
3632
// TODO: it would be nice to re-factor this with the pro-rating code up above into one common code block.
3633
if (orderItemSeqId.equals(valueObj.getString("orderItemSeqId"))) {
3634                                    Debug.log("Explode OrderAdjustment [" + valueObj.toString() + "] ", module);
3635                                    for (int a = 0; assocOrderItems.size() > a; a++) {
3636                                        GenericValue assocOrderItem = (GenericValue) assocOrderItems.get(a);
3637                                        String JavaDoc assocOrderItemSeqId = assocOrderItem.getString("orderItemSeqId");
3638
3639                                        Double JavaDoc productToQuantity = assocOrderItem.getDouble("cancelQuantity");
3640                                        Double JavaDoc amount = valueObj.getDouble("amount");
3641
3642                                        Double JavaDoc percentage = new Double JavaDoc(productToQuantity.doubleValue() / sumAssocQty);
3643                                        amount = new Double JavaDoc(amount.doubleValue() * percentage.doubleValue());
3644                                        GenericValue newValueObj = GenericValue.create(valueObj);
3645                                        Double JavaDoc itemQuantity = assocOrderItem.getDouble("quantity");
3646                                        newValueObj.put("sourcePercentage", new Double JavaDoc(amount.doubleValue() / itemQuantity.doubleValue()));
3647                                        newValueObj.put("orderItemSeqId", assocOrderItemSeqId);
3648                                        newValueObj.put("amount", amount);
3649                                        newOrderItemShipGroupInfo.add(newValueObj);
3650                                        Debug.log("Create new Order Adjustment [" + newValueObj.toString() + "]", module);
3651                                    }//for
3652
}//if
3653
}//if
3654
}//while
3655
}//if
3656

3657                    for (int a = 0; assocOrderItems.size() > a; a++) {
3658                        GenericValue assocOrderItem = (GenericValue) assocOrderItems.get(a);
3659                        assocOrderItem.remove("cancelQuantity");
3660                        newOrderItems.add(assocOrderItem);
3661                    }//for
3662

3663                    // Deal with price rules: get all price rules for this line item by filtering the input price infos for this order item's seq id
3664
List andCondList = UtilMisc.toList(new EntityExpr("orderItemSeqId", EntityOperator.EQUALS, orderItem.getString("orderItemSeqId")));
3665                    List lineItemPriceInfos = EntityUtil.filterByAnd(orderItemPriceInfo, andCondList);
3666                    if ((lineItemPriceInfos != null) && (lineItemPriceInfos.size() > 0)) {
3667
3668                        // loop through the exploded items
3669
Iterator expItemIter = assocOrderItems.iterator();
3670                        while (expItemIter.hasNext()) {
3671                            GenericValue expItem = (GenericValue) expItemIter.next();
3672
3673                            // apply price rules
3674
List newOrderItemPriceInfos = new LinkedList();
3675                            Iterator oipii = lineItemPriceInfos.iterator();
3676                            while (oipii.hasNext()) {
3677                                GenericValue oipi = (GenericValue) oipii.next();
3678                                GenericValue newoipi = (GenericValue) oipi.clone();
3679                                newoipi.set("orderItemSeqId", expItem.getString("orderItemSeqId"));
3680                                newOrderItemPriceInfos.add(newoipi);
3681                                Debug.logInfo("Applying price rule " + oipi.getString("productPriceRuleId") + " to order item seq Id " + expItem.getString("orderItemSeqId"), module);
3682                            }
3683                            // add the new order item price infos
3684
orderItemPriceInfo.addAll(newOrderItemPriceInfos);
3685                        }
3686                        // finally, remove the price infos for the marketing package
3687
orderItemPriceInfo.removeAll(lineItemPriceInfos);
3688                    }
3689                } else {
3690                    //deal with the orderItem which cannot be explode - just carry them with their adjustments over in the same ship group
3691
newOrderItems.add(orderItem);
3692                    //order adjustment
3693
if (orderAdjustments != null && orderAdjustments.size() > 0) {
3694                        for (int a = 0; orderAdjustments.size() > a; a++) {
3695                            GenericValue orderAdjustment = (GenericValue) orderAdjustments.get(a);
3696                            if (orderItemSeqId.equals(orderAdjustment.getString("orderItemSeqId"))) {
3697                                newOrderAdjustments.add(orderAdjustment);
3698                            }//if
3699
}//for
3700
}//if
3701
//order item ship group
3702
if (orderItemShipGroupInfo != null && orderItemShipGroupInfo.size() > 0) {
3703                        Iterator osiInfos = orderItemShipGroupInfo.iterator();
3704                        while (osiInfos.hasNext()) {
3705                            GenericValue valueObj = (GenericValue) osiInfos.next();
3706                            if ("OrderAdjustment".equals(valueObj.getEntityName()) || "OrderItemShipGroupAssoc".equals(valueObj.getEntityName())) {
3707                                if (orderItemSeqId.equals(valueObj.getString("orderItemSeqId"))) {
3708                                    newOrderItemShipGroupInfo.add(valueObj);
3709                                }//if
3710
}//if
3711
}//while
3712
}//if
3713
} // if
3714
} catch (Exception JavaDoc e) {
3715                Debug.logWarning(e, "There was an error in the [explodeMarketingPkgAutoItem]: " + e.getMessage(), module);
3716                throw e;
3717            }// try
3718
}// while
3719

3720        orderItems.clear();
3721        orderItems.addAll(newOrderItems);
3722        orderAdjustments.clear();
3723        orderAdjustments.addAll(newOrderAdjustments);
3724        orderItemShipGroupInfo.clear();
3725        orderItemShipGroupInfo.addAll(newOrderItemShipGroupInfo);
3726    }// explodeMarketingPkgAutoItem
3727

3728    public static Map massChangeApproved(DispatchContext dctx, Map context) {
3729        LocalDispatcher dispatcher = dctx.getDispatcher();
3730        GenericDelegator delegator = dctx.getDelegator();
3731        GenericValue userLogin = (GenericValue) context.get("userLogin");
3732        List orderIds = (List) context.get("orderIdList");
3733        Iterator i = orderIds.iterator();
3734        while (i.hasNext()) {
3735            String JavaDoc orderId = (String JavaDoc) i.next();
3736            if (UtilValidate.isEmpty(orderId)) {
3737                continue;
3738            }
3739            GenericValue orderHeader = null;
3740            try {
3741                orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId));
3742            } catch (GenericEntityException e) {
3743                Debug.logError(e, module);
3744                return ServiceUtil.returnError(e.getMessage());
3745            }
3746            if (orderHeader == null) {
3747                return ServiceUtil.returnError("Order #" + orderId + " was not found.");
3748            }
3749
3750            // by changing all the items to approved, the checkOrderItemStatus service will automatically set the order to approved.
3751
Map ctx = FastMap.newInstance();
3752            ctx.put("statusId", "ITEM_APPROVED");
3753            ctx.put("orderId", orderId);
3754            ctx.put("userLogin", userLogin);
3755            Map resp = null;
3756            try {
3757                resp = dispatcher.runSync("changeOrderItemStatus", ctx);
3758            } catch (GenericServiceException e) {
3759                Debug.logError(e, module);
3760                return ServiceUtil.returnError(e.getMessage());
3761            }
3762            if (ServiceUtil.isError(resp)) {
3763                return ServiceUtil.returnError(ServiceUtil.getErrorMessage(resp));
3764            }
3765        }
3766        return ServiceUtil.returnSuccess();
3767    }
3768
3769    public static Map massPickOrders(DispatchContext dctx, Map context) {
3770        LocalDispatcher dispatcher = dctx.getDispatcher();
3771        GenericDelegator delegator = dctx.getDelegator();
3772        GenericValue userLogin = (GenericValue) context.get("userLogin");
3773
3774        // grouped by facility
3775
Map facilityOrdersMap = FastMap.newInstance();
3776
3777        // make the list per facility
3778
List orderIds = (List) context.get("orderIdList");
3779        Iterator i = orderIds.iterator();
3780        while (i.hasNext()) {
3781            String JavaDoc orderId = (String JavaDoc) i.next();
3782            if (UtilValidate.isEmpty(orderId)) {
3783                continue;
3784            }
3785            List invInfo = null;
3786            try {
3787                invInfo = delegator.findByAnd("OrderItemAndShipGrpInvResAndItem",
3788                        UtilMisc.toMap("orderId", orderId, "statusId", "ITEM_APPROVED"));
3789            } catch (GenericEntityException e) {
3790                Debug.logError(e, module);
3791                return ServiceUtil.returnError(e.getMessage());
3792            }
3793            if (invInfo != null) {
3794                Iterator ii = invInfo.iterator();
3795                while (ii.hasNext()) {
3796                    GenericValue inv = (GenericValue) ii.next();
3797                    String JavaDoc facilityId = inv.getString("facilityId");
3798                    List orderIdsByFacility = (List) facilityOrdersMap.get(facilityId);
3799                    if (orderIdsByFacility == null) {
3800                        orderIdsByFacility = new ArrayList();
3801                    }
3802                    orderIdsByFacility.add(orderId);
3803                    facilityOrdersMap.put(facilityId, orderIdsByFacility);
3804                }
3805            }
3806        }
3807
3808        // now create the pick lists for each facility
3809
Iterator fi = facilityOrdersMap.keySet().iterator();
3810        while (fi.hasNext()) {
3811            String JavaDoc facilityId = (String JavaDoc) fi.next();
3812            List orderIdList = (List) facilityOrdersMap.get(facilityId);
3813
3814            Map ctx = FastMap.newInstance();
3815            ctx.put("userLogin", userLogin);
3816            ctx.put("orderIdList", orderIdList);
3817            ctx.put("facilityId", facilityId);
3818
3819            Map resp = null;
3820            try {
3821                resp = dispatcher.runSync("createPicklistFromOrders", ctx);
3822            } catch (GenericServiceException e) {
3823                Debug.logError(e, module);
3824                return ServiceUtil.returnError(e.getMessage());
3825            }
3826            if (ServiceUtil.isError(resp)) {
3827                return ServiceUtil.returnError(ServiceUtil.getErrorMessage(resp));
3828            }
3829        }
3830
3831        return ServiceUtil.returnSuccess();
3832    }
3833}
3834
Popular Tags