protected boolean compareAndAdjustFulfillmentGroupOffers( PromotableOrder order, boolean fgOfferApplied) { Money regularOrderDiscountShippingTotal = BroadleafCurrencyUtils.getMoney(BigDecimal.ZERO, order.getOrderCurrency()); regularOrderDiscountShippingTotal = regularOrderDiscountShippingTotal.add(order.calculateSubtotalWithoutAdjustments()); for (PromotableFulfillmentGroup fg : order.getFulfillmentGroups()) { regularOrderDiscountShippingTotal = regularOrderDiscountShippingTotal.add(fg.getFinalizedPriceWithAdjustments()); } Money discountOrderRegularShippingTotal = BroadleafCurrencyUtils.getMoney(BigDecimal.ZERO, order.getOrderCurrency()); discountOrderRegularShippingTotal = discountOrderRegularShippingTotal.add(order.calculateSubtotalWithAdjustments()); for (PromotableFulfillmentGroup fg : order.getFulfillmentGroups()) { discountOrderRegularShippingTotal = discountOrderRegularShippingTotal.add(fg.calculatePriceWithoutAdjustments()); } if (discountOrderRegularShippingTotal.lessThan(regularOrderDiscountShippingTotal)) { // order/item offer is better; remove totalitarian fulfillment group offer and process other // fg offers order.removeAllCandidateFulfillmentOfferAdjustments(); fgOfferApplied = false; } else { // totalitarian fg offer is better; remove all order/item offers order.removeAllCandidateOrderOfferAdjustments(); order.removeAllCandidateItemOfferAdjustments(); order.getOrder().setSubTotal(order.calculateSubtotalWithAdjustments()); } return fgOfferApplied; }
protected void applyFulfillmentGroupOffer( PromotableFulfillmentGroup promotableFulfillmentGroup, PromotableCandidateFulfillmentGroupOffer fulfillmentGroupOffer) { if (promotableFulfillmentGroup.canApplyOffer(fulfillmentGroupOffer)) { PromotableFulfillmentGroupAdjustment promotableFulfillmentGroupAdjustment = promotableItemFactory.createPromotableFulfillmentGroupAdjustment( fulfillmentGroupOffer, promotableFulfillmentGroup); promotableFulfillmentGroup.addCandidateFulfillmentGroupAdjustment( promotableFulfillmentGroupAdjustment); } }
@Override public void calculateFulfillmentGroupTotal(PromotableOrder order) { Money totalFulfillmentCharges = BroadleafCurrencyUtils.getMoney(BigDecimal.ZERO, order.getOrderCurrency()); for (PromotableFulfillmentGroup fulfillmentGroupMember : order.getFulfillmentGroups()) { PromotableFulfillmentGroup fulfillmentGroup = fulfillmentGroupMember; Money fulfillmentCharges = fulfillmentGroup.getFinalizedPriceWithAdjustments(); fulfillmentGroup.getFulfillmentGroup().setFulfillmentPrice(fulfillmentCharges); totalFulfillmentCharges = totalFulfillmentCharges.add(fulfillmentCharges); } order.setTotalFufillmentCharges(totalFulfillmentCharges); }
@Override public void filterFulfillmentGroupLevelOffer( PromotableOrder order, List<PromotableCandidateFulfillmentGroupOffer> qualifiedFGOffers, Offer offer) { for (PromotableFulfillmentGroup fulfillmentGroup : order.getFulfillmentGroups()) { boolean fgLevelQualification = false; fgQualification: { // handle legacy fields in addition to the 1.5 order rule field if (couldOfferApplyToOrder(offer, order, fulfillmentGroup)) { fgLevelQualification = true; break fgQualification; } for (PromotableOrderItem discreteOrderItem : order.getAllOrderItems()) { if (couldOfferApplyToOrder(offer, order, discreteOrderItem, fulfillmentGroup)) { fgLevelQualification = true; break fgQualification; } } } if (fgLevelQualification) { fgLevelQualification = false; // handle 1.5 FG field if (couldOfferApplyToFulfillmentGroup(offer, fulfillmentGroup)) { fgLevelQualification = true; } } // Item Qualification - new for 1.5! if (fgLevelQualification) { CandidatePromotionItems candidates = couldOfferApplyToOrderItems(offer, fulfillmentGroup.getDiscountableOrderItems()); if (candidates.isMatchedQualifier()) { PromotableCandidateFulfillmentGroupOffer candidateOffer = createCandidateFulfillmentGroupOffer(offer, qualifiedFGOffers, fulfillmentGroup); candidateOffer.getCandidateQualifiersMap().putAll(candidates.getCandidateQualifiersMap()); } } } }
protected boolean couldOfferApplyToFulfillmentGroup( Offer offer, PromotableFulfillmentGroup fulfillmentGroup) { boolean appliesToItem = false; OfferRule rule = null; OfferOfferRuleXref ruleXref = offer.getOfferMatchRulesXref().get(OfferRuleType.FULFILLMENT_GROUP.getType()); if (ruleXref != null && ruleXref.getOfferRule() != null) { rule = ruleXref.getOfferRule(); } if (rule != null && rule.getMatchRule() != null) { HashMap<String, Object> vars = new HashMap<String, Object>(); fulfillmentGroup.updateRuleVariables(vars); Boolean expressionOutcome = executeExpression(rule.getMatchRule(), vars); if (expressionOutcome != null && expressionOutcome) { appliesToItem = true; } } else { appliesToItem = true; } return appliesToItem; }
@Override @SuppressWarnings("unchecked") public boolean applyAllFulfillmentGroupOffers( List<PromotableCandidateFulfillmentGroupOffer> qualifiedFGOffers, PromotableOrder order) { Map<FulfillmentGroupOfferPotential, List<PromotableCandidateFulfillmentGroupOffer>> offerMap = new HashMap< FulfillmentGroupOfferPotential, List<PromotableCandidateFulfillmentGroupOffer>>(); for (PromotableCandidateFulfillmentGroupOffer candidate : qualifiedFGOffers) { FulfillmentGroupOfferPotential potential = new FulfillmentGroupOfferPotential(); potential.setOffer(candidate.getOffer()); if (offerMap.get(potential) == null) { offerMap.put(potential, new ArrayList<PromotableCandidateFulfillmentGroupOffer>()); } offerMap.get(potential).add(candidate); } List<FulfillmentGroupOfferPotential> potentials = new ArrayList<FulfillmentGroupOfferPotential>(); for (FulfillmentGroupOfferPotential potential : offerMap.keySet()) { List<PromotableCandidateFulfillmentGroupOffer> fgOffers = offerMap.get(potential); Collections.sort( fgOffers, new ReverseComparator(new BeanComparator("discountedAmount", new NullComparator()))); Collections.sort(fgOffers, new BeanComparator("priority", new NullComparator())); if (potential.getOffer().isLimitedUsePerOrder() && fgOffers.size() > potential.getOffer().getMaxUsesPerOrder()) { for (int j = potential.getOffer().getMaxUsesPerOrder(); j < fgOffers.size(); j++) { fgOffers.remove(j); } } for (PromotableCandidateFulfillmentGroupOffer candidate : fgOffers) { if (potential.getTotalSavings().getAmount().equals(BankersRounding.zeroAmount())) { BroadleafCurrency currency = order.getOrderCurrency(); if (currency != null) { potential.setTotalSavings(new Money(BigDecimal.ZERO, currency.getCurrencyCode())); } else { potential.setTotalSavings(new Money(BigDecimal.ZERO)); } } Money priceBeforeAdjustments = candidate.getFulfillmentGroup().calculatePriceWithoutAdjustments(); Money discountedPrice = candidate.getDiscountedPrice(); potential.setTotalSavings( potential.getTotalSavings().add(priceBeforeAdjustments.subtract(discountedPrice))); potential.setPriority(candidate.getOffer().getPriority()); } potentials.add(potential); } // Sort fg potentials by priority and discount Collections.sort(potentials, new BeanComparator("totalSavings", Collections.reverseOrder())); Collections.sort(potentials, new BeanComparator("priority")); potentials = removeTrailingNotCombinableFulfillmentGroupOffers(potentials); boolean fgOfferApplied = false; for (FulfillmentGroupOfferPotential potential : potentials) { Offer offer = potential.getOffer(); boolean alreadyContainsTotalitarianOffer = order.isTotalitarianOfferApplied(); List<PromotableCandidateFulfillmentGroupOffer> candidates = offerMap.get(potential); for (PromotableCandidateFulfillmentGroupOffer candidate : candidates) { applyFulfillmentGroupOffer(candidate.getFulfillmentGroup(), candidate); fgOfferApplied = true; } for (PromotableFulfillmentGroup fg : order.getFulfillmentGroups()) { fg.chooseSaleOrRetailAdjustments(); } if ((offer.isTotalitarianOffer() != null && offer.isTotalitarianOffer()) || alreadyContainsTotalitarianOffer) { fgOfferApplied = compareAndAdjustFulfillmentGroupOffers(order, fgOfferApplied); if (fgOfferApplied) { break; } } else if (!offer.isCombinableWithOtherOffers()) { break; } } return fgOfferApplied; }