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()));
}
}
}
}
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;
}
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);
}
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);
}
};
}
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;
}
Aggregations