Search in sources :

Example 1 with PromotableCandidateFulfillmentGroupOffer

use of org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateFulfillmentGroupOffer in project BroadleafCommerce by BroadleafCommerce.

the class FulfillmentGroupOfferProcessorTest method testFilterFulfillmentGroupLevelOffer.

public void testFilterFulfillmentGroupLevelOffer() {
    replay();
    PromotableOrder order = dataProvider.createBasicPromotableOrder();
    List<PromotableCandidateFulfillmentGroupOffer> qualifiedOffers = new ArrayList<PromotableCandidateFulfillmentGroupOffer>();
    List<Offer> offers = dataProvider.createFGBasedOffer("order.subTotal.getAmount()>20", "fulfillmentGroup.address.postalCode==75244", OfferDiscountType.PERCENT_OFF);
    fgProcessor.filterFulfillmentGroupLevelOffer(order, qualifiedOffers, offers.get(0));
    // test that the valid fg offer is included
    // No item criteria, so each fulfillment group applies
    assertTrue(qualifiedOffers.size() == 2 && qualifiedOffers.get(0).getOffer().equals(offers.get(0)));
    qualifiedOffers = new ArrayList<PromotableCandidateFulfillmentGroupOffer>();
    offers = dataProvider.createFGBasedOfferWithItemCriteria("order.subTotal.getAmount()>20", "fulfillmentGroup.address.postalCode==75244", OfferDiscountType.PERCENT_OFF, "([MVEL.eval(\"toUpperCase()\",\"test1\")] contains MVEL.eval(\"toUpperCase()\", discreteOrderItem.category.name))");
    fgProcessor.filterFulfillmentGroupLevelOffer(order, qualifiedOffers, offers.get(0));
    // test that the valid fg offer is included
    // only 1 fulfillment group has qualifying items
    assertTrue(qualifiedOffers.size() == 1 && qualifiedOffers.get(0).getOffer().equals(offers.get(0)));
    qualifiedOffers = new ArrayList<PromotableCandidateFulfillmentGroupOffer>();
    offers = dataProvider.createFGBasedOfferWithItemCriteria("order.subTotal.getAmount()>20", "fulfillmentGroup.address.postalCode==75240", OfferDiscountType.PERCENT_OFF, "([MVEL.eval(\"toUpperCase()\",\"test1\"),MVEL.eval(\"toUpperCase()\",\"test2\")] contains MVEL.eval(\"toUpperCase()\", discreteOrderItem.category.name))");
    fgProcessor.filterFulfillmentGroupLevelOffer(order, qualifiedOffers, offers.get(0));
    // test that the invalid fg offer is excluded - zipcode is wrong
    assertTrue(qualifiedOffers.size() == 0);
    qualifiedOffers = new ArrayList<PromotableCandidateFulfillmentGroupOffer>();
    offers = dataProvider.createFGBasedOfferWithItemCriteria("order.subTotal.getAmount()>20", "fulfillmentGroup.address.postalCode==75244", OfferDiscountType.PERCENT_OFF, "([MVEL.eval(\"toUpperCase()\",\"test5\"),MVEL.eval(\"toUpperCase()\",\"test6\")] contains MVEL.eval(\"toUpperCase()\", discreteOrderItem.category.name))");
    fgProcessor.filterFulfillmentGroupLevelOffer(order, qualifiedOffers, offers.get(0));
    // test that the invalid fg offer is excluded - no qualifying items
    assertTrue(qualifiedOffers.size() == 0);
    verify();
}
Also used : CandidateFulfillmentGroupOffer(org.broadleafcommerce.core.offer.domain.CandidateFulfillmentGroupOffer) PromotableCandidateFulfillmentGroupOffer(org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateFulfillmentGroupOffer) CandidateItemOffer(org.broadleafcommerce.core.offer.domain.CandidateItemOffer) Offer(org.broadleafcommerce.core.offer.domain.Offer) ArrayList(java.util.ArrayList) PromotableCandidateFulfillmentGroupOffer(org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateFulfillmentGroupOffer) PromotableOrder(org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrder)

Example 2 with PromotableCandidateFulfillmentGroupOffer

use of org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateFulfillmentGroupOffer in project BroadleafCommerce by BroadleafCommerce.

the class FulfillmentGroupOfferProcessorImpl method createCandidateFulfillmentGroupOffer.

protected PromotableCandidateFulfillmentGroupOffer createCandidateFulfillmentGroupOffer(Offer offer, List<PromotableCandidateFulfillmentGroupOffer> qualifiedFGOffers, PromotableFulfillmentGroup fulfillmentGroup) {
    PromotableCandidateFulfillmentGroupOffer promotableCandidateFulfillmentGroupOffer = promotableItemFactory.createPromotableCandidateFulfillmentGroupOffer(fulfillmentGroup, offer);
    qualifiedFGOffers.add(promotableCandidateFulfillmentGroupOffer);
    return promotableCandidateFulfillmentGroupOffer;
}
Also used : PromotableCandidateFulfillmentGroupOffer(org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateFulfillmentGroupOffer)

Example 3 with PromotableCandidateFulfillmentGroupOffer

use of org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateFulfillmentGroupOffer in project BroadleafCommerce by BroadleafCommerce.

the class FulfillmentGroupOfferProcessorImpl method filterFulfillmentGroupLevelOffer.

@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());
            // on all the items in the order across all fulfillment groups (not the default behavior)
            if (!candidates.isMatchedQualifier() && getQualifyGroupAcrossAllOrderItems(fulfillmentGroup)) {
                candidates = couldOfferApplyToOrderItems(offer, order.getAllOrderItems());
            }
            if (candidates.isMatchedQualifier()) {
                PromotableCandidateFulfillmentGroupOffer candidateOffer = createCandidateFulfillmentGroupOffer(offer, qualifiedFGOffers, fulfillmentGroup);
                candidateOffer.getCandidateQualifiersMap().putAll(candidates.getCandidateQualifiersMap());
            }
        }
    }
}
Also used : CandidatePromotionItems(org.broadleafcommerce.core.offer.service.discount.CandidatePromotionItems) PromotableFulfillmentGroup(org.broadleafcommerce.core.offer.service.discount.domain.PromotableFulfillmentGroup) PromotableCandidateFulfillmentGroupOffer(org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateFulfillmentGroupOffer) PromotableOrderItem(org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrderItem)

Example 4 with PromotableCandidateFulfillmentGroupOffer

use of org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateFulfillmentGroupOffer in project BroadleafCommerce by BroadleafCommerce.

the class FulfillmentGroupOfferProcessorImpl method applyAllFulfillmentGroupOffers.

@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);
            }
        }
        filterOffersByQualifyingAndSubtotalRequirements(order, fgOffers);
        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;
}
Also used : HashMap(java.util.HashMap) NullComparator(org.apache.commons.collections.comparators.NullComparator) FulfillmentGroupOfferPotential(org.broadleafcommerce.core.offer.service.discount.FulfillmentGroupOfferPotential) ArrayList(java.util.ArrayList) ReverseComparator(org.apache.commons.collections.comparators.ReverseComparator) BeanComparator(org.apache.commons.beanutils.BeanComparator) Money(org.broadleafcommerce.common.money.Money) BroadleafCurrency(org.broadleafcommerce.common.currency.domain.BroadleafCurrency) PromotableCandidateFulfillmentGroupOffer(org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateFulfillmentGroupOffer) Offer(org.broadleafcommerce.core.offer.domain.Offer) PromotableFulfillmentGroup(org.broadleafcommerce.core.offer.service.discount.domain.PromotableFulfillmentGroup) ArrayList(java.util.ArrayList) List(java.util.List) PromotableCandidateFulfillmentGroupOffer(org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateFulfillmentGroupOffer)

Example 5 with PromotableCandidateFulfillmentGroupOffer

use of org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateFulfillmentGroupOffer in project BroadleafCommerce by BroadleafCommerce.

the class OfferServiceImpl method applyAndSaveFulfillmentGroupOffersToOrder.

@Override
@Transactional("blTransactionManager")
public Order applyAndSaveFulfillmentGroupOffersToOrder(List<Offer> offers, Order order) throws PricingException {
    OfferContext offerContext = OfferContext.getOfferContext();
    if (offerContext == null || offerContext.executePromotionCalculation) {
        PromotableOrder promotableOrder = promotableItemFactory.createPromotableOrder(order, true);
        List<Offer> possibleFGOffers = new ArrayList<Offer>();
        for (Offer offer : offers) {
            if (offer.getType().getType().equals(OfferType.FULFILLMENT_GROUP.getType())) {
                possibleFGOffers.add(offer);
            }
        }
        List<Offer> filteredOffers = orderOfferProcessor.filterOffers(possibleFGOffers, order.getCustomer());
        List<PromotableCandidateFulfillmentGroupOffer> qualifiedFGOffers = new ArrayList<PromotableCandidateFulfillmentGroupOffer>();
        for (Offer offer : filteredOffers) {
            fulfillmentGroupOfferProcessor.filterFulfillmentGroupLevelOffer(promotableOrder, qualifiedFGOffers, offer);
        }
        if (!qualifiedFGOffers.isEmpty()) {
            fulfillmentGroupOfferProcessor.applyAllFulfillmentGroupOffers(qualifiedFGOffers, promotableOrder);
            fulfillmentGroupOfferProcessor.calculateFulfillmentGroupTotal(promotableOrder);
            orderOfferProcessor.synchronizeAdjustmentsAndPrices(promotableOrder);
        }
        return orderService.save(order, false);
    }
    return order;
}
Also used : PromotableCandidateItemOffer(org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateItemOffer) PromotableCandidateFulfillmentGroupOffer(org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateFulfillmentGroupOffer) PromotableCandidateOrderOffer(org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateOrderOffer) CustomerOffer(org.broadleafcommerce.core.offer.domain.CustomerOffer) Offer(org.broadleafcommerce.core.offer.domain.Offer) ArrayList(java.util.ArrayList) PromotableCandidateFulfillmentGroupOffer(org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateFulfillmentGroupOffer) PromotableOrder(org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrder) Transactional(org.springframework.transaction.annotation.Transactional)

Aggregations

PromotableCandidateFulfillmentGroupOffer (org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateFulfillmentGroupOffer)7 ArrayList (java.util.ArrayList)5 Offer (org.broadleafcommerce.core.offer.domain.Offer)5 PromotableFulfillmentGroup (org.broadleafcommerce.core.offer.service.discount.domain.PromotableFulfillmentGroup)4 PromotableOrder (org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrder)4 CandidateFulfillmentGroupOffer (org.broadleafcommerce.core.offer.domain.CandidateFulfillmentGroupOffer)3 CandidateItemOffer (org.broadleafcommerce.core.offer.domain.CandidateItemOffer)3 PromotableOrderItem (org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrderItem)2 BigDecimal (java.math.BigDecimal)1 HashMap (java.util.HashMap)1 List (java.util.List)1 BeanComparator (org.apache.commons.beanutils.BeanComparator)1 NullComparator (org.apache.commons.collections.comparators.NullComparator)1 ReverseComparator (org.apache.commons.collections.comparators.ReverseComparator)1 BroadleafCurrency (org.broadleafcommerce.common.currency.domain.BroadleafCurrency)1 Money (org.broadleafcommerce.common.money.Money)1 CustomerOffer (org.broadleafcommerce.core.offer.domain.CustomerOffer)1 CandidatePromotionItems (org.broadleafcommerce.core.offer.service.discount.CandidatePromotionItems)1 FulfillmentGroupOfferPotential (org.broadleafcommerce.core.offer.service.discount.FulfillmentGroupOfferPotential)1 PromotableCandidateItemOffer (org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateItemOffer)1