Search in sources :

Example 16 with BundleOrderItem

use of org.broadleafcommerce.core.order.domain.BundleOrderItem in project BroadleafCommerce by BroadleafCommerce.

the class AutoBundleActivity method unBundleItems.

/**
 * Removes all automatic bundles from the order and replaces with DiscreteOrderItems.
 *
 * @param order
 */
private List<DiscreteOrderItem> unBundleItems(Order order) throws PricingException {
    List<DiscreteOrderItem> unbundledItems = null;
    for (OrderItem orderItem : order.getOrderItems()) {
        if (orderItem instanceof BundleOrderItem) {
            BundleOrderItem bundleOrderItem = (BundleOrderItem) orderItem;
            if (bundleOrderItem.getProductBundle() != null && bundleOrderItem.getProductBundle().getAutoBundle()) {
                if (unbundledItems == null) {
                    unbundledItems = new ArrayList<DiscreteOrderItem>();
                }
                for (DiscreteOrderItem item : bundleOrderItem.getDiscreteOrderItems()) {
                    DiscreteOrderItem newOrderItem = (DiscreteOrderItem) item.clone();
                    newOrderItem.setQuantity(item.getQuantity() * bundleOrderItem.getQuantity());
                    newOrderItem.setSkuBundleItem(null);
                    newOrderItem.setBundleOrderItem(null);
                    newOrderItem.updateSaleAndRetailPrices();
                    newOrderItem.setOrder(order);
                    unbundledItems.add(newOrderItem);
                }
            }
        }
    }
    return unbundledItems;
}
Also used : DiscreteOrderItem(org.broadleafcommerce.core.order.domain.DiscreteOrderItem) BundleOrderItem(org.broadleafcommerce.core.order.domain.BundleOrderItem) DiscreteOrderItem(org.broadleafcommerce.core.order.domain.DiscreteOrderItem) OrderItem(org.broadleafcommerce.core.order.domain.OrderItem) BundleOrderItem(org.broadleafcommerce.core.order.domain.BundleOrderItem)

Example 17 with BundleOrderItem

use of org.broadleafcommerce.core.order.domain.BundleOrderItem in project BroadleafCommerce by BroadleafCommerce.

the class AutoBundleActivity method countMaximumApplications.

protected int countMaximumApplications(Order order, SkuBundleItem skuBundleItem, Set<Long> processedBundles) {
    int skuMatches = 0;
    Long skuId = skuBundleItem.getSku().getId();
    for (OrderItem orderItem : order.getOrderItems()) {
        if (orderItem instanceof DiscreteOrderItem) {
            DiscreteOrderItem item = (DiscreteOrderItem) orderItem;
            if (skuId.equals(item.getSku().getId())) {
                skuMatches = skuMatches + item.getQuantity();
            }
        } else if (orderItem instanceof BundleOrderItem) {
            BundleOrderItem bundleItem = (BundleOrderItem) orderItem;
            if (bundleItem.getProductBundle() != null && bundleItem.getProductBundle().getAutoBundle()) {
                if (!processedBundles.contains(bundleItem.getId())) {
                    for (DiscreteOrderItem discreteItem : bundleItem.getDiscreteOrderItems()) {
                        if (skuId.equals(discreteItem.getSku().getId())) {
                            skuMatches = skuMatches + (discreteItem.getQuantity() * bundleItem.getQuantity());
                        }
                    }
                }
            }
        }
    }
    return skuMatches / skuBundleItem.getQuantity();
}
Also used : DiscreteOrderItem(org.broadleafcommerce.core.order.domain.DiscreteOrderItem) BundleOrderItem(org.broadleafcommerce.core.order.domain.BundleOrderItem) DiscreteOrderItem(org.broadleafcommerce.core.order.domain.DiscreteOrderItem) OrderItem(org.broadleafcommerce.core.order.domain.OrderItem) BundleOrderItem(org.broadleafcommerce.core.order.domain.BundleOrderItem)

Example 18 with BundleOrderItem

use of org.broadleafcommerce.core.order.domain.BundleOrderItem in project BroadleafCommerce by BroadleafCommerce.

the class ConsolidateFulfillmentFeesActivity method execute.

@Override
public ProcessContext<Order> execute(ProcessContext<Order> context) throws Exception {
    Order order = context.getSeedData();
    for (FulfillmentGroup fulfillmentGroup : order.getFulfillmentGroups()) {
        // create and associate all the Fulfillment Fees
        for (FulfillmentGroupItem item : fulfillmentGroup.getFulfillmentGroupItems()) {
            List<SkuFee> fees = null;
            if (item.getOrderItem() instanceof BundleOrderItem) {
                fees = ((BundleOrderItem) item.getOrderItem()).getSku().getFees();
            } else if (item.getOrderItem() instanceof DiscreteOrderItem) {
                fees = ((DiscreteOrderItem) item.getOrderItem()).getSku().getFees();
            }
            if (fees != null) {
                for (SkuFee fee : fees) {
                    if (SkuFeeType.FULFILLMENT.equals(fee.getFeeType())) {
                        if (shouldApplyFeeToFulfillmentGroup(fee, fulfillmentGroup)) {
                            FulfillmentGroupFee fulfillmentFee = fulfillmentGroupService.createFulfillmentGroupFee();
                            fulfillmentFee.setName(fee.getName());
                            fulfillmentFee.setTaxable(fee.getTaxable());
                            fulfillmentFee.setAmount(fee.getAmount());
                            fulfillmentFee.setFulfillmentGroup(fulfillmentGroup);
                            fulfillmentGroup.addFulfillmentGroupFee(fulfillmentFee);
                        }
                    }
                }
            }
        }
        if (fulfillmentGroup.getFulfillmentGroupFees().size() > 0) {
            fulfillmentGroup = fulfillmentGroupService.save(fulfillmentGroup);
        }
    }
    context.setSeedData(order);
    return context;
}
Also used : Order(org.broadleafcommerce.core.order.domain.Order) DiscreteOrderItem(org.broadleafcommerce.core.order.domain.DiscreteOrderItem) BundleOrderItem(org.broadleafcommerce.core.order.domain.BundleOrderItem) SkuFee(org.broadleafcommerce.core.catalog.domain.SkuFee) FulfillmentGroupItem(org.broadleafcommerce.core.order.domain.FulfillmentGroupItem) FulfillmentGroup(org.broadleafcommerce.core.order.domain.FulfillmentGroup) FulfillmentGroupFee(org.broadleafcommerce.core.order.domain.FulfillmentGroupFee)

Example 19 with BundleOrderItem

use of org.broadleafcommerce.core.order.domain.BundleOrderItem in project BroadleafCommerce by BroadleafCommerce.

the class FulfillmentGroupItemStrategyImpl method verify.

@Override
public CartOperationRequest verify(CartOperationRequest request) throws PricingException {
    Order order = request.getOrder();
    if (isRemoveEmptyFulfillmentGroups() && order.getFulfillmentGroups() != null) {
        ListIterator<FulfillmentGroup> fgIter = order.getFulfillmentGroups().listIterator();
        while (fgIter.hasNext()) {
            FulfillmentGroup fg = fgIter.next();
            if (fg.getFulfillmentGroupItems() == null || fg.getFulfillmentGroupItems().size() == 0) {
                fgIter.remove();
                fulfillmentGroupService.delete(fg);
            }
        }
    }
    Map<Long, Integer> oiQuantityMap = new HashMap<Long, Integer>();
    List<OrderItem> expandedOrderItems = new ArrayList<OrderItem>();
    for (OrderItem oi : order.getOrderItems()) {
        if (oi instanceof BundleOrderItem) {
            for (DiscreteOrderItem doi : ((BundleOrderItem) oi).getDiscreteOrderItems()) {
                expandedOrderItems.add(doi);
            }
        } else if (oi instanceof DiscreteOrderItem) {
            expandedOrderItems.add(oi);
        } else {
            expandedOrderItems.add(oi);
        }
    }
    for (OrderItem oi : expandedOrderItems) {
        Integer oiQuantity = oiQuantityMap.get(oi.getId());
        if (oiQuantity == null) {
            oiQuantity = 0;
        }
        if (oi instanceof DiscreteOrderItem && ((DiscreteOrderItem) oi).getBundleOrderItem() != null) {
            oiQuantity += ((DiscreteOrderItem) oi).getBundleOrderItem().getQuantity() * oi.getQuantity();
        } else {
            oiQuantity += oi.getQuantity();
        }
        oiQuantityMap.put(oi.getId(), oiQuantity);
    }
    for (FulfillmentGroup fg : order.getFulfillmentGroups()) {
        for (FulfillmentGroupItem fgi : fg.getFulfillmentGroupItems()) {
            Long oiId = fgi.getOrderItem().getId();
            Integer oiQuantity = oiQuantityMap.get(oiId);
            if (oiQuantity == null) {
                throw new IllegalStateException("Fulfillment group items and discrete order items are not in sync. DiscreteOrderItem id: " + oiId);
            }
            oiQuantity -= fgi.getQuantity();
            oiQuantityMap.put(oiId, oiQuantity);
        }
    }
    for (Entry<Long, Integer> entry : oiQuantityMap.entrySet()) {
        if (!entry.getValue().equals(0)) {
            throw new IllegalStateException("Not enough fulfillment group items found for DiscreteOrderItem id: " + entry.getKey());
        }
    }
    return request;
}
Also used : Order(org.broadleafcommerce.core.order.domain.Order) DiscreteOrderItem(org.broadleafcommerce.core.order.domain.DiscreteOrderItem) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) BundleOrderItem(org.broadleafcommerce.core.order.domain.BundleOrderItem) DiscreteOrderItem(org.broadleafcommerce.core.order.domain.DiscreteOrderItem) OrderItem(org.broadleafcommerce.core.order.domain.OrderItem) BundleOrderItem(org.broadleafcommerce.core.order.domain.BundleOrderItem) FulfillmentGroupItem(org.broadleafcommerce.core.order.domain.FulfillmentGroupItem) FulfillmentGroup(org.broadleafcommerce.core.order.domain.FulfillmentGroup)

Example 20 with BundleOrderItem

use of org.broadleafcommerce.core.order.domain.BundleOrderItem in project BroadleafCommerce by BroadleafCommerce.

the class BandedFulfillmentPricingProvider method estimateCostForFulfillmentGroup.

@Override
public FulfillmentEstimationResponse estimateCostForFulfillmentGroup(FulfillmentGroup fulfillmentGroup, Set<FulfillmentOption> options) throws FulfillmentPriceException {
    // Set up the response object
    FulfillmentEstimationResponse res = new FulfillmentEstimationResponse();
    HashMap<FulfillmentOption, Money> shippingPrices = new HashMap<FulfillmentOption, Money>();
    res.setFulfillmentOptionPrices(shippingPrices);
    for (FulfillmentOption option : options) {
        if (canCalculateCostForFulfillmentGroup(fulfillmentGroup, option)) {
            List<? extends FulfillmentBand> bands = null;
            if (option instanceof BandedPriceFulfillmentOption) {
                bands = ((BandedPriceFulfillmentOption) option).getBands();
            } else if (option instanceof BandedWeightFulfillmentOption) {
                bands = ((BandedWeightFulfillmentOption) option).getBands();
            }
            if (bands == null || bands.isEmpty()) {
                // Something is misconfigured. There are no bands associated with this fulfillment option
                throw new IllegalStateException("There were no Fulfillment Price Bands configured for a BandedPriceFulfillmentOption with ID: " + option.getId());
            }
            // Calculate the amount that the band will be applied to
            BigDecimal retailTotal = BigDecimal.ZERO;
            BigDecimal flatTotal = BigDecimal.ZERO;
            BigDecimal weightTotal = BigDecimal.ZERO;
            boolean foundCandidateForBand = false;
            for (FulfillmentGroupItem fulfillmentGroupItem : fulfillmentGroup.getFulfillmentGroupItems()) {
                // If this item has a Sku associated with it which also has a flat rate for this fulfillment option, don't add it to the price
                // or weight total but instead tack it onto the final rate
                boolean addToTotal = true;
                Sku sku = null;
                if (fulfillmentGroupItem.getOrderItem() instanceof DiscreteOrderItem) {
                    sku = ((DiscreteOrderItem) fulfillmentGroupItem.getOrderItem()).getSku();
                } else if (fulfillmentGroupItem.getOrderItem() instanceof BundleOrderItem) {
                    sku = ((BundleOrderItem) fulfillmentGroupItem.getOrderItem()).getSku();
                }
                if (sku != null && option.getUseFlatRates()) {
                    BigDecimal rate = sku.getFulfillmentFlatRates().get(option);
                    if (rate != null) {
                        addToTotal = false;
                        flatTotal = flatTotal.add(rate);
                    }
                }
                if (addToTotal) {
                    foundCandidateForBand = true;
                    BigDecimal price = (fulfillmentGroupItem.getTotalItemAmount() != null) ? fulfillmentGroupItem.getTotalItemAmount().getAmount() : null;
                    if (price == null) {
                        price = fulfillmentGroupItem.getOrderItem().getAveragePrice().getAmount().multiply(BigDecimal.valueOf(fulfillmentGroupItem.getQuantity()));
                    }
                    retailTotal = retailTotal.add(price);
                    if (sku != null && sku.getWeight() != null && sku.getWeight().getWeight() != null) {
                        BigDecimal convertedWeight = convertWeight(sku.getWeight().getWeight(), sku.getWeight().getWeightUnitOfMeasure()).multiply(BigDecimal.valueOf(fulfillmentGroupItem.getQuantity()));
                        weightTotal = weightTotal.add(convertedWeight);
                    }
                }
            }
            // Used to keep track of the lowest price when there is are bands that have the same
            // minimum amount
            BigDecimal lowestBandFulfillmentPrice = null;
            // Used to keep track of the amount for the lowest band fulfillment price. Used to compare
            // if 2 bands are configured for the same minimum amount
            BigDecimal lowestBandFulfillmentPriceMinimumAmount = BigDecimal.ZERO;
            if (foundCandidateForBand) {
                for (FulfillmentBand band : bands) {
                    BigDecimal bandMinimumAmount = BigDecimal.ZERO;
                    boolean foundMatch = false;
                    if (band instanceof FulfillmentPriceBand) {
                        bandMinimumAmount = ((FulfillmentPriceBand) band).getRetailPriceMinimumAmount();
                        foundMatch = retailTotal.compareTo(bandMinimumAmount) >= 0;
                    } else if (band instanceof FulfillmentWeightBand) {
                        bandMinimumAmount = ((FulfillmentWeightBand) band).getMinimumWeight();
                        foundMatch = weightTotal.compareTo(bandMinimumAmount) >= 0;
                    }
                    if (foundMatch) {
                        // So far, we've found a potential match
                        // Now, determine if this is a percentage or actual amount
                        FulfillmentBandResultAmountType resultAmountType = band.getResultAmountType();
                        BigDecimal bandFulfillmentPrice = null;
                        if (FulfillmentBandResultAmountType.RATE.equals(resultAmountType)) {
                            bandFulfillmentPrice = band.getResultAmount();
                        } else if (FulfillmentBandResultAmountType.PERCENTAGE.equals(resultAmountType)) {
                            // Since this is a percentage, we calculate the result amount based on retailTotal and the band percentage
                            bandFulfillmentPrice = retailTotal.multiply(band.getResultAmount());
                        } else {
                            LOG.warn("Unknown FulfillmentBandResultAmountType: " + resultAmountType.getType() + " Should be RATE or PERCENTAGE. Ignoring.");
                        }
                        if (bandFulfillmentPrice != null) {
                            // haven't initialized the lowest price yet so just take on this one
                            if (lowestBandFulfillmentPrice == null) {
                                lowestBandFulfillmentPrice = bandFulfillmentPrice;
                                lowestBandFulfillmentPriceMinimumAmount = bandMinimumAmount;
                            }
                            // is cheaper
                            if (lowestBandFulfillmentPriceMinimumAmount.compareTo(bandMinimumAmount) == 0) {
                                if (bandFulfillmentPrice.compareTo(lowestBandFulfillmentPrice) <= 0) {
                                    lowestBandFulfillmentPrice = bandFulfillmentPrice;
                                    lowestBandFulfillmentPriceMinimumAmount = bandMinimumAmount;
                                }
                            } else if (bandMinimumAmount.compareTo(lowestBandFulfillmentPriceMinimumAmount) > 0) {
                                lowestBandFulfillmentPrice = bandFulfillmentPrice;
                                lowestBandFulfillmentPriceMinimumAmount = bandMinimumAmount;
                            }
                        } else {
                            throw new IllegalStateException("Bands must have a non-null fulfillment price");
                        }
                    }
                }
            }
            // If I didn't find a valid band, initialize the fulfillment price to zero
            if (lowestBandFulfillmentPrice == null) {
                lowestBandFulfillmentPrice = BigDecimal.ZERO;
            }
            // add the flat rate amount calculated on the Sku
            lowestBandFulfillmentPrice = lowestBandFulfillmentPrice.add(flatTotal);
            shippingPrices.put(option, BroadleafCurrencyUtils.getMoney(lowestBandFulfillmentPrice, fulfillmentGroup.getOrder().getCurrency()));
        }
    }
    return res;
}
Also used : DiscreteOrderItem(org.broadleafcommerce.core.order.domain.DiscreteOrderItem) HashMap(java.util.HashMap) BandedPriceFulfillmentOption(org.broadleafcommerce.core.order.fulfillment.domain.BandedPriceFulfillmentOption) BandedWeightFulfillmentOption(org.broadleafcommerce.core.order.fulfillment.domain.BandedWeightFulfillmentOption) FulfillmentOption(org.broadleafcommerce.core.order.domain.FulfillmentOption) BandedPriceFulfillmentOption(org.broadleafcommerce.core.order.fulfillment.domain.BandedPriceFulfillmentOption) FulfillmentBand(org.broadleafcommerce.core.order.fulfillment.domain.FulfillmentBand) BigDecimal(java.math.BigDecimal) FulfillmentPriceBand(org.broadleafcommerce.core.order.fulfillment.domain.FulfillmentPriceBand) Money(org.broadleafcommerce.common.money.Money) BundleOrderItem(org.broadleafcommerce.core.order.domain.BundleOrderItem) FulfillmentGroupItem(org.broadleafcommerce.core.order.domain.FulfillmentGroupItem) FulfillmentBandResultAmountType(org.broadleafcommerce.core.order.service.type.FulfillmentBandResultAmountType) Sku(org.broadleafcommerce.core.catalog.domain.Sku) BandedWeightFulfillmentOption(org.broadleafcommerce.core.order.fulfillment.domain.BandedWeightFulfillmentOption) FulfillmentWeightBand(org.broadleafcommerce.core.order.fulfillment.domain.FulfillmentWeightBand)

Aggregations

BundleOrderItem (org.broadleafcommerce.core.order.domain.BundleOrderItem)35 DiscreteOrderItem (org.broadleafcommerce.core.order.domain.DiscreteOrderItem)30 OrderItem (org.broadleafcommerce.core.order.domain.OrderItem)23 Order (org.broadleafcommerce.core.order.domain.Order)16 ArrayList (java.util.ArrayList)13 FulfillmentGroupItem (org.broadleafcommerce.core.order.domain.FulfillmentGroupItem)10 FulfillmentGroup (org.broadleafcommerce.core.order.domain.FulfillmentGroup)9 Sku (org.broadleafcommerce.core.catalog.domain.Sku)8 HashMap (java.util.HashMap)7 ProductBundle (org.broadleafcommerce.core.catalog.domain.ProductBundle)5 GiftWrapOrderItem (org.broadleafcommerce.core.order.domain.GiftWrapOrderItem)5 Transactional (org.springframework.transaction.annotation.Transactional)5 Product (org.broadleafcommerce.core.catalog.domain.Product)4 OrderItemRequestDTO (org.broadleafcommerce.core.order.service.call.OrderItemRequestDTO)4 Test (org.testng.annotations.Test)4 List (java.util.List)3 Money (org.broadleafcommerce.common.money.Money)3 Category (org.broadleafcommerce.core.catalog.domain.Category)3 SkuBundleItem (org.broadleafcommerce.core.catalog.domain.SkuBundleItem)3 BigDecimal (java.math.BigDecimal)2