KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * $Id: ShoppingCart.java 7271 2006-04-11 00:55:00Z 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.shoppingcart;
25
26 import java.io.Serializable JavaDoc;
27 import java.math.BigDecimal JavaDoc;
28 import java.sql.Timestamp JavaDoc;
29 import java.util.ArrayList JavaDoc;
30 import java.util.Collection JavaDoc;
31 import java.util.Collections JavaDoc;
32 import java.util.Comparator JavaDoc;
33 import java.util.HashMap JavaDoc;
34 import java.util.HashSet JavaDoc;
35 import java.util.Iterator JavaDoc;
36 import java.util.LinkedList JavaDoc;
37 import java.util.List JavaDoc;
38 import java.util.Locale JavaDoc;
39 import java.util.Map JavaDoc;
40 import java.util.Set JavaDoc;
41
42 import org.apache.commons.collections.map.LinkedMap;
43 import org.ofbiz.base.util.Debug;
44 import org.ofbiz.base.util.GeneralException;
45 import org.ofbiz.base.util.UtilDateTime;
46 import org.ofbiz.base.util.UtilFormatOut;
47 import org.ofbiz.base.util.UtilMisc;
48 import org.ofbiz.base.util.UtilProperties;
49 import org.ofbiz.base.util.UtilValidate;
50 import org.ofbiz.entity.GenericDelegator;
51 import org.ofbiz.entity.GenericEntityException;
52 import org.ofbiz.entity.GenericPK;
53 import org.ofbiz.entity.GenericValue;
54 import org.ofbiz.entity.util.EntityUtil;
55 import org.ofbiz.party.contact.ContactHelper;
56 import org.ofbiz.order.order.OrderReadHelper;
57 import org.ofbiz.order.finaccount.FinAccountHelper;
58 import org.ofbiz.order.shoppingcart.product.ProductPromoWorker;
59 import org.ofbiz.order.shoppingcart.shipping.ShippingEstimateWrapper;
60 import org.ofbiz.order.shoppinglist.ShoppingListEvents;
61 import org.ofbiz.product.config.ProductConfigWrapper;
62 import org.ofbiz.product.store.ProductStoreWorker;
63 import org.ofbiz.service.LocalDispatcher;
64
65 /**
66  * Shopping Cart Object
67  *
68  * @author <a HREF="mailto:jaz@ofbiz.org">Andy Zeneski</a>
69  * @author <a HREF="mailto:jonesde@ofbiz.org">David E. Jones</a>
70  * @version $Rev: 7271 $
71  * @since 2.0
72  */

73 public class ShoppingCart implements Serializable JavaDoc {
74
75     public static final String JavaDoc module = ShoppingCart.class.getName();
76     public static final String JavaDoc resource_error = "OrderErrorUiLabels";
77
78     private String JavaDoc orderType = "SALES_ORDER"; // default orderType
79
private String JavaDoc channel = "UNKNWN_SALES_CHANNEL"; // default channel enum
80

81     private String JavaDoc poNumber = null;
82     private String JavaDoc orderId = null;
83     private String JavaDoc firstAttemptOrderId = null;
84     private String JavaDoc externalId = null;
85     private String JavaDoc internalCode = null;
86     private String JavaDoc billingAccountId = null;
87     private double billingAccountAmt = 0.00;
88     private String JavaDoc agreementId = null;
89     private String JavaDoc quoteId = null;
90     private long nextItemSeq = 1;
91
92     private String JavaDoc defaultItemDeliveryDate = null;
93     private String JavaDoc defaultItemComment = null;
94
95     private String JavaDoc orderAdditionalEmails = null;
96     private boolean viewCartOnAdd = false;
97     private boolean readOnlyCart = false;
98
99     private Timestamp JavaDoc lastListRestore = null;
100     private String JavaDoc autoSaveListId = null;
101
102     /** Holds value of order adjustments. */
103     private List JavaDoc adjustments = new LinkedList JavaDoc();
104     // OrderTerms
105
private boolean orderTermSet = false;
106     private List JavaDoc orderTerms = new LinkedList JavaDoc();
107
108     private List JavaDoc cartLines = new LinkedList JavaDoc();
109     private List JavaDoc paymentInfo = new LinkedList JavaDoc();
110     private List JavaDoc shipInfo = new LinkedList JavaDoc();
111     private Map JavaDoc contactMechIdsMap = new HashMap JavaDoc();
112     private Map JavaDoc orderAttributes = new HashMap JavaDoc();
113     private Map JavaDoc attributes = new HashMap JavaDoc(); // user defined attributes
114

115     /** contains a list of partyId for each roleTypeId (key) */
116     private Map JavaDoc additionalPartyRole = new HashMap JavaDoc();
117
118     /** these are defaults for all ship groups */
119     private Timestamp JavaDoc defaultShipAfterDate = null;
120     private Timestamp JavaDoc defaultShipBeforeDate = null;
121     
122     public static class ProductPromoUseInfo implements Serializable JavaDoc {
123         public String JavaDoc productPromoId = null;
124         public String JavaDoc productPromoCodeId = null;
125         public double totalDiscountAmount = 0;
126         public double quantityLeftInActions = 0;
127
128         public ProductPromoUseInfo(String JavaDoc productPromoId, String JavaDoc productPromoCodeId, double totalDiscountAmount, double quantityLeftInActions) {
129             this.productPromoId = productPromoId;
130             this.productPromoCodeId = productPromoCodeId;
131             this.totalDiscountAmount = totalDiscountAmount;
132             this.quantityLeftInActions = quantityLeftInActions;
133         }
134
135         public String JavaDoc getProductPromoId() { return this.productPromoId; }
136         public String JavaDoc getProductPromoCodeId() { return this.productPromoCodeId; }
137         public double getTotalDiscountAmount() { return this.totalDiscountAmount; }
138         public double getQuantityLeftInActions() { return this.quantityLeftInActions; }
139     }
140
141     public static class CartShipInfo implements Serializable JavaDoc {
142         public LinkedMap shipItemInfo = new LinkedMap();
143         public List JavaDoc shipTaxAdj = new LinkedList JavaDoc();
144         public String JavaDoc contactMechId = null;
145         public String JavaDoc shipmentMethodTypeId = null;
146         public String JavaDoc carrierRoleTypeId = null;
147         public String JavaDoc carrierPartyId = null;
148         public String JavaDoc giftMessage = null;
149         public String JavaDoc shippingInstructions = null;
150         public String JavaDoc maySplit = "N";
151         public String JavaDoc isGift = "N";
152         public double shipEstimate = 0.00;
153         public Timestamp JavaDoc shipBeforeDate = null;
154         public Timestamp JavaDoc shipAfterDate = null;
155
156         public List JavaDoc makeItemShipGroupAndAssoc(GenericDelegator delegator, ShoppingCart cart, long groupIndex) {
157             String JavaDoc shipGroupSeqId = UtilFormatOut.formatPaddedNumber(groupIndex, 5);
158             List JavaDoc values = new LinkedList JavaDoc();
159             
160             // create order contact mech for shipping address
161
if (contactMechId != null) {
162                 GenericValue orderCm = delegator.makeValue("OrderContactMech", null);
163                 orderCm.set("contactMechPurposeTypeId", "SHIPPING_LOCATION");
164                 orderCm.set("contactMechId", contactMechId);
165                 values.add(orderCm);
166             }
167
168             // create the ship group
169
GenericValue shipGroup = delegator.makeValue("OrderItemShipGroup", null);
170             shipGroup.set("shipmentMethodTypeId", shipmentMethodTypeId);
171             shipGroup.set("carrierRoleTypeId", carrierRoleTypeId);
172             shipGroup.set("carrierPartyId", carrierPartyId);
173             shipGroup.set("shippingInstructions", shippingInstructions);
174             shipGroup.set("giftMessage", giftMessage);
175             shipGroup.set("contactMechId", contactMechId);
176             shipGroup.set("maySplit", maySplit);
177             shipGroup.set("isGift", isGift);
178             shipGroup.set("shipGroupSeqId", shipGroupSeqId);
179             
180             // use the cart's default ship before and after dates here
181
if ((shipBeforeDate == null) && (cart.getDefaultShipBeforeDate() != null)) {
182                 shipGroup.set("shipByDate", cart.getDefaultShipBeforeDate());
183             } else {
184                 shipGroup.set("shipByDate", shipBeforeDate);
185             }
186             if ((shipAfterDate == null) && (cart.getDefaultShipAfterDate() != null)) {
187                 shipGroup.set("shipAfterDate", cart.getDefaultShipAfterDate());
188             } else {
189                 shipGroup.set("shipAfterDate", shipAfterDate);
190             }
191             
192             values.add(shipGroup);
193
194             // create the shipping estimate adjustments
195
if (shipEstimate != 0) {
196                 GenericValue shipAdj = delegator.makeValue("OrderAdjustment", null);
197                 shipAdj.set("orderAdjustmentTypeId", "SHIPPING_CHARGES");
198                 shipAdj.set("amount", new Double JavaDoc(shipEstimate));
199                 shipAdj.set("shipGroupSeqId", shipGroupSeqId);
200                 values.add(shipAdj);
201             }
202
203             // create the top level tax adjustments
204
Iterator JavaDoc ti = shipTaxAdj.iterator();
205             while (ti.hasNext()) {
206                 GenericValue taxAdj = (GenericValue) ti.next();
207                 taxAdj.set("shipGroupSeqId", shipGroupSeqId);
208                 values.add(taxAdj);
209             }
210
211             // create the ship group item associations
212
Iterator JavaDoc i = shipItemInfo.keySet().iterator();
213             while (i.hasNext()) {
214                 ShoppingCartItem item = (ShoppingCartItem) i.next();
215                 CartShipItemInfo itemInfo = (CartShipItemInfo) shipItemInfo.get(item);
216
217                 GenericValue assoc = delegator.makeValue("OrderItemShipGroupAssoc", null);
218                 assoc.set("orderItemSeqId", item.getOrderItemSeqId());
219                 assoc.set("shipGroupSeqId", shipGroupSeqId);
220                 assoc.set("quantity", new Double JavaDoc(itemInfo.quantity));
221                 values.add(assoc);
222
223                 // create the item tax adjustment
224
Iterator JavaDoc iti = itemInfo.itemTaxAdj.iterator();
225                 while (iti.hasNext()) {
226                     GenericValue taxAdj = (GenericValue) iti.next();
227                     taxAdj.set("orderItemSeqId", item.getOrderItemSeqId());
228                     taxAdj.set("shipGroupSeqId", shipGroupSeqId);
229                     values.add(taxAdj);
230                 }
231             }
232
233             return values;
234         }
235
236         public CartShipItemInfo setItemInfo(ShoppingCartItem item, double quantity, List JavaDoc taxAdj) {
237             CartShipItemInfo itemInfo = (CartShipItemInfo) shipItemInfo.get(item);
238             if (itemInfo == null) {
239                 itemInfo = new CartShipItemInfo();
240                 itemInfo.item = item;
241                 shipItemInfo.put(item, itemInfo);
242             }
243             itemInfo.quantity = quantity;
244             itemInfo.itemTaxAdj.clear();
245             if (taxAdj == null) {
246                 taxAdj = new LinkedList JavaDoc();
247             }
248             itemInfo.itemTaxAdj.addAll(taxAdj);
249             return itemInfo;
250         }
251
252         public CartShipItemInfo setItemInfo(ShoppingCartItem item, List JavaDoc taxAdj) {
253             CartShipItemInfo itemInfo = (CartShipItemInfo) shipItemInfo.get(item);
254             if (itemInfo == null) {
255                 itemInfo = new CartShipItemInfo();
256                 itemInfo.item = item;
257                 shipItemInfo.put(item, itemInfo);
258             }
259             itemInfo.itemTaxAdj.clear();
260             if (taxAdj == null) {
261                 taxAdj = new LinkedList JavaDoc();
262             }
263             itemInfo.itemTaxAdj.addAll(taxAdj);
264             return itemInfo;
265         }
266
267         public CartShipItemInfo setItemInfo(ShoppingCartItem item, double quantity) {
268             CartShipItemInfo itemInfo = (CartShipItemInfo) shipItemInfo.get(item);
269             if (itemInfo == null) {
270                 itemInfo = new CartShipItemInfo();
271                 itemInfo.item = item;
272                 shipItemInfo.put(item, itemInfo);
273             }
274             itemInfo.quantity = quantity;
275             return itemInfo;
276         }
277
278         public CartShipItemInfo getShipItemInfo(ShoppingCartItem item) {
279             return (CartShipItemInfo) shipItemInfo.get(item);
280         }
281
282         public Set JavaDoc getShipItems() {
283             return shipItemInfo.keySet();
284         }
285
286         /**
287          * Reset the ship group's shipBeforeDate if it is after the parameter
288          * @param newShipBeforeDate
289          */

290         public void resetShipBeforeDateIfAfter(Timestamp JavaDoc newShipBeforeDate) {
291             if (newShipBeforeDate != null) {
292                 if ((this.shipBeforeDate == null) || (!this.shipBeforeDate.before(newShipBeforeDate))) {
293                     this.shipBeforeDate = newShipBeforeDate;
294                 }
295             }
296         }
297         
298         /**
299          * Reset the ship group's shipAfterDate if it is before the parameter
300          * @param newShipBeforeDate
301          */

302         public void resetShipAfterDateIfBefore(Timestamp JavaDoc newShipAfterDate) {
303             if (newShipAfterDate != null) {
304                 if ((this.shipAfterDate == null) || (!this.shipAfterDate.after(newShipAfterDate))) {
305                     this.shipAfterDate = newShipAfterDate;
306                 }
307             }
308         }
309         
310         public double getTotalTax(ShoppingCart cart) {
311             double taxTotal = 0.00;
312             for (int i = 0; i < shipTaxAdj.size(); i++) {
313                 GenericValue v = (GenericValue) shipTaxAdj.get(i);
314                 taxTotal += OrderReadHelper.calcOrderAdjustment(v, cart.getSubTotal());
315             }
316
317             Iterator JavaDoc iter = shipItemInfo.values().iterator();
318             while (iter.hasNext()) {
319                 CartShipItemInfo info = (CartShipItemInfo) iter.next();
320                 taxTotal += info.getItemTax(cart);
321             }
322
323             return taxTotal;
324         }
325
326         public static class CartShipItemInfo implements Serializable JavaDoc {
327             public List JavaDoc itemTaxAdj = new LinkedList JavaDoc();
328             public ShoppingCartItem item = null;
329             public double quantity = 0;
330
331             public double getItemTax(ShoppingCart cart) {
332                 double itemTax = 0.00;
333
334                 for (int i = 0; i < itemTaxAdj.size(); i++) {
335                     GenericValue v = (GenericValue) itemTaxAdj.get(i);
336                     itemTax += OrderReadHelper.calcItemAdjustment(v, new Double JavaDoc(quantity), new Double JavaDoc(item.getBasePrice()));
337                 }
338
339                 return itemTax;
340             }
341
342             public double getItemQuantity() {
343                 return this.quantity;
344             }
345         }
346     }
347
348     public static class CartPaymentInfo implements Serializable JavaDoc, Comparable JavaDoc {
349         public String JavaDoc paymentMethodTypeId = null;
350         public String JavaDoc paymentMethodId = null;
351         public String JavaDoc securityCode = null;
352         public String JavaDoc postalCode = null;
353         public String JavaDoc[] refNum = new String JavaDoc[2];
354         public Double JavaDoc amount = null;
355         public boolean singleUse = false;
356         public boolean isPresent = false;
357         public boolean overflow = false;
358
359         public GenericValue getValueObject(GenericDelegator delegator) {
360             String JavaDoc entityName = null;
361             Map JavaDoc lookupFields = null;
362             if (paymentMethodId != null) {
363                 lookupFields = UtilMisc.toMap("paymentMethodId", paymentMethodId);
364                 entityName = "PaymentMethod";
365             } else if (paymentMethodTypeId != null) {
366                 lookupFields = UtilMisc.toMap("paymentMethodTypeId", paymentMethodTypeId);
367                 entityName = "PaymentMethodType";
368             } else {
369                 throw new IllegalArgumentException JavaDoc("Could not create value object because paymentMethodId and paymentMethodTypeId are null");
370             }
371
372             try {
373                 return delegator.findByPrimaryKeyCache(entityName, lookupFields);
374             } catch (GenericEntityException e) {
375                 Debug.logError(e, module);
376             }
377
378             return null;
379         }
380
381         public GenericValue getBillingAddress(GenericDelegator delegator) {
382             GenericValue valueObj = this.getValueObject(delegator);
383             GenericValue postalAddress = null;
384
385             if ("PaymentMethod".equals(valueObj.getEntityName())) {
386                 String JavaDoc paymentMethodTypeId = valueObj.getString("paymentMethodTypeId");
387                 String JavaDoc paymentMethodId = valueObj.getString("paymentMethodId");
388                 Map JavaDoc lookupFields = UtilMisc.toMap("paymentMethodId", paymentMethodId);
389
390                 // billing account, credit card, gift card, eft account all have postal address
391
try {
392                     GenericValue pmObj = null;
393                     if ("CREDIT_CARD".equals(paymentMethodTypeId)) {
394                         pmObj = delegator.findByPrimaryKey("CreditCard", lookupFields);
395                     } else if ("GIFT_CARD".equals(paymentMethodTypeId)) {
396                         pmObj = delegator.findByPrimaryKey("GiftCard", lookupFields);
397                     } else if ("EFT_ACCOUNT".equals(paymentMethodTypeId)) {
398                         pmObj = delegator.findByPrimaryKey("EftAccount", lookupFields);
399                     } else if ("EXT_BILLACT".equals(paymentMethodTypeId)) {
400                         pmObj = delegator.findByPrimaryKey("BillingAccount", lookupFields);
401                     }
402                     if (pmObj != null) {
403                         postalAddress = pmObj.getRelatedOne("PostalAddress");
404                     } else {
405                         Debug.logInfo("No PaymentMethod Object Found - " + paymentMethodId, module);
406                     }
407                 } catch (GenericEntityException e) {
408                     Debug.logError(e, module);
409                 }
410             }
411
412             return postalAddress;
413         }
414
415         public List JavaDoc makeOrderPaymentInfos(GenericDelegator delegator) {
416             GenericValue valueObj = this.getValueObject(delegator);
417             List JavaDoc values = new LinkedList JavaDoc();
418             if (valueObj != null) {
419                 // first create a BILLING_LOCATION for the payment method address if there is one
420
if ("PaymentMethod".equals(valueObj.getEntityName())) {
421                     String JavaDoc paymentMethodTypeId = valueObj.getString("paymentMethodTypeId");
422                     String JavaDoc paymentMethodId = valueObj.getString("paymentMethodId");
423                     Map JavaDoc lookupFields = UtilMisc.toMap("paymentMethodId", paymentMethodId);
424                     String JavaDoc billingAddressId = null;
425
426                     GenericValue billingAddress = this.getBillingAddress(delegator);
427                     if (billingAddress != null) {
428                         billingAddressId = billingAddress.getString("contactMechId");
429                     }
430
431                     if (UtilValidate.isNotEmpty(billingAddressId)) {
432                         GenericValue orderCm = delegator.makeValue("OrderContactMech", null);
433                         orderCm.set("contactMechPurposeTypeId", "BILLING_LOCATION");
434                         orderCm.set("contactMechId", billingAddressId);
435                         values.add(orderCm);
436                     }
437                 }
438
439                 // create the OrderPaymentPreference record
440
GenericValue opp = delegator.makeValue("OrderPaymentPreference", new HashMap JavaDoc());
441                 opp.set("paymentMethodTypeId", valueObj.getString("paymentMethodTypeId"));
442                 opp.set("presentFlag", isPresent ? "Y" : "N");
443                 opp.set("overflowFlag", overflow ? "Y" : "N");
444                 opp.set("paymentMethodId", paymentMethodId);
445                 opp.set("billingPostalCode", postalCode);
446                 opp.set("maxAmount", amount);
447                 if (refNum != null) {
448                     opp.set("manualRefNum", refNum[0]);
449                     opp.set("manualAuthCode", refNum[1]);
450                 }
451                 if (securityCode != null) {
452                     opp.set("securityCode", securityCode);
453                 }
454                 if (paymentMethodId != null) {
455                     opp.set("statusId", "PAYMENT_NOT_AUTH");
456                 } else if (paymentMethodTypeId != null) {
457                     // external payment method types require notification when received
458
// internal payment method types are assumed to be in-hand
459
if (paymentMethodTypeId.startsWith("EXT_")) {
460                         opp.set("statusId", "PAYMENT_NOT_RECEIVED");
461                     } else {
462                         opp.set("statusId", "PAYMENT_RECEIVED");
463                     }
464                 }
465                 Debug.log("Creating OrderPaymentPreference - " + opp, module);
466                 values.add(opp);
467             }
468
469             return values;
470         }
471
472         public int compareTo(Object JavaDoc o) {
473             CartPaymentInfo that = (CartPaymentInfo) o;
474             Debug.logInfo("Compare [" + this.toString() + "] to [" + that.toString() + "]", module);
475             if (this.paymentMethodId != null) {
476                 if (that.paymentMethodId == null) {
477                     return 1;
478                 } else {
479                     int pmCmp = this.paymentMethodId.compareTo(that.paymentMethodId);
480                     if (pmCmp == 0) {
481                         if (this.refNum != null && this.refNum[0] != null) {
482                             if (that.refNum != null && that.refNum[0] != null) {
483                                 return this.refNum[0].compareTo(that.refNum[0]);
484                             } else {
485                                 return 1;
486                             }
487                         } else {
488                             if (that.refNum != null && that.refNum[0] != null) {
489                                 return -1;
490                             } else {
491                                 return 0;
492                             }
493                         }
494                     } else {
495                         return pmCmp;
496                     }
497                 }
498             } else {
499                 if (that.paymentMethodId != null) {
500                     return -1;
501                 } else {
502                     int pmtCmp = this.paymentMethodTypeId.compareTo(that.paymentMethodTypeId);
503                     if (pmtCmp == 0) {
504                         if (this.refNum != null && this.refNum[0] != null) {
505                             if (that.refNum != null && that.refNum[0] != null) {
506                                 return this.refNum[0].compareTo(that.refNum[0]);
507                             } else {
508                                 return 1;
509                             }
510                         } else {
511                             if (that.refNum != null && that.refNum[0] != null) {
512                                 return -1;
513                             } else {
514                                 return 0;
515                             }
516                         }
517                     } else {
518                         return pmtCmp;
519                     }
520                 }
521             }
522         }
523
524         public String JavaDoc toString() {
525             return "Pm: " + paymentMethodId + " / PmType: " + paymentMethodTypeId + " / Amt: " + amount + " / Ref: " + refNum[0] + "!" + refNum[1];
526         }
527     }
528
529     /** Contains a List for each productPromoId (key) containing a productPromoCodeId (or empty string for no code) for each use of the productPromoId */
530     private List JavaDoc productPromoUseInfoList = new LinkedList JavaDoc();
531     /** Contains the promo codes entered */
532     private Set JavaDoc productPromoCodes = new HashSet JavaDoc();
533     private List JavaDoc freeShippingProductPromoActions = new ArrayList JavaDoc();
534     /** Note that even though this is promotion info, it should NOT be cleared when the promos are cleared, it is a preference that will be used in the next promo calculation */
535     private Map JavaDoc desiredAlternateGiftByAction = new HashMap JavaDoc();
536     private Timestamp JavaDoc cartCreatedTs = UtilDateTime.nowTimestamp();
537
538     private transient GenericDelegator delegator = null;
539     private String JavaDoc delegatorName = null;
540
541     protected String JavaDoc productStoreId = null;
542     protected String JavaDoc transactionId = null;
543     protected String JavaDoc facilityId = null;
544     protected String JavaDoc webSiteId = null;
545     protected String JavaDoc terminalId = null;
546
547     /** General partyId for the Order, all other IDs default to this one if not specified explicitly */
548     protected String JavaDoc orderPartyId = null;
549
550     // sales order parties
551
protected String JavaDoc placingCustomerPartyId = null;
552     protected String JavaDoc billToCustomerPartyId = null;
553     protected String JavaDoc shipToCustomerPartyId = null;
554     protected String JavaDoc endUserCustomerPartyId = null;
555
556     // purchase order parties
557
protected String JavaDoc billFromVendorPartyId = null;
558     protected String JavaDoc shipFromVendorPartyId = null;
559     protected String JavaDoc supplierAgentPartyId = null;
560
561     protected GenericValue userLogin = null;
562     protected GenericValue autoUserLogin = null;
563
564     protected Locale JavaDoc locale; // holds the locale from the user session
565
protected String JavaDoc currencyUom = null;
566     protected boolean holdOrder = false;
567     protected Timestamp JavaDoc orderDate = null;
568
569     /** don't allow empty constructor */
570     protected ShoppingCart() {}
571
572     /** Creates a new cloned ShoppingCart Object. */
573     public ShoppingCart(ShoppingCart cart) {
574         this.delegator = cart.getDelegator();
575         this.delegatorName = delegator.getDelegatorName();
576         this.productStoreId = cart.getProductStoreId();
577         this.poNumber = cart.getPoNumber();
578         this.orderId = cart.getOrderId();
579         this.firstAttemptOrderId = cart.getFirstAttemptOrderId();
580         this.billingAccountId = cart.getBillingAccountId();
581         this.agreementId = cart.getAgreementId();
582         this.quoteId = cart.getQuoteId();
583         this.orderAdditionalEmails = cart.getOrderAdditionalEmails();
584         this.adjustments = new LinkedList JavaDoc(cart.getAdjustments());
585         this.contactMechIdsMap = new HashMap JavaDoc(cart.getOrderContactMechIds());
586         this.freeShippingProductPromoActions = new ArrayList JavaDoc(cart.getFreeShippingProductPromoActions());
587         this.desiredAlternateGiftByAction = cart.getAllDesiredAlternateGiftByActionCopy();
588         this.productPromoUseInfoList = new LinkedList JavaDoc(cart.productPromoUseInfoList);
589         this.productPromoCodes = new HashSet JavaDoc(cart.productPromoCodes);
590         this.locale = cart.getLocale();
591         this.currencyUom = cart.getCurrency();
592         this.externalId = cart.getExternalId();
593         this.internalCode = cart.getInternalCode();
594         this.viewCartOnAdd = cart.viewCartOnAdd();
595         this.defaultShipAfterDate = cart.getDefaultShipAfterDate();
596         this.defaultShipBeforeDate = cart.getDefaultShipBeforeDate();
597         
598         // clone the additionalPartyRoleMap
599
this.additionalPartyRole = new HashMap JavaDoc();
600         Iterator JavaDoc it = cart.additionalPartyRole.entrySet().iterator();
601         while (it.hasNext()) {
602             Map.Entry JavaDoc me = (Map.Entry JavaDoc) it.next();
603             this.additionalPartyRole.put(me.getKey(), new LinkedList JavaDoc((Collection JavaDoc) me.getValue()));
604         }
605
606         // clone the items
607
List JavaDoc items = cart.items();
608         Iterator JavaDoc itIt = items.iterator();
609         while (itIt.hasNext()) {
610             cartLines.add(new ShoppingCartItem((ShoppingCartItem) itIt.next()));
611         }
612     }
613
614     /** Creates new empty ShoppingCart object. */
615     public ShoppingCart(GenericDelegator delegator, String JavaDoc productStoreId, String JavaDoc webSiteId, Locale JavaDoc locale, String JavaDoc currencyUom, String JavaDoc billToCustomerPartyId, String JavaDoc billFromVendorPartyId) {
616         this.delegator = delegator;
617         this.delegatorName = delegator.getDelegatorName();
618         this.productStoreId = productStoreId;
619         this.webSiteId = webSiteId;
620         this.currencyUom = currencyUom;
621         this.locale = locale;
622         if (this.locale == null) {
623             this.locale = Locale.getDefault();
624         }
625
626         if (productStoreId == null) {
627             throw new IllegalArgumentException JavaDoc("productStoreId cannot be null");
628         }
629
630         // set the default view cart on add for this store
631
GenericValue productStore = ProductStoreWorker.getProductStore(productStoreId, delegator);
632         if (productStore == null) {
633             throw new IllegalArgumentException JavaDoc("Unable to locate ProductStore by ID [" + productStoreId + "]");
634         }
635         
636         String JavaDoc storeViewCartOnAdd = productStore.getString("viewCartOnAdd");
637         if (storeViewCartOnAdd != null && "Y".equalsIgnoreCase(storeViewCartOnAdd)) {
638             this.viewCartOnAdd = true;
639         }
640
641         if (billFromVendorPartyId == null) {
642             // since default cart is of type SALES_ORDER, set to store's payToPartyId
643
this.billFromVendorPartyId = productStore.getString("payToPartyId");
644         } else {
645             this.billFromVendorPartyId = billFromVendorPartyId;
646         }
647         this.billToCustomerPartyId = billToCustomerPartyId;
648     }
649
650
651     /** Creates new empty ShoppingCart object. */
652     public ShoppingCart(GenericDelegator delegator, String JavaDoc productStoreId, String JavaDoc webSiteId, Locale JavaDoc locale, String JavaDoc currencyUom) {
653         this(delegator, productStoreId, webSiteId, locale, currencyUom, null, null);
654     }
655
656     /** Creates a new empty ShoppingCart object. */
657     public ShoppingCart(GenericDelegator delegator, String JavaDoc productStoreId, Locale JavaDoc locale, String JavaDoc currencyUom) {
658         this(delegator, productStoreId, null, locale, currencyUom);
659     }
660
661     public GenericDelegator getDelegator() {
662         if (delegator == null) {
663             delegator = GenericDelegator.getGenericDelegator(delegatorName);
664         }
665         return delegator;
666     }
667
668     public String JavaDoc getProductStoreId() {
669         return this.productStoreId;
670     }
671
672     /**
673      * This is somewhat of a dangerous method, changing the productStoreId changes a lot of stuff including:
674      * - some items in the cart may not be valid in any catalog in the new store
675      * - promotions need to be recalculated for the products that remain
676      * - what else? lots of settings on the ProductStore...
677      *
678      * So for now this can only be called if the cart is empty... otherwise it wil throw an exception
679      *
680      */

681     public void setProductStoreId(String JavaDoc productStoreId) {
682         if ((productStoreId == null && this.productStoreId == null) || (productStoreId != null && productStoreId.equals(this.productStoreId))) {
683             return;
684         }
685
686         if (this.size() == 0) {
687             this.productStoreId = productStoreId;
688         } else {
689             throw new IllegalArgumentException JavaDoc("Cannot set productStoreId when the cart is not empty; cart size is " + this.size());
690         }
691     }
692
693     public String JavaDoc getTransactionId() {
694         return this.transactionId;
695     }
696
697     public void setTransactionId(String JavaDoc transactionId) {
698         this.transactionId = transactionId;
699     }
700
701     public String JavaDoc getTerminalId() {
702         return this.terminalId;
703     }
704
705     public void setTerminalId(String JavaDoc terminalId) {
706         this.terminalId = terminalId;
707     }
708
709     public String JavaDoc getFacilityId() {
710         return this.facilityId;
711     }
712
713     public void setFacilityId(String JavaDoc facilityId) {
714         this.facilityId = facilityId;
715     }
716
717     public Locale JavaDoc getLocale() {
718         return locale;
719     }
720
721     public void setLocale(Locale JavaDoc locale) {
722         this.locale = locale;
723     }
724
725     public void setAttribute(String JavaDoc name, Object JavaDoc value) {
726         this.attributes.put(name, value);
727     }
728
729     public Object JavaDoc getAttribute(String JavaDoc name) {
730         return this.attributes.get(name);
731     }
732
733     public void removeOrderAttribute(String JavaDoc name) {
734         this.orderAttributes.remove(name);
735     }
736
737     public void setOrderAttribute(String JavaDoc name, String JavaDoc value) {
738         this.orderAttributes.put(name, value);
739     }
740
741     public String JavaDoc getOrderAttribute(String JavaDoc name) {
742         return (String JavaDoc) this.orderAttributes.get(name);
743     }
744
745     public void setHoldOrder(boolean b) {
746         this.holdOrder = b;
747     }
748
749     public boolean getHoldOrder() {
750         return this.holdOrder;
751     }
752
753     public void setOrderDate(Timestamp JavaDoc t) {
754         this.orderDate = t;
755     }
756
757     public Timestamp JavaDoc getOrderDate() {
758         return this.orderDate;
759     }
760     
761     /** Sets the currency for the cart. */
762     public void setCurrency(LocalDispatcher dispatcher, String JavaDoc currencyUom) throws CartItemModifyException {
763         if (isReadOnlyCart()) {
764            throw new CartItemModifyException("Cart items cannot be changed");
765         }
766         String JavaDoc previousCurrency = this.currencyUom;
767         this.currencyUom = currencyUom;
768         if (!previousCurrency.equals(this.currencyUom)) {
769             Iterator JavaDoc itemIterator = this.iterator();
770             while (itemIterator.hasNext()) {
771                 ShoppingCartItem item = (ShoppingCartItem) itemIterator.next();
772                 item.updatePrice(dispatcher, this);
773             }
774         }
775     }
776
777     /** Get the current currency setting. */
778     public String JavaDoc getCurrency() {
779         if (this.currencyUom != null) {
780             return this.currencyUom;
781         } else {
782             // uh oh, not good, should always be passed in on init, we can't really do anything without it, so throw an exception
783
throw new IllegalStateException JavaDoc("The Currency UOM is not set in the shopping cart, this is not a valid state, it should always be passed in when the cart is created.");
784         }
785     }
786
787     public Timestamp JavaDoc getCartCreatedTime() {
788         return this.cartCreatedTs;
789     }
790
791     private GenericValue getSupplierProduct(String JavaDoc productId, double quantity, LocalDispatcher dispatcher) {
792         GenericValue supplierProduct = null;
793         Map JavaDoc params = UtilMisc.toMap("productId", productId,
794                                     "partyId", this.getPartyId(),
795                                     "currencyUomId", this.getCurrency(),
796                                     "quantity", new Double JavaDoc(quantity));
797         try {
798             Map JavaDoc result = dispatcher.runSync("getSuppliersForProduct", params);
799             List JavaDoc productSuppliers = (List JavaDoc)result.get("supplierProducts");
800             if ((productSuppliers != null) && (productSuppliers.size() > 0)) {
801                 supplierProduct = (GenericValue) productSuppliers.get(0);
802             }
803             //} catch (GenericServiceException e) {
804
} catch (Exception JavaDoc e) {
805             Debug.logWarning(UtilProperties.getMessage(resource_error,"OrderRunServiceGetSuppliersForProductError", locale) + e.getMessage(), module);
806         }
807         return supplierProduct;
808     }
809
810     // =======================================================================
811
// Methods for cart items
812
// =======================================================================
813

814     /** Add an item to the shopping cart, or if already there, increase the quantity.
815      * @return the new/increased item index
816      * @throws CartItemModifyException
817      */

818     public int addOrIncreaseItem(String JavaDoc productId, double selectedAmount, double quantity, Timestamp JavaDoc reservStart, double reservLength, double reservPersons, Timestamp JavaDoc shipBeforeDate, Timestamp JavaDoc shipAfterDate, Map JavaDoc features, Map JavaDoc attributes, String JavaDoc prodCatalogId, ProductConfigWrapper configWrapper, LocalDispatcher dispatcher) throws CartItemModifyException, ItemNotFoundException {
819         if (isReadOnlyCart()) {
820            throw new CartItemModifyException("Cart items cannot be changed");
821         }
822         
823         GenericValue supplierProduct = null;
824         // Check for existing cart item.
825
for (int i = 0; i < this.cartLines.size(); i++) {
826             ShoppingCartItem sci = (ShoppingCartItem) cartLines.get(i);
827
828             if (sci.equals(productId, reservStart, reservLength, reservPersons, features, attributes, prodCatalogId, configWrapper, selectedAmount)) {
829                 double newQuantity = sci.getQuantity() + quantity;
830
831                 if (Debug.verboseOn()) Debug.logVerbose("Found a match for id " + productId + " on line " + i + ", updating quantity to " + newQuantity, module);
832                 sci.setQuantity(newQuantity, dispatcher, this);
833
834                 if (getOrderType().equals("PURCHASE_ORDER")) {
835                     supplierProduct = getSupplierProduct(productId, newQuantity, dispatcher);
836                     if (supplierProduct != null && supplierProduct.getDouble("lastPrice") != null) {
837                         sci.setBasePrice(supplierProduct.getDouble("lastPrice").doubleValue());
838                         sci.setName(ShoppingCartItem.getPurchaseOrderItemDescription(sci.getProduct(), supplierProduct, this.getLocale()));
839                     } else {
840                        throw new CartItemModifyException("SupplierProduct not found");
841                     }
842                  }
843                 return i;
844             }
845         }
846         // Add the new item to the shopping cart if it wasn't found.
847
if (getOrderType().equals("PURCHASE_ORDER")) {
848             //GenericValue productSupplier = null;
849
supplierProduct = getSupplierProduct(productId, quantity, dispatcher);
850             if (supplierProduct != null || "_NA_".equals(this.getPartyId())) {
851                  return this.addItem(0, ShoppingCartItem.makePurchaseOrderItem(new Integer JavaDoc(0), productId, selectedAmount, quantity, features, attributes, prodCatalogId, configWrapper, dispatcher, this, supplierProduct, shipBeforeDate, shipAfterDate));
852             } else {
853                 throw new CartItemModifyException("SupplierProduct not found");
854             }
855         } else {
856             return this.addItem(0, ShoppingCartItem.makeItem(new Integer JavaDoc(0), productId, selectedAmount, quantity, reservStart, reservLength, reservPersons, shipBeforeDate, shipAfterDate, features, attributes, prodCatalogId, configWrapper, dispatcher, this));
857         }
858     }
859     public int addOrIncreaseItem(String JavaDoc productId, double selectedAmount, double quantity, Map JavaDoc features, Map JavaDoc attributes, String JavaDoc prodCatalogId, LocalDispatcher dispatcher) throws CartItemModifyException, ItemNotFoundException {
860         return addOrIncreaseItem(productId, 0.00, quantity, null, 0.00 ,0.00, null, null, features, attributes, prodCatalogId, null, dispatcher);
861     }
862     public int addOrIncreaseItem(String JavaDoc productId, double quantity, Map JavaDoc features, Map JavaDoc attributes, String JavaDoc prodCatalogId, LocalDispatcher dispatcher) throws CartItemModifyException, ItemNotFoundException {
863         return addOrIncreaseItem(productId, 0.00, quantity, null, 0.00 ,0.00, null, null, features, attributes, prodCatalogId, null, dispatcher);
864     }
865     public int addOrIncreaseItem(String JavaDoc productId, double quantity, Timestamp JavaDoc reservStart, double reservLength, double reservPersons, Map JavaDoc features, Map JavaDoc attributes, String JavaDoc prodCatalogId, LocalDispatcher dispatcher) throws CartItemModifyException, ItemNotFoundException {
866         return addOrIncreaseItem(productId, 0.00, quantity, reservStart, reservLength, reservPersons, null, null, features, attributes, prodCatalogId, null, dispatcher);
867     }
868     public int addOrIncreaseItem(String JavaDoc productId, double quantity, LocalDispatcher dispatcher) throws CartItemModifyException, ItemNotFoundException {
869         return addOrIncreaseItem(productId, quantity, null, null, null, dispatcher);
870     }
871
872     /** Add a non-product item to the shopping cart.
873      * @return the new item index
874      * @throws CartItemModifyException
875      */

876     public int addNonProductItem(String JavaDoc itemType, String JavaDoc description, String JavaDoc categoryId, double price, double quantity, Map JavaDoc attributes, String JavaDoc prodCatalogId, LocalDispatcher dispatcher) throws CartItemModifyException {
877         return this.addItem(0, ShoppingCartItem.makeItem(new Integer JavaDoc(0), itemType, description, categoryId, price, 0.00, quantity, attributes, prodCatalogId, dispatcher, this, true));
878     }
879
880     /** Add an item to the shopping cart. */
881     public int addItem(int index, ShoppingCartItem item) throws CartItemModifyException {
882         if (isReadOnlyCart()) {
883            throw new CartItemModifyException("Cart items cannot be changed");
884         }
885         if (!cartLines.contains(item)) {
886             cartLines.add(index, item);
887             return index;
888         } else {
889             return this.getItemIndex(item);
890         }
891     }
892
893     /** Add an item to the shopping cart. */
894     public int addItemToEnd(String JavaDoc productId, double amount, double quantity, HashMap JavaDoc features, HashMap JavaDoc attributes, String JavaDoc prodCatalogId, LocalDispatcher dispatcher, boolean triggerExternalOps) throws CartItemModifyException, ItemNotFoundException {
895         return addItemToEnd(ShoppingCartItem.makeItem(null, productId, amount, quantity, features, attributes, prodCatalogId, null, dispatcher, this, triggerExternalOps));
896     }
897
898     /** Add an item to the shopping cart. */
899     public int addItemToEnd(String JavaDoc productId, double amount, double quantity, double unitPrice, HashMap JavaDoc features, HashMap JavaDoc attributes, String JavaDoc prodCatalogId, LocalDispatcher dispatcher, boolean triggerExternalOps, boolean triggerPriceRules) throws CartItemModifyException, ItemNotFoundException {
900         return addItemToEnd(ShoppingCartItem.makeItem(null, productId, amount, quantity, unitPrice, null, 0.00, 0.00, null, null, features, attributes, prodCatalogId, null, dispatcher, this, triggerExternalOps, triggerPriceRules));
901     }
902
903     /** Add an item to the shopping cart. */
904     public int addItemToEnd(String JavaDoc productId, double amount, double quantity, HashMap JavaDoc features, HashMap JavaDoc attributes, String JavaDoc prodCatalogId, LocalDispatcher dispatcher) throws CartItemModifyException, ItemNotFoundException {
905         return addItemToEnd(ShoppingCartItem.makeItem(null, productId, amount, quantity, features, attributes, prodCatalogId, dispatcher, this));
906     }
907
908     /** Add an item to the shopping cart. */
909     public int addItemToEnd(ShoppingCartItem item) throws CartItemModifyException {
910         if (isReadOnlyCart()) {
911            throw new CartItemModifyException("Cart items cannot be changed");
912         }
913         if (!cartLines.contains(item)) {
914             cartLines.add(item);
915             return cartLines.size() - 1;
916         } else {
917             return this.getItemIndex(item);
918         }
919     }
920
921     /** Get a ShoppingCartItem from the cart object. */
922     public ShoppingCartItem findCartItem(String JavaDoc productId, Map JavaDoc features, Map JavaDoc attributes, String JavaDoc prodCatalogId, double selectedAmount) {
923         // Check for existing cart item.
924
for (int i = 0; i < this.cartLines.size(); i++) {
925             ShoppingCartItem cartItem = (ShoppingCartItem) cartLines.get(i);
926
927             if (cartItem.equals(productId, features, attributes, prodCatalogId, selectedAmount)) {
928                 return cartItem;
929             }
930         }
931         return null;
932     }
933
934     /** Get all ShoppingCartItems from the cart object with the given productId. */
935     public List JavaDoc findAllCartItems(String JavaDoc productId) {
936         if (productId == null) return new LinkedList JavaDoc(this.cartLines);
937         List JavaDoc itemsToReturn = new LinkedList JavaDoc();
938
939         // Check for existing cart item.
940
for (int i = 0; i < this.cartLines.size(); i++) {
941             ShoppingCartItem cartItem = (ShoppingCartItem) cartLines.get(i);
942
943             if (productId.equals(cartItem.getProductId())) {
944                 itemsToReturn.add(cartItem);
945             }
946         }
947         return itemsToReturn;
948     }
949
950     /** Remove quantity 0 ShoppingCartItems from the cart object. */
951     public void removeEmptyCartItems() {
952         // Check for existing cart item.
953
for (int i = 0; i < this.cartLines.size();) {
954             ShoppingCartItem cartItem = (ShoppingCartItem) cartLines.get(i);
955
956             if (cartItem.getQuantity() == 0.0) {
957                 this.clearItemShipInfo(cartItem);
958                 cartLines.remove(i);
959             } else {
960                 i++;
961             }
962         }
963     }
964
965     public boolean containAnyWorkEffortCartItems() {
966         // Check for existing cart item.
967
for (int i = 0; i < this.cartLines.size();) {
968             ShoppingCartItem cartItem = (ShoppingCartItem) cartLines.get(i);
969             if (cartItem.getItemType().equals("RENTAL_ORDER_ITEM")) { // create workeffort items?
970
return true;
971             } else {
972                 i++;
973             }
974         }
975         return false;
976     }
977
978     public boolean containAllWorkEffortCartItems() {
979         // Check for existing cart item.
980
for (int i = 0; i < this.cartLines.size();) {
981             ShoppingCartItem cartItem = (ShoppingCartItem) cartLines.get(i);
982             if (!cartItem.getItemType().equals("RENTAL_ORDER_ITEM")) { // not a item to create workefforts?
983
return false;
984             } else {
985                 i++;
986             }
987         }
988         return true;
989     }
990
991     /** Returns this item's index. */
992     public int getItemIndex(ShoppingCartItem item) {
993         return cartLines.indexOf(item);
994     }
995
996     /** Get a ShoppingCartItem from the cart object. */
997     public ShoppingCartItem findCartItem(int index) {
998         if (cartLines.size() <= index)
999             return null;
1000        return (ShoppingCartItem) cartLines.get(index);
1001    }
1002
1003    public ShoppingCartItem findCartItem(String JavaDoc orderItemSeqId) {
1004        if (orderItemSeqId != null) {
1005            for (int i = 0; i < this.cartLines.size(); i++) {
1006                ShoppingCartItem cartItem = (ShoppingCartItem) cartLines.get(i);
1007                String JavaDoc itemSeqId = cartItem.getOrderItemSeqId();
1008                if (itemSeqId != null && orderItemSeqId.equals(itemSeqId)) {
1009                    return cartItem;
1010                }
1011            }
1012        }
1013        return null;
1014    }
1015
1016    /** Remove an item from the cart object. */
1017    public void removeCartItem(int index, LocalDispatcher dispatcher) throws CartItemModifyException {
1018        if (isReadOnlyCart()) {
1019           throw new CartItemModifyException("Cart items cannot be changed");
1020        }
1021        if (index < 0) return;
1022        if (cartLines.size() <= index) return;
1023        ShoppingCartItem item = (ShoppingCartItem) cartLines.remove(index);
1024
1025        // set quantity to 0 to trigger necessary events
1026
item.setQuantity(0.0, dispatcher, this);
1027    }
1028
1029    /** Moves a line item to a differnt index. */
1030    public void moveCartItem(int fromIndex, int toIndex) {
1031        if (toIndex < fromIndex) {
1032            cartLines.add(toIndex, cartLines.remove(fromIndex));
1033        } else if (toIndex > fromIndex) {
1034            cartLines.add(toIndex - 1, cartLines.remove(fromIndex));
1035        }
1036    }
1037
1038    /** Returns the number of items in the cart object. */
1039    public int size() {
1040        return cartLines.size();
1041    }
1042
1043    /** Returns a Collection of items in the cart object. */
1044    public List JavaDoc items() {
1045        return cartLines;
1046    }
1047
1048    /** Returns an iterator of cart items. */
1049    public Iterator JavaDoc iterator() {
1050        return cartLines.iterator();
1051    }
1052
1053    /** Gets the userLogin associated with the cart; may be null */
1054    public GenericValue getUserLogin() {
1055        return this.userLogin;
1056    }
1057
1058    public void setUserLogin(GenericValue userLogin, LocalDispatcher dispatcher) throws CartItemModifyException {
1059        this.userLogin = userLogin;
1060        this.handleNewUser(dispatcher);
1061    }
1062
1063    protected void setUserLogin(GenericValue userLogin) {
1064        if (this.userLogin == null) {
1065            this.userLogin = userLogin;
1066        } else {
1067            throw new IllegalArgumentException JavaDoc("Cannot change UserLogin object with this method");
1068        }
1069    }
1070
1071    public GenericValue getAutoUserLogin() {
1072        return this.autoUserLogin;
1073    }
1074
1075    public void setAutoUserLogin(GenericValue autoUserLogin, LocalDispatcher dispatcher) throws CartItemModifyException {
1076        this.autoUserLogin = autoUserLogin;
1077        if (getUserLogin() == null) {
1078            this.handleNewUser(dispatcher);
1079        }
1080    }
1081
1082    protected void setAutoUserLogin(GenericValue autoUserLogin) {
1083        if (this.autoUserLogin == null) {
1084            this.autoUserLogin = autoUserLogin;
1085        } else {
1086            throw new IllegalArgumentException JavaDoc("Cannot change AutoUserLogin object with this method");
1087        }
1088    }
1089
1090    public void handleNewUser(LocalDispatcher dispatcher) throws CartItemModifyException {
1091        String JavaDoc partyId = this.getPartyId();
1092        if (UtilValidate.isNotEmpty(partyId)) {
1093            // recalculate all prices
1094
Iterator JavaDoc cartItemIter = this.iterator();
1095            while (cartItemIter.hasNext()) {
1096                ShoppingCartItem cartItem = (ShoppingCartItem) cartItemIter.next();
1097                cartItem.updatePrice(dispatcher, this);
1098            }
1099
1100            // check all promo codes, remove on failed check
1101
Iterator JavaDoc promoCodeIter = this.productPromoCodes.iterator();
1102            while (promoCodeIter.hasNext()) {
1103                String JavaDoc promoCode = (String JavaDoc) promoCodeIter.next();
1104                String JavaDoc checkResult = ProductPromoWorker.checkCanUsePromoCode(promoCode, partyId, this.getDelegator());
1105                if (checkResult != null) {
1106                    promoCodeIter.remove();
1107                    Debug.logWarning(UtilProperties.getMessage(resource_error,"OrderOnUserChangePromoCodeWasRemovedBecause", UtilMisc.toMap("checkResult",checkResult), locale), module);
1108                }
1109            }
1110
1111            // rerun promotions
1112
ProductPromoWorker.doPromotions(this, dispatcher);
1113        }
1114    }
1115
1116    public String JavaDoc getExternalId() {
1117        return this.externalId;
1118    }
1119
1120    public void setExternalId(String JavaDoc externalId) {
1121        this.externalId = externalId;
1122    }
1123
1124    public String JavaDoc getInternalCode() {
1125        return this.internalCode;
1126    }
1127
1128    public void setInternalCode(String JavaDoc internalCode) {
1129        this.internalCode = internalCode;
1130    }
1131
1132    public String JavaDoc getWebSiteId() {
1133        return this.webSiteId;
1134    }
1135
1136    public void setWebSiteId(String JavaDoc webSiteId) {
1137        this.webSiteId = webSiteId;
1138    }
1139
1140    /**
1141     * Set ship before date for a particular ship group
1142     * @param idx
1143     * @param shipBeforeDate
1144     */

1145   public void setShipBeforeDate(int idx, Timestamp JavaDoc shipBeforeDate) {
1146       CartShipInfo csi = this.getShipInfo(idx);
1147       csi.shipBeforeDate = shipBeforeDate;
1148   }
1149
1150   /**
1151    * Set ship before date for ship group 0
1152    * @param shipBeforeDate
1153    */

1154   public void setShipBeforeDate(Timestamp JavaDoc shipBeforeDate) {
1155       this.setShipBeforeDate(0, shipBeforeDate);
1156   }
1157
1158   /**
1159    * Get ship before date for a particular ship group
1160    * @param idx
1161    * @return
1162    */

1163   public Timestamp JavaDoc getShipBeforeDate(int idx) {
1164       CartShipInfo csi = this.getShipInfo(idx);
1165       return csi.shipBeforeDate;
1166   }
1167
1168   /**
1169    * Get ship before date for ship group 0
1170    * @return
1171    */

1172   public Timestamp JavaDoc getShipBeforeDate() {
1173       return this.getShipBeforeDate(0);
1174   }
1175
1176   /**
1177    * Set ship after date for a particular ship group
1178    * @param idx
1179    * @param shipAfterDate
1180    */

1181   public void setShipAfterDate(int idx, Timestamp JavaDoc shipAfterDate) {
1182       CartShipInfo csi = this.getShipInfo(idx);
1183       csi.shipAfterDate = shipAfterDate;
1184   }
1185
1186   /**
1187    * Set ship after date for a particular ship group
1188    * @param shipAfterDate
1189    */

1190   public void setShipAfterDate(Timestamp JavaDoc shipAfterDate) {
1191       this.setShipAfterDate(0, shipAfterDate);
1192   }
1193
1194   /**
1195    * Get ship after date for a particular ship group
1196    * @param idx
1197    * @return
1198    */

1199   public Timestamp JavaDoc getShipAfterDate(int idx) {
1200       CartShipInfo csi = this.getShipInfo(idx);
1201       return csi.shipAfterDate;
1202   }
1203
1204   /**
1205    * Get ship after date for ship group 0
1206    * @return
1207    */

1208   public Timestamp JavaDoc getShipAfterDate() {
1209       return this.getShipAfterDate(0);
1210   }
1211
1212   public void setDefaultShipBeforeDate(Timestamp JavaDoc defaultShipBeforeDate) {
1213      this.defaultShipBeforeDate = defaultShipBeforeDate;
1214   }
1215   
1216   public Timestamp JavaDoc getDefaultShipBeforeDate() {
1217       return this.defaultShipBeforeDate;
1218   }
1219   
1220   public void setDefaultShipAfterDate(Timestamp JavaDoc defaultShipAfterDate) {
1221       this.defaultShipAfterDate = defaultShipAfterDate;
1222   }
1223   
1224   public Timestamp JavaDoc getDefaultShipAfterDate() {
1225       return this.defaultShipAfterDate;
1226   }
1227   
1228    public String JavaDoc getOrderPartyId() {
1229        return this.orderPartyId != null ? this.orderPartyId : this.getPartyId();
1230    }
1231
1232    public void setOrderPartyId(String JavaDoc orderPartyId) {
1233        this.orderPartyId = orderPartyId;
1234    }
1235
1236    public String JavaDoc getPlacingCustomerPartyId() {
1237        return this.placingCustomerPartyId != null ? this.placingCustomerPartyId : this.getPartyId();
1238    }
1239
1240    public void setPlacingCustomerPartyId(String JavaDoc placingCustomerPartyId) {
1241        this.placingCustomerPartyId = placingCustomerPartyId;
1242        if (UtilValidate.isEmpty(this.orderPartyId)) this.orderPartyId = placingCustomerPartyId;
1243    }
1244
1245    public String JavaDoc getBillToCustomerPartyId() {
1246        return this.billToCustomerPartyId != null ? this.billToCustomerPartyId : this.getPartyId();
1247    }
1248
1249    public void setBillToCustomerPartyId(String JavaDoc billToCustomerPartyId) {
1250        this.billToCustomerPartyId = billToCustomerPartyId;
1251        if ((UtilValidate.isEmpty(this.orderPartyId)) && !(orderType.equals("PURCHASE_ORDER"))) {
1252            this.orderPartyId = billToCustomerPartyId; // orderPartyId should be bill-to-customer when it is not a purchase order
1253
}
1254    }
1255
1256    public String JavaDoc getShipToCustomerPartyId() {
1257        return this.shipToCustomerPartyId != null ? this.shipToCustomerPartyId : this.getPartyId();
1258    }
1259
1260    public void setShipToCustomerPartyId(String JavaDoc shipToCustomerPartyId) {
1261        this.shipToCustomerPartyId = shipToCustomerPartyId;
1262        if (UtilValidate.isEmpty(this.orderPartyId)) this.orderPartyId = shipToCustomerPartyId;
1263    }
1264
1265    public String JavaDoc getEndUserCustomerPartyId() {
1266        return this.endUserCustomerPartyId != null ? this.endUserCustomerPartyId : this.getPartyId();
1267    }
1268
1269    public void setEndUserCustomerPartyId(String JavaDoc endUserCustomerPartyId) {
1270        this.endUserCustomerPartyId = endUserCustomerPartyId;
1271        if (UtilValidate.isEmpty(this.orderPartyId)) this.orderPartyId = endUserCustomerPartyId;
1272    }
1273
1274// protected String billFromVendorPartyId = null;
1275
// protected String shipFromVendorPartyId = null;
1276
//protected String supplierAgentPartyId = null;
1277

1278    public String JavaDoc getBillFromVendorPartyId() {
1279        return this.billFromVendorPartyId != null ? this.billFromVendorPartyId : this.getPartyId();
1280    }
1281
1282    public void setBillFromVendorPartyId(String JavaDoc billFromVendorPartyId) {
1283        this.billFromVendorPartyId = billFromVendorPartyId;
1284        if ((UtilValidate.isEmpty(this.orderPartyId)) && (orderType.equals("PURCHASE_ORDER"))) {
1285            this.orderPartyId = billFromVendorPartyId; // orderPartyId should be bill-from-vendor when it is a purchase order
1286
}
1287
1288    }
1289
1290    public String JavaDoc getShipFromVendorPartyId() {
1291        return this.shipFromVendorPartyId != null ? this.shipFromVendorPartyId : this.getPartyId();
1292    }
1293
1294    public void setShipFromVendorPartyId(String JavaDoc shipFromVendorPartyId) {
1295        this.shipFromVendorPartyId = shipFromVendorPartyId;
1296        if (UtilValidate.isEmpty(this.orderPartyId)) this.orderPartyId = shipFromVendorPartyId;
1297    }
1298
1299    public String JavaDoc getSupplierAgentPartyId() {
1300        return this.supplierAgentPartyId != null ? this.supplierAgentPartyId : this.getPartyId();
1301    }
1302
1303    public void setSupplierAgentPartyId(String JavaDoc supplierAgentPartyId) {
1304        this.supplierAgentPartyId = supplierAgentPartyId;
1305        if (UtilValidate.isEmpty(this.orderPartyId)) this.orderPartyId = supplierAgentPartyId;
1306    }
1307
1308    public String JavaDoc getPartyId() {
1309        String JavaDoc partyId = this.orderPartyId;
1310
1311        if (partyId == null && getUserLogin() != null) {
1312            partyId = getUserLogin().getString("partyId");
1313        }
1314        if (partyId == null && getAutoUserLogin() != null) {
1315            partyId = getAutoUserLogin().getString("partyId");
1316        }
1317        return partyId;
1318    }
1319
1320    public void setAutoSaveListId(String JavaDoc id) {
1321        this.autoSaveListId = id;
1322    }
1323
1324    public String JavaDoc getAutoSaveListId() {
1325        return this.autoSaveListId;
1326    }
1327
1328    public void setLastListRestore(Timestamp JavaDoc time) {
1329        this.lastListRestore = time;
1330    }
1331
1332    public Timestamp JavaDoc getLastListRestore() {
1333        return this.lastListRestore;
1334    }
1335
1336    public Double JavaDoc getPartyDaysSinceCreated(Timestamp JavaDoc nowTimestamp) {
1337        String JavaDoc partyId = this.getPartyId();
1338        if (UtilValidate.isEmpty(partyId)) {
1339            return null;
1340        }
1341        try {
1342            GenericValue party = this.getDelegator().findByPrimaryKeyCache("Party", UtilMisc.toMap("partyId", partyId));
1343            if (party == null) {
1344                return null;
1345            }
1346            Timestamp JavaDoc createdDate = party.getTimestamp("createdDate");
1347            if (createdDate == null) {
1348                return null;
1349            }
1350            double diffMillis = nowTimestamp.getTime() - createdDate.getTime();
1351            // millis per day: 1000.0 * 60.0 * 60.0 * 24.0 = 86400000.0
1352
return new Double JavaDoc((diffMillis) / 86400000.0);
1353        } catch (GenericEntityException e) {
1354            Debug.logError(e, "Error looking up party when getting createdDate", module);
1355            return null;
1356        }
1357    }
1358
1359    // =======================================================================
1360
// Methods for cart fields
1361
// =======================================================================
1362

1363    /** Clears out the cart. */
1364    public void clear() {
1365        this.poNumber = null;
1366        this.orderId = null;
1367        this.firstAttemptOrderId = null;
1368        this.billingAccountId = null;
1369        this.billingAccountAmt = 0.00;
1370        this.nextItemSeq = 1;
1371
1372        this.agreementId = null;
1373        this.quoteId = null;
1374
1375        this.defaultItemDeliveryDate = null;
1376        this.defaultItemComment = null;
1377        this.orderAdditionalEmails = null;
1378
1379        //this.viewCartOnAdd = false;
1380
this.readOnlyCart = false;
1381
1382        this.lastListRestore = null;
1383        this.autoSaveListId = null;
1384
1385        this.orderTermSet = false;
1386        this.orderTerms.clear();
1387
1388        this.adjustments.clear();
1389
1390        this.expireSingleUsePayments();
1391        this.cartLines.clear();
1392        this.clearPayments();
1393        this.shipInfo.clear();
1394        this.contactMechIdsMap.clear();
1395
1396        // clear the additionalPartyRole Map
1397
Iterator JavaDoc it = this.additionalPartyRole.entrySet().iterator();
1398        while (it.hasNext()) {
1399            Map.Entry JavaDoc me = (Map.Entry JavaDoc) it.next();
1400            ((LinkedList JavaDoc) me.getValue()).clear();
1401        }
1402        this.additionalPartyRole.clear();
1403
1404        this.freeShippingProductPromoActions.clear();
1405        this.desiredAlternateGiftByAction.clear();
1406        this.productPromoUseInfoList.clear();
1407        this.productPromoCodes.clear();
1408
1409        // clear the auto-save info
1410
if (ProductStoreWorker.autoSaveCart(this.getDelegator(), this.getProductStoreId())) {
1411            GenericValue ul = this.getUserLogin();
1412            if (ul == null) {
1413                ul = this.getAutoUserLogin();
1414            }
1415
1416            // load the auto-save list ID
1417
if (autoSaveListId == null) {
1418                try {
1419                    autoSaveListId = ShoppingListEvents.getAutoSaveListId(this.getDelegator(), null, null, ul, this.getProductStoreId());
1420                } catch (GeneralException e) {
1421                    Debug.logError(e, module);
1422                }
1423            }
1424
1425            // clear the list
1426
if (autoSaveListId != null) {
1427                try {
1428                    org.ofbiz.order.shoppinglist.ShoppingListEvents.clearListInfo(this.getDelegator(), autoSaveListId);
1429                } catch (GenericEntityException e) {
1430                    Debug.logError(e, module);
1431                }
1432            }
1433            this.lastListRestore = null;
1434            this.autoSaveListId = null;
1435        }
1436    }
1437
1438    /** Sets the order type. */
1439    public void setOrderType(String JavaDoc orderType) {
1440        this.orderType = orderType;
1441    }
1442
1443    /** Returns the order type. */
1444    public String JavaDoc getOrderType() {
1445        return this.orderType;
1446    }
1447
1448    public void setChannelType(String JavaDoc channelType) {
1449        this.channel = channelType;
1450    }
1451
1452    public String JavaDoc getChannelType() {
1453        return this.channel;
1454    }
1455
1456    public boolean isPurchaseOrder() {
1457        return "PURCHASE_ORDER".equals(this.orderType);
1458    }
1459
1460    public boolean isSalesOrder() {
1461        return "SALES_ORDER".equals(this.orderType);
1462    }
1463
1464    /** Sets the PO Number in the cart. */
1465    public void setPoNumber(String JavaDoc poNumber) {
1466        this.poNumber = poNumber;
1467    }
1468
1469    /** Returns the po number. */
1470    public String JavaDoc getPoNumber() {
1471        return poNumber;
1472    }
1473
1474    public void setDefaultItemDeliveryDate(String JavaDoc date) {
1475        this.defaultItemDeliveryDate = date;
1476    }
1477
1478    public String JavaDoc getDefaultItemDeliveryDate() {
1479        return this.defaultItemDeliveryDate;
1480    }
1481
1482    public void setDefaultItemComment(String JavaDoc comment) {
1483        this.defaultItemComment = comment;
1484    }
1485
1486    public String JavaDoc getDefaultItemComment() {
1487        return this.defaultItemComment;
1488    }
1489
1490    public void setAgreementId(String JavaDoc agreementId) {
1491        this.agreementId = agreementId;
1492    }
1493
1494    public String JavaDoc getAgreementId() {
1495        return this.agreementId;
1496    }
1497
1498    public void setQuoteId(String JavaDoc quoteId) {
1499        this.quoteId = quoteId;
1500    }
1501
1502    public String JavaDoc getQuoteId() {
1503        return this.quoteId;
1504    }
1505
1506    // =======================================================================
1507
// Payment Method
1508
// =======================================================================
1509

1510    public String JavaDoc getPaymentMethodTypeId(String JavaDoc paymentMethodId) {
1511        try {
1512            GenericValue pm = this.getDelegator().findByPrimaryKey("PaymentMethod", UtilMisc.toMap("paymentMethodId", paymentMethodId));
1513            if (pm != null) {
1514                return pm.getString("paymentMethodTypeId");
1515            }
1516        } catch (GenericEntityException e) {
1517            Debug.logError(e, module);
1518        }
1519        return null;
1520    }
1521
1522    /** Creates a CartPaymentInfo object */
1523    public CartPaymentInfo makePaymentInfo(String JavaDoc id, String JavaDoc refNum, Double JavaDoc amount) {
1524        CartPaymentInfo inf = new CartPaymentInfo();
1525        inf.refNum[0] = refNum;
1526        inf.amount = amount;
1527
1528        if (!isPaymentMethodType(id)) {
1529            inf.paymentMethodTypeId = this.getPaymentMethodTypeId(id);
1530            inf.paymentMethodId = id;
1531        } else {
1532            inf.paymentMethodTypeId = id;
1533        }
1534        return inf;
1535    }
1536
1537    /** Locates the index of an existing CartPaymentInfo object or -1 if none found */
1538    public int getPaymentInfoIndex(String JavaDoc id, String JavaDoc refNum) {
1539        CartPaymentInfo thisInf = this.makePaymentInfo(id, refNum, null);
1540        for (int i = 0; i < paymentInfo.size(); i++) {
1541            CartPaymentInfo inf = (CartPaymentInfo) paymentInfo.get(i);
1542            if (inf.compareTo(thisInf) == 0) {
1543                return i;
1544            }
1545        }
1546        return -1;
1547    }
1548
1549    /** Returns the CartPaymentInfo objects which have matching fields */
1550    public List JavaDoc getPaymentInfos(boolean isPaymentMethod, boolean isPaymentMethodType, boolean hasRefNum) {
1551        List JavaDoc foundRecords = new LinkedList JavaDoc();
1552        Iterator JavaDoc i = paymentInfo.iterator();
1553        while (i.hasNext()) {
1554            CartPaymentInfo inf = (CartPaymentInfo) i.next();
1555            if (isPaymentMethod && inf.paymentMethodId != null) {
1556                if (hasRefNum && inf.refNum != null) {
1557                    foundRecords.add(inf);
1558                } else if (!hasRefNum && inf.refNum == null) {
1559                    foundRecords.add(inf);
1560                }
1561            } else if (isPaymentMethodType && inf.paymentMethodTypeId != null) {
1562                if (hasRefNum && inf.refNum != null) {
1563                    foundRecords.add(inf);
1564                } else if (!hasRefNum && inf.refNum == null) {
1565                    foundRecords.add(inf);
1566                }
1567            }
1568        }
1569        return foundRecords;
1570    }
1571
1572    /** Locates an existing CartPaymentInfo object by index */
1573    public CartPaymentInfo getPaymentInfo(int index) {
1574        return (CartPaymentInfo) paymentInfo.get(index);
1575    }
1576
1577    /** Locates an existing (or creates a new) CartPaymentInfo object */
1578    public CartPaymentInfo getPaymentInfo(String JavaDoc id, String JavaDoc refNum, String JavaDoc authCode, Double JavaDoc amount, boolean update) {
1579        CartPaymentInfo thisInf = this.makePaymentInfo(id, refNum, amount);
1580        Iterator JavaDoc i = paymentInfo.iterator();
1581        while (i.hasNext()) {
1582            CartPaymentInfo inf = (CartPaymentInfo) i.next();
1583            if (inf.compareTo(thisInf) == 0) {
1584                // update the info
1585
if (update) {
1586                    inf.refNum[0] = refNum;
1587                    inf.refNum[1] = authCode;
1588                    inf.amount = amount;
1589                }
1590                Debug.logInfo("Returned existing PaymentInfo - " + inf.toString(), module);
1591                return inf;
1592            }
1593        }
1594
1595        Debug.logInfo("Returned new PaymentInfo - " + thisInf.toString(), module);
1596        return thisInf;
1597    }
1598
1599    /** Locates an existing (or creates a new) CartPaymentInfo object */
1600    public CartPaymentInfo getPaymentInfo(String JavaDoc id, String JavaDoc refNum, String JavaDoc authCode, Double JavaDoc amount) {
1601        return this.getPaymentInfo(id, refNum, authCode, amount, false);
1602    }
1603
1604    /** Locates an existing (or creates a new) CartPaymentInfo object */
1605    public CartPaymentInfo getPaymentInfo(String JavaDoc id) {
1606        return this.getPaymentInfo(id, null, null, null, false);
1607    }
1608
1609    /** adds a payment method/payment method type */
1610    public void addPaymentAmount(String JavaDoc id, Double JavaDoc amount, String JavaDoc refNum, String JavaDoc authCode, boolean isSingleUse, boolean isPresent, boolean replace) {
1611        CartPaymentInfo inf = this.getPaymentInfo(id, refNum, authCode, amount, true);
1612        inf.singleUse = isSingleUse;
1613        if (replace) {
1614            paymentInfo.remove(inf);
1615        }
1616        paymentInfo.add(inf);
1617    }
1618
1619    /** adds a payment method/payment method type */
1620    public void addPaymentAmount(String JavaDoc id, Double JavaDoc amount, boolean isSingleUse) {
1621        this.addPaymentAmount(id, amount, null, null, isSingleUse, false, true);
1622    }
1623
1624    /** adds a payment method/payment method type */
1625    public void addPaymentAmount(String JavaDoc id, double amount, boolean isSingleUse) {
1626        this.addPaymentAmount(id, new Double JavaDoc(amount), isSingleUse);
1627    }
1628
1629    /** adds a payment method/payment method type */
1630    public void addPaymentAmount(String JavaDoc id, Double JavaDoc amount) {
1631        this.addPaymentAmount(id, amount, false);
1632    }
1633
1634    /** adds a payment method/payment method type */
1635    public void addPaymentAmount(String JavaDoc id, double amount) {
1636        this.addPaymentAmount(id, new Double JavaDoc(amount), false);
1637    }
1638
1639    /** adds a payment method/payment method type */
1640    public void addPayment(String JavaDoc id) {
1641        this.addPaymentAmount(id, null, false);
1642    }
1643
1644    /** returns the payment method/payment method type amount */
1645    public Double JavaDoc getPaymentAmount(String JavaDoc id) {
1646        return this.getPaymentInfo(id).amount;
1647    }
1648
1649    public void addPaymentRef(String JavaDoc id, String JavaDoc ref, String JavaDoc authCode) {
1650        this.getPaymentInfo(id).refNum[0] = ref;
1651        this.getPaymentInfo(id).refNum[1] = authCode;
1652    }
1653
1654    public String JavaDoc getPaymentRef(String JavaDoc id) {
1655        Iterator JavaDoc i = paymentInfo.iterator();
1656        while (i.hasNext()) {
1657            CartPaymentInfo inf = (CartPaymentInfo) i.next();
1658            if (inf.paymentMethodId.equals(id) || inf.paymentMethodTypeId.equals(id)) {
1659                return inf.refNum[0];
1660            }
1661        }
1662        return null;
1663    }
1664    
1665    /** returns the total payment amounts */
1666    public double getPaymentTotal() {
1667        double total = 0.00;
1668        Iterator JavaDoc i = paymentInfo.iterator();
1669        while (i.hasNext()) {
1670            CartPaymentInfo inf = (CartPaymentInfo) i.next();
1671            if (inf.amount != null) {
1672                total += inf.amount.doubleValue();
1673            }
1674        }
1675        return total;
1676    }
1677
1678    public int selectedPayments() {
1679        return paymentInfo.size();
1680    }
1681
1682    public boolean isPaymentSelected(String JavaDoc id) {
1683        CartPaymentInfo inf = this.getPaymentInfo(id);
1684        return paymentInfo.contains(inf);
1685    }
1686
1687    /** removes a specific payment method/payment method type */
1688    public void clearPayment(String JavaDoc id) {
1689        CartPaymentInfo inf = this.getPaymentInfo(id);
1690        paymentInfo.remove(inf);
1691    }
1692
1693    /** removes a specific payment info from the list */
1694    public void clearPayment(int index) {
1695        paymentInfo.remove(index);
1696    }
1697
1698    /** clears all payment method/payment method types */
1699    public void clearPayments() {
1700        this.expireSingleUsePayments();
1701        paymentInfo.clear();
1702    }
1703
1704    private void expireSingleUsePayments() {
1705        Timestamp JavaDoc now = UtilDateTime.nowTimestamp();
1706        Iterator JavaDoc i = paymentInfo.iterator();
1707        while (i.hasNext()) {
1708            CartPaymentInfo inf = (CartPaymentInfo) i.next();
1709            if (inf.paymentMethodId == null || !inf.singleUse) {
1710                continue;
1711            }
1712
1713            GenericValue paymentMethod = null;
1714            try {
1715                paymentMethod = this.getDelegator().findByPrimaryKey("PaymentMethod", UtilMisc.toMap("paymentMethodId", inf.paymentMethodId));
1716            } catch (GenericEntityException e) {
1717                Debug.logError(e, "ERROR: Unable to get payment method record to expire : " + inf.paymentMethodId, module);
1718            }
1719            if (paymentMethod != null) {
1720                paymentMethod.set("thruDate", now);
1721                try {
1722                    paymentMethod.store();
1723                } catch (GenericEntityException e) {
1724                    Debug.logError(e, "Unable to store single use PaymentMethod record : " + paymentMethod, module);
1725                }
1726            } else {
1727                Debug.logError("ERROR: Received back a null payment method record for expired ID : " + inf.paymentMethodId, module);
1728            }
1729        }
1730    }
1731
1732    /** Returns the Payment Method Ids */
1733    public List JavaDoc getPaymentMethodIds() {
1734        List JavaDoc pmi = new LinkedList JavaDoc();
1735        Iterator JavaDoc i = paymentInfo.iterator();
1736        while (i.hasNext()) {
1737            CartPaymentInfo inf = (CartPaymentInfo) i.next();
1738            if (inf.paymentMethodId != null) {
1739                pmi.add(inf.paymentMethodId);
1740            }
1741        }
1742        return pmi;
1743    }
1744
1745    /** Returns the Payment Method Ids */
1746    public List JavaDoc getPaymentMethodTypeIds() {
1747       List JavaDoc pmt = new LinkedList JavaDoc();
1748        Iterator JavaDoc i = paymentInfo.iterator();
1749        while (i.hasNext()) {
1750            CartPaymentInfo inf = (CartPaymentInfo) i.next();
1751            if (inf.paymentMethodTypeId != null) {
1752                pmt.add(inf.paymentMethodTypeId);
1753            }
1754        }
1755        return pmt;
1756    }
1757
1758    /** Returns a list of PaymentMethod value objects selected in the cart */
1759    public List JavaDoc getPaymentMethods() {
1760        List JavaDoc methods = new LinkedList JavaDoc();
1761        if (paymentInfo != null && paymentInfo.size() > 0) {
1762            Iterator JavaDoc i = getPaymentMethodIds().iterator();
1763            while (i.hasNext()) {
1764                String JavaDoc id = (String JavaDoc) i.next();
1765                try {
1766                    methods.add(this.getDelegator().findByPrimaryKeyCache("PaymentMethod", UtilMisc.toMap("paymentMethodId", id)));
1767                } catch (GenericEntityException e) {
1768                    Debug.logError(e, "Unable to get payment method from the database", module);
1769                }
1770            }
1771        }
1772
1773        return methods;
1774    }
1775
1776    /** Returns a list of PaymentMethodType value objects selected in the cart */
1777    public List JavaDoc getPaymentMethodTypes() {
1778        List JavaDoc types = new LinkedList JavaDoc();
1779        if (paymentInfo != null && paymentInfo.size() > 0) {
1780            Iterator JavaDoc i = getPaymentMethodTypeIds().iterator();
1781            while (i.hasNext()) {
1782                String JavaDoc id = (String JavaDoc) i.next();
1783                try {
1784                    types.add(this.getDelegator().findByPrimaryKeyCache("PaymentMethodType", UtilMisc.toMap("paymentMethodTypeId", id)));
1785                } catch (GenericEntityException e) {
1786                    Debug.logError(e, "Unable to get payment method type from the database", module);
1787                }
1788            }
1789        }
1790
1791        return types;
1792    }
1793
1794    public List JavaDoc getCreditCards() {
1795        List JavaDoc paymentMethods = this.getPaymentMethods();
1796        List JavaDoc creditCards = new LinkedList JavaDoc();
1797        if (paymentMethods != null) {
1798            Iterator JavaDoc i = paymentMethods.iterator();
1799            while (i.hasNext()) {
1800                GenericValue pm = (GenericValue) i.next();
1801                if ("CREDIT_CARD".equals(pm.getString("paymentMethodTypeId"))) {
1802                    try {
1803                        GenericValue cc = pm.getRelatedOne("CreditCard");
1804                        creditCards.add(cc);
1805                    } catch (GenericEntityException e) {
1806                        Debug.logError(e, "Unable to get credit card record from payment method : " + pm, module);
1807                    }
1808                }
1809            }
1810        }
1811
1812        return creditCards;
1813    }
1814
1815    public List JavaDoc getGiftCards() {
1816        List JavaDoc paymentMethods = this.getPaymentMethods();
1817        List JavaDoc giftCards = new LinkedList JavaDoc();
1818        if (paymentMethods != null) {
1819            Iterator JavaDoc i = paymentMethods.iterator();
1820            while (i.hasNext()) {
1821                GenericValue pm = (GenericValue) i.next();
1822                if ("GIFT_CARD".equals(pm.getString("paymentMethodTypeId"))) {
1823                    try {
1824                        GenericValue gc = pm.getRelatedOne("GiftCard");
1825                        giftCards.add(gc);
1826                    } catch (GenericEntityException e) {
1827                        Debug.logError(e, "Unable to get gift card record from payment method : " + pm, module);
1828                    }
1829                }
1830            }
1831        }
1832
1833        return giftCards;
1834    }
1835
1836    /* determines if the id supplied is a payment method or not by searching in the entity engine */
1837    public boolean isPaymentMethodType(String JavaDoc id) {
1838        GenericValue paymentMethodType = null;
1839        try {
1840            paymentMethodType = this.getDelegator().findByPrimaryKeyCache("PaymentMethodType", UtilMisc.toMap("paymentMethodTypeId", id));
1841        } catch (GenericEntityException e) {
1842            Debug.logInfo(e, "Problems getting PaymentMethodType", module);
1843        }
1844        if (paymentMethodType == null) {
1845            return false;
1846        } else {
1847            return true;
1848        }
1849    }
1850
1851    /**
1852     * Returns ProductStoreFinActSetting based on cart's productStoreId and FinAccountHelper's defined giftCertFinAcctTypeId
1853     * @param delegator
1854     * @return
1855     * @throws GenericEntityException
1856     */

1857    public GenericValue getGiftCertSettingFromStore(GenericDelegator delegator) throws GenericEntityException {
1858        return delegator.findByPrimaryKeyCache("ProductStoreFinActSetting", UtilMisc.toMap("productStoreId", getProductStoreId(), "finAccountTypeId", FinAccountHelper.giftCertFinAccountTypeId));
1859    }
1860    
1861    /**
1862     * Determines whether pin numbers are required for gift cards, based on ProductStoreFinActSetting. Default to true.
1863     * @return
1864     */

1865    public boolean isPinRequiredForGC(GenericDelegator delegator) {
1866        try {
1867            GenericValue giftCertSettings = getGiftCertSettingFromStore(delegator);
1868            if (giftCertSettings != null) {
1869                if ("Y".equals(giftCertSettings.getString("requirePinCode"))) {
1870                    return true;
1871                } else {
1872                    return false;
1873                }
1874            } else {
1875                Debug.logWarning("No product store gift certificate settings found for store [" + getProductStoreId() + "]", module);
1876                return true;
1877            }
1878        } catch (GenericEntityException ex) {
1879            Debug.logError("Error checking if store requires pin number for GC: " + ex.getMessage(), module);
1880            return true;
1881        }
1882    }
1883    
1884    /**
1885     * Returns whether the cart should validate gift cards against FinAccount (ie, internal gift certificates). Defaults to false.
1886     * @param delegator
1887     * @return
1888     */

1889    public boolean isValidateGCFinAccount(GenericDelegator delegator) {
1890        try {
1891            GenericValue giftCertSettings = getGiftCertSettingFromStore(delegator);
1892            if (giftCertSettings != null) {
1893                if ("Y".equals(giftCertSettings.getString("validateGCFinAcct"))) {
1894                    return true;
1895                } else {
1896                    return false;
1897                }
1898            } else {
1899                Debug.logWarning("No product store gift certificate settings found for store [" + getProductStoreId() + "]", module);
1900                return false;
1901            }
1902        } catch (GenericEntityException ex) {
1903            Debug.logError("Error checking if store requires pin number for GC: " + ex.getMessage(), module);
1904            return false;
1905        }
1906    }
1907    
1908    // =======================================================================
1909
// Billing Accounts
1910
// =======================================================================
1911

1912    /** Sets the billing account id string. */
1913    public void setBillingAccount(String JavaDoc billingAccountId, double amount) {
1914        this.billingAccountId = billingAccountId;
1915        this.billingAccountAmt = amount;
1916    }
1917
1918    /** Returns the billing message string. */
1919    public String JavaDoc getBillingAccountId() {
1920        return this.billingAccountId;
1921    }
1922
1923    /** Returns the amount to be billed to the billing account.*/
1924    public double getBillingAccountAmount() {
1925        return this.billingAccountAmt;
1926    }
1927
1928    // =======================================================================
1929
// Shipping Charges
1930
// =======================================================================
1931

1932    /** Returns the order level shipping amount */
1933    public double getOrderShipping() {
1934        return OrderReadHelper.calcOrderAdjustments(this.getAdjustments(), this.getSubTotal(), false, false, true);
1935    }
1936
1937    // ----------------------------------------
1938
// Ship Group Methods
1939
// ----------------------------------------
1940

1941    public List JavaDoc getShipGroups() {
1942        return this.shipInfo;
1943    }
1944
1945    public Map JavaDoc getShipGroups(ShoppingCartItem item) {
1946        Map JavaDoc shipGroups = new LinkedMap();
1947        if (item != null) {
1948            for (int i = 0; i < shipInfo.size(); i++) {
1949                CartShipInfo csi = (CartShipInfo) shipInfo.get(i);
1950                CartShipInfo.CartShipItemInfo csii = (CartShipInfo.CartShipItemInfo) csi.shipItemInfo.get(item);
1951                if (csii != null) {
1952                    if (this.checkShipItemInfo(csi, csii)) {
1953                        shipGroups.put(new Integer JavaDoc(i), new Double JavaDoc(csii.quantity));
1954                    }
1955                }
1956            }
1957        }
1958        return shipGroups;
1959    }
1960
1961    public Map JavaDoc getShipGroups(int itemIndex) {
1962        return this.getShipGroups(this.findCartItem(itemIndex));
1963    }
1964
1965    public CartShipInfo getShipInfo(int idx) {
1966        if (idx == -1 ) {
1967            return null;
1968        }
1969
1970        if (shipInfo.size() == 0) {
1971            shipInfo.add(new CartShipInfo());
1972        }
1973
1974        return (CartShipInfo) shipInfo.get(idx);
1975    }
1976
1977    public int getShipGroupSize() {
1978        return this.shipInfo.size();
1979    }
1980
1981    /** Returns the ShoppingCartItem (key) and quantity (value) associated with the ship group */
1982    public Map JavaDoc getShipGroupItems(int idx) {
1983        CartShipInfo csi = this.getShipInfo(idx);
1984        Map JavaDoc qtyMap = new HashMap JavaDoc();
1985        Iterator JavaDoc i = csi.shipItemInfo.keySet().iterator();
1986        while (i.hasNext()) {
1987            ShoppingCartItem item = (ShoppingCartItem) i.next();
1988            CartShipInfo.CartShipItemInfo csii = (CartShipInfo.CartShipItemInfo) csi.shipItemInfo.get(item);
1989            qtyMap.put(item, new Double JavaDoc(csii.quantity));
1990        }
1991        return qtyMap;
1992    }
1993
1994    public void clearItemShipInfo(ShoppingCartItem item) {
1995        for (int i = 0; i < shipInfo.size(); i++) {
1996            CartShipInfo csi = this.getShipInfo(i);
1997            csi.shipItemInfo.remove(item);
1998        }
1999        this.cleanUpShipGroups();
2000    }
2001
2002    public void setItemShipGroupEstimate(double amount, int idx) {
2003        CartShipInfo csi = this.getShipInfo(idx);
2004        csi.shipEstimate = amount;
2005    }
2006
2007    /**
2008     * Updates the shipBefore and shipAfterDates of all ship groups that the item belongs to, re-setting
2009     * ship group ship before date if item ship before date is before it and ship group ship after date if
2010     * item ship after date is before it.
2011     * @param item
2012     */

2013    public void setShipGroupShipDatesFromItem(ShoppingCartItem item) {
2014        Map JavaDoc shipGroups = this.getShipGroups(item);
2015        
2016        if ((shipGroups != null) && (shipGroups.keySet() != null)) {
2017            for (Iterator JavaDoc shipGroupKeys = shipGroups.keySet().iterator(); shipGroupKeys.hasNext(); ) {
2018                Integer JavaDoc shipGroup = (Integer JavaDoc) shipGroupKeys.next();
2019                CartShipInfo shipInfo = this.getShipInfo(shipGroup.intValue());
2020                
2021                shipInfo.resetShipAfterDateIfBefore(item.getShipAfterDate());
2022                shipInfo.resetShipBeforeDateIfAfter(item.getShipBeforeDate());
2023            }
2024        }
2025    }
2026    
2027    public double getItemShipGroupEstimate(int idx) {
2028        CartShipInfo csi = this.getShipInfo(idx);
2029        return csi.shipEstimate;
2030    }
2031
2032    public void setItemShipGroupQty(int itemIndex, double quantity, int idx) {
2033        this.setItemShipGroupQty(this.findCartItem(itemIndex), itemIndex, quantity, idx);
2034    }
2035
2036    public void setItemShipGroupQty(ShoppingCartItem item, double quantity, int idx) {
2037        this.setItemShipGroupQty(item, this.getItemIndex(item), quantity, idx);
2038    }
2039
2040    public void setItemShipGroupQty(ShoppingCartItem item, int itemIndex, double quantity, int idx) {
2041        if (itemIndex > -1) {
2042            CartShipInfo csi = this.getShipInfo(idx);
2043
2044            // never set less than zero
2045
if (quantity < 0) {
2046                quantity = 0;
2047            }
2048
2049            // never set more than quantity ordered
2050
if (quantity > item.getQuantity()) {
2051                quantity = item.getQuantity();
2052            }
2053            
2054            // re-set the ship group's before and after dates based on the item's
2055
csi.resetShipBeforeDateIfAfter(item.getShipBeforeDate());
2056            csi.resetShipAfterDateIfBefore(item.getShipAfterDate());
2057            
2058            CartShipInfo.CartShipItemInfo csii = csi.setItemInfo(item, quantity);
2059            this.checkShipItemInfo(csi, csii);
2060        }
2061    }
2062
2063    public double getItemShipGroupQty(ShoppingCartItem item, int idx) {
2064        if (item != null) {
2065            CartShipInfo csi = this.getShipInfo(idx);
2066            CartShipInfo.CartShipItemInfo csii = (CartShipInfo.CartShipItemInfo) csi.shipItemInfo.get(item);
2067            if (csii != null) {
2068                return csii.quantity;
2069            }
2070        }
2071        return 0;
2072    }
2073
2074    public double getItemShipGroupQty(int itemIndex, int idx) {
2075        return this.getItemShipGroupQty(this.findCartItem(itemIndex), idx);
2076    }
2077
2078    public void positionItemToGroup(int itemIndex, double quantity, int fromIndex, int toIndex) {
2079        this.positionItemToGroup(this.findCartItem(itemIndex), quantity, fromIndex, toIndex);
2080    }
2081
2082    public void positionItemToGroup(ShoppingCartItem item, double quantity, int fromIndex, int toIndex) {
2083        if (fromIndex == toIndex || quantity <= 0) {
2084            // do nothing
2085
return;
2086        }
2087
2088        // get the ship groups; create the TO group if needed
2089
CartShipInfo fromGroup = this.getShipInfo(fromIndex);
2090        CartShipInfo toGroup = null;
2091        if (toIndex == -1) {
2092            toGroup = new CartShipInfo();
2093            shipInfo.add(toGroup);
2094            toIndex = shipInfo.size() - 1;
2095        } else {
2096            toGroup = this.getShipInfo(toIndex);
2097        }
2098
2099        // adjust the quantities
2100
if (fromGroup != null && toGroup != null) {
2101            double fromQty = this.getItemShipGroupQty(item, fromIndex);
2102            double toQty = this.getItemShipGroupQty(item, toIndex);
2103            if (fromQty > 0) {
2104                if (quantity > fromQty) {
2105                    quantity = fromQty;
2106                }
2107                fromQty -= quantity;
2108                toQty += quantity;
2109                this.setItemShipGroupQty(item, fromQty, fromIndex);
2110                this.setItemShipGroupQty(item, toQty, toIndex);
2111            }
2112
2113            // remove any empty ship groups
2114
this.cleanUpShipGroups();
2115        }
2116    }
2117
2118    // removes 0 quantity items
2119
protected boolean checkShipItemInfo(CartShipInfo csi, CartShipInfo.CartShipItemInfo csii) {
2120        if (csii.quantity == 0 || csii.item.getQuantity() == 0) {
2121            csi.shipItemInfo.remove(csii.item);
2122            return false;
2123        }
2124        return true;
2125    }
2126
2127    protected void cleanUpShipGroups() {
2128        for (int i = 0; i < shipInfo.size(); i++) {
2129            CartShipInfo csi = this.getShipInfo(i);
2130            Iterator JavaDoc si = csi.shipItemInfo.keySet().iterator();
2131            while (si.hasNext()) {
2132                ShoppingCartItem item = (ShoppingCartItem) si.next();
2133                if (item.getQuantity() == 0.0) {
2134                    si.remove();
2135                }
2136            }
2137            if (csi.shipItemInfo.size() == 0) {
2138                shipInfo.remove(csi);
2139            }
2140        }
2141    }
2142
2143    /** Sets the shipping contact mech id. */
2144    public void setShippingContactMechId(int idx, String JavaDoc shippingContactMechId) {
2145        CartShipInfo csi = this.getShipInfo(idx);
2146        csi.contactMechId = shippingContactMechId;
2147    }
2148
2149    public void setShippingContactMechId(String JavaDoc shippingContactMechId) {
2150        this.setShippingContactMechId(0, shippingContactMechId);
2151    }
2152
2153    /** Returns the shipping contact mech id. */
2154    public String JavaDoc getShippingContactMechId(int idx) {
2155        CartShipInfo csi = this.getShipInfo(idx);
2156        return csi.contactMechId;
2157    }
2158
2159    public String JavaDoc getShippingContactMechId() {
2160        return this.getShippingContactMechId(0);
2161    }
2162
2163    /** Sets the shipment method type. */
2164    public void setShipmentMethodTypeId(int idx, String JavaDoc shipmentMethodTypeId) {
2165        CartShipInfo csi = this.getShipInfo(idx);
2166        csi.shipmentMethodTypeId = shipmentMethodTypeId;
2167    }
2168
2169    public void setShipmentMethodTypeId(String JavaDoc shipmentMethodTypeId) {
2170        this.setShipmentMethodTypeId(0, shipmentMethodTypeId);
2171    }
2172
2173    /** Returns the shipment method type ID */
2174    public String JavaDoc getShipmentMethodTypeId(int idx) {
2175        CartShipInfo csi = this.getShipInfo(idx);
2176        return csi.shipmentMethodTypeId;
2177    }
2178
2179    public String JavaDoc getShipmentMethodTypeId() {
2180        return this.getShipmentMethodTypeId(0);
2181    }
2182
2183    /** Returns the shipment method type. */
2184    public GenericValue getShipmentMethodType(int idx) {
2185        String JavaDoc shipmentMethodTypeId = this.getShipmentMethodTypeId(idx);
2186        if (UtilValidate.isNotEmpty(shipmentMethodTypeId)) {
2187            try {
2188                return this.getDelegator().findByPrimaryKey("ShipmentMethodType",
2189                        UtilMisc.toMap("shipmentMethodTypeId", shipmentMethodTypeId));
2190            } catch (GenericEntityException e) {
2191                Debug.logWarning(e, module);
2192            }
2193        }
2194        return null;
2195    }
2196
2197    /** Sets the shipping instructions. */
2198    public void setShippingInstructions(int idx, String JavaDoc shippingInstructions) {
2199        CartShipInfo csi = this.getShipInfo(idx);
2200        csi.shippingInstructions = shippingInstructions;
2201    }
2202
2203    public void setShippingInstructions(String JavaDoc shippingInstructions) {
2204        this.setShippingInstructions(0, shippingInstructions);
2205    }
2206
2207    /** Returns the shipping instructions. */
2208    public String JavaDoc getShippingInstructions(int idx) {
2209        CartShipInfo csi = this.getShipInfo(idx);
2210        return csi.shippingInstructions;
2211    }
2212
2213    public String JavaDoc getShippingInstructions() {
2214        return this.getShippingInstructions(0);
2215    }
2216
2217    public void setMaySplit(int idx, Boolean JavaDoc maySplit) {
2218        CartShipInfo csi = this.getShipInfo(idx);
2219        csi.maySplit = maySplit.booleanValue() ? "Y" : "N";
2220    }
2221
2222    public void setMaySplit(Boolean JavaDoc maySplit) {
2223        this.setMaySplit(0, maySplit);
2224    }
2225
2226    /** Returns Boolean.TRUE if the order may be split (null if unspecified) */
2227    public String JavaDoc getMaySplit(int idx) {
2228        CartShipInfo csi = this.getShipInfo(idx);
2229        return csi.maySplit;
2230    }
2231
2232    public String JavaDoc getMaySplit() {
2233        return this.getMaySplit(0);
2234    }
2235
2236    public void setGiftMessage(int idx, String JavaDoc giftMessage) {
2237        CartShipInfo csi = this.getShipInfo(idx);
2238        csi.giftMessage = giftMessage;
2239    }
2240
2241    public void setGiftMessage(String JavaDoc giftMessage) {
2242        this.setGiftMessage(0, giftMessage);
2243    }
2244
2245    public String JavaDoc getGiftMessage(int idx) {
2246        CartShipInfo csi = this.getShipInfo(idx);
2247        return csi.giftMessage;
2248    }
2249
2250    public String JavaDoc getGiftMessage() {
2251        return this.getGiftMessage(0);
2252    }
2253
2254    public void setIsGift(int idx, Boolean JavaDoc isGift) {
2255        CartShipInfo csi = this.getShipInfo(idx);
2256        csi.isGift = isGift.booleanValue() ? "Y" : "N";
2257    }
2258
2259    public void setIsGift(Boolean JavaDoc isGift) {
2260        this.setIsGift(0, isGift);
2261    }
2262
2263    public String JavaDoc getIsGift(int idx) {
2264        CartShipInfo csi = this.getShipInfo(idx);
2265        return csi.isGift;
2266    }
2267
2268    public String JavaDoc getIsGift() {
2269        return this.getIsGift(0);
2270    }
2271
2272    public void setCarrierPartyId(int idx, String JavaDoc carrierPartyId) {
2273        CartShipInfo csi = this.getShipInfo(idx);
2274        csi.carrierPartyId = carrierPartyId;
2275    }
2276
2277    public void setCarrierPartyId(String JavaDoc carrierPartyId) {
2278        this.setCarrierPartyId(0, carrierPartyId);
2279    }
2280
2281    public String JavaDoc getCarrierPartyId(int idx) {
2282        CartShipInfo csi = this.getShipInfo(idx);
2283        return csi.carrierPartyId;
2284    }
2285
2286    public String JavaDoc getCarrierPartyId() {
2287        return this.getCarrierPartyId(0);
2288    }
2289
2290    public void setOrderAdditionalEmails(String JavaDoc orderAdditionalEmails) {
2291        this.orderAdditionalEmails = orderAdditionalEmails;
2292    }
2293
2294    public String JavaDoc getOrderAdditionalEmails() {
2295        return orderAdditionalEmails;
2296    }
2297
2298    public GenericValue getShippingAddress(int idx) {
2299        if (this.getShippingContactMechId(idx) != null) {
2300            try {
2301                return getDelegator().findByPrimaryKey("PostalAddress", UtilMisc.toMap("contactMechId", this.getShippingContactMechId(idx)));
2302            } catch (GenericEntityException e) {
2303                Debug.logWarning(e.toString(), module);
2304                return null;
2305            }
2306        } else {
2307            return null;
2308        }
2309    }
2310
2311    public GenericValue getShippingAddress() {
2312        return this.getShippingAddress(0);
2313    }
2314
2315    // Preset with default values some of the checkout options to get a quicker checkout process.
2316
public void setDefaultCheckoutOptions(LocalDispatcher dispatcher) {
2317        // skip the add party screen
2318
this.setAttribute("addpty", "Y");
2319        // set as the default shipping location the first from the list of available shipping locations
2320
if (this.getPartyId() != null && !this.getPartyId().equals("_NA_")) {
2321            try {
2322                GenericValue orderParty = delegator.findByPrimaryKey("Party", UtilMisc.toMap("partyId", this.getPartyId()));
2323                Collection JavaDoc shippingContactMechList = ContactHelper.getContactMech(orderParty, "SHIPPING_LOCATION", "POSTAL_ADDRESS", false);
2324                if (shippingContactMechList != null && shippingContactMechList.size() > 0) {
2325                    GenericValue shippingContactMech = (GenericValue)(shippingContactMechList.iterator()).next();
2326                    this.setShippingContactMechId(shippingContactMech.getString("contactMechId"));
2327                }
2328            } catch (GenericEntityException e) {
2329                Debug.logError(e, "Error setting shippingContactMechId in setDefaultCheckoutOptions() method.", module);
2330            }
2331        }
2332        // set the default shipment method
2333
ShippingEstimateWrapper shipEstimateWrapper = org.ofbiz.order.shoppingcart.shipping.ShippingEstimateWrapper.getWrapper(dispatcher, this, 0);
2334        GenericValue carrierShipmentMethod = EntityUtil.getFirst(shipEstimateWrapper.getShippingMethods());
2335        if (carrierShipmentMethod != null) {
2336            this.setShipmentMethodTypeId(carrierShipmentMethod.getString("shipmentMethodTypeId"));
2337            this.setCarrierPartyId(carrierShipmentMethod.getString("partyId"));
2338        }
2339    }
2340
2341    // Returns the tax amount for a ship group. */
2342
public double getTotalSalesTax(int shipGroup) {
2343        CartShipInfo csi = this.getShipInfo(shipGroup);
2344        return csi.getTotalTax(this);
2345    }
2346
2347    /** Returns the tax amount from the cart object. */
2348    public double getTotalSalesTax() {
2349        double totalTax = 0.00;
2350        for (int i = 0; i < shipInfo.size(); i++) {
2351            CartShipInfo csi = this.getShipInfo(i);
2352            totalTax += csi.getTotalTax(this);
2353        }
2354        return totalTax;
2355    }
2356
2357    /** Returns the shipping amount from the cart object. */
2358    public double getTotalShipping() {
2359        double tempShipping = 0.0;
2360
2361        Iterator JavaDoc shipIter = shipInfo.iterator();
2362        while (shipIter.hasNext()) {
2363            CartShipInfo csi = (CartShipInfo) shipIter.next();
2364            tempShipping += csi.shipEstimate;
2365
2366        }
2367
2368        return tempShipping;
2369    }
2370
2371    /** Returns the item-total in the cart (not including discount/tax/shipping). */
2372    public double getItemTotal() {
2373        double itemTotal = 0.00;
2374        Iterator JavaDoc i = iterator();
2375
2376        while (i.hasNext()) {
2377            itemTotal += ((ShoppingCartItem) i.next()).getBasePrice();
2378        }
2379        return itemTotal;
2380    }
2381
2382    /** Returns the sub-total in the cart (item-total - discount). */
2383    public double getSubTotal() {
2384        double itemsTotal = 0.00;
2385        Iterator JavaDoc i = iterator();
2386
2387        while (i.hasNext()) {
2388            itemsTotal += ((ShoppingCartItem) i.next()).getItemSubTotal();
2389        }
2390        return itemsTotal;
2391    }
2392
2393    /** Returns the total from the cart, including tax/shipping. */
2394    public double getGrandTotal() {
2395        // sales tax and shipping are not stored as adjustments but rather as part of the ship group
2396
// Debug.logInfo("Subtotal:" + this.getSubTotal() + " Shipping:" + this.getTotalShipping() + "SalesTax: "+ this.getTotalSalesTax() + " others: " + this.getOrderOtherAdjustmentTotal(),module);
2397
return this.getSubTotal() + this.getTotalShipping() + this.getTotalSalesTax() + this.getOrderOtherAdjustmentTotal();
2398    }
2399
2400    public double getDisplaySubTotal() {
2401        double itemsTotal = 0.00;
2402        Iterator JavaDoc i = iterator();
2403
2404        while (i.hasNext()) {
2405            itemsTotal += ((ShoppingCartItem) i.next()).getDisplayItemSubTotal();
2406        }
2407        return itemsTotal;
2408    }
2409
2410    /** Returns the total from the cart, including tax/shipping. */
2411    public double getDisplayGrandTotal() {
2412        return this.getDisplaySubTotal() + this.getTotalShipping() + this.getTotalSalesTax() + this.getOrderOtherAdjustmentTotal();
2413    }
2414
2415    public double getOrderOtherAdjustmentTotal() {
2416        return OrderReadHelper.calcOrderAdjustmentsBd(this.getAdjustments(), new BigDecimal JavaDoc(this.getSubTotal()), true, false, false).doubleValue();
2417    }
2418
2419    /** Returns the sub-total in the cart (item-total - discount). */
2420    public double getSubTotalForPromotions() {
2421        double itemsTotal = 0.00;
2422        Iterator JavaDoc i = iterator();
2423
2424        while (i.hasNext()) {
2425            ShoppingCartItem cartItem = (ShoppingCartItem) i.next();
2426            GenericValue product = cartItem.getProduct();
2427            if (product != null && "N".equals(product.getString("includeInPromotions"))) {
2428                // don't include in total if this is the case...
2429
continue;
2430            }
2431            itemsTotal += cartItem.getItemSubTotal();
2432        }
2433        return itemsTotal;
2434    }
2435
2436    /** Add a contact mech to this purpose; the contactMechPurposeTypeId is required */
2437    public void addContactMech(String JavaDoc contactMechPurposeTypeId, String JavaDoc contactMechId) {
2438        if (contactMechPurposeTypeId == null) throw new IllegalArgumentException JavaDoc("You must specify a contactMechPurposeTypeId to add a ContactMech");
2439        contactMechIdsMap.put(contactMechPurposeTypeId, contactMechId);
2440    }
2441
2442    /** Get the contactMechId for this cart given the contactMechPurposeTypeId */
2443    public String JavaDoc getContactMech(String JavaDoc contactMechPurposeTypeId) {
2444        return (String JavaDoc) contactMechIdsMap.get(contactMechPurposeTypeId);
2445    }
2446
2447    /** Remove the contactMechId from this cart given the contactMechPurposeTypeId */
2448    public String JavaDoc removeContactMech(String JavaDoc contactMechPurposeTypeId) {
2449        return (String JavaDoc) contactMechIdsMap.remove(contactMechPurposeTypeId);
2450    }
2451
2452    public Map JavaDoc getOrderContactMechIds() {
2453        return this.contactMechIdsMap;
2454    }
2455
2456    /** Get a List of adjustments on the order (ie cart) */
2457    public List JavaDoc getAdjustments() {
2458        return adjustments;
2459    }
2460
2461    /** Add an adjustment to the order; don't worry about setting the orderId, orderItemSeqId or orderAdjustmentId; they will be set when the order is created */
2462    public int addAdjustment(GenericValue adjustment) {
2463        adjustments.add(adjustment);
2464        return adjustments.indexOf(adjustment);
2465    }
2466
2467    public void removeAdjustment(int index) {
2468        adjustments.remove(index);
2469    }
2470
2471    /** Get a List of orderTerms on the order (ie cart) */
2472    public List JavaDoc getOrderTerms() {
2473        return orderTerms;
2474    }
2475
2476    /** Add an orderTerm to the order */
2477    public int addOrderTerm(String JavaDoc termTypeId,Double JavaDoc termValue,Long JavaDoc termDays) {
2478        GenericValue orderTerm = GenericValue.create(delegator.getModelEntity("OrderTerm"));
2479        orderTerm.put("termTypeId", termTypeId);
2480        orderTerm.put("termValue", termValue);
2481        orderTerm.put("termDays", termDays);
2482        return addOrderTerm(orderTerm);
2483    }
2484
2485    /** Add an orderTerm to the order */
2486    public int addOrderTerm(GenericValue orderTerm) {
2487        orderTerms.add(orderTerm);
2488        return orderTerms.indexOf(orderTerm);
2489    }
2490
2491    public void removeOrderTerm(int index) {
2492        orderTerms.remove(index);
2493    }
2494
2495    public void removeOrderTerms() {
2496        orderTerms.clear();
2497    }
2498
2499    public boolean isOrderTermSet(){
2500       return orderTermSet;
2501    }
2502
2503    public void setOrderTermSet(boolean orderTermSet){
2504         this.orderTermSet = orderTermSet;
2505     }
2506
2507    public boolean isReadOnlyCart(){
2508       return readOnlyCart;
2509    }
2510
2511    public void setReadOnlyCart(boolean readOnlyCart){
2512         this.readOnlyCart = readOnlyCart;
2513     }
2514
2515    /** go through the order adjustments and remove all adjustments with the given type */
2516    public void removeAdjustmentByType(String JavaDoc orderAdjustmentTypeId) {
2517        if (orderAdjustmentTypeId == null) return;
2518
2519        // make a list of adjustment lists including the cart adjustments and the cartItem adjustments for each item
2520
List JavaDoc adjsLists = new LinkedList JavaDoc();
2521
2522        if (this.getAdjustments() != null) {
2523            adjsLists.add(this.getAdjustments());
2524        }
2525        Iterator JavaDoc cartIterator = this.iterator();
2526
2527        while (cartIterator.hasNext()) {
2528            ShoppingCartItem item = (ShoppingCartItem) cartIterator.next();
2529
2530            if (item.getAdjustments() != null) {
2531                adjsLists.add(item.getAdjustments());
2532            }
2533        }
2534
2535        Iterator JavaDoc adjsListsIter = adjsLists.iterator();
2536
2537        while (adjsListsIter.hasNext()) {
2538            List JavaDoc adjs = (List JavaDoc) adjsListsIter.next();
2539
2540            if (adjs != null) {
2541                for (int i = 0; i < adjs.size();) {
2542                    GenericValue orderAdjustment = (GenericValue) adjs.get(i);
2543
2544                    if (orderAdjustmentTypeId.equals(orderAdjustment.getString("orderAdjustmentTypeId"))) {
2545                        adjs.remove(i);
2546                    } else {
2547                        i++;
2548                    }
2549                }
2550            }
2551        }
2552    }
2553
2554    /** Returns the total weight in the cart. */
2555    public double getTotalWeight() {
2556        double weight = 0.0;
2557        Iterator JavaDoc i = iterator();
2558
2559        while (i.hasNext()) {
2560            ShoppingCartItem item = (ShoppingCartItem) i.next();
2561
2562            weight += (item.getWeight() * item.getQuantity());
2563        }
2564        return weight;
2565    }
2566
2567    /** Returns the total quantity in the cart. */
2568    public double getTotalQuantity() {
2569        double count = 0.0;
2570        Iterator JavaDoc i = iterator();
2571
2572        while (i.hasNext()) {
2573            count += ((ShoppingCartItem) i.next()).getQuantity();
2574        }
2575        return count;
2576    }
2577
2578    /** Returns the SHIPPABLE item-total in the cart for a specific ship group. */
2579    public double getShippableTotal(int idx) {
2580        CartShipInfo info = this.getShipInfo(idx);
2581        double itemTotal = 0.0;
2582
2583        Iterator JavaDoc i = info.shipItemInfo.keySet().iterator();
2584        while (i.hasNext()) {
2585            ShoppingCartItem item = (ShoppingCartItem) i.next();
2586            CartShipInfo.CartShipItemInfo csii = (CartShipInfo.CartShipItemInfo) info.shipItemInfo.get(item);
2587            if (csii != null && csii.quantity > 0) {
2588                if (item.shippingApplies()) {
2589                    itemTotal += item.getItemSubTotal(csii.quantity);
2590                }
2591            }
2592        }
2593
2594        return itemTotal;
2595    }
2596
2597    /** Returns the total SHIPPABLE quantity in the cart for a specific ship group. */
2598    public double getShippableQuantity(int idx) {
2599        CartShipInfo info = this.getShipInfo(idx);
2600        double count = 0.0;
2601
2602        Iterator JavaDoc i = info.shipItemInfo.keySet().iterator();
2603        while (i.hasNext()) {
2604            ShoppingCartItem item = (ShoppingCartItem) i.next();
2605            CartShipInfo.CartShipItemInfo csii = (CartShipInfo.CartShipItemInfo) info.shipItemInfo.get(item);
2606            if (csii != null && csii.quantity > 0) {
2607                if (item.shippingApplies()) {
2608                    count += csii.quantity;
2609                }
2610            }
2611        }
2612
2613        return count;
2614    }
2615
2616    /** Returns the total SHIPPABLE weight in the cart for a specific ship group. */
2617    public double getShippableWeight(int idx) {
2618        CartShipInfo info = this.getShipInfo(idx);
2619        double weight = 0.0;
2620
2621        Iterator JavaDoc i = info.shipItemInfo.keySet().iterator();
2622        while (i.hasNext()) {
2623            ShoppingCartItem item = (ShoppingCartItem) i.next();
2624            CartShipInfo.CartShipItemInfo csii = (CartShipInfo.CartShipItemInfo) info.shipItemInfo.get(item);
2625            if (csii != null && csii.quantity > 0) {
2626                if (item.shippingApplies()) {
2627                    weight += (item.getWeight() * csii.quantity);
2628                }
2629            }
2630        }
2631
2632        return weight;
2633    }
2634
2635    /** Returns a List of shippable item's size for a specific ship group. */
2636    public List JavaDoc getShippableSizes(int idx) {
2637        CartShipInfo info = this.getShipInfo(idx);
2638        List JavaDoc shippableSizes = new LinkedList JavaDoc();
2639
2640        Iterator JavaDoc i = info.shipItemInfo.keySet().iterator();
2641        while (i.hasNext()) {
2642            ShoppingCartItem item = (ShoppingCartItem) i.next();
2643            CartShipInfo.CartShipItemInfo csii = (CartShipInfo.CartShipItemInfo) info.shipItemInfo.get(item);
2644            if (csii != null && csii.quantity > 0) {
2645                if (item.shippingApplies()) {
2646                    shippableSizes.add(new Double JavaDoc(item.getSize()));
2647                }
2648            }
2649        }
2650
2651        return shippableSizes;
2652    }
2653
2654    /** Returns a List of shippable item info (quantity, size, weight) for a specific ship group */
2655    public List JavaDoc getShippableItemInfo(int idx) {
2656        CartShipInfo info = this.getShipInfo(idx);
2657        List JavaDoc itemInfos = new LinkedList JavaDoc();
2658
2659        Iterator JavaDoc i = info.shipItemInfo.keySet().iterator();
2660        while (i.hasNext()) {
2661            ShoppingCartItem item = (ShoppingCartItem) i.next();
2662            CartShipInfo.CartShipItemInfo csii = (CartShipInfo.CartShipItemInfo) info.shipItemInfo.get(item);
2663            if (csii != null && csii.quantity > 0) {
2664                if (item.shippingApplies()) {
2665                    Map JavaDoc itemInfo = item.getItemProductInfo();
2666                    itemInfo.put("quantity", new Double JavaDoc(csii.quantity));
2667                    itemInfos.add(itemInfo);
2668                }
2669            }
2670        }
2671
2672        return itemInfos;
2673    }
2674
2675    /** Returns true when there are shippable items in the cart */
2676    public boolean shippingApplies() {
2677        boolean shippingApplies = false;
2678        Iterator JavaDoc i = this.iterator();
2679        while (i.hasNext()) {
2680            ShoppingCartItem item = (ShoppingCartItem) i.next();
2681            if (item.shippingApplies()) {
2682                shippingApplies = true;
2683                break;
2684            }
2685        }
2686        return shippingApplies;
2687    }
2688
2689    /** Returns true when there are taxable items in the cart */
2690    public boolean taxApplies() {
2691        boolean taxApplies = false;
2692        Iterator JavaDoc i = this.iterator();
2693        while (i.hasNext()) {
2694            ShoppingCartItem item = (ShoppingCartItem) i.next();
2695            if (item.taxApplies()) {
2696                taxApplies = true;
2697                break;
2698            }
2699        }
2700        return taxApplies;
2701    }
2702
2703    /** Returns a Map of all features applied to products in the cart with quantities for a specific ship group. */
2704    public Map JavaDoc getFeatureIdQtyMap(int idx) {
2705        CartShipInfo info = this.getShipInfo(idx);
2706        Map JavaDoc featureMap = new HashMap JavaDoc();
2707
2708        Iterator JavaDoc i = info.shipItemInfo.keySet().iterator();
2709        while (i.hasNext()) {
2710            ShoppingCartItem item = (ShoppingCartItem) i.next();
2711            CartShipInfo.CartShipItemInfo csii = (CartShipInfo.CartShipItemInfo) info.shipItemInfo.get(item);
2712            if (csii != null && csii.quantity > 0) {
2713                featureMap.putAll(item.getFeatureIdQtyMap(csii.quantity));
2714            }
2715        }
2716
2717        return featureMap;
2718    }
2719
2720    /** Returns true if the user wishes to view the cart everytime an item is added. */
2721    public boolean viewCartOnAdd() {
2722        return viewCartOnAdd;
2723    }
2724
2725    /** Returns true if the user wishes to view the cart everytime an item is added. */
2726    public void setViewCartOnAdd(boolean viewCartOnAdd) {
2727        this.viewCartOnAdd = viewCartOnAdd;
2728    }
2729
2730    /** Returns the order ID associated with this cart or null if no order has been created yet. */
2731    public String JavaDoc getOrderId() {
2732        return this.orderId;
2733    }
2734
2735    /** Returns the first attempt order ID associated with this cart or null if no order has been created yet. */
2736    public String JavaDoc getFirstAttemptOrderId() {
2737        return this.firstAttemptOrderId;
2738    }
2739
2740    /** Sets the orderId associated with this cart. */
2741    public void setOrderId(String JavaDoc orderId) {
2742        this.orderId = orderId;
2743    }
2744
2745    public void setNextItemSeq(long seq) throws GeneralException {
2746        if (this.nextItemSeq != 1) {
2747            throw new GeneralException("Cannot set the item sequence once the sequence has been incremented!");
2748        } else {
2749            this.nextItemSeq = seq;
2750        }
2751    }
2752
2753    /** TODO: Sets the first attempt orderId for this cart. */
2754    public void setFirstAttemptOrderId(String JavaDoc orderId) {
2755        this.firstAttemptOrderId = orderId;
2756    }
2757
2758    public void removeAllFreeShippingProductPromoActions() {
2759        this.freeShippingProductPromoActions.clear();
2760    }
2761    /** Removes a free shipping ProductPromoAction by trying to find one in the list with the same primary key. */
2762    public void removeFreeShippingProductPromoAction(GenericPK productPromoActionPK) {
2763        if (productPromoActionPK == null) return;
2764
2765        Iterator JavaDoc fsppas = this.freeShippingProductPromoActions.iterator();
2766        while (fsppas.hasNext()) {
2767            if (productPromoActionPK.equals(((GenericValue) fsppas.next()).getPrimaryKey())) {
2768                fsppas.remove();
2769            }
2770        }
2771    }
2772    /** Adds a ProductPromoAction to be used for free shipping (must be of type free shipping, or nothing will be done). */
2773    public void addFreeShippingProductPromoAction(GenericValue productPromoAction) {
2774        if (productPromoAction == null) return;
2775        // is this a free shipping action?
2776
if (!"PROMO_FREE_SHIPPING".equals(productPromoAction.getString("productPromoActionEnumId"))) return; // Changed 1-5-04 by Si Chen
2777

2778        // to easily make sure that no duplicate exists, do a remove first
2779
this.removeFreeShippingProductPromoAction(productPromoAction.getPrimaryKey());
2780        this.freeShippingProductPromoActions.add(productPromoAction);
2781    }
2782    public List JavaDoc getFreeShippingProductPromoActions() {
2783        return this.freeShippingProductPromoActions;
2784    }
2785
2786    public void removeAllDesiredAlternateGiftByActions() {
2787        this.desiredAlternateGiftByAction.clear();
2788    }
2789    public void setDesiredAlternateGiftByAction(GenericPK productPromoActionPK, String JavaDoc productId) {
2790        this.desiredAlternateGiftByAction.put(productPromoActionPK, productId);
2791    }
2792    public String JavaDoc getDesiredAlternateGiftByAction(GenericPK productPromoActionPK) {
2793        return (String JavaDoc) this.desiredAlternateGiftByAction.get(productPromoActionPK);
2794    }
2795    public Map JavaDoc getAllDesiredAlternateGiftByActionCopy() {
2796        return new HashMap JavaDoc(this.desiredAlternateGiftByAction);
2797    }
2798
2799    public void addProductPromoUse(String JavaDoc productPromoId, String JavaDoc productPromoCodeId, double totalDiscountAmount, double quantityLeftInActions) {
2800        if (UtilValidate.isNotEmpty(productPromoCodeId) && !this.productPromoCodes.contains(productPromoCodeId)) {
2801            throw new IllegalStateException JavaDoc("Cannot add a use to a promo code use for a code that has not been entered.");
2802        }
2803        if (Debug.verboseOn()) Debug.logVerbose("Used promotion [" + productPromoId + "] with code [" + productPromoCodeId + "] for total discount [" + totalDiscountAmount + "] and quantity left in actions [" + quantityLeftInActions + "]", module);
2804        this.productPromoUseInfoList.add(new ProductPromoUseInfo(productPromoId, productPromoCodeId, totalDiscountAmount, quantityLeftInActions));
2805    }
2806
2807    public void clearProductPromoUseInfo() {
2808        // clear out info for general promo use
2809
this.productPromoUseInfoList.clear();
2810    }
2811
2812    public void clearCartItemUseInPromoInfo() {
2813        // clear out info about which cart items have been used in promos
2814
Iterator JavaDoc cartLineIter = this.iterator();
2815        while (cartLineIter.hasNext()) {
2816            ShoppingCartItem cartLine = (ShoppingCartItem) cartLineIter.next();
2817            cartLine.clearPromoRuleUseInfo();
2818        }
2819    }
2820
2821    public Iterator JavaDoc getProductPromoUseInfoIter() {
2822        return productPromoUseInfoList.iterator();
2823    }
2824
2825    public double getProductPromoUseTotalDiscount(String JavaDoc productPromoId) {
2826        if (productPromoId == null) return 0;
2827        double totalDiscount = 0;
2828        Iterator JavaDoc productPromoUseInfoIter = this.productPromoUseInfoList.iterator();
2829        while (productPromoUseInfoIter.hasNext()) {
2830            ProductPromoUseInfo productPromoUseInfo = (ProductPromoUseInfo) productPromoUseInfoIter.next();
2831            if (productPromoId.equals(productPromoUseInfo.productPromoId)) {
2832                totalDiscount += productPromoUseInfo.getTotalDiscountAmount();
2833            }
2834        }
2835        return totalDiscount;
2836    }
2837
2838    public int getProductPromoUseCount(String JavaDoc productPromoId) {
2839        if (productPromoId == null) return 0;
2840        int useCount = 0;
2841        Iterator JavaDoc productPromoUseInfoIter = this.productPromoUseInfoList.iterator();
2842        while (productPromoUseInfoIter.hasNext()) {
2843            ProductPromoUseInfo productPromoUseInfo = (ProductPromoUseInfo) productPromoUseInfoIter.next();
2844            if (productPromoId.equals(productPromoUseInfo.productPromoId)) {
2845                useCount++;
2846            }
2847        }
2848        return useCount;
2849    }
2850
2851    public int getProductPromoCodeUse(String JavaDoc productPromoCodeId) {
2852        if (productPromoCodeId == null) return 0;
2853        int useCount = 0;
2854        Iterator JavaDoc productPromoUseInfoIter = this.productPromoUseInfoList.iterator();
2855        while (productPromoUseInfoIter.hasNext()) {
2856            ProductPromoUseInfo productPromoUseInfo = (ProductPromoUseInfo) productPromoUseInfoIter.next();
2857            if (productPromoCodeId.equals(productPromoUseInfo.productPromoCodeId)) {
2858                useCount++;
2859            }
2860        }
2861        return useCount;
2862    }
2863
2864    public void clearAllPromotionInformation() {
2865        this.clearAllPromotionAdjustments();
2866
2867        // remove all free shipping promo actions
2868
this.removeAllFreeShippingProductPromoActions();
2869
2870        // clear promo uses & reset promo code uses, and reset info about cart items used for promos (ie qualifiers and benefiters)
2871
this.clearProductPromoUseInfo();
2872        this.clearCartItemUseInPromoInfo();
2873    }
2874
2875    public void clearAllPromotionAdjustments() {
2876        // remove cart adjustments from promo actions
2877
List JavaDoc cartAdjustments = this.getAdjustments();
2878        if (cartAdjustments != null) {
2879            Iterator JavaDoc cartAdjustmentIter = cartAdjustments.iterator();
2880            while (cartAdjustmentIter.hasNext()) {
2881                GenericValue checkOrderAdjustment = (GenericValue) cartAdjustmentIter.next();
2882                if (UtilValidate.isNotEmpty(checkOrderAdjustment.getString("productPromoId")) &&
2883                        UtilValidate.isNotEmpty(checkOrderAdjustment.getString("productPromoRuleId")) &&
2884                        UtilValidate.isNotEmpty(checkOrderAdjustment.getString("productPromoActionSeqId"))) {
2885                    cartAdjustmentIter.remove();
2886                }
2887            }
2888        }
2889
2890        // remove cart lines that are promos (ie GWPs) and cart line adjustments from promo actions
2891
Iterator JavaDoc cartItemIter = this.iterator();
2892        while (cartItemIter.hasNext()) {
2893            ShoppingCartItem checkItem = (ShoppingCartItem) cartItemIter.next();
2894            if (checkItem.getIsPromo()) {
2895                this.clearItemShipInfo(checkItem);
2896                cartItemIter.remove();
2897            } else {
2898                // found a promo item with the productId, see if it has a matching adjustment on it
2899
Iterator JavaDoc checkOrderAdjustments = UtilMisc.toIterator(checkItem.getAdjustments());
2900                while (checkOrderAdjustments != null && checkOrderAdjustments.hasNext()) {
2901                    GenericValue checkOrderAdjustment = (GenericValue) checkOrderAdjustments.next();
2902                    if (UtilValidate.isNotEmpty(checkOrderAdjustment.getString("productPromoId")) &&
2903                            UtilValidate.isNotEmpty(checkOrderAdjustment.getString("productPromoRuleId")) &&
2904                            UtilValidate.isNotEmpty(checkOrderAdjustment.getString("productPromoActionSeqId"))) {
2905                        checkOrderAdjustments.remove();
2906                    }
2907                }
2908            }
2909        }
2910    }
2911
2912    public void clearAllAdjustments() {
2913        // remove all the promotion information (including adjustments)
2914
clearAllPromotionInformation();
2915        // remove all cart adjustments
2916
this.adjustments.clear();
2917        // remove all cart item adjustments
2918
Iterator JavaDoc cartItemIter = this.iterator();
2919        while (cartItemIter.hasNext()) {
2920            ShoppingCartItem checkItem = (ShoppingCartItem) cartItemIter.next();
2921            checkItem.getAdjustments().clear();
2922        }
2923    }
2924
2925    public void clearAllItemStatus() {
2926        Iterator JavaDoc lineIter = this.iterator();
2927        while (lineIter.hasNext()) {
2928            ShoppingCartItem item = (ShoppingCartItem) lineIter.next();
2929            item.setStatusId(null);
2930        }
2931    }
2932
2933    /** Adds a promotion code to the cart, checking if it is valid. If it is valid this will return null, otherwise it will return a message stating why it was not valid
2934     * @param productPromoCodeId The promotion code to check and add
2935     * @return String that is null if valid, and added to cart, or an error message of the code was not valid and not added to the cart.
2936     */

2937    public String JavaDoc addProductPromoCode(String JavaDoc productPromoCodeId, LocalDispatcher dispatcher) {
2938        if (this.productPromoCodes.contains(productPromoCodeId)) {
2939            return "The promotion code [" + productPromoCodeId + "] has already been entered.";
2940        }
2941        // if the promo code requires it make sure the code is valid
2942
String JavaDoc checkResult = ProductPromoWorker.checkCanUsePromoCode(productPromoCodeId, this.getPartyId(), this.getDelegator());
2943        if (checkResult == null) {
2944            this.productPromoCodes.add(productPromoCodeId);
2945            // new promo code, re-evaluate promos
2946
ProductPromoWorker.doPromotions(this, dispatcher);
2947            return null;
2948        } else {
2949            return checkResult;
2950        }
2951    }
2952
2953    public Set JavaDoc getProductPromoCodesEntered() {
2954        return this.productPromoCodes;
2955    }
2956
2957    public synchronized void resetPromoRuleUse(String JavaDoc productPromoId, String JavaDoc productPromoRuleId) {
2958        Iterator JavaDoc lineIter = this.iterator();
2959        while (lineIter.hasNext()) {
2960            ShoppingCartItem cartItem = (ShoppingCartItem) lineIter.next();
2961            cartItem.resetPromoRuleUse(productPromoId, productPromoRuleId);
2962        }
2963    }
2964
2965    public synchronized void confirmPromoRuleUse(String JavaDoc productPromoId, String JavaDoc productPromoRuleId) {
2966        Iterator JavaDoc lineIter = this.iterator();
2967        while (lineIter.hasNext()) {
2968            ShoppingCartItem cartItem = (ShoppingCartItem) lineIter.next();
2969            cartItem.confirmPromoRuleUse(productPromoId, productPromoRuleId);
2970        }
2971    }
2972
2973    /**
2974     * Associates a party with a role to the order.
2975     * @param partyId identifier of the party to associate to order
2976     * @param roleTypeId identifier of the role used in party-order association
2977     */

2978    public void addAdditionalPartyRole(String JavaDoc partyId, String JavaDoc roleTypeId) {
2979        // search if there is an existing entry
2980
List JavaDoc parties = (List JavaDoc) additionalPartyRole.get(roleTypeId);
2981        if (parties != null) {
2982            Iterator JavaDoc it = parties.iterator();
2983            while (it.hasNext()) {
2984                if (((String JavaDoc) it.next()).equals(partyId)) {
2985                    return;
2986                }
2987            }
2988        } else {
2989            parties = new LinkedList JavaDoc();
2990            additionalPartyRole.put(roleTypeId, parties);
2991        }
2992
2993        parties.add(0, partyId);
2994    }
2995
2996    /**
2997     * Removes a previously associated party to the order.
2998     * @param partyId identifier of the party to associate to order
2999     * @param roleTypeId identifier of the role used in party-order association
3000     */

3001    public void removeAdditionalPartyRole(String JavaDoc partyId, String JavaDoc roleTypeId) {
3002        List JavaDoc parties = (List JavaDoc) additionalPartyRole.get(roleTypeId);
3003
3004        if (parties != null) {
3005            Iterator JavaDoc it = parties.iterator();
3006            while (it.hasNext()) {
3007                if (((String JavaDoc) it.next()).equals(partyId)) {
3008                    it.remove();
3009
3010                    if (parties.isEmpty()) {
3011                        additionalPartyRole.remove(roleTypeId);
3012                    }
3013                    return;
3014                }
3015            }
3016        }
3017    }
3018
3019    public Map JavaDoc getAdditionalPartyRoleMap() {
3020        return additionalPartyRole;
3021    }
3022
3023    // =======================================================================
3024
// Methods used for order creation
3025
// =======================================================================
3026

3027    private void explodeItems(LocalDispatcher dispatcher) {
3028        synchronized (cartLines) {
3029            if (dispatcher != null) {
3030                List JavaDoc cartLineItems = new LinkedList JavaDoc(cartLines);
3031                Iterator JavaDoc itemIter = cartLineItems.iterator();
3032
3033                while (itemIter.hasNext()) {
3034                    ShoppingCartItem item = (ShoppingCartItem) itemIter.next();
3035
3036                    Debug.logInfo("Item qty: " + item.getQuantity(), module);
3037                    try {
3038                        item.explodeItem(this, dispatcher);
3039                    } catch (CartItemModifyException e) {
3040                        Debug.logError(e, "Problem exploding item! Item not exploded.", module);
3041                    }
3042                }
3043            }
3044        }
3045    }
3046
3047    public List JavaDoc makeOrderItems() {
3048        return makeOrderItems(false, null);
3049    }
3050
3051    public List JavaDoc makeOrderItems(boolean explodeItems, LocalDispatcher dispatcher) {
3052        // do the explosion
3053
if (explodeItems && dispatcher != null)
3054            explodeItems(dispatcher);
3055
3056        // now build the lines
3057
synchronized (cartLines) {
3058            List JavaDoc result = new LinkedList JavaDoc();
3059
3060            Iterator JavaDoc itemIter = cartLines.iterator();
3061
3062            while (itemIter.hasNext()) {
3063                ShoppingCartItem item = (ShoppingCartItem) itemIter.next();
3064
3065                if (UtilValidate.isEmpty(item.getOrderItemSeqId())) {
3066                    String JavaDoc orderItemSeqId = UtilFormatOut.formatPaddedNumber(nextItemSeq, 5);
3067                    item.setOrderItemSeqId(orderItemSeqId);
3068                } else {
3069                    try {
3070                        int thisSeqId = Integer.parseInt(item.getOrderItemSeqId());
3071                        if (thisSeqId > nextItemSeq) {
3072                            nextItemSeq = thisSeqId;
3073                        }
3074                    } catch (NumberFormatException JavaDoc e) {
3075                        Debug.logError(e, module);
3076                    }
3077                }
3078                nextItemSeq++;
3079
3080                // the initial status for all item types
3081
String JavaDoc initialStatus = "ITEM_CREATED";
3082                String JavaDoc status = item.getStatusId();
3083                if (status == null) {
3084                    status = initialStatus;
3085                }
3086
3087                GenericValue orderItem = getDelegator().makeValue("OrderItem", null);
3088                orderItem.set("orderItemSeqId", item.getOrderItemSeqId());
3089                orderItem.set("orderItemTypeId", item.getItemType());
3090                orderItem.set("productId", item.getProductId());
3091                orderItem.set("prodCatalogId", item.getProdCatalogId());
3092                orderItem.set("productCategoryId", item.getProductCategoryId());
3093                orderItem.set("quantity", new Double JavaDoc(item.getQuantity()));
3094                orderItem.set("selectedAmount", new Double JavaDoc(item.getSelectedAmount()));
3095                orderItem.set("unitPrice", new Double JavaDoc(item.getBasePrice()));
3096                orderItem.set("unitListPrice", new Double JavaDoc(item.getListPrice()));
3097                orderItem.set("isModifiedPrice",item.getIsModifiedPrice() ? "Y" : "N");
3098                orderItem.set("isPromo", item.getIsPromo() ? "Y" : "N");
3099
3100                orderItem.set("shoppingListId", item.getShoppingListId());
3101                orderItem.set("shoppingListItemSeqId", item.getShoppingListItemSeqId());
3102
3103                orderItem.set("itemDescription", item.getName());
3104                orderItem.set("comments", item.getItemComment());
3105                orderItem.set("estimatedDeliveryDate", item.getDesiredDeliveryDate());
3106                orderItem.set("correspondingPoId", this.getPoNumber());
3107                orderItem.set("quoteId", item.getQuoteId());
3108                orderItem.set("quoteItemSeqId", item.getQuoteItemSeqId());
3109                orderItem.set("statusId", status);
3110
3111                orderItem.set("shipBeforeDate", item.getShipBeforeDate());
3112                orderItem.set("shipAfterDate", item.getShipAfterDate());
3113
3114                result.add(orderItem);
3115                // don't do anything with adjustments here, those will be added below in makeAllAdjustments
3116
}
3117            return result;
3118        }
3119    }
3120
3121    /** create WorkEfforts from the shoppingcart items when itemType = RENTAL_ORDER_ITEM */
3122    public List JavaDoc makeWorkEfforts() {
3123        List JavaDoc allWorkEfforts = new LinkedList JavaDoc();
3124        Iterator JavaDoc itemIter = cartLines.iterator();
3125
3126        while (itemIter.hasNext()) {
3127            ShoppingCartItem item = (ShoppingCartItem) itemIter.next();
3128            if ("RENTAL_ORDER_ITEM".equals(item.getItemType())) { // prepare workeffort when the order item is a rental item
3129
GenericValue workEffort = getDelegator().makeValue("WorkEffort", null);
3130                workEffort.set("workEffortId",item.getOrderItemSeqId()); // fill temporary with sequence number
3131
workEffort.set("estimatedStartDate",item.getReservStart());
3132                workEffort.set("estimatedCompletionDate",item.getReservStart(item.getReservLength()));
3133                workEffort.set("reservPersons",new Double JavaDoc(item.getReservPersons()));
3134                workEffort.set("reserv2ndPPPerc", new Double JavaDoc(item.getReserv2ndPPPerc()));
3135                workEffort.set("reservNthPPPerc", new Double JavaDoc(item.getReservNthPPPerc()));
3136
3137                allWorkEfforts.add(workEffort);
3138            }
3139        }
3140        return allWorkEfforts;
3141    }
3142
3143    /** make a list of all adjustments including order adjustments, order line adjustments, and special adjustments (shipping and tax if applicable) */
3144    public List JavaDoc makeAllAdjustments() {
3145        List JavaDoc allAdjs = new LinkedList JavaDoc();
3146
3147        // before returning adjustments, go through them to find all that need counter adjustments (for instance: free shipping)
3148
Iterator JavaDoc allAdjsIter = this.getAdjustments().iterator();
3149
3150        while (allAdjsIter.hasNext()) {
3151            GenericValue orderAdjustment = (GenericValue) allAdjsIter.next();
3152
3153            allAdjs.add(orderAdjustment);
3154
3155            if ("SHIPPING_CHARGES".equals(orderAdjustment.get("orderAdjustmentTypeId"))) {
3156                Iterator JavaDoc fsppas = this.freeShippingProductPromoActions.iterator();
3157
3158                while (fsppas.hasNext()) {
3159                    GenericValue productPromoAction = (GenericValue) fsppas.next();
3160
3161                    // TODO - we need to change the way free shipping promotions work
3162
/*
3163                    if ((productPromoAction.get("productId") == null || productPromoAction.getString("productId").equals(this.getShipmentMethodTypeId())) &&
3164                        (productPromoAction.get("partyId") == null || productPromoAction.getString("partyId").equals(this.getCarrierPartyId()))) {
3165                        Double shippingAmount = new Double(-OrderReadHelper.calcOrderAdjustment(orderAdjustment, getSubTotal()));
3166                        // always set orderAdjustmentTypeId to SHIPPING_CHARGES for free shipping adjustments
3167                        GenericValue fsOrderAdjustment = getDelegator().makeValue("OrderAdjustment",
3168                                UtilMisc.toMap("orderItemSeqId", orderAdjustment.get("orderItemSeqId"), "orderAdjustmentTypeId", "SHIPPING_CHARGES", "amount", shippingAmount,
3169                                    "productPromoId", productPromoAction.get("productPromoId"), "productPromoRuleId", productPromoAction.get("productPromoRuleId"),
3170                                    "productPromoActionSeqId", productPromoAction.get("productPromoActionSeqId")));
3171
3172                        allAdjs.add(fsOrderAdjustment);
3173
3174                        // if free shipping IS applied to this orderAdjustment, break
3175                        // out of the loop so that even if there are multiple free
3176                        // shipping adjustments that apply to this orderAdjustment it
3177                        // will only be compensated for once
3178                        break;
3179                    }
3180                    */

3181                }
3182            }
3183        }
3184
3185        // add all of the item adjustments to this list too
3186
Iterator JavaDoc itemIter = cartLines.iterator();
3187
3188        while (itemIter.hasNext()) {
3189            ShoppingCartItem item = (ShoppingCartItem) itemIter.next();
3190            Collection JavaDoc adjs = item.getAdjustments();
3191
3192            if (adjs != null) {
3193                Iterator JavaDoc adjIter = adjs.iterator();
3194
3195                while (adjIter.hasNext()) {
3196                    GenericValue orderAdjustment = (GenericValue) adjIter.next();
3197
3198                    orderAdjustment.set("orderItemSeqId", item.getOrderItemSeqId());
3199                    allAdjs.add(orderAdjustment);
3200
3201                    if ("SHIPPING_CHARGES".equals(orderAdjustment.get("orderAdjustmentTypeId"))) {
3202                        Iterator JavaDoc fsppas = this.freeShippingProductPromoActions.iterator();
3203
3204                        while (fsppas.hasNext()) {
3205                            GenericValue productPromoAction = (GenericValue) fsppas.next();
3206
3207                            // TODO - fix the free shipping promotions!!
3208
/*
3209                            if ((productPromoAction.get("productId") == null || productPromoAction.getString("productId").equals(item.getShipmentMethodTypeId())) &&
3210                                (productPromoAction.get("partyId") == null || productPromoAction.getString("partyId").equals(item.getCarrierPartyId()))) {
3211                                Double shippingAmount = new Double(-OrderReadHelper.calcItemAdjustment(orderAdjustment, new Double(item.getQuantity()), new Double(item.getItemSubTotal())));
3212                                // always set orderAdjustmentTypeId to SHIPPING_CHARGES for free shipping adjustments
3213                                GenericValue fsOrderAdjustment = getDelegator().makeValue("OrderAdjustment",
3214                                        UtilMisc.toMap("orderItemSeqId", orderAdjustment.get("orderItemSeqId"), "orderAdjustmentTypeId", "SHIPPING_CHARGES", "amount", shippingAmount,
3215                                            "productPromoId", productPromoAction.get("productPromoId"), "productPromoRuleId", productPromoAction.get("productPromoRuleId"),
3216                                            "productPromoActionSeqId", productPromoAction.get("productPromoActionSeqId")));
3217
3218                                allAdjs.add(fsOrderAdjustment);
3219
3220                                // if free shipping IS applied to this orderAdjustment, break
3221                                // out of the loop so that even if there are multiple free
3222                                // shipping adjustments that apply to this orderAdjustment it
3223                                // will only be compensated for once
3224                                break;
3225                            }
3226                            */

3227                        }
3228                    }
3229                }
3230            }
3231        }
3232
3233        return allAdjs;
3234    }
3235
3236    /** make a list of all quote adjustments including header adjustments, line adjustments, and special adjustments (shipping and tax if applicable).
3237     * Internally, the quote adjustments are created from the order adjustments.
3238     */

3239    public List JavaDoc makeAllQuoteAdjustments() {
3240        List JavaDoc quoteAdjs = new LinkedList JavaDoc();
3241
3242        List JavaDoc orderAdjs = makeAllAdjustments();
3243        Iterator JavaDoc orderAdjsIter = orderAdjs.iterator();
3244
3245        while (orderAdjsIter.hasNext()) {
3246            GenericValue orderAdj = (GenericValue) orderAdjsIter.next();
3247            GenericValue quoteAdj = this.getDelegator().makeValue("QuoteAdjustment", null);
3248            quoteAdj.put("quoteAdjustmentId", orderAdj.get("orderAdjustmentId"));
3249            quoteAdj.put("quoteAdjustmentTypeId", orderAdj.get("orderAdjustmentTypeId"));
3250            quoteAdj.put("quoteItemSeqId", orderAdj.get("orderItemSeqId"));
3251            quoteAdj.put("comments", orderAdj.get("comments"));
3252            quoteAdj.put("description", orderAdj.get("description"));
3253            quoteAdj.put("amount", orderAdj.get("amount"));
3254            quoteAdj.put("productPromoId", orderAdj.get("productPromoId"));
3255            quoteAdj.put("productPromoRuleId", orderAdj.get("productPromoRuleId"));
3256            quoteAdj.put("productPromoActionSeqId", orderAdj.get("productPromoActionSeqId"));
3257            quoteAdj.put("productFeatureId", orderAdj.get("productFeatureId"));
3258            quoteAdj.put("correspondingProductId", orderAdj.get("correspondingProductId"));
3259            quoteAdj.put("sourceReferenceId", orderAdj.get("sourceReferenceId"));
3260            quoteAdj.put("sourcePercentage", orderAdj.get("sourcePercentage"));
3261            quoteAdj.put("customerReferenceId", orderAdj.get("customerReferenceId"));
3262            quoteAdj.put("primaryGeoId", orderAdj.get("primaryGeoId"));
3263            quoteAdj.put("secondaryGeoId", orderAdj.get("secondaryGeoId"));
3264            quoteAdj.put("exemptAmount", orderAdj.get("exemptAmount"));
3265            quoteAdj.put("taxAuthGeoId", orderAdj.get("taxAuthGeoId"));
3266            quoteAdj.put("taxAuthPartyId", orderAdj.get("taxAuthPartyId"));
3267            quoteAdj.put("overrideGlAccountId", orderAdj.get("overrideGlAccountId"));
3268            quoteAdj.put("includeInTax", orderAdj.get("includeInTax"));
3269            quoteAdj.put("includeInShipping", orderAdj.get("includeInShipping"));
3270            quoteAdj.put("createdDate", orderAdj.get("createdDate"));
3271            quoteAdj.put("createdByUserLogin", orderAdj.get("createdByUserLogin"));
3272            quoteAdjs.add(quoteAdj);
3273        }
3274
3275        return quoteAdjs;
3276    }
3277
3278    /** make a list of all OrderPaymentPreferences and Billing info including all payment methods and types */
3279    public List JavaDoc makeAllOrderPaymentInfos() {
3280        List JavaDoc allOpPrefs = new LinkedList JavaDoc();
3281        Iterator JavaDoc i = paymentInfo.iterator();
3282        while (i.hasNext()) {
3283            CartPaymentInfo inf = (CartPaymentInfo) i.next();
3284            allOpPrefs.addAll(inf.makeOrderPaymentInfos(this.getDelegator()));
3285
3286        }
3287
3288        return allOpPrefs;
3289    }
3290
3291    /** make a list of OrderItemPriceInfos from the ShoppingCartItems */
3292    public List JavaDoc makeAllOrderItemPriceInfos() {
3293        List JavaDoc allInfos = new LinkedList JavaDoc();
3294
3295        // add all of the item adjustments to this list too
3296
Iterator JavaDoc itemIter = cartLines.iterator();
3297
3298        while (itemIter.hasNext()) {
3299            ShoppingCartItem item = (ShoppingCartItem) itemIter.next();
3300            Collection JavaDoc infos = item.getOrderItemPriceInfos();
3301
3302            if (infos != null) {
3303                Iterator JavaDoc infosIter = infos.iterator();
3304
3305                while (infosIter.hasNext()) {
3306                    GenericValue orderItemPriceInfo = (GenericValue) infosIter.next();
3307
3308                    orderItemPriceInfo.set("orderItemSeqId", item.getOrderItemSeqId());
3309                    allInfos.add(orderItemPriceInfo);
3310                }
3311            }
3312        }
3313
3314        return allInfos;
3315    }
3316
3317    public List JavaDoc makeProductPromoUses() {
3318        List JavaDoc productPromoUses = new ArrayList JavaDoc(this.productPromoUseInfoList.size());
3319        String JavaDoc partyId = this.getPartyId();
3320        int sequenceValue = 0;
3321        Iterator JavaDoc productPromoUseInfoIter = this.productPromoUseInfoList.iterator();
3322        while (productPromoUseInfoIter.hasNext()) {
3323            ProductPromoUseInfo productPromoUseInfo = (ProductPromoUseInfo) productPromoUseInfoIter.next();
3324            GenericValue productPromoUse = this.getDelegator().makeValue("ProductPromoUse", null);
3325            productPromoUse.set("promoSequenceId", UtilFormatOut.formatPaddedNumber(sequenceValue, 5));
3326            productPromoUse.set("productPromoId", productPromoUseInfo.getProductPromoId());
3327            productPromoUse.set("productPromoCodeId", productPromoUseInfo.getProductPromoCodeId());
3328            productPromoUse.set("totalDiscountAmount", new Double JavaDoc(productPromoUseInfo.getTotalDiscountAmount()));
3329            productPromoUse.set("quantityLeftInActions", new Double JavaDoc(productPromoUseInfo.getQuantityLeftInActions()));
3330            productPromoUse.set("partyId", partyId);
3331            productPromoUses.add(productPromoUse);
3332            sequenceValue++;
3333        }
3334        return productPromoUses;
3335    }
3336
3337    /** make a list of SurveyResponse object to update with order information set */
3338    public List JavaDoc makeAllOrderItemSurveyResponses() {
3339        List JavaDoc allInfos = new LinkedList JavaDoc();
3340        Iterator JavaDoc itemIter = this.iterator();
3341        while (itemIter.hasNext()) {
3342            ShoppingCartItem item = (ShoppingCartItem) itemIter.next();
3343            List JavaDoc responses = (List JavaDoc) item.getAttribute("surveyResponses");
3344            if (responses != null) {
3345                Iterator JavaDoc ri = responses.iterator();
3346                while (ri.hasNext()) {
3347                    String JavaDoc responseId = (String JavaDoc) ri.next();
3348                    GenericValue response = null;
3349                    try {
3350                        response = this.getDelegator().findByPrimaryKey("SurveyResponse", UtilMisc.toMap("surveyResponseId", responseId));
3351                    } catch (GenericEntityException e) {
3352                        Debug.logError(e, "Unable to obtain SurveyResponse record for ID : " + responseId, module);
3353                    }
3354                    if (response != null) {
3355                        response.set("orderItemSeqId", item.getOrderItemSeqId());
3356                        allInfos.add(response);
3357                    }
3358                }
3359            }
3360        }
3361        return allInfos;
3362    }
3363
3364    /** make a list of OrderContactMechs from the ShoppingCart and the ShoppingCartItems */
3365    public List JavaDoc makeAllOrderContactMechs() {
3366        List JavaDoc allOrderContactMechs = new LinkedList JavaDoc();
3367
3368        Map JavaDoc contactMechIds = this.getOrderContactMechIds();
3369
3370        if (contactMechIds != null) {
3371            Iterator JavaDoc cMechIdsIter = contactMechIds.entrySet().iterator();
3372
3373            while (cMechIdsIter.hasNext()) {
3374                Map.Entry JavaDoc entry = (Map.Entry JavaDoc) cMechIdsIter.next();
3375                GenericValue orderContactMech = getDelegator().makeValue("OrderContactMech", null);
3376
3377                orderContactMech.set("contactMechPurposeTypeId", entry.getKey());
3378                orderContactMech.set("contactMechId", entry.getValue());
3379                allOrderContactMechs.add(orderContactMech);
3380            }
3381        }
3382
3383        return allOrderContactMechs;
3384    }
3385
3386    /** make a list of OrderContactMechs from the ShoppingCart and the ShoppingCartItems */
3387    public List JavaDoc makeAllOrderItemContactMechs() {
3388        List JavaDoc allOrderContactMechs = new LinkedList JavaDoc();
3389
3390        Iterator JavaDoc itemIter = cartLines.iterator();
3391
3392        while (itemIter.hasNext()) {
3393            ShoppingCartItem item = (ShoppingCartItem) itemIter.next();
3394            Map JavaDoc itemContactMechIds = item.getOrderItemContactMechIds();
3395
3396            if (itemContactMechIds != null) {
3397                Iterator JavaDoc cMechIdsIter = itemContactMechIds.entrySet().iterator();
3398
3399                while (cMechIdsIter.hasNext()) {
3400                    Map.Entry JavaDoc entry = (Map.Entry JavaDoc) cMechIdsIter.next();
3401                    GenericValue orderContactMech = getDelegator().makeValue("OrderItemContactMech", null);
3402
3403                    orderContactMech.set("contactMechPurposeTypeId", entry.getKey());
3404                    orderContactMech.set("contactMechId", entry.getValue());
3405                    orderContactMech.set("orderItemSeqId", item.getOrderItemSeqId());
3406                    allOrderContactMechs.add(orderContactMech);
3407                }
3408            }
3409        }
3410
3411        return allOrderContactMechs;
3412    }
3413
3414    public List JavaDoc makeAllShipGroupInfos() {
3415        List JavaDoc groups = new LinkedList JavaDoc();
3416        Iterator JavaDoc grpIterator = shipInfo.iterator();
3417        long seqId = 1;
3418        while (grpIterator.hasNext()) {
3419            CartShipInfo csi = (CartShipInfo) grpIterator.next();
3420            groups.addAll(csi.makeItemShipGroupAndAssoc(this.getDelegator(), this, seqId));
3421            seqId++;
3422        }
3423        return groups;
3424    }
3425
3426    public List JavaDoc makeAllOrderItemAttributes() {
3427        List JavaDoc allOrderItemAttributes = new LinkedList JavaDoc();
3428
3429        Iterator JavaDoc itemIter = cartLines.iterator();
3430        while (itemIter.hasNext()) {
3431            ShoppingCartItem item = (ShoppingCartItem) itemIter.next();
3432            Map JavaDoc attrs = item.getOrderItemAttributes();
3433            Iterator JavaDoc i = attrs.entrySet().iterator();
3434            while (i.hasNext()) {
3435                Map.Entry JavaDoc entry = (Map.Entry JavaDoc) i.next();
3436                GenericValue itemAtt = this.getDelegator().makeValue("OrderItemAttribute", null);
3437                itemAtt.set("orderItemSeqId", item.getOrderItemSeqId());
3438                itemAtt.set("attrName", entry.getKey());
3439                itemAtt.set("attrValue", entry.getValue());
3440                allOrderItemAttributes.add(itemAtt);
3441            }
3442        }
3443        return allOrderItemAttributes;
3444    }
3445
3446    public List JavaDoc makeAllOrderAttributes() {
3447        List JavaDoc allOrderAttributes = new LinkedList JavaDoc();
3448
3449        Iterator JavaDoc i = orderAttributes.entrySet().iterator();
3450        while (i.hasNext()) {
3451            Map.Entry JavaDoc entry = (Map.Entry JavaDoc) i.next();
3452            GenericValue orderAtt = this.getDelegator().makeValue("OrderAttribute", null);
3453            orderAtt.put("attrName", entry.getKey());
3454            orderAtt.put("attrValue", entry.getValue());
3455            allOrderAttributes.add(orderAtt);
3456        }
3457        return allOrderAttributes;
3458    }
3459
3460    public List JavaDoc makeAllOrderItemAssociations() {
3461        List JavaDoc allOrderItemAssociations = new LinkedList JavaDoc();
3462
3463        if (getOrderType().equals("PURCHASE_ORDER")) {
3464            Iterator JavaDoc itemIter = cartLines.iterator();
3465
3466            while (itemIter.hasNext()) {
3467                ShoppingCartItem item = (ShoppingCartItem) itemIter.next();
3468                String JavaDoc requirementId = item.getRequirementId();
3469
3470                if (requirementId != null) {
3471                    try {
3472                        List JavaDoc commitments = getDelegator().findByAnd("OrderRequirementCommitment", UtilMisc.toMap("requirementId", requirementId));
3473                        // TODO: multiple commitments for the same requirement are still not supported
3474
GenericValue commitment = EntityUtil.getFirst(commitments);
3475                        if (commitment != null) {
3476                            GenericValue orderItemAssociation = getDelegator().makeValue("OrderItemAssociation", null);
3477                            orderItemAssociation.set("salesOrderId", commitment.getString("orderId"));
3478                            orderItemAssociation.set("soItemSeqId", commitment.getString("orderItemSeqId"));
3479                            orderItemAssociation.set("poItemSeqId", item.getOrderItemSeqId());
3480                            allOrderItemAssociations.add(orderItemAssociation);
3481                        }
3482                    } catch (GenericEntityException e) {
3483                        Debug.logError(e, "Unable to load OrderRequirementCommitment records for requirement ID : " + requirementId, module);
3484                    }
3485                }
3486            }
3487        }
3488        return allOrderItemAssociations;
3489    }
3490
3491    /** Returns a Map of cart values to pass to the storeOrder service */
3492    public Map JavaDoc makeCartMap(LocalDispatcher dispatcher, boolean explodeItems) {
3493        Map JavaDoc result = new HashMap JavaDoc();
3494
3495        result.put("orderTypeId", this.getOrderType());
3496        result.put("externalId", this.getExternalId());
3497        result.put("internalCode", this.getInternalCode());
3498        result.put("salesChannelEnumId", this.getChannelType());
3499        result.put("orderItems", this.makeOrderItems(explodeItems, dispatcher));
3500        result.put("workEfforts", this.makeWorkEfforts());
3501        result.put("orderAdjustments", this.makeAllAdjustments());
3502        result.put("orderTerms", this.getOrderTerms());
3503        result.put("orderItemPriceInfos", this.makeAllOrderItemPriceInfos());
3504        result.put("orderProductPromoUses", this.makeProductPromoUses());
3505
3506        result.put("orderAttributes", this.makeAllOrderAttributes());
3507        result.put("orderItemAttributes", this.makeAllOrderItemAttributes());
3508        result.put("orderContactMechs", this.makeAllOrderContactMechs());
3509        result.put("orderItemContactMechs", this.makeAllOrderItemContactMechs());
3510        result.put("orderPaymentInfo", this.makeAllOrderPaymentInfos());
3511        result.put("orderItemShipGroupInfo", this.makeAllShipGroupInfos());
3512        result.put("orderItemSurveyResponses", this.makeAllOrderItemSurveyResponses());
3513        result.put("orderAdditionalPartyRoleMap", this.getAdditionalPartyRoleMap());
3514        result.put("orderItemAssociations", this.makeAllOrderItemAssociations());
3515
3516        result.put("firstAttemptOrderId", this.getFirstAttemptOrderId());
3517        result.put("currencyUom", this.getCurrency());
3518        result.put("billingAccountId", this.getBillingAccountId());
3519
3520        result.put("billToCustomerPartyId", this.getBillToCustomerPartyId());
3521        result.put("billFromVendorPartyId", this.getBillFromVendorPartyId());
3522
3523        if (this.isSalesOrder()) {
3524            result.put("placingCustomerPartyId", this.getPlacingCustomerPartyId());
3525            result.put("shipToCustomerPartyId", this.getShipToCustomerPartyId());
3526            result.put("endUserCustomerPartyId", this.getEndUserCustomerPartyId());
3527        }
3528
3529        if (this.isPurchaseOrder()) {
3530            result.put("shipFromVendorPartyId", this.getShipFromVendorPartyId());
3531            result.put("supplierAgentPartyId", this.getSupplierAgentPartyId());
3532        }
3533
3534        return result;
3535    }
3536
3537    public List JavaDoc getLineListOrderedByBasePrice(boolean ascending) {
3538        List JavaDoc result = new ArrayList JavaDoc(this.cartLines);
3539        Collections.sort(result, new BasePriceOrderComparator(ascending));
3540        return result;
3541    }
3542
3543    static class BasePriceOrderComparator implements Comparator JavaDoc, Serializable JavaDoc {
3544
3545        private boolean ascending = false;
3546
3547        BasePriceOrderComparator(boolean ascending) {
3548            this.ascending = ascending;
3549        }
3550
3551        public int compare(java.lang.Object JavaDoc obj, java.lang.Object JavaDoc obj1) {
3552            ShoppingCartItem cartItem = (ShoppingCartItem) obj;
3553            ShoppingCartItem cartItem1 = (ShoppingCartItem) obj1;
3554
3555            int compareValue = new Double JavaDoc(cartItem.getBasePrice()).compareTo(new Double JavaDoc(cartItem1.getBasePrice()));
3556            if (this.ascending) {
3557                return compareValue;
3558            } else {
3559                return -compareValue;
3560            }
3561        }
3562
3563        public boolean equals(java.lang.Object JavaDoc obj) {
3564            if (obj instanceof BasePriceOrderComparator) {
3565                return this.ascending == ((BasePriceOrderComparator) obj).ascending;
3566            } else {
3567                return false;
3568            }
3569        }
3570    }
3571
3572    protected void finalize() throws Throwable JavaDoc {
3573        // DEJ20050518 we should not call clear because it kills the auto-save shopping list and is unnecessary given that when this object is GC'ed it will cause everything it points to that isn't referenced anywhere else to be GC'ed too: this.clear();
3574
super.finalize();
3575    }
3576}
3577
Popular Tags