⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 productpromoworker.java

📁 Sequoia ERP是一个真正的企业级开源ERP解决方案。它提供的模块包括:电子商务应用(e-commerce), POS系统(point of sales),知识管理,存货与仓库管理
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
            agreementItem = EntityUtil.getFirst(agreementItems);        } catch (GenericEntityException e) {            Debug.logError(e, "Error looking up agreement items for agreement with id " + agreementId, module);        }        if (agreementItem == null) {            Debug.logWarning(UtilProperties.getMessage(resource_error,"OrderNoAgreementItemFoundForAgreementWithIdNotDoingPromotions", UtilMisc.toMap("agreementId", agreementId), cart.getLocale()), module);            return productPromoList;        }        try {            // loop through promotions and get a list of all of the rules...            List agreementPromoApplsList = agreementItem.getRelatedCache("AgreementPromoAppl", null, UtilMisc.toList("sequenceNum"));            agreementPromoApplsList = EntityUtil.filterByDate(agreementPromoApplsList, nowTimestamp);            if (agreementPromoApplsList == null || agreementPromoApplsList.size() == 0) {                if (Debug.verboseOn()) Debug.logVerbose("Not doing promotions, none applied to agreement with ID " + agreementId, module);            }            Iterator agreementPromoAppls = UtilMisc.toIterator(agreementPromoApplsList);            while (agreementPromoAppls != null && agreementPromoAppls.hasNext()) {                GenericValue agreementPromoAppl = (GenericValue) agreementPromoAppls.next();                GenericValue productPromo = agreementPromoAppl.getRelatedOneCache("ProductPromo");                productPromoList.add(productPromo);            }        } catch (GenericEntityException e) {            Debug.logError(e, "Error looking up promotion data while doing promotions", module);        }        return productPromoList;    }    public static void doPromotions(ShoppingCart cart, LocalDispatcher dispatcher) {        ProductPromoWorker.doPromotions(cart, null, dispatcher);    }    public static void doPromotions(ShoppingCart cart, List productPromoList, 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();                // there will be a ton of db access, so just do a big catch entity exception block        try {            if (productPromoList == null) {                if (cart.getOrderType().equals("SALES_ORDER")) {                    productPromoList = ProductPromoWorker.getProductStorePromotions(cart, nowTimestamp, dispatcher);                } else {                    productPromoList = ProductPromoWorker.getAgreementPromotions(cart, nowTimestamp, dispatcher);                }            }            // 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 = FastList.newInstance();            List productPromoDiscountMapListOrderTotal = FastList.newInstance();            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);                        List sortedProductPromoList = new ArrayList(productPromoDiscountMapList.size());            Iterator productPromoDiscountMapIter = productPromoDiscountMapList.iterator();            while (productPromoDiscountMapIter.hasNext()) {                Map productPromoDiscountMap = (Map) productPromoDiscountMapIter.next();                GenericValue productPromo = (GenericValue) productPromoDiscountMap.get("productPromo");                sortedProductPromoList.add(productPromo);                if (Debug.verboseOn()) Debug.logVerbose("Sorted Promo [" + productPromo.getString("productPromoId") + "] with total discount: " + productPromoDiscountMap.get("totalDiscountAmount"), module);            }                        // okay, all ready, do the real run, clearing the temporary result first...            cart.clearAllPromotionInformation();            runProductPromos(sortedProductPromoList, cart, delegator, dispatcher, nowTimestamp, false);        } catch (NumberFormatException e) {            Debug.logError(e, "Number not formatted correctly in promotion rules, not completed...", module);        } catch (GenericEntityException e) {            Debug.logError(e, "Error looking up promotion data while doing promotions", module);        } catch (Exception e) {            Debug.logError(e, "Error running promotions, will ignore: " + e.toString(), module);        }    }    protected static boolean hasOrderTotalCondition(GenericValue productPromo, GenericDelegator delegator) throws GenericEntityException {        boolean hasOtCond = false;        List productPromoConds = delegator.findByAndCache("ProductPromoCond", UtilMisc.toMap("productPromoId", productPromo.get("productPromoId")), UtilMisc.toList("productPromoCondSeqId"));        Iterator productPromoCondIter = productPromoConds.iterator();        while (productPromoCondIter.hasNext()) {            GenericValue productPromoCond = (GenericValue) productPromoCondIter.next();            String inputParamEnumId = productPromoCond.getString("inputParamEnumId");            if ("PPIP_ORDER_TOTAL".equals(inputParamEnumId)) {                hasOtCond = true;                break;            }        }        return hasOtCond;    }        protected static void runProductPromos(List productPromoList, ShoppingCart cart, GenericDelegator delegator, LocalDispatcher dispatcher, Timestamp nowTimestamp, boolean isolatedTestRun) throws GeneralException {        String partyId = cart.getPartyId();        // this is our safety net; we should never need to loop through the rules more than a certain number of times, this is that number and may have to be changed for insanely large promo sets...        long maxIterations = 1000;        // part of the safety net to avoid infinite iteration        long numberOfIterations = 0;                // set a max limit on how many times each promo can be run, for cases where there is no use limit this will be the use limit        //default to 2 times the number of items in the cart        long maxUseLimit = 2 * Math.round(cart.getTotalQuantity());                try {            // repeat until no more rules to run: either all rules are run, or no changes to the cart in a loop            boolean cartChanged = true;            while (cartChanged) {                cartChanged = false;                numberOfIterations++;                if (numberOfIterations > maxIterations) {                    Debug.logError("ERROR: While calculating promotions the promotion rules where run more than " + maxIterations + " times, so the calculation has been ended. This should generally never happen unless you have bad rule definitions.", module);                    break;                }                Iterator productPromoIter = productPromoList.iterator();                while (productPromoIter.hasNext()) {                    GenericValue productPromo = (GenericValue) productPromoIter.next();                    String productPromoId = productPromo.getString("productPromoId");                    List productPromoRules = productPromo.getRelatedCache("ProductPromoRule", null, null);                    if (productPromoRules != null && productPromoRules.size() > 0) {                        // always have a useLimit to avoid unlimited looping, default to 1 if no other is specified                        Long candidateUseLimit = getProductPromoUseLimit(productPromo, partyId, delegator);                        Long useLimit = candidateUseLimit;                        if (Debug.verboseOn()) Debug.logVerbose("Running promotion [" + productPromoId + "], useLimit=" + useLimit + ", # of rules=" + productPromoRules.size(), module);                        boolean requireCode = "Y".equals(productPromo.getString("requireCode"));                        // check if promo code required                        if (requireCode) {                            Set enteredCodes = cart.getProductPromoCodesEntered();                            if (enteredCodes.size() > 0) {                                // get all promo codes entered, do a query with an IN condition to see if any of those are related                                EntityCondition codeCondition = new EntityExpr(new EntityExpr("productPromoId", EntityOperator.EQUALS, productPromoId), EntityOperator.AND, new EntityExpr("productPromoCodeId", EntityOperator.IN, enteredCodes));                                // may want to sort by something else to decide which code to use if there is more than one candidate                                List productPromoCodeList = delegator.findByCondition("ProductPromoCode", codeCondition, null, UtilMisc.toList("productPromoCodeId"));                                Iterator productPromoCodeIter = productPromoCodeList.iterator();                                // support multiple promo codes for a single promo, ie if we run into a use limit for one code see if we can find another for this promo                                // check the use limit before each pass so if the promo use limit has been hit we don't keep on trying for the promo code use limit, if there is one of course                                while ((useLimit == null || useLimit.longValue() > cart.getProductPromoUseCount(productPromoId)) && productPromoCodeIter.hasNext()) {                                    GenericValue productPromoCode = (GenericValue) productPromoCodeIter.next();                                    String productPromoCodeId = productPromoCode.getString("productPromoCodeId");                                    Long codeUseLimit = getProductPromoCodeUseLimit(productPromoCode, partyId, delegator);                                    if (runProductPromoRules(cart, cartChanged, useLimit, true, productPromoCodeId, codeUseLimit, maxUseLimit, productPromo, productPromoRules, dispatcher, delegator, nowTimestamp)) {                                        cartChanged = true;                                    }                                                                        if (cart.getProductPromoUseCount(productPromoId) > maxUseLimit) {                                        Debug.logError("ERROR: While calculating promotions the promotion [" + productPromoId + "] action was applied more than " + maxUseLimit + " times, so the calculation has been ended. This should generally never happen unless you have bad rule definitions.", module);                                        break;                                    }                                }                            }                        } else {                            try {                                if (runProductPromoRules(cart, cartChanged, useLimit, false, null, null, maxUseLimit, productPromo, productPromoRules, dispatcher, delegator, nowTimestamp)) {                                    cartChanged = true;                                }                            } catch (RuntimeException e) {                                throw new GeneralException("Error running promotion with ID [" + productPromoId + "]", e);                            }                        }                    }                                        // if this is an isolatedTestRun clear out adjustments and cart item promo use info                    if (isolatedTestRun) {                        cart.clearAllPromotionAdjustments();                        cart.clearCartItemUseInPromoInfo();                    }                }                                // if this is an isolatedTestRun, then only go through it once, never retry                if (isolatedTestRun) {                    cartChanged = false;                }            }        } catch (UseLimitException e) {            Debug.logError(e, e.toString(), module);        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -