📄 productpromoworker.java
字号:
/*
* $Id: ProductPromoWorker.java,v 1.44 2004/02/25 05:16:20 jonesde Exp $
*
* Copyright (c) 2001, 2002 The Open For Business Project - www.ofbiz.org
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
* OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
* THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package org.ofbiz.order.shoppingcart.product;
import java.util.*;
import java.sql.Timestamp;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.UtilMisc;
import org.ofbiz.base.util.UtilProperties;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.base.util.UtilDateTime;
import org.ofbiz.entity.GenericDelegator;
import org.ofbiz.entity.GenericEntityException;
import org.ofbiz.entity.GenericValue;
import org.ofbiz.entity.condition.EntityCondition;
import org.ofbiz.entity.condition.EntityConditionList;
import org.ofbiz.entity.condition.EntityExpr;
import org.ofbiz.entity.condition.EntityOperator;
import org.ofbiz.entity.util.EntityUtil;
import org.ofbiz.order.shoppingcart.CartItemModifyException;
import org.ofbiz.order.shoppingcart.ShoppingCart;
import org.ofbiz.order.shoppingcart.ShoppingCartEvents;
import org.ofbiz.order.shoppingcart.ShoppingCartItem;
import org.ofbiz.product.store.ProductStoreWorker;
import org.ofbiz.product.product.ProductContentWrapper;
import org.ofbiz.product.product.ProductSearch;
import org.ofbiz.service.LocalDispatcher;
/**
* ProductPromoWorker - Worker class for catalog/product promotion related functionality
*
* @author <a href="mailto:jonesde@ofbiz.org">David E. Jones</a>
* @author <a href="mailto:jaz@ofbiz.org">Andy Zeneski</a>
* @version $Revision: 1.44 $
* @since 2.0
*/
public class ProductPromoWorker {
public static final String module = ProductPromoWorker.class.getName();
public static List getStoreProductPromos(GenericDelegator delegator, ServletRequest request) {
List productPromos = new LinkedList();
Timestamp nowTimestamp = UtilDateTime.nowTimestamp();
try {
GenericValue productStore = ProductStoreWorker.getProductStore(request);
if (productStore != null) {
String productStoreId = productStore.getString("productStoreId");
Iterator productStorePromoAppls = UtilMisc.toIterator(EntityUtil.filterByDate(productStore.getRelatedCache("ProductStorePromoAppl", UtilMisc.toMap("productStoreId", productStoreId), UtilMisc.toList("sequenceNum")), true));
while (productStorePromoAppls != null && productStorePromoAppls.hasNext()) {
GenericValue productStorePromoAppl = (GenericValue) productStorePromoAppls.next();
GenericValue productPromo = productStorePromoAppl.getRelatedOneCache("ProductPromo");
List productPromoRules = productPromo.getRelatedCache("ProductPromoRule", null, null);
// get the ShoppingCart out of the session.
HttpServletRequest req = null;
ShoppingCart cart = null;
try {
req = (HttpServletRequest) request;
cart = ShoppingCartEvents.getCartObject(req);
} catch (ClassCastException cce) {
Debug.logInfo("Not a HttpServletRequest, no shopping cart found.", module);
}
boolean condResult = true;
if (productPromoRules != null) {
Iterator promoRulesItr = productPromoRules.iterator();
while (condResult && promoRulesItr != null && promoRulesItr.hasNext()) {
GenericValue promoRule = (GenericValue) promoRulesItr.next();
Iterator productPromoConds = UtilMisc.toIterator(promoRule.getRelatedCache("ProductPromoCond", null, UtilMisc.toList("productPromoCondSeqId")));
while (condResult && productPromoConds != null && productPromoConds.hasNext()) {
GenericValue productPromoCond = (GenericValue) productPromoConds.next();
// evaluate the party related conditions; so we don't show the promo if it doesn't apply.
if ("PPIP_PARTY_ID".equals(productPromoCond.getString("inputParamEnumId"))) {
condResult = checkCondition(productPromoCond, cart, delegator, nowTimestamp);
} else if ("PRIP_PARTY_GRP_MEM".equals(productPromoCond.getString("inputParamEnumId"))) {
condResult = checkCondition(productPromoCond, cart, delegator, nowTimestamp);
} else if ("PRIP_PARTY_CLASS".equals(productPromoCond.getString("inputParamEnumId"))) {
condResult = checkCondition(productPromoCond, cart, delegator, nowTimestamp);
} else if ("PPIP_ROLE_TYPE".equals(productPromoCond.getString("inputParamEnumId"))) {
condResult = checkCondition(productPromoCond, cart, delegator, nowTimestamp);
}
}
}
if (!condResult) productPromo = null;
}
if (productPromo != null) productPromos.add(productPromo);
}
}
} catch (GenericEntityException e) {
Debug.logError(e, module);
}
return productPromos;
}
public static void doPromotions(ShoppingCart cart, LocalDispatcher dispatcher) {
// this is called when a user logs in so that per customer limits are honored, called by cart when new userlogin is set
// there is code to store ProductPromoUse information when an order is placed
// ProductPromoUses are ignored if the corresponding order is cancelled
// limits sub total for promos to not use gift cards (products with a don't use in promo indicator), also exclude gift cards from all other promotion considerations including subTotals for discounts, etc
// TODO: (not done, delay, still considering...) add code to check ProductPromoUse limits per promo (customer, promo), and per code (customer, code) to avoid use of promos or codes getting through due to multiple carts getting promos applied at the same time, possibly on totally different servers
GenericDelegator delegator = cart.getDelegator();
Timestamp nowTimestamp = UtilDateTime.nowTimestamp();
// start out by clearing all existing promotions, then we can just add all that apply
cart.clearAllPromotionInformation();
String productStoreId = cart.getProductStoreId();
GenericValue productStore = null;
try {
productStore = delegator.findByPrimaryKeyCache("ProductStore", UtilMisc.toMap("productStoreId", productStoreId));
} catch (GenericEntityException e) {
Debug.logError(e, "Error looking up store with id " + productStoreId, module);
}
if (productStore == null) {
Debug.logWarning("No store found with id " + productStoreId + ", not doing promotions", module);
return;
}
// there will be a ton of db access, so just do a big catch entity exception block
try {
// loop through promotions and get a list of all of the rules...
List productStorePromoApplsList = productStore.getRelatedCache("ProductStorePromoAppl", null, UtilMisc.toList("sequenceNum"));
productStorePromoApplsList = EntityUtil.filterByDate(productStorePromoApplsList, nowTimestamp);
if (productStorePromoApplsList == null || productStorePromoApplsList.size() == 0) {
if (Debug.infoOn()) Debug.logInfo("Not doing promotions, none applied to store with ID " + productStoreId, module);
}
List productPromoList = new LinkedList();
Iterator prodCatalogPromoAppls = UtilMisc.toIterator(productStorePromoApplsList);
while (prodCatalogPromoAppls != null && prodCatalogPromoAppls.hasNext()) {
GenericValue prodCatalogPromoAppl = (GenericValue) prodCatalogPromoAppls.next();
GenericValue productPromo = prodCatalogPromoAppl.getRelatedOneCache("ProductPromo");
productPromoList.add(productPromo);
}
// do a calculate only run through the promotions, then order by descending totalDiscountAmount for each promotion
// NOTE: on this run, with isolatedTestRun passed as false it should not apply any adjustments
// or track which cart items are used for which promotions, but it will track ProductPromoUseInfo and
// useLimits; we are basicly just trying to run each promo "independently" to see how much each is worth
runProductPromos(productPromoList, cart, delegator, dispatcher, nowTimestamp, true);
// NOTE: after that first pass we could remove any that have a 0 totalDiscountAmount from the run list, but we won't because by the time they are run the cart may have changed enough to get them to go; also, certain actions like free shipping should always be run even though we won't know what the totalDiscountAmount is at the time the promotion is run
// each ProductPromoUseInfo on the shopping cart will contain it's total value, so add up all totals for each promoId and put them in a List of Maps
// create a List of Maps with productPromo and totalDiscountAmount, use the Map sorter to sort them descending by totalDiscountAmount
// before sorting split into two lists and sort each list; one list for promos that have a order total condition, and the other list for all promos that don't; then we'll always run the ones that have no condition on the order total first
List productPromoDiscountMapList = new LinkedList();
List productPromoDiscountMapListOrderTotal = new LinkedList();
Iterator productPromoIter = productPromoList.iterator();
while (productPromoIter.hasNext()) {
GenericValue productPromo = (GenericValue) productPromoIter.next();
Map productPromoDiscountMap = UtilMisc.toMap("productPromo", productPromo, "totalDiscountAmount", new Double(cart.getProductPromoUseTotalDiscount(productPromo.getString("productPromoId"))));
if (hasOrderTotalCondition(productPromo, delegator)) {
productPromoDiscountMapListOrderTotal.add(productPromoDiscountMap);
} else {
productPromoDiscountMapList.add(productPromoDiscountMap);
}
}
// sort the Map List, do it ascending because the discount amounts will be negative, so the lowest number is really the highest discount
productPromoDiscountMapList = UtilMisc.sortMaps(productPromoDiscountMapList, UtilMisc.toList("+totalDiscountAmount"));
productPromoDiscountMapListOrderTotal = UtilMisc.sortMaps(productPromoDiscountMapListOrderTotal, UtilMisc.toList("+totalDiscountAmount"));
productPromoDiscountMapList.addAll(productPromoDiscountMapListOrderTotal);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -