Source Code Cross Referenced for ShoppingCartItem.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.math.BigDecimal;
0021:        import java.sql.Timestamp;
0022:        import java.util.ArrayList;
0023:        import java.util.Arrays;
0024:        import java.util.HashMap;
0025:        import java.util.Iterator;
0026:        import java.util.LinkedList;
0027:        import java.util.List;
0028:        import java.util.Locale;
0029:        import java.util.Map;
0030:        import java.util.Set;
0031:
0032:        import javolution.util.FastMap;
0033:
0034:        import org.apache.commons.collections.set.ListOrderedSet;
0035:        import org.ofbiz.base.util.Debug;
0036:        import org.ofbiz.base.util.GeneralException;
0037:        import org.ofbiz.base.util.UtilDateTime;
0038:        import org.ofbiz.base.util.UtilFormatOut;
0039:        import org.ofbiz.base.util.UtilMisc;
0040:        import org.ofbiz.base.util.UtilProperties;
0041:        import org.ofbiz.base.util.UtilValidate;
0042:        import org.ofbiz.entity.GenericDelegator;
0043:        import org.ofbiz.entity.GenericEntityException;
0044:        import org.ofbiz.entity.GenericPK;
0045:        import org.ofbiz.entity.GenericValue;
0046:        import org.ofbiz.entity.condition.EntityExpr;
0047:        import org.ofbiz.entity.condition.EntityOperator;
0048:        import org.ofbiz.entity.util.EntityUtil;
0049:        import org.ofbiz.order.order.OrderReadHelper;
0050:        import org.ofbiz.order.shoppingcart.product.ProductPromoWorker;
0051:        import org.ofbiz.order.shoppinglist.ShoppingListEvents;
0052:        import org.ofbiz.product.catalog.CatalogWorker;
0053:        import org.ofbiz.product.category.CategoryWorker;
0054:        import org.ofbiz.product.config.ProductConfigWrapper;
0055:        import org.ofbiz.product.product.ProductContentWrapper;
0056:        import org.ofbiz.product.product.ProductWorker;
0057:        import org.ofbiz.product.store.ProductStoreWorker;
0058:        import org.ofbiz.service.GenericServiceException;
0059:        import org.ofbiz.service.LocalDispatcher;
0060:        import org.ofbiz.service.ModelService;
0061:        import org.ofbiz.service.ServiceUtil;
0062:
0063:        /**
0064:         * <p><b>Title:</b> ShoppingCartItem.java
0065:         * <p><b>Description:</b> Shopping cart item object.
0066:         */
0067:        public class ShoppingCartItem implements  java.io.Serializable {
0068:
0069:            public static String module = ShoppingCartItem.class.getName();
0070:            public static final String resource = "OrderUiLabels";
0071:            public static final String resource_error = "OrderErrorUiLabels";
0072:            public static String[] attributeNames = { "shoppingListId",
0073:                    "shoppingListItemSeqId", "surveyResponses",
0074:                    "itemDesiredDeliveryDate", "itemComment" };
0075:
0076:            private transient GenericDelegator delegator = null;
0077:            /** the actual or variant product */
0078:            private transient GenericValue _product = null;
0079:            /** the virtual product if _product is a variant */
0080:            private transient GenericValue _parentProduct = null;
0081:
0082:            private String delegatorName = null;
0083:            private String prodCatalogId = null;
0084:            private String productId = null;
0085:            private String parentProductId = null;
0086:            private String externalId = null;
0087:            /** ends up in orderItemTypeId */
0088:            private String itemType = null;
0089:            private ShoppingCart.ShoppingCartItemGroup itemGroup = null;
0090:            private String productCategoryId = null;
0091:            private String itemDescription = null;
0092:            /** for reservations: date start*/
0093:            private Timestamp reservStart = null;
0094:            /** for reservations: length */
0095:            private double reservLength = 0;
0096:            /** for reservations: number of persons using */
0097:            private double reservPersons = 0;
0098:            private double quantity = 0.0;
0099:            private double basePrice = 0.0;
0100:            private Double displayPrice = null;
0101:            private Double recurringBasePrice = null;
0102:            private Double recurringDisplayPrice = null;
0103:            /** comes from price calc, used for special promo price promotion action */
0104:            private Double specialPromoPrice = null;
0105:            /** for reservations: extra % 2nd person */
0106:            private double reserv2ndPPPerc = 0.0;
0107:            /** for reservations: extra % Nth person */
0108:            private double reservNthPPPerc = 0.0;
0109:            private double listPrice = 0.0;
0110:            /** flag to know if the price have been modified */
0111:            private boolean isModifiedPrice = false;
0112:            private double selectedAmount = 0.0;
0113:            private String requirementId = null;
0114:            private String quoteId = null;
0115:            private String quoteItemSeqId = null;
0116:            // The following three optional fields are used to collect information for the OrderItemAssoc entity 
0117:            private String associatedOrderId = null; // the order Id, if any, to which the given item is associated (typically a sales order item can be associated to a purchase order item, for example in drop shipments)
0118:            private String associatedOrderItemSeqId = null; // the order item Id, if any, to which the given item is associated
0119:            private String orderItemAssocTypeId = "PURCHASE_ORDER"; // the type of association between this item and an external item; by default, for backward compatibility, a PURCHASE association is used (i.e. the extarnal order is a sales order and this item is a purchase order item created to fulfill the sales order item
0120:
0121:            private String statusId = null;
0122:            private Map orderItemAttributes = null;
0123:            private Map attributes = null;
0124:            private String orderItemSeqId = null;
0125:            private Locale locale = null;
0126:            private Timestamp shipBeforeDate = null;
0127:            private Timestamp shipAfterDate = null;
0128:
0129:            private Map contactMechIdsMap = FastMap.newInstance();
0130:            private List orderItemPriceInfos = null;
0131:            private List itemAdjustments = new LinkedList();
0132:            private boolean isPromo = false;
0133:            private double promoQuantityUsed = 0;
0134:            private Map quantityUsedPerPromoCandidate = new HashMap();
0135:            private Map quantityUsedPerPromoFailed = new HashMap();
0136:            private Map quantityUsedPerPromoActual = new HashMap();
0137:            private Map additionalProductFeatureAndAppls = new HashMap();
0138:            private List alternativeOptionProductIds = null;
0139:            private ProductConfigWrapper configWrapper = null;
0140:            private List featuresForSupplier = new LinkedList();
0141:
0142:            /**
0143:             * Makes a ShoppingCartItem for a purchase order item and adds it to the cart.
0144:             * NOTE: This method will get the product entity and check to make sure it can be purchased.
0145:             *
0146:             * @param cartLocation The location to place this item; null will place at the end
0147:             * @param productId The primary key of the product being added
0148:             * @param quantity The quantity to add
0149:             * @param additionalProductFeatureAndAppls Product feature/appls map
0150:             * @param attributes All unique attributes for this item (NOT features)
0151:             * @param prodCatalogId The catalog this item was added from
0152:             * @param configWrapper The product configuration wrapper (null if the product is not configurable)
0153:             * @param dispatcher LocalDispatcher object for doing promotions, etc
0154:             * @param cart The parent shopping cart object this item will belong to
0155:             * @param supplierProduct GenericValue of SupplierProduct entity, containing product description and prices
0156:             * @param shipBeforeDate Request that the shipment be made before this date
0157:             * @param shipAfterDate Request that the shipment be made after this date
0158:             * @return a new ShoppingCartItem object
0159:             * @throws CartItemModifyException
0160:             */
0161:            public static ShoppingCartItem makePurchaseOrderItem(
0162:                    Integer cartLocation, String productId,
0163:                    Double selectedAmountDbl, double quantity,
0164:                    Map additionalProductFeatureAndAppls, Map attributes,
0165:                    String prodCatalogId, ProductConfigWrapper configWrapper,
0166:                    String itemType,
0167:                    ShoppingCart.ShoppingCartItemGroup itemGroup,
0168:                    LocalDispatcher dispatcher, ShoppingCart cart,
0169:                    GenericValue supplierProduct, Timestamp shipBeforeDate,
0170:                    Timestamp shipAfterDate) throws CartItemModifyException,
0171:                    ItemNotFoundException {
0172:                GenericDelegator delegator = cart.getDelegator();
0173:                GenericValue product = null;
0174:
0175:                try {
0176:                    product = delegator.findByPrimaryKeyCache("Product",
0177:                            UtilMisc.toMap("productId", productId));
0178:                } catch (GenericEntityException e) {
0179:                    Debug.logWarning(e.toString(), module);
0180:                    product = null;
0181:                }
0182:
0183:                if (product == null) {
0184:                    Map messageMap = UtilMisc.toMap("productId", productId);
0185:
0186:                    String excMsg = UtilProperties.getMessage(resource,
0187:                            "item.product_not_found", messageMap, cart
0188:                                    .getLocale());
0189:
0190:                    Debug.logWarning(excMsg, module);
0191:                    throw new ItemNotFoundException(excMsg);
0192:                }
0193:                ShoppingCartItem newItem = new ShoppingCartItem(product,
0194:                        additionalProductFeatureAndAppls, attributes,
0195:                        prodCatalogId, configWrapper, cart.getLocale(),
0196:                        itemType, itemGroup, null);
0197:
0198:                // check to see if product is virtual
0199:                if ("Y".equals(product.getString("isVirtual"))) {
0200:                    Map messageMap = UtilMisc.toMap("productName", product
0201:                            .getString("productName"), "productId", product
0202:                            .getString("productId"));
0203:
0204:                    String excMsg = UtilProperties.getMessage(resource,
0205:                            "item.cannot_add_product_virtual", messageMap, cart
0206:                                    .getLocale());
0207:
0208:                    Debug.logWarning(excMsg, module);
0209:                    throw new CartItemModifyException(excMsg);
0210:                }
0211:
0212:                // Timestamp nowTimestamp = UtilDateTime.nowTimestamp();
0213:
0214:                // check to see if the product is fully configured
0215:                if ("AGGREGATED".equals(product.getString("productTypeId"))) {
0216:                    if (configWrapper == null || !configWrapper.isCompleted()) {
0217:                        Map messageMap = UtilMisc.toMap("productName", product
0218:                                .getString("productName"), "productId", product
0219:                                .getString("productId"));
0220:
0221:                        String excMsg = UtilProperties
0222:                                .getMessage(
0223:                                        resource,
0224:                                        "item.cannot_add_product_not_configured_correctly",
0225:                                        messageMap, cart.getLocale());
0226:
0227:                        Debug.logWarning(excMsg, module);
0228:                        throw new CartItemModifyException(excMsg);
0229:                    }
0230:                }
0231:
0232:                // add to cart before setting quantity so that we can get order total, etc
0233:                if (cartLocation == null) {
0234:                    cart.addItemToEnd(newItem);
0235:                } else {
0236:                    cart.addItem(cartLocation.intValue(), newItem);
0237:                }
0238:
0239:                if (selectedAmountDbl != null) {
0240:                    newItem.setSelectedAmount(selectedAmountDbl.doubleValue());
0241:                }
0242:
0243:                // set the ship before/after dates.  this needs to happen before setQuantity because setQuantity causes the ship group's dates to be
0244:                // checked versus the cart item's
0245:                newItem
0246:                        .setShipBeforeDate(shipBeforeDate != null ? shipBeforeDate
0247:                                : cart.getDefaultShipBeforeDate());
0248:                newItem.setShipAfterDate(shipAfterDate != null ? shipAfterDate
0249:                        : cart.getDefaultShipAfterDate());
0250:
0251:                try {
0252:                    newItem.setQuantity(quantity, dispatcher, cart, true);
0253:                } catch (CartItemModifyException e) {
0254:                    cart.removeCartItem(cart.getItemIndex(newItem), dispatcher);
0255:                    cart.clearItemShipInfo(newItem);
0256:                    cart.removeEmptyCartItems();
0257:                    throw e;
0258:                }
0259:
0260:                // specific for purchase orders - description is set to supplierProductId + supplierProductName, price set to lastPrice of SupplierProduct
0261:                // if supplierProduct has no supplierProductName, use the regular supplierProductId
0262:                if (supplierProduct != null) {
0263:                    newItem.setName(getPurchaseOrderItemDescription(product,
0264:                            supplierProduct, cart.getLocale()));
0265:                    newItem.setBasePrice(supplierProduct.getDouble("lastPrice")
0266:                            .doubleValue());
0267:                } else {
0268:                    newItem.setName(product.getString("internalName"));
0269:                }
0270:                return newItem;
0271:
0272:            }
0273:
0274:            /**
0275:             * Makes a ShoppingCartItem and adds it to the cart.
0276:             * NOTE: This method will get the product entity and check to make sure it can be purchased.
0277:             *
0278:             * @param cartLocation The location to place this item; null will place at the end
0279:             * @param productId The primary key of the product being added
0280:             * @param selectedAmountDbl Optional. Defaults to 0.0. If a selectedAmount is needed (complements the quantity value), pass it in here.
0281:             * @param quantity Required. The quantity to add.
0282:             * @param unitPriceDbl Optional. Defaults to 0.0, which causes calculation of price.
0283:             * @param reservStart Optional. The start of the reservation.
0284:             * @param reservLengthDbl Optional. The length of the reservation.
0285:             * @param reservPersonsDbl Optional. The number of persons taking advantage of the reservation.
0286:             * @param shipBeforeDate Optional. The date to ship the order by.
0287:             * @param shipAfterDate Optional. Wait until this date to ship.
0288:             * @param additionalProductFeatureAndAppls Optional. Product feature/appls map.
0289:             * @param attributes Optional. All unique attributes for this item (NOT features).
0290:             * @param prodCatalogId Optional, but strongly recommended. The catalog this item was added from.
0291:             * @param configWrapper Optional. The product configuration wrapper (null if the product is not configurable).
0292:             * @param itemType Optional. Specifies the type of cart item, corresponds to an OrderItemType and should be a valid orderItemTypeId.
0293:             * @param itemGroup Optional. Specifies which item group in the cart this should belong to, if item groups are needed/desired.
0294:             * @param dispatcher Required (for price calculation, promos, etc). LocalDispatcher object for doing promotions, etc.
0295:             * @param cart Required. The parent shopping cart object this item will belong to.
0296:             * @param triggerExternalOpsBool Optional. Defaults to true. Trigger external operations (like promotions and such)?
0297:             * @param triggerPriceRulesBool Optional. Defaults to true. Trigger the price rules to calculate the price for this item?
0298:             * 
0299:             * @return a new ShoppingCartItem object
0300:             * @throws CartItemModifyException
0301:             */
0302:            public static ShoppingCartItem makeItem(Integer cartLocation,
0303:                    String productId, Double selectedAmountDbl,
0304:                    double quantity, Double unitPriceDbl,
0305:                    Timestamp reservStart, Double reservLengthDbl,
0306:                    Double reservPersonsDbl, Timestamp shipBeforeDate,
0307:                    Timestamp shipAfterDate,
0308:                    Map additionalProductFeatureAndAppls, Map attributes,
0309:                    String prodCatalogId, ProductConfigWrapper configWrapper,
0310:                    String itemType,
0311:                    ShoppingCart.ShoppingCartItemGroup itemGroup,
0312:                    LocalDispatcher dispatcher, ShoppingCart cart,
0313:                    Boolean triggerExternalOpsBool,
0314:                    Boolean triggerPriceRulesBool, String parentProductId,
0315:                    Boolean skipInventoryChecks, Boolean skipProductChecks)
0316:                    throws CartItemModifyException, ItemNotFoundException {
0317:                GenericDelegator delegator = cart.getDelegator();
0318:                GenericValue product = null;
0319:                GenericValue parentProduct = null;
0320:
0321:                try {
0322:                    product = delegator.findByPrimaryKeyCache("Product",
0323:                            UtilMisc.toMap("productId", productId));
0324:
0325:                    // first see if there is a purchase allow category and if this product is in it or not
0326:                    String purchaseProductCategoryId = CatalogWorker
0327:                            .getCatalogPurchaseAllowCategoryId(delegator,
0328:                                    prodCatalogId);
0329:                    if (product != null && purchaseProductCategoryId != null) {
0330:                        if (!CategoryWorker.isProductInCategory(delegator,
0331:                                product.getString("productId"),
0332:                                purchaseProductCategoryId)) {
0333:                            // a Purchase allow productCategoryId was found, but the product is not in the category, axe it...
0334:                            product = null;
0335:                        }
0336:                    }
0337:                } catch (GenericEntityException e) {
0338:                    Debug.logWarning(e.toString(), module);
0339:                    product = null;
0340:                }
0341:
0342:                if (product == null) {
0343:                    Map messageMap = UtilMisc.toMap("productId", productId);
0344:                    String excMsg = UtilProperties.getMessage(resource,
0345:                            "item.product_not_found", messageMap, cart
0346:                                    .getLocale());
0347:
0348:                    Debug.logWarning(excMsg, module);
0349:                    throw new ItemNotFoundException(excMsg);
0350:                }
0351:
0352:                if (parentProductId != null) {
0353:                    try {
0354:                        parentProduct = delegator.findByPrimaryKeyCache(
0355:                                "Product", UtilMisc.toMap("productId",
0356:                                        parentProductId));
0357:                    } catch (GenericEntityException e) {
0358:                        Debug.logWarning(e.toString(), module);
0359:                        parentProduct = null;
0360:                    }
0361:                }
0362:                return makeItem(cartLocation, product, selectedAmountDbl,
0363:                        quantity, unitPriceDbl, reservStart, reservLengthDbl,
0364:                        reservPersonsDbl, shipBeforeDate, shipAfterDate,
0365:                        additionalProductFeatureAndAppls, attributes,
0366:                        prodCatalogId, configWrapper, itemType, itemGroup,
0367:                        dispatcher, cart, triggerExternalOpsBool,
0368:                        triggerPriceRulesBool, parentProduct,
0369:                        skipInventoryChecks, skipProductChecks);
0370:            }
0371:
0372:            /**
0373:             * Makes a ShoppingCartItem and adds it to the cart.
0374:             * WARNING: This method does not check if the product is in a purchase category.
0375:             * rental fields were added.
0376:             *
0377:             * @param cartLocation The location to place this item; null will place at the end
0378:             * @param product The product entity relating to the product being added
0379:             * @param selectedAmountDbl Optional. Defaults to 0.0. If a selectedAmount is needed (complements the quantity value), pass it in here.
0380:             * @param quantity Required. The quantity to add.
0381:             * @param unitPriceDbl Optional. Defaults to 0.0, which causes calculation of price.
0382:             * @param reservStart Optional. The start of the reservation.
0383:             * @param reservLengthDbl Optional. The length of the reservation.
0384:             * @param reservPersonsDbl Optional. The number of persons taking advantage of the reservation.
0385:             * @param shipBeforeDate Optional. The date to ship the order by.
0386:             * @param shipAfterDate Optional. Wait until this date to ship.
0387:             * @param additionalProductFeatureAndAppls Optional. Product feature/appls map.
0388:             * @param attributes Optional. All unique attributes for this item (NOT features).
0389:             * @param prodCatalogId Optional, but strongly recommended. The catalog this item was added from.
0390:             * @param configWrapper Optional. The product configuration wrapper (null if the product is not configurable).
0391:             * @param itemType Optional. Specifies the type of cart item, corresponds to an OrderItemType and should be a valid orderItemTypeId.
0392:             * @param itemGroup Optional. Specifies which item group in the cart this should belong to, if item groups are needed/desired.
0393:             * @param dispatcher Required (for price calculation, promos, etc). LocalDispatcher object for doing promotions, etc.
0394:             * @param cart Required. The parent shopping cart object this item will belong to.
0395:             * @param triggerExternalOpsBool Optional. Defaults to true. Trigger external operations (like promotions and such)?
0396:             * @param triggerPriceRulesBool Optional. Defaults to true. Trigger the price rules to calculate the price for this item?
0397:             * 
0398:             * @return a new ShoppingCartItem object
0399:             * @throws CartItemModifyException
0400:             */
0401:            public static ShoppingCartItem makeItem(Integer cartLocation,
0402:                    GenericValue product, Double selectedAmountDbl,
0403:                    double quantity, Double unitPriceDbl,
0404:                    Timestamp reservStart, Double reservLengthDbl,
0405:                    Double reservPersonsDbl, Timestamp shipBeforeDate,
0406:                    Timestamp shipAfterDate,
0407:                    Map additionalProductFeatureAndAppls, Map attributes,
0408:                    String prodCatalogId, ProductConfigWrapper configWrapper,
0409:                    String itemType,
0410:                    ShoppingCart.ShoppingCartItemGroup itemGroup,
0411:                    LocalDispatcher dispatcher, ShoppingCart cart,
0412:                    Boolean triggerExternalOpsBool,
0413:                    Boolean triggerPriceRulesBool, GenericValue parentProduct,
0414:                    Boolean skipInventoryChecks, Boolean skipProductChecks)
0415:                    throws CartItemModifyException {
0416:
0417:                ShoppingCartItem newItem = new ShoppingCartItem(product,
0418:                        additionalProductFeatureAndAppls, attributes,
0419:                        prodCatalogId, configWrapper, cart.getLocale(),
0420:                        itemType, itemGroup, parentProduct);
0421:
0422:                double selectedAmount = selectedAmountDbl == null ? 0.0
0423:                        : selectedAmountDbl.doubleValue();
0424:                double unitPrice = unitPriceDbl == null ? 0.0 : unitPriceDbl
0425:                        .doubleValue();
0426:                double reservLength = reservLengthDbl == null ? 0.0
0427:                        : reservLengthDbl.doubleValue();
0428:                double reservPersons = reservPersonsDbl == null ? 0.0
0429:                        : reservPersonsDbl.doubleValue();
0430:                boolean triggerPriceRules = triggerPriceRulesBool == null ? true
0431:                        : triggerPriceRulesBool.booleanValue();
0432:                boolean triggerExternalOps = triggerExternalOpsBool == null ? true
0433:                        : triggerExternalOpsBool.booleanValue();
0434:
0435:                // check to see if product is virtual
0436:                if ("Y".equals(product.getString("isVirtual"))) {
0437:                    Map messageMap = UtilMisc.toMap("productName", product
0438:                            .getString("productName"), "productId", product
0439:                            .getString("productId"));
0440:
0441:                    String excMsg = UtilProperties.getMessage(resource,
0442:                            "item.cannot_add_product_virtual", messageMap, cart
0443:                                    .getLocale());
0444:
0445:                    Debug.logWarning(excMsg, module);
0446:                    throw new CartItemModifyException(excMsg);
0447:                }
0448:
0449:                java.sql.Timestamp nowTimestamp = UtilDateTime.nowTimestamp();
0450:
0451:                if (!skipProductChecks.booleanValue()) {
0452:                    // check to see if introductionDate hasn't passed yet
0453:                    if (product.get("introductionDate") != null
0454:                            && nowTimestamp.before(product
0455:                                    .getTimestamp("introductionDate"))) {
0456:                        Map messageMap = UtilMisc.toMap("productName", product
0457:                                .getString("productName"), "productId", product
0458:                                .getString("productId"));
0459:
0460:                        String excMsg = UtilProperties.getMessage(resource,
0461:                                "item.cannot_add_product_not_yet_available",
0462:                                messageMap, cart.getLocale());
0463:
0464:                        Debug.logWarning(excMsg, module);
0465:                        throw new CartItemModifyException(excMsg);
0466:                    }
0467:
0468:                    // check to see if salesDiscontinuationDate has passed
0469:                    if (product.get("salesDiscontinuationDate") != null
0470:                            && nowTimestamp.after(product
0471:                                    .getTimestamp("salesDiscontinuationDate"))) {
0472:                        Map messageMap = UtilMisc.toMap("productName", product
0473:                                .getString("productName"), "productId", product
0474:                                .getString("productId"));
0475:
0476:                        String excMsg = UtilProperties.getMessage(resource,
0477:                                "item.cannot_add_product_no_longer_available",
0478:                                messageMap, cart.getLocale());
0479:
0480:                        Debug.logWarning(excMsg, module);
0481:                        throw new CartItemModifyException(excMsg);
0482:                    }
0483:                    /*
0484:                    if (product.get("salesDiscWhenNotAvail") != null && "Y".equals(product.getString("salesDiscWhenNotAvail"))) {
0485:                        // check atp and if <= 0 then the product is no more available because
0486:                        // all the units in warehouse are reserved by other sales orders and no new purchase orders will be done 
0487:                        // for this product.
0488:                        if (!newItem.isInventoryAvailableOrNotRequired(quantity, cart.getProductStoreId(), dispatcher)) {
0489:                            Map messageMap = UtilMisc.toMap("productName", product.getString("productName"), 
0490:                                                            "productId", product.getString("productId"));
0491:
0492:                            String excMsg = UtilProperties.getMessage(resource, "item.cannot_add_product_no_longer_available",
0493:                                                          messageMap , cart.getLocale() );
0494:
0495:                            Debug.logWarning(excMsg, module);
0496:                            throw new CartItemModifyException(excMsg);
0497:                        }
0498:                    }
0499:                     */
0500:                }
0501:                // check to see if the product is a rental item
0502:                if ("ASSET_USAGE".equals(product.getString("productTypeId"))) {
0503:                    if (reservStart == null) {
0504:                        String excMsg = UtilProperties.getMessage(resource,
0505:                                "item.missing_reservation_starting_date", cart
0506:                                        .getLocale());
0507:                        throw new CartItemModifyException(excMsg);
0508:                    }
0509:
0510:                    if (reservStart.before(UtilDateTime.nowTimestamp())) {
0511:                        String excMsg = UtilProperties.getMessage(resource,
0512:                                "item.reservation_from_tomorrow", cart
0513:                                        .getLocale());
0514:                        throw new CartItemModifyException(excMsg);
0515:                    }
0516:                    newItem.setReservStart(reservStart);
0517:
0518:                    if (reservLength < 1) {
0519:                        String excMsg = UtilProperties.getMessage(resource,
0520:                                "item.number_of_days", cart.getLocale());
0521:                        throw new CartItemModifyException(excMsg);
0522:                    }
0523:                    newItem.setReservLength(reservLength);
0524:
0525:                    if (product.get("reservMaxPersons") != null) {
0526:                        double reservMaxPersons = product.getDouble(
0527:                                "reservMaxPersons").doubleValue();
0528:                        if (reservMaxPersons < reservPersons) {
0529:                            Map messageMap = UtilMisc.toMap("reservMaxPersons",
0530:                                    product.getString("reservMaxPersons"),
0531:                                    "reservPersons",
0532:                                    (new Double(reservPersons)).toString());
0533:                            String excMsg = UtilProperties.getMessage(resource,
0534:                                    "item.maximum_number_of_person_renting",
0535:                                    messageMap, cart.getLocale());
0536:
0537:                            Debug.logInfo(excMsg, module);
0538:                            throw new CartItemModifyException(excMsg);
0539:                        }
0540:                    }
0541:                    newItem.setReservPersons(reservPersons);
0542:
0543:                    if (product.get("reserv2ndPPPerc") != null)
0544:                        newItem.setReserv2ndPPPerc(product.getDouble(
0545:                                "reserv2ndPPPerc").doubleValue());
0546:
0547:                    if (product.get("reservNthPPPerc") != null)
0548:                        newItem.setReservNthPPPerc(product.getDouble(
0549:                                "reservNthPPPerc").doubleValue());
0550:
0551:                    // check to see if the related fixed asset is available for rent
0552:                    String isAvailable = checkAvailability(product
0553:                            .getString("productId"), quantity, reservStart,
0554:                            reservLength, cart);
0555:                    if (isAvailable.compareTo("OK") != 0) {
0556:                        Map messageMap = UtilMisc.toMap("productId", product
0557:                                .getString("productId"), "availableMessage",
0558:                                isAvailable);
0559:                        String excMsg = UtilProperties.getMessage(resource,
0560:                                "item.product_not_available", messageMap, cart
0561:                                        .getLocale());
0562:                        Debug.logInfo(excMsg, module);
0563:                        throw new CartItemModifyException(isAvailable);
0564:                    }
0565:                }
0566:
0567:                // check to see if the product is fully configured
0568:                if ("AGGREGATED".equals(product.getString("productTypeId"))) {
0569:                    if (configWrapper == null || !configWrapper.isCompleted()) {
0570:                        Map messageMap = UtilMisc.toMap("productName", product
0571:                                .getString("productName"), "productId", product
0572:                                .getString("productId"));
0573:                        String excMsg = UtilProperties
0574:                                .getMessage(
0575:                                        resource,
0576:                                        "item.cannot_add_product_not_configured_correctly",
0577:                                        messageMap, cart.getLocale());
0578:                        Debug.logWarning(excMsg, module);
0579:                        throw new CartItemModifyException(excMsg);
0580:                    }
0581:                }
0582:
0583:                // set the ship before and after dates (defaults to cart ship before/after dates)
0584:                newItem
0585:                        .setShipBeforeDate(shipBeforeDate != null ? shipBeforeDate
0586:                                : cart.getDefaultShipBeforeDate());
0587:                newItem.setShipAfterDate(shipAfterDate != null ? shipAfterDate
0588:                        : cart.getDefaultShipAfterDate());
0589:
0590:                // set the product unit price as base price
0591:                // if triggerPriceRules is true this price will be overriden
0592:                newItem.setBasePrice(unitPrice);
0593:
0594:                // add to cart before setting quantity so that we can get order total, etc
0595:                if (cartLocation == null) {
0596:                    cart.addItemToEnd(newItem);
0597:                } else {
0598:                    cart.addItem(cartLocation.intValue(), newItem);
0599:                }
0600:
0601:                // We have to set the selectedAmount before calling setQuantity because
0602:                // selectedAmount changes the item's base price (used in the updatePrice
0603:                // method called inside the setQuantity method)
0604:                if (selectedAmount > 0) {
0605:                    newItem.setSelectedAmount(selectedAmount);
0606:                }
0607:
0608:                try {
0609:                    newItem.setQuantity((int) quantity, dispatcher, cart,
0610:                            triggerExternalOps, true, triggerPriceRules,
0611:                            skipInventoryChecks.booleanValue());
0612:                } catch (CartItemModifyException e) {
0613:                    Debug.logWarning(e.getMessage(), module);
0614:                    cart.removeCartItem(cart.getItemIndex(newItem), dispatcher);
0615:                    cart.clearItemShipInfo(newItem);
0616:                    cart.removeEmptyCartItems();
0617:                    throw e;
0618:                }
0619:
0620:                return newItem;
0621:            }
0622:
0623:            /**
0624:             * Makes a non-product ShoppingCartItem and adds it to the cart.
0625:             * NOTE: This is only for non-product items; items without a product entity (work items, bulk items, etc)
0626:             *
0627:             * @param cartLocation The location to place this item; null will place at the end
0628:             * @param itemType The OrderItemTypeId for the item being added
0629:             * @param itemDescription The optional description of the item
0630:             * @param productCategoryId The optional category the product *will* go in
0631:             * @param basePrice The price for this item
0632:             * @param selectedAmount
0633:             * @param quantity The quantity to add
0634:             * @param attributes All unique attributes for this item (NOT features)
0635:             * @param prodCatalogId The catalog this item was added from
0636:             * @param dispatcher LocalDispatcher object for doing promotions, etc
0637:             * @param cart The parent shopping cart object this item will belong to
0638:             * @param triggerExternalOpsBool Indicates if we should run external operations (promotions, auto-save, etc)
0639:             * @return a new ShoppingCartItem object
0640:             * @throws CartItemModifyException
0641:             */
0642:            public static ShoppingCartItem makeItem(Integer cartLocation,
0643:                    String itemType, String itemDescription,
0644:                    String productCategoryId, Double basePrice,
0645:                    Double selectedAmount, double quantity, Map attributes,
0646:                    String prodCatalogId,
0647:                    ShoppingCart.ShoppingCartItemGroup itemGroup,
0648:                    LocalDispatcher dispatcher, ShoppingCart cart,
0649:                    Boolean triggerExternalOpsBool)
0650:                    throws CartItemModifyException {
0651:
0652:                GenericDelegator delegator = cart.getDelegator();
0653:                ShoppingCartItem newItem = new ShoppingCartItem(delegator,
0654:                        itemType, itemDescription, productCategoryId,
0655:                        basePrice, attributes, prodCatalogId, cart.getLocale(),
0656:                        itemGroup);
0657:
0658:                // add to cart before setting quantity so that we can get order total, etc
0659:                if (cartLocation == null) {
0660:                    cart.addItemToEnd(newItem);
0661:                } else {
0662:                    cart.addItem(cartLocation.intValue(), newItem);
0663:                }
0664:
0665:                boolean triggerExternalOps = triggerExternalOpsBool == null ? true
0666:                        : triggerExternalOpsBool.booleanValue();
0667:
0668:                try {
0669:                    newItem.setQuantity(quantity, dispatcher, cart,
0670:                            triggerExternalOps);
0671:                } catch (CartItemModifyException e) {
0672:                    cart.removeEmptyCartItems();
0673:                    throw e;
0674:                }
0675:
0676:                if (selectedAmount != null) {
0677:                    newItem.setSelectedAmount(selectedAmount.doubleValue());
0678:                }
0679:                return newItem;
0680:            }
0681:
0682:            /** Clone an item. */
0683:            public ShoppingCartItem(ShoppingCartItem item) {
0684:                try {
0685:                    this ._product = item.getProduct();
0686:                } catch (IllegalStateException e) {
0687:                    this ._product = null;
0688:                }
0689:                this .delegator = item.getDelegator();
0690:                this .delegatorName = item.delegatorName;
0691:                this .prodCatalogId = item.getProdCatalogId();
0692:                this .productId = item.getProductId();
0693:                this .itemType = item.getItemType();
0694:                this .itemGroup = item.getItemGroup();
0695:                this .productCategoryId = item.getProductCategoryId();
0696:                this .quantity = item.getQuantity();
0697:                this .reservStart = item.getReservStart();
0698:                this .reservLength = item.getReservLength();
0699:                this .reservPersons = item.getReservPersons();
0700:                this .selectedAmount = item.getSelectedAmount();
0701:                this .setBasePrice(item.getBasePrice());
0702:                this .setDisplayPrice(item.getDisplayPrice());
0703:                this .setRecurringBasePrice(item.getRecurringBasePrice());
0704:                this .setRecurringDisplayPrice(item.getRecurringDisplayPrice());
0705:                this .listPrice = item.getListPrice();
0706:                this .reserv2ndPPPerc = item.getReserv2ndPPPerc();
0707:                this .reservNthPPPerc = item.getReservNthPPPerc();
0708:                this .requirementId = item.getRequirementId();
0709:                this .quoteId = item.getQuoteId();
0710:                this .quoteItemSeqId = item.getQuoteItemSeqId();
0711:                this .associatedOrderId = item.getAssociatedOrderId();
0712:                this .associatedOrderItemSeqId = item
0713:                        .getAssociatedOrderItemSeqId();
0714:                this .orderItemAssocTypeId = item.getOrderItemAssocTypeId();
0715:                this .isPromo = item.getIsPromo();
0716:                this .promoQuantityUsed = item.promoQuantityUsed;
0717:                this .locale = item.locale;
0718:                this .quantityUsedPerPromoCandidate = new HashMap(
0719:                        item.quantityUsedPerPromoCandidate);
0720:                this .quantityUsedPerPromoFailed = new HashMap(
0721:                        item.quantityUsedPerPromoFailed);
0722:                this .quantityUsedPerPromoActual = new HashMap(
0723:                        item.quantityUsedPerPromoActual);
0724:                this .orderItemSeqId = item.getOrderItemSeqId();
0725:                this .additionalProductFeatureAndAppls = item
0726:                        .getAdditionalProductFeatureAndAppls() == null ? null
0727:                        : new HashMap(item
0728:                                .getAdditionalProductFeatureAndAppls());
0729:                this .attributes = item.getAttributes() == null ? new HashMap()
0730:                        : new HashMap(item.getAttributes());
0731:                this .contactMechIdsMap = item.getOrderItemContactMechIds() == null ? null
0732:                        : new HashMap(item.getOrderItemContactMechIds());
0733:                this .orderItemPriceInfos = item.getOrderItemPriceInfos() == null ? null
0734:                        : new LinkedList(item.getOrderItemPriceInfos());
0735:                this .itemAdjustments = item.getAdjustments() == null ? null
0736:                        : new LinkedList(item.getAdjustments());
0737:                if (this ._product == null) {
0738:                    this .itemDescription = item.getName();
0739:                }
0740:                if (item.configWrapper != null) {
0741:                    this .configWrapper = new ProductConfigWrapper(
0742:                            item.configWrapper);
0743:                }
0744:            }
0745:
0746:            /** Cannot create shopping cart item with no parameters */
0747:            protected ShoppingCartItem() {
0748:            }
0749:
0750:            /** Creates new ShoppingCartItem object. */
0751:            protected ShoppingCartItem(GenericValue product,
0752:                    Map additionalProductFeatureAndAppls, Map attributes,
0753:                    String prodCatalogId, Locale locale, String itemType,
0754:                    ShoppingCart.ShoppingCartItemGroup itemGroup) {
0755:                this (product, additionalProductFeatureAndAppls, attributes,
0756:                        prodCatalogId, null, locale, itemType, itemGroup, null);
0757:                if (product != null) {
0758:                    String productName = ProductContentWrapper
0759:                            .getProductContentAsText(product, "PRODUCT_NAME",
0760:                                    this .locale, null);
0761:                    // if the productName is null or empty, see if there is an associated virtual product and get the productName of that product
0762:                    if (UtilValidate.isEmpty(productName)) {
0763:                        GenericValue parentProduct = this .getParentProduct();
0764:                        if (parentProduct != null) {
0765:                            productName = ProductContentWrapper
0766:                                    .getProductContentAsText(parentProduct,
0767:                                            "PRODUCT_NAME", this .locale, null);
0768:                        }
0769:                    }
0770:
0771:                    if (productName == null) {
0772:                        this .itemDescription = "";
0773:                    } else {
0774:                        this .itemDescription = productName;
0775:                    }
0776:                }
0777:            }
0778:
0779:            /** Creates new ShoppingCartItem object. */
0780:            protected ShoppingCartItem(GenericValue product,
0781:                    Map additionalProductFeatureAndAppls, Map attributes,
0782:                    String prodCatalogId, ProductConfigWrapper configWrapper,
0783:                    Locale locale, String itemType,
0784:                    ShoppingCart.ShoppingCartItemGroup itemGroup,
0785:                    GenericValue parentProduct) {
0786:                this ._product = product;
0787:                this .productId = _product.getString("productId");
0788:                this ._parentProduct = parentProduct;
0789:                if (parentProduct != null)
0790:                    this .parentProductId = _parentProduct
0791:                            .getString("productId");
0792:                if (UtilValidate.isEmpty(itemType)) {
0793:                    if (_product.getString("productTypeId").equals(
0794:                            "ASSET_USAGE")) {
0795:                        this .itemType = "RENTAL_ORDER_ITEM"; // will create additional workeffort/asset usage records
0796:                    } else {
0797:                        this .itemType = "PRODUCT_ORDER_ITEM";
0798:                    }
0799:                } else {
0800:                    this .itemType = itemType;
0801:                }
0802:                this .itemGroup = itemGroup;
0803:                this .prodCatalogId = prodCatalogId;
0804:                this .attributes = (attributes == null ? FastMap.newInstance()
0805:                        : attributes);
0806:                this .delegator = _product.getDelegator();
0807:                this .delegatorName = _product.getDelegator().getDelegatorName();
0808:                this 
0809:                        .addAllProductFeatureAndAppls(additionalProductFeatureAndAppls);
0810:                this .locale = locale;
0811:                this .configWrapper = configWrapper;
0812:            }
0813:
0814:            /** Creates new ShopingCartItem object. */
0815:            protected ShoppingCartItem(GenericDelegator delegator,
0816:                    String itemTypeId, String description, String categoryId,
0817:                    Double basePrice, Map attributes, String prodCatalogId,
0818:                    Locale locale, ShoppingCart.ShoppingCartItemGroup itemGroup) {
0819:                this .delegator = delegator;
0820:                this .itemType = itemTypeId;
0821:                this .itemGroup = itemGroup;
0822:                this .itemDescription = description;
0823:                this .productCategoryId = categoryId;
0824:                if (basePrice != null) {
0825:                    this .setBasePrice(basePrice.doubleValue());
0826:                    this .setDisplayPrice(basePrice.doubleValue());
0827:                }
0828:                this .attributes = (attributes == null ? FastMap.newInstance()
0829:                        : attributes);
0830:                this .prodCatalogId = prodCatalogId;
0831:                this .delegatorName = delegator.getDelegatorName();
0832:                this .locale = locale;
0833:            }
0834:
0835:            public String getProdCatalogId() {
0836:                return this .prodCatalogId;
0837:            }
0838:
0839:            public void setExternalId(String externalId) {
0840:                this .externalId = externalId;
0841:            }
0842:
0843:            public String getExternalId() {
0844:                return this .externalId;
0845:            }
0846:
0847:            /** Sets the user selected amount */
0848:            public void setSelectedAmount(double selectedAmount) {
0849:                this .selectedAmount = selectedAmount;
0850:            }
0851:
0852:            /** Returns the user selected amount */
0853:            public double getSelectedAmount() {
0854:                return this .selectedAmount;
0855:            }
0856:
0857:            /** Sets the base price for the item; use with caution */
0858:            public void setBasePrice(double basePrice) {
0859:                this .basePrice = basePrice;
0860:            }
0861:
0862:            /** Sets the display price for the item; use with caution */
0863:            public void setDisplayPrice(double displayPrice) {
0864:                this .displayPrice = new Double(displayPrice);
0865:            }
0866:
0867:            /** Sets the base price for the item; use with caution */
0868:            public void setRecurringBasePrice(Double recurringBasePrice) {
0869:                this .recurringBasePrice = recurringBasePrice;
0870:            }
0871:
0872:            /** Sets the display price for the item; use with caution */
0873:            public void setRecurringDisplayPrice(Double recurringDisplayPrice) {
0874:                this .recurringDisplayPrice = recurringDisplayPrice;
0875:            }
0876:
0877:            public void setSpecialPromoPrice(Double specialPromoPrice) {
0878:                this .specialPromoPrice = specialPromoPrice;
0879:            }
0880:
0881:            /** Sets the extra % for second person */
0882:            public void setReserv2ndPPPerc(double reserv2ndPPPerc) {
0883:                this .reserv2ndPPPerc = reserv2ndPPPerc;
0884:            }
0885:
0886:            /** Sets the extra % for third and following person */
0887:            public void setReservNthPPPerc(double reservNthPPPerc) {
0888:                this .reservNthPPPerc = reservNthPPPerc;
0889:            }
0890:
0891:            /** Sets the reservation start date */
0892:            public void setReservStart(Timestamp reservStart) {
0893:                this .reservStart = reservStart;
0894:            }
0895:
0896:            /** Sets the reservation length */
0897:            public void setReservLength(double reservLength) {
0898:                this .reservLength = reservLength;
0899:            }
0900:
0901:            /** Sets number of persons using the reservation */
0902:            public void setReservPersons(double reservPersons) {
0903:                this .reservPersons = reservPersons;
0904:            }
0905:
0906:            /** Sets the quantity for the item and validates the change in quantity, etc */
0907:            public void setQuantity(double quantity,
0908:                    LocalDispatcher dispatcher, ShoppingCart cart)
0909:                    throws CartItemModifyException {
0910:                this .setQuantity(quantity, dispatcher, cart, true);
0911:            }
0912:
0913:            /** Sets the quantity for the item and validates the change in quantity, etc */
0914:            public void setQuantity(double quantity,
0915:                    LocalDispatcher dispatcher, ShoppingCart cart,
0916:                    boolean triggerExternalOps) throws CartItemModifyException {
0917:                this .setQuantity(quantity, dispatcher, cart,
0918:                        triggerExternalOps, true);
0919:            }
0920:
0921:            /** Sets the quantity for the item and validates the change in quantity, etc */
0922:            public void setQuantity(double quantity,
0923:                    LocalDispatcher dispatcher, ShoppingCart cart,
0924:                    boolean triggerExternalOps, boolean resetShipGroup)
0925:                    throws CartItemModifyException {
0926:                this .setQuantity((int) quantity, dispatcher, cart,
0927:                        triggerExternalOps, resetShipGroup, true, false);
0928:            }
0929:
0930:            /** Sets the quantity for the item and validates the change in quantity, etc */
0931:            public void setQuantity(double quantity,
0932:                    LocalDispatcher dispatcher, ShoppingCart cart,
0933:                    boolean triggerExternalOps, boolean resetShipGroup,
0934:                    boolean updateProductPrice) throws CartItemModifyException {
0935:                this .setQuantity((int) quantity, dispatcher, cart,
0936:                        triggerExternalOps, resetShipGroup, updateProductPrice,
0937:                        false);
0938:            }
0939:
0940:            /** returns "OK" when the product can be booked or returns a string with the dates the related fixed Asset is not available */
0941:            public static String checkAvailability(String productId,
0942:                    double quantity, Timestamp reservStart,
0943:                    double reservLength, ShoppingCart cart) {
0944:                GenericDelegator delegator = cart.getDelegator();
0945:                // find related fixedAsset
0946:                List selFixedAssetProduct = null;
0947:                GenericValue fixedAssetProduct = null;
0948:                try {
0949:                    List allFixedAssetProduct = delegator.findByAnd(
0950:                            "FixedAssetProduct", UtilMisc.toMap("productId",
0951:                                    productId, "fixedAssetProductTypeId",
0952:                                    "FAPT_USE"));
0953:                    selFixedAssetProduct = EntityUtil.filterByDate(
0954:                            allFixedAssetProduct, UtilDateTime.nowTimestamp(),
0955:                            "fromDate", "thruDate", true);
0956:                } catch (GenericEntityException e) {
0957:                    Map messageMap = UtilMisc.toMap("productId", productId);
0958:                    String msg = UtilProperties.getMessage(resource,
0959:                            "item.cannot_find_Fixed_Asset", messageMap, cart
0960:                                    .getLocale());
0961:                    return msg;
0962:                }
0963:                if (selFixedAssetProduct != null
0964:                        && selFixedAssetProduct.size() > 0) {
0965:                    Iterator firstOne = selFixedAssetProduct.iterator();
0966:                    fixedAssetProduct = (GenericValue) firstOne.next();
0967:                } else {
0968:                    Map messageMap = UtilMisc.toMap("productId", productId);
0969:                    String msg = UtilProperties.getMessage(resource,
0970:                            "item.cannot_find_Fixed_Asset", messageMap, cart
0971:                                    .getLocale());
0972:                    return msg;
0973:                }
0974:
0975:                // find the fixed asset itself
0976:                GenericValue fixedAsset = null;
0977:                try {
0978:                    fixedAsset = fixedAssetProduct.getRelatedOne("FixedAsset");
0979:                } catch (GenericEntityException e) {
0980:                    Map messageMap = UtilMisc.toMap("fixedAssetId",
0981:                            fixedAssetProduct.getString("fixedAssetId"));
0982:                    String msg = UtilProperties.getMessage(resource,
0983:                            "item.fixed_Asset_not_found", messageMap, cart
0984:                                    .getLocale());
0985:                    return msg;
0986:                }
0987:                if (fixedAsset == null) {
0988:                    Map messageMap = UtilMisc.toMap("fixedAssetId",
0989:                            fixedAssetProduct.getString("fixedAssetId"));
0990:                    String msg = UtilProperties.getMessage(resource,
0991:                            "item.fixed_Asset_not_found", messageMap, cart
0992:                                    .getLocale());
0993:                    return msg;
0994:                }
0995:                //Debug.logInfo("Checking availability for product: " + productId.toString() + " and related FixedAsset: " + fixedAssetProduct.getString("fixedAssetId"),module);
0996:                // see if this fixed asset has a calendar, when no create one and attach to fixed asset
0997:                // DEJ20050725 this isn't being used anywhere, commenting out for now and not assigning from the getRelatedOne: GenericValue techDataCalendar = null;
0998:                GenericValue techDataCalendar = null;
0999:                try {
1000:                    techDataCalendar = fixedAsset
1001:                            .getRelatedOne("TechDataCalendar");
1002:                } catch (GenericEntityException e) {
1003:                    Debug.logWarning(e, module);
1004:                }
1005:                if (techDataCalendar == null) {
1006:                    // no calendar ok, when not more that total capacity
1007:                    if (fixedAsset.getDouble("productionCapacity")
1008:                            .doubleValue() >= quantity) {
1009:                        String msg = UtilProperties.getMessage(resource,
1010:                                "item.availableOk", cart.getLocale());
1011:                        return msg;
1012:                    } else {
1013:                        Map messageMap = UtilMisc.toMap("quantityReq",
1014:                                (new Double(quantity)).toString(),
1015:                                "quantityAvail", fixedAsset
1016:                                        .getString("productionCapacity"));
1017:                        String msg = UtilProperties.getMessage(resource,
1018:                                "item.availableQnt", messageMap, cart
1019:                                        .getLocale());
1020:                        return msg;
1021:                    }
1022:                }
1023:                // now find all the dates and check the availabilty for each date
1024:                // please note that calendarId is the same for (TechData)Calendar, CalendarExcDay and CalendarExWeek
1025:                long dayCount = 0;
1026:                String resultMessage = "";
1027:                while (dayCount < (long) reservLength) {
1028:                    GenericValue techDataCalendarExcDay = null;
1029:                    // find an existing Day exception record
1030:                    Timestamp exceptionDateStartTime = new Timestamp(
1031:                            (long) (reservStart.getTime() + (dayCount++ * 86400000)));
1032:                    try {
1033:                        techDataCalendarExcDay = delegator.findByPrimaryKey(
1034:                                "TechDataCalendarExcDay", UtilMisc.toMap(
1035:                                        "calendarId", fixedAsset
1036:                                                .get("calendarId"),
1037:                                        "exceptionDateStartTime",
1038:                                        exceptionDateStartTime));
1039:                    } catch (GenericEntityException e) {
1040:                        Debug.logWarning(e, module);
1041:                    }
1042:                    if (techDataCalendarExcDay == null) {
1043:                        //Debug.logInfo(" No exception day record found, available: " + fixedAsset.getString("productionCapacity") + " Requested now: " + quantity, module);
1044:                        if (fixedAsset.get("productionCapacity") != null
1045:                                && fixedAsset.getDouble("productionCapacity")
1046:                                        .doubleValue() < quantity)
1047:                            resultMessage = resultMessage
1048:                                    .concat(exceptionDateStartTime.toString()
1049:                                            .substring(0, 10)
1050:                                            + ", ");
1051:                    } else {
1052:                        // see if we can get the number of assets available
1053:                        // first try techDataCalendarExcDay(exceptionCapacity) and then FixedAsset(productionCapacity)
1054:                        // if still zero, do not check availability
1055:                        double exceptionCapacity = 0.00;
1056:                        if (techDataCalendarExcDay.get("exceptionCapacity") != null)
1057:                            exceptionCapacity = techDataCalendarExcDay
1058:                                    .getDouble("exceptionCapacity")
1059:                                    .doubleValue();
1060:                        if (exceptionCapacity == 0.00
1061:                                && fixedAsset.get("productionCapacity") != null)
1062:                            exceptionCapacity = fixedAsset.getDouble(
1063:                                    "productionCapacity").doubleValue();
1064:                        if (exceptionCapacity != 0.00) {
1065:                            double usedCapacity = 0.00;
1066:                            if (techDataCalendarExcDay.get("usedCapacity") != null)
1067:                                usedCapacity = techDataCalendarExcDay
1068:                                        .getDouble("usedCapacity")
1069:                                        .doubleValue();
1070:                            if (exceptionCapacity < (quantity + usedCapacity)) {
1071:                                resultMessage = resultMessage
1072:                                        .concat(exceptionDateStartTime
1073:                                                .toString().substring(0, 10)
1074:                                                + ", ");
1075:                                Debug
1076:                                        .logInfo(
1077:                                                "No rental fixed Asset available: "
1078:                                                        + exceptionCapacity
1079:                                                        + " already used: "
1080:                                                        + usedCapacity
1081:                                                        + " Requested now: "
1082:                                                        + quantity, module);
1083:                            }
1084:                        }
1085:                    }
1086:                }
1087:                if (resultMessage.compareTo("") == 0) {
1088:                    String msg = UtilProperties.getMessage(resource,
1089:                            "item.availableOk", cart.getLocale());
1090:                    return msg;
1091:                } else {
1092:                    Map messageMap = UtilMisc.toMap("resultMessage",
1093:                            resultMessage);
1094:                    String msg = UtilProperties.getMessage(resource,
1095:                            "item.notAvailable", messageMap, cart.getLocale());
1096:                    return msg;
1097:                }
1098:            }
1099:
1100:            protected boolean isInventoryAvailableOrNotRequired(
1101:                    double quantity, String productStoreId,
1102:                    LocalDispatcher dispatcher) throws CartItemModifyException {
1103:                boolean inventoryAvailable = true;
1104:                try {
1105:                    Map invReqResult = dispatcher.runSync(
1106:                            "isStoreInventoryAvailableOrNotRequired", UtilMisc
1107:                                    .toMap("productStoreId", productStoreId,
1108:                                            "productId", productId, "product",
1109:                                            this .getProduct(), "quantity",
1110:                                            new Double(quantity)));
1111:                    if (ServiceUtil.isError(invReqResult)) {
1112:                        Debug.logError(
1113:                                "Error calling isStoreInventoryAvailableOrNotRequired service, result is: "
1114:                                        + invReqResult, module);
1115:                        throw new CartItemModifyException((String) invReqResult
1116:                                .get(ModelService.ERROR_MESSAGE));
1117:                    }
1118:                    inventoryAvailable = "Y".equals((String) invReqResult
1119:                            .get("availableOrNotRequired"));
1120:                } catch (GenericServiceException e) {
1121:                    String errMsg = "Fatal error calling inventory checking services: "
1122:                            + e.toString();
1123:                    Debug.logError(e, errMsg, module);
1124:                    throw new CartItemModifyException(errMsg);
1125:                }
1126:                return inventoryAvailable;
1127:            }
1128:
1129:            protected void setQuantity(int quantity,
1130:                    LocalDispatcher dispatcher, ShoppingCart cart,
1131:                    boolean triggerExternalOps, boolean resetShipGroup,
1132:                    boolean updateProductPrice, boolean skipInventoryChecks)
1133:                    throws CartItemModifyException {
1134:                if (this .quantity == quantity) {
1135:                    return;
1136:                }
1137:
1138:                if (this .isPromo) {
1139:                    throw new CartItemModifyException(
1140:                            "Sorry, you can't change the quantity on the promotion item "
1141:                                    + this .getName() + " (product ID: "
1142:                                    + productId + "), not setting quantity.");
1143:                }
1144:
1145:                // needed for inventory checking and auto-save
1146:                String productStoreId = cart.getProductStoreId();
1147:
1148:                if (!skipInventoryChecks
1149:                        && !"PURCHASE_ORDER".equals(cart.getOrderType())) {
1150:                    // check inventory if new quantity is greater than old quantity; don't worry about inventory getting pulled out from under, that will be handled at checkout time
1151:                    if (_product != null && quantity > this .quantity) {
1152:                        if (!isInventoryAvailableOrNotRequired(quantity,
1153:                                productStoreId, dispatcher)) {
1154:                            String excMsg = "Sorry, we do not have enough (you tried "
1155:                                    + UtilFormatOut.formatQuantity(quantity)
1156:                                    + ") of the product "
1157:                                    + this .getName()
1158:                                    + " (product ID: "
1159:                                    + productId
1160:                                    + ") in stock, not adding to cart. Please try a lower quantity, try again later, or call customer service for more information.";
1161:                            Debug.logWarning(excMsg, module);
1162:                            throw new CartItemModifyException(excMsg);
1163:                        }
1164:                    }
1165:                }
1166:
1167:                // set quantity before promos so order total, etc will be updated
1168:                this .quantity = quantity;
1169:
1170:                if (updateProductPrice) {
1171:                    this .updatePrice(dispatcher, cart);
1172:                }
1173:
1174:                // apply/unapply promotions
1175:                if (triggerExternalOps) {
1176:                    ProductPromoWorker.doPromotions(cart, dispatcher);
1177:                }
1178:
1179:                if (!"PURCHASE_ORDER".equals(cart.getOrderType())) {
1180:                    // store the auto-save cart
1181:                    if (triggerExternalOps
1182:                            && ProductStoreWorker.autoSaveCart(delegator,
1183:                                    productStoreId)) {
1184:                        try {
1185:                            ShoppingListEvents.fillAutoSaveList(cart,
1186:                                    dispatcher);
1187:                        } catch (GeneralException e) {
1188:                            Debug.logWarning(e, UtilProperties.getMessage(
1189:                                    resource_error,
1190:                                    "OrderUnableToStoreAutoSaveCart", locale));
1191:                        }
1192:                    }
1193:                }
1194:
1195:                // set the item ship group
1196:                if (resetShipGroup) {
1197:                    cart.clearItemShipInfo(this );
1198:
1199:                    /*
1200:
1201:                    // Deprecated in favour of ShoppingCart.createDropShipGroups(), called during checkout
1202:
1203:                    int shipGroupIndex = -1;
1204:                    if ("PURCHASE_ORDER".equals(cart.getOrderType())) {
1205:                        shipGroupIndex = 0;
1206:                    } else {
1207:                        if (_product != null && "PRODRQM_DS".equals(_product.getString("requirementMethodEnumId"))) {
1208:                            // this is a drop-ship only product: we need a ship group with supplierPartyId set
1209:                            Map supplierProductsResult = null;
1210:                            try {
1211:                                supplierProductsResult = dispatcher.runSync("getSuppliersForProduct", UtilMisc.toMap("productId", _product.getString("productId"),
1212:                                                                                                                         "quantity", new Double(quantity),
1213:                                                                                                                         "currencyUomId", cart.getCurrency(),
1214:                                                                                                                         "canDropShip", "Y",
1215:                                                                                                                         "userLogin", cart.getUserLogin()));
1216:                                List productSuppliers = (List)supplierProductsResult.get("supplierProducts");
1217:                                GenericValue supplierProduct = EntityUtil.getFirst(productSuppliers);
1218:                                if (supplierProduct != null) {
1219:                                    String supplierPartyId = supplierProduct.getString("partyId");
1220:                                    List shipGroups = cart.getShipGroups();
1221:                                    for(int i = 0; i < shipGroups.size(); i++) {
1222:                                        ShoppingCart.CartShipInfo csi = (ShoppingCart.CartShipInfo)shipGroups.get(i);
1223:                                        if (supplierPartyId.equals(csi.getSupplierPartyId())) {
1224:                                            shipGroupIndex = i;
1225:                                            break;
1226:                                        }
1227:                                    }
1228:                                    if (shipGroupIndex == -1) {
1229:                                        // create a new ship group
1230:                                        shipGroupIndex = cart.addShipInfo();
1231:                                        cart.setSupplierPartyId(shipGroupIndex, supplierPartyId);
1232:                                    }
1233:                                }
1234:                            } catch (Exception e) {
1235:                                Debug.logWarning("Error calling getSuppliersForProduct service, result is: " + supplierProductsResult, module);
1236:                            }
1237:                        }
1238:
1239:                        if (shipGroupIndex == -1) {
1240:                            List shipGroups = cart.getShipGroups();
1241:                            for(int i = 0; i < shipGroups.size(); i++) {
1242:                                ShoppingCart.CartShipInfo csi = (ShoppingCart.CartShipInfo)shipGroups.get(i);
1243:                                if (csi.getSupplierPartyId() == null) {
1244:                                    shipGroupIndex = i;
1245:                                    break;
1246:                                }
1247:                            }
1248:                            if (shipGroupIndex == -1) {
1249:                                // create a new ship group
1250:                                shipGroupIndex = cart.addShipInfo();
1251:                            }
1252:                        }
1253:                    }
1254:                    cart.setItemShipGroupQty(this, quantity, shipGroupIndex);
1255:                     */
1256:                    cart.setItemShipGroupQty(this , quantity, 0);
1257:                }
1258:            }
1259:
1260:            public void updatePrice(LocalDispatcher dispatcher,
1261:                    ShoppingCart cart) throws CartItemModifyException {
1262:                // set basePrice using the calculateProductPrice service
1263:                if (_product != null && isModifiedPrice == false) {
1264:                    try {
1265:                        Map priceContext = FastMap.newInstance();
1266:                        priceContext.put("currencyUomId", cart.getCurrency());
1267:
1268:                        String partyId = cart.getPartyId();
1269:                        if (partyId != null) {
1270:                            priceContext.put("partyId", partyId);
1271:                        }
1272:                        priceContext.put("quantity", new Double(this 
1273:                                .getQuantity()));
1274:                        priceContext.put("product", this .getProduct());
1275:                        if (cart.getOrderType().equals("PURCHASE_ORDER")) {
1276:                            Map priceResult = dispatcher.runSync(
1277:                                    "calculatePurchasePrice", priceContext);
1278:                            if (ServiceUtil.isError(priceResult)) {
1279:                                throw new CartItemModifyException(
1280:                                        "There was an error while calculating the price: "
1281:                                                + ServiceUtil
1282:                                                        .getErrorMessage(priceResult));
1283:                            }
1284:                            Boolean validPriceFound = (Boolean) priceResult
1285:                                    .get("validPriceFound");
1286:                            if (!validPriceFound.booleanValue()) {
1287:                                throw new CartItemModifyException(
1288:                                        "Could not find a valid price for the product with ID ["
1289:                                                + this .getProductId()
1290:                                                + "] and supplier with ID ["
1291:                                                + partyId
1292:                                                + "], not adding to cart.");
1293:                            }
1294:
1295:                            this .setBasePrice(((Double) priceResult
1296:                                    .get("price")).doubleValue());
1297:                            this .setDisplayPrice(this .basePrice);
1298:                            this .orderItemPriceInfos = (List) priceResult
1299:                                    .get("orderItemPriceInfos");
1300:                        } else {
1301:                            priceContext.put("prodCatalogId", this 
1302:                                    .getProdCatalogId());
1303:                            priceContext.put("webSiteId", cart.getWebSiteId());
1304:                            priceContext.put("productStoreId", cart
1305:                                    .getProductStoreId());
1306:                            priceContext.put("agreementId", cart
1307:                                    .getAgreementId());
1308:                            priceContext.put("productPricePurposeId",
1309:                                    "PURCHASE");
1310:                            priceContext.put("checkIncludeVat", "Y");
1311:                            Map priceResult = dispatcher.runSync(
1312:                                    "calculateProductPrice", priceContext);
1313:                            if (ServiceUtil.isError(priceResult)) {
1314:                                throw new CartItemModifyException(
1315:                                        "There was an error while calculating the price: "
1316:                                                + ServiceUtil
1317:                                                        .getErrorMessage(priceResult));
1318:                            }
1319:
1320:                            Boolean validPriceFound = (Boolean) priceResult
1321:                                    .get("validPriceFound");
1322:                            if (Boolean.FALSE.equals(validPriceFound)) {
1323:                                throw new CartItemModifyException(
1324:                                        "Could not find a valid price for the product with ID ["
1325:                                                + this .getProductId()
1326:                                                + "], not adding to cart.");
1327:                            }
1328:
1329:                            if (priceResult.get("listPrice") != null) {
1330:                                this .listPrice = ((Double) priceResult
1331:                                        .get("listPrice")).doubleValue();
1332:                            }
1333:
1334:                            if (priceResult.get("basePrice") != null) {
1335:                                this .setBasePrice(((Double) priceResult
1336:                                        .get("basePrice")).doubleValue());
1337:                            }
1338:
1339:                            if (priceResult.get("price") != null) {
1340:                                this .setDisplayPrice(((Double) priceResult
1341:                                        .get("price")).doubleValue());
1342:                            }
1343:
1344:                            this .setSpecialPromoPrice((Double) priceResult
1345:                                    .get("specialPromoPrice"));
1346:
1347:                            this .orderItemPriceInfos = (List) priceResult
1348:                                    .get("orderItemPriceInfos");
1349:
1350:                            // If product is configurable, the price is taken from the configWrapper.
1351:                            if (configWrapper != null) {
1352:                                // TODO: for configurable products need to do something to make them VAT aware... for now base and display prices are the same
1353:                                this 
1354:                                        .setBasePrice(configWrapper
1355:                                                .getTotalPrice());
1356:                                this .setDisplayPrice(configWrapper
1357:                                        .getTotalPrice());
1358:                            }
1359:
1360:                            // no try to do a recurring price calculation; not all products have recurring prices so may be null
1361:                            Map recurringPriceContext = FastMap.newInstance();
1362:                            recurringPriceContext.putAll(priceContext);
1363:                            recurringPriceContext.put("productPricePurposeId",
1364:                                    "RECURRING_CHARGE");
1365:                            Map recurringPriceResult = dispatcher.runSync(
1366:                                    "calculateProductPrice",
1367:                                    recurringPriceContext);
1368:                            if (ServiceUtil.isError(recurringPriceResult)) {
1369:                                throw new CartItemModifyException(
1370:                                        "There was an error while calculating the price: "
1371:                                                + ServiceUtil
1372:                                                        .getErrorMessage(recurringPriceResult));
1373:                            }
1374:
1375:                            // for the recurring price only set the values iff validPriceFound is true
1376:                            Boolean validRecurringPriceFound = (Boolean) recurringPriceResult
1377:                                    .get("validPriceFound");
1378:                            if (Boolean.TRUE.equals(validRecurringPriceFound)) {
1379:                                if (recurringPriceResult.get("basePrice") != null) {
1380:                                    this 
1381:                                            .setRecurringBasePrice((Double) recurringPriceResult
1382:                                                    .get("basePrice"));
1383:                                }
1384:                                if (recurringPriceResult.get("price") != null) {
1385:                                    this 
1386:                                            .setRecurringDisplayPrice((Double) recurringPriceResult
1387:                                                    .get("price"));
1388:                                }
1389:                            }
1390:                        }
1391:                    } catch (GenericServiceException e) {
1392:                        throw new CartItemModifyException(
1393:                                "There was an error while calculating the price",
1394:                                e);
1395:                    }
1396:                }
1397:            }
1398:
1399:            /** Returns the quantity. */
1400:            public double getQuantity() {
1401:                return this .quantity;
1402:            }
1403:
1404:            /** Returns the reservation start date. */
1405:            public Timestamp getReservStart() {
1406:                return this .getReservStart(0);
1407:            }
1408:
1409:            /** Returns the reservation start date with a number of days added. */
1410:            public Timestamp getReservStart(double addDays) {
1411:                if (addDays == 0)
1412:                    return this .reservStart;
1413:                else {
1414:                    if (this .reservStart != null)
1415:                        return new Timestamp(
1416:                                (long) (this .reservStart.getTime() + (addDays * 86400000.0)));
1417:                    else
1418:                        return null;
1419:                }
1420:            }
1421:
1422:            /** Returns the reservation length. */
1423:            public double getReservLength() {
1424:                return this .reservLength;
1425:            }
1426:
1427:            /** Returns the reservation number of persons. */
1428:            public double getReservPersons() {
1429:                return this .reservPersons;
1430:            }
1431:
1432:            public double getPromoQuantityUsed() {
1433:                if (this .getIsPromo()) {
1434:                    return this .quantity;
1435:                } else {
1436:                    return this .promoQuantityUsed;
1437:                }
1438:            }
1439:
1440:            public double getPromoQuantityAvailable() {
1441:                if (this .getIsPromo()) {
1442:                    return 0;
1443:                } else {
1444:                    return this .quantity - this .promoQuantityUsed;
1445:                }
1446:            }
1447:
1448:            public Iterator getQuantityUsedPerPromoActualIter() {
1449:                return this .quantityUsedPerPromoActual.entrySet().iterator();
1450:            }
1451:
1452:            public Iterator getQuantityUsedPerPromoCandidateIter() {
1453:                return this .quantityUsedPerPromoCandidate.entrySet().iterator();
1454:            }
1455:
1456:            public Iterator getQuantityUsedPerPromoFailedIter() {
1457:                return this .quantityUsedPerPromoFailed.entrySet().iterator();
1458:            }
1459:
1460:            public synchronized double addPromoQuantityCandidateUse(
1461:                    double quantityDesired,
1462:                    GenericValue productPromoCondAction,
1463:                    boolean checkAvailableOnly) {
1464:                if (quantityDesired == 0)
1465:                    return 0;
1466:                double promoQuantityAvailable = this 
1467:                        .getPromoQuantityAvailable();
1468:                double promoQuantityToUse = quantityDesired;
1469:                if (promoQuantityAvailable > 0) {
1470:                    if (promoQuantityToUse > promoQuantityAvailable) {
1471:                        promoQuantityToUse = promoQuantityAvailable;
1472:                    }
1473:
1474:                    if (!checkAvailableOnly) {
1475:                        // keep track of candidate promo uses on cartItem
1476:                        GenericPK productPromoCondActionPK = productPromoCondAction
1477:                                .getPrimaryKey();
1478:                        Double existingValue = (Double) this .quantityUsedPerPromoCandidate
1479:                                .get(productPromoCondActionPK);
1480:                        if (existingValue == null) {
1481:                            this .quantityUsedPerPromoCandidate.put(
1482:                                    productPromoCondActionPK, new Double(
1483:                                            promoQuantityToUse));
1484:                        } else {
1485:                            this .quantityUsedPerPromoCandidate.put(
1486:                                    productPromoCondActionPK, new Double(
1487:                                            promoQuantityToUse
1488:                                                    + existingValue
1489:                                                            .doubleValue()));
1490:                        }
1491:
1492:                        this .promoQuantityUsed += promoQuantityToUse;
1493:                        //Debug.logInfo("promoQuantityToUse=" + promoQuantityToUse + ", quantityDesired=" + quantityDesired + ", for promoCondAction: " + productPromoCondAction, module);
1494:                        //Debug.logInfo("promoQuantityUsed now=" + promoQuantityUsed, module);
1495:                    }
1496:
1497:                    return promoQuantityToUse;
1498:                } else {
1499:                    return 0;
1500:                }
1501:            }
1502:
1503:            public double getPromoQuantityCandidateUse(
1504:                    GenericValue productPromoCondAction) {
1505:                GenericPK productPromoCondActionPK = productPromoCondAction
1506:                        .getPrimaryKey();
1507:                Double existingValue = (Double) this .quantityUsedPerPromoCandidate
1508:                        .get(productPromoCondActionPK);
1509:                if (existingValue == null) {
1510:                    return 0;
1511:                } else {
1512:                    return existingValue.doubleValue();
1513:                }
1514:            }
1515:
1516:            public double getPromoQuantityCandidateUseActionAndAllConds(
1517:                    GenericValue productPromoAction) {
1518:                double totalUse = 0;
1519:                String productPromoId = productPromoAction
1520:                        .getString("productPromoId");
1521:                String productPromoRuleId = productPromoAction
1522:                        .getString("productPromoRuleId");
1523:
1524:                GenericPK productPromoActionPK = productPromoAction
1525:                        .getPrimaryKey();
1526:                Double existingValue = (Double) this .quantityUsedPerPromoCandidate
1527:                        .get(productPromoActionPK);
1528:                if (existingValue != null) {
1529:                    totalUse = existingValue.doubleValue();
1530:                }
1531:
1532:                Iterator entryIter = this .quantityUsedPerPromoCandidate
1533:                        .entrySet().iterator();
1534:                while (entryIter.hasNext()) {
1535:                    Map.Entry entry = (Map.Entry) entryIter.next();
1536:                    GenericPK productPromoCondActionPK = (GenericPK) entry
1537:                            .getKey();
1538:                    Double quantityUsed = (Double) entry.getValue();
1539:                    if (quantityUsed != null) {
1540:                        // must be in the same rule and be a condition
1541:                        if (productPromoId.equals(productPromoCondActionPK
1542:                                .getString("productPromoId"))
1543:                                && productPromoRuleId
1544:                                        .equals(productPromoCondActionPK
1545:                                                .getString("productPromoRuleId"))
1546:                                && productPromoCondActionPK
1547:                                        .containsKey("productPromoCondSeqId")) {
1548:                            totalUse += quantityUsed.doubleValue();
1549:                        }
1550:                    }
1551:                }
1552:
1553:                return totalUse;
1554:            }
1555:
1556:            public synchronized void resetPromoRuleUse(String productPromoId,
1557:                    String productPromoRuleId) {
1558:                Iterator entryIter = this .quantityUsedPerPromoCandidate
1559:                        .entrySet().iterator();
1560:                while (entryIter.hasNext()) {
1561:                    Map.Entry entry = (Map.Entry) entryIter.next();
1562:                    GenericPK productPromoCondActionPK = (GenericPK) entry
1563:                            .getKey();
1564:                    Double quantityUsed = (Double) entry.getValue();
1565:                    if (productPromoId.equals(productPromoCondActionPK
1566:                            .getString("productPromoId"))
1567:                            && productPromoRuleId
1568:                                    .equals(productPromoCondActionPK
1569:                                            .getString("productPromoRuleId"))) {
1570:                        entryIter.remove();
1571:                        Double existingValue = (Double) this .quantityUsedPerPromoFailed
1572:                                .get(productPromoCondActionPK);
1573:                        if (existingValue == null) {
1574:                            this .quantityUsedPerPromoFailed.put(
1575:                                    productPromoCondActionPK, quantityUsed);
1576:                        } else {
1577:                            this .quantityUsedPerPromoFailed.put(
1578:                                    productPromoCondActionPK, new Double(
1579:                                            quantityUsed.doubleValue()
1580:                                                    + existingValue
1581:                                                            .doubleValue()));
1582:                        }
1583:                        this .promoQuantityUsed -= quantityUsed.doubleValue();
1584:                    }
1585:                }
1586:            }
1587:
1588:            public synchronized void confirmPromoRuleUse(String productPromoId,
1589:                    String productPromoRuleId) {
1590:                Iterator entryIter = this .quantityUsedPerPromoCandidate
1591:                        .entrySet().iterator();
1592:                while (entryIter.hasNext()) {
1593:                    Map.Entry entry = (Map.Entry) entryIter.next();
1594:                    GenericPK productPromoCondActionPK = (GenericPK) entry
1595:                            .getKey();
1596:                    Double quantityUsed = (Double) entry.getValue();
1597:                    if (productPromoId.equals(productPromoCondActionPK
1598:                            .getString("productPromoId"))
1599:                            && productPromoRuleId
1600:                                    .equals(productPromoCondActionPK
1601:                                            .getString("productPromoRuleId"))) {
1602:                        entryIter.remove();
1603:                        Double existingValue = (Double) this .quantityUsedPerPromoActual
1604:                                .get(productPromoCondActionPK);
1605:                        if (existingValue == null) {
1606:                            this .quantityUsedPerPromoActual.put(
1607:                                    productPromoCondActionPK, quantityUsed);
1608:                        } else {
1609:                            this .quantityUsedPerPromoActual.put(
1610:                                    productPromoCondActionPK, new Double(
1611:                                            quantityUsed.doubleValue()
1612:                                                    + existingValue
1613:                                                            .doubleValue()));
1614:                        }
1615:                    }
1616:                }
1617:            }
1618:
1619:            public synchronized void clearPromoRuleUseInfo() {
1620:                this .quantityUsedPerPromoActual.clear();
1621:                this .quantityUsedPerPromoCandidate.clear();
1622:                this .quantityUsedPerPromoFailed.clear();
1623:                this .promoQuantityUsed = this .getIsPromo() ? this .quantity : 0;
1624:            }
1625:
1626:            /** Sets the item comment. */
1627:            public void setItemComment(String itemComment) {
1628:                this .setAttribute("itemComment", itemComment);
1629:            }
1630:
1631:            /** Returns the item's comment. */
1632:            public String getItemComment() {
1633:                return (String) this .getAttribute("itemComment");
1634:            }
1635:
1636:            /** Sets the item's customer desired delivery date. */
1637:            public void setDesiredDeliveryDate(Timestamp ddDate) {
1638:                if (ddDate != null) {
1639:                    this .setAttribute("itemDesiredDeliveryDate", ddDate
1640:                            .toString());
1641:                }
1642:            }
1643:
1644:            /** Returns the item's customer desired delivery date. */
1645:            public Timestamp getDesiredDeliveryDate() {
1646:                String ddDate = (String) this 
1647:                        .getAttribute("itemDesiredDeliveryDate");
1648:
1649:                if (ddDate != null) {
1650:                    try {
1651:                        return Timestamp.valueOf(ddDate);
1652:                    } catch (IllegalArgumentException e) {
1653:                        Debug
1654:                                .logWarning(
1655:                                        e,
1656:                                        UtilProperties
1657:                                                .getMessage(
1658:                                                        resource_error,
1659:                                                        "OrderProblemGettingItemDesiredDeliveryDateFor",
1660:                                                        UtilMisc
1661:                                                                .toMap(
1662:                                                                        "productId",
1663:                                                                        this 
1664:                                                                                .getProductId()),
1665:                                                        locale));
1666:                        return null;
1667:                    }
1668:                }
1669:                return null;
1670:            }
1671:
1672:            /** Sets the date to ship before */
1673:            public void setShipBeforeDate(Timestamp date) {
1674:                this .shipBeforeDate = date;
1675:
1676:            }
1677:
1678:            /** Returns the date to ship before */
1679:            public Timestamp getShipBeforeDate() {
1680:                return this .shipBeforeDate;
1681:            }
1682:
1683:            /** Sets the date to ship after */
1684:            public void setShipAfterDate(Timestamp date) {
1685:                this .shipAfterDate = date;
1686:            }
1687:
1688:            /** Returns the date to ship after */
1689:            public Timestamp getShipAfterDate() {
1690:                return this .shipAfterDate;
1691:            }
1692:
1693:            /** Sets the item type. */
1694:            public void setItemType(String itemType) {
1695:                this .itemType = itemType;
1696:            }
1697:
1698:            /** Returns the item type. */
1699:            public String getItemType() {
1700:                return this .itemType;
1701:            }
1702:
1703:            /** Returns the item type. */
1704:            public GenericValue getItemTypeGenericValue() {
1705:                try {
1706:                    return this .getDelegator().findByPrimaryKeyCache(
1707:                            "OrderItemType",
1708:                            UtilMisc.toMap("orderItemTypeId", this .itemType));
1709:                } catch (GenericEntityException e) {
1710:                    Debug.logError(e,
1711:                            "Error getting ShippingCartItem's OrderItemType",
1712:                            module);
1713:                    return null;
1714:                }
1715:            }
1716:
1717:            /** Sets the item group. */
1718:            public void setItemGroup(
1719:                    ShoppingCart.ShoppingCartItemGroup itemGroup) {
1720:                this .itemGroup = itemGroup;
1721:            }
1722:
1723:            /** Sets the item group. */
1724:            public void setItemGroup(String groupNumber, ShoppingCart cart) {
1725:                this .itemGroup = cart.getItemGroupByNumber(groupNumber);
1726:            }
1727:
1728:            /** Returns the item group. */
1729:            public ShoppingCart.ShoppingCartItemGroup getItemGroup() {
1730:                return this .itemGroup;
1731:            }
1732:
1733:            public boolean isInItemGroup(String groupNumber) {
1734:                if (this .itemGroup == null)
1735:                    return false;
1736:                if (this .itemGroup.getGroupNumber().equals(groupNumber))
1737:                    return true;
1738:                return false;
1739:            }
1740:
1741:            /** Returns the item type description. */
1742:            public String getItemTypeDescription() {
1743:                GenericValue orderItemType = null;
1744:                if (this .getItemType() != null) {
1745:                    try {
1746:                        orderItemType = this .getDelegator()
1747:                                .findByPrimaryKeyCache(
1748:                                        "OrderItemType",
1749:                                        UtilMisc.toMap("orderItemTypeId", this 
1750:                                                .getItemType()));
1751:                    } catch (GenericEntityException e) {
1752:                        Debug.logWarning(e, UtilProperties.getMessage(
1753:                                resource_error,
1754:                                "OrderProblemsGettingOrderItemTypeFor",
1755:                                UtilMisc.toMap("orderItemTypeId", this 
1756:                                        .getItemType()), locale));
1757:                    }
1758:                }
1759:                if (orderItemType != null) {
1760:                    return orderItemType.getString("description");
1761:                }
1762:                return null;
1763:            }
1764:
1765:            /** Returns the productCategoryId for the item or null if none. */
1766:            public String getProductCategoryId() {
1767:                return this .productCategoryId;
1768:            }
1769:
1770:            public void setProductCategoryId(String productCategoryId) {
1771:                this .productCategoryId = productCategoryId;
1772:            }
1773:
1774:            public void setOrderItemSeqId(String orderItemSeqId) {
1775:                Debug.log("Setting orderItemSeqId - " + orderItemSeqId, module);
1776:                this .orderItemSeqId = orderItemSeqId;
1777:            }
1778:
1779:            public String getOrderItemSeqId() {
1780:                return orderItemSeqId;
1781:            }
1782:
1783:            public void setShoppingList(String shoppingListId, String itemSeqId) {
1784:                attributes.put("shoppingListId", shoppingListId);
1785:                attributes.put("shoppingListItemSeqId", itemSeqId);
1786:            }
1787:
1788:            public String getShoppingListId() {
1789:                return (String) attributes.get("shoppingListId");
1790:            }
1791:
1792:            public String getShoppingListItemSeqId() {
1793:                return (String) attributes.get("shoppingListItemSeqId");
1794:            }
1795:
1796:            /** Sets the requirementId. */
1797:            public void setRequirementId(String requirementId) {
1798:                this .requirementId = requirementId;
1799:            }
1800:
1801:            /** Returns the requirementId. */
1802:            public String getRequirementId() {
1803:                return this .requirementId;
1804:            }
1805:
1806:            /** Sets the quoteId. */
1807:            public void setQuoteId(String quoteId) {
1808:                this .quoteId = quoteId;
1809:            }
1810:
1811:            /** Returns the quoteId. */
1812:            public String getQuoteId() {
1813:                return this .quoteId;
1814:            }
1815:
1816:            /** Sets the quoteItemSeqId. */
1817:            public void setQuoteItemSeqId(String quoteItemSeqId) {
1818:                this .quoteItemSeqId = quoteItemSeqId;
1819:            }
1820:
1821:            /** Returns the quoteItemSeqId. */
1822:            public String getQuoteItemSeqId() {
1823:                return this .quoteItemSeqId;
1824:            }
1825:
1826:            /** Sets the orderItemAssocTypeId. */
1827:            public void setOrderItemAssocTypeId(String orderItemAssocTypeId) {
1828:                if (orderItemAssocTypeId != null) {
1829:                    this .orderItemAssocTypeId = orderItemAssocTypeId;
1830:                }
1831:            }
1832:
1833:            /** Returns the OrderItemAssocTypeId. */
1834:            public String getOrderItemAssocTypeId() {
1835:                return this .orderItemAssocTypeId;
1836:            }
1837:
1838:            /** Sets the associatedOrderId. */
1839:            public void setAssociatedOrderId(String associatedOrderId) {
1840:                this .associatedOrderId = associatedOrderId;
1841:            }
1842:
1843:            /** Returns the associatedId. */
1844:            public String getAssociatedOrderId() {
1845:                return this .associatedOrderId;
1846:            }
1847:
1848:            /** Sets the associatedOrderItemSeqId. */
1849:            public void setAssociatedOrderItemSeqId(
1850:                    String associatedOrderItemSeqId) {
1851:                this .associatedOrderItemSeqId = associatedOrderItemSeqId;
1852:            }
1853:
1854:            /** Returns the associatedOrderItemSeqId. */
1855:            public String getAssociatedOrderItemSeqId() {
1856:                return this .associatedOrderItemSeqId;
1857:            }
1858:
1859:            public String getStatusId() {
1860:                return this .statusId;
1861:            }
1862:
1863:            public void setStatusId(String statusId) {
1864:                this .statusId = statusId;
1865:            }
1866:
1867:            /** Returns true if shipping charges apply to this item. */
1868:            public boolean shippingApplies() {
1869:                GenericValue product = getProduct();
1870:                if (product != null) {
1871:                    return ProductWorker.shippingApplies(product);
1872:                } else {
1873:                    // we don't ship non-product items
1874:                    return false;
1875:                }
1876:            }
1877:
1878:            /** Returns true if tax charges apply to this item. */
1879:            public boolean taxApplies() {
1880:                GenericValue product = getProduct();
1881:                if (product != null) {
1882:                    return ProductWorker.taxApplies(product);
1883:                } else {
1884:                    // we do tax non-product items
1885:                    return true;
1886:                }
1887:            }
1888:
1889:            /** Returns the item's productId. */
1890:            public String getProductId() {
1891:                return productId;
1892:            }
1893:
1894:            /** Set the item's description. */
1895:            public void setName(String itemName) {
1896:                this .itemDescription = itemName;
1897:            }
1898:
1899:            /** Returns the item's description. */
1900:            public String getName() {
1901:                if (itemDescription != null) {
1902:                    return itemDescription;
1903:                } else {
1904:                    GenericValue product = getProduct();
1905:                    if (product != null) {
1906:                        String productName = ProductContentWrapper
1907:                                .getProductContentAsText(product,
1908:                                        "PRODUCT_NAME", this .locale, null);
1909:                        // if the productName is null or empty, see if there is an associated virtual product and get the productName of that product
1910:                        if (UtilValidate.isEmpty(productName)) {
1911:                            GenericValue parentProduct = this 
1912:                                    .getParentProduct();
1913:                            if (parentProduct != null) {
1914:                                productName = ProductContentWrapper
1915:                                        .getProductContentAsText(parentProduct,
1916:                                                "PRODUCT_NAME", this .locale,
1917:                                                null);
1918:                            }
1919:                        }
1920:                        if (productName == null) {
1921:                            return "";
1922:                        } else {
1923:                            return productName;
1924:                        }
1925:                    } else {
1926:                        return "";
1927:                    }
1928:                }
1929:            }
1930:
1931:            /** Returns the item's description. */
1932:            public String getDescription() {
1933:                GenericValue product = getProduct();
1934:
1935:                if (product != null) {
1936:                    String description = ProductContentWrapper
1937:                            .getProductContentAsText(product, "DESCRIPTION",
1938:                                    this .locale, null);
1939:
1940:                    // if the description is null or empty, see if there is an associated virtual product and get the description of that product
1941:                    if (UtilValidate.isEmpty(description)) {
1942:                        GenericValue parentProduct = this .getParentProduct();
1943:                        if (parentProduct != null) {
1944:                            description = ProductContentWrapper
1945:                                    .getProductContentAsText(parentProduct,
1946:                                            "DESCRIPTION", this .locale, null);
1947:                        }
1948:                    }
1949:
1950:                    if (description == null) {
1951:                        return "";
1952:                    } else {
1953:                        return description;
1954:                    }
1955:                } else {
1956:                    return null;
1957:                }
1958:            }
1959:
1960:            public ProductConfigWrapper getConfigWrapper() {
1961:                return configWrapper;
1962:            }
1963:
1964:            /** Returns the item's unit weight */
1965:            public double getWeight() {
1966:                GenericValue product = getProduct();
1967:                if (product != null) {
1968:                    Double weight = product.getDouble("weight");
1969:
1970:                    // if the weight is null, see if there is an associated virtual product and get the weight of that product
1971:                    if (weight == null) {
1972:                        GenericValue parentProduct = this .getParentProduct();
1973:                        if (parentProduct != null)
1974:                            weight = parentProduct.getDouble("weight");
1975:                    }
1976:
1977:                    if (weight == null) {
1978:                        return 0;
1979:                    } else {
1980:                        return weight.doubleValue();
1981:                    }
1982:                } else {
1983:                    // non-product items have 0 weight
1984:                    return 0;
1985:                }
1986:            }
1987:
1988:            /** Returns the item's pieces included */
1989:            public long getPiecesIncluded() {
1990:                GenericValue product = getProduct();
1991:                if (product != null) {
1992:                    Long pieces = product.getLong("piecesIncluded");
1993:
1994:                    // if the piecesIncluded is null, see if there is an associated virtual product and get the piecesIncluded of that product
1995:                    if (pieces == null) {
1996:                        GenericValue parentProduct = this .getParentProduct();
1997:                        if (parentProduct != null)
1998:                            pieces = parentProduct.getLong("piecesIncluded");
1999:                    }
2000:
2001:                    if (pieces == null) {
2002:                        return 1;
2003:                    } else {
2004:                        return pieces.longValue();
2005:                    }
2006:                } else {
2007:                    // non-product item assumed 1 piece
2008:                    return 1;
2009:                }
2010:            }
2011:
2012:            /** Returns a Set of the item's features */
2013:            public Set getFeatureSet() {
2014:                Set featureSet = new ListOrderedSet();
2015:                GenericValue product = this .getProduct();
2016:                if (product != null) {
2017:                    List featureAppls = null;
2018:                    try {
2019:                        featureAppls = product.getRelated("ProductFeatureAppl");
2020:                        List filterExprs = UtilMisc.toList(new EntityExpr(
2021:                                "productFeatureApplTypeId",
2022:                                EntityOperator.EQUALS, "STANDARD_FEATURE"));
2023:                        filterExprs.add(new EntityExpr(
2024:                                "productFeatureApplTypeId",
2025:                                EntityOperator.EQUALS, "REQUIRED_FEATURE"));
2026:                        featureAppls = EntityUtil.filterByOr(featureAppls,
2027:                                filterExprs);
2028:                    } catch (GenericEntityException e) {
2029:                        Debug.logError(e,
2030:                                "Unable to get features from product : "
2031:                                        + product.get("productId"), module);
2032:                    }
2033:                    if (featureAppls != null) {
2034:                        Iterator fai = featureAppls.iterator();
2035:                        while (fai.hasNext()) {
2036:                            GenericValue appl = (GenericValue) fai.next();
2037:                            featureSet.add(appl.getString("productFeatureId"));
2038:                        }
2039:                    }
2040:                }
2041:                if (this .additionalProductFeatureAndAppls != null) {
2042:                    Iterator aapi = this .additionalProductFeatureAndAppls
2043:                            .values().iterator();
2044:                    while (aapi.hasNext()) {
2045:                        GenericValue appl = (GenericValue) aapi.next();
2046:                        featureSet.add(appl.getString("productFeatureId"));
2047:                    }
2048:                }
2049:                return featureSet;
2050:            }
2051:
2052:            /** Returns a list of the item's standard features */
2053:            public List getStandardFeatureList() {
2054:                List features = null;
2055:                GenericValue product = this .getProduct();
2056:                if (product != null) {
2057:                    try {
2058:                        List featureAppls = product
2059:                                .getRelated("ProductFeatureAndAppl");
2060:                        features = EntityUtil.filterByAnd(featureAppls,
2061:                                UtilMisc.toMap("productFeatureApplTypeId",
2062:                                        "STANDARD_FEATURE"));
2063:                    } catch (GenericEntityException e) {
2064:                        Debug.logError(e,
2065:                                "Unable to get features from product : "
2066:                                        + product.get("productId"), module);
2067:                    }
2068:                }
2069:                return features;
2070:            }
2071:
2072:            /** Returns a List of the item's features for supplier*/
2073:            public List getFeaturesForSupplier(LocalDispatcher dispatcher,
2074:                    String partyId) {
2075:                List featureAppls = getStandardFeatureList();
2076:                if (featureAppls != null && featureAppls.size() > 0) {
2077:                    try {
2078:                        Map result = dispatcher.runSync(
2079:                                "convertFeaturesForSupplier", UtilMisc.toMap(
2080:                                        "partyId", partyId, "productFeatures",
2081:                                        featureAppls));
2082:                        featuresForSupplier = (List) result
2083:                                .get("convertedProductFeatures");
2084:                    } catch (GenericServiceException e) {
2085:                        Debug.logError(e,
2086:                                "Unable to get features for supplier from product : "
2087:                                        + this .productId, module);
2088:                    }
2089:                }
2090:                return featuresForSupplier;
2091:            }
2092:
2093:            /** Returns the item's size (length + girth) */
2094:            public double getSize() {
2095:                GenericValue product = getProduct();
2096:                if (product != null) {
2097:                    Double height = product.getDouble("shippingHeight");
2098:                    Double width = product.getDouble("shippingWidth");
2099:                    Double depth = product.getDouble("shippingDepth");
2100:
2101:                    // if all are null, see if there is an associated virtual product and get the info of that product
2102:                    if (height == null && width == null && depth == null) {
2103:                        GenericValue parentProduct = this .getParentProduct();
2104:                        if (parentProduct != null) {
2105:                            height = parentProduct.getDouble("shippingHeight");
2106:                            width = parentProduct.getDouble("shippingWidth");
2107:                            depth = parentProduct.getDouble("shippingDepth");
2108:                        }
2109:                    }
2110:
2111:                    if (height == null)
2112:                        height = new Double(0);
2113:                    if (width == null)
2114:                        width = new Double(0);
2115:                    if (depth == null)
2116:                        depth = new Double(0);
2117:
2118:                    // determine girth (longest field is length)
2119:                    double[] sizeInfo = { height.doubleValue(),
2120:                            width.doubleValue(), depth.doubleValue() };
2121:                    Arrays.sort(sizeInfo);
2122:
2123:                    return (sizeInfo[0] * 2) + (sizeInfo[1] * 2) + sizeInfo[2];
2124:                } else {
2125:                    // non-product items have 0 size
2126:                    return 0;
2127:                }
2128:            }
2129:
2130:            public Map getItemProductInfo() {
2131:                Map itemInfo = FastMap.newInstance();
2132:                itemInfo.put("productId", this .getProductId());
2133:                itemInfo.put("weight", new Double(this .getWeight()));
2134:                itemInfo.put("size", new Double(this .getSize()));
2135:                itemInfo.put("piecesIncluded", new Long(this 
2136:                        .getPiecesIncluded()));
2137:                itemInfo.put("featureSet", this .getFeatureSet());
2138:                GenericValue product = getProduct();
2139:                if (product != null) {
2140:                    itemInfo.put("inShippingBox", product
2141:                            .getString("inShippingBox"));
2142:                    if (product.getString("inShippingBox") != null
2143:                            && product.getString("inShippingBox").equals("Y")) {
2144:                        itemInfo.put("shippingHeight", product
2145:                                .getDouble("shippingHeight"));
2146:                        itemInfo.put("shippingWidth", product
2147:                                .getDouble("shippingWidth"));
2148:                        itemInfo.put("shippingDepth", product
2149:                                .getDouble("shippingDepth"));
2150:                    }
2151:                }
2152:                return itemInfo;
2153:            }
2154:
2155:            /** Returns the base price. */
2156:            public double getBasePrice() {
2157:                double curBasePrice;
2158:                if (selectedAmount > 0) {
2159:                    curBasePrice = basePrice * selectedAmount;
2160:                } else {
2161:                    curBasePrice = basePrice;
2162:                }
2163:                return curBasePrice;
2164:            }
2165:
2166:            public double getDisplayPrice() {
2167:                double curDisplayPrice;
2168:                if (this .displayPrice == null) {
2169:                    curDisplayPrice = this .getBasePrice();
2170:                } else {
2171:                    if (selectedAmount > 0) {
2172:                        curDisplayPrice = this .displayPrice.doubleValue()
2173:                                * this .selectedAmount;
2174:                    } else {
2175:                        curDisplayPrice = this .displayPrice.doubleValue();
2176:                    }
2177:                }
2178:                return curDisplayPrice;
2179:            }
2180:
2181:            public Double getSpecialPromoPrice() {
2182:                return this .specialPromoPrice;
2183:            }
2184:
2185:            public Double getRecurringBasePrice() {
2186:                if (this .recurringBasePrice == null)
2187:                    return null;
2188:
2189:                if (selectedAmount > 0) {
2190:                    return new Double(this .recurringBasePrice.doubleValue()
2191:                            * selectedAmount);
2192:                } else {
2193:                    return this .recurringBasePrice;
2194:                }
2195:            }
2196:
2197:            public Double getRecurringDisplayPrice() {
2198:                if (this .recurringDisplayPrice == null) {
2199:                    return this .getRecurringBasePrice();
2200:                }
2201:
2202:                if (selectedAmount > 0) {
2203:                    return new Double(this .recurringDisplayPrice.doubleValue()
2204:                            * this .selectedAmount);
2205:                } else {
2206:                    return this .recurringDisplayPrice;
2207:                }
2208:            }
2209:
2210:            /** Returns the list price. */
2211:            public double getListPrice() {
2212:                return listPrice;
2213:            }
2214:
2215:            /** Returns isModifiedPrice */
2216:            public boolean getIsModifiedPrice() {
2217:                return isModifiedPrice;
2218:            }
2219:
2220:            /** Set isModifiedPrice */
2221:            public void setIsModifiedPrice(boolean isModifiedPrice) {
2222:                this .isModifiedPrice = isModifiedPrice;
2223:            }
2224:
2225:            /** get the percentage for the second person */
2226:            public double getReserv2ndPPPerc() {
2227:                return reserv2ndPPPerc;
2228:            }
2229:
2230:            /** get the percentage for the third and following person */
2231:            public double getReservNthPPPerc() {
2232:                return reservNthPPPerc;
2233:            }
2234:
2235:            /** Returns the "other" adjustments. */
2236:            public double getOtherAdjustments() {
2237:                return OrderReadHelper.calcItemAdjustmentsBd(
2238:                        new BigDecimal(quantity),
2239:                        new BigDecimal(getBasePrice()), this .getAdjustments(),
2240:                        true, false, false, false, false).doubleValue();
2241:            }
2242:
2243:            /** Returns the "other" adjustments. */
2244:            public double getOtherAdjustmentsRecurring() {
2245:                return OrderReadHelper
2246:                        .calcItemAdjustmentsRecurringBd(
2247:                                new BigDecimal(quantity),
2248:                                new BigDecimal(
2249:                                        getRecurringBasePrice() == null ? 0.0
2250:                                                : getRecurringBasePrice()
2251:                                                        .doubleValue()),
2252:                                this .getAdjustments(), true, false, false,
2253:                                false, false).doubleValue();
2254:            }
2255:
2256:            /** calculates for a reservation the percentage/100 extra for more than 1 person. */
2257:            // similar code at editShoppingList.bsh
2258:            public double getRentalAdjustment() {
2259:                if (!"RENTAL_ORDER_ITEM".equals(this .itemType)) {
2260:                    // not a rental item?
2261:                    return 1;
2262:                }
2263:                double persons = this .getReservPersons();
2264:                double rentalValue = 0;
2265:                if (persons > 1) {
2266:                    if (persons > 2) {
2267:                        persons -= 2;
2268:                        if (getReservNthPPPerc() > 0) {
2269:                            rentalValue = persons * getReservNthPPPerc();
2270:                        } else {
2271:                            rentalValue = persons * getReserv2ndPPPerc();
2272:                        }
2273:                        persons = 2;
2274:                    }
2275:                    if (persons == 2) {
2276:                        rentalValue += getReserv2ndPPPerc();
2277:                    }
2278:                }
2279:                rentalValue += 100; // add final 100 percent for first person
2280:                //     Debug.log("rental parameters....Nbr of persons:" + getReservPersons() + " extra% 2nd person:" + getReserv2ndPPPerc()+ " extra% Nth person:" + getReservNthPPPerc() + "  total rental adjustment:" + rentalValue/100 * getReservLength() );
2281:                return rentalValue / 100 * getReservLength(); // return total rental adjustment
2282:            }
2283:
2284:            /** Returns the total line price. */
2285:            public double getItemSubTotal(double quantity) {
2286:                //        Debug.logInfo("Price" + getBasePrice() + " quantity" +  quantity + " Rental adj:" + getRentalAdjustment() + " other adj:" + getOtherAdjustments(), module);
2287:                return (getBasePrice() * quantity * getRentalAdjustment())
2288:                        + getOtherAdjustments();
2289:            }
2290:
2291:            public double getItemSubTotal() {
2292:                return this .getItemSubTotal(this .getQuantity());
2293:            }
2294:
2295:            public double getDisplayItemSubTotal() {
2296:                return (this .getDisplayPrice() * this .getQuantity() * this 
2297:                        .getRentalAdjustment())
2298:                        + this .getOtherAdjustments();
2299:            }
2300:
2301:            public double getDisplayItemSubTotalNoAdj() {
2302:                return this .getDisplayPrice() * this .getQuantity();
2303:            }
2304:
2305:            public double getDisplayItemRecurringSubTotal() {
2306:                Double curRecurringDisplayPrice = this 
2307:                        .getRecurringDisplayPrice();
2308:
2309:                if (curRecurringDisplayPrice == null) {
2310:                    return this .getOtherAdjustmentsRecurring();
2311:                }
2312:
2313:                return (curRecurringDisplayPrice.doubleValue() * this 
2314:                        .getQuantity())
2315:                        + this .getOtherAdjustmentsRecurring();
2316:            }
2317:
2318:            public double getDisplayItemRecurringSubTotalNoAdj() {
2319:                Double curRecurringDisplayPrice = this 
2320:                        .getRecurringDisplayPrice();
2321:                if (curRecurringDisplayPrice == null)
2322:                    return 0.0;
2323:
2324:                return curRecurringDisplayPrice.doubleValue()
2325:                        * this .getQuantity();
2326:            }
2327:
2328:            public void addAllProductFeatureAndAppls(
2329:                    Map productFeatureAndApplsToAdd) {
2330:                if (productFeatureAndApplsToAdd == null)
2331:                    return;
2332:                Iterator productFeatureAndApplsToAddIter = productFeatureAndApplsToAdd
2333:                        .values().iterator();
2334:                while (productFeatureAndApplsToAddIter.hasNext()) {
2335:                    GenericValue additionalProductFeatureAndAppl = (GenericValue) productFeatureAndApplsToAddIter
2336:                            .next();
2337:                    this 
2338:                            .putAdditionalProductFeatureAndAppl(additionalProductFeatureAndAppl);
2339:                }
2340:            }
2341:
2342:            public void putAdditionalProductFeatureAndAppl(
2343:                    GenericValue additionalProductFeatureAndAppl) {
2344:                if (additionalProductFeatureAndAppl == null)
2345:                    return;
2346:
2347:                // if one already exists with the given type, remove it with the corresponding adjustment
2348:                removeAdditionalProductFeatureAndAppl(additionalProductFeatureAndAppl
2349:                        .getString("productFeatureTypeId"));
2350:
2351:                // adds to additional map and creates an adjustment with given price
2352:                String featureType = additionalProductFeatureAndAppl
2353:                        .getString("productFeatureTypeId");
2354:                this .additionalProductFeatureAndAppls.put(featureType,
2355:                        additionalProductFeatureAndAppl);
2356:
2357:                GenericValue orderAdjustment = this .getDelegator().makeValue(
2358:                        "OrderAdjustment", null);
2359:                orderAdjustment.set("orderAdjustmentTypeId",
2360:                        "ADDITIONAL_FEATURE");
2361:                orderAdjustment.set("description",
2362:                        additionalProductFeatureAndAppl.get("description"));
2363:                orderAdjustment
2364:                        .set("productFeatureId",
2365:                                additionalProductFeatureAndAppl
2366:                                        .get("productFeatureId"));
2367:
2368:                // NOTE: this is a VERY simple pricing scheme for additional features and will likely need to be extended for most real applications
2369:                double amount = 0;
2370:                Double amountDbl = (Double) additionalProductFeatureAndAppl
2371:                        .get("amount");
2372:                if (amountDbl != null) {
2373:                    amount = amountDbl.doubleValue() * this .getQuantity();
2374:                }
2375:                orderAdjustment.set("amount", new Double(amount));
2376:
2377:                Double recurringAmountDbl = (Double) additionalProductFeatureAndAppl
2378:                        .get("recurringAmount");
2379:                if (recurringAmountDbl != null) {
2380:                    double recurringAmount = recurringAmountDbl.doubleValue()
2381:                            * this .getQuantity();
2382:                    orderAdjustment.set("recurringAmount", new Double(
2383:                            recurringAmount));
2384:                    //Debug.logInfo("Setting recurringAmount " + recurringAmount + " for " + orderAdjustment, module);
2385:                }
2386:
2387:                this .addAdjustment(orderAdjustment);
2388:            }
2389:
2390:            public GenericValue getAdditionalProductFeatureAndAppl(
2391:                    String productFeatureTypeId) {
2392:                if (this .additionalProductFeatureAndAppls == null)
2393:                    return null;
2394:                return (GenericValue) this .additionalProductFeatureAndAppls
2395:                        .get(productFeatureTypeId);
2396:            }
2397:
2398:            public GenericValue removeAdditionalProductFeatureAndAppl(
2399:                    String productFeatureTypeId) {
2400:                if (this .additionalProductFeatureAndAppls == null)
2401:                    return null;
2402:
2403:                GenericValue oldAdditionalProductFeatureAndAppl = (GenericValue) this .additionalProductFeatureAndAppls
2404:                        .remove(productFeatureTypeId);
2405:
2406:                if (oldAdditionalProductFeatureAndAppl != null) {
2407:                    removeFeatureAdjustment(oldAdditionalProductFeatureAndAppl
2408:                            .getString("productFeatureId"));
2409:                }
2410:
2411:                //if (this.additionalProductFeatureAndAppls.size() == 0) this.additionalProductFeatureAndAppls = null;
2412:
2413:                return oldAdditionalProductFeatureAndAppl;
2414:            }
2415:
2416:            public Map getAdditionalProductFeatureAndAppls() {
2417:                return this .additionalProductFeatureAndAppls;
2418:            }
2419:
2420:            public Map getFeatureIdQtyMap(double quantity) {
2421:                Map featureMap = FastMap.newInstance();
2422:                GenericValue product = this .getProduct();
2423:                if (product != null) {
2424:                    List featureAppls = null;
2425:                    try {
2426:                        featureAppls = product.getRelated("ProductFeatureAppl");
2427:                        List filterExprs = UtilMisc.toList(new EntityExpr(
2428:                                "productFeatureApplTypeId",
2429:                                EntityOperator.EQUALS, "STANDARD_FEATURE"));
2430:                        filterExprs.add(new EntityExpr(
2431:                                "productFeatureApplTypeId",
2432:                                EntityOperator.EQUALS, "REQUIRED_FEATURE"));
2433:                        featureAppls = EntityUtil.filterByOr(featureAppls,
2434:                                filterExprs);
2435:                    } catch (GenericEntityException e) {
2436:                        Debug.logError(e,
2437:                                "Unable to get features from product : "
2438:                                        + product.get("productId"), module);
2439:                    }
2440:                    if (featureAppls != null) {
2441:                        Iterator fai = featureAppls.iterator();
2442:                        while (fai.hasNext()) {
2443:                            GenericValue appl = (GenericValue) fai.next();
2444:                            Double lastQuantity = (Double) featureMap.get(appl
2445:                                    .getString("productFeatureId"));
2446:                            if (lastQuantity == null) {
2447:                                lastQuantity = new Double(0);
2448:                            }
2449:                            Double newQuantity = new Double(lastQuantity
2450:                                    .doubleValue()
2451:                                    + quantity);
2452:                            featureMap.put(appl.getString("productFeatureId"),
2453:                                    newQuantity);
2454:                        }
2455:                    }
2456:                }
2457:                if (this .additionalProductFeatureAndAppls != null) {
2458:                    Iterator aapi = this .additionalProductFeatureAndAppls
2459:                            .values().iterator();
2460:                    while (aapi.hasNext()) {
2461:                        GenericValue appl = (GenericValue) aapi.next();
2462:                        Double lastQuantity = (Double) featureMap.get(appl
2463:                                .getString("productFeatureId"));
2464:                        if (lastQuantity == null) {
2465:                            lastQuantity = new Double(0);
2466:                        }
2467:                        Double newQuantity = new Double(lastQuantity
2468:                                .doubleValue()
2469:                                + quantity);
2470:                        featureMap.put(appl.getString("productFeatureId"),
2471:                                newQuantity);
2472:                    }
2473:                }
2474:                return featureMap;
2475:            }
2476:
2477:            /** Removes an item attribute. */
2478:            public void removeAttribute(String name) {
2479:                attributes.remove(name);
2480:            }
2481:
2482:            /** Sets an item attribute. */
2483:            public void setAttribute(String name, Object value) {
2484:                attributes.put(name, value);
2485:            }
2486:
2487:            /** Return a specific attribute. */
2488:            public Object getAttribute(String name) {
2489:                return attributes.get(name);
2490:            }
2491:
2492:            /** Returns the attributes for the item. */
2493:            public Map getAttributes() {
2494:                return attributes;
2495:            }
2496:
2497:            /** Remove an OrderItemAttribute. */
2498:            public void removeOrderItemAttribute(String name) {
2499:                if (orderItemAttributes != null) {
2500:                    orderItemAttributes.remove(name);
2501:                }
2502:            }
2503:
2504:            /** Creates an OrderItemAttribute entry. */
2505:            public void setOrderItemAttribute(String name, String value) {
2506:                if (orderItemAttributes == null)
2507:                    orderItemAttributes = FastMap.newInstance();
2508:                this .orderItemAttributes.put(name, value);
2509:            }
2510:
2511:            /** Return an OrderItemAttribute. */
2512:            public String getOrderItemAttribute(String name) {
2513:                if (orderItemAttributes == null)
2514:                    return null;
2515:                return (String) this .orderItemAttributes.get(name);
2516:            }
2517:
2518:            public Map getOrderItemAttributes() {
2519:                Map attrs = FastMap.newInstance();
2520:                if (orderItemAttributes != null) {
2521:                    attrs.putAll(orderItemAttributes);
2522:                }
2523:                return attrs;
2524:            }
2525:
2526:            /** Add an adjustment to the order item; don't worry about setting the orderId, orderItemSeqId or orderAdjustmentId; they will be set when the order is created */
2527:            public int addAdjustment(GenericValue adjustment) {
2528:                itemAdjustments.add(adjustment);
2529:                return itemAdjustments.indexOf(adjustment);
2530:            }
2531:
2532:            public void removeAdjustment(GenericValue adjustment) {
2533:                itemAdjustments.remove(adjustment);
2534:            }
2535:
2536:            public void removeAdjustment(int index) {
2537:                itemAdjustments.remove(index);
2538:            }
2539:
2540:            public List getAdjustments() {
2541:                return itemAdjustments;
2542:            }
2543:
2544:            public void removeFeatureAdjustment(String productFeatureId) {
2545:                if (productFeatureId == null)
2546:                    return;
2547:                Iterator itemAdjustmentsIter = itemAdjustments.iterator();
2548:
2549:                while (itemAdjustmentsIter.hasNext()) {
2550:                    GenericValue itemAdjustment = (GenericValue) itemAdjustmentsIter
2551:                            .next();
2552:
2553:                    if (productFeatureId.equals(itemAdjustment
2554:                            .getString("productFeatureId"))) {
2555:                        itemAdjustmentsIter.remove();
2556:                    }
2557:                }
2558:            }
2559:
2560:            public List getOrderItemPriceInfos() {
2561:                return orderItemPriceInfos;
2562:            }
2563:
2564:            /** Add a contact mech to this purpose; the contactMechPurposeTypeId is required */
2565:            public void addContactMech(String contactMechPurposeTypeId,
2566:                    String contactMechId) {
2567:                if (contactMechPurposeTypeId == null)
2568:                    throw new IllegalArgumentException(
2569:                            "You must specify a contactMechPurposeTypeId to add a ContactMech");
2570:                contactMechIdsMap.put(contactMechPurposeTypeId, contactMechId);
2571:            }
2572:
2573:            /** Get the contactMechId for this item given the contactMechPurposeTypeId */
2574:            public String getContactMech(String contactMechPurposeTypeId) {
2575:                return (String) contactMechIdsMap.get(contactMechPurposeTypeId);
2576:            }
2577:
2578:            /** Remove the contactMechId from this item given the contactMechPurposeTypeId */
2579:            public String removeContactMech(String contactMechPurposeTypeId) {
2580:                return (String) contactMechIdsMap
2581:                        .remove(contactMechPurposeTypeId);
2582:            }
2583:
2584:            public Map getOrderItemContactMechIds() {
2585:                return contactMechIdsMap;
2586:            }
2587:
2588:            public void setIsPromo(boolean isPromo) {
2589:                this .isPromo = isPromo;
2590:            }
2591:
2592:            public boolean getIsPromo() {
2593:                return this .isPromo;
2594:            }
2595:
2596:            public List getAlternativeOptionProductIds() {
2597:                return this .alternativeOptionProductIds;
2598:            }
2599:
2600:            public void setAlternativeOptionProductIds(
2601:                    List alternativeOptionProductIds) {
2602:                this .alternativeOptionProductIds = alternativeOptionProductIds;
2603:            }
2604:
2605:            /** Compares the specified object with this cart item. */
2606:            public boolean equals(ShoppingCartItem item) {
2607:                if (item == null)
2608:                    return false;
2609:                return this .equals(item.getProductId(),
2610:                        item.additionalProductFeatureAndAppls, item.attributes,
2611:                        item.prodCatalogId, item.selectedAmount, item
2612:                                .getItemType(), item.getItemGroup(), item
2613:                                .getIsPromo());
2614:            }
2615:
2616:            /** Compares the specified object with this cart item. Defaults isPromo to false. Default to no itemGroup. */
2617:            public boolean equals(String productId,
2618:                    Map additionalProductFeatureAndAppls, Map attributes,
2619:                    String prodCatalogId, double selectedAmount) {
2620:                return equals(productId, additionalProductFeatureAndAppls,
2621:                        attributes, prodCatalogId, selectedAmount, null, null,
2622:                        false);
2623:            }
2624:
2625:            /** Compares the specified object with this cart item. Defaults isPromo to false. */
2626:            public boolean equals(String productId,
2627:                    Map additionalProductFeatureAndAppls, Map attributes,
2628:                    String prodCatalogId, ProductConfigWrapper configWrapper,
2629:                    String itemType,
2630:                    ShoppingCart.ShoppingCartItemGroup itemGroup,
2631:                    double selectedAmount) {
2632:                return equals(productId, null, 0.00, 0.00,
2633:                        additionalProductFeatureAndAppls, attributes,
2634:                        prodCatalogId, selectedAmount, configWrapper, itemType,
2635:                        itemGroup, false);
2636:            }
2637:
2638:            /** Compares the specified object with this cart item including rental data. Defaults isPromo to false. */
2639:            public boolean equals(String productId, Timestamp reservStart,
2640:                    double reservLength, double reservPersons,
2641:                    Map additionalProductFeatureAndAppls, Map attributes,
2642:                    String prodCatalogId, ProductConfigWrapper configWrapper,
2643:                    String itemType,
2644:                    ShoppingCart.ShoppingCartItemGroup itemGroup,
2645:                    double selectedAmount) {
2646:                return equals(productId, reservStart, reservLength,
2647:                        reservPersons, additionalProductFeatureAndAppls,
2648:                        attributes, prodCatalogId, selectedAmount,
2649:                        configWrapper, itemType, itemGroup, false);
2650:            }
2651:
2652:            /** Compares the specified object with this cart item. Defaults isPromo to false. */
2653:            public boolean equals(String productId,
2654:                    Map additionalProductFeatureAndAppls, Map attributes,
2655:                    String prodCatalogId, double selectedAmount,
2656:                    String itemType,
2657:                    ShoppingCart.ShoppingCartItemGroup itemGroup,
2658:                    boolean isPromo) {
2659:                return equals(productId, null, 0.00, 0.00,
2660:                        additionalProductFeatureAndAppls, attributes,
2661:                        prodCatalogId, selectedAmount, null, itemType,
2662:                        itemGroup, isPromo);
2663:            }
2664:
2665:            /** Compares the specified object with this cart item. */
2666:            public boolean equals(String productId, Timestamp reservStart,
2667:                    double reservLength, double reservPersons,
2668:                    Map additionalProductFeatureAndAppls, Map attributes,
2669:                    String prodCatalogId, double selectedAmount,
2670:                    ProductConfigWrapper configWrapper, String itemType,
2671:                    ShoppingCart.ShoppingCartItemGroup itemGroup,
2672:                    boolean isPromo) {
2673:                if (this .productId == null || productId == null) {
2674:                    // all non-product items are unique
2675:                    return false;
2676:                }
2677:                if (!this .productId.equals(productId)) {
2678:                    return false;
2679:                }
2680:
2681:                if ((this .prodCatalogId == null && prodCatalogId != null)
2682:                        || (this .prodCatalogId != null && prodCatalogId == null)) {
2683:                    return false;
2684:                }
2685:                if (this .prodCatalogId != null && prodCatalogId != null
2686:                        && !this .prodCatalogId.equals(prodCatalogId)) {
2687:                    return false;
2688:                }
2689:
2690:                if (this .getSelectedAmount() != selectedAmount) {
2691:                    return false;
2692:                }
2693:
2694:                if ((this .reservStart == null && reservStart != null)
2695:                        || (this .reservStart != null && reservStart == null)) {
2696:                    return false;
2697:                }
2698:                if (this .reservStart != null && reservStart != null
2699:                        && !this .reservStart.equals(reservStart)) {
2700:                    return false;
2701:                }
2702:
2703:                if (this .reservLength != reservLength) {
2704:                    return false;
2705:                }
2706:
2707:                if (this .reservPersons != reservPersons) {
2708:                    return false;
2709:                }
2710:
2711:                if (this .isPromo != isPromo) {
2712:                    return false;
2713:                }
2714:
2715:                if ((this .additionalProductFeatureAndAppls != null && additionalProductFeatureAndAppls != null)
2716:                        && (this .additionalProductFeatureAndAppls.size() != additionalProductFeatureAndAppls
2717:                                .size())
2718:                        && !(this .additionalProductFeatureAndAppls
2719:                                .equals(additionalProductFeatureAndAppls))) {
2720:                    return false;
2721:                }
2722:
2723:                if ((this .attributes != null && attributes != null)
2724:                        && ((this .attributes.size() != attributes.size()) || !(this .attributes
2725:                                .equals(attributes)))) {
2726:                    return false;
2727:                }
2728:
2729:                if (configWrapper != null
2730:                        && !configWrapper.equals(this .configWrapper)) {
2731:                    return false;
2732:                }
2733:
2734:                if (itemType != null && !itemType.equals(this .itemType)) {
2735:                    return false;
2736:                }
2737:
2738:                if (itemGroup != null && !itemGroup.equals(this .itemGroup)) {
2739:                    return false;
2740:                }
2741:
2742:                if (quoteId != null) {
2743:                    // all items linked to a quote are unique
2744:                    return false;
2745:                }
2746:
2747:                if (requirementId != null) {
2748:                    // all items linked to a requirement are unique
2749:                    return false;
2750:                }
2751:
2752:                return true;
2753:            }
2754:
2755:            /** Gets the Product entity. If it is not already retreived gets it from the delegator */
2756:            public GenericValue getProduct() {
2757:                if (this ._product != null) {
2758:                    return this ._product;
2759:                }
2760:                if (this .productId != null) {
2761:                    try {
2762:                        this ._product = this .getDelegator()
2763:                                .findByPrimaryKeyCache("Product",
2764:                                        UtilMisc.toMap("productId", productId));
2765:                    } catch (GenericEntityException e) {
2766:                        throw new RuntimeException(
2767:                                "Entity Engine error getting Product ("
2768:                                        + e.getMessage() + ")");
2769:                    }
2770:                }
2771:                return this ._product;
2772:            }
2773:
2774:            public GenericValue getParentProduct() {
2775:                if (this ._parentProduct != null) {
2776:                    return this ._parentProduct;
2777:                }
2778:                if (this .productId == null) {
2779:                    throw new IllegalStateException("Bad product id");
2780:                }
2781:
2782:                this ._parentProduct = ProductWorker.getParentProduct(productId,
2783:                        this .getDelegator());
2784:
2785:                return this ._parentProduct;
2786:            }
2787:
2788:            public String getParentProductId() {
2789:                GenericValue parentProduct = this .getParentProduct();
2790:                if (parentProduct != null) {
2791:                    return parentProduct.getString("productId");
2792:                } else {
2793:                    return null;
2794:                }
2795:            }
2796:
2797:            public Map getOptionalProductFeatures() {
2798:                if (_product != null) {
2799:                    return ProductWorker.getOptionalProductFeatures(
2800:                            getDelegator(), this .productId);
2801:                } else {
2802:                    // non-product items do not have features
2803:                    return FastMap.newInstance();
2804:                }
2805:            }
2806:
2807:            public GenericDelegator getDelegator() {
2808:                if (delegator == null) {
2809:                    if (UtilValidate.isEmpty(delegatorName)) {
2810:                        throw new IllegalStateException("Bad delegator name");
2811:                    }
2812:                    delegator = GenericDelegator
2813:                            .getGenericDelegator(delegatorName);
2814:                }
2815:                return delegator;
2816:            }
2817:
2818:            public void explodeItem(ShoppingCart cart,
2819:                    LocalDispatcher dispatcher) throws CartItemModifyException {
2820:                double baseQuantity = this .getQuantity();
2821:                int this Index = cart.items().indexOf(this );
2822:                List newItems = new ArrayList();
2823:
2824:                if (baseQuantity > 1) {
2825:                    for (int i = 1; i < baseQuantity; i++) {
2826:                        // clone the item
2827:                        ShoppingCartItem item = new ShoppingCartItem(this );
2828:
2829:                        // set the new item's quantity
2830:                        item.setQuantity(1, dispatcher, cart, false);
2831:
2832:                        // now copy/calc the adjustments
2833:                        Debug.logInfo("Clone's adj: " + item.getAdjustments(),
2834:                                module);
2835:                        if (item.getAdjustments() != null
2836:                                && item.getAdjustments().size() > 0) {
2837:                            List adjustments = new LinkedList(item
2838:                                    .getAdjustments());
2839:                            Iterator adjIterator = adjustments.iterator();
2840:
2841:                            while (adjIterator.hasNext()) {
2842:                                GenericValue adjustment = (GenericValue) adjIterator
2843:                                        .next();
2844:
2845:                                if (adjustment != null) {
2846:                                    item.removeAdjustment(adjustment);
2847:                                    GenericValue newAdjustment = GenericValue
2848:                                            .create(adjustment);
2849:                                    Double adjAmount = newAdjustment
2850:                                            .getDouble("amount");
2851:
2852:                                    // we use != becuase adjustments can be +/-
2853:                                    if (adjAmount != null
2854:                                            && adjAmount.doubleValue() != 0.00)
2855:                                        newAdjustment.set("amount", new Double(
2856:                                                adjAmount.doubleValue()
2857:                                                        / baseQuantity));
2858:                                    Debug.logInfo("Cloned adj: "
2859:                                            + newAdjustment, module);
2860:                                    item.addAdjustment(newAdjustment);
2861:                                } else {
2862:                                    Debug.logInfo("Clone Adjustment is null",
2863:                                            module);
2864:                                }
2865:                            }
2866:                        }
2867:                        newItems.add(item);
2868:                    }
2869:
2870:                    // set this item's quantity
2871:                    this .setQuantity(1, dispatcher, cart, false);
2872:
2873:                    Debug.logInfo("BaseQuantity: " + baseQuantity, module);
2874:                    Debug.logInfo("Item's Adj: " + this .getAdjustments(),
2875:                            module);
2876:
2877:                    // re-calc this item's adjustments
2878:                    if (this .getAdjustments() != null
2879:                            && this .getAdjustments().size() > 0) {
2880:                        List adjustments = new LinkedList(this .getAdjustments());
2881:                        Iterator adjIterator = adjustments.iterator();
2882:
2883:                        while (adjIterator.hasNext()) {
2884:                            GenericValue adjustment = (GenericValue) adjIterator
2885:                                    .next();
2886:
2887:                            if (adjustment != null) {
2888:                                this .removeAdjustment(adjustment);
2889:                                GenericValue newAdjustment = GenericValue
2890:                                        .create(adjustment);
2891:                                Double adjAmount = newAdjustment
2892:                                        .getDouble("amount");
2893:
2894:                                // we use != becuase adjustments can be +/-
2895:                                if (adjAmount != null
2896:                                        && adjAmount.doubleValue() != 0.00)
2897:                                    newAdjustment.set("amount", new Double(
2898:                                            adjAmount.doubleValue()
2899:                                                    / baseQuantity));
2900:                                Debug.logInfo("Updated adj: " + newAdjustment,
2901:                                        module);
2902:                                this .addAdjustment(newAdjustment);
2903:                            }
2904:                        }
2905:                    }
2906:
2907:                    // add the cloned item(s) to the cart
2908:                    Iterator newItemsItr = newItems.iterator();
2909:
2910:                    while (newItemsItr.hasNext()) {
2911:                        cart.addItem(this Index, (ShoppingCartItem) newItemsItr
2912:                                .next());
2913:                    }
2914:                }
2915:            }
2916:
2917:            public static String getPurchaseOrderItemDescription(
2918:                    GenericValue product, GenericValue supplierProduct,
2919:                    Locale locale) {
2920:                String itemDescription = "";
2921:                String supplierProductId = supplierProduct
2922:                        .getString("supplierProductId");
2923:                if (supplierProductId == null) {
2924:                    supplierProductId = "";
2925:                } else {
2926:                    supplierProductId += " ";
2927:                }
2928:                String supplierProductName = supplierProduct
2929:                        .getString("supplierProductName");
2930:                if (supplierProductName == null) {
2931:                    if (supplierProductName == null) {
2932:                        supplierProductName = ProductContentWrapper
2933:                                .getProductContentAsText(product,
2934:                                        "PRODUCT_NAME", locale, null);
2935:                    }
2936:                }
2937:                itemDescription = supplierProductId + supplierProductName;
2938:                return itemDescription;
2939:            }
2940:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.