Source Code Cross Referenced for ShoppingCart.java in  » ERP-CRM-Financial » ofbiz » org » ofbiz » order » shoppingcart » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » ERP CRM Financial » ofbiz » org.ofbiz.order.shoppingcart 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*******************************************************************************
0002:         * Licensed to the Apache Software Foundation (ASF) under one
0003:         * or more contributor license agreements.  See the NOTICE file
0004:         * distributed with this work for additional information
0005:         * regarding copyright ownership.  The ASF licenses this file
0006:         * to you under the Apache License, Version 2.0 (the
0007:         * "License"); you may not use this file except in compliance
0008:         * with the License.  You may obtain a copy of the License at
0009:         * 
0010:         * http://www.apache.org/licenses/LICENSE-2.0
0011:         * 
0012:         * Unless required by applicable law or agreed to in writing,
0013:         * software distributed under the License is distributed on an
0014:         * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
0015:         * KIND, either express or implied.  See the License for the
0016:         * specific language governing permissions and limitations
0017:         * under the License.
0018:         *******************************************************************************/package org.ofbiz.order.shoppingcart;
0019:
0020:        import java.io.Serializable;
0021:        import java.math.BigDecimal;
0022:        import java.sql.Timestamp;
0023:        import java.util.*;
0024:
0025:        import javolution.util.FastList;
0026:        import javolution.util.FastMap;
0027:
0028:        import org.apache.commons.collections.map.LinkedMap;
0029:        import org.ofbiz.base.util.Debug;
0030:        import org.ofbiz.base.util.GeneralException;
0031:        import org.ofbiz.base.util.UtilDateTime;
0032:        import org.ofbiz.base.util.UtilFormatOut;
0033:        import org.ofbiz.base.util.UtilMisc;
0034:        import org.ofbiz.base.util.UtilNumber;
0035:        import org.ofbiz.base.util.UtilProperties;
0036:        import org.ofbiz.base.util.UtilValidate;
0037:        import org.ofbiz.entity.GenericDelegator;
0038:        import org.ofbiz.entity.GenericEntityException;
0039:        import org.ofbiz.entity.GenericPK;
0040:        import org.ofbiz.entity.GenericValue;
0041:        import org.ofbiz.entity.util.EntityUtil;
0042:        import org.ofbiz.party.contact.ContactHelper;
0043:        import org.ofbiz.party.contact.ContactMechWorker;
0044:        import org.ofbiz.order.order.OrderReadHelper;
0045:        import org.ofbiz.order.finaccount.FinAccountHelper;
0046:        import org.ofbiz.order.shoppingcart.product.ProductPromoWorker;
0047:        import org.ofbiz.order.shoppingcart.shipping.ShippingEstimateWrapper;
0048:        import org.ofbiz.order.shoppinglist.ShoppingListEvents;
0049:        import org.ofbiz.product.category.CategoryWorker;
0050:        import org.ofbiz.product.config.ProductConfigWrapper;
0051:        import org.ofbiz.product.store.ProductStoreWorker;
0052:        import org.ofbiz.service.LocalDispatcher;
0053:
0054:        /**
0055:         * Shopping Cart Object
0056:         */
0057:        public class ShoppingCart implements  Serializable {
0058:
0059:            public static final String module = ShoppingCart.class.getName();
0060:            public static final String resource_error = "OrderErrorUiLabels";
0061:
0062:            // scales and rounding modes for BigDecimal math
0063:            public static final int scale = UtilNumber
0064:                    .getBigDecimalScale("order.decimals");
0065:            public static final int rounding = UtilNumber
0066:                    .getBigDecimalRoundingMode("order.rounding");
0067:            public static final int taxCalcScale = UtilNumber
0068:                    .getBigDecimalScale("salestax.calc.decimals");
0069:            public static final int taxFinalScale = UtilNumber
0070:                    .getBigDecimalScale("salestax.final.decimals");
0071:            public static final int taxRounding = UtilNumber
0072:                    .getBigDecimalRoundingMode("salestax.rounding");
0073:            public static final BigDecimal ZERO = (new BigDecimal("0"))
0074:                    .setScale(scale, rounding);
0075:            public static final BigDecimal percentage = (new BigDecimal("0.01"))
0076:                    .setScale(scale, rounding);
0077:
0078:            private String orderType = "SALES_ORDER"; // default orderType
0079:            private String channel = "UNKNWN_SALES_CHANNEL"; // default channel enum
0080:
0081:            private String poNumber = null;
0082:            private String orderId = null;
0083:            private String orderName = null;
0084:            private String firstAttemptOrderId = null;
0085:            private String externalId = null;
0086:            private String internalCode = null;
0087:            private String billingAccountId = null;
0088:            private double billingAccountAmt = 0.00;
0089:            private String agreementId = null;
0090:            private String quoteId = null;
0091:            private long nextItemSeq = 1;
0092:
0093:            private String defaultItemDeliveryDate = null;
0094:            private String defaultItemComment = null;
0095:
0096:            private String orderAdditionalEmails = null;
0097:            private boolean viewCartOnAdd = false;
0098:            private boolean readOnlyCart = false;
0099:
0100:            private Timestamp lastListRestore = null;
0101:            private String autoSaveListId = null;
0102:
0103:            /** Holds value of order adjustments. */
0104:            private List adjustments = new LinkedList();
0105:            // OrderTerms
0106:            private boolean orderTermSet = false;
0107:            private List orderTerms = new LinkedList();
0108:
0109:            private List cartLines = FastList.newInstance();
0110:            private Map itemGroupByNumberMap = FastMap.newInstance();
0111:            protected long nextGroupNumber = 1;
0112:            private List paymentInfo = FastList.newInstance();
0113:            private List shipInfo = FastList.newInstance();
0114:            private Map contactMechIdsMap = new HashMap();
0115:            private Map orderAttributes = new HashMap();
0116:            private Map attributes = new HashMap(); // user defined attributes
0117:            // Lists of internal/public notes: when the order is stored they are transformed into OrderHeaderNotes
0118:            private List internalOrderNotes = FastList.newInstance(); // internal notes
0119:            private List orderNotes = FastList.newInstance(); // public notes (printed on documents etc.)
0120:
0121:            /** contains a list of partyId for each roleTypeId (key) */
0122:            private Map additionalPartyRole = new HashMap();
0123:
0124:            /** these are defaults for all ship groups */
0125:            private Timestamp defaultShipAfterDate = null;
0126:            private Timestamp defaultShipBeforeDate = null;
0127:
0128:            /** Contains a List for each productPromoId (key) containing a productPromoCodeId (or empty string for no code) for each use of the productPromoId */
0129:            private List productPromoUseInfoList = new LinkedList();
0130:            /** Contains the promo codes entered */
0131:            private Set productPromoCodes = new HashSet();
0132:            private List freeShippingProductPromoActions = new ArrayList();
0133:            /** 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 */
0134:            private Map desiredAlternateGiftByAction = new HashMap();
0135:            private Timestamp cartCreatedTs = UtilDateTime.nowTimestamp();
0136:
0137:            private transient GenericDelegator delegator = null;
0138:            private String delegatorName = null;
0139:
0140:            protected String productStoreId = null;
0141:            protected String transactionId = null;
0142:            protected String facilityId = null;
0143:            protected String webSiteId = null;
0144:            protected String terminalId = null;
0145:            protected String autoOrderShoppingListId = null;
0146:
0147:            /** General partyId for the Order, all other IDs default to this one if not specified explicitly */
0148:            protected String orderPartyId = null;
0149:
0150:            // sales order parties
0151:            protected String placingCustomerPartyId = null;
0152:            protected String billToCustomerPartyId = null;
0153:            protected String shipToCustomerPartyId = null;
0154:            protected String endUserCustomerPartyId = null;
0155:
0156:            // purchase order parties
0157:            protected String billFromVendorPartyId = null;
0158:            protected String shipFromVendorPartyId = null;
0159:            protected String supplierAgentPartyId = null;
0160:
0161:            protected GenericValue userLogin = null;
0162:            protected GenericValue autoUserLogin = null;
0163:
0164:            protected Locale locale; // holds the locale from the user session
0165:            protected String currencyUom = null;
0166:            protected boolean holdOrder = false;
0167:            protected Timestamp orderDate = null;
0168:
0169:            /** don't allow empty constructor */
0170:            protected ShoppingCart() {
0171:            }
0172:
0173:            /** Creates a new cloned ShoppingCart Object. */
0174:            public ShoppingCart(ShoppingCart cart) {
0175:                this .delegator = cart.getDelegator();
0176:                this .delegatorName = delegator.getDelegatorName();
0177:                this .productStoreId = cart.getProductStoreId();
0178:                this .poNumber = cart.getPoNumber();
0179:                this .orderId = cart.getOrderId();
0180:                this .orderName = "Copy of " + cart.getOrderName();
0181:                this .firstAttemptOrderId = cart.getFirstAttemptOrderId();
0182:                this .billingAccountId = cart.getBillingAccountId();
0183:                this .agreementId = cart.getAgreementId();
0184:                this .quoteId = cart.getQuoteId();
0185:                this .orderAdditionalEmails = cart.getOrderAdditionalEmails();
0186:                this .adjustments = new LinkedList(cart.getAdjustments());
0187:                this .contactMechIdsMap = new HashMap(cart
0188:                        .getOrderContactMechIds());
0189:                this .freeShippingProductPromoActions = new ArrayList(cart
0190:                        .getFreeShippingProductPromoActions());
0191:                this .desiredAlternateGiftByAction = cart
0192:                        .getAllDesiredAlternateGiftByActionCopy();
0193:                this .productPromoUseInfoList = new LinkedList(
0194:                        cart.productPromoUseInfoList);
0195:                this .productPromoCodes = new HashSet(cart.productPromoCodes);
0196:                this .locale = cart.getLocale();
0197:                this .currencyUom = cart.getCurrency();
0198:                this .externalId = cart.getExternalId();
0199:                this .internalCode = cart.getInternalCode();
0200:                this .viewCartOnAdd = cart.viewCartOnAdd();
0201:                this .defaultShipAfterDate = cart.getDefaultShipAfterDate();
0202:                this .defaultShipBeforeDate = cart.getDefaultShipBeforeDate();
0203:
0204:                this .terminalId = cart.getTerminalId();
0205:                this .transactionId = cart.getTransactionId();
0206:                this .autoOrderShoppingListId = cart
0207:                        .getAutoOrderShoppingListId();
0208:
0209:                // clone the additionalPartyRoleMap
0210:                this .additionalPartyRole = new HashMap();
0211:                Iterator it = cart.additionalPartyRole.entrySet().iterator();
0212:                while (it.hasNext()) {
0213:                    Map.Entry me = (Map.Entry) it.next();
0214:                    this .additionalPartyRole.put(me.getKey(), new LinkedList(
0215:                            (Collection) me.getValue()));
0216:                }
0217:
0218:                // clone the groups
0219:                Iterator groupIt = cart.itemGroupByNumberMap.values()
0220:                        .iterator();
0221:                while (groupIt.hasNext()) {
0222:                    ShoppingCartItemGroup itemGroup = (ShoppingCartItemGroup) groupIt
0223:                            .next();
0224:                    // get the new parent group by number from the existing set; as before the parent must come before all children to work...
0225:                    ShoppingCartItemGroup parentGroup = null;
0226:                    if (itemGroup.getParentGroup() != null)
0227:                        parentGroup = this .getItemGroupByNumber(itemGroup
0228:                                .getParentGroup().getGroupNumber());
0229:                    ShoppingCartItemGroup newGroup = new ShoppingCartItemGroup(
0230:                            itemGroup, parentGroup);
0231:                    itemGroupByNumberMap.put(newGroup.getGroupNumber(),
0232:                            newGroup);
0233:                }
0234:
0235:                // clone the items
0236:                List items = cart.items();
0237:                Iterator itIt = items.iterator();
0238:                while (itIt.hasNext()) {
0239:                    cartLines.add(new ShoppingCartItem((ShoppingCartItem) itIt
0240:                            .next()));
0241:                }
0242:            }
0243:
0244:            /** Creates new empty ShoppingCart object. */
0245:            public ShoppingCart(GenericDelegator delegator,
0246:                    String productStoreId, String webSiteId, Locale locale,
0247:                    String currencyUom, String billToCustomerPartyId,
0248:                    String billFromVendorPartyId) {
0249:                this .delegator = delegator;
0250:                this .delegatorName = delegator.getDelegatorName();
0251:                this .productStoreId = productStoreId;
0252:                this .webSiteId = webSiteId;
0253:                this .currencyUom = currencyUom;
0254:                this .locale = locale;
0255:                if (this .locale == null) {
0256:                    this .locale = Locale.getDefault();
0257:                }
0258:
0259:                if (productStoreId == null) {
0260:                    throw new IllegalArgumentException(
0261:                            "productStoreId cannot be null");
0262:                }
0263:
0264:                // set the default view cart on add for this store
0265:                GenericValue productStore = ProductStoreWorker.getProductStore(
0266:                        productStoreId, delegator);
0267:                if (productStore == null) {
0268:                    throw new IllegalArgumentException(
0269:                            "Unable to locate ProductStore by ID ["
0270:                                    + productStoreId + "]");
0271:                }
0272:
0273:                String storeViewCartOnAdd = productStore
0274:                        .getString("viewCartOnAdd");
0275:                if (storeViewCartOnAdd != null
0276:                        && "Y".equalsIgnoreCase(storeViewCartOnAdd)) {
0277:                    this .viewCartOnAdd = true;
0278:                }
0279:
0280:                if (billFromVendorPartyId == null) {
0281:                    // since default cart is of type SALES_ORDER, set to store's payToPartyId
0282:                    this .billFromVendorPartyId = productStore
0283:                            .getString("payToPartyId");
0284:                } else {
0285:                    this .billFromVendorPartyId = billFromVendorPartyId;
0286:                }
0287:                this .billToCustomerPartyId = billToCustomerPartyId;
0288:            }
0289:
0290:            /** Creates new empty ShoppingCart object. */
0291:            public ShoppingCart(GenericDelegator delegator,
0292:                    String productStoreId, String webSiteId, Locale locale,
0293:                    String currencyUom) {
0294:                this (delegator, productStoreId, webSiteId, locale, currencyUom,
0295:                        null, null);
0296:            }
0297:
0298:            /** Creates a new empty ShoppingCart object. */
0299:            public ShoppingCart(GenericDelegator delegator,
0300:                    String productStoreId, Locale locale, String currencyUom) {
0301:                this (delegator, productStoreId, null, locale, currencyUom);
0302:            }
0303:
0304:            public GenericDelegator getDelegator() {
0305:                if (delegator == null) {
0306:                    delegator = GenericDelegator
0307:                            .getGenericDelegator(delegatorName);
0308:                }
0309:                return delegator;
0310:            }
0311:
0312:            public String getProductStoreId() {
0313:                return this .productStoreId;
0314:            }
0315:
0316:            /**
0317:             * This is somewhat of a dangerous method, changing the productStoreId changes a lot of stuff including:
0318:             * - some items in the cart may not be valid in any catalog in the new store
0319:             * - promotions need to be recalculated for the products that remain
0320:             * - what else? lots of settings on the ProductStore...
0321:             *
0322:             * So for now this can only be called if the cart is empty... otherwise it wil throw an exception
0323:             *
0324:             */
0325:            public void setProductStoreId(String productStoreId) {
0326:                if ((productStoreId == null && this .productStoreId == null)
0327:                        || (productStoreId != null && productStoreId
0328:                                .equals(this .productStoreId))) {
0329:                    return;
0330:                }
0331:
0332:                if (this .size() == 0) {
0333:                    this .productStoreId = productStoreId;
0334:                } else {
0335:                    throw new IllegalArgumentException(
0336:                            "Cannot set productStoreId when the cart is not empty; cart size is "
0337:                                    + this .size());
0338:                }
0339:            }
0340:
0341:            public String getTransactionId() {
0342:                return this .transactionId;
0343:            }
0344:
0345:            public void setTransactionId(String transactionId) {
0346:                this .transactionId = transactionId;
0347:            }
0348:
0349:            public String getTerminalId() {
0350:                return this .terminalId;
0351:            }
0352:
0353:            public void setTerminalId(String terminalId) {
0354:                this .terminalId = terminalId;
0355:            }
0356:
0357:            public String getAutoOrderShoppingListId() {
0358:                return this .autoOrderShoppingListId;
0359:            }
0360:
0361:            public void setAutoOrderShoppingListId(
0362:                    String autoOrderShoppingListId) {
0363:                this .autoOrderShoppingListId = autoOrderShoppingListId;
0364:            }
0365:
0366:            public String getFacilityId() {
0367:                return this .facilityId;
0368:            }
0369:
0370:            public void setFacilityId(String facilityId) {
0371:                this .facilityId = facilityId;
0372:            }
0373:
0374:            public Locale getLocale() {
0375:                return locale;
0376:            }
0377:
0378:            public void setLocale(Locale locale) {
0379:                this .locale = locale;
0380:            }
0381:
0382:            public void setOrderName(String orderName) {
0383:                this .orderName = orderName;
0384:            }
0385:
0386:            public String getOrderName() {
0387:                return orderName;
0388:            }
0389:
0390:            public void setAttribute(String name, Object value) {
0391:                this .attributes.put(name, value);
0392:            }
0393:
0394:            public Object getAttribute(String name) {
0395:                return this .attributes.get(name);
0396:            }
0397:
0398:            public void removeOrderAttribute(String name) {
0399:                this .orderAttributes.remove(name);
0400:            }
0401:
0402:            public void setOrderAttribute(String name, String value) {
0403:                this .orderAttributes.put(name, value);
0404:            }
0405:
0406:            public String getOrderAttribute(String name) {
0407:                return (String) this .orderAttributes.get(name);
0408:            }
0409:
0410:            public void setHoldOrder(boolean b) {
0411:                this .holdOrder = b;
0412:            }
0413:
0414:            public boolean getHoldOrder() {
0415:                return this .holdOrder;
0416:            }
0417:
0418:            public void setOrderDate(Timestamp t) {
0419:                this .orderDate = t;
0420:            }
0421:
0422:            public Timestamp getOrderDate() {
0423:                return this .orderDate;
0424:            }
0425:
0426:            /** Sets the currency for the cart. */
0427:            public void setCurrency(LocalDispatcher dispatcher,
0428:                    String currencyUom) throws CartItemModifyException {
0429:                if (isReadOnlyCart()) {
0430:                    throw new CartItemModifyException(
0431:                            "Cart items cannot be changed");
0432:                }
0433:                String previousCurrency = this .currencyUom;
0434:                this .currencyUom = currencyUom;
0435:                if (!previousCurrency.equals(this .currencyUom)) {
0436:                    Iterator itemIterator = this .iterator();
0437:                    while (itemIterator.hasNext()) {
0438:                        ShoppingCartItem item = (ShoppingCartItem) itemIterator
0439:                                .next();
0440:                        item.updatePrice(dispatcher, this );
0441:                    }
0442:                }
0443:            }
0444:
0445:            /** Get the current currency setting. */
0446:            public String getCurrency() {
0447:                if (this .currencyUom != null) {
0448:                    return this .currencyUom;
0449:                } else {
0450:                    // uh oh, not good, should always be passed in on init, we can't really do anything without it, so throw an exception
0451:                    throw new IllegalStateException(
0452:                            "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.");
0453:                }
0454:            }
0455:
0456:            public Timestamp getCartCreatedTime() {
0457:                return this .cartCreatedTs;
0458:            }
0459:
0460:            private GenericValue getSupplierProduct(String productId,
0461:                    double quantity, LocalDispatcher dispatcher) {
0462:                GenericValue supplierProduct = null;
0463:                Map params = UtilMisc.toMap("productId", productId, "partyId",
0464:                        this .getPartyId(), "currencyUomId", this .getCurrency(),
0465:                        "quantity", new Double(quantity));
0466:                try {
0467:                    Map result = dispatcher.runSync("getSuppliersForProduct",
0468:                            params);
0469:                    List productSuppliers = (List) result
0470:                            .get("supplierProducts");
0471:                    if ((productSuppliers != null)
0472:                            && (productSuppliers.size() > 0)) {
0473:                        supplierProduct = (GenericValue) productSuppliers
0474:                                .get(0);
0475:                    }
0476:                    //} catch (GenericServiceException e) {
0477:                } catch (Exception e) {
0478:                    Debug.logWarning(UtilProperties.getMessage(resource_error,
0479:                            "OrderRunServiceGetSuppliersForProductError",
0480:                            locale)
0481:                            + e.getMessage(), module);
0482:                }
0483:                return supplierProduct;
0484:            }
0485:
0486:            // =======================================================================
0487:            // Methods for cart items
0488:            // =======================================================================
0489:
0490:            /** Add an item to the shopping cart, or if already there, increase the quantity.
0491:             * @return the new/increased item index
0492:             * @throws CartItemModifyException
0493:             */
0494:            public int addOrIncreaseItem(String productId,
0495:                    Double selectedAmountDbl, double quantity,
0496:                    Timestamp reservStart, Double reservLengthDbl,
0497:                    Double reservPersonsDbl, Timestamp shipBeforeDate,
0498:                    Timestamp shipAfterDate, Map features, Map attributes,
0499:                    String prodCatalogId, ProductConfigWrapper configWrapper,
0500:                    String itemType, String itemGroupNumber,
0501:                    String parentProductId, LocalDispatcher dispatcher)
0502:                    throws CartItemModifyException, ItemNotFoundException {
0503:                if (isReadOnlyCart()) {
0504:                    throw new CartItemModifyException(
0505:                            "Cart items cannot be changed");
0506:                }
0507:
0508:                double selectedAmount = selectedAmountDbl == null ? 0.0
0509:                        : selectedAmountDbl.doubleValue();
0510:                double reservLength = reservLengthDbl == null ? 0.0
0511:                        : reservLengthDbl.doubleValue();
0512:                double reservPersons = reservPersonsDbl == null ? 0.0
0513:                        : reservPersonsDbl.doubleValue();
0514:
0515:                ShoppingCart.ShoppingCartItemGroup itemGroup = this 
0516:                        .getItemGroupByNumber(itemGroupNumber);
0517:                GenericValue supplierProduct = null;
0518:                // Check for existing cart item.
0519:                for (int i = 0; i < this .cartLines.size(); i++) {
0520:                    ShoppingCartItem sci = (ShoppingCartItem) cartLines.get(i);
0521:
0522:                    if (sci.equals(productId, reservStart, reservLength,
0523:                            reservPersons, features, attributes, prodCatalogId,
0524:                            configWrapper, itemType, itemGroup, selectedAmount)) {
0525:                        double newQuantity = sci.getQuantity() + quantity;
0526:                        if (sci.getItemType().equals("RENTAL_ORDER_ITEM")) {
0527:                            // check to see if the related fixed asset is available for the new quantity
0528:                            String isAvailable = ShoppingCartItem
0529:                                    .checkAvailability(productId, newQuantity,
0530:                                            reservStart, reservLength, this );
0531:                            if (isAvailable.compareTo("OK") != 0) {
0532:                                Map messageMap = UtilMisc.toMap("productId",
0533:                                        productId, "availableMessage",
0534:                                        isAvailable);
0535:                                String excMsg = UtilProperties.getMessage(
0536:                                        ShoppingCartItem.resource,
0537:                                        "item.product_not_available",
0538:                                        messageMap, this .getLocale());
0539:                                Debug.logInfo(excMsg, module);
0540:                                throw new CartItemModifyException(isAvailable);
0541:                            }
0542:                        }
0543:
0544:                        if (Debug.verboseOn())
0545:                            Debug.logVerbose("Found a match for id "
0546:                                    + productId + " on line " + i
0547:                                    + ", updating quantity to " + newQuantity,
0548:                                    module);
0549:                        sci.setQuantity(newQuantity, dispatcher, this );
0550:
0551:                        if (getOrderType().equals("PURCHASE_ORDER")) {
0552:                            supplierProduct = getSupplierProduct(productId,
0553:                                    newQuantity, dispatcher);
0554:                            if (supplierProduct != null
0555:                                    && supplierProduct.getDouble("lastPrice") != null) {
0556:                                sci.setBasePrice(supplierProduct.getDouble(
0557:                                        "lastPrice").doubleValue());
0558:                                sci.setName(ShoppingCartItem
0559:                                        .getPurchaseOrderItemDescription(sci
0560:                                                .getProduct(), supplierProduct,
0561:                                                this .getLocale()));
0562:                            } else {
0563:                                throw new CartItemModifyException(
0564:                                        "SupplierProduct not found");
0565:                            }
0566:                        }
0567:                        return i;
0568:                    }
0569:                }
0570:                // Add the new item to the shopping cart if it wasn't found.
0571:                if (getOrderType().equals("PURCHASE_ORDER")) {
0572:                    //GenericValue productSupplier = null;
0573:                    supplierProduct = getSupplierProduct(productId, quantity,
0574:                            dispatcher);
0575:                    if (supplierProduct != null
0576:                            || "_NA_".equals(this .getPartyId())) {
0577:                        return this .addItem(0, ShoppingCartItem
0578:                                .makePurchaseOrderItem(new Integer(0),
0579:                                        productId, selectedAmountDbl, quantity,
0580:                                        features, attributes, prodCatalogId,
0581:                                        configWrapper, itemType, itemGroup,
0582:                                        dispatcher, this , supplierProduct,
0583:                                        shipBeforeDate, shipAfterDate));
0584:                    } else {
0585:                        throw new CartItemModifyException(
0586:                                "SupplierProduct not found");
0587:                    }
0588:                } else {
0589:                    return this .addItem(0, ShoppingCartItem.makeItem(
0590:                            new Integer(0), productId, selectedAmountDbl,
0591:                            quantity, null, reservStart, reservLengthDbl,
0592:                            reservPersonsDbl, shipBeforeDate, shipAfterDate,
0593:                            features, attributes, prodCatalogId, configWrapper,
0594:                            itemType, itemGroup, dispatcher, this ,
0595:                            Boolean.TRUE, Boolean.TRUE, parentProductId,
0596:                            Boolean.FALSE, Boolean.FALSE));
0597:                }
0598:            }
0599:
0600:            /** Add a non-product item to the shopping cart.
0601:             * @return the new item index
0602:             * @throws CartItemModifyException
0603:             */
0604:            public int addNonProductItem(String itemType, String description,
0605:                    String categoryId, Double price, double quantity,
0606:                    Map attributes, String prodCatalogId,
0607:                    String itemGroupNumber, LocalDispatcher dispatcher)
0608:                    throws CartItemModifyException {
0609:                ShoppingCart.ShoppingCartItemGroup itemGroup = this 
0610:                        .getItemGroupByNumber(itemGroupNumber);
0611:                return this .addItem(0, ShoppingCartItem.makeItem(
0612:                        new Integer(0), itemType, description, categoryId,
0613:                        price, null, quantity, attributes, prodCatalogId,
0614:                        itemGroup, dispatcher, this , Boolean.TRUE));
0615:            }
0616:
0617:            /** Add an item to the shopping cart. */
0618:            public int addItem(int index, ShoppingCartItem item)
0619:                    throws CartItemModifyException {
0620:                if (isReadOnlyCart()) {
0621:                    throw new CartItemModifyException(
0622:                            "Cart items cannot be changed");
0623:                }
0624:                if (!cartLines.contains(item)) {
0625:                    cartLines.add(index, item);
0626:                    return index;
0627:                } else {
0628:                    return this .getItemIndex(item);
0629:                }
0630:            }
0631:
0632:            /** Add an item to the shopping cart. */
0633:            public int addItemToEnd(String productId, Double amount,
0634:                    double quantity, Double unitPrice, HashMap features,
0635:                    HashMap attributes, String prodCatalogId, String itemType,
0636:                    LocalDispatcher dispatcher, Boolean triggerExternalOps,
0637:                    Boolean triggerPriceRules) throws CartItemModifyException,
0638:                    ItemNotFoundException {
0639:                return addItemToEnd(productId, amount, quantity, unitPrice,
0640:                        features, attributes, prodCatalogId, itemType,
0641:                        dispatcher, triggerExternalOps, triggerPriceRules,
0642:                        Boolean.FALSE, Boolean.FALSE);
0643:            }
0644:
0645:            /** Add an item to the shopping cart. */
0646:            public int addItemToEnd(String productId, Double amount,
0647:                    double quantity, Double unitPrice, HashMap features,
0648:                    HashMap attributes, String prodCatalogId, String itemType,
0649:                    LocalDispatcher dispatcher, Boolean triggerExternalOps,
0650:                    Boolean triggerPriceRules, Boolean skipInventoryChecks,
0651:                    Boolean skipProductChecks) throws CartItemModifyException,
0652:                    ItemNotFoundException {
0653:                return addItemToEnd(ShoppingCartItem.makeItem(null, productId,
0654:                        amount, quantity, unitPrice, null, null, null, null,
0655:                        null, features, attributes, prodCatalogId, null,
0656:                        itemType, null, dispatcher, this , triggerExternalOps,
0657:                        triggerPriceRules, null, skipInventoryChecks,
0658:                        skipProductChecks));
0659:            }
0660:
0661:            /** Add an item to the shopping cart. */
0662:            public int addItemToEnd(ShoppingCartItem item)
0663:                    throws CartItemModifyException {
0664:                if (isReadOnlyCart()) {
0665:                    throw new CartItemModifyException(
0666:                            "Cart items cannot be changed");
0667:                }
0668:                if (!cartLines.contains(item)) {
0669:                    cartLines.add(item);
0670:                    return cartLines.size() - 1;
0671:                } else {
0672:                    return this .getItemIndex(item);
0673:                }
0674:            }
0675:
0676:            /** Get a ShoppingCartItem from the cart object. */
0677:            public ShoppingCartItem findCartItem(String productId,
0678:                    Map features, Map attributes, String prodCatalogId,
0679:                    double selectedAmount) {
0680:                // Check for existing cart item.
0681:                for (int i = 0; i < this .cartLines.size(); i++) {
0682:                    ShoppingCartItem cartItem = (ShoppingCartItem) cartLines
0683:                            .get(i);
0684:
0685:                    if (cartItem.equals(productId, features, attributes,
0686:                            prodCatalogId, selectedAmount)) {
0687:                        return cartItem;
0688:                    }
0689:                }
0690:                return null;
0691:            }
0692:
0693:            /** Get all ShoppingCartItems from the cart object with the given productId. */
0694:            public List findAllCartItems(String productId) {
0695:                return this .findAllCartItems(productId, null);
0696:            }
0697:
0698:            /** Get all ShoppingCartItems from the cart object with the given productId and optional groupNumber to limit it to a specific item group */
0699:            public List findAllCartItems(String productId, String groupNumber) {
0700:                if (productId == null)
0701:                    return this .items();
0702:
0703:                List itemsToReturn = FastList.newInstance();
0704:                // Check for existing cart item.
0705:                Iterator cartItemIter = this .cartLines.iterator();
0706:                while (cartItemIter.hasNext()) {
0707:                    ShoppingCartItem cartItem = (ShoppingCartItem) cartItemIter
0708:                            .next();
0709:                    if (UtilValidate.isNotEmpty(groupNumber)
0710:                            && !cartItem.isInItemGroup(groupNumber)) {
0711:                        continue;
0712:                    }
0713:                    if (productId.equals(cartItem.getProductId())) {
0714:                        itemsToReturn.add(cartItem);
0715:                    }
0716:                }
0717:                return itemsToReturn;
0718:            }
0719:
0720:            /** Get all ShoppingCartItems from the cart object with the given productCategoryId and optional groupNumber to limit it to a specific item group */
0721:            public List findAllCartItemsInCategory(String productCategoryId,
0722:                    String groupNumber) {
0723:                if (productCategoryId == null)
0724:                    return this .items();
0725:
0726:                GenericDelegator delegator = this .getDelegator();
0727:                List itemsToReturn = FastList.newInstance();
0728:                try {
0729:                    // Check for existing cart item
0730:                    Iterator cartItemIter = this .cartLines.iterator();
0731:                    while (cartItemIter.hasNext()) {
0732:                        ShoppingCartItem cartItem = (ShoppingCartItem) cartItemIter
0733:                                .next();
0734:                        //Debug.logInfo("Checking cartItem with product [" + cartItem.getProductId() + "] becuase that is in group [" + (cartItem.getItemGroup()==null ? "no group" : cartItem.getItemGroup().getGroupNumber()) + "]", module);
0735:
0736:                        if (UtilValidate.isNotEmpty(groupNumber)
0737:                                && !cartItem.isInItemGroup(groupNumber)) {
0738:                            //Debug.logInfo("Not using cartItem with product [" + cartItem.getProductId() + "] becuase not in group [" + groupNumber + "]", module);
0739:                            continue;
0740:                        }
0741:                        if (CategoryWorker.isProductInCategory(delegator,
0742:                                cartItem.getProductId(), productCategoryId)) {
0743:                            itemsToReturn.add(cartItem);
0744:                        } else {
0745:                            //Debug.logInfo("Not using cartItem with product [" + cartItem.getProductId() + "] becuase not in category [" + productCategoryId + "]", module);
0746:                        }
0747:                    }
0748:                } catch (GenericEntityException e) {
0749:                    Debug.logError(e,
0750:                            "Error getting cart items that are in a category: "
0751:                                    + e.toString(), module);
0752:                }
0753:                //Debug.logInfo("Got [" + itemsToReturn.size() + "] cart items in category [" + productCategoryId + "] and item group [" + groupNumber + "]", module);
0754:                return itemsToReturn;
0755:            }
0756:
0757:            /** Remove quantity 0 ShoppingCartItems from the cart object. */
0758:            public void removeEmptyCartItems() {
0759:                // Check for existing cart item.
0760:                for (int i = 0; i < this .cartLines.size();) {
0761:                    ShoppingCartItem cartItem = (ShoppingCartItem) cartLines
0762:                            .get(i);
0763:
0764:                    if (cartItem.getQuantity() == 0.0) {
0765:                        this .clearItemShipInfo(cartItem);
0766:                        cartLines.remove(i);
0767:                    } else {
0768:                        i++;
0769:                    }
0770:                }
0771:            }
0772:
0773:            // =============== some misc utility methods, mostly for dealing with lists of items =================
0774:            public void removeExtraItems(List multipleItems,
0775:                    LocalDispatcher dispatcher, int maxItems)
0776:                    throws CartItemModifyException {
0777:                // if 1 or 0 items, do nothing
0778:                if (multipleItems.size() <= maxItems)
0779:                    return;
0780:
0781:                // remove all except first <maxItems> in list from the cart, first because new cart items are added to the beginning...
0782:                List localList = FastList.newInstance();
0783:                localList.addAll(multipleItems);
0784:                // the ones to keep...
0785:                for (int i = 0; i < maxItems; i++)
0786:                    localList.remove(0);
0787:                Iterator localIter = localList.iterator();
0788:                while (localIter.hasNext()) {
0789:                    ShoppingCartItem item = (ShoppingCartItem) localIter.next();
0790:                    this .removeCartItem(item, dispatcher);
0791:                }
0792:            }
0793:
0794:            public static double getItemsTotalQuantity(List cartItems) {
0795:                double totalQuantity = 0;
0796:                Iterator localIter = cartItems.iterator();
0797:                while (localIter.hasNext()) {
0798:                    ShoppingCartItem item = (ShoppingCartItem) localIter.next();
0799:                    totalQuantity += item.getQuantity();
0800:                }
0801:                return totalQuantity;
0802:            }
0803:
0804:            public static List getItemsProducts(List cartItems) {
0805:                List productList = FastList.newInstance();
0806:                Iterator localIter = cartItems.iterator();
0807:                while (localIter.hasNext()) {
0808:                    ShoppingCartItem item = (ShoppingCartItem) localIter.next();
0809:                    GenericValue product = item.getProduct();
0810:                    if (product != null) {
0811:                        productList.add(product);
0812:                    }
0813:                }
0814:                return productList;
0815:            }
0816:
0817:            public void ensureItemsQuantity(List cartItems,
0818:                    LocalDispatcher dispatcher, double quantity)
0819:                    throws CartItemModifyException {
0820:                Iterator localIter = cartItems.iterator();
0821:                while (localIter.hasNext()) {
0822:                    ShoppingCartItem item = (ShoppingCartItem) localIter.next();
0823:                    if (item.getQuantity() != quantity) {
0824:                        item.setQuantity(quantity, dispatcher, this );
0825:                    }
0826:                }
0827:            }
0828:
0829:            public double ensureItemsTotalQuantity(List cartItems,
0830:                    LocalDispatcher dispatcher, double quantity)
0831:                    throws CartItemModifyException {
0832:                double quantityRemoved = 0;
0833:                // go through the items and reduce quantityToKeep by the item quantities until it is 0, then remove the remaining...
0834:                double quantityToKeep = quantity;
0835:                Iterator localIter = cartItems.iterator();
0836:                while (localIter.hasNext()) {
0837:                    ShoppingCartItem item = (ShoppingCartItem) localIter.next();
0838:
0839:                    if (quantityToKeep >= item.getQuantity()) {
0840:                        // quantityToKeep sufficient to keep it all... just reduce quantityToKeep and move on  
0841:                        quantityToKeep = quantityToKeep - item.getQuantity();
0842:                    } else {
0843:                        // there is more in this than we want to keep, so reduce the quantity, or remove altogether...
0844:                        if (quantityToKeep == 0) {
0845:                            // nothing left to keep, just remove it...
0846:                            quantityRemoved += item.getQuantity();
0847:                            this .removeCartItem(item, dispatcher);
0848:                        } else {
0849:                            // there is some to keep, so reduce quantity to quantityToKeep, at this point we know we'll take up all of the rest of the quantityToKeep
0850:                            quantityRemoved += (item.getQuantity() - quantityToKeep);
0851:                            item.setQuantity(quantityToKeep, dispatcher, this );
0852:                            quantityToKeep = 0;
0853:                        }
0854:                    }
0855:                }
0856:                return quantityRemoved;
0857:            }
0858:
0859:            // ============== WorkEffort related methods ===============
0860:            public boolean containAnyWorkEffortCartItems() {
0861:                // Check for existing cart item.
0862:                for (int i = 0; i < this .cartLines.size(); i++) {
0863:                    ShoppingCartItem cartItem = (ShoppingCartItem) cartLines
0864:                            .get(i);
0865:                    if (cartItem.getItemType().equals("RENTAL_ORDER_ITEM")) { // create workeffort items?
0866:                        return true;
0867:                    }
0868:                }
0869:                return false;
0870:            }
0871:
0872:            public boolean containAllWorkEffortCartItems() {
0873:                // Check for existing cart item.
0874:                for (int i = 0; i < this .cartLines.size(); i++) {
0875:                    ShoppingCartItem cartItem = (ShoppingCartItem) cartLines
0876:                            .get(i);
0877:                    if (!cartItem.getItemType().equals("RENTAL_ORDER_ITEM")) { // not a item to create workefforts?
0878:                        return false;
0879:                    }
0880:                }
0881:                return true;
0882:            }
0883:
0884:            /** 
0885:             * Check to see if the cart contains only Digital Goods, ie no Finished Goods and no Finished/Digital Goods, et cetera. 
0886:             * This is determined by making sure no Product has a type where ProductType.isPhysical!=N. 
0887:             */
0888:            public boolean containOnlyDigitalGoods() {
0889:                for (int i = 0; i < this .cartLines.size(); i++) {
0890:                    ShoppingCartItem cartItem = (ShoppingCartItem) cartLines
0891:                            .get(i);
0892:                    GenericValue product = cartItem.getProduct();
0893:                    try {
0894:                        GenericValue productType = product
0895:                                .getRelatedOneCache("ProductType");
0896:                        if (productType == null
0897:                                || !"N".equals(productType
0898:                                        .getString("isPhysical"))) {
0899:                            return false;
0900:                        }
0901:                    } catch (GenericEntityException e) {
0902:                        Debug.logError(e, "Error looking up ProductType: "
0903:                                + e.toString(), module);
0904:                        // consider this not a digital good if we don't have "proof"
0905:                        return false;
0906:                    }
0907:                }
0908:                return true;
0909:            }
0910:
0911:            /** Returns this item's index. */
0912:            public int getItemIndex(ShoppingCartItem item) {
0913:                return cartLines.indexOf(item);
0914:            }
0915:
0916:            /** Get a ShoppingCartItem from the cart object. */
0917:            public ShoppingCartItem findCartItem(int index) {
0918:                if (cartLines.size() <= index) {
0919:                    return null;
0920:                }
0921:                return (ShoppingCartItem) cartLines.get(index);
0922:            }
0923:
0924:            public ShoppingCartItem findCartItem(String orderItemSeqId) {
0925:                if (orderItemSeqId != null) {
0926:                    for (int i = 0; i < this .cartLines.size(); i++) {
0927:                        ShoppingCartItem cartItem = (ShoppingCartItem) cartLines
0928:                                .get(i);
0929:                        String itemSeqId = cartItem.getOrderItemSeqId();
0930:                        if (itemSeqId != null
0931:                                && orderItemSeqId.equals(itemSeqId)) {
0932:                            return cartItem;
0933:                        }
0934:                    }
0935:                }
0936:                return null;
0937:            }
0938:
0939:            public void removeCartItem(ShoppingCartItem item,
0940:                    LocalDispatcher dispatcher) throws CartItemModifyException {
0941:                if (item == null)
0942:                    return;
0943:                this .removeCartItem(this .getItemIndex(item), dispatcher);
0944:            }
0945:
0946:            /** Remove an item from the cart object. */
0947:            public void removeCartItem(int index, LocalDispatcher dispatcher)
0948:                    throws CartItemModifyException {
0949:                if (isReadOnlyCart()) {
0950:                    throw new CartItemModifyException(
0951:                            "Cart items cannot be changed");
0952:                }
0953:                if (index < 0)
0954:                    return;
0955:                if (cartLines.size() <= index)
0956:                    return;
0957:                ShoppingCartItem item = (ShoppingCartItem) cartLines
0958:                        .remove(index);
0959:
0960:                // set quantity to 0 to trigger necessary events
0961:                item.setQuantity(0.0, dispatcher, this );
0962:            }
0963:
0964:            /** Moves a line item to a differnt index. */
0965:            public void moveCartItem(int fromIndex, int toIndex) {
0966:                if (toIndex < fromIndex) {
0967:                    cartLines.add(toIndex, cartLines.remove(fromIndex));
0968:                } else if (toIndex > fromIndex) {
0969:                    cartLines.add(toIndex - 1, cartLines.remove(fromIndex));
0970:                }
0971:            }
0972:
0973:            /** Returns the number of items in the cart object. */
0974:            public int size() {
0975:                return cartLines.size();
0976:            }
0977:
0978:            /** Returns a Collection of items in the cart object. */
0979:            public List items() {
0980:                List result = FastList.newInstance();
0981:                result.addAll(cartLines);
0982:                return result;
0983:            }
0984:
0985:            /** Returns an iterator of cart items. */
0986:            public Iterator iterator() {
0987:                return cartLines.iterator();
0988:            }
0989:
0990:            public ShoppingCart.ShoppingCartItemGroup getItemGroupByNumber(
0991:                    String groupNumber) {
0992:                if (UtilValidate.isEmpty(groupNumber))
0993:                    return null;
0994:                return (ShoppingCart.ShoppingCartItemGroup) this .itemGroupByNumberMap
0995:                        .get(groupNumber);
0996:            }
0997:
0998:            /** Creates a new Item Group and returns the groupNumber that represents it */
0999:            public String addItemGroup(String groupName,
1000:                    String parentGroupNumber) {
1001:                ShoppingCart.ShoppingCartItemGroup parentGroup = this 
1002:                        .getItemGroupByNumber(parentGroupNumber);
1003:                ShoppingCart.ShoppingCartItemGroup newGroup = new ShoppingCart.ShoppingCartItemGroup(
1004:                        this .nextGroupNumber, groupName, parentGroup);
1005:                this .nextGroupNumber++;
1006:                this .itemGroupByNumberMap.put(newGroup.getGroupNumber(),
1007:                        newGroup);
1008:                return newGroup.getGroupNumber();
1009:            }
1010:
1011:            public List getCartItemsInNoGroup() {
1012:                List cartItemList = FastList.newInstance();
1013:                Iterator cartLineIter = this .cartLines.iterator();
1014:                while (cartLineIter.hasNext()) {
1015:                    ShoppingCartItem cartItem = (ShoppingCartItem) cartLineIter
1016:                            .next();
1017:                    if (cartItem.getItemGroup() == null) {
1018:                        cartItemList.add(cartItem);
1019:                    }
1020:                }
1021:                return cartItemList;
1022:            }
1023:
1024:            public List getCartItemsInGroup(String groupNumber) {
1025:                List cartItemList = FastList.newInstance();
1026:                ShoppingCart.ShoppingCartItemGroup itemGroup = this 
1027:                        .getItemGroupByNumber(groupNumber);
1028:                if (itemGroup != null) {
1029:                    Iterator cartLineIter = this .cartLines.iterator();
1030:                    while (cartLineIter.hasNext()) {
1031:                        ShoppingCartItem cartItem = (ShoppingCartItem) cartLineIter
1032:                                .next();
1033:                        if (itemGroup.equals(cartItem.getItemGroup())) {
1034:                            cartItemList.add(cartItem);
1035:                        }
1036:                    }
1037:                }
1038:                return cartItemList;
1039:            }
1040:
1041:            public void deleteItemGroup(String groupNumber) {
1042:                ShoppingCartItemGroup itemGroup = this 
1043:                        .getItemGroupByNumber(groupNumber);
1044:                if (itemGroup != null) {
1045:                    // go through all cart items and remove from group if they are in it
1046:                    List cartItemList = this .getCartItemsInGroup(groupNumber);
1047:                    Iterator cartItemIter = cartItemList.iterator();
1048:                    while (cartItemIter.hasNext()) {
1049:                        ShoppingCartItem cartItem = (ShoppingCartItem) cartItemIter
1050:                                .next();
1051:                        cartItem.setItemGroup(null);
1052:                    }
1053:
1054:                    // if this is a parent of any set them to this group's parent (or null)
1055:                    Iterator itemGroupIter = this .itemGroupByNumberMap.values()
1056:                            .iterator();
1057:                    while (itemGroupIter.hasNext()) {
1058:                        ShoppingCartItemGroup otherItemGroup = (ShoppingCartItemGroup) itemGroupIter
1059:                                .next();
1060:                        if (itemGroup.equals(otherItemGroup.getParentGroup())) {
1061:                            otherItemGroup.inheritParentsParent();
1062:                        }
1063:                    }
1064:
1065:                    // finally, remove the itemGroup...
1066:                    this .itemGroupByNumberMap.remove(groupNumber);
1067:                }
1068:            }
1069:
1070:            //=======================================================
1071:            // Other General Info Maintenance Methods
1072:            //=======================================================
1073:
1074:            /** Gets the userLogin associated with the cart; may be null */
1075:            public GenericValue getUserLogin() {
1076:                return this .userLogin;
1077:            }
1078:
1079:            public void setUserLogin(GenericValue userLogin,
1080:                    LocalDispatcher dispatcher) throws CartItemModifyException {
1081:                this .userLogin = userLogin;
1082:                this .handleNewUser(dispatcher);
1083:            }
1084:
1085:            protected void setUserLogin(GenericValue userLogin) {
1086:                if (this .userLogin == null) {
1087:                    this .userLogin = userLogin;
1088:                } else {
1089:                    throw new IllegalArgumentException(
1090:                            "Cannot change UserLogin object with this method");
1091:                }
1092:            }
1093:
1094:            public GenericValue getAutoUserLogin() {
1095:                return this .autoUserLogin;
1096:            }
1097:
1098:            public void setAutoUserLogin(GenericValue autoUserLogin,
1099:                    LocalDispatcher dispatcher) throws CartItemModifyException {
1100:                this .autoUserLogin = autoUserLogin;
1101:                if (getUserLogin() == null) {
1102:                    this .handleNewUser(dispatcher);
1103:                }
1104:            }
1105:
1106:            protected void setAutoUserLogin(GenericValue autoUserLogin) {
1107:                if (this .autoUserLogin == null) {
1108:                    this .autoUserLogin = autoUserLogin;
1109:                } else {
1110:                    throw new IllegalArgumentException(
1111:                            "Cannot change AutoUserLogin object with this method");
1112:                }
1113:            }
1114:
1115:            public void handleNewUser(LocalDispatcher dispatcher)
1116:                    throws CartItemModifyException {
1117:                String partyId = this .getPartyId();
1118:                if (UtilValidate.isNotEmpty(partyId)) {
1119:                    // recalculate all prices
1120:                    Iterator cartItemIter = this .iterator();
1121:                    while (cartItemIter.hasNext()) {
1122:                        ShoppingCartItem cartItem = (ShoppingCartItem) cartItemIter
1123:                                .next();
1124:                        cartItem.updatePrice(dispatcher, this );
1125:                    }
1126:
1127:                    // check all promo codes, remove on failed check
1128:                    Iterator promoCodeIter = this .productPromoCodes.iterator();
1129:                    while (promoCodeIter.hasNext()) {
1130:                        String promoCode = (String) promoCodeIter.next();
1131:                        String checkResult = ProductPromoWorker
1132:                                .checkCanUsePromoCode(promoCode, partyId, this 
1133:                                        .getDelegator());
1134:                        if (checkResult != null) {
1135:                            promoCodeIter.remove();
1136:                            Debug
1137:                                    .logWarning(
1138:                                            UtilProperties
1139:                                                    .getMessage(
1140:                                                            resource_error,
1141:                                                            "OrderOnUserChangePromoCodeWasRemovedBecause",
1142:                                                            UtilMisc
1143:                                                                    .toMap(
1144:                                                                            "checkResult",
1145:                                                                            checkResult),
1146:                                                            locale), module);
1147:                        }
1148:                    }
1149:
1150:                    // rerun promotions
1151:                    ProductPromoWorker.doPromotions(this , dispatcher);
1152:                }
1153:            }
1154:
1155:            public String getExternalId() {
1156:                return this .externalId;
1157:            }
1158:
1159:            public void setExternalId(String externalId) {
1160:                this .externalId = externalId;
1161:            }
1162:
1163:            public String getInternalCode() {
1164:                return this .internalCode;
1165:            }
1166:
1167:            public void setInternalCode(String internalCode) {
1168:                this .internalCode = internalCode;
1169:            }
1170:
1171:            public String getWebSiteId() {
1172:                return this .webSiteId;
1173:            }
1174:
1175:            public void setWebSiteId(String webSiteId) {
1176:                this .webSiteId = webSiteId;
1177:            }
1178:
1179:            /**
1180:             * Set ship before date for a particular ship group
1181:             * @param idx
1182:             * @param shipBeforeDate
1183:             */
1184:            public void setShipBeforeDate(int idx, Timestamp shipBeforeDate) {
1185:                CartShipInfo csi = this .getShipInfo(idx);
1186:                csi.shipBeforeDate = shipBeforeDate;
1187:            }
1188:
1189:            /**
1190:             * Set ship before date for ship group 0
1191:             * @param shipBeforeDate
1192:             */
1193:            public void setShipBeforeDate(Timestamp shipBeforeDate) {
1194:                this .setShipBeforeDate(0, shipBeforeDate);
1195:            }
1196:
1197:            /**
1198:             * Get ship before date for a particular ship group
1199:             * @param idx
1200:             * @return
1201:             */
1202:            public Timestamp getShipBeforeDate(int idx) {
1203:                CartShipInfo csi = this .getShipInfo(idx);
1204:                return csi.shipBeforeDate;
1205:            }
1206:
1207:            /**
1208:             * Get ship before date for ship group 0
1209:             * @return
1210:             */
1211:            public Timestamp getShipBeforeDate() {
1212:                return this .getShipBeforeDate(0);
1213:            }
1214:
1215:            /**
1216:             * Set ship after date for a particular ship group
1217:             * @param idx
1218:             * @param shipAfterDate
1219:             */
1220:            public void setShipAfterDate(int idx, Timestamp shipAfterDate) {
1221:                CartShipInfo csi = this .getShipInfo(idx);
1222:                csi.shipAfterDate = shipAfterDate;
1223:            }
1224:
1225:            /**
1226:             * Set ship after date for a particular ship group
1227:             * @param shipAfterDate
1228:             */
1229:            public void setShipAfterDate(Timestamp shipAfterDate) {
1230:                this .setShipAfterDate(0, shipAfterDate);
1231:            }
1232:
1233:            /**
1234:             * Get ship after date for a particular ship group
1235:             * @param idx
1236:             * @return
1237:             */
1238:            public Timestamp getShipAfterDate(int idx) {
1239:                CartShipInfo csi = this .getShipInfo(idx);
1240:                return csi.shipAfterDate;
1241:            }
1242:
1243:            /**
1244:             * Get ship after date for ship group 0
1245:             * @return
1246:             */
1247:            public Timestamp getShipAfterDate() {
1248:                return this .getShipAfterDate(0);
1249:            }
1250:
1251:            public void setDefaultShipBeforeDate(Timestamp defaultShipBeforeDate) {
1252:                this .defaultShipBeforeDate = defaultShipBeforeDate;
1253:            }
1254:
1255:            public Timestamp getDefaultShipBeforeDate() {
1256:                return this .defaultShipBeforeDate;
1257:            }
1258:
1259:            public void setDefaultShipAfterDate(Timestamp defaultShipAfterDate) {
1260:                this .defaultShipAfterDate = defaultShipAfterDate;
1261:            }
1262:
1263:            public Timestamp getDefaultShipAfterDate() {
1264:                return this .defaultShipAfterDate;
1265:            }
1266:
1267:            public String getOrderPartyId() {
1268:                return this .orderPartyId != null ? this .orderPartyId : this 
1269:                        .getPartyId();
1270:            }
1271:
1272:            public void setOrderPartyId(String orderPartyId) {
1273:                this .orderPartyId = orderPartyId;
1274:            }
1275:
1276:            public String getPlacingCustomerPartyId() {
1277:                return this .placingCustomerPartyId != null ? this .placingCustomerPartyId
1278:                        : this .getPartyId();
1279:            }
1280:
1281:            public void setPlacingCustomerPartyId(String placingCustomerPartyId) {
1282:                this .placingCustomerPartyId = placingCustomerPartyId;
1283:                if (UtilValidate.isEmpty(this .orderPartyId))
1284:                    this .orderPartyId = placingCustomerPartyId;
1285:            }
1286:
1287:            public String getBillToCustomerPartyId() {
1288:                return this .billToCustomerPartyId != null ? this .billToCustomerPartyId
1289:                        : this .getPartyId();
1290:            }
1291:
1292:            public void setBillToCustomerPartyId(String billToCustomerPartyId) {
1293:                this .billToCustomerPartyId = billToCustomerPartyId;
1294:                if ((UtilValidate.isEmpty(this .orderPartyId))
1295:                        && !(orderType.equals("PURCHASE_ORDER"))) {
1296:                    this .orderPartyId = billToCustomerPartyId; // orderPartyId should be bill-to-customer when it is not a purchase order
1297:                }
1298:            }
1299:
1300:            public String getShipToCustomerPartyId() {
1301:                return this .shipToCustomerPartyId != null ? this .shipToCustomerPartyId
1302:                        : this .getPartyId();
1303:            }
1304:
1305:            public void setShipToCustomerPartyId(String shipToCustomerPartyId) {
1306:                this .shipToCustomerPartyId = shipToCustomerPartyId;
1307:                if (UtilValidate.isEmpty(this .orderPartyId))
1308:                    this .orderPartyId = shipToCustomerPartyId;
1309:            }
1310:
1311:            public String getEndUserCustomerPartyId() {
1312:                return this .endUserCustomerPartyId != null ? this .endUserCustomerPartyId
1313:                        : this .getPartyId();
1314:            }
1315:
1316:            public void setEndUserCustomerPartyId(String endUserCustomerPartyId) {
1317:                this .endUserCustomerPartyId = endUserCustomerPartyId;
1318:                if (UtilValidate.isEmpty(this .orderPartyId))
1319:                    this .orderPartyId = endUserCustomerPartyId;
1320:            }
1321:
1322:            //    protected String billFromVendorPartyId = null;
1323:            //  protected String shipFromVendorPartyId = null;
1324:            //protected String supplierAgentPartyId = null;
1325:
1326:            public String getBillFromVendorPartyId() {
1327:                return this .billFromVendorPartyId != null ? this .billFromVendorPartyId
1328:                        : this .getPartyId();
1329:            }
1330:
1331:            public void setBillFromVendorPartyId(String billFromVendorPartyId) {
1332:                this .billFromVendorPartyId = billFromVendorPartyId;
1333:                if ((UtilValidate.isEmpty(this .orderPartyId))
1334:                        && (orderType.equals("PURCHASE_ORDER"))) {
1335:                    this .orderPartyId = billFromVendorPartyId; // orderPartyId should be bill-from-vendor when it is a purchase order
1336:                }
1337:
1338:            }
1339:
1340:            public String getShipFromVendorPartyId() {
1341:                return this .shipFromVendorPartyId != null ? this .shipFromVendorPartyId
1342:                        : this .getPartyId();
1343:            }
1344:
1345:            public void setShipFromVendorPartyId(String shipFromVendorPartyId) {
1346:                this .shipFromVendorPartyId = shipFromVendorPartyId;
1347:                if (UtilValidate.isEmpty(this .orderPartyId))
1348:                    this .orderPartyId = shipFromVendorPartyId;
1349:            }
1350:
1351:            public String getSupplierAgentPartyId() {
1352:                return this .supplierAgentPartyId != null ? this .supplierAgentPartyId
1353:                        : this .getPartyId();
1354:            }
1355:
1356:            public void setSupplierAgentPartyId(String supplierAgentPartyId) {
1357:                this .supplierAgentPartyId = supplierAgentPartyId;
1358:                if (UtilValidate.isEmpty(this .orderPartyId))
1359:                    this .orderPartyId = supplierAgentPartyId;
1360:            }
1361:
1362:            public String getPartyId() {
1363:                String partyId = this .orderPartyId;
1364:
1365:                if (partyId == null && getUserLogin() != null) {
1366:                    partyId = getUserLogin().getString("partyId");
1367:                }
1368:                if (partyId == null && getAutoUserLogin() != null) {
1369:                    partyId = getAutoUserLogin().getString("partyId");
1370:                }
1371:                return partyId;
1372:            }
1373:
1374:            public void setAutoSaveListId(String id) {
1375:                this .autoSaveListId = id;
1376:            }
1377:
1378:            public String getAutoSaveListId() {
1379:                return this .autoSaveListId;
1380:            }
1381:
1382:            public void setLastListRestore(Timestamp time) {
1383:                this .lastListRestore = time;
1384:            }
1385:
1386:            public Timestamp getLastListRestore() {
1387:                return this .lastListRestore;
1388:            }
1389:
1390:            public Double getPartyDaysSinceCreated(Timestamp nowTimestamp) {
1391:                String partyId = this .getPartyId();
1392:                if (UtilValidate.isEmpty(partyId)) {
1393:                    return null;
1394:                }
1395:                try {
1396:                    GenericValue party = this .getDelegator()
1397:                            .findByPrimaryKeyCache("Party",
1398:                                    UtilMisc.toMap("partyId", partyId));
1399:                    if (party == null) {
1400:                        return null;
1401:                    }
1402:                    Timestamp createdDate = party.getTimestamp("createdDate");
1403:                    if (createdDate == null) {
1404:                        return null;
1405:                    }
1406:                    double diffMillis = nowTimestamp.getTime()
1407:                            - createdDate.getTime();
1408:                    // millis per day: 1000.0 * 60.0 * 60.0 * 24.0 = 86400000.0
1409:                    return new Double((diffMillis) / 86400000.0);
1410:                } catch (GenericEntityException e) {
1411:                    Debug.logError(e,
1412:                            "Error looking up party when getting createdDate",
1413:                            module);
1414:                    return null;
1415:                }
1416:            }
1417:
1418:            // =======================================================================
1419:            // Methods for cart fields
1420:            // =======================================================================
1421:
1422:            /** Clears out the cart. */
1423:            public void clear() {
1424:                this .poNumber = null;
1425:                this .orderId = null;
1426:                this .firstAttemptOrderId = null;
1427:                this .billingAccountId = null;
1428:                this .billingAccountAmt = 0.00;
1429:                this .nextItemSeq = 1;
1430:
1431:                this .agreementId = null;
1432:                this .quoteId = null;
1433:
1434:                this .defaultItemDeliveryDate = null;
1435:                this .defaultItemComment = null;
1436:                this .orderAdditionalEmails = null;
1437:
1438:                //this.viewCartOnAdd = false;
1439:                this .readOnlyCart = false;
1440:
1441:                this .lastListRestore = null;
1442:                this .autoSaveListId = null;
1443:
1444:                this .orderTermSet = false;
1445:                this .orderTerms.clear();
1446:
1447:                this .adjustments.clear();
1448:
1449:                this .expireSingleUsePayments();
1450:                this .cartLines.clear();
1451:                this .itemGroupByNumberMap.clear();
1452:                this .clearPayments();
1453:                this .shipInfo.clear();
1454:                this .contactMechIdsMap.clear();
1455:                this .internalOrderNotes.clear();
1456:                this .orderNotes.clear();
1457:
1458:                // clear the additionalPartyRole Map
1459:                Iterator it = this .additionalPartyRole.entrySet().iterator();
1460:                while (it.hasNext()) {
1461:                    Map.Entry me = (Map.Entry) it.next();
1462:                    ((LinkedList) me.getValue()).clear();
1463:                }
1464:                this .additionalPartyRole.clear();
1465:
1466:                this .freeShippingProductPromoActions.clear();
1467:                this .desiredAlternateGiftByAction.clear();
1468:                this .productPromoUseInfoList.clear();
1469:                this .productPromoCodes.clear();
1470:
1471:                // clear the auto-save info
1472:                if (ProductStoreWorker.autoSaveCart(this .getDelegator(), this 
1473:                        .getProductStoreId())) {
1474:                    GenericValue ul = this .getUserLogin();
1475:                    if (ul == null) {
1476:                        ul = this .getAutoUserLogin();
1477:                    }
1478:
1479:                    // load the auto-save list ID
1480:                    if (autoSaveListId == null) {
1481:                        try {
1482:                            autoSaveListId = ShoppingListEvents
1483:                                    .getAutoSaveListId(this .getDelegator(),
1484:                                            null, null, ul, this 
1485:                                                    .getProductStoreId());
1486:                        } catch (GeneralException e) {
1487:                            Debug.logError(e, module);
1488:                        }
1489:                    }
1490:
1491:                    // clear the list
1492:                    if (autoSaveListId != null) {
1493:                        try {
1494:                            org.ofbiz.order.shoppinglist.ShoppingListEvents
1495:                                    .clearListInfo(this .getDelegator(),
1496:                                            autoSaveListId);
1497:                        } catch (GenericEntityException e) {
1498:                            Debug.logError(e, module);
1499:                        }
1500:                    }
1501:                    this .lastListRestore = null;
1502:                    this .autoSaveListId = null;
1503:                }
1504:            }
1505:
1506:            /** Sets the order type. */
1507:            public void setOrderType(String orderType) {
1508:                this .orderType = orderType;
1509:            }
1510:
1511:            /** Returns the order type. */
1512:            public String getOrderType() {
1513:                return this .orderType;
1514:            }
1515:
1516:            public void setChannelType(String channelType) {
1517:                this .channel = channelType;
1518:            }
1519:
1520:            public String getChannelType() {
1521:                return this .channel;
1522:            }
1523:
1524:            public boolean isPurchaseOrder() {
1525:                return "PURCHASE_ORDER".equals(this .orderType);
1526:            }
1527:
1528:            public boolean isSalesOrder() {
1529:                return "SALES_ORDER".equals(this .orderType);
1530:            }
1531:
1532:            /** Sets the PO Number in the cart. */
1533:            public void setPoNumber(String poNumber) {
1534:                this .poNumber = poNumber;
1535:            }
1536:
1537:            /** Returns the po number. */
1538:            public String getPoNumber() {
1539:                return poNumber;
1540:            }
1541:
1542:            public void setDefaultItemDeliveryDate(String date) {
1543:                this .defaultItemDeliveryDate = date;
1544:            }
1545:
1546:            public String getDefaultItemDeliveryDate() {
1547:                return this .defaultItemDeliveryDate;
1548:            }
1549:
1550:            public void setDefaultItemComment(String comment) {
1551:                this .defaultItemComment = comment;
1552:            }
1553:
1554:            public String getDefaultItemComment() {
1555:                return this .defaultItemComment;
1556:            }
1557:
1558:            public void setAgreementId(String agreementId) {
1559:                this .agreementId = agreementId;
1560:            }
1561:
1562:            public String getAgreementId() {
1563:                return this .agreementId;
1564:            }
1565:
1566:            public void setQuoteId(String quoteId) {
1567:                this .quoteId = quoteId;
1568:            }
1569:
1570:            public String getQuoteId() {
1571:                return this .quoteId;
1572:            }
1573:
1574:            // =======================================================================
1575:            // Payment Method
1576:            // =======================================================================
1577:
1578:            public String getPaymentMethodTypeId(String paymentMethodId) {
1579:                try {
1580:                    GenericValue pm = this .getDelegator().findByPrimaryKey(
1581:                            "PaymentMethod",
1582:                            UtilMisc.toMap("paymentMethodId", paymentMethodId));
1583:                    if (pm != null) {
1584:                        return pm.getString("paymentMethodTypeId");
1585:                    }
1586:                } catch (GenericEntityException e) {
1587:                    Debug.logError(e, module);
1588:                }
1589:                return null;
1590:            }
1591:
1592:            /** Creates a CartPaymentInfo object */
1593:            public CartPaymentInfo makePaymentInfo(String id, String refNum,
1594:                    Double amount) {
1595:                CartPaymentInfo inf = new CartPaymentInfo();
1596:                inf.refNum[0] = refNum;
1597:                inf.amount = amount;
1598:
1599:                if (!isPaymentMethodType(id)) {
1600:                    inf.paymentMethodTypeId = this .getPaymentMethodTypeId(id);
1601:                    inf.paymentMethodId = id;
1602:                } else {
1603:                    inf.paymentMethodTypeId = id;
1604:                }
1605:                return inf;
1606:            }
1607:
1608:            /** Locates the index of an existing CartPaymentInfo object or -1 if none found */
1609:            public int getPaymentInfoIndex(String id, String refNum) {
1610:                CartPaymentInfo this Inf = this 
1611:                        .makePaymentInfo(id, refNum, null);
1612:                for (int i = 0; i < paymentInfo.size(); i++) {
1613:                    CartPaymentInfo inf = (CartPaymentInfo) paymentInfo.get(i);
1614:                    if (inf.compareTo(this Inf) == 0) {
1615:                        return i;
1616:                    }
1617:                }
1618:                return -1;
1619:            }
1620:
1621:            /** Returns the CartPaymentInfo objects which have matching fields */
1622:            public List getPaymentInfos(boolean isPaymentMethod,
1623:                    boolean isPaymentMethodType, boolean hasRefNum) {
1624:                List foundRecords = new LinkedList();
1625:                Iterator i = paymentInfo.iterator();
1626:                while (i.hasNext()) {
1627:                    CartPaymentInfo inf = (CartPaymentInfo) i.next();
1628:                    if (isPaymentMethod && inf.paymentMethodId != null) {
1629:                        if (hasRefNum && inf.refNum != null) {
1630:                            foundRecords.add(inf);
1631:                        } else if (!hasRefNum && inf.refNum == null) {
1632:                            foundRecords.add(inf);
1633:                        }
1634:                    } else if (isPaymentMethodType
1635:                            && inf.paymentMethodTypeId != null) {
1636:                        if (hasRefNum && inf.refNum != null) {
1637:                            foundRecords.add(inf);
1638:                        } else if (!hasRefNum && inf.refNum == null) {
1639:                            foundRecords.add(inf);
1640:                        }
1641:                    }
1642:                }
1643:                return foundRecords;
1644:            }
1645:
1646:            /** Locates an existing CartPaymentInfo object by index */
1647:            public CartPaymentInfo getPaymentInfo(int index) {
1648:                return (CartPaymentInfo) paymentInfo.get(index);
1649:            }
1650:
1651:            /** Locates an existing (or creates a new) CartPaymentInfo object */
1652:            public CartPaymentInfo getPaymentInfo(String id, String refNum,
1653:                    String authCode, Double amount, boolean update) {
1654:                CartPaymentInfo this Inf = this .makePaymentInfo(id, refNum,
1655:                        amount);
1656:                Iterator i = paymentInfo.iterator();
1657:                while (i.hasNext()) {
1658:                    CartPaymentInfo inf = (CartPaymentInfo) i.next();
1659:                    if (inf.compareTo(this Inf) == 0) {
1660:                        // update the info
1661:                        if (update) {
1662:                            inf.refNum[0] = refNum;
1663:                            inf.refNum[1] = authCode;
1664:                            inf.amount = amount;
1665:                        }
1666:                        Debug.logInfo("Returned existing PaymentInfo - "
1667:                                + inf.toString(), module);
1668:                        return inf;
1669:                    }
1670:                }
1671:
1672:                Debug.logInfo("Returned new PaymentInfo - "
1673:                        + this Inf.toString(), module);
1674:                return this Inf;
1675:            }
1676:
1677:            /** Locates an existing (or creates a new) CartPaymentInfo object */
1678:            public CartPaymentInfo getPaymentInfo(String id, String refNum,
1679:                    String authCode, Double amount) {
1680:                return this .getPaymentInfo(id, refNum, authCode, amount, false);
1681:            }
1682:
1683:            /** Locates an existing (or creates a new) CartPaymentInfo object */
1684:            public CartPaymentInfo getPaymentInfo(String id) {
1685:                return this .getPaymentInfo(id, null, null, null, false);
1686:            }
1687:
1688:            /** adds a payment method/payment method type */
1689:            public CartPaymentInfo addPaymentAmount(String id, Double amount,
1690:                    String refNum, String authCode, boolean isSingleUse,
1691:                    boolean isPresent, boolean replace) {
1692:                CartPaymentInfo inf = this .getPaymentInfo(id, refNum, authCode,
1693:                        amount, replace);
1694:                inf.singleUse = isSingleUse;
1695:                if (replace) {
1696:                    paymentInfo.remove(inf);
1697:                }
1698:                paymentInfo.add(inf);
1699:
1700:                return inf;
1701:            }
1702:
1703:            /** adds a payment method/payment method type */
1704:            public CartPaymentInfo addPaymentAmount(String id, Double amount,
1705:                    boolean isSingleUse) {
1706:                return this .addPaymentAmount(id, amount, null, null,
1707:                        isSingleUse, false, true);
1708:            }
1709:
1710:            /** adds a payment method/payment method type */
1711:            public CartPaymentInfo addPaymentAmount(String id, double amount,
1712:                    boolean isSingleUse) {
1713:                return this .addPaymentAmount(id, new Double(amount),
1714:                        isSingleUse);
1715:            }
1716:
1717:            /** adds a payment method/payment method type */
1718:            public CartPaymentInfo addPaymentAmount(String id, Double amount) {
1719:                return this .addPaymentAmount(id, amount, false);
1720:            }
1721:
1722:            /** adds a payment method/payment method type */
1723:            public CartPaymentInfo addPaymentAmount(String id, double amount) {
1724:                return this .addPaymentAmount(id, new Double(amount), false);
1725:            }
1726:
1727:            /** adds a payment method/payment method type */
1728:            public CartPaymentInfo addPayment(String id) {
1729:                return this .addPaymentAmount(id, null, false);
1730:            }
1731:
1732:            /** returns the payment method/payment method type amount */
1733:            public Double getPaymentAmount(String id) {
1734:                return this .getPaymentInfo(id).amount;
1735:            }
1736:
1737:            public void addPaymentRef(String id, String ref, String authCode) {
1738:                this .getPaymentInfo(id).refNum[0] = ref;
1739:                this .getPaymentInfo(id).refNum[1] = authCode;
1740:            }
1741:
1742:            public String getPaymentRef(String id) {
1743:                Iterator i = paymentInfo.iterator();
1744:                while (i.hasNext()) {
1745:                    CartPaymentInfo inf = (CartPaymentInfo) i.next();
1746:                    if (inf.paymentMethodId.equals(id)
1747:                            || inf.paymentMethodTypeId.equals(id)) {
1748:                        return inf.refNum[0];
1749:                    }
1750:                }
1751:                return null;
1752:            }
1753:
1754:            /** returns the total payment amounts */
1755:            public double getPaymentTotal() {
1756:                double total = 0.00;
1757:                Iterator i = paymentInfo.iterator();
1758:                while (i.hasNext()) {
1759:                    CartPaymentInfo inf = (CartPaymentInfo) i.next();
1760:                    if (inf.amount != null) {
1761:                        total += inf.amount.doubleValue();
1762:                    }
1763:                }
1764:                return total;
1765:            }
1766:
1767:            public int selectedPayments() {
1768:                return paymentInfo.size();
1769:            }
1770:
1771:            public boolean isPaymentSelected(String id) {
1772:                CartPaymentInfo inf = this .getPaymentInfo(id);
1773:                return paymentInfo.contains(inf);
1774:            }
1775:
1776:            /** removes a specific payment method/payment method type */
1777:            public void clearPayment(String id) {
1778:                CartPaymentInfo inf = this .getPaymentInfo(id);
1779:                paymentInfo.remove(inf);
1780:            }
1781:
1782:            /** removes a specific payment info from the list */
1783:            public void clearPayment(int index) {
1784:                paymentInfo.remove(index);
1785:            }
1786:
1787:            /** clears all payment method/payment method types */
1788:            public void clearPayments() {
1789:                this .expireSingleUsePayments();
1790:                paymentInfo.clear();
1791:            }
1792:
1793:            /** remove all the paymentMethods based on the paymentMethodIds */
1794:            public void clearPaymentMethodsById(List paymentMethodIdsToRemove) {
1795:                if (UtilValidate.isEmpty(paymentMethodIdsToRemove))
1796:                    return;
1797:                for (Iterator iter = paymentInfo.iterator(); iter.hasNext();) {
1798:                    CartPaymentInfo info = (CartPaymentInfo) iter.next();
1799:                    if (paymentMethodIdsToRemove.contains(info.paymentMethodId)) {
1800:                        iter.remove();
1801:                    }
1802:                }
1803:            }
1804:
1805:            /** remove declined payment methods for an order from cart.  The idea is to call this after an attempted order is rejected */
1806:            public void clearDeclinedPaymentMethodsFromOrder(
1807:                    GenericDelegator delegator, String orderId) {
1808:                try {
1809:                    List declinedPaymentMethods = delegator.findByAnd(
1810:                            "OrderPaymentPreference", UtilMisc.toMap("orderId",
1811:                                    orderId, "statusId", "PAYMENT_DECLINED"));
1812:                    if (!UtilValidate.isEmpty(declinedPaymentMethods)) {
1813:                        List paymentMethodIdsToRemove = new ArrayList();
1814:                        for (Iterator iter = declinedPaymentMethods.iterator(); iter
1815:                                .hasNext();) {
1816:                            GenericValue opp = (GenericValue) iter.next();
1817:                            paymentMethodIdsToRemove.add(opp
1818:                                    .getString("paymentMethodId"));
1819:                        }
1820:                        clearPaymentMethodsById(paymentMethodIdsToRemove);
1821:                    }
1822:                } catch (GenericEntityException ex) {
1823:                    Debug.logError(
1824:                            "Unable to remove declined payment methods from cart due to "
1825:                                    + ex.getMessage(), module);
1826:                    return;
1827:                }
1828:            }
1829:
1830:            private void expireSingleUsePayments() {
1831:                Timestamp now = UtilDateTime.nowTimestamp();
1832:                Iterator i = paymentInfo.iterator();
1833:                while (i.hasNext()) {
1834:                    CartPaymentInfo inf = (CartPaymentInfo) i.next();
1835:                    if (inf.paymentMethodId == null || !inf.singleUse) {
1836:                        continue;
1837:                    }
1838:
1839:                    GenericValue paymentMethod = null;
1840:                    try {
1841:                        paymentMethod = this .getDelegator().findByPrimaryKey(
1842:                                "PaymentMethod",
1843:                                UtilMisc.toMap("paymentMethodId",
1844:                                        inf.paymentMethodId));
1845:                    } catch (GenericEntityException e) {
1846:                        Debug.logError(e,
1847:                                "ERROR: Unable to get payment method record to expire : "
1848:                                        + inf.paymentMethodId, module);
1849:                    }
1850:                    if (paymentMethod != null) {
1851:                        paymentMethod.set("thruDate", now);
1852:                        try {
1853:                            paymentMethod.store();
1854:                        } catch (GenericEntityException e) {
1855:                            Debug.logError(e,
1856:                                    "Unable to store single use PaymentMethod record : "
1857:                                            + paymentMethod, module);
1858:                        }
1859:                    } else {
1860:                        Debug.logError(
1861:                                "ERROR: Received back a null payment method record for expired ID : "
1862:                                        + inf.paymentMethodId, module);
1863:                    }
1864:                }
1865:            }
1866:
1867:            /** Returns the Payment Method Ids */
1868:            public List getPaymentMethodIds() {
1869:                List pmi = new LinkedList();
1870:                Iterator i = paymentInfo.iterator();
1871:                while (i.hasNext()) {
1872:                    CartPaymentInfo inf = (CartPaymentInfo) i.next();
1873:                    if (inf.paymentMethodId != null) {
1874:                        pmi.add(inf.paymentMethodId);
1875:                    }
1876:                }
1877:                return pmi;
1878:            }
1879:
1880:            /** Returns the Payment Method Ids */
1881:            public List getPaymentMethodTypeIds() {
1882:                List pmt = FastList.newInstance();
1883:                Iterator i = paymentInfo.iterator();
1884:                while (i.hasNext()) {
1885:                    CartPaymentInfo inf = (CartPaymentInfo) i.next();
1886:                    if (inf.paymentMethodTypeId != null) {
1887:                        pmt.add(inf.paymentMethodTypeId);
1888:                    }
1889:                }
1890:                return pmt;
1891:            }
1892:
1893:            /** Returns a list of PaymentMethod value objects selected in the cart */
1894:            public List getPaymentMethods() {
1895:                List methods = FastList.newInstance();
1896:                if (paymentInfo != null && paymentInfo.size() > 0) {
1897:                    Iterator paymentMethodIdIter = getPaymentMethodIds()
1898:                            .iterator();
1899:                    while (paymentMethodIdIter.hasNext()) {
1900:                        String paymentMethodId = (String) paymentMethodIdIter
1901:                                .next();
1902:                        try {
1903:                            GenericValue paymentMethod = this .getDelegator()
1904:                                    .findByPrimaryKeyCache(
1905:                                            "PaymentMethod",
1906:                                            UtilMisc.toMap("paymentMethodId",
1907:                                                    paymentMethodId));
1908:                            if (paymentMethod != null) {
1909:                                methods.add(paymentMethod);
1910:                            } else {
1911:                                Debug.logError(
1912:                                        "Error getting cart payment methods, the paymentMethodId ["
1913:                                                + paymentMethodId
1914:                                                + "] is not valid", module);
1915:                            }
1916:                        } catch (GenericEntityException e) {
1917:                            Debug
1918:                                    .logError(
1919:                                            e,
1920:                                            "Unable to get payment method from the database",
1921:                                            module);
1922:                        }
1923:                    }
1924:                }
1925:
1926:                return methods;
1927:            }
1928:
1929:            /** Returns a list of PaymentMethodType value objects selected in the cart */
1930:            public List getPaymentMethodTypes() {
1931:                List types = new LinkedList();
1932:                if (paymentInfo != null && paymentInfo.size() > 0) {
1933:                    Iterator i = getPaymentMethodTypeIds().iterator();
1934:                    while (i.hasNext()) {
1935:                        String id = (String) i.next();
1936:                        try {
1937:                            types
1938:                                    .add(this 
1939:                                            .getDelegator()
1940:                                            .findByPrimaryKeyCache(
1941:                                                    "PaymentMethodType",
1942:                                                    UtilMisc
1943:                                                            .toMap(
1944:                                                                    "paymentMethodTypeId",
1945:                                                                    id)));
1946:                        } catch (GenericEntityException e) {
1947:                            Debug
1948:                                    .logError(
1949:                                            e,
1950:                                            "Unable to get payment method type from the database",
1951:                                            module);
1952:                        }
1953:                    }
1954:                }
1955:
1956:                return types;
1957:            }
1958:
1959:            public List getCreditCards() {
1960:                List paymentMethods = this .getPaymentMethods();
1961:                List creditCards = new LinkedList();
1962:                if (paymentMethods != null) {
1963:                    Iterator i = paymentMethods.iterator();
1964:                    while (i.hasNext()) {
1965:                        GenericValue pm = (GenericValue) i.next();
1966:                        if ("CREDIT_CARD".equals(pm
1967:                                .getString("paymentMethodTypeId"))) {
1968:                            try {
1969:                                GenericValue cc = pm
1970:                                        .getRelatedOne("CreditCard");
1971:                                creditCards.add(cc);
1972:                            } catch (GenericEntityException e) {
1973:                                Debug.logError(e,
1974:                                        "Unable to get credit card record from payment method : "
1975:                                                + pm, module);
1976:                            }
1977:                        }
1978:                    }
1979:                }
1980:
1981:                return creditCards;
1982:            }
1983:
1984:            public List getGiftCards() {
1985:                List paymentMethods = this .getPaymentMethods();
1986:                List giftCards = new LinkedList();
1987:                if (paymentMethods != null) {
1988:                    Iterator i = paymentMethods.iterator();
1989:                    while (i.hasNext()) {
1990:                        GenericValue pm = (GenericValue) i.next();
1991:                        if ("GIFT_CARD".equals(pm
1992:                                .getString("paymentMethodTypeId"))) {
1993:                            try {
1994:                                GenericValue gc = pm.getRelatedOne("GiftCard");
1995:                                giftCards.add(gc);
1996:                            } catch (GenericEntityException e) {
1997:                                Debug.logError(e,
1998:                                        "Unable to get gift card record from payment method : "
1999:                                                + pm, module);
2000:                            }
2001:                        }
2002:                    }
2003:                }
2004:
2005:                return giftCards;
2006:            }
2007:
2008:            /* determines if the id supplied is a payment method or not by searching in the entity engine */
2009:            public boolean isPaymentMethodType(String id) {
2010:                GenericValue paymentMethodType = null;
2011:                try {
2012:                    paymentMethodType = this .getDelegator()
2013:                            .findByPrimaryKeyCache("PaymentMethodType",
2014:                                    UtilMisc.toMap("paymentMethodTypeId", id));
2015:                } catch (GenericEntityException e) {
2016:                    Debug.logInfo(e, "Problems getting PaymentMethodType",
2017:                            module);
2018:                }
2019:                if (paymentMethodType == null) {
2020:                    return false;
2021:                } else {
2022:                    return true;
2023:                }
2024:            }
2025:
2026:            /**
2027:             * Returns ProductStoreFinActSetting based on cart's productStoreId and FinAccountHelper's defined giftCertFinAcctTypeId
2028:             * @param delegator
2029:             * @return
2030:             * @throws GenericEntityException
2031:             */
2032:            public GenericValue getGiftCertSettingFromStore(
2033:                    GenericDelegator delegator) throws GenericEntityException {
2034:                return delegator.findByPrimaryKeyCache(
2035:                        "ProductStoreFinActSetting", UtilMisc.toMap(
2036:                                "productStoreId", getProductStoreId(),
2037:                                "finAccountTypeId",
2038:                                FinAccountHelper.giftCertFinAccountTypeId));
2039:            }
2040:
2041:            /**
2042:             * Determines whether pin numbers are required for gift cards, based on ProductStoreFinActSetting.  Default to true.
2043:             * @return
2044:             */
2045:            public boolean isPinRequiredForGC(GenericDelegator delegator) {
2046:                try {
2047:                    GenericValue giftCertSettings = getGiftCertSettingFromStore(delegator);
2048:                    if (giftCertSettings != null) {
2049:                        if ("Y".equals(giftCertSettings
2050:                                .getString("requirePinCode"))) {
2051:                            return true;
2052:                        } else {
2053:                            return false;
2054:                        }
2055:                    } else {
2056:                        Debug.logWarning(
2057:                                "No product store gift certificate settings found for store ["
2058:                                        + getProductStoreId() + "]", module);
2059:                        return true;
2060:                    }
2061:                } catch (GenericEntityException ex) {
2062:                    Debug.logError(
2063:                            "Error checking if store requires pin number for GC: "
2064:                                    + ex.getMessage(), module);
2065:                    return true;
2066:                }
2067:            }
2068:
2069:            /**
2070:             * Returns whether the cart should validate gift cards against FinAccount (ie, internal gift certificates).  Defaults to false.
2071:             * @param delegator
2072:             * @return
2073:             */
2074:            public boolean isValidateGCFinAccount(GenericDelegator delegator) {
2075:                try {
2076:                    GenericValue giftCertSettings = getGiftCertSettingFromStore(delegator);
2077:                    if (giftCertSettings != null) {
2078:                        if ("Y".equals(giftCertSettings
2079:                                .getString("validateGCFinAcct"))) {
2080:                            return true;
2081:                        } else {
2082:                            return false;
2083:                        }
2084:                    } else {
2085:                        Debug.logWarning(
2086:                                "No product store gift certificate settings found for store ["
2087:                                        + getProductStoreId() + "]", module);
2088:                        return false;
2089:                    }
2090:                } catch (GenericEntityException ex) {
2091:                    Debug.logError(
2092:                            "Error checking if store requires pin number for GC: "
2093:                                    + ex.getMessage(), module);
2094:                    return false;
2095:                }
2096:            }
2097:
2098:            // =======================================================================
2099:            // Billing Accounts
2100:            // =======================================================================
2101:
2102:            /** Sets the billing account id string. */
2103:            public void setBillingAccount(String billingAccountId, double amount) {
2104:                this .billingAccountId = billingAccountId;
2105:                this .billingAccountAmt = amount;
2106:            }
2107:
2108:            /** Returns the billing message string. */
2109:            public String getBillingAccountId() {
2110:                return this .billingAccountId;
2111:            }
2112:
2113:            /** Returns the amount to be billed to the billing account.*/
2114:            public double getBillingAccountAmount() {
2115:                return this .billingAccountAmt;
2116:            }
2117:
2118:            // =======================================================================
2119:            // Shipping Charges
2120:            // =======================================================================
2121:
2122:            /** Returns the order level shipping amount */
2123:            public double getOrderShipping() {
2124:                return OrderReadHelper.calcOrderAdjustmentsBd(
2125:                        this .getAdjustments(),
2126:                        new BigDecimal(this .getSubTotal()), false, false, true)
2127:                        .doubleValue();
2128:            }
2129:
2130:            // ----------------------------------------
2131:            // Ship Group Methods
2132:            // ----------------------------------------
2133:
2134:            public int addShipInfo() {
2135:                shipInfo.add(new CartShipInfo());
2136:                return (shipInfo.size() - 1);
2137:            }
2138:
2139:            public List getShipGroups() {
2140:                return this .shipInfo;
2141:            }
2142:
2143:            public Map getShipGroups(ShoppingCartItem item) {
2144:                Map shipGroups = new LinkedMap();
2145:                if (item != null) {
2146:                    for (int i = 0; i < this .shipInfo.size(); i++) {
2147:                        CartShipInfo csi = (CartShipInfo) shipInfo.get(i);
2148:                        CartShipInfo.CartShipItemInfo csii = (CartShipInfo.CartShipItemInfo) csi.shipItemInfo
2149:                                .get(item);
2150:                        if (csii != null) {
2151:                            if (this .checkShipItemInfo(csi, csii)) {
2152:                                shipGroups.put(new Integer(i), new Double(
2153:                                        csii.quantity));
2154:                            }
2155:                        }
2156:                    }
2157:                }
2158:                return shipGroups;
2159:            }
2160:
2161:            public Map getShipGroups(int itemIndex) {
2162:                return this .getShipGroups(this .findCartItem(itemIndex));
2163:            }
2164:
2165:            public CartShipInfo getShipInfo(int idx) {
2166:                if (idx == -1) {
2167:                    return null;
2168:                }
2169:
2170:                if (shipInfo.size() == idx) {
2171:                    shipInfo.add(new CartShipInfo());
2172:                }
2173:
2174:                return (CartShipInfo) shipInfo.get(idx);
2175:            }
2176:
2177:            public int getShipGroupSize() {
2178:                return this .shipInfo.size();
2179:            }
2180:
2181:            /** Returns the ShoppingCartItem (key) and quantity (value) associated with the ship group */
2182:            public Map getShipGroupItems(int idx) {
2183:                CartShipInfo csi = this .getShipInfo(idx);
2184:                Map qtyMap = new HashMap();
2185:                Iterator i = csi.shipItemInfo.keySet().iterator();
2186:                while (i.hasNext()) {
2187:                    ShoppingCartItem item = (ShoppingCartItem) i.next();
2188:                    CartShipInfo.CartShipItemInfo csii = (CartShipInfo.CartShipItemInfo) csi.shipItemInfo
2189:                            .get(item);
2190:                    qtyMap.put(item, new Double(csii.quantity));
2191:                }
2192:                return qtyMap;
2193:            }
2194:
2195:            public void clearItemShipInfo(ShoppingCartItem item) {
2196:                for (int i = 0; i < shipInfo.size(); i++) {
2197:                    CartShipInfo csi = this .getShipInfo(i);
2198:                    csi.shipItemInfo.remove(item);
2199:                }
2200:                this .cleanUpShipGroups();
2201:            }
2202:
2203:            public void setItemShipGroupEstimate(double amount, int idx) {
2204:                CartShipInfo csi = this .getShipInfo(idx);
2205:                csi.shipEstimate = amount;
2206:            }
2207:
2208:            /**
2209:             * Updates the shipBefore and shipAfterDates of all ship groups that the item belongs to, re-setting
2210:             * ship group ship before date if item ship before date is before it and ship group ship after date if
2211:             * item ship after date is before it.  
2212:             * @param item
2213:             */
2214:            public void setShipGroupShipDatesFromItem(ShoppingCartItem item) {
2215:                Map shipGroups = this .getShipGroups(item);
2216:
2217:                if ((shipGroups != null) && (shipGroups.keySet() != null)) {
2218:                    for (Iterator shipGroupKeys = shipGroups.keySet()
2219:                            .iterator(); shipGroupKeys.hasNext();) {
2220:                        Integer shipGroup = (Integer) shipGroupKeys.next();
2221:                        CartShipInfo cartShipInfo = this .getShipInfo(shipGroup
2222:                                .intValue());
2223:
2224:                        cartShipInfo.resetShipAfterDateIfBefore(item
2225:                                .getShipAfterDate());
2226:                        cartShipInfo.resetShipBeforeDateIfAfter(item
2227:                                .getShipBeforeDate());
2228:                    }
2229:                }
2230:            }
2231:
2232:            public double getItemShipGroupEstimate(int idx) {
2233:                CartShipInfo csi = this .getShipInfo(idx);
2234:                return csi.shipEstimate;
2235:            }
2236:
2237:            public void setItemShipGroupQty(int itemIndex, double quantity,
2238:                    int idx) {
2239:                this .setItemShipGroupQty(this .findCartItem(itemIndex),
2240:                        itemIndex, quantity, idx);
2241:            }
2242:
2243:            public void setItemShipGroupQty(ShoppingCartItem item,
2244:                    double quantity, int idx) {
2245:                this .setItemShipGroupQty(item, this .getItemIndex(item),
2246:                        quantity, idx);
2247:            }
2248:
2249:            public void setItemShipGroupQty(ShoppingCartItem item,
2250:                    int itemIndex, double quantity, int idx) {
2251:                if (itemIndex > -1) {
2252:                    CartShipInfo csi = this .getShipInfo(idx);
2253:
2254:                    // never set less than zero
2255:                    if (quantity < 0) {
2256:                        quantity = 0;
2257:                    }
2258:
2259:                    // never set more than quantity ordered
2260:                    if (quantity > item.getQuantity()) {
2261:                        quantity = item.getQuantity();
2262:                    }
2263:
2264:                    // re-set the ship group's before and after dates based on the item's
2265:                    csi.resetShipBeforeDateIfAfter(item.getShipBeforeDate());
2266:                    csi.resetShipAfterDateIfBefore(item.getShipAfterDate());
2267:
2268:                    CartShipInfo.CartShipItemInfo csii = csi.setItemInfo(item,
2269:                            quantity);
2270:                    this .checkShipItemInfo(csi, csii);
2271:                }
2272:            }
2273:
2274:            public double getItemShipGroupQty(ShoppingCartItem item, int idx) {
2275:                if (item != null) {
2276:                    CartShipInfo csi = this .getShipInfo(idx);
2277:                    CartShipInfo.CartShipItemInfo csii = (CartShipInfo.CartShipItemInfo) csi.shipItemInfo
2278:                            .get(item);
2279:                    if (csii != null) {
2280:                        return csii.quantity;
2281:                    }
2282:                }
2283:                return 0;
2284:            }
2285:
2286:            public double getItemShipGroupQty(int itemIndex, int idx) {
2287:                return this .getItemShipGroupQty(this .findCartItem(itemIndex),
2288:                        idx);
2289:            }
2290:
2291:            public void positionItemToGroup(int itemIndex, double quantity,
2292:                    int fromIndex, int toIndex, boolean clearEmptyGroups) {
2293:                this .positionItemToGroup(this .findCartItem(itemIndex),
2294:                        quantity, fromIndex, toIndex, clearEmptyGroups);
2295:            }
2296:
2297:            public void positionItemToGroup(ShoppingCartItem item,
2298:                    double quantity, int fromIndex, int toIndex,
2299:                    boolean clearEmptyGroups) {
2300:                if (fromIndex == toIndex || quantity <= 0) {
2301:                    // do nothing
2302:                    return;
2303:                }
2304:
2305:                // get the ship groups; create the TO group if needed
2306:                CartShipInfo fromGroup = this .getShipInfo(fromIndex);
2307:                CartShipInfo toGroup = null;
2308:                if (toIndex == -1) {
2309:                    toGroup = new CartShipInfo();
2310:                    this .shipInfo.add(toGroup);
2311:                    toIndex = this .shipInfo.size() - 1;
2312:                } else {
2313:                    toGroup = this .getShipInfo(toIndex);
2314:                }
2315:
2316:                // adjust the quantities
2317:                if (fromGroup != null && toGroup != null) {
2318:                    double fromQty = this .getItemShipGroupQty(item, fromIndex);
2319:                    double toQty = this .getItemShipGroupQty(item, toIndex);
2320:                    if (fromQty > 0) {
2321:                        if (quantity > fromQty) {
2322:                            quantity = fromQty;
2323:                        }
2324:                        fromQty -= quantity;
2325:                        toQty += quantity;
2326:                        this .setItemShipGroupQty(item, fromQty, fromIndex);
2327:                        this .setItemShipGroupQty(item, toQty, toIndex);
2328:                    }
2329:
2330:                    if (clearEmptyGroups) {
2331:                        // remove any empty ship groups
2332:                        this .cleanUpShipGroups();
2333:                    }
2334:                }
2335:            }
2336:
2337:            // removes 0 quantity items
2338:            protected boolean checkShipItemInfo(CartShipInfo csi,
2339:                    CartShipInfo.CartShipItemInfo csii) {
2340:                if (csii.quantity == 0 || csii.item.getQuantity() == 0) {
2341:                    csi.shipItemInfo.remove(csii.item);
2342:                    return false;
2343:                }
2344:                return true;
2345:            }
2346:
2347:            protected void cleanUpShipGroups() {
2348:                for (int i = 0; i < this .shipInfo.size(); i++) {
2349:                    CartShipInfo csi = this .getShipInfo(i);
2350:                    Iterator si = csi.shipItemInfo.keySet().iterator();
2351:                    while (si.hasNext()) {
2352:                        ShoppingCartItem item = (ShoppingCartItem) si.next();
2353:                        if (item.getQuantity() == 0.0) {
2354:                            si.remove();
2355:                        }
2356:                    }
2357:                    if (csi.shipItemInfo.size() == 0) {
2358:                        this .shipInfo.remove(csi);
2359:                    }
2360:                }
2361:            }
2362:
2363:            /** Sets the shipping contact mech id. */
2364:            public void setShippingContactMechId(int idx,
2365:                    String shippingContactMechId) {
2366:                CartShipInfo csi = this .getShipInfo(idx);
2367:                csi.contactMechId = shippingContactMechId;
2368:            }
2369:
2370:            public void setShippingContactMechId(String shippingContactMechId) {
2371:                this .setShippingContactMechId(0, shippingContactMechId);
2372:            }
2373:
2374:            /** Returns the shipping contact mech id. */
2375:            public String getShippingContactMechId(int idx) {
2376:                CartShipInfo csi = this .getShipInfo(idx);
2377:                return csi.contactMechId;
2378:            }
2379:
2380:            public String getShippingContactMechId() {
2381:                return this .getShippingContactMechId(0);
2382:            }
2383:
2384:            /** Sets the shipment method type. */
2385:            public void setShipmentMethodTypeId(int idx,
2386:                    String shipmentMethodTypeId) {
2387:                CartShipInfo csi = this .getShipInfo(idx);
2388:                csi.shipmentMethodTypeId = shipmentMethodTypeId;
2389:            }
2390:
2391:            public void setShipmentMethodTypeId(String shipmentMethodTypeId) {
2392:                this .setShipmentMethodTypeId(0, shipmentMethodTypeId);
2393:            }
2394:
2395:            /** Returns the shipment method type ID */
2396:            public String getShipmentMethodTypeId(int idx) {
2397:                CartShipInfo csi = this .getShipInfo(idx);
2398:                return csi.shipmentMethodTypeId;
2399:            }
2400:
2401:            public String getShipmentMethodTypeId() {
2402:                return this .getShipmentMethodTypeId(0);
2403:            }
2404:
2405:            /** Returns the shipment method type. */
2406:            public GenericValue getShipmentMethodType(int idx) {
2407:                String shipmentMethodTypeId = this .getShipmentMethodTypeId(idx);
2408:                if (UtilValidate.isNotEmpty(shipmentMethodTypeId)) {
2409:                    try {
2410:                        return this .getDelegator().findByPrimaryKey(
2411:                                "ShipmentMethodType",
2412:                                UtilMisc.toMap("shipmentMethodTypeId",
2413:                                        shipmentMethodTypeId));
2414:                    } catch (GenericEntityException e) {
2415:                        Debug.logWarning(e, module);
2416:                    }
2417:                }
2418:                return null;
2419:            }
2420:
2421:            /** Sets the supplier for the given ship group (drop shipment). */
2422:            public void setSupplierPartyId(int idx, String supplierPartyId) {
2423:                CartShipInfo csi = this .getShipInfo(idx);
2424:                // TODO: before we set the value we have to verify if all the products
2425:                //       already in this ship group are drop shippable from the supplier
2426:                csi.supplierPartyId = supplierPartyId;
2427:            }
2428:
2429:            /** Returns the supplier for the given ship group (drop shipment). */
2430:            public String getSupplierPartyId(int idx) {
2431:                CartShipInfo csi = this .getShipInfo(idx);
2432:                return csi.supplierPartyId;
2433:            }
2434:
2435:            /** Sets the shipping instructions. */
2436:            public void setShippingInstructions(int idx,
2437:                    String shippingInstructions) {
2438:                CartShipInfo csi = this .getShipInfo(idx);
2439:                csi.shippingInstructions = shippingInstructions;
2440:            }
2441:
2442:            public void setShippingInstructions(String shippingInstructions) {
2443:                this .setShippingInstructions(0, shippingInstructions);
2444:            }
2445:
2446:            /** Returns the shipping instructions. */
2447:            public String getShippingInstructions(int idx) {
2448:                CartShipInfo csi = this .getShipInfo(idx);
2449:                return csi.shippingInstructions;
2450:            }
2451:
2452:            public String getShippingInstructions() {
2453:                return this .getShippingInstructions(0);
2454:            }
2455:
2456:            public void setMaySplit(int idx, Boolean maySplit) {
2457:                CartShipInfo csi = this .getShipInfo(idx);
2458:                csi.maySplit = maySplit.booleanValue() ? "Y" : "N";
2459:            }
2460:
2461:            public void setMaySplit(Boolean maySplit) {
2462:                this .setMaySplit(0, maySplit);
2463:            }
2464:
2465:            /** Returns Boolean.TRUE if the order may be split (null if unspecified) */
2466:            public String getMaySplit(int idx) {
2467:                CartShipInfo csi = this .getShipInfo(idx);
2468:                return csi.maySplit;
2469:            }
2470:
2471:            public String getMaySplit() {
2472:                return this .getMaySplit(0);
2473:            }
2474:
2475:            public void setGiftMessage(int idx, String giftMessage) {
2476:                CartShipInfo csi = this .getShipInfo(idx);
2477:                csi.giftMessage = giftMessage;
2478:            }
2479:
2480:            public void setGiftMessage(String giftMessage) {
2481:                this .setGiftMessage(0, giftMessage);
2482:            }
2483:
2484:            public String getGiftMessage(int idx) {
2485:                CartShipInfo csi = this .getShipInfo(idx);
2486:                return csi.giftMessage;
2487:            }
2488:
2489:            public String getGiftMessage() {
2490:                return this .getGiftMessage(0);
2491:            }
2492:
2493:            public void setIsGift(int idx, Boolean isGift) {
2494:                CartShipInfo csi = this .getShipInfo(idx);
2495:                csi.isGift = isGift.booleanValue() ? "Y" : "N";
2496:            }
2497:
2498:            public void setIsGift(Boolean isGift) {
2499:                this .setIsGift(0, isGift);
2500:            }
2501:
2502:            public String getIsGift(int idx) {
2503:                CartShipInfo csi = this .getShipInfo(idx);
2504:                return csi.isGift;
2505:            }
2506:
2507:            public String getIsGift() {
2508:                return this .getIsGift(0);
2509:            }
2510:
2511:            public void setCarrierPartyId(int idx, String carrierPartyId) {
2512:                CartShipInfo csi = this .getShipInfo(idx);
2513:                csi.carrierPartyId = carrierPartyId;
2514:            }
2515:
2516:            public void setCarrierPartyId(String carrierPartyId) {
2517:                this .setCarrierPartyId(0, carrierPartyId);
2518:            }
2519:
2520:            public String getCarrierPartyId(int idx) {
2521:                CartShipInfo csi = this .getShipInfo(idx);
2522:                return csi.carrierPartyId;
2523:            }
2524:
2525:            public String getCarrierPartyId() {
2526:                return this .getCarrierPartyId(0);
2527:            }
2528:
2529:            public void setOrderAdditionalEmails(String orderAdditionalEmails) {
2530:                this .orderAdditionalEmails = orderAdditionalEmails;
2531:            }
2532:
2533:            public String getOrderAdditionalEmails() {
2534:                return orderAdditionalEmails;
2535:            }
2536:
2537:            public GenericValue getShippingAddress(int idx) {
2538:                if (this .getShippingContactMechId(idx) != null) {
2539:                    try {
2540:                        return getDelegator().findByPrimaryKey(
2541:                                "PostalAddress",
2542:                                UtilMisc.toMap("contactMechId", this 
2543:                                        .getShippingContactMechId(idx)));
2544:                    } catch (GenericEntityException e) {
2545:                        Debug.logWarning(e.toString(), module);
2546:                        return null;
2547:                    }
2548:                } else {
2549:                    return null;
2550:                }
2551:            }
2552:
2553:            public GenericValue getShippingAddress() {
2554:                return this .getShippingAddress(0);
2555:            }
2556:
2557:            // ----------------------------------------
2558:            // internal/public notes
2559:            // ----------------------------------------
2560:
2561:            public List getInternalOrderNotes() {
2562:                return this .internalOrderNotes;
2563:            }
2564:
2565:            public List getOrderNotes() {
2566:                return this .orderNotes;
2567:            }
2568:
2569:            public void addInternalOrderNote(String note) {
2570:                this .internalOrderNotes.add(note);
2571:            }
2572:
2573:            public void addOrderNote(String note) {
2574:                this .orderNotes.add(note);
2575:            }
2576:
2577:            // Preset with default values some of the checkout options to get a quicker checkout process.
2578:            public void setDefaultCheckoutOptions(LocalDispatcher dispatcher) {
2579:                // skip the add party screen
2580:                this .setAttribute("addpty", "Y");
2581:                if (getOrderType().equals("SALES_ORDER")) {
2582:                    // checkout options for sales orders
2583:                    // set as the default shipping location the first from the list of available shipping locations
2584:                    if (this .getPartyId() != null
2585:                            && !this .getPartyId().equals("_NA_")) {
2586:                        try {
2587:                            GenericValue orderParty = delegator
2588:                                    .findByPrimaryKey("Party", UtilMisc.toMap(
2589:                                            "partyId", this .getPartyId()));
2590:                            Collection shippingContactMechList = ContactHelper
2591:                                    .getContactMech(orderParty,
2592:                                            "SHIPPING_LOCATION",
2593:                                            "POSTAL_ADDRESS", false);
2594:                            if (shippingContactMechList != null
2595:                                    && shippingContactMechList.size() > 0) {
2596:                                GenericValue shippingContactMech = (GenericValue) (shippingContactMechList
2597:                                        .iterator()).next();
2598:                                this 
2599:                                        .setShippingContactMechId(shippingContactMech
2600:                                                .getString("contactMechId"));
2601:                            }
2602:                        } catch (GenericEntityException e) {
2603:                            Debug
2604:                                    .logError(
2605:                                            e,
2606:                                            "Error setting shippingContactMechId in setDefaultCheckoutOptions() method.",
2607:                                            module);
2608:                        }
2609:                    }
2610:                    // set the default shipment method
2611:                    ShippingEstimateWrapper shipEstimateWrapper = org.ofbiz.order.shoppingcart.shipping.ShippingEstimateWrapper
2612:                            .getWrapper(dispatcher, this , 0);
2613:                    GenericValue carrierShipmentMethod = EntityUtil
2614:                            .getFirst(shipEstimateWrapper.getShippingMethods());
2615:                    if (carrierShipmentMethod != null) {
2616:                        this .setShipmentMethodTypeId(carrierShipmentMethod
2617:                                .getString("shipmentMethodTypeId"));
2618:                        this .setCarrierPartyId(carrierShipmentMethod
2619:                                .getString("partyId"));
2620:                    }
2621:                } else {
2622:                    // checkout options for purchase orders
2623:                    // TODO: should we select a default agreement? For now we don't do this.
2624:                    // skip the order terms selection step
2625:                    this .setOrderTermSet(true);
2626:                    // set as the default shipping location the first from the list of available shipping locations
2627:                    String companyId = this .getBillToCustomerPartyId();
2628:                    if (companyId != null) {
2629:                        // the facilityId should be set prior to triggering default options, otherwise we do not set up facility information
2630:                        String defaultFacilityId = getFacilityId();
2631:                        if (defaultFacilityId != null) {
2632:                            List facilityContactMechValueMaps = ContactMechWorker
2633:                                    .getFacilityContactMechValueMaps(delegator,
2634:                                            defaultFacilityId, false, null);
2635:                            if (facilityContactMechValueMaps != null) {
2636:                                Iterator facilityContactMechValueMapsIt = facilityContactMechValueMaps
2637:                                        .iterator();
2638:                                while (facilityContactMechValueMapsIt.hasNext()) {
2639:                                    Map facilityContactMechValueMap = (Map) facilityContactMechValueMapsIt
2640:                                            .next();
2641:                                    if (facilityContactMechValueMap
2642:                                            .get("postalAddress") != null) {
2643:                                        GenericValue postalAddress = (GenericValue) facilityContactMechValueMap
2644:                                                .get("postalAddress");
2645:                                        this 
2646:                                                .setShippingContactMechId(
2647:                                                        0,
2648:                                                        postalAddress
2649:                                                                .getString("contactMechId"));
2650:                                        break;
2651:                                    }
2652:                                }
2653:                            }
2654:                        }
2655:                    }
2656:                    // shipping options
2657:                    this .setShipmentMethodTypeId(0, "NO_SHIPPING");
2658:                    this .setCarrierPartyId(0, "_NA_");
2659:                    this .setShippingInstructions(0, "");
2660:                    this .setGiftMessage(0, "");
2661:                    this .setMaySplit(0, Boolean.TRUE);
2662:                    this .setIsGift(0, Boolean.FALSE);
2663:                    //this.setInternalCode(internalCode);
2664:                }
2665:            }
2666:
2667:            // Returns the tax amount for a ship group. */
2668:            public double getTotalSalesTax(int shipGroup) {
2669:                CartShipInfo csi = this .getShipInfo(shipGroup);
2670:                return csi.getTotalTax(this );
2671:            }
2672:
2673:            /** Returns the tax amount from the cart object. */
2674:            public double getTotalSalesTax() {
2675:                BigDecimal totalTax = ZERO;
2676:                for (int i = 0; i < shipInfo.size(); i++) {
2677:                    CartShipInfo csi = this .getShipInfo(i);
2678:                    totalTax = totalTax.add(
2679:                            new BigDecimal(csi.getTotalTax(this ))).setScale(
2680:                            taxCalcScale, taxRounding);
2681:                }
2682:                return totalTax.setScale(taxFinalScale, taxRounding)
2683:                        .doubleValue();
2684:            }
2685:
2686:            /** Returns the shipping amount from the cart object. */
2687:            public double getTotalShipping() {
2688:                double tempShipping = 0.0;
2689:
2690:                Iterator shipIter = this .shipInfo.iterator();
2691:                while (shipIter.hasNext()) {
2692:                    CartShipInfo csi = (CartShipInfo) shipIter.next();
2693:                    tempShipping += csi.shipEstimate;
2694:
2695:                }
2696:
2697:                return tempShipping;
2698:            }
2699:
2700:            /** Returns the item-total in the cart (not including discount/tax/shipping). */
2701:            public double getItemTotal() {
2702:                double itemTotal = 0.00;
2703:                Iterator i = iterator();
2704:
2705:                while (i.hasNext()) {
2706:                    itemTotal += ((ShoppingCartItem) i.next()).getBasePrice();
2707:                }
2708:                return itemTotal;
2709:            }
2710:
2711:            /** Returns the sub-total in the cart (item-total - discount). */
2712:            public double getSubTotal() {
2713:                double itemsTotal = 0.00;
2714:                Iterator i = iterator();
2715:
2716:                while (i.hasNext()) {
2717:                    itemsTotal += ((ShoppingCartItem) i.next())
2718:                            .getItemSubTotal();
2719:                }
2720:                return itemsTotal;
2721:            }
2722:
2723:            /** Returns the total from the cart, including tax/shipping. */
2724:            public double getGrandTotal() {
2725:                // sales tax and shipping are not stored as adjustments but rather as part of the ship group
2726:                // Debug.logInfo("Subtotal:" + this.getSubTotal() + " Shipping:" + this.getTotalShipping() + "SalesTax: "+ this.getTotalSalesTax() + " others: " + this.getOrderOtherAdjustmentTotal(),module);
2727:                return this .getSubTotal() + this .getTotalShipping()
2728:                        + this .getTotalSalesTax()
2729:                        + this .getOrderOtherAdjustmentTotal();
2730:            }
2731:
2732:            public double getDisplaySubTotal() {
2733:                double itemsTotal = 0.00;
2734:                Iterator i = iterator();
2735:                while (i.hasNext()) {
2736:                    itemsTotal += ((ShoppingCartItem) i.next())
2737:                            .getDisplayItemSubTotal();
2738:                }
2739:                return itemsTotal;
2740:            }
2741:
2742:            public double getDisplayRecurringSubTotal() {
2743:                double itemsTotal = 0.00;
2744:                Iterator i = iterator();
2745:                while (i.hasNext()) {
2746:                    itemsTotal += ((ShoppingCartItem) i.next())
2747:                            .getDisplayItemRecurringSubTotal();
2748:                }
2749:                return itemsTotal;
2750:            }
2751:
2752:            /** Returns the total from the cart, including tax/shipping. */
2753:            public double getDisplayGrandTotal() {
2754:                return this .getDisplaySubTotal() + this .getTotalShipping()
2755:                        + this .getTotalSalesTax()
2756:                        + this .getOrderOtherAdjustmentTotal();
2757:            }
2758:
2759:            public double getOrderOtherAdjustmentTotal() {
2760:                return OrderReadHelper.calcOrderAdjustmentsBd(
2761:                        this .getAdjustments(),
2762:                        new BigDecimal(this .getSubTotal()), true, false, false)
2763:                        .doubleValue();
2764:            }
2765:
2766:            /** Returns the sub-total in the cart (item-total - discount). */
2767:            public double getSubTotalForPromotions() {
2768:                double itemsTotal = 0.00;
2769:                Iterator i = iterator();
2770:
2771:                while (i.hasNext()) {
2772:                    ShoppingCartItem cartItem = (ShoppingCartItem) i.next();
2773:                    GenericValue product = cartItem.getProduct();
2774:                    if (product != null
2775:                            && "N".equals(product
2776:                                    .getString("includeInPromotions"))) {
2777:                        // don't include in total if this is the case...
2778:                        continue;
2779:                    }
2780:                    itemsTotal += cartItem.getItemSubTotal();
2781:                }
2782:                return itemsTotal;
2783:            }
2784:
2785:            /**
2786:             * Get the total payment amount by payment type.  Specify null to get amount
2787:             * over all types.
2788:             */
2789:            public double getOrderPaymentPreferenceTotalByType(
2790:                    String paymentMethodTypeId) {
2791:                double total = 0.0;
2792:                String this PaymentMethodTypeId = null;
2793:                for (Iterator iter = paymentInfo.iterator(); iter.hasNext();) {
2794:                    CartPaymentInfo payment = (CartPaymentInfo) iter.next();
2795:                    if (payment.amount == null)
2796:                        continue;
2797:                    if (payment.paymentMethodId != null) {
2798:                        try {
2799:                            // need to determine the payment method type from the payment method
2800:                            GenericValue paymentMethod = this .getDelegator()
2801:                                    .findByPrimaryKeyCache(
2802:                                            "PaymentMethod",
2803:                                            UtilMisc.toMap("paymentMethodId",
2804:                                                    payment.paymentMethodId));
2805:                            if (paymentMethod != null) {
2806:                                this PaymentMethodTypeId = paymentMethod
2807:                                        .getString("paymentMethodTypeId");
2808:                            }
2809:                        } catch (GenericEntityException e) {
2810:                            Debug.logError(e, e.getMessage(), module);
2811:                        }
2812:                    } else {
2813:                        this PaymentMethodTypeId = payment.paymentMethodTypeId;
2814:                    }
2815:
2816:                    // add the amount according to paymentMethodType
2817:                    if (paymentMethodTypeId == null
2818:                            || paymentMethodTypeId
2819:                                    .equals(this PaymentMethodTypeId)) {
2820:                        total += payment.amount.doubleValue();
2821:                    }
2822:                }
2823:                return total;
2824:            }
2825:
2826:            public double getCreditCardPaymentPreferenceTotal() {
2827:                return getOrderPaymentPreferenceTotalByType("CREDIT_CARD");
2828:            }
2829:
2830:            public double getBillingAccountPaymentPreferenceTotal() {
2831:                return getOrderPaymentPreferenceTotalByType("EXT_BILLACT");
2832:            }
2833:
2834:            public double getGiftCardPaymentPreferenceTotal() {
2835:                return getOrderPaymentPreferenceTotalByType("GIFT_CARD");
2836:            }
2837:
2838:            /** Add a contact mech to this purpose; the contactMechPurposeTypeId is required */
2839:            public void addContactMech(String contactMechPurposeTypeId,
2840:                    String contactMechId) {
2841:                if (contactMechPurposeTypeId == null)
2842:                    throw new IllegalArgumentException(
2843:                            "You must specify a contactMechPurposeTypeId to add a ContactMech");
2844:                contactMechIdsMap.put(contactMechPurposeTypeId, contactMechId);
2845:            }
2846:
2847:            /** Get the contactMechId for this cart given the contactMechPurposeTypeId */
2848:            public String getContactMech(String contactMechPurposeTypeId) {
2849:                return (String) contactMechIdsMap.get(contactMechPurposeTypeId);
2850:            }
2851:
2852:            /** Remove the contactMechId from this cart given the contactMechPurposeTypeId */
2853:            public String removeContactMech(String contactMechPurposeTypeId) {
2854:                return (String) contactMechIdsMap
2855:                        .remove(contactMechPurposeTypeId);
2856:            }
2857:
2858:            public Map getOrderContactMechIds() {
2859:                return this .contactMechIdsMap;
2860:            }
2861:
2862:            /** Get a List of adjustments on the order (ie cart) */
2863:            public List getAdjustments() {
2864:                return adjustments;
2865:            }
2866:
2867:            /** 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 */
2868:            public int addAdjustment(GenericValue adjustment) {
2869:                adjustments.add(adjustment);
2870:                return adjustments.indexOf(adjustment);
2871:            }
2872:
2873:            public void removeAdjustment(int index) {
2874:                adjustments.remove(index);
2875:            }
2876:
2877:            /** Get a List of orderTerms on the order (ie cart) */
2878:            public List getOrderTerms() {
2879:                return orderTerms;
2880:            }
2881:
2882:            /** Add an orderTerm to the order */
2883:            public int addOrderTerm(String termTypeId, Double termValue,
2884:                    Long termDays) {
2885:                return addOrderTerm(termTypeId, termValue, termDays, null);
2886:            }
2887:
2888:            /** Add an orderTerm to the order */
2889:            public int addOrderTerm(String termTypeId, Double termValue,
2890:                    Long termDays, String description) {
2891:                GenericValue orderTerm = GenericValue.create(delegator
2892:                        .getModelEntity("OrderTerm"));
2893:                orderTerm.put("termTypeId", termTypeId);
2894:                orderTerm.put("termValue", termValue);
2895:                orderTerm.put("termDays", termDays);
2896:                orderTerm.put("description", description);
2897:                return addOrderTerm(orderTerm);
2898:            }
2899:
2900:            /** Add an orderTerm to the order */
2901:            public int addOrderTerm(GenericValue orderTerm) {
2902:                orderTerms.add(orderTerm);
2903:                return orderTerms.indexOf(orderTerm);
2904:            }
2905:
2906:            public void removeOrderTerm(int index) {
2907:                orderTerms.remove(index);
2908:            }
2909:
2910:            public void removeOrderTerms() {
2911:                orderTerms.clear();
2912:            }
2913:
2914:            public boolean isOrderTermSet() {
2915:                return orderTermSet;
2916:            }
2917:
2918:            public void setOrderTermSet(boolean orderTermSet) {
2919:                this .orderTermSet = orderTermSet;
2920:            }
2921:
2922:            public boolean isReadOnlyCart() {
2923:                return readOnlyCart;
2924:            }
2925:
2926:            public void setReadOnlyCart(boolean readOnlyCart) {
2927:                this .readOnlyCart = readOnlyCart;
2928:            }
2929:
2930:            /** go through the order adjustments and remove all adjustments with the given type */
2931:            public void removeAdjustmentByType(String orderAdjustmentTypeId) {
2932:                if (orderAdjustmentTypeId == null)
2933:                    return;
2934:
2935:                // make a list of adjustment lists including the cart adjustments and the cartItem adjustments for each item
2936:                List adjsLists = new LinkedList();
2937:
2938:                if (this .getAdjustments() != null) {
2939:                    adjsLists.add(this .getAdjustments());
2940:                }
2941:                Iterator cartIterator = this .iterator();
2942:
2943:                while (cartIterator.hasNext()) {
2944:                    ShoppingCartItem item = (ShoppingCartItem) cartIterator
2945:                            .next();
2946:
2947:                    if (item.getAdjustments() != null) {
2948:                        adjsLists.add(item.getAdjustments());
2949:                    }
2950:                }
2951:
2952:                Iterator adjsListsIter = adjsLists.iterator();
2953:
2954:                while (adjsListsIter.hasNext()) {
2955:                    List adjs = (List) adjsListsIter.next();
2956:
2957:                    if (adjs != null) {
2958:                        for (int i = 0; i < adjs.size();) {
2959:                            GenericValue orderAdjustment = (GenericValue) adjs
2960:                                    .get(i);
2961:
2962:                            if (orderAdjustmentTypeId.equals(orderAdjustment
2963:                                    .getString("orderAdjustmentTypeId"))) {
2964:                                adjs.remove(i);
2965:                            } else {
2966:                                i++;
2967:                            }
2968:                        }
2969:                    }
2970:                }
2971:            }
2972:
2973:            /** Returns the total weight in the cart. */
2974:            public double getTotalWeight() {
2975:                double weight = 0.0;
2976:                Iterator i = iterator();
2977:
2978:                while (i.hasNext()) {
2979:                    ShoppingCartItem item = (ShoppingCartItem) i.next();
2980:
2981:                    weight += (item.getWeight() * item.getQuantity());
2982:                }
2983:                return weight;
2984:            }
2985:
2986:            /** Returns the total quantity in the cart. */
2987:            public double getTotalQuantity() {
2988:                double count = 0.0;
2989:                Iterator i = iterator();
2990:
2991:                while (i.hasNext()) {
2992:                    count += ((ShoppingCartItem) i.next()).getQuantity();
2993:                }
2994:                return count;
2995:            }
2996:
2997:            /** Returns the SHIPPABLE item-total in the cart for a specific ship group. */
2998:            public double getShippableTotal(int idx) {
2999:                CartShipInfo info = this .getShipInfo(idx);
3000:                double itemTotal = 0.0;
3001:
3002:                Iterator i = info.shipItemInfo.keySet().iterator();
3003:                while (i.hasNext()) {
3004:                    ShoppingCartItem item = (ShoppingCartItem) i.next();
3005:                    CartShipInfo.CartShipItemInfo csii = (CartShipInfo.CartShipItemInfo) info.shipItemInfo
3006:                            .get(item);
3007:                    if (csii != null && csii.quantity > 0) {
3008:                        if (item.shippingApplies()) {
3009:                            itemTotal += item.getItemSubTotal(csii.quantity);
3010:                        }
3011:                    }
3012:                }
3013:
3014:                return itemTotal;
3015:            }
3016:
3017:            /** Returns the total SHIPPABLE quantity in the cart for a specific ship group. */
3018:            public double getShippableQuantity(int idx) {
3019:                CartShipInfo info = this .getShipInfo(idx);
3020:                double count = 0.0;
3021:
3022:                Iterator i = info.shipItemInfo.keySet().iterator();
3023:                while (i.hasNext()) {
3024:                    ShoppingCartItem item = (ShoppingCartItem) i.next();
3025:                    CartShipInfo.CartShipItemInfo csii = (CartShipInfo.CartShipItemInfo) info.shipItemInfo
3026:                            .get(item);
3027:                    if (csii != null && csii.quantity > 0) {
3028:                        if (item.shippingApplies()) {
3029:                            count += csii.quantity;
3030:                        }
3031:                    }
3032:                }
3033:
3034:                return count;
3035:            }
3036:
3037:            /** Returns the total SHIPPABLE weight in the cart for a specific ship group. */
3038:            public double getShippableWeight(int idx) {
3039:                CartShipInfo info = this .getShipInfo(idx);
3040:                double weight = 0.0;
3041:
3042:                Iterator i = info.shipItemInfo.keySet().iterator();
3043:                while (i.hasNext()) {
3044:                    ShoppingCartItem item = (ShoppingCartItem) i.next();
3045:                    CartShipInfo.CartShipItemInfo csii = (CartShipInfo.CartShipItemInfo) info.shipItemInfo
3046:                            .get(item);
3047:                    if (csii != null && csii.quantity > 0) {
3048:                        if (item.shippingApplies()) {
3049:                            weight += (item.getWeight() * csii.quantity);
3050:                        }
3051:                    }
3052:                }
3053:
3054:                return weight;
3055:            }
3056:
3057:            /** Returns a List of shippable item's size for a specific ship group. */
3058:            public List getShippableSizes(int idx) {
3059:                CartShipInfo info = this .getShipInfo(idx);
3060:                List shippableSizes = new LinkedList();
3061:
3062:                Iterator i = info.shipItemInfo.keySet().iterator();
3063:                while (i.hasNext()) {
3064:                    ShoppingCartItem item = (ShoppingCartItem) i.next();
3065:                    CartShipInfo.CartShipItemInfo csii = (CartShipInfo.CartShipItemInfo) info.shipItemInfo
3066:                            .get(item);
3067:                    if (csii != null && csii.quantity > 0) {
3068:                        if (item.shippingApplies()) {
3069:                            shippableSizes.add(new Double(item.getSize()));
3070:                        }
3071:                    }
3072:                }
3073:
3074:                return shippableSizes;
3075:            }
3076:
3077:            /** Returns a List of shippable item info (quantity, size, weight) for a specific ship group */
3078:            public List getShippableItemInfo(int idx) {
3079:                CartShipInfo info = this .getShipInfo(idx);
3080:                List itemInfos = new LinkedList();
3081:
3082:                Iterator i = info.shipItemInfo.keySet().iterator();
3083:                while (i.hasNext()) {
3084:                    ShoppingCartItem item = (ShoppingCartItem) i.next();
3085:                    CartShipInfo.CartShipItemInfo csii = (CartShipInfo.CartShipItemInfo) info.shipItemInfo
3086:                            .get(item);
3087:                    if (csii != null && csii.quantity > 0) {
3088:                        if (item.shippingApplies()) {
3089:                            Map itemInfo = item.getItemProductInfo();
3090:                            itemInfo.put("quantity", new Double(csii.quantity));
3091:                            itemInfos.add(itemInfo);
3092:                        }
3093:                    }
3094:                }
3095:
3096:                return itemInfos;
3097:            }
3098:
3099:            /** Returns true when there are shippable items in the cart */
3100:            public boolean shippingApplies() {
3101:                boolean shippingApplies = false;
3102:                Iterator i = this .iterator();
3103:                while (i.hasNext()) {
3104:                    ShoppingCartItem item = (ShoppingCartItem) i.next();
3105:                    if (item.shippingApplies()) {
3106:                        shippingApplies = true;
3107:                        break;
3108:                    }
3109:                }
3110:                return shippingApplies;
3111:            }
3112:
3113:            /** Returns true when there are taxable items in the cart */
3114:            public boolean taxApplies() {
3115:                boolean taxApplies = false;
3116:                Iterator i = this .iterator();
3117:                while (i.hasNext()) {
3118:                    ShoppingCartItem item = (ShoppingCartItem) i.next();
3119:                    if (item.taxApplies()) {
3120:                        taxApplies = true;
3121:                        break;
3122:                    }
3123:                }
3124:                return taxApplies;
3125:            }
3126:
3127:            /** Returns a Map of all features applied to products in the cart with quantities for a specific ship group. */
3128:            public Map getFeatureIdQtyMap(int idx) {
3129:                CartShipInfo info = this .getShipInfo(idx);
3130:                Map featureMap = new HashMap();
3131:
3132:                Iterator i = info.shipItemInfo.keySet().iterator();
3133:                while (i.hasNext()) {
3134:                    ShoppingCartItem item = (ShoppingCartItem) i.next();
3135:                    CartShipInfo.CartShipItemInfo csii = (CartShipInfo.CartShipItemInfo) info.shipItemInfo
3136:                            .get(item);
3137:                    if (csii != null && csii.quantity > 0) {
3138:                        featureMap.putAll(item
3139:                                .getFeatureIdQtyMap(csii.quantity));
3140:                    }
3141:                }
3142:
3143:                return featureMap;
3144:            }
3145:
3146:            /** Returns true if the user wishes to view the cart everytime an item is added. */
3147:            public boolean viewCartOnAdd() {
3148:                return viewCartOnAdd;
3149:            }
3150:
3151:            /** Returns true if the user wishes to view the cart everytime an item is added. */
3152:            public void setViewCartOnAdd(boolean viewCartOnAdd) {
3153:                this .viewCartOnAdd = viewCartOnAdd;
3154:            }
3155:
3156:            /** Returns the order ID associated with this cart or null if no order has been created yet. */
3157:            public String getOrderId() {
3158:                return this .orderId;
3159:            }
3160:
3161:            /** Returns the first attempt order ID associated with this cart or null if no order has been created yet. */
3162:            public String getFirstAttemptOrderId() {
3163:                return this .firstAttemptOrderId;
3164:            }
3165:
3166:            /** Sets the orderId associated with this cart. */
3167:            public void setOrderId(String orderId) {
3168:                this .orderId = orderId;
3169:            }
3170:
3171:            public void setNextItemSeq(long seq) throws GeneralException {
3172:                if (this .nextItemSeq != 1) {
3173:                    throw new GeneralException(
3174:                            "Cannot set the item sequence once the sequence has been incremented!");
3175:                } else {
3176:                    this .nextItemSeq = seq;
3177:                }
3178:            }
3179:
3180:            /** TODO: Sets the first attempt orderId for this cart. */
3181:            public void setFirstAttemptOrderId(String orderId) {
3182:                this .firstAttemptOrderId = orderId;
3183:            }
3184:
3185:            public void removeAllFreeShippingProductPromoActions() {
3186:                this .freeShippingProductPromoActions.clear();
3187:            }
3188:
3189:            /** Removes a free shipping ProductPromoAction by trying to find one in the list with the same primary key. */
3190:            public void removeFreeShippingProductPromoAction(
3191:                    GenericPK productPromoActionPK) {
3192:                if (productPromoActionPK == null)
3193:                    return;
3194:
3195:                Iterator fsppas = this .freeShippingProductPromoActions
3196:                        .iterator();
3197:                while (fsppas.hasNext()) {
3198:                    if (productPromoActionPK.equals(((GenericValue) fsppas
3199:                            .next()).getPrimaryKey())) {
3200:                        fsppas.remove();
3201:                    }
3202:                }
3203:            }
3204:
3205:            /** Adds a ProductPromoAction to be used for free shipping (must be of type free shipping, or nothing will be done). */
3206:            public void addFreeShippingProductPromoAction(
3207:                    GenericValue productPromoAction) {
3208:                if (productPromoAction == null)
3209:                    return;
3210:                // is this a free shipping action?
3211:                if (!"PROMO_FREE_SHIPPING".equals(productPromoAction
3212:                        .getString("productPromoActionEnumId")))
3213:                    return; // Changed 1-5-04 by Si Chen
3214:
3215:                // to easily make sure that no duplicate exists, do a remove first
3216:                this .removeFreeShippingProductPromoAction(productPromoAction
3217:                        .getPrimaryKey());
3218:                this .freeShippingProductPromoActions.add(productPromoAction);
3219:            }
3220:
3221:            public List getFreeShippingProductPromoActions() {
3222:                return this .freeShippingProductPromoActions;
3223:            }
3224:
3225:            public void removeAllDesiredAlternateGiftByActions() {
3226:                this .desiredAlternateGiftByAction.clear();
3227:            }
3228:
3229:            public void setDesiredAlternateGiftByAction(
3230:                    GenericPK productPromoActionPK, String productId) {
3231:                this .desiredAlternateGiftByAction.put(productPromoActionPK,
3232:                        productId);
3233:            }
3234:
3235:            public String getDesiredAlternateGiftByAction(
3236:                    GenericPK productPromoActionPK) {
3237:                return (String) this .desiredAlternateGiftByAction
3238:                        .get(productPromoActionPK);
3239:            }
3240:
3241:            public Map getAllDesiredAlternateGiftByActionCopy() {
3242:                return new HashMap(this .desiredAlternateGiftByAction);
3243:            }
3244:
3245:            public void addProductPromoUse(String productPromoId,
3246:                    String productPromoCodeId, double totalDiscountAmount,
3247:                    double quantityLeftInActions) {
3248:                if (UtilValidate.isNotEmpty(productPromoCodeId)
3249:                        && !this .productPromoCodes.contains(productPromoCodeId)) {
3250:                    throw new IllegalStateException(
3251:                            "Cannot add a use to a promo code use for a code that has not been entered.");
3252:                }
3253:                if (Debug.verboseOn())
3254:                    Debug.logVerbose("Used promotion [" + productPromoId
3255:                            + "] with code [" + productPromoCodeId
3256:                            + "] for total discount [" + totalDiscountAmount
3257:                            + "] and quantity left in actions ["
3258:                            + quantityLeftInActions + "]", module);
3259:                this .productPromoUseInfoList.add(new ProductPromoUseInfo(
3260:                        productPromoId, productPromoCodeId,
3261:                        totalDiscountAmount, quantityLeftInActions));
3262:            }
3263:
3264:            public void clearProductPromoUseInfo() {
3265:                // clear out info for general promo use
3266:                this .productPromoUseInfoList.clear();
3267:            }
3268:
3269:            public void clearCartItemUseInPromoInfo() {
3270:                // clear out info about which cart items have been used in promos
3271:                Iterator cartLineIter = this .iterator();
3272:                while (cartLineIter.hasNext()) {
3273:                    ShoppingCartItem cartLine = (ShoppingCartItem) cartLineIter
3274:                            .next();
3275:                    cartLine.clearPromoRuleUseInfo();
3276:                }
3277:            }
3278:
3279:            public Iterator getProductPromoUseInfoIter() {
3280:                return productPromoUseInfoList.iterator();
3281:            }
3282:
3283:            public double getProductPromoUseTotalDiscount(String productPromoId) {
3284:                if (productPromoId == null)
3285:                    return 0;
3286:                double totalDiscount = 0;
3287:                Iterator productPromoUseInfoIter = this .productPromoUseInfoList
3288:                        .iterator();
3289:                while (productPromoUseInfoIter.hasNext()) {
3290:                    ProductPromoUseInfo productPromoUseInfo = (ProductPromoUseInfo) productPromoUseInfoIter
3291:                            .next();
3292:                    if (productPromoId
3293:                            .equals(productPromoUseInfo.productPromoId)) {
3294:                        totalDiscount += productPromoUseInfo
3295:                                .getTotalDiscountAmount();
3296:                    }
3297:                }
3298:                return totalDiscount;
3299:            }
3300:
3301:            public int getProductPromoUseCount(String productPromoId) {
3302:                if (productPromoId == null)
3303:                    return 0;
3304:                int useCount = 0;
3305:                Iterator productPromoUseInfoIter = this .productPromoUseInfoList
3306:                        .iterator();
3307:                while (productPromoUseInfoIter.hasNext()) {
3308:                    ProductPromoUseInfo productPromoUseInfo = (ProductPromoUseInfo) productPromoUseInfoIter
3309:                            .next();
3310:                    if (productPromoId
3311:                            .equals(productPromoUseInfo.productPromoId)) {
3312:                        useCount++;
3313:                    }
3314:                }
3315:                return useCount;
3316:            }
3317:
3318:            public int getProductPromoCodeUse(String productPromoCodeId) {
3319:                if (productPromoCodeId == null)
3320:                    return 0;
3321:                int useCount = 0;
3322:                Iterator productPromoUseInfoIter = this .productPromoUseInfoList
3323:                        .iterator();
3324:                while (productPromoUseInfoIter.hasNext()) {
3325:                    ProductPromoUseInfo productPromoUseInfo = (ProductPromoUseInfo) productPromoUseInfoIter
3326:                            .next();
3327:                    if (productPromoCodeId
3328:                            .equals(productPromoUseInfo.productPromoCodeId)) {
3329:                        useCount++;
3330:                    }
3331:                }
3332:                return useCount;
3333:            }
3334:
3335:            public void clearAllPromotionInformation() {
3336:                this .clearAllPromotionAdjustments();
3337:
3338:                // remove all free shipping promo actions
3339:                this .removeAllFreeShippingProductPromoActions();
3340:
3341:                // clear promo uses & reset promo code uses, and reset info about cart items used for promos (ie qualifiers and benefiters)
3342:                this .clearProductPromoUseInfo();
3343:                this .clearCartItemUseInPromoInfo();
3344:            }
3345:
3346:            public void clearAllPromotionAdjustments() {
3347:                // remove cart adjustments from promo actions
3348:                List cartAdjustments = this .getAdjustments();
3349:                if (cartAdjustments != null) {
3350:                    Iterator cartAdjustmentIter = cartAdjustments.iterator();
3351:                    while (cartAdjustmentIter.hasNext()) {
3352:                        GenericValue checkOrderAdjustment = (GenericValue) cartAdjustmentIter
3353:                                .next();
3354:                        if (UtilValidate.isNotEmpty(checkOrderAdjustment
3355:                                .getString("productPromoId"))
3356:                                && UtilValidate.isNotEmpty(checkOrderAdjustment
3357:                                        .getString("productPromoRuleId"))
3358:                                && UtilValidate.isNotEmpty(checkOrderAdjustment
3359:                                        .getString("productPromoActionSeqId"))) {
3360:                            cartAdjustmentIter.remove();
3361:                        }
3362:                    }
3363:                }
3364:
3365:                // remove cart lines that are promos (ie GWPs) and cart line adjustments from promo actions
3366:                Iterator cartItemIter = this .iterator();
3367:                while (cartItemIter.hasNext()) {
3368:                    ShoppingCartItem checkItem = (ShoppingCartItem) cartItemIter
3369:                            .next();
3370:                    if (checkItem.getIsPromo()) {
3371:                        this .clearItemShipInfo(checkItem);
3372:                        cartItemIter.remove();
3373:                    } else {
3374:                        // found a promo item with the productId, see if it has a matching adjustment on it
3375:                        Iterator checkOrderAdjustments = UtilMisc
3376:                                .toIterator(checkItem.getAdjustments());
3377:                        while (checkOrderAdjustments != null
3378:                                && checkOrderAdjustments.hasNext()) {
3379:                            GenericValue checkOrderAdjustment = (GenericValue) checkOrderAdjustments
3380:                                    .next();
3381:                            if (UtilValidate.isNotEmpty(checkOrderAdjustment
3382:                                    .getString("productPromoId"))
3383:                                    && UtilValidate
3384:                                            .isNotEmpty(checkOrderAdjustment
3385:                                                    .getString("productPromoRuleId"))
3386:                                    && UtilValidate
3387:                                            .isNotEmpty(checkOrderAdjustment
3388:                                                    .getString("productPromoActionSeqId"))) {
3389:                                checkOrderAdjustments.remove();
3390:                            }
3391:                        }
3392:                    }
3393:                }
3394:            }
3395:
3396:            public void clearAllAdjustments() {
3397:                // remove all the promotion information (including adjustments)
3398:                clearAllPromotionInformation();
3399:                // remove all cart adjustments
3400:                this .adjustments.clear();
3401:                // remove all cart item adjustments
3402:                Iterator cartItemIter = this .iterator();
3403:                while (cartItemIter.hasNext()) {
3404:                    ShoppingCartItem checkItem = (ShoppingCartItem) cartItemIter
3405:                            .next();
3406:                    checkItem.getAdjustments().clear();
3407:                }
3408:            }
3409:
3410:            public void clearAllItemStatus() {
3411:                Iterator lineIter = this .iterator();
3412:                while (lineIter.hasNext()) {
3413:                    ShoppingCartItem item = (ShoppingCartItem) lineIter.next();
3414:                    item.setStatusId(null);
3415:                }
3416:            }
3417:
3418:            /** 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
3419:             * @param productPromoCodeId The promotion code to check and add
3420:             * @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.
3421:             */
3422:            public String addProductPromoCode(String productPromoCodeId,
3423:                    LocalDispatcher dispatcher) {
3424:                if (this .productPromoCodes.contains(productPromoCodeId)) {
3425:                    return "The promotion code [" + productPromoCodeId
3426:                            + "] has already been entered.";
3427:                }
3428:                // if the promo code requires it make sure the code is valid
3429:                String checkResult = ProductPromoWorker.checkCanUsePromoCode(
3430:                        productPromoCodeId, this .getPartyId(), this 
3431:                                .getDelegator());
3432:                if (checkResult == null) {
3433:                    this .productPromoCodes.add(productPromoCodeId);
3434:                    // new promo code, re-evaluate promos
3435:                    ProductPromoWorker.doPromotions(this , dispatcher);
3436:                    return null;
3437:                } else {
3438:                    return checkResult;
3439:                }
3440:            }
3441:
3442:            public Set getProductPromoCodesEntered() {
3443:                return this .productPromoCodes;
3444:            }
3445:
3446:            public synchronized void resetPromoRuleUse(String productPromoId,
3447:                    String productPromoRuleId) {
3448:                Iterator lineIter = this .iterator();
3449:                while (lineIter.hasNext()) {
3450:                    ShoppingCartItem cartItem = (ShoppingCartItem) lineIter
3451:                            .next();
3452:                    cartItem.resetPromoRuleUse(productPromoId,
3453:                            productPromoRuleId);
3454:                }
3455:            }
3456:
3457:            public synchronized void confirmPromoRuleUse(String productPromoId,
3458:                    String productPromoRuleId) {
3459:                Iterator lineIter = this .iterator();
3460:                while (lineIter.hasNext()) {
3461:                    ShoppingCartItem cartItem = (ShoppingCartItem) lineIter
3462:                            .next();
3463:                    cartItem.confirmPromoRuleUse(productPromoId,
3464:                            productPromoRuleId);
3465:                }
3466:            }
3467:
3468:            /**
3469:             * Associates a party with a role to the order.
3470:             * @param partyId identifier of the party to associate to order
3471:             * @param roleTypeId identifier of the role used in party-order association
3472:             */
3473:            public void addAdditionalPartyRole(String partyId, String roleTypeId) {
3474:                // search if there is an existing entry
3475:                List parties = (List) additionalPartyRole.get(roleTypeId);
3476:                if (parties != null) {
3477:                    Iterator it = parties.iterator();
3478:                    while (it.hasNext()) {
3479:                        if (((String) it.next()).equals(partyId)) {
3480:                            return;
3481:                        }
3482:                    }
3483:                } else {
3484:                    parties = new LinkedList();
3485:                    additionalPartyRole.put(roleTypeId, parties);
3486:                }
3487:
3488:                parties.add(0, partyId);
3489:            }
3490:
3491:            /**
3492:             * Removes a previously associated party to the order.
3493:             * @param partyId identifier of the party to associate to order
3494:             * @param roleTypeId identifier of the role used in party-order association
3495:             */
3496:            public void removeAdditionalPartyRole(String partyId,
3497:                    String roleTypeId) {
3498:                List parties = (List) additionalPartyRole.get(roleTypeId);
3499:
3500:                if (parties != null) {
3501:                    Iterator it = parties.iterator();
3502:                    while (it.hasNext()) {
3503:                        if (((String) it.next()).equals(partyId)) {
3504:                            it.remove();
3505:
3506:                            if (parties.isEmpty()) {
3507:                                additionalPartyRole.remove(roleTypeId);
3508:                            }
3509:                            return;
3510:                        }
3511:                    }
3512:                }
3513:            }
3514:
3515:            public Map getAdditionalPartyRoleMap() {
3516:                return additionalPartyRole;
3517:            }
3518:
3519:            // =======================================================================
3520:            // Methods used for order creation
3521:            // =======================================================================
3522:
3523:            public List makeOrderItemGroups() {
3524:                List result = FastList.newInstance();
3525:                Iterator groupValueIter = this .itemGroupByNumberMap.values()
3526:                        .iterator();
3527:                while (groupValueIter.hasNext()) {
3528:                    ShoppingCart.ShoppingCartItemGroup itemGroup = (ShoppingCart.ShoppingCartItemGroup) groupValueIter
3529:                            .next();
3530:                    result.add(itemGroup
3531:                            .makeOrderItemGroup(this .getDelegator()));
3532:                }
3533:                return result;
3534:            }
3535:
3536:            private void explodeItems(LocalDispatcher dispatcher) {
3537:                if (dispatcher == null)
3538:                    return;
3539:                synchronized (cartLines) {
3540:                    List cartLineItems = new LinkedList(cartLines);
3541:                    Iterator itemIter = cartLineItems.iterator();
3542:
3543:                    while (itemIter.hasNext()) {
3544:                        ShoppingCartItem item = (ShoppingCartItem) itemIter
3545:                                .next();
3546:
3547:                        //Debug.logInfo("Item qty: " + item.getQuantity(), module);
3548:                        try {
3549:                            item.explodeItem(this , dispatcher);
3550:                        } catch (CartItemModifyException e) {
3551:                            Debug
3552:                                    .logError(
3553:                                            e,
3554:                                            "Problem exploding item! Item not exploded.",
3555:                                            module);
3556:                        }
3557:                    }
3558:                }
3559:            }
3560:
3561:            /**
3562:             * Does an "explode", or "unitize" operation on a list of cart items.
3563:             * Resulting state for each item with quantity X is X items of quantity 1.
3564:             * 
3565:             * @param shoppingCartItems
3566:             * @param dispatcher
3567:             */
3568:            public void explodeItems(List shoppingCartItems,
3569:                    LocalDispatcher dispatcher) {
3570:                if (dispatcher == null)
3571:                    return;
3572:                synchronized (cartLines) {
3573:                    Iterator itemIter = shoppingCartItems.iterator();
3574:                    while (itemIter.hasNext()) {
3575:                        ShoppingCartItem item = (ShoppingCartItem) itemIter
3576:                                .next();
3577:
3578:                        //Debug.logInfo("Item qty: " + item.getQuantity(), module);
3579:                        try {
3580:                            item.explodeItem(this , dispatcher);
3581:                        } catch (CartItemModifyException e) {
3582:                            Debug
3583:                                    .logError(
3584:                                            e,
3585:                                            "Problem exploding (unitizing) item! Item not exploded.",
3586:                                            module);
3587:                        }
3588:                    }
3589:                }
3590:            }
3591:
3592:            public List makeOrderItems() {
3593:                return makeOrderItems(false, null);
3594:            }
3595:
3596:            public List makeOrderItems(boolean explodeItems,
3597:                    LocalDispatcher dispatcher) {
3598:                // do the explosion
3599:                if (explodeItems && dispatcher != null) {
3600:                    explodeItems(dispatcher);
3601:                }
3602:
3603:                // now build the lines
3604:                synchronized (cartLines) {
3605:                    List result = FastList.newInstance();
3606:
3607:                    Iterator itemIter = cartLines.iterator();
3608:                    while (itemIter.hasNext()) {
3609:                        ShoppingCartItem item = (ShoppingCartItem) itemIter
3610:                                .next();
3611:
3612:                        if (UtilValidate.isEmpty(item.getOrderItemSeqId())) {
3613:                            String orderItemSeqId = UtilFormatOut
3614:                                    .formatPaddedNumber(nextItemSeq, 5);
3615:                            item.setOrderItemSeqId(orderItemSeqId);
3616:                        } else {
3617:                            try {
3618:                                int this SeqId = Integer.parseInt(item
3619:                                        .getOrderItemSeqId());
3620:                                if (this SeqId > nextItemSeq) {
3621:                                    nextItemSeq = this SeqId;
3622:                                }
3623:                            } catch (NumberFormatException e) {
3624:                                Debug.logError(e, module);
3625:                            }
3626:                        }
3627:                        nextItemSeq++;
3628:
3629:                        // the initial status for all item types
3630:                        String initialStatus = "ITEM_CREATED";
3631:                        String status = item.getStatusId();
3632:                        if (status == null) {
3633:                            status = initialStatus;
3634:                        }
3635:
3636:                        GenericValue orderItem = getDelegator().makeValue(
3637:                                "OrderItem", null);
3638:                        orderItem.set("orderItemSeqId", item
3639:                                .getOrderItemSeqId());
3640:                        orderItem.set("externalId", item.getExternalId());
3641:                        orderItem.set("orderItemTypeId", item.getItemType());
3642:                        if (item.getItemGroup() != null)
3643:                            orderItem.set("orderItemGroupSeqId", item
3644:                                    .getItemGroup().getGroupNumber());
3645:                        orderItem.set("productId", item.getProductId());
3646:                        orderItem.set("prodCatalogId", item.getProdCatalogId());
3647:                        orderItem.set("productCategoryId", item
3648:                                .getProductCategoryId());
3649:                        orderItem.set("quantity",
3650:                                new Double(item.getQuantity()));
3651:                        orderItem.set("selectedAmount", new Double(item
3652:                                .getSelectedAmount()));
3653:                        orderItem.set("unitPrice", new Double(item
3654:                                .getBasePrice()));
3655:                        orderItem.set("unitListPrice", new Double(item
3656:                                .getListPrice()));
3657:                        orderItem.set("isModifiedPrice", item
3658:                                .getIsModifiedPrice() ? "Y" : "N");
3659:                        orderItem.set("isPromo", item.getIsPromo() ? "Y" : "N");
3660:
3661:                        orderItem.set("shoppingListId", item
3662:                                .getShoppingListId());
3663:                        orderItem.set("shoppingListItemSeqId", item
3664:                                .getShoppingListItemSeqId());
3665:
3666:                        orderItem.set("itemDescription", item.getName());
3667:                        orderItem.set("comments", item.getItemComment());
3668:                        orderItem.set("estimatedDeliveryDate", item
3669:                                .getDesiredDeliveryDate());
3670:                        orderItem.set("correspondingPoId", this .getPoNumber());
3671:                        orderItem.set("quoteId", item.getQuoteId());
3672:                        orderItem.set("quoteItemSeqId", item
3673:                                .getQuoteItemSeqId());
3674:                        orderItem.set("statusId", status);
3675:
3676:                        orderItem.set("shipBeforeDate", item
3677:                                .getShipBeforeDate());
3678:                        orderItem.set("shipAfterDate", item.getShipAfterDate());
3679:
3680:                        result.add(orderItem);
3681:                        // don't do anything with adjustments here, those will be added below in makeAllAdjustments
3682:                    }
3683:                    return result;
3684:                }
3685:            }
3686:
3687:            /** create WorkEfforts from the shoppingcart items when itemType = RENTAL_ORDER_ITEM */
3688:            public List makeWorkEfforts() {
3689:                List allWorkEfforts = new LinkedList();
3690:                Iterator itemIter = cartLines.iterator();
3691:
3692:                while (itemIter.hasNext()) {
3693:                    ShoppingCartItem item = (ShoppingCartItem) itemIter.next();
3694:                    if ("RENTAL_ORDER_ITEM".equals(item.getItemType())) { // prepare workeffort when the order item is a rental item
3695:                        GenericValue workEffort = getDelegator().makeValue(
3696:                                "WorkEffort", null);
3697:                        workEffort
3698:                                .set("workEffortId", item.getOrderItemSeqId()); // fill temporary with sequence number
3699:                        workEffort.set("estimatedStartDate", item
3700:                                .getReservStart());
3701:                        workEffort.set("estimatedCompletionDate", item
3702:                                .getReservStart(item.getReservLength()));
3703:                        workEffort.set("reservPersons", new Double(item
3704:                                .getReservPersons()));
3705:                        workEffort.set("reserv2ndPPPerc", new Double(item
3706:                                .getReserv2ndPPPerc()));
3707:                        workEffort.set("reservNthPPPerc", new Double(item
3708:                                .getReservNthPPPerc()));
3709:
3710:                        allWorkEfforts.add(workEffort);
3711:                    }
3712:                }
3713:                return allWorkEfforts;
3714:            }
3715:
3716:            /** make a list of all adjustments including order adjustments, order line adjustments, and special adjustments (shipping and tax if applicable) */
3717:            public List makeAllAdjustments() {
3718:                List allAdjs = new LinkedList();
3719:
3720:                // before returning adjustments, go through them to find all that need counter adjustments (for instance: free shipping)
3721:                Iterator allAdjsIter = this .getAdjustments().iterator();
3722:
3723:                while (allAdjsIter.hasNext()) {
3724:                    GenericValue orderAdjustment = (GenericValue) allAdjsIter
3725:                            .next();
3726:
3727:                    allAdjs.add(orderAdjustment);
3728:
3729:                    if ("SHIPPING_CHARGES".equals(orderAdjustment
3730:                            .get("orderAdjustmentTypeId"))) {
3731:                        Iterator fsppas = this .freeShippingProductPromoActions
3732:                                .iterator();
3733:
3734:                        while (fsppas.hasNext()) {
3735:                            GenericValue productPromoAction = (GenericValue) fsppas
3736:                                    .next();
3737:
3738:                            // TODO - we need to change the way free shipping promotions work
3739:                            /*
3740:                            if ((productPromoAction.get("productId") == null || productPromoAction.getString("productId").equals(this.getShipmentMethodTypeId())) &&
3741:                                (productPromoAction.get("partyId") == null || productPromoAction.getString("partyId").equals(this.getCarrierPartyId()))) {
3742:                                Double shippingAmount = new Double(-OrderReadHelper.calcOrderAdjustment(orderAdjustment, getSubTotal()));
3743:                                // always set orderAdjustmentTypeId to SHIPPING_CHARGES for free shipping adjustments
3744:                                GenericValue fsOrderAdjustment = getDelegator().makeValue("OrderAdjustment",
3745:                                        UtilMisc.toMap("orderItemSeqId", orderAdjustment.get("orderItemSeqId"), "orderAdjustmentTypeId", "SHIPPING_CHARGES", "amount", shippingAmount,
3746:                                            "productPromoId", productPromoAction.get("productPromoId"), "productPromoRuleId", productPromoAction.get("productPromoRuleId"),
3747:                                            "productPromoActionSeqId", productPromoAction.get("productPromoActionSeqId")));
3748:
3749:                                allAdjs.add(fsOrderAdjustment);
3750:
3751:                                // if free shipping IS applied to this orderAdjustment, break
3752:                                // out of the loop so that even if there are multiple free
3753:                                // shipping adjustments that apply to this orderAdjustment it
3754:                                // will only be compensated for once
3755:                                break;
3756:                            }
3757:                             */
3758:                        }
3759:                    }
3760:                }
3761:
3762:                // add all of the item adjustments to this list too
3763:                Iterator itemIter = cartLines.iterator();
3764:
3765:                while (itemIter.hasNext()) {
3766:                    ShoppingCartItem item = (ShoppingCartItem) itemIter.next();
3767:                    Collection adjs = item.getAdjustments();
3768:
3769:                    if (adjs != null) {
3770:                        Iterator adjIter = adjs.iterator();
3771:
3772:                        while (adjIter.hasNext()) {
3773:                            GenericValue orderAdjustment = (GenericValue) adjIter
3774:                                    .next();
3775:
3776:                            orderAdjustment.set("orderItemSeqId", item
3777:                                    .getOrderItemSeqId());
3778:                            allAdjs.add(orderAdjustment);
3779:
3780:                            if ("SHIPPING_CHARGES".equals(orderAdjustment
3781:                                    .get("orderAdjustmentTypeId"))) {
3782:                                Iterator fsppas = this .freeShippingProductPromoActions
3783:                                        .iterator();
3784:
3785:                                while (fsppas.hasNext()) {
3786:                                    GenericValue productPromoAction = (GenericValue) fsppas
3787:                                            .next();
3788:
3789:                                    // TODO - fix the free shipping promotions!!
3790:                                    /*
3791:                                    if ((productPromoAction.get("productId") == null || productPromoAction.getString("productId").equals(item.getShipmentMethodTypeId())) &&
3792:                                        (productPromoAction.get("partyId") == null || productPromoAction.getString("partyId").equals(item.getCarrierPartyId()))) {
3793:                                        Double shippingAmount = new Double(-OrderReadHelper.calcItemAdjustment(orderAdjustment, new Double(item.getQuantity()), new Double(item.getItemSubTotal())));
3794:                                        // always set orderAdjustmentTypeId to SHIPPING_CHARGES for free shipping adjustments
3795:                                        GenericValue fsOrderAdjustment = getDelegator().makeValue("OrderAdjustment",
3796:                                                UtilMisc.toMap("orderItemSeqId", orderAdjustment.get("orderItemSeqId"), "orderAdjustmentTypeId", "SHIPPING_CHARGES", "amount", shippingAmount,
3797:                                                    "productPromoId", productPromoAction.get("productPromoId"), "productPromoRuleId", productPromoAction.get("productPromoRuleId"),
3798:                                                    "productPromoActionSeqId", productPromoAction.get("productPromoActionSeqId")));
3799:
3800:                                        allAdjs.add(fsOrderAdjustment);
3801:
3802:                                        // if free shipping IS applied to this orderAdjustment, break
3803:                                        // out of the loop so that even if there are multiple free
3804:                                        // shipping adjustments that apply to this orderAdjustment it
3805:                                        // will only be compensated for once
3806:                                        break;
3807:                                    }
3808:                                     */
3809:                                }
3810:                            }
3811:                        }
3812:                    }
3813:                }
3814:
3815:                return allAdjs;
3816:            }
3817:
3818:            /** make a list of all quote adjustments including header adjustments, line adjustments, and special adjustments (shipping and tax if applicable).
3819:             *  Internally, the quote adjustments are created from the order adjustments.
3820:             */
3821:            public List makeAllQuoteAdjustments() {
3822:                List quoteAdjs = new LinkedList();
3823:
3824:                List orderAdjs = makeAllAdjustments();
3825:                Iterator orderAdjsIter = orderAdjs.iterator();
3826:
3827:                while (orderAdjsIter.hasNext()) {
3828:                    GenericValue orderAdj = (GenericValue) orderAdjsIter.next();
3829:                    GenericValue quoteAdj = this .getDelegator().makeValue(
3830:                            "QuoteAdjustment", null);
3831:                    quoteAdj.put("quoteAdjustmentId", orderAdj
3832:                            .get("orderAdjustmentId"));
3833:                    quoteAdj.put("quoteAdjustmentTypeId", orderAdj
3834:                            .get("orderAdjustmentTypeId"));
3835:                    quoteAdj.put("quoteItemSeqId", orderAdj
3836:                            .get("orderItemSeqId"));
3837:                    quoteAdj.put("comments", orderAdj.get("comments"));
3838:                    quoteAdj.put("description", orderAdj.get("description"));
3839:                    quoteAdj.put("amount", orderAdj.get("amount"));
3840:                    quoteAdj.put("productPromoId", orderAdj
3841:                            .get("productPromoId"));
3842:                    quoteAdj.put("productPromoRuleId", orderAdj
3843:                            .get("productPromoRuleId"));
3844:                    quoteAdj.put("productPromoActionSeqId", orderAdj
3845:                            .get("productPromoActionSeqId"));
3846:                    quoteAdj.put("productFeatureId", orderAdj
3847:                            .get("productFeatureId"));
3848:                    quoteAdj.put("correspondingProductId", orderAdj
3849:                            .get("correspondingProductId"));
3850:                    quoteAdj.put("sourceReferenceId", orderAdj
3851:                            .get("sourceReferenceId"));
3852:                    quoteAdj.put("sourcePercentage", orderAdj
3853:                            .get("sourcePercentage"));
3854:                    quoteAdj.put("customerReferenceId", orderAdj
3855:                            .get("customerReferenceId"));
3856:                    quoteAdj.put("primaryGeoId", orderAdj.get("primaryGeoId"));
3857:                    quoteAdj.put("secondaryGeoId", orderAdj
3858:                            .get("secondaryGeoId"));
3859:                    quoteAdj.put("exemptAmount", orderAdj.get("exemptAmount"));
3860:                    quoteAdj.put("taxAuthGeoId", orderAdj.get("taxAuthGeoId"));
3861:                    quoteAdj.put("taxAuthPartyId", orderAdj
3862:                            .get("taxAuthPartyId"));
3863:                    quoteAdj.put("overrideGlAccountId", orderAdj
3864:                            .get("overrideGlAccountId"));
3865:                    quoteAdj.put("includeInTax", orderAdj.get("includeInTax"));
3866:                    quoteAdj.put("includeInShipping", orderAdj
3867:                            .get("includeInShipping"));
3868:                    quoteAdj.put("createdDate", orderAdj.get("createdDate"));
3869:                    quoteAdj.put("createdByUserLogin", orderAdj
3870:                            .get("createdByUserLogin"));
3871:                    quoteAdjs.add(quoteAdj);
3872:                }
3873:
3874:                return quoteAdjs;
3875:            }
3876:
3877:            /** make a list of all OrderPaymentPreferences and Billing info including all payment methods and types */
3878:            public List makeAllOrderPaymentInfos(LocalDispatcher dispatcher) {
3879:                List allOpPrefs = new LinkedList();
3880:                BigDecimal remainingAmount = new BigDecimal(this 
3881:                        .getGrandTotal()
3882:                        - this .getPaymentTotal());
3883:                remainingAmount = remainingAmount.setScale(2,
3884:                        BigDecimal.ROUND_HALF_UP);
3885:                if (getBillingAccountId() != null
3886:                        && this .billingAccountAmt <= 0) {
3887:                    double billingAccountAvailableAmount = CheckOutHelper
3888:                            .availableAccountBalance(getBillingAccountId(),
3889:                                    dispatcher);
3890:                    if (this .billingAccountAmt == 0.0
3891:                            && billingAccountAvailableAmount > 0) {
3892:                        this .billingAccountAmt = billingAccountAvailableAmount;
3893:                    }
3894:                    if (remainingAmount.doubleValue() < getBillingAccountAmount()) {
3895:                        this .billingAccountAmt = remainingAmount.doubleValue();
3896:                    }
3897:                    if (billingAccountAvailableAmount < getBillingAccountAmount()) {
3898:                        this .billingAccountAmt = billingAccountAvailableAmount;
3899:                    }
3900:                    BigDecimal billingAccountAmountSelected = new BigDecimal(
3901:                            getBillingAccountAmount());
3902:                    GenericValue opp = delegator.makeValue(
3903:                            "OrderPaymentPreference", new HashMap());
3904:                    opp.set("paymentMethodTypeId", "EXT_BILLACT");
3905:                    opp.set("presentFlag", "N");
3906:                    opp.set("overflowFlag", "N");
3907:                    opp.set("maxAmount", new Double(
3908:                            billingAccountAmountSelected.doubleValue()));
3909:                    opp.set("statusId", "PAYMENT_NOT_RECEIVED");
3910:                    allOpPrefs.add(opp);
3911:                    remainingAmount = remainingAmount
3912:                            .subtract(billingAccountAmountSelected);
3913:                    if (remainingAmount.compareTo(ZERO) < 0) {
3914:                        remainingAmount = ZERO;
3915:                    }
3916:                }
3917:                Iterator i = paymentInfo.iterator();
3918:                while (i.hasNext()) {
3919:                    CartPaymentInfo inf = (CartPaymentInfo) i.next();
3920:                    if (inf.amount == null) {
3921:                        inf.amount = new Double(remainingAmount.doubleValue());
3922:                        remainingAmount = ZERO;
3923:                    }
3924:                    allOpPrefs.addAll(inf.makeOrderPaymentInfos(this 
3925:                            .getDelegator()));
3926:                }
3927:                return allOpPrefs;
3928:            }
3929:
3930:            /** make a list of OrderItemPriceInfos from the ShoppingCartItems */
3931:            public List makeAllOrderItemPriceInfos() {
3932:                List allInfos = new LinkedList();
3933:
3934:                // add all of the item adjustments to this list too
3935:                Iterator itemIter = cartLines.iterator();
3936:
3937:                while (itemIter.hasNext()) {
3938:                    ShoppingCartItem item = (ShoppingCartItem) itemIter.next();
3939:                    Collection infos = item.getOrderItemPriceInfos();
3940:
3941:                    if (infos != null) {
3942:                        Iterator infosIter = infos.iterator();
3943:
3944:                        while (infosIter.hasNext()) {
3945:                            GenericValue orderItemPriceInfo = (GenericValue) infosIter
3946:                                    .next();
3947:
3948:                            orderItemPriceInfo.set("orderItemSeqId", item
3949:                                    .getOrderItemSeqId());
3950:                            allInfos.add(orderItemPriceInfo);
3951:                        }
3952:                    }
3953:                }
3954:
3955:                return allInfos;
3956:            }
3957:
3958:            public List makeProductPromoUses() {
3959:                List productPromoUses = new ArrayList(
3960:                        this .productPromoUseInfoList.size());
3961:                String partyId = this .getPartyId();
3962:                int sequenceValue = 0;
3963:                Iterator productPromoUseInfoIter = this .productPromoUseInfoList
3964:                        .iterator();
3965:                while (productPromoUseInfoIter.hasNext()) {
3966:                    ProductPromoUseInfo productPromoUseInfo = (ProductPromoUseInfo) productPromoUseInfoIter
3967:                            .next();
3968:                    GenericValue productPromoUse = this .getDelegator()
3969:                            .makeValue("ProductPromoUse", null);
3970:                    productPromoUse.set("promoSequenceId", UtilFormatOut
3971:                            .formatPaddedNumber(sequenceValue, 5));
3972:                    productPromoUse.set("productPromoId", productPromoUseInfo
3973:                            .getProductPromoId());
3974:                    productPromoUse.set("productPromoCodeId",
3975:                            productPromoUseInfo.getProductPromoCodeId());
3976:                    productPromoUse.set("totalDiscountAmount", new Double(
3977:                            productPromoUseInfo.getTotalDiscountAmount()));
3978:                    productPromoUse.set("quantityLeftInActions", new Double(
3979:                            productPromoUseInfo.getQuantityLeftInActions()));
3980:                    productPromoUse.set("partyId", partyId);
3981:                    productPromoUses.add(productPromoUse);
3982:                    sequenceValue++;
3983:                }
3984:                return productPromoUses;
3985:            }
3986:
3987:            /** make a list of SurveyResponse object to update with order information set */
3988:            public List makeAllOrderItemSurveyResponses() {
3989:                List allInfos = new LinkedList();
3990:                Iterator itemIter = this .iterator();
3991:                while (itemIter.hasNext()) {
3992:                    ShoppingCartItem item = (ShoppingCartItem) itemIter.next();
3993:                    List responses = (List) item
3994:                            .getAttribute("surveyResponses");
3995:                    if (responses != null) {
3996:                        Iterator ri = responses.iterator();
3997:                        while (ri.hasNext()) {
3998:                            String responseId = (String) ri.next();
3999:                            GenericValue response = null;
4000:                            try {
4001:                                response = this .getDelegator()
4002:                                        .findByPrimaryKey(
4003:                                                "SurveyResponse",
4004:                                                UtilMisc.toMap(
4005:                                                        "surveyResponseId",
4006:                                                        responseId));
4007:                            } catch (GenericEntityException e) {
4008:                                Debug.logError(e,
4009:                                        "Unable to obtain SurveyResponse record for ID : "
4010:                                                + responseId, module);
4011:                            }
4012:                            if (response != null) {
4013:                                response.set("orderItemSeqId", item
4014:                                        .getOrderItemSeqId());
4015:                                allInfos.add(response);
4016:                            }
4017:                        }
4018:                    }
4019:                }
4020:                return allInfos;
4021:            }
4022:
4023:            /** make a list of OrderContactMechs from the ShoppingCart and the ShoppingCartItems */
4024:            public List makeAllOrderContactMechs() {
4025:                List allOrderContactMechs = new LinkedList();
4026:
4027:                Map contactMechIds = this .getOrderContactMechIds();
4028:
4029:                if (contactMechIds != null) {
4030:                    Iterator cMechIdsIter = contactMechIds.entrySet()
4031:                            .iterator();
4032:
4033:                    while (cMechIdsIter.hasNext()) {
4034:                        Map.Entry entry = (Map.Entry) cMechIdsIter.next();
4035:                        GenericValue orderContactMech = getDelegator()
4036:                                .makeValue("OrderContactMech", null);
4037:
4038:                        orderContactMech.set("contactMechPurposeTypeId", entry
4039:                                .getKey());
4040:                        orderContactMech.set("contactMechId", entry.getValue());
4041:                        allOrderContactMechs.add(orderContactMech);
4042:                    }
4043:                }
4044:
4045:                return allOrderContactMechs;
4046:            }
4047:
4048:            /** make a list of OrderContactMechs from the ShoppingCart and the ShoppingCartItems */
4049:            public List makeAllOrderItemContactMechs() {
4050:                List allOrderContactMechs = new LinkedList();
4051:
4052:                Iterator itemIter = cartLines.iterator();
4053:
4054:                while (itemIter.hasNext()) {
4055:                    ShoppingCartItem item = (ShoppingCartItem) itemIter.next();
4056:                    Map itemContactMechIds = item.getOrderItemContactMechIds();
4057:
4058:                    if (itemContactMechIds != null) {
4059:                        Iterator cMechIdsIter = itemContactMechIds.entrySet()
4060:                                .iterator();
4061:
4062:                        while (cMechIdsIter.hasNext()) {
4063:                            Map.Entry entry = (Map.Entry) cMechIdsIter.next();
4064:                            GenericValue orderContactMech = getDelegator()
4065:                                    .makeValue("OrderItemContactMech", null);
4066:
4067:                            orderContactMech.set("contactMechPurposeTypeId",
4068:                                    entry.getKey());
4069:                            orderContactMech.set("contactMechId", entry
4070:                                    .getValue());
4071:                            orderContactMech.set("orderItemSeqId", item
4072:                                    .getOrderItemSeqId());
4073:                            allOrderContactMechs.add(orderContactMech);
4074:                        }
4075:                    }
4076:                }
4077:
4078:                return allOrderContactMechs;
4079:            }
4080:
4081:            public List makeAllShipGroupInfos() {
4082:                List groups = new LinkedList();
4083:                Iterator grpIterator = this .shipInfo.iterator();
4084:                long seqId = 1;
4085:                while (grpIterator.hasNext()) {
4086:                    CartShipInfo csi = (CartShipInfo) grpIterator.next();
4087:                    groups.addAll(csi.makeItemShipGroupAndAssoc(this 
4088:                            .getDelegator(), this , seqId));
4089:                    seqId++;
4090:                }
4091:                return groups;
4092:            }
4093:
4094:            public List makeAllOrderItemAttributes() {
4095:                List allOrderItemAttributes = new LinkedList();
4096:
4097:                Iterator itemIter = cartLines.iterator();
4098:                while (itemIter.hasNext()) {
4099:                    ShoppingCartItem item = (ShoppingCartItem) itemIter.next();
4100:                    Map attrs = item.getOrderItemAttributes();
4101:                    Iterator i = attrs.entrySet().iterator();
4102:                    while (i.hasNext()) {
4103:                        Map.Entry entry = (Map.Entry) i.next();
4104:                        GenericValue itemAtt = this .getDelegator().makeValue(
4105:                                "OrderItemAttribute", null);
4106:                        itemAtt.set("orderItemSeqId", item.getOrderItemSeqId());
4107:                        itemAtt.set("attrName", entry.getKey());
4108:                        itemAtt.set("attrValue", entry.getValue());
4109:                        allOrderItemAttributes.add(itemAtt);
4110:                    }
4111:                }
4112:                return allOrderItemAttributes;
4113:            }
4114:
4115:            public List makeAllOrderAttributes() {
4116:                List allOrderAttributes = new LinkedList();
4117:
4118:                Iterator i = orderAttributes.entrySet().iterator();
4119:                while (i.hasNext()) {
4120:                    Map.Entry entry = (Map.Entry) i.next();
4121:                    GenericValue orderAtt = this .getDelegator().makeValue(
4122:                            "OrderAttribute", null);
4123:                    orderAtt.put("attrName", entry.getKey());
4124:                    orderAtt.put("attrValue", entry.getValue());
4125:                    allOrderAttributes.add(orderAtt);
4126:                }
4127:                return allOrderAttributes;
4128:            }
4129:
4130:            public List makeAllOrderItemAssociations() {
4131:                List allOrderItemAssociations = new LinkedList();
4132:
4133:                Iterator itemIter = cartLines.iterator();
4134:
4135:                while (itemIter.hasNext()) {
4136:                    ShoppingCartItem item = (ShoppingCartItem) itemIter.next();
4137:                    String requirementId = item.getRequirementId();
4138:                    if (requirementId != null) {
4139:                        try {
4140:                            List commitments = getDelegator().findByAnd(
4141:                                    "OrderRequirementCommitment",
4142:                                    UtilMisc.toMap("requirementId",
4143:                                            requirementId));
4144:                            // TODO: multiple commitments for the same requirement are still not supported
4145:                            GenericValue commitment = EntityUtil
4146:                                    .getFirst(commitments);
4147:                            if (commitment != null) {
4148:                                GenericValue orderItemAssociation = getDelegator()
4149:                                        .makeValue("OrderItemAssoc", null);
4150:                                orderItemAssociation.set("orderId", commitment
4151:                                        .getString("orderId"));
4152:                                orderItemAssociation.set("orderItemSeqId",
4153:                                        commitment.getString("orderItemSeqId"));
4154:                                orderItemAssociation.set("shipGroupSeqId",
4155:                                        "_NA_");
4156:                                orderItemAssociation.set("toOrderItemSeqId",
4157:                                        item.getOrderItemSeqId());
4158:                                orderItemAssociation.set("toShipGroupSeqId",
4159:                                        "_NA_");
4160:                                orderItemAssociation.set(
4161:                                        "orderItemAssocTypeId",
4162:                                        "PURCHASE_ORDER");
4163:                                allOrderItemAssociations
4164:                                        .add(orderItemAssociation);
4165:                            }
4166:                        } catch (GenericEntityException e) {
4167:                            Debug.logError(e,
4168:                                    "Unable to load OrderRequirementCommitment records for requirement ID : "
4169:                                            + requirementId, module);
4170:                        }
4171:                    }
4172:                    if (item.getAssociatedOrderId() != null
4173:                            && item.getAssociatedOrderItemSeqId() != null) {
4174:                        GenericValue orderItemAssociation = getDelegator()
4175:                                .makeValue("OrderItemAssoc", null);
4176:                        orderItemAssociation.set("orderId", item
4177:                                .getAssociatedOrderId());
4178:                        orderItemAssociation.set("orderItemSeqId", item
4179:                                .getAssociatedOrderItemSeqId());
4180:                        orderItemAssociation.set("shipGroupSeqId", "_NA_");
4181:                        orderItemAssociation.set("toOrderItemSeqId", item
4182:                                .getOrderItemSeqId());
4183:                        orderItemAssociation.set("toShipGroupSeqId", "_NA_");
4184:                        orderItemAssociation.set("orderItemAssocTypeId", item
4185:                                .getOrderItemAssocTypeId());
4186:                        allOrderItemAssociations.add(orderItemAssociation);
4187:                    }
4188:                }
4189:                return allOrderItemAssociations;
4190:            }
4191:
4192:            /** Returns a Map of cart values to pass to the storeOrder service */
4193:            public Map makeCartMap(LocalDispatcher dispatcher,
4194:                    boolean explodeItems) {
4195:                Map result = new HashMap();
4196:
4197:                result.put("orderTypeId", this .getOrderType());
4198:                result.put("orderName", this .getOrderName());
4199:                result.put("externalId", this .getExternalId());
4200:                result.put("orderDate", this .getOrderDate());
4201:                result.put("internalCode", this .getInternalCode());
4202:                result.put("salesChannelEnumId", this .getChannelType());
4203:                result.put("orderItemGroups", this .makeOrderItemGroups());
4204:                result.put("orderItems", this .makeOrderItems(explodeItems,
4205:                        dispatcher));
4206:                result.put("workEfforts", this .makeWorkEfforts());
4207:                result.put("orderAdjustments", this .makeAllAdjustments());
4208:                result.put("orderTerms", this .getOrderTerms());
4209:                result.put("orderItemPriceInfos", this 
4210:                        .makeAllOrderItemPriceInfos());
4211:                result
4212:                        .put("orderProductPromoUses", this 
4213:                                .makeProductPromoUses());
4214:
4215:                result.put("orderAttributes", this .makeAllOrderAttributes());
4216:                result.put("orderItemAttributes", this 
4217:                        .makeAllOrderItemAttributes());
4218:                result
4219:                        .put("orderContactMechs", this 
4220:                                .makeAllOrderContactMechs());
4221:                result.put("orderItemContactMechs", this 
4222:                        .makeAllOrderItemContactMechs());
4223:                result.put("orderPaymentInfo", this 
4224:                        .makeAllOrderPaymentInfos(dispatcher));
4225:                result.put("orderItemShipGroupInfo", this 
4226:                        .makeAllShipGroupInfos());
4227:                result.put("orderItemSurveyResponses", this 
4228:                        .makeAllOrderItemSurveyResponses());
4229:                result.put("orderAdditionalPartyRoleMap", this 
4230:                        .getAdditionalPartyRoleMap());
4231:                result.put("orderItemAssociations", this 
4232:                        .makeAllOrderItemAssociations());
4233:                result.put("orderInternalNotes", this .getInternalOrderNotes());
4234:                result.put("orderNotes", this .getOrderNotes());
4235:
4236:                result
4237:                        .put("firstAttemptOrderId", this 
4238:                                .getFirstAttemptOrderId());
4239:                result.put("currencyUom", this .getCurrency());
4240:                result.put("billingAccountId", this .getBillingAccountId());
4241:
4242:                result.put("partyId", this .getPartyId());
4243:                result.put("productStoreId", this .getProductStoreId());
4244:                result.put("transactionId", this .getTransactionId());
4245:                result.put("originFacilityId", this .getFacilityId());
4246:                result.put("terminalId", this .getTerminalId());
4247:                result.put("autoOrderShoppingListId", this 
4248:                        .getAutoOrderShoppingListId());
4249:
4250:                result.put("billToCustomerPartyId", this 
4251:                        .getBillToCustomerPartyId());
4252:                result.put("billFromVendorPartyId", this 
4253:                        .getBillFromVendorPartyId());
4254:
4255:                if (this .isSalesOrder()) {
4256:                    result.put("placingCustomerPartyId", this 
4257:                            .getPlacingCustomerPartyId());
4258:                    result.put("shipToCustomerPartyId", this 
4259:                            .getShipToCustomerPartyId());
4260:                    result.put("endUserCustomerPartyId", this 
4261:                            .getEndUserCustomerPartyId());
4262:                }
4263:
4264:                if (this .isPurchaseOrder()) {
4265:                    result.put("shipFromVendorPartyId", this 
4266:                            .getShipFromVendorPartyId());
4267:                    result.put("supplierAgentPartyId", this 
4268:                            .getSupplierAgentPartyId());
4269:                }
4270:
4271:                return result;
4272:            }
4273:
4274:            public List getLineListOrderedByBasePrice(boolean ascending) {
4275:                List result = new ArrayList(this .cartLines);
4276:                Collections.sort(result,
4277:                        new BasePriceOrderComparator(ascending));
4278:                return result;
4279:            }
4280:
4281:            public Map getShipGroupsBySupplier(String supplierPartyId) {
4282:                Map shipGroups = new TreeMap();
4283:                for (int i = 0; i < this .shipInfo.size(); i++) {
4284:                    CartShipInfo csi = (CartShipInfo) shipInfo.get(i);
4285:                    if ((csi.supplierPartyId == null && supplierPartyId == null)
4286:                            || (UtilValidate.isNotEmpty(csi.supplierPartyId) && csi.supplierPartyId
4287:                                    .equals(supplierPartyId))) {
4288:                        shipGroups.put(new Integer(i), csi);
4289:                    }
4290:                }
4291:                return shipGroups;
4292:            }
4293:
4294:            /**
4295:             * Examine each item of each ship group and create new ship groups if the item should be drop shipped
4296:             * @param dispatcher
4297:             * @throws CartItemModifyException
4298:             */
4299:            public void createDropShipGroups(LocalDispatcher dispatcher)
4300:                    throws CartItemModifyException {
4301:
4302:                // Retrieve the facilityId from the cart's productStoreId because ShoppingCart.setFacilityId() doesn't seem to be used anywhere
4303:                String facilityId = null;
4304:                if (UtilValidate.isNotEmpty(this .getProductStoreId())) {
4305:                    try {
4306:                        GenericValue productStore = delegator
4307:                                .findByPrimaryKeyCache("ProductStore", UtilMisc
4308:                                        .toMap("productStoreId", this 
4309:                                                .getProductStoreId()));
4310:                        facilityId = productStore
4311:                                .getString("inventoryFacilityId");
4312:                    } catch (Exception e) {
4313:                        Debug.logError(UtilProperties.getMessage(
4314:                                resource_error,
4315:                                "OrderProblemGettingProductStoreRecords",
4316:                                locale)
4317:                                + e.getMessage(), module);
4318:                        return;
4319:                    }
4320:                }
4321:
4322:                List shipGroups = getShipGroups();
4323:                if (shipGroups == null)
4324:                    return;
4325:
4326:                // Intermediate structure supplierPartyId -> { ShoppingCartItem = { originalShipGroupIndex = dropShipQuantity } } to collect drop-shippable items
4327:                Map dropShipItems = new HashMap();
4328:
4329:                for (int shipGroupIndex = 0; shipGroupIndex < shipGroups.size(); shipGroupIndex++) {
4330:
4331:                    CartShipInfo shipInfo = (CartShipInfo) shipGroups
4332:                            .get(shipGroupIndex);
4333:
4334:                    // Ignore ship groups that are already drop shipped
4335:                    String shipGroupSupplierPartyId = shipInfo
4336:                            .getSupplierPartyId();
4337:                    if (UtilValidate.isNotEmpty(shipGroupSupplierPartyId))
4338:                        continue;
4339:
4340:                    // Ignore empty ship groups
4341:                    Set shipItems = shipInfo.getShipItems();
4342:                    if (UtilValidate.isEmpty(shipItems))
4343:                        continue;
4344:
4345:                    Iterator siit = shipItems.iterator();
4346:                    while (siit.hasNext()) {
4347:
4348:                        ShoppingCartItem cartItem = (ShoppingCartItem) siit
4349:                                .next();
4350:
4351:                        double itemQuantity = cartItem.getQuantity();
4352:                        double dropShipQuantity = 0;
4353:
4354:                        GenericValue product = cartItem.getProduct();
4355:                        if (product == null) {
4356:                            continue;
4357:                        }
4358:                        String productId = product.getString("productId");
4359:                        String requirementMethodEnumId = product
4360:                                .getString("requirementMethodEnumId");
4361:
4362:                        if ("PRODRQM_DS".equals(requirementMethodEnumId)) {
4363:
4364:                            // Drop ship the full quantity if the product is marked drop-ship only
4365:                            dropShipQuantity = itemQuantity;
4366:
4367:                        } else if ("PRODRQM_DSATP"
4368:                                .equals(requirementMethodEnumId)) {
4369:
4370:                            // Drop ship the quantity not available in inventory if the product is marked drop-ship on low inventory
4371:                            try {
4372:
4373:                                // Get ATP for the product
4374:                                Map getProductInventoryAvailableResult = dispatcher
4375:                                        .runSync(
4376:                                                "getInventoryAvailableByFacility",
4377:                                                UtilMisc.toMap("productId",
4378:                                                        productId,
4379:                                                        "facilityId",
4380:                                                        facilityId));
4381:                                double availableToPromise = ((Double) getProductInventoryAvailableResult
4382:                                        .get("availableToPromiseTotal"))
4383:                                        .doubleValue();
4384:
4385:                                if (itemQuantity <= availableToPromise) {
4386:                                    dropShipQuantity = 0;
4387:                                } else {
4388:                                    dropShipQuantity = itemQuantity
4389:                                            - availableToPromise;
4390:                                }
4391:
4392:                            } catch (Exception e) {
4393:                                Debug
4394:                                        .logWarning(
4395:                                                UtilProperties
4396:                                                        .getMessage(
4397:                                                                resource_error,
4398:                                                                "OrderRunServiceGetInventoryAvailableByFacilityError",
4399:                                                                locale)
4400:                                                        + e.getMessage(),
4401:                                                module);
4402:                            }
4403:                        } else {
4404:
4405:                            // Don't drop ship anything if the product isn't so marked
4406:                            dropShipQuantity = 0;
4407:                        }
4408:
4409:                        if (dropShipQuantity <= 0)
4410:                            continue;
4411:
4412:                        // Find a supplier for the product
4413:                        String supplierPartyId = null;
4414:                        try {
4415:                            Map getSuppliersForProductResult = dispatcher
4416:                                    .runSync("getSuppliersForProduct", UtilMisc
4417:                                            .toMap("productId", productId,
4418:                                                    "quantity", new Double(
4419:                                                            dropShipQuantity),
4420:                                                    "canDropShip", "Y",
4421:                                                    "currencyUomId",
4422:                                                    getCurrency()));
4423:                            List supplierProducts = (List) getSuppliersForProductResult
4424:                                    .get("supplierProducts");
4425:
4426:                            // Order suppliers by supplierPrefOrderId so that preferred suppliers are used first
4427:                            supplierProducts = EntityUtil.orderBy(
4428:                                    supplierProducts, UtilMisc
4429:                                            .toList("supplierPrefOrderId"));
4430:                            GenericValue supplierProduct = EntityUtil
4431:                                    .getFirst(supplierProducts);
4432:                            if (!UtilValidate.isEmpty(supplierProduct)) {
4433:                                supplierPartyId = supplierProduct
4434:                                        .getString("partyId");
4435:                            }
4436:                        } catch (Exception e) {
4437:                            Debug
4438:                                    .logWarning(
4439:                                            UtilProperties
4440:                                                    .getMessage(
4441:                                                            resource_error,
4442:                                                            "OrderRunServiceGetSuppliersForProductError",
4443:                                                            locale)
4444:                                                    + e.getMessage(), module);
4445:                        }
4446:
4447:                        // Leave the items untouched if we couldn't find a supplier
4448:                        if (UtilValidate.isEmpty(supplierPartyId))
4449:                            continue;
4450:
4451:                        if (!dropShipItems.containsKey(supplierPartyId))
4452:                            dropShipItems.put(supplierPartyId, new HashMap());
4453:                        Map supplierCartItems = (Map) dropShipItems
4454:                                .get(supplierPartyId);
4455:
4456:                        if (!supplierCartItems.containsKey(cartItem))
4457:                            supplierCartItems.put(cartItem, new HashMap());
4458:                        Map cartItemGroupQuantities = (Map) supplierCartItems
4459:                                .get(cartItem);
4460:
4461:                        cartItemGroupQuantities.put(
4462:                                new Integer(shipGroupIndex), new Double(
4463:                                        dropShipQuantity));
4464:                    }
4465:                }
4466:
4467:                // Reassign the drop-shippable item quantities to new or existing drop-ship groups
4468:                Iterator dsit = dropShipItems.keySet().iterator();
4469:                while (dsit.hasNext()) {
4470:                    String supplierPartyId = (String) dsit.next();
4471:
4472:                    CartShipInfo shipInfo = null;
4473:                    int newShipGroupIndex = -1;
4474:
4475:                    // Attempt to get the first ship group for the supplierPartyId
4476:                    TreeMap supplierShipGroups = (TreeMap) this 
4477:                            .getShipGroupsBySupplier(supplierPartyId);
4478:                    if (!UtilValidate.isEmpty(supplierShipGroups)) {
4479:                        newShipGroupIndex = ((Integer) supplierShipGroups
4480:                                .firstKey()).intValue();
4481:                        shipInfo = (CartShipInfo) supplierShipGroups
4482:                                .get(supplierShipGroups.firstKey());
4483:                    }
4484:                    if (newShipGroupIndex == -1) {
4485:                        newShipGroupIndex = addShipInfo();
4486:                        shipInfo = (CartShipInfo) this .shipInfo
4487:                                .get(newShipGroupIndex);
4488:                    }
4489:                    shipInfo.supplierPartyId = supplierPartyId;
4490:
4491:                    Map supplierCartItems = (Map) dropShipItems
4492:                            .get(supplierPartyId);
4493:                    Iterator itit = supplierCartItems.keySet().iterator();
4494:                    while (itit.hasNext()) {
4495:
4496:                        ShoppingCartItem cartItem = (ShoppingCartItem) itit
4497:                                .next();
4498:                        Map cartItemGroupQuantities = (Map) supplierCartItems
4499:                                .get(cartItem);
4500:                        Iterator cigit = cartItemGroupQuantities.keySet()
4501:                                .iterator();
4502:                        while (cigit.hasNext()) {
4503:
4504:                            Integer previousShipGroupIndex = (Integer) cigit
4505:                                    .next();
4506:                            double dropShipQuantity = ((Double) cartItemGroupQuantities
4507:                                    .get(previousShipGroupIndex)).doubleValue();
4508:                            positionItemToGroup(cartItem, dropShipQuantity,
4509:                                    previousShipGroupIndex.intValue(),
4510:                                    newShipGroupIndex, true);
4511:                        }
4512:                    }
4513:                }
4514:            }
4515:
4516:            static class BasePriceOrderComparator implements  Comparator,
4517:                    Serializable {
4518:                private boolean ascending = false;
4519:
4520:                BasePriceOrderComparator(boolean ascending) {
4521:                    this .ascending = ascending;
4522:                }
4523:
4524:                public int compare(java.lang.Object obj, java.lang.Object obj1) {
4525:                    ShoppingCartItem cartItem = (ShoppingCartItem) obj;
4526:                    ShoppingCartItem cartItem1 = (ShoppingCartItem) obj1;
4527:
4528:                    int compareValue = new Double(cartItem.getBasePrice())
4529:                            .compareTo(new Double(cartItem1.getBasePrice()));
4530:                    if (this .ascending) {
4531:                        return compareValue;
4532:                    } else {
4533:                        return -compareValue;
4534:                    }
4535:                }
4536:
4537:                public boolean equals(java.lang.Object obj) {
4538:                    if (obj instanceof  BasePriceOrderComparator) {
4539:                        return this .ascending == ((BasePriceOrderComparator) obj).ascending;
4540:                    } else {
4541:                        return false;
4542:                    }
4543:                }
4544:            }
4545:
4546:            public static class ShoppingCartItemGroup implements  Serializable {
4547:                private long groupNumber;
4548:                private String groupName;
4549:                private ShoppingCartItemGroup parentGroup;
4550:
4551:                // don't allow empty constructor
4552:                private ShoppingCartItemGroup() {
4553:                }
4554:
4555:                protected ShoppingCartItemGroup(long groupNumber,
4556:                        String groupName) {
4557:                    this (groupNumber, groupName, null);
4558:                }
4559:
4560:                /** Note that to avoid foreign key issues when the groups are created a parentGroup should have a lower number than the child group. */
4561:                protected ShoppingCartItemGroup(long groupNumber,
4562:                        String groupName, ShoppingCartItemGroup parentGroup) {
4563:                    this .groupNumber = groupNumber;
4564:                    this .groupName = groupName;
4565:                    this .parentGroup = parentGroup;
4566:                }
4567:
4568:                protected ShoppingCartItemGroup(
4569:                        ShoppingCartItemGroup itemGroup,
4570:                        ShoppingCartItemGroup parentGroup) {
4571:                    this .groupNumber = itemGroup.groupNumber;
4572:                    this .groupName = itemGroup.groupName;
4573:                    this .parentGroup = parentGroup;
4574:                }
4575:
4576:                public String getGroupNumber() {
4577:                    return UtilFormatOut
4578:                            .formatPaddedNumber(this .groupNumber, 2);
4579:                }
4580:
4581:                public String getGroupName() {
4582:                    return this .groupName;
4583:                }
4584:
4585:                public void setGroupName(String str) {
4586:                    this .groupName = str;
4587:                }
4588:
4589:                public ShoppingCartItemGroup getParentGroup() {
4590:                    return this .parentGroup;
4591:                }
4592:
4593:                protected GenericValue makeOrderItemGroup(
4594:                        GenericDelegator delegator) {
4595:                    GenericValue orderItemGroup = delegator.makeValue(
4596:                            "OrderItemGroup", null);
4597:                    orderItemGroup.set("orderItemGroupSeqId", this 
4598:                            .getGroupNumber());
4599:                    orderItemGroup.set("groupName", this .getGroupName());
4600:                    if (this .parentGroup != null) {
4601:                        orderItemGroup.set("parentGroupSeqId", this .parentGroup
4602:                                .getGroupNumber());
4603:                    }
4604:                    return orderItemGroup;
4605:                }
4606:
4607:                public void inheritParentsParent() {
4608:                    if (this .parentGroup != null) {
4609:                        this .parentGroup = this .parentGroup.getParentGroup();
4610:                    }
4611:                }
4612:
4613:                public boolean equals(Object obj) {
4614:                    if (obj == null)
4615:                        return false;
4616:                    ShoppingCartItemGroup that = (ShoppingCartItemGroup) obj;
4617:                    if (that.groupNumber == this .groupNumber) {
4618:                        return true;
4619:                    }
4620:                    return false;
4621:                }
4622:            }
4623:
4624:            public static class ProductPromoUseInfo implements  Serializable {
4625:                public String productPromoId = null;
4626:                public String productPromoCodeId = null;
4627:                public double totalDiscountAmount = 0;
4628:                public double quantityLeftInActions = 0;
4629:
4630:                public ProductPromoUseInfo(String productPromoId,
4631:                        String productPromoCodeId, double totalDiscountAmount,
4632:                        double quantityLeftInActions) {
4633:                    this .productPromoId = productPromoId;
4634:                    this .productPromoCodeId = productPromoCodeId;
4635:                    this .totalDiscountAmount = totalDiscountAmount;
4636:                    this .quantityLeftInActions = quantityLeftInActions;
4637:                }
4638:
4639:                public String getProductPromoId() {
4640:                    return this .productPromoId;
4641:                }
4642:
4643:                public String getProductPromoCodeId() {
4644:                    return this .productPromoCodeId;
4645:                }
4646:
4647:                public double getTotalDiscountAmount() {
4648:                    return this .totalDiscountAmount;
4649:                }
4650:
4651:                public double getQuantityLeftInActions() {
4652:                    return this .quantityLeftInActions;
4653:                }
4654:            }
4655:
4656:            public static class CartShipInfo implements  Serializable {
4657:                public LinkedMap shipItemInfo = new LinkedMap();
4658:                public List shipTaxAdj = new LinkedList();
4659:                public String contactMechId = null;
4660:                public String shipmentMethodTypeId = null;
4661:                public String supplierPartyId = null;
4662:                public String carrierRoleTypeId = null;
4663:                public String carrierPartyId = null;
4664:                public String giftMessage = null;
4665:                public String shippingInstructions = null;
4666:                public String maySplit = "N";
4667:                public String isGift = "N";
4668:                public double shipEstimate = 0.00;
4669:                public Timestamp shipBeforeDate = null;
4670:                public Timestamp shipAfterDate = null;
4671:
4672:                public String getContactMechId() {
4673:                    return contactMechId;
4674:                }
4675:
4676:                public String getCarrierPartyId() {
4677:                    return carrierPartyId;
4678:                }
4679:
4680:                public String getSupplierPartyId() {
4681:                    return supplierPartyId;
4682:                }
4683:
4684:                public String getShipmentMethodTypeId() {
4685:                    return shipmentMethodTypeId;
4686:                }
4687:
4688:                public List makeItemShipGroupAndAssoc(
4689:                        GenericDelegator delegator, ShoppingCart cart,
4690:                        long groupIndex) {
4691:                    String shipGroupSeqId = UtilFormatOut.formatPaddedNumber(
4692:                            groupIndex, 5);
4693:                    List values = new LinkedList();
4694:
4695:                    // create order contact mech for shipping address
4696:                    if (contactMechId != null) {
4697:                        GenericValue orderCm = delegator.makeValue(
4698:                                "OrderContactMech", null);
4699:                        orderCm.set("contactMechPurposeTypeId",
4700:                                "SHIPPING_LOCATION");
4701:                        orderCm.set("contactMechId", contactMechId);
4702:                        values.add(orderCm);
4703:                    }
4704:
4705:                    // create the ship group
4706:                    GenericValue shipGroup = delegator.makeValue(
4707:                            "OrderItemShipGroup", null);
4708:                    shipGroup.set("shipmentMethodTypeId", shipmentMethodTypeId);
4709:                    shipGroup.set("carrierRoleTypeId", carrierRoleTypeId);
4710:                    shipGroup.set("carrierPartyId", carrierPartyId);
4711:                    shipGroup.set("supplierPartyId", supplierPartyId);
4712:                    shipGroup.set("shippingInstructions", shippingInstructions);
4713:                    shipGroup.set("giftMessage", giftMessage);
4714:                    shipGroup.set("contactMechId", contactMechId);
4715:                    shipGroup.set("maySplit", maySplit);
4716:                    shipGroup.set("isGift", isGift);
4717:                    shipGroup.set("shipGroupSeqId", shipGroupSeqId);
4718:
4719:                    // use the cart's default ship before and after dates here
4720:                    if ((shipBeforeDate == null)
4721:                            && (cart.getDefaultShipBeforeDate() != null)) {
4722:                        shipGroup.set("shipByDate", cart
4723:                                .getDefaultShipBeforeDate());
4724:                    } else {
4725:                        shipGroup.set("shipByDate", shipBeforeDate);
4726:                    }
4727:                    if ((shipAfterDate == null)
4728:                            && (cart.getDefaultShipAfterDate() != null)) {
4729:                        shipGroup.set("shipAfterDate", cart
4730:                                .getDefaultShipAfterDate());
4731:                    } else {
4732:                        shipGroup.set("shipAfterDate", shipAfterDate);
4733:                    }
4734:
4735:                    values.add(shipGroup);
4736:
4737:                    // create the shipping estimate adjustments
4738:                    if (shipEstimate != 0) {
4739:                        GenericValue shipAdj = delegator.makeValue(
4740:                                "OrderAdjustment", null);
4741:                        shipAdj
4742:                                .set("orderAdjustmentTypeId",
4743:                                        "SHIPPING_CHARGES");
4744:                        shipAdj.set("amount", new Double(shipEstimate));
4745:                        shipAdj.set("shipGroupSeqId", shipGroupSeqId);
4746:                        values.add(shipAdj);
4747:                    }
4748:
4749:                    // create the top level tax adjustments
4750:                    Iterator ti = shipTaxAdj.iterator();
4751:                    while (ti.hasNext()) {
4752:                        GenericValue taxAdj = (GenericValue) ti.next();
4753:                        taxAdj.set("shipGroupSeqId", shipGroupSeqId);
4754:                        values.add(taxAdj);
4755:                    }
4756:
4757:                    // create the ship group item associations
4758:                    Iterator i = shipItemInfo.keySet().iterator();
4759:                    while (i.hasNext()) {
4760:                        ShoppingCartItem item = (ShoppingCartItem) i.next();
4761:                        CartShipItemInfo itemInfo = (CartShipItemInfo) shipItemInfo
4762:                                .get(item);
4763:
4764:                        GenericValue assoc = delegator.makeValue(
4765:                                "OrderItemShipGroupAssoc", null);
4766:                        assoc.set("orderItemSeqId", item.getOrderItemSeqId());
4767:                        assoc.set("shipGroupSeqId", shipGroupSeqId);
4768:                        assoc.set("quantity", new Double(itemInfo.quantity));
4769:                        values.add(assoc);
4770:
4771:                        // create the item tax adjustment
4772:                        Iterator iti = itemInfo.itemTaxAdj.iterator();
4773:                        while (iti.hasNext()) {
4774:                            GenericValue taxAdj = (GenericValue) iti.next();
4775:                            taxAdj.set("orderItemSeqId", item
4776:                                    .getOrderItemSeqId());
4777:                            taxAdj.set("shipGroupSeqId", shipGroupSeqId);
4778:                            values.add(taxAdj);
4779:                        }
4780:                    }
4781:
4782:                    return values;
4783:                }
4784:
4785:                public CartShipItemInfo setItemInfo(ShoppingCartItem item,
4786:                        double quantity, List taxAdj) {
4787:                    CartShipItemInfo itemInfo = (CartShipItemInfo) shipItemInfo
4788:                            .get(item);
4789:                    if (itemInfo == null) {
4790:                        itemInfo = new CartShipItemInfo();
4791:                        itemInfo.item = item;
4792:                        shipItemInfo.put(item, itemInfo);
4793:                    }
4794:                    itemInfo.quantity = quantity;
4795:                    itemInfo.itemTaxAdj.clear();
4796:                    if (taxAdj == null) {
4797:                        taxAdj = new LinkedList();
4798:                    }
4799:                    itemInfo.itemTaxAdj.addAll(taxAdj);
4800:                    return itemInfo;
4801:                }
4802:
4803:                public CartShipItemInfo setItemInfo(ShoppingCartItem item,
4804:                        List taxAdj) {
4805:                    CartShipItemInfo itemInfo = (CartShipItemInfo) shipItemInfo
4806:                            .get(item);
4807:                    if (itemInfo == null) {
4808:                        itemInfo = new CartShipItemInfo();
4809:                        itemInfo.item = item;
4810:                        shipItemInfo.put(item, itemInfo);
4811:                    }
4812:                    itemInfo.itemTaxAdj.clear();
4813:                    if (taxAdj == null) {
4814:                        taxAdj = new LinkedList();
4815:                    }
4816:                    itemInfo.itemTaxAdj.addAll(taxAdj);
4817:                    return itemInfo;
4818:                }
4819:
4820:                public CartShipItemInfo setItemInfo(ShoppingCartItem item,
4821:                        double quantity) {
4822:                    CartShipItemInfo itemInfo = (CartShipItemInfo) shipItemInfo
4823:                            .get(item);
4824:                    if (itemInfo == null) {
4825:                        itemInfo = new CartShipItemInfo();
4826:                        itemInfo.item = item;
4827:                        shipItemInfo.put(item, itemInfo);
4828:                    }
4829:                    itemInfo.quantity = quantity;
4830:                    return itemInfo;
4831:                }
4832:
4833:                public CartShipItemInfo getShipItemInfo(ShoppingCartItem item) {
4834:                    return (CartShipItemInfo) shipItemInfo.get(item);
4835:                }
4836:
4837:                public Set getShipItems() {
4838:                    return shipItemInfo.keySet();
4839:                }
4840:
4841:                /**
4842:                 * Reset the ship group's shipBeforeDate if it is after the parameter 
4843:                 * @param newShipBeforeDate
4844:                 */
4845:                public void resetShipBeforeDateIfAfter(
4846:                        Timestamp newShipBeforeDate) {
4847:                    if (newShipBeforeDate != null) {
4848:                        if ((this .shipBeforeDate == null)
4849:                                || (!this .shipBeforeDate
4850:                                        .before(newShipBeforeDate))) {
4851:                            this .shipBeforeDate = newShipBeforeDate;
4852:                        }
4853:                    }
4854:                }
4855:
4856:                /**
4857:                 * Reset the ship group's shipAfterDate if it is before the parameter 
4858:                 * @param newShipBeforeDate
4859:                 */
4860:                public void resetShipAfterDateIfBefore(
4861:                        Timestamp newShipAfterDate) {
4862:                    if (newShipAfterDate != null) {
4863:                        if ((this .shipAfterDate == null)
4864:                                || (!this .shipAfterDate.after(newShipAfterDate))) {
4865:                            this .shipAfterDate = newShipAfterDate;
4866:                        }
4867:                    }
4868:                }
4869:
4870:                public double getTotalTax(ShoppingCart cart) {
4871:                    double taxTotal = 0.00;
4872:                    for (int i = 0; i < shipTaxAdj.size(); i++) {
4873:                        GenericValue v = (GenericValue) shipTaxAdj.get(i);
4874:                        taxTotal += OrderReadHelper.calcOrderAdjustmentBd(v,
4875:                                new BigDecimal(cart.getSubTotal()))
4876:                                .doubleValue();
4877:                    }
4878:
4879:                    Iterator iter = shipItemInfo.values().iterator();
4880:                    while (iter.hasNext()) {
4881:                        CartShipItemInfo info = (CartShipItemInfo) iter.next();
4882:                        taxTotal += info.getItemTax(cart);
4883:                    }
4884:
4885:                    return taxTotal;
4886:                }
4887:
4888:                public static class CartShipItemInfo implements  Serializable {
4889:                    public List itemTaxAdj = new LinkedList();
4890:                    public ShoppingCartItem item = null;
4891:                    public double quantity = 0;
4892:
4893:                    public double getItemTax(ShoppingCart cart) {
4894:                        double itemTax = 0.00;
4895:
4896:                        for (int i = 0; i < itemTaxAdj.size(); i++) {
4897:                            GenericValue v = (GenericValue) itemTaxAdj.get(i);
4898:                            itemTax += OrderReadHelper.calcItemAdjustmentBd(v,
4899:                                    new BigDecimal(quantity),
4900:                                    new BigDecimal(item.getBasePrice()))
4901:                                    .doubleValue();
4902:                        }
4903:
4904:                        return itemTax;
4905:                    }
4906:
4907:                    public double getItemQuantity() {
4908:                        return this .quantity;
4909:                    }
4910:                }
4911:            }
4912:
4913:            public static class CartPaymentInfo implements  Serializable,
4914:                    Comparable {
4915:                public String paymentMethodTypeId = null;
4916:                public String paymentMethodId = null;
4917:                public String finAccountId = null;
4918:                public String securityCode = null;
4919:                public String postalCode = null;
4920:                public String[] refNum = new String[2];
4921:                public Double amount = null;
4922:                public boolean singleUse = false;
4923:                public boolean isPresent = false;
4924:                public boolean overflow = false;
4925:
4926:                public GenericValue getValueObject(GenericDelegator delegator) {
4927:                    String entityName = null;
4928:                    Map lookupFields = null;
4929:                    if (paymentMethodId != null) {
4930:                        lookupFields = UtilMisc.toMap("paymentMethodId",
4931:                                paymentMethodId);
4932:                        entityName = "PaymentMethod";
4933:                    } else if (paymentMethodTypeId != null) {
4934:                        lookupFields = UtilMisc.toMap("paymentMethodTypeId",
4935:                                paymentMethodTypeId);
4936:                        entityName = "PaymentMethodType";
4937:                    } else {
4938:                        throw new IllegalArgumentException(
4939:                                "Could not create value object because paymentMethodId and paymentMethodTypeId are null");
4940:                    }
4941:
4942:                    try {
4943:                        return delegator.findByPrimaryKeyCache(entityName,
4944:                                lookupFields);
4945:                    } catch (GenericEntityException e) {
4946:                        Debug.logError(e, module);
4947:                    }
4948:
4949:                    return null;
4950:                }
4951:
4952:                public GenericValue getBillingAddress(GenericDelegator delegator) {
4953:                    GenericValue valueObj = this .getValueObject(delegator);
4954:                    GenericValue postalAddress = null;
4955:
4956:                    if ("PaymentMethod".equals(valueObj.getEntityName())) {
4957:                        String paymentMethodTypeId = valueObj
4958:                                .getString("paymentMethodTypeId");
4959:                        String paymentMethodId = valueObj
4960:                                .getString("paymentMethodId");
4961:                        Map lookupFields = UtilMisc.toMap("paymentMethodId",
4962:                                paymentMethodId);
4963:
4964:                        // billing account, credit card, gift card, eft account all have postal address
4965:                        try {
4966:                            GenericValue pmObj = null;
4967:                            if ("CREDIT_CARD".equals(paymentMethodTypeId)) {
4968:                                pmObj = delegator.findByPrimaryKey(
4969:                                        "CreditCard", lookupFields);
4970:                            } else if ("GIFT_CARD".equals(paymentMethodTypeId)) {
4971:                                pmObj = delegator.findByPrimaryKey("GiftCard",
4972:                                        lookupFields);
4973:                            } else if ("EFT_ACCOUNT"
4974:                                    .equals(paymentMethodTypeId)) {
4975:                                pmObj = delegator.findByPrimaryKey(
4976:                                        "EftAccount", lookupFields);
4977:                            } else if ("EXT_BILLACT"
4978:                                    .equals(paymentMethodTypeId)) {
4979:                                pmObj = delegator.findByPrimaryKey(
4980:                                        "BillingAccount", lookupFields);
4981:                            }
4982:                            if (pmObj != null) {
4983:                                postalAddress = pmObj
4984:                                        .getRelatedOne("PostalAddress");
4985:                            } else {
4986:                                Debug.logInfo(
4987:                                        "No PaymentMethod Object Found - "
4988:                                                + paymentMethodId, module);
4989:                            }
4990:                        } catch (GenericEntityException e) {
4991:                            Debug.logError(e, module);
4992:                        }
4993:                    }
4994:
4995:                    return postalAddress;
4996:                }
4997:
4998:                public List makeOrderPaymentInfos(GenericDelegator delegator) {
4999:                    GenericValue valueObj = this .getValueObject(delegator);
5000:                    List values = new LinkedList();
5001:                    if (valueObj != null) {
5002:                        // first create a BILLING_LOCATION for the payment method address if there is one
5003:                        if ("PaymentMethod".equals(valueObj.getEntityName())) {
5004:                            //String paymentMethodTypeId = valueObj.getString("paymentMethodTypeId");
5005:                            //String paymentMethodId = valueObj.getString("paymentMethodId");
5006:                            //Map lookupFields = UtilMisc.toMap("paymentMethodId", paymentMethodId);
5007:                            String billingAddressId = null;
5008:
5009:                            GenericValue billingAddress = this 
5010:                                    .getBillingAddress(delegator);
5011:                            if (billingAddress != null) {
5012:                                billingAddressId = billingAddress
5013:                                        .getString("contactMechId");
5014:                            }
5015:
5016:                            if (UtilValidate.isNotEmpty(billingAddressId)) {
5017:                                GenericValue orderCm = delegator.makeValue(
5018:                                        "OrderContactMech", null);
5019:                                orderCm.set("contactMechPurposeTypeId",
5020:                                        "BILLING_LOCATION");
5021:                                orderCm.set("contactMechId", billingAddressId);
5022:                                values.add(orderCm);
5023:                            }
5024:                        }
5025:
5026:                        BigDecimal amountBd = new BigDecimal(amount
5027:                                .doubleValue());
5028:                        amountBd = amountBd.setScale(scale, rounding);
5029:
5030:                        // create the OrderPaymentPreference record
5031:                        GenericValue opp = delegator.makeValue(
5032:                                "OrderPaymentPreference", new HashMap());
5033:                        opp.set("paymentMethodTypeId", valueObj
5034:                                .getString("paymentMethodTypeId"));
5035:                        opp.set("presentFlag", isPresent ? "Y" : "N");
5036:                        opp.set("overflowFlag", overflow ? "Y" : "N");
5037:                        opp.set("paymentMethodId", paymentMethodId);
5038:                        opp.set("finAccountId", finAccountId);
5039:                        opp.set("billingPostalCode", postalCode);
5040:                        opp.set("maxAmount", amountBd);
5041:                        if (refNum != null) {
5042:                            opp.set("manualRefNum", refNum[0]);
5043:                            opp.set("manualAuthCode", refNum[1]);
5044:                        }
5045:                        if (securityCode != null) {
5046:                            opp.set("securityCode", securityCode);
5047:                        }
5048:                        if (paymentMethodId != null
5049:                                || "FIN_ACCOUNT".equals(paymentMethodTypeId)) {
5050:                            opp.set("statusId", "PAYMENT_NOT_AUTH");
5051:                        } else if (paymentMethodTypeId != null) {
5052:                            // external payment method types require notification when received
5053:                            // internal payment method types are assumed to be in-hand
5054:                            if (paymentMethodTypeId.startsWith("EXT_")) {
5055:                                opp.set("statusId", "PAYMENT_NOT_RECEIVED");
5056:                            } else {
5057:                                opp.set("statusId", "PAYMENT_RECEIVED");
5058:                            }
5059:                        }
5060:                        Debug.log("Creating OrderPaymentPreference - " + opp,
5061:                                module);
5062:                        values.add(opp);
5063:                    }
5064:
5065:                    return values;
5066:                }
5067:
5068:                public int compareTo(Object o) {
5069:                    CartPaymentInfo that = (CartPaymentInfo) o;
5070:                    Debug.logInfo("Compare [" + this .toString() + "] to ["
5071:                            + that.toString() + "]", module);
5072:                    if (this .paymentMethodId != null) {
5073:                        if (that.paymentMethodId == null) {
5074:                            return 1;
5075:                        } else {
5076:                            int pmCmp = this .paymentMethodId
5077:                                    .compareTo(that.paymentMethodId);
5078:                            if (pmCmp == 0) {
5079:                                if (this .refNum != null
5080:                                        && this .refNum[0] != null) {
5081:                                    if (that.refNum != null
5082:                                            && that.refNum[0] != null) {
5083:                                        return this .refNum[0]
5084:                                                .compareTo(that.refNum[0]);
5085:                                    } else {
5086:                                        return 1;
5087:                                    }
5088:                                } else {
5089:                                    if (that.refNum != null
5090:                                            && that.refNum[0] != null) {
5091:                                        return -1;
5092:                                    } else {
5093:                                        return 0;
5094:                                    }
5095:                                }
5096:                            } else {
5097:                                return pmCmp;
5098:                            }
5099:                        }
5100:                    } else {
5101:                        if (that.paymentMethodId != null) {
5102:                            return -1;
5103:                        } else {
5104:                            int pmtCmp = this .paymentMethodTypeId
5105:                                    .compareTo(that.paymentMethodTypeId);
5106:                            if (pmtCmp == 0) {
5107:                                if (this .refNum != null
5108:                                        && this .refNum[0] != null) {
5109:                                    if (that.refNum != null
5110:                                            && that.refNum[0] != null) {
5111:                                        return this .refNum[0]
5112:                                                .compareTo(that.refNum[0]);
5113:                                    } else {
5114:                                        return 1;
5115:                                    }
5116:                                } else {
5117:                                    if (that.refNum != null
5118:                                            && that.refNum[0] != null) {
5119:                                        return -1;
5120:                                    } else {
5121:                                        return 0;
5122:                                    }
5123:                                }
5124:                            } else {
5125:                                return pmtCmp;
5126:                            }
5127:                        }
5128:                    }
5129:                }
5130:
5131:                public String toString() {
5132:                    return "Pm: " + paymentMethodId + " / PmType: "
5133:                            + paymentMethodTypeId + " / Amt: " + amount
5134:                            + " / Ref: " + refNum[0] + "!" + refNum[1];
5135:                }
5136:            }
5137:
5138:            protected void finalize() throws Throwable {
5139:                // 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();
5140:                super.finalize();
5141:            }
5142:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.