Search in sources :

Example 11 with PromotableOrder

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

the class OrderOfferProcessorImpl method synchronizeOrderAdjustments.

protected void synchronizeOrderAdjustments(PromotableOrder promotableOrder) {
    Order order = promotableOrder.getOrder();
    if (order.getOrderAdjustments().isEmpty() && promotableOrder.getCandidateOrderAdjustments().isEmpty()) {
        return;
    }
    Map<Long, PromotableOrderAdjustment> newAdjustmentsMap = buildPromotableOrderAdjustmentsMap(promotableOrder);
    Iterator<OrderAdjustment> orderAdjIterator = order.getOrderAdjustments().iterator();
    while (orderAdjIterator.hasNext()) {
        OrderAdjustment adjustment = orderAdjIterator.next();
        if (adjustment.getOffer() != null) {
            Long offerId = adjustment.getOffer().getId();
            PromotableOrderAdjustment promotableAdjustment = newAdjustmentsMap.remove(offerId);
            if (promotableAdjustment != null) {
                if (!adjustment.getValue().equals(promotableAdjustment.getAdjustmentValue())) {
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("Updating value for order adjustment with offer Id " + offerId + " to " + promotableAdjustment.getAdjustmentValue());
                    }
                    adjustment.setValue(promotableAdjustment.getAdjustmentValue());
                }
            } else {
                // No longer using this order adjustment, remove it.
                orderAdjIterator.remove();
            }
        }
    }
    for (PromotableOrderAdjustment promotableOrderAdjustment : newAdjustmentsMap.values()) {
        // Add the newly introduced adjustments.
        Offer offer = promotableOrderAdjustment.getOffer();
        OrderAdjustment orderAdjustment = offerDao.createOrderAdjustment();
        orderAdjustment.init(order, offer, offer.getName());
        orderAdjustment.setValue(promotableOrderAdjustment.getAdjustmentValue());
        order.getOrderAdjustments().add(orderAdjustment);
    }
}
Also used : PromotableOrder(org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrder) Order(org.broadleafcommerce.core.order.domain.Order) PromotableOrderAdjustment(org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrderAdjustment) OrderAdjustment(org.broadleafcommerce.core.offer.domain.OrderAdjustment) PromotableCandidateItemOffer(org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateItemOffer) PromotableCandidateOrderOffer(org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateOrderOffer) Offer(org.broadleafcommerce.core.offer.domain.Offer) PromotableOrderAdjustment(org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrderAdjustment)

Example 12 with PromotableOrder

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

the class OrderOfferProcessorImpl method synchronizeFulfillmentGroups.

protected void synchronizeFulfillmentGroups(PromotableOrder promotableOrder) {
    Order order = promotableOrder.getOrder();
    Map<Long, PromotableFulfillmentGroup> fgMap = buildPromotableFulfillmentGroupMap(promotableOrder);
    for (FulfillmentGroup fg : order.getFulfillmentGroups()) {
        synchronizeFulfillmentGroupAdjustments(fg, fgMap.get(fg.getId()));
    }
}
Also used : PromotableOrder(org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrder) Order(org.broadleafcommerce.core.order.domain.Order) PromotableFulfillmentGroup(org.broadleafcommerce.core.offer.service.discount.domain.PromotableFulfillmentGroup) FulfillmentGroup(org.broadleafcommerce.core.order.domain.FulfillmentGroup) PromotableFulfillmentGroup(org.broadleafcommerce.core.offer.service.discount.domain.PromotableFulfillmentGroup)

Example 13 with PromotableOrder

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

the class OfferServiceImpl method applyAndSaveOffersToOrder.

/*
     *
     * Offers Logic:
     * 1) Remove all existing offers in the Order (order, item, and fulfillment)
     * 2) Check and remove offers
     *    a) Remove out of date offers
     *    b) Remove offers that do not apply to this customer
     * 3) Loop through offers
     *    a) Verifies type of offer (order, order item, fulfillment)
     *    b) Verifies if offer can be applies
     *    c) Assign offer to type (order, order item, or fulfillment)
     * 4) Sorts the order and item offers list by priority and then discount
     * 5) Identify the best offers to apply to order item and create adjustments for each item offer
     * 6) Compare order item adjustment price to sales price, and remove adjustments if sale price is better
     * 7) Identify the best offers to apply to the order and create adjustments for each order offer
     * 8) If item contains non-combinable offers remove either the item or order adjustments based on discount value
     * 9) Set final order item prices and reapply order offers
     *
     * Assumptions:
     * 1) % off all items will be created as an item offer with no expression
     * 2) $ off order will be created as an order offer
     * 3) Order offers applies to the best price for each item (not just retail price)
     * 4) Fulfillment offers apply to best price for each item (not just retail price)
     * 5) Stackable only applies to the same offer type (i.e. a not stackable order offer can be used with item offers)
     * 6) Fulfillment offers cannot be not combinable
     * 7) Order offers cannot be FIXED_PRICE
     * 8) FIXED_PRICE offers cannot be stackable
     * 9) Non-combinable offers only apply to the order and order items, fulfillment group offers will always apply
     *
     */
@Override
@Transactional("blTransactionManager")
public Order applyAndSaveOffersToOrder(List<Offer> offers, Order order) throws PricingException {
    /*
        TODO rather than a threadlocal, we should update the "shouldPrice" boolean on the service API to
        use a richer object to describe the parameters of the pricing call. This object would include
        the pricing boolean, but would also include a list of activities to include or exclude in the
        call - see http://jira.broadleafcommerce.org/browse/BLC-664
         */
    OfferContext offerContext = OfferContext.getOfferContext();
    if (offerContext == null || offerContext.executePromotionCalculation) {
        PromotableOrder promotableOrder = promotableItemFactory.createPromotableOrder(order, false);
        List<Offer> filteredOffers = orderOfferProcessor.filterOffers(offers, order.getCustomer());
        if ((filteredOffers == null) || (filteredOffers.isEmpty())) {
            if (LOG.isTraceEnabled()) {
                LOG.trace("No offers applicable to this order.");
            }
        } else {
            List<PromotableCandidateOrderOffer> qualifiedOrderOffers = new ArrayList<PromotableCandidateOrderOffer>();
            List<PromotableCandidateItemOffer> qualifiedItemOffers = new ArrayList<PromotableCandidateItemOffer>();
            itemOfferProcessor.filterOffers(promotableOrder, filteredOffers, qualifiedOrderOffers, qualifiedItemOffers);
            if (!(qualifiedItemOffers.isEmpty() && qualifiedOrderOffers.isEmpty())) {
                // At this point, we should have a PromotableOrder that contains PromotableItems each of which
                // has a list of candidatePromotions that might be applied.
                // We also have a list of orderOffers that might apply and a list of itemOffers that might apply.
                itemOfferProcessor.applyAndCompareOrderAndItemOffers(promotableOrder, qualifiedOrderOffers, qualifiedItemOffers);
            }
        }
        orderOfferProcessor.synchronizeAdjustmentsAndPrices(promotableOrder);
        verifyAdjustments(order, true);
        order.setSubTotal(order.calculateSubTotal());
        order.finalizeItemPrices();
        order = orderService.save(order, false);
        boolean madeChange = verifyAdjustments(order, false);
        if (madeChange) {
            order = 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) PromotableCandidateItemOffer(org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateItemOffer) PromotableCandidateOrderOffer(org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateOrderOffer) ArrayList(java.util.ArrayList) PromotableOrder(org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrder) Transactional(org.springframework.transaction.annotation.Transactional)

Example 14 with PromotableOrder

use of org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrder 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)

Example 15 with PromotableOrder

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

the class OfferDataItemProvider method createBasicPromotableOrder.

public PromotableOrder createBasicPromotableOrder() {
    Order order = createBasicOrder();
    PromotableOrder promotableOrder = new PromotableOrderImpl(order, new PromotableItemFactoryImpl(), false);
    return promotableOrder;
}
Also used : PromotableOrder(org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrder) Order(org.broadleafcommerce.core.order.domain.Order) PromotableItemFactoryImpl(org.broadleafcommerce.core.offer.service.discount.domain.PromotableItemFactoryImpl) PromotableOrderImpl(org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrderImpl) PromotableOrder(org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrder)

Aggregations

PromotableOrder (org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrder)25 Offer (org.broadleafcommerce.core.offer.domain.Offer)20 ArrayList (java.util.ArrayList)13 CandidateItemOffer (org.broadleafcommerce.core.offer.domain.CandidateItemOffer)11 PromotableCandidateOrderOffer (org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateOrderOffer)9 PromotableCandidateFulfillmentGroupOffer (org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateFulfillmentGroupOffer)8 PromotableCandidateItemOffer (org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateItemOffer)8 PromotableOrderItem (org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrderItem)8 Order (org.broadleafcommerce.core.order.domain.Order)7 CandidateFulfillmentGroupOffer (org.broadleafcommerce.core.offer.domain.CandidateFulfillmentGroupOffer)6 OfferQualifyingCriteriaXref (org.broadleafcommerce.core.offer.domain.OfferQualifyingCriteriaXref)4 CandidatePromotionItems (org.broadleafcommerce.core.offer.service.discount.CandidatePromotionItems)4 Money (org.broadleafcommerce.common.money.Money)3 PromotableFulfillmentGroup (org.broadleafcommerce.core.offer.service.discount.domain.PromotableFulfillmentGroup)3 PromotableItemFactoryImpl (org.broadleafcommerce.core.offer.service.discount.domain.PromotableItemFactoryImpl)3 PromotableOrderImpl (org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrderImpl)3 CustomerOffer (org.broadleafcommerce.core.offer.domain.CustomerOffer)2 OfferDataItemProvider (org.broadleafcommerce.core.offer.service.OfferDataItemProvider)2 PromotableCandidateItemOfferImpl (org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateItemOfferImpl)2 PromotableOrderItemImpl (org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrderItemImpl)2