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