Search in sources :

Example 1 with PromotableOrderItemPriceDetail

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

the class ItemOfferProcessorImpl method calculatePotentialSavings.

/**
 * This method determines the potential savings for each item offer as if it was the only item offer being applied.
 * @param itemOffers
 * @param order
 */
protected void calculatePotentialSavings(List<PromotableCandidateItemOffer> itemOffers, PromotableOrder order) {
    if (itemOffers.size() > 1) {
        for (PromotableCandidateItemOffer itemOffer : itemOffers) {
            Money potentialSavings = new Money(order.getOrderCurrency());
            Offer offer = itemOffer.getOffer();
            BigDecimal calculatedWeightedPercent = new BigDecimal(0);
            markQualifiersAndTargets(order, itemOffer);
            for (PromotableOrderItemPriceDetail detail : order.getAllPromotableOrderItemPriceDetails()) {
                PromotableOrderItem item = detail.getPromotableOrderItem();
                for (PromotionDiscount discount : detail.getPromotionDiscounts()) {
                    Money itemSavings = calculatePotentialSavingsForOrderItem(itemOffer, item, discount.getQuantity());
                    potentialSavings = potentialSavings.add(itemSavings);
                    if (useCalculatePercent(offer)) {
                        BigDecimal discountPercent = calculatePercent(item.calculateTotalWithoutAdjustments(), itemSavings);
                        calculatedWeightedPercent = calculatedWeightedPercent.add(discountPercent);
                    } else if (hasQualifierAndQualifierRestricted(offer)) {
                        BigDecimal discountPercent = calculateWeightedPercent(discount, item, itemSavings);
                        calculatedWeightedPercent = calculatedWeightedPercent.add(discountPercent);
                    }
                }
                // Reset state back for next offer
                detail.getPromotionDiscounts().clear();
                detail.getPromotionQualifiers().clear();
            }
            itemOffer.setPotentialSavings(potentialSavings);
            if (usePercentOffValue(offer)) {
                itemOffer.setWeightedPercentSaved(offer.getValue());
            } else if (useCalculatePercent(offer) || hasQualifierAndQualifierRestricted(offer)) {
                itemOffer.setWeightedPercentSaved(calculatedWeightedPercent);
            }
            if (itemOffer.getUses() == 0) {
                itemOffer.setPotentialSavingsQtyOne(potentialSavings);
            } else {
                itemOffer.setPotentialSavingsQtyOne(potentialSavings.divide(itemOffer.getUses()));
            }
        }
    }
}
Also used : Money(org.broadleafcommerce.common.money.Money) PromotableCandidateItemOffer(org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateItemOffer) 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) BigDecimal(java.math.BigDecimal) PromotableOrderItem(org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrderItem) PromotionDiscount(org.broadleafcommerce.core.offer.service.discount.PromotionDiscount) PromotableOrderItemPriceDetail(org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrderItemPriceDetail)

Example 2 with PromotableOrderItemPriceDetail

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

the class ItemOfferProcessorImpl method markQualifiers.

/**
 * Loop through ItemCriteria and mark qualifiers required to give the promotion to 1 or more targets.
 * @param itemOffer
 * @param order
 * @return
 */
protected boolean markQualifiers(PromotableCandidateItemOffer itemOffer, PromotableOrder order) {
    for (OfferItemCriteria itemCriteria : itemOffer.getCandidateQualifiersMap().keySet()) {
        List<PromotableOrderItem> promotableItems = itemOffer.getCandidateQualifiersMap().get(itemCriteria);
        List<PromotableOrderItemPriceDetail> priceDetails = buildPriceDetailListFromOrderItems(promotableItems);
        int qualifierQtyNeeded = offerServiceUtilities.markQualifiersForCriteria(itemOffer, itemCriteria, priceDetails);
        if (qualifierQtyNeeded != 0) {
            return false;
        }
    }
    return true;
}
Also used : OfferItemCriteria(org.broadleafcommerce.core.offer.domain.OfferItemCriteria) PromotableOrderItem(org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrderItem) PromotableOrderItemPriceDetail(org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrderItemPriceDetail)

Example 3 with PromotableOrderItemPriceDetail

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

the class OrderOfferProcessorImpl method synchronizeItemPriceDetails.

protected void synchronizeItemPriceDetails(OrderItem orderItem, PromotableOrderItem promotableOrderItem) {
    Map<String, PromotableOrderItemPriceDetail> promotableDetailsMap = buildPromotableDetailsMap(promotableOrderItem);
    Map<Long, OrderItemPriceDetail> unmatchedDetailsMap = new HashMap<Long, OrderItemPriceDetail>();
    for (OrderItemPriceDetail orderItemPriceDetail : orderItem.getOrderItemPriceDetails()) {
        String detailKey = buildItemPriceDetailKey(orderItemPriceDetail);
        PromotableOrderItemPriceDetail promotableDetail = promotableDetailsMap.remove(detailKey);
        if (promotableDetail != null) {
            processMatchingDetails(orderItemPriceDetail, promotableDetail);
        } else {
            unmatchedDetailsMap.put(orderItemPriceDetail.getId(), orderItemPriceDetail);
        }
    }
    Iterator<OrderItemPriceDetail> unmatchedDetailsIterator = unmatchedDetailsMap.values().iterator();
    for (PromotableOrderItemPriceDetail priceDetail : promotableDetailsMap.values()) {
        if (unmatchedDetailsIterator.hasNext()) {
            // Reuse an existing priceDetail
            OrderItemPriceDetail existingDetail = unmatchedDetailsIterator.next();
            // Reset use Sale flag to true
            existingDetail.setUseSalePrice(true);
            offerServiceUtilities.updatePriceDetail(existingDetail, priceDetail);
            unmatchedDetailsIterator.remove();
        } else {
            // Create a new priceDetail
            OrderItemPriceDetail newPriceDetail = orderItemDao.createOrderItemPriceDetail();
            newPriceDetail.setOrderItem(orderItem);
            offerServiceUtilities.updatePriceDetail(newPriceDetail, priceDetail);
            orderItem.getOrderItemPriceDetails().add(newPriceDetail);
        }
    }
    // Remove any unmatched details
    Iterator<OrderItemPriceDetail> pdIterator = orderItem.getOrderItemPriceDetails().iterator();
    offerServiceUtilities.removeUnmatchedPriceDetails(unmatchedDetailsMap, pdIterator);
}
Also used : HashMap(java.util.HashMap) OrderItemPriceDetail(org.broadleafcommerce.core.order.domain.OrderItemPriceDetail) PromotableOrderItemPriceDetail(org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrderItemPriceDetail) PromotableOrderItemPriceDetail(org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrderItemPriceDetail)

Example 4 with PromotableOrderItemPriceDetail

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

the class OfferServiceUtilitiesImpl method getPromotableItemComparator.

protected Comparator<PromotableOrderItemPriceDetail> getPromotableItemComparator(final boolean applyToSalePrice) {
    return new Comparator<PromotableOrderItemPriceDetail>() {

        @Override
        public int compare(PromotableOrderItemPriceDetail o1, PromotableOrderItemPriceDetail o2) {
            Money price = o1.getPromotableOrderItem().getPriceBeforeAdjustments(applyToSalePrice);
            Money price2 = o2.getPromotableOrderItem().getPriceBeforeAdjustments(applyToSalePrice);
            // highest amount first
            return price2.compareTo(price);
        }
    };
}
Also used : Money(org.broadleafcommerce.common.money.Money) Comparator(java.util.Comparator) PromotableOrderItemPriceDetail(org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrderItemPriceDetail)

Example 5 with PromotableOrderItemPriceDetail

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

the class OfferServiceUtilitiesImpl method markTargetsForCriteria.

@Override
public int markTargetsForCriteria(PromotableCandidateItemOffer itemOffer, OrderItem relatedQualifier, boolean checkOnly, Offer promotion, OrderItem relatedQualifierRoot, OfferItemCriteria itemCriteria, List<PromotableOrderItemPriceDetail> priceDetails, int targetQtyNeeded) {
    for (PromotableOrderItemPriceDetail priceDetail : priceDetails) {
        if (relatedQualifier != null) {
            // We need to make sure that this item is either a parent, child, or the same as the qualifier root
            OrderItem thisItem = priceDetail.getPromotableOrderItem().getOrderItem();
            if (!relatedQualifierRoot.isAParentOf(thisItem) && !thisItem.isAParentOf(relatedQualifierRoot) && !thisItem.equals(relatedQualifierRoot)) {
                continue;
            }
        }
        int itemQtyAvailableToBeUsedAsTarget = priceDetail.getQuantityAvailableToBeUsedAsTarget(itemOffer);
        if (itemQtyAvailableToBeUsedAsTarget > 0) {
            if (promotion.isUnlimitedUsePerOrder() || (itemOffer.getUses() < promotion.getMaxUsesPerOrder())) {
                int qtyToMarkAsTarget = Math.min(targetQtyNeeded, itemQtyAvailableToBeUsedAsTarget);
                targetQtyNeeded -= qtyToMarkAsTarget;
                if (!checkOnly) {
                    priceDetail.addPromotionDiscount(itemOffer, itemCriteria, qtyToMarkAsTarget);
                }
            }
        }
        if (targetQtyNeeded == 0) {
            break;
        }
    }
    return targetQtyNeeded;
}
Also used : PromotableOrderItem(org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrderItem) DiscreteOrderItem(org.broadleafcommerce.core.order.domain.DiscreteOrderItem) OrderItem(org.broadleafcommerce.core.order.domain.OrderItem) PromotableOrderItemPriceDetail(org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrderItemPriceDetail)

Aggregations

PromotableOrderItemPriceDetail (org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrderItemPriceDetail)12 PromotableOrderItem (org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrderItem)7 OfferItemCriteria (org.broadleafcommerce.core.offer.domain.OfferItemCriteria)4 OrderItem (org.broadleafcommerce.core.order.domain.OrderItem)4 Money (org.broadleafcommerce.common.money.Money)3 DiscreteOrderItem (org.broadleafcommerce.core.order.domain.DiscreteOrderItem)3 Offer (org.broadleafcommerce.core.offer.domain.Offer)2 PromotionDiscount (org.broadleafcommerce.core.offer.service.discount.PromotionDiscount)2 PromotionQualifier (org.broadleafcommerce.core.offer.service.discount.PromotionQualifier)2 PromotableCandidateItemOffer (org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateItemOffer)2 PromotableCandidateOrderOffer (org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateOrderOffer)2 BigDecimal (java.math.BigDecimal)1 ArrayList (java.util.ArrayList)1 Comparator (java.util.Comparator)1 HashMap (java.util.HashMap)1 List (java.util.List)1 OrderItemPriceDetail (org.broadleafcommerce.core.order.domain.OrderItemPriceDetail)1 OrderItemHolder (org.broadleafcommerce.core.order.domain.dto.OrderItemHolder)1