KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ofbiz > order > shoppingcart > ShoppingCartHelper


1 /*
2  * $Id: ShoppingCartHelper.java 7151 2006-03-31 13:17:41Z jacopo $
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.shoppingcart;
25
26 import java.sql.Timestamp JavaDoc;
27 import java.text.NumberFormat JavaDoc;
28 import java.text.ParseException JavaDoc;
29 import java.util.ArrayList JavaDoc;
30 import java.util.Collection JavaDoc;
31 import java.util.HashMap JavaDoc;
32 import java.util.Iterator JavaDoc;
33 import java.util.List JavaDoc;
34 import java.util.Map JavaDoc;
35 import java.util.Set JavaDoc;
36 import java.util.Vector JavaDoc;
37 import java.util.Locale JavaDoc;
38
39 import org.ofbiz.base.util.Debug;
40 import org.ofbiz.base.util.UtilDateTime;
41 import org.ofbiz.base.util.UtilHttp;
42 import org.ofbiz.base.util.UtilMisc;
43 import org.ofbiz.base.util.UtilProperties;
44 import org.ofbiz.base.util.UtilValidate;
45 import org.ofbiz.entity.GenericDelegator;
46 import org.ofbiz.entity.GenericEntityException;
47 import org.ofbiz.entity.GenericValue;
48 import org.ofbiz.entity.util.EntityUtil;
49 import org.ofbiz.order.shoppingcart.product.ProductPromoWorker;
50 import org.ofbiz.product.config.ProductConfigWrapper;
51 import org.ofbiz.security.Security;
52 import org.ofbiz.service.GenericServiceException;
53 import org.ofbiz.service.LocalDispatcher;
54 import org.ofbiz.service.ModelService;
55 import org.ofbiz.service.ServiceUtil;
56
57 /**
58  * A facade over the
59  * {@link org.ofbiz.order.shoppingcart.ShoppingCart ShoppingCart}
60  * providing catalog and product services to simplify the interaction
61  * with the cart directly.
62  *
63  * @author <a HREF="mailto:tristana@twibble.org">Tristan Austin</a>
64  * @author <a HREF="mailto:jaz@ofbiz.org">Andy Zeneski</a>
65  * @version $Rev: 7151 $
66  * @since 2.0
67  */

68 public class ShoppingCartHelper {
69
70     public static final String JavaDoc resource = "OrderUiLabels";
71     public static String JavaDoc module = ShoppingCartHelper.class.getName();
72     public static final String JavaDoc resource_error = "OrderErrorUiLabels";
73
74     // The shopping cart to manipulate
75
private ShoppingCart cart = null;
76
77     // The entity engine delegator
78
private GenericDelegator delegator = null;
79
80     // The service invoker
81
private LocalDispatcher dispatcher = null;
82
83     /**
84      * Changes will be made to the cart directly, as opposed
85      * to a copy of the cart provided.
86      *
87      * @param cart The cart to manipulate
88      */

89     public ShoppingCartHelper(GenericDelegator delegator, LocalDispatcher dispatcher, ShoppingCart cart) {
90         this.dispatcher = dispatcher;
91         this.delegator = delegator;
92         this.cart = cart;
93
94         if (delegator == null) {
95             this.delegator = dispatcher.getDelegator();
96         }
97         if (dispatcher == null) {
98             throw new IllegalArgumentException JavaDoc("Dispatcher argument is null");
99         }
100         if (cart == null) {
101             throw new IllegalArgumentException JavaDoc("ShoppingCart argument is null");
102         }
103     }
104
105     /** Event to add an item to the shopping cart. */
106     public Map JavaDoc addToCart(String JavaDoc catalogId, String JavaDoc shoppingListId, String JavaDoc shoppingListItemSeqId, String JavaDoc productId,
107             String JavaDoc productCategoryId, String JavaDoc itemType, String JavaDoc itemDescription,
108             double price, double amount, double quantity,
109             java.sql.Timestamp JavaDoc reservStart, double reservLength, double reservPersons,
110             java.sql.Timestamp JavaDoc shipBeforeDate, java.sql.Timestamp JavaDoc shipAfterDate,
111             ProductConfigWrapper configWrapper, Map JavaDoc context) {
112         Map JavaDoc result = null;
113         Map JavaDoc attributes = null;
114         // price sanity check
115
if (productId == null && price < 0) {
116             String JavaDoc errMsg = UtilProperties.getMessage(resource, "cart.price_not_positive_number", this.cart.getLocale());
117             result = ServiceUtil.returnError(errMsg);
118             return result;
119         }
120
121         // quantity sanity check
122
if (quantity < 1) {
123             String JavaDoc errMsg = UtilProperties.getMessage(resource, "cart.quantity_not_positive_number", this.cart.getLocale());
124             result = ServiceUtil.returnError(errMsg);
125             return result;
126         }
127
128         // amount sanity check
129
if (amount < 0) {
130             amount = 0;
131         }
132
133         // check desiredDeliveryDate syntax and remove if empty
134
String JavaDoc ddDate = (String JavaDoc) context.get("itemDesiredDeliveryDate");
135         if (!UtilValidate.isEmpty(ddDate)) {
136             try {
137                 java.sql.Timestamp.valueOf((String JavaDoc) context.get("itemDesiredDeliveryDate"));
138             } catch (IllegalArgumentException JavaDoc e) {
139                 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderInvalidDesiredDeliveryDateSyntaxError",this.cart.getLocale()));
140             }
141         } else {
142             context.remove("itemDesiredDeliveryDate");
143         }
144
145         // remove an empty comment
146
String JavaDoc comment = (String JavaDoc) context.get("itemComment");
147         if (UtilValidate.isEmpty(comment)) {
148             context.remove("itemComment");
149         }
150
151         // stores the default desired delivery date in the cart if need
152
if (!UtilValidate.isEmpty((String JavaDoc) context.get("useAsDefaultDesiredDeliveryDate"))) {
153             cart.setDefaultItemDeliveryDate((String JavaDoc) context.get("itemDesiredDeliveryDate"));
154         } else {
155             // do we really want to clear this if it isn't checked?
156
cart.setDefaultItemDeliveryDate(null);
157         }
158
159         // stores the default comment in session if need
160
if (!UtilValidate.isEmpty((String JavaDoc) context.get("useAsDefaultComment"))) {
161             cart.setDefaultItemComment((String JavaDoc) context.get("itemComment"));
162         } else {
163             // do we really want to clear this if it isn't checked?
164
cart.setDefaultItemComment(null);
165         }
166
167         // Create a HashMap of product attributes - From ShoppingCartItem.attributeNames[]
168
for (int namesIdx = 0; namesIdx < ShoppingCartItem.attributeNames.length; namesIdx++) {
169             if (attributes == null)
170                 attributes = new HashMap JavaDoc();
171             if (context.containsKey(ShoppingCartItem.attributeNames[namesIdx])) {
172                 attributes.put(ShoppingCartItem.attributeNames[namesIdx], context.get(ShoppingCartItem.attributeNames[namesIdx]));
173             }
174         }
175
176         // check for required amount flag; if amount and no flag set to 0
177
GenericValue product = null;
178         if (productId != null) {
179             try {
180                 product = delegator.findByPrimaryKeyCache("Product", UtilMisc.toMap("productId", productId));
181             } catch (GenericEntityException e) {
182                 Debug.logError(e, "Unable to lookup product : " + productId, module);
183             }
184             if (product == null || product.get("requireAmount") == null || "N".equals(product.getString("requireAmount"))) {
185                 amount = 0;
186             }
187         }
188
189         // add or increase the item to the cart
190
try {
191             int itemId = -1;
192             if (productId != null) {
193                 itemId = cart.addOrIncreaseItem(productId, amount, quantity, reservStart, reservLength, reservPersons, shipBeforeDate, shipAfterDate,
194                         null, attributes, catalogId, configWrapper, dispatcher);
195             } else {
196                 itemId = cart.addNonProductItem(itemType, itemDescription, productCategoryId, price, quantity, attributes, catalogId, dispatcher);
197             }
198
199             // set the shopping list info
200
if (itemId > -1 && shoppingListId != null && shoppingListItemSeqId != null) {
201                 ShoppingCartItem item = cart.findCartItem(itemId);
202                 item.setShoppingList(shoppingListId, shoppingListItemSeqId);
203             }
204         } catch (CartItemModifyException e) {
205             if (cart.getOrderType().equals("PURCHASE_ORDER")) {
206                 String JavaDoc errMsg = UtilProperties.getMessage(resource, "cart.product_not_valid_for_supplier", this.cart.getLocale());
207                 errMsg = errMsg + " (" + e.getMessage() + ")";
208                 result = ServiceUtil.returnError(errMsg);
209             } else {
210                 result = ServiceUtil.returnError(e.getMessage());
211             }
212             return result;
213         } catch (ItemNotFoundException e) {
214             result = ServiceUtil.returnError(e.getMessage());
215             return result;
216         }
217         
218         // Indicate there were no critical errors
219
result = ServiceUtil.returnSuccess();
220         return result;
221     }
222
223     public Map JavaDoc addToCartFromOrder(String JavaDoc catalogId, String JavaDoc orderId, String JavaDoc[] itemIds, boolean addAll) {
224         ArrayList JavaDoc errorMsgs = new ArrayList JavaDoc();
225         Map JavaDoc result;
226         String JavaDoc errMsg = null;
227
228         if (orderId == null || orderId.length() <= 0) {
229             errMsg = UtilProperties.getMessage(resource,"cart.order_not_specified_to_add_from", this.cart.getLocale());
230             result = ServiceUtil.returnError(errMsg);
231             return result;
232         }
233
234         boolean noItems = true;
235
236         if (addAll) {
237             Iterator JavaDoc itemIter = null;
238
239             try {
240                 itemIter = UtilMisc.toIterator(delegator.findByAnd("OrderItem", UtilMisc.toMap("orderId", orderId), null));
241             } catch (GenericEntityException e) {
242                 Debug.logWarning(e.getMessage(), module);
243                 itemIter = null;
244             }
245
246             String JavaDoc orderItemTypeId = null;
247             if (itemIter != null && itemIter.hasNext()) {
248                 while (itemIter.hasNext()) {
249                     GenericValue orderItem = (GenericValue) itemIter.next();
250                     orderItemTypeId = orderItem.getString("orderItemTypeId");
251                     // do not store rental items
252
if (orderItemTypeId.equals("RENTAL_ORDER_ITEM"))
253                         continue;
254                     // never read: int itemId = -1;
255
if (orderItem.get("productId") != null && orderItem.get("quantity") != null) {
256                         double amount = 0.00;
257                         if (orderItem.get("selectedAmount") != null) {
258                             amount = orderItem.getDouble("selectedAmount").doubleValue();
259                         }
260                         try {
261                             this.cart.addOrIncreaseItem(orderItem.getString("productId"),
262                                     amount, orderItem.getDouble("quantity").doubleValue(),
263                                     null, null, catalogId, dispatcher);
264                             noItems = false;
265                         } catch (CartItemModifyException e) {
266                             errorMsgs.add(e.getMessage());
267                         } catch (ItemNotFoundException e) {
268                             errorMsgs.add(e.getMessage());
269                         }
270                     }
271                 }
272                 if (errorMsgs.size() > 0) {
273                     result = ServiceUtil.returnError(errorMsgs);
274                     result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS);
275                     return result; // don't return error because this is a non-critical error and should go back to the same page
276
}
277             } else {
278                 noItems = true;
279             }
280         } else {
281             noItems = true;
282             if (itemIds != null) {
283
284                 for (int i = 0; i < itemIds.length; i++) {
285                     String JavaDoc orderItemSeqId = itemIds[i];
286                     GenericValue orderItem = null;
287
288                     try {
289                         orderItem = delegator.findByPrimaryKey("OrderItem", UtilMisc.toMap("orderId", orderId, "orderItemSeqId", orderItemSeqId));
290                     } catch (GenericEntityException e) {
291                         Debug.logWarning(e.getMessage(), module);
292                         errorMsgs.add("Order line \"" + orderItemSeqId + "\" not found, so not added.");
293                         continue;
294                     }
295                     if (orderItem != null) {
296                         if (orderItem.get("productId") != null && orderItem.get("quantity") != null) {
297                             double amount = 0.00;
298                             if (orderItem.get("selectedAmount") != null) {
299                                 amount = orderItem.getDouble("selectedAmount").doubleValue();
300                             }
301                             try {
302                                 this.cart.addOrIncreaseItem(orderItem.getString("productId"), amount,
303                                         orderItem.getDouble("quantity").doubleValue(), null, null, catalogId, dispatcher);
304                                 noItems = false;
305                             } catch (CartItemModifyException e) {
306                                 errorMsgs.add(e.getMessage());
307                             } catch (ItemNotFoundException e) {
308                                 errorMsgs.add(e.getMessage());
309                             }
310                         }
311                     }
312                 }
313                 if (errorMsgs.size() > 0) {
314                     result = ServiceUtil.returnError(errorMsgs);
315                     result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS);
316                     return result; // don't return error because this is a non-critical error and should go back to the same page
317
}
318             } // else no items
319
}
320
321         if (noItems) {
322             result = ServiceUtil.returnSuccess();
323             result.put("_ERROR_MESSAGE_", UtilProperties.getMessage(resource_error,"OrderNoItemsFoundToAdd", this.cart.getLocale()));
324             return result; // don't return error because this is a non-critical error and should go back to the same page
325
}
326
327         result = ServiceUtil.returnSuccess();
328         return result;
329     }
330
331     /**
332      * Adds all products in a category according to quantity request parameter
333      * for each; if no parameter for a certain product in the category, or if
334      * quantity is 0, do not add
335      */

336     public Map JavaDoc addToCartBulk(String JavaDoc catalogId, String JavaDoc categoryId, Map JavaDoc context) {
337         String JavaDoc keyPrefix = "quantity_";
338         
339         // iterate through the context and find all keys that start with "quantity_"
340
Iterator JavaDoc entryIter = context.entrySet().iterator();
341         while (entryIter.hasNext()) {
342             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) entryIter.next();
343             String JavaDoc productId = null;
344             if (entry.getKey() instanceof String JavaDoc) {
345                 String JavaDoc key = (String JavaDoc) entry.getKey();
346                 //Debug.logInfo("Bulk Key: " + key, module);
347
if (key.startsWith(keyPrefix)) {
348                     productId = key.substring(keyPrefix.length());
349                 } else {
350                     continue;
351                 }
352             } else {
353                 continue;
354             }
355             String JavaDoc quantStr = (String JavaDoc) entry.getValue();
356
357             if (quantStr != null && quantStr.length() > 0) {
358                 double quantity = 0;
359
360                 try {
361                     quantity = Double.parseDouble(quantStr);
362                 } catch (NumberFormatException JavaDoc nfe) {
363                     quantity = 0;
364                 }
365                 if (quantity > 0.0) {
366                     try {
367                         if (Debug.verboseOn()) Debug.logVerbose("Bulk Adding to cart [" + quantity + "] of [" + productId + "]", module);
368                         this.cart.addOrIncreaseItem(productId, 0.00, quantity, null, null, catalogId, dispatcher);
369                     } catch (CartItemModifyException e) {
370                         return ServiceUtil.returnError(e.getMessage());
371                     } catch (ItemNotFoundException e) {
372                         return ServiceUtil.returnError(e.getMessage());
373                     }
374                 }
375             }
376         }
377
378         //Indicate there were no non critical errors
379
return ServiceUtil.returnSuccess();
380     }
381
382     /**
383      * Adds a set of requirements to the cart.
384      */

385     public Map JavaDoc addToCartBulkRequirements(String JavaDoc catalogId, Map JavaDoc context) {
386         NumberFormat JavaDoc nf = NumberFormat.getNumberInstance(this.cart.getLocale());
387         // check if we are using per row submit
388
boolean useRowSubmit = (!context.containsKey("_useRowSubmit"))? false :
389                 "Y".equalsIgnoreCase((String JavaDoc)context.get("_useRowSubmit"));
390         
391         // check if we are to also look in a global scope (no delimiter)
392
boolean checkGlobalScope = (!context.containsKey("_checkGlobalScope"))? false :
393                 "Y".equalsIgnoreCase((String JavaDoc)context.get("_checkGlobalScope"));
394         
395         int rowCount = 0; // parsed int value
396
try {
397             if (context.containsKey("_rowCount")) {
398                 rowCount = Integer.parseInt((String JavaDoc)context.get("_rowCount"));
399             }
400         } catch (NumberFormatException JavaDoc e) {
401             //throw new EventHandlerException("Invalid value for _rowCount");
402
}
403         
404         // now loop throw the rows and prepare/invoke the service for each
405
for (int i = 0; i < rowCount; i++) {
406             String JavaDoc productId = null;
407             String JavaDoc quantStr = null;
408             String JavaDoc requirementId = null;
409             String JavaDoc thisSuffix = UtilHttp.MULTI_ROW_DELIMITER + i;
410             boolean rowSelected = (!context.containsKey("_rowSubmit" + thisSuffix))? false :
411                     "Y".equalsIgnoreCase((String JavaDoc)context.get("_rowSubmit" + thisSuffix));
412             
413             // make sure we are to process this row
414
if (useRowSubmit && !rowSelected) {
415                 continue;
416             }
417             
418             // build the context
419
if (context.containsKey("productId" + thisSuffix)) {
420                 productId = (String JavaDoc) context.get("productId" + thisSuffix);
421                 quantStr = (String JavaDoc) context.get("quantity" + thisSuffix);
422                 requirementId = (String JavaDoc) context.get("requirementId" + thisSuffix);
423                 if (quantStr != null && quantStr.length() > 0) {
424                     double quantity = 0;
425                     try {
426                         quantity = nf.parse(quantStr).doubleValue();
427                     } catch (ParseException JavaDoc nfe) {
428                         quantity = 0;
429                     }
430                     if (quantity > 0.0) {
431                         Iterator JavaDoc items = this.cart.iterator();
432                         boolean requirementAlreadyInCart = false;
433                         while (items.hasNext() && !requirementAlreadyInCart) {
434                             ShoppingCartItem sci = (ShoppingCartItem)items.next();
435                             if (sci.getRequirementId() != null && sci.getRequirementId().equals(requirementId)) {
436                                 requirementAlreadyInCart = true;
437                                 continue;
438                             }
439                         }
440                         if (requirementAlreadyInCart) {
441                             if (Debug.warningOn()) Debug.logWarning(UtilProperties.getMessage(resource_error,"OrderTheRequirementIsAlreadyInTheCartNotAdding", UtilMisc.toMap("requirementId",requirementId), cart.getLocale()), module);
442                             continue;
443                         }
444                         try {
445                             if (Debug.verboseOn()) Debug.logVerbose("Bulk Adding to cart requirement [" + quantity + "] of [" + productId + "]", module);
446                             int index = this.cart.addOrIncreaseItem(productId, 0.00, quantity, null, null, catalogId, dispatcher);
447                             ShoppingCartItem sci = (ShoppingCartItem)this.cart.items().get(index);
448                             sci.setRequirementId(requirementId);
449                         } catch (CartItemModifyException e) {
450                             return ServiceUtil.returnError(e.getMessage());
451                         } catch (ItemNotFoundException e) {
452                             return ServiceUtil.returnError(e.getMessage());
453                         }
454                     }
455                 }
456             }
457         }
458         //Indicate there were no non critical errors
459
return ServiceUtil.returnSuccess();
460     }
461
462     /**
463      * Adds all products in a category according to default quantity on ProductCategoryMember
464      * for each; if no default for a certain product in the category, or if
465      * quantity is 0, do not add
466      */

467     public Map JavaDoc addCategoryDefaults(String JavaDoc catalogId, String JavaDoc categoryId) {
468         ArrayList JavaDoc errorMsgs = new ArrayList JavaDoc();
469         Map JavaDoc result = null;
470         String JavaDoc errMsg = null;
471
472         if (categoryId == null || categoryId.length() <= 0) {
473             errMsg = UtilProperties.getMessage(resource,"cart.category_not_specified_to_add_from", this.cart.getLocale());
474             result = ServiceUtil.returnError(errMsg);
475 // result = ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderNoCategorySpecifiedToAddFrom.",this.cart.getLocale()));
476
return result;
477         }
478
479         Collection JavaDoc prodCatMemberCol = null;
480
481         try {
482             prodCatMemberCol = delegator.findByAndCache("ProductCategoryMember", UtilMisc.toMap("productCategoryId", categoryId));
483         } catch (GenericEntityException e) {
484             Debug.logWarning(e.toString(), module);
485             Map JavaDoc messageMap = UtilMisc.toMap("categoryId", categoryId);
486             messageMap.put("message", e.getMessage());
487             errMsg = UtilProperties.getMessage(resource,"cart.could_not_get_products_in_category_cart", messageMap, this.cart.getLocale());
488             result = ServiceUtil.returnError(errMsg);
489             return result;
490         }
491
492         if (prodCatMemberCol == null) {
493             Map JavaDoc messageMap = UtilMisc.toMap("categoryId", categoryId);
494             errMsg = UtilProperties.getMessage(resource,"cart.could_not_get_products_in_category", messageMap, this.cart.getLocale());
495             result = ServiceUtil.returnError(errMsg);
496             return result;
497         }
498
499         double totalQuantity = 0;
500         Iterator JavaDoc pcmIter = prodCatMemberCol.iterator();
501
502         while (pcmIter.hasNext()) {
503             GenericValue productCategoryMember = (GenericValue) pcmIter.next();
504             Double JavaDoc quantity = productCategoryMember.getDouble("quantity");
505
506             if (quantity != null && quantity.doubleValue() > 0.0) {
507                 try {
508                     this.cart.addOrIncreaseItem(productCategoryMember.getString("productId"),
509                             0.00, quantity.doubleValue(), null, null, catalogId, dispatcher);
510                     totalQuantity += quantity.doubleValue();
511                 } catch (CartItemModifyException e) {
512                     errorMsgs.add(e.getMessage());
513                 } catch (ItemNotFoundException e) {
514                     errorMsgs.add(e.getMessage());
515                 }
516             }
517         }
518         if (errorMsgs.size() > 0) {
519             result = ServiceUtil.returnError(errorMsgs);
520             result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS);
521             return result; // don't return error because this is a non-critical error and should go back to the same page
522
}
523
524         result = ServiceUtil.returnSuccess();
525         result.put("totalQuantity", new Double JavaDoc(totalQuantity));
526         return result;
527     }
528
529     /** Delete an item from the shopping cart. */
530     public Map JavaDoc deleteFromCart(Map JavaDoc context) {
531         Map JavaDoc result = null;
532         Set JavaDoc names = context.keySet();
533         Iterator JavaDoc i = names.iterator();
534         ArrayList JavaDoc errorMsgs = new ArrayList JavaDoc();
535
536         while (i.hasNext()) {
537             String JavaDoc o = (String JavaDoc) i.next();
538
539             if (o.toUpperCase().startsWith("DELETE")) {
540                 try {
541                     String JavaDoc indexStr = o.substring(o.lastIndexOf('_') + 1);
542                     int index = Integer.parseInt(indexStr);
543
544                     try {
545                         this.cart.removeCartItem(index, dispatcher);
546                     } catch (CartItemModifyException e) {
547                         errorMsgs.add(e.getMessage());
548                     }
549                 } catch (NumberFormatException JavaDoc nfe) {}
550             }
551         }
552
553         if (errorMsgs.size() > 0) {
554             result = ServiceUtil.returnError(errorMsgs);
555             result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS);
556             return result; // don't return error because this is a non-critical error and should go back to the same page
557
}
558
559         result = ServiceUtil.returnSuccess();
560         return result;
561     }
562
563     /** Update the items in the shopping cart. */
564     public Map JavaDoc modifyCart(Security security, GenericValue userLogin, Map JavaDoc context, boolean removeSelected, String JavaDoc[] selectedItems, Locale JavaDoc locale) {
565         Map JavaDoc result = null;
566         if (locale == null) {
567             locale = this.cart.getLocale();
568         }
569         NumberFormat JavaDoc nf = NumberFormat.getNumberInstance(locale);
570
571         ArrayList JavaDoc deleteList = new ArrayList JavaDoc();
572         ArrayList JavaDoc errorMsgs = new ArrayList JavaDoc();
573
574         Set JavaDoc names = context.keySet();
575         Iterator JavaDoc i = names.iterator();
576
577         double oldQuantity = -1;
578         String JavaDoc oldDescription = "";
579         double oldPrice = -1;
580
581         if (this.cart.isReadOnlyCart()) {
582             String JavaDoc errMsg = UtilProperties.getMessage(resource, "cart.cart_is_in_read_only_mode", this.cart.getLocale());
583             errorMsgs.add(errMsg);
584             result = ServiceUtil.returnError(errorMsgs);
585             return result;
586         }
587
588         // TODO: This should be refactored to use UtilHttp.parseMultiFormData(parameters)
589
while (i.hasNext()) {
590             String JavaDoc o = (String JavaDoc) i.next();
591             int underscorePos = o.lastIndexOf('_');
592
593             if (underscorePos >= 0) {
594                 try {
595                     String JavaDoc indexStr = o.substring(underscorePos + 1);
596                     int index = Integer.parseInt(indexStr);
597                     String JavaDoc quantString = (String JavaDoc) context.get(o);
598                     double quantity = -1;
599                     String JavaDoc itemDescription="";
600                     if (quantString != null) quantString = quantString.trim();
601
602                     // get the cart item
603
ShoppingCartItem item = this.cart.findCartItem(index);
604                     if (o.toUpperCase().startsWith("OPTION")) {
605                         if (quantString.toUpperCase().startsWith("NO^")) {
606                             if (quantString.length() > 2) { // the length of the prefix
607
String JavaDoc featureTypeId = this.getRemoveFeatureTypeId(o);
608                                 if (featureTypeId != null) {
609                                     item.removeAdditionalProductFeatureAndAppl(featureTypeId);
610                                 }
611                             }
612                         } else {
613                             GenericValue featureAppl = this.getFeatureAppl(item.getProductId(), o, quantString);
614                             if (featureAppl != null) {
615                                 item.putAdditionalProductFeatureAndAppl(featureAppl);
616                             }
617                         }
618                     } else if (o.toUpperCase().startsWith("DESCRIPTION")) {
619                         itemDescription = quantString; // the quantString is actually the description if the field name starts with DESCRIPTION
620
} else if (o.startsWith("reservStart")) {
621                         // should have format: yyyy-mm-dd hh:mm:ss.fffffffff
622
quantString += " 00:00:00.000000000";
623                         if (item != null) {
624                                 Timestamp JavaDoc reservStart = Timestamp.valueOf((String JavaDoc) quantString);
625                                 item.setReservStart(reservStart);
626                         }
627                     } else if (o.startsWith("reservLength")) {
628                         if (item != null) {
629                                 double reservLength = nf.parse(quantString).doubleValue();
630                                 item.setReservLength(reservLength);
631                         }
632                     } else if (o.startsWith("reservPersons")) {
633                         if (item != null) {
634                                 double reservPersons = nf.parse(quantString).doubleValue();
635                                 item.setReservPersons(reservPersons);
636                         }
637                     } else if (o.startsWith("shipBeforeDate")) {
638                         if (item != null && quantString.length() > 0) {
639                             // input is either yyyy-mm-dd or a full timestamp
640
if (quantString.length() == 10)
641                                 quantString += " 00:00:00.000";
642                             item.setShipBeforeDate(Timestamp.valueOf(quantString));
643                         }
644                     } else if (o.startsWith("shipAfterDate")) {
645                         if (item != null && quantString.length() > 0) {
646                             // input is either yyyy-mm-dd or a full timestamp
647
if (quantString.length() == 10)
648                                 quantString += " 00:00:00.000";
649                             item.setShipAfterDate(Timestamp.valueOf(quantString));
650                         }
651                     } else {
652                         quantity = nf.parse(quantString).doubleValue();
653                         if (quantity < 0) {
654                             throw new CartItemModifyException("Quantity must be a positive number.");
655                         }
656                     }
657
658                     // perhaps we need to reset the ship groups' before and after dates based on new dates for the items
659
if (o.startsWith("shipAfterDate") || o.startsWith("shipBeforeDate")) {
660                         this.cart.setShipGroupShipDatesFromItem(item);
661                     }
662                     
663                     if (o.toUpperCase().startsWith("UPDATE")) {
664                         if (quantity == 0.0) {
665                             deleteList.add(item);
666                         } else {
667                             if (item != null) {
668                                 try {
669                                     // if, on a purchase order, the quantity has changed, get the new SupplierProduct entity for this quantity level.
670
if (cart.getOrderType().equals("PURCHASE_ORDER")) {
671                                         oldQuantity = item.getQuantity();
672                                         if (oldQuantity != quantity) {
673                                             // save the old description and price, in case the user wants to change those as well
674
oldDescription = item.getName();
675                                             oldPrice = item.getBasePrice();
676
677
678                                             GenericValue productSupplier = this.getProductSupplier(item.getProductId(), new Double JavaDoc(quantity), cart.getCurrency());
679
680                                             if (productSupplier == null) {
681                                                 if ("_NA_".equals(cart.getPartyId())) {
682                                                     // no supplier does not require the supplier product
683
item.setQuantity(quantity, dispatcher, this.cart);
684                                                     item.setName(item.getProduct().getString("internalName"));
685                                                 } else {
686                                                     // in this case, the user wanted to purchase a quantity which is not available (probably below minimum)
687
String JavaDoc errMsg = UtilProperties.getMessage(resource, "cart.product_not_valid_for_supplier", this.cart.getLocale());
688                                                     errMsg = errMsg + " (" + item.getProductId() + ", " + quantity + ", " + cart.getCurrency() + ")";
689                                                     errorMsgs.add(errMsg);
690                                                 }
691                                             } else {
692                                                 item.setQuantity(quantity, dispatcher, this.cart);
693                                                 item.setBasePrice(productSupplier.getDouble("lastPrice").doubleValue());
694                                                 item.setName(ShoppingCartItem.getPurchaseOrderItemDescription(item.getProduct(), productSupplier, cart.getLocale()));
695                                             }
696                                         }
697                                     } else {
698                                        item.setQuantity(quantity, dispatcher, this.cart);
699                                     }
700                                 } catch (CartItemModifyException e) {
701                                     errorMsgs.add(e.getMessage());
702                                 }
703                             }
704                         }
705                     }
706
707                     if (o.toUpperCase().startsWith("DESCRIPTION")) {
708                        if (!oldDescription.equals(itemDescription)){
709                            if (security.hasEntityPermission("ORDERMGR", "_CREATE", userLogin)) {
710                                if (item != null) {
711                                   item.setName(itemDescription);
712                                }
713                            }
714                        }
715                     }
716
717                     if (o.toUpperCase().startsWith("PRICE")) {
718                       NumberFormat JavaDoc pf = NumberFormat.getCurrencyInstance(locale);
719                       String JavaDoc tmpQuantity = pf.format(quantity);
720                       String JavaDoc tmpOldPrice = pf.format(oldPrice);
721                       if (!tmpOldPrice.equals(tmpQuantity)) {
722                         if (security.hasEntityPermission("ORDERMGR", "_CREATE", userLogin)) {
723                             if (item != null) {
724                                item.setBasePrice(quantity); // this is quantity because the parsed number variable is the same as quantity
725
item.setDisplayPrice(quantity); // or the amount shown the cart items page won't be right
726
item.setIsModifiedPrice(true); // flag as a modified price
727
}
728                             }
729                         }
730                     }
731
732                     if (o.toUpperCase().startsWith("DELETE")) {
733                         deleteList.add(this.cart.findCartItem(index));
734                     }
735                 } catch (NumberFormatException JavaDoc nfe) {
736                     Debug.logWarning(nfe, UtilProperties.getMessage(resource_error,"OrderCaughtNumberFormatExceptionOnCartUpdate", cart.getLocale()));
737                 } catch (ParseException JavaDoc pe) {
738                     Debug.logWarning(pe, UtilProperties.getMessage(resource_error,"OrderCaughtParseExceptionOnCartUpdate", cart.getLocale()));
739                 } catch (Exception JavaDoc e) {
740                     Debug.logWarning(e, UtilProperties.getMessage(resource_error,"OrderCaughtExceptionOnCartUpdate", cart.getLocale()));
741                 }
742             } // else not a parameter we need
743
}
744
745         // get a list of the items to delete
746
if (removeSelected) {
747             for (int si = 0; si < selectedItems.length; si++) {
748                 String JavaDoc indexStr = selectedItems[si];
749                 ShoppingCartItem item = null;
750                 try {
751                     int index = Integer.parseInt(indexStr);
752                     item = this.cart.findCartItem(index);
753                 } catch (Exception JavaDoc e) {
754                     Debug.logWarning(e, UtilProperties.getMessage(resource_error,"OrderProblemsGettingTheCartItemByIndex", cart.getLocale()));
755                 }
756                 if (item != null) {
757                     deleteList.add(item);
758                 }
759             }
760         }
761
762         Iterator JavaDoc di = deleteList.iterator();
763
764         while (di.hasNext()) {
765             ShoppingCartItem item = (ShoppingCartItem) di.next();
766             int itemIndex = this.cart.getItemIndex(item);
767
768             if (Debug.infoOn())
769                 Debug.logInfo("Removing item index: " + itemIndex, module);
770             try {
771                 this.cart.removeCartItem(itemIndex, dispatcher);
772             } catch (CartItemModifyException e) {
773                 result = ServiceUtil.returnError(new Vector JavaDoc());
774                 errorMsgs.add(e.getMessage());
775             }
776         }
777
778         if (context.containsKey("alwaysShowcart")) {
779             this.cart.setViewCartOnAdd(true);
780         } else {
781             this.cart.setViewCartOnAdd(false);
782         }
783
784         // Promotions are run again.
785
ProductPromoWorker.doPromotions(this.cart, dispatcher);
786
787         if (errorMsgs.size() > 0) {
788             result = ServiceUtil.returnError(errorMsgs);
789             return result;
790         }
791
792         result = ServiceUtil.returnSuccess();
793         return result;
794     }
795
796     /** Empty the shopping cart. */
797     public boolean clearCart() {
798         this.cart.clear();
799         return true;
800     }
801
802     /** Returns the shopping cart this helper is wrapping. */
803     public ShoppingCart getCartObject() {
804         return this.cart;
805     }
806
807     public GenericValue getFeatureAppl(String JavaDoc productId, String JavaDoc optionField, String JavaDoc featureId) {
808         if (delegator == null) {
809             throw new IllegalArgumentException JavaDoc("No delegator available to lookup ProductFeature");
810         }
811
812         Map JavaDoc fields = UtilMisc.toMap("productId", productId, "productFeatureId", featureId);
813         if (optionField != null) {
814             int featureTypeStartIndex = optionField.indexOf('^') + 1;
815             int featureTypeEndIndex = optionField.lastIndexOf('_');
816             if (featureTypeStartIndex > 0 && featureTypeEndIndex > 0) {
817                 fields.put("productFeatureTypeId", optionField.substring(featureTypeStartIndex, featureTypeEndIndex));
818             }
819         }
820
821         GenericValue productFeatureAppl = null;
822         List JavaDoc features = null;
823         try {
824             features = delegator.findByAnd("ProductFeatureAndAppl", fields, UtilMisc.toList("-fromDate"));
825         } catch (GenericEntityException e) {
826             Debug.logError(e, module);
827             return null;
828         }
829
830         if (features != null) {
831             if (features.size() > 1) {
832                 features = EntityUtil.filterByDate(features);
833             }
834             productFeatureAppl = EntityUtil.getFirst(features);
835         }
836
837         return productFeatureAppl;
838     }
839
840     public String JavaDoc getRemoveFeatureTypeId(String JavaDoc optionField) {
841         if (optionField != null) {
842             int featureTypeStartIndex = optionField.indexOf('^') + 1;
843             int featureTypeEndIndex = optionField.lastIndexOf('_');
844             if (featureTypeStartIndex > 0 && featureTypeEndIndex > 0) {
845                 return optionField.substring(featureTypeStartIndex, featureTypeEndIndex);
846             }
847         }
848         return null;
849     }
850     /**
851      * Select an agreement
852      *
853      * @param agreementId
854      */

855     public Map JavaDoc selectAgreement(String JavaDoc agreementId) {
856         ArrayList JavaDoc errorMsgs = new ArrayList JavaDoc();
857         Map JavaDoc result = null;
858         GenericValue agreement = null;
859
860         if ((this.delegator == null) || (this.dispatcher == null) || (this.cart == null)) {
861             result = ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderDispatcherOrDelegatorOrCartArgumentIsNull",this.cart.getLocale()));
862             return result;
863         }
864
865         if ((agreementId == null) || (agreementId.length() <= 0)) {
866             result = ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderNoAgreementSpecified",this.cart.getLocale()));
867             return result;
868         }
869
870         try {
871             agreement = this.delegator.findByPrimaryKeyCache("Agreement",UtilMisc.toMap("agreementId", agreementId));
872         } catch (GenericEntityException e) {
873             Debug.logWarning(e.toString(), module);
874             result = ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderCouldNotGetAgreement",UtilMisc.toMap("agreementId",agreementId),this.cart.getLocale()) + UtilProperties.getMessage(resource_error,"OrderError",this.cart.getLocale()) + e.getMessage());
875             return result;
876         }
877
878         if (agreement == null) {
879             result = ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderCouldNotGetAgreement",UtilMisc.toMap("agreementId",agreementId),this.cart.getLocale()));
880         } else {
881             // set the agreement id in the cart
882
cart.setAgreementId(agreementId);
883             try {
884                  // set the currency based on the pricing agreement
885
List JavaDoc agreementItems = agreement.getRelated("AgreementItem", UtilMisc.toMap("agreementItemTypeId", "AGREEMENT_PRICING_PR"), null);
886                  if (agreementItems.size() > 0) {
887                        GenericValue agreementItem = (GenericValue) agreementItems.get(0);
888                        String JavaDoc currencyUomId = (String JavaDoc) agreementItem.get("currencyUomId");
889                        try {
890                             cart.setCurrency(dispatcher,currencyUomId);
891                        } catch (CartItemModifyException ex) {
892                         result = ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderSetCurrencyError",this.cart.getLocale()) + ex.getMessage());
893                             return result;
894                        }
895                  }
896             } catch (GenericEntityException e) {
897                 Debug.logWarning(e.toString(), module);
898                 result = ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderCouldNotGetAgreementItemsThrough",UtilMisc.toMap("agreementId",agreementId),this.cart.getLocale()) + UtilProperties.getMessage(resource_error,"OrderError",this.cart.getLocale()) + e.getMessage());
899                 return result;
900             }
901
902             try {
903                  // clear the existing order terms
904
cart.removeOrderTerms();
905                  // set order terms based on agreement terms
906
List JavaDoc agreementTerms = agreement.getRelated("AgreementTerm");
907                  if (agreementTerms.size() > 0) {
908                       for (int i = 0; agreementTerms.size() > i;i++) {
909                            GenericValue agreementTerm = (GenericValue) agreementTerms.get(i);
910                            String JavaDoc termTypeId = (String JavaDoc) agreementTerm.get("termTypeId");
911                            Double JavaDoc termValue = (Double JavaDoc) agreementTerm.get("termValue");
912                            Long JavaDoc termDays = (Long JavaDoc) agreementTerm.get("termDays");
913                            cart.addOrderTerm(termTypeId, termValue, termDays);
914                       }
915                   }
916             } catch (GenericEntityException e) {
917                   Debug.logWarning(e.toString(), module);
918                   result = ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderCouldNotGetAgreementTermsThrough",UtilMisc.toMap("agreementId",agreementId),this.cart.getLocale()) + UtilProperties.getMessage(resource_error,"OrderError",this.cart.getLocale()) + e.getMessage());
919                   return result;
920             }
921         }
922         return result;
923     }
924
925     public Map JavaDoc setCurrency(String JavaDoc currencyUomId) {
926         Map JavaDoc result = null;
927
928         try {
929             this.cart.setCurrency(this.dispatcher,currencyUomId);
930             result = ServiceUtil.returnSuccess();
931          } catch (CartItemModifyException ex) {
932             result = ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"Set currency error",this.cart.getLocale()) + ex.getMessage());
933              return result;
934          }
935         return result;
936     }
937
938     public Map JavaDoc addOrderTerm(String JavaDoc termTypeId,Double JavaDoc termValue,Long JavaDoc termDays) {
939         Map JavaDoc result = null;
940         String JavaDoc errMsg = null;
941
942         this.cart.addOrderTerm(termTypeId,termValue,termDays);
943         result = ServiceUtil.returnSuccess();
944
945         return result;
946     }
947
948     public Map JavaDoc removeOrderTerm(int index) {
949         Map JavaDoc result = null;
950         String JavaDoc errMsg = null;
951         this.cart.removeOrderTerm(index);
952         result = ServiceUtil.returnSuccess();
953         return result;
954     }
955
956     /** Get the first SupplierProduct record for productId with matching quantity and currency */
957     public GenericValue getProductSupplier(String JavaDoc productId, Double JavaDoc quantity, String JavaDoc currencyUomId) {
958         GenericValue productSupplier = null;
959         Map JavaDoc params = UtilMisc.toMap("productId", productId,
960                                     "partyId", cart.getPartyId(),
961                                     "currencyUomId", currencyUomId,
962                                     "quantity", quantity);
963         try {
964             Map JavaDoc result = dispatcher.runSync("getSuppliersForProduct", params);
965             List JavaDoc productSuppliers = (List JavaDoc)result.get("supplierProducts");
966             if ((productSuppliers != null) && (productSuppliers.size() > 0)) {
967                 productSupplier=(GenericValue) productSuppliers.get(0);
968             }
969         } catch (GenericServiceException e) {
970             Debug.logWarning(UtilProperties.getMessage(resource_error,"OrderRunServiceGetSuppliersForProductError", cart.getLocale()) + e.getMessage(), module);
971         }
972         return productSupplier;
973     }
974
975 }
976
Popular Tags