use of org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrderItem 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());
}
}
}
}
use of org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrderItem in project BroadleafCommerce by BroadleafCommerce.
the class ItemOfferProcessorImpl method filterItemLevelOffer.
/* (non-Javadoc)
* @see org.broadleafcommerce.core.offer.service.processor.ItemOfferProcessor#filterItemLevelOffer(org.broadleafcommerce.core.order.domain.Order, java.util.List, java.util.List, org.broadleafcommerce.core.offer.domain.Offer)
*/
@Override
public void filterItemLevelOffer(PromotableOrder order, List<PromotableCandidateItemOffer> qualifiedItemOffers, Offer offer) {
boolean isNewFormat = CollectionUtils.isNotEmpty(offer.getQualifyingItemCriteriaXref()) || CollectionUtils.isNotEmpty(offer.getTargetItemCriteriaXref());
boolean itemLevelQualification = false;
boolean offerCreated = false;
for (PromotableOrderItem promotableOrderItem : order.getDiscountableOrderItems()) {
if (couldOfferApplyToOrder(offer, order, promotableOrderItem)) {
if (!isNewFormat) {
// support legacy offers
PromotableCandidateItemOffer candidate = createCandidateItemOffer(qualifiedItemOffers, offer, order);
if (!candidate.getLegacyCandidateTargets().contains(promotableOrderItem)) {
candidate.getLegacyCandidateTargets().add(promotableOrderItem);
}
offerCreated = true;
continue;
}
itemLevelQualification = true;
break;
}
for (PromotableFulfillmentGroup fulfillmentGroup : order.getFulfillmentGroups()) {
if (couldOfferApplyToOrder(offer, order, promotableOrderItem, fulfillmentGroup)) {
if (!isNewFormat) {
// support legacy offers
PromotableCandidateItemOffer candidate = createCandidateItemOffer(qualifiedItemOffers, offer, order);
if (!candidate.getLegacyCandidateTargets().contains(promotableOrderItem)) {
candidate.getLegacyCandidateTargets().add(promotableOrderItem);
}
offerCreated = true;
continue;
}
itemLevelQualification = true;
break;
}
}
}
// Item Qualification - new for 1.5!
if (itemLevelQualification && !offerCreated) {
CandidatePromotionItems candidates = couldOfferApplyToOrderItems(offer, order.getDiscountableOrderItems(offer.getApplyDiscountToSalePrice()));
PromotableCandidateItemOffer candidateOffer = null;
if (candidates.isMatchedQualifier()) {
// we don't know the final target yet, so put null for the order item for now
candidateOffer = createCandidateItemOffer(qualifiedItemOffers, offer, order);
candidateOffer.getCandidateQualifiersMap().putAll(candidates.getCandidateQualifiersMap());
}
if (candidates.isMatchedTarget() && candidates.isMatchedQualifier()) {
if (candidateOffer == null) {
// we don't know the final target yet, so put null for the order item for now
candidateOffer = createCandidateItemOffer(qualifiedItemOffers, offer, order);
}
candidateOffer.getCandidateTargetsMap().putAll(candidates.getCandidateTargetsMap());
}
}
}
use of org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrderItem in project BroadleafCommerce by BroadleafCommerce.
the class ItemOfferProcessorImpl method markTargets.
/**
* Loop through ItemCriteria and mark targets that can get this promotion to give the promotion to 1 or more targets.
* @param itemOffer
* @param order
* @return
*/
public boolean markTargets(PromotableCandidateItemOffer itemOffer, PromotableOrder order, OrderItem relatedQualifier, boolean checkOnly) {
Offer promotion = itemOffer.getOffer();
if (itemOffer.getCandidateTargetsMap().keySet().isEmpty()) {
return false;
}
OrderItem relatedQualifierRoot = offerServiceUtilities.findRelatedQualifierRoot(relatedQualifier);
for (OfferItemCriteria itemCriteria : itemOffer.getCandidateTargetsMap().keySet()) {
List<PromotableOrderItem> promotableItems = itemOffer.getCandidateTargetsMap().get(itemCriteria);
List<PromotableOrderItemPriceDetail> priceDetails = buildPriceDetailListFromOrderItems(promotableItems);
offerServiceUtilities.sortTargetItemDetails(priceDetails, itemOffer.getOffer().getApplyDiscountToSalePrice());
int targetQtyNeeded = itemCriteria.getQuantity();
// This code was added to support a requirement of buying at least "x" matching items
// but also applying the item to "x+1", "x+2", etc.
int minRequiredTargetQuantity = itemOffer.getMinimumRequiredTargetQuantity();
if (minRequiredTargetQuantity > 1 && minRequiredTargetQuantity > targetQtyNeeded) {
targetQtyNeeded = minRequiredTargetQuantity;
}
targetQtyNeeded = offerServiceUtilities.markTargetsForCriteria(itemOffer, relatedQualifier, checkOnly, promotion, relatedQualifierRoot, itemCriteria, priceDetails, targetQtyNeeded);
if (targetQtyNeeded != 0) {
return false;
}
}
if (!checkOnly) {
itemOffer.addUse();
}
return true;
}
use of org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrderItem in project BroadleafCommerce by BroadleafCommerce.
the class ItemOfferProcessorImpl method determineBestPermutation.
protected List<PromotableCandidateItemOffer> determineBestPermutation(List<PromotableCandidateItemOffer> itemOffers, PromotableOrder order) {
List<List<PromotableCandidateItemOffer>> permutations = buildItemOfferPermutations(itemOffers);
removeDuplicatePermutations(permutations);
List<PromotableCandidateItemOffer> bestOfferList = null;
Money lowestSubtotal = null;
if (permutations.size() > 1) {
for (List<PromotableCandidateItemOffer> offerList : permutations) {
for (PromotableCandidateItemOffer offer : offerList) {
offer.resetUses();
}
applyAllItemOffers(offerList, order);
chooseSaleOrRetailAdjustments(order);
Money testSubtotal = order.calculateSubtotalWithAdjustments();
if (lowestSubtotal == null || testSubtotal.lessThan(lowestSubtotal)) {
lowestSubtotal = testSubtotal;
bestOfferList = offerList;
}
// clear price details
for (PromotableOrderItem item : order.getDiscountableOrderItems()) {
item.resetPriceDetails();
}
}
} else {
bestOfferList = permutations.get(0);
}
for (PromotableCandidateItemOffer offer : bestOfferList) {
offer.resetUses();
}
return bestOfferList;
}
use of org.broadleafcommerce.core.offer.service.discount.domain.PromotableOrderItem in project BroadleafCommerce by BroadleafCommerce.
the class ItemOfferProcessorImpl method markRelatedQualifiersAndTargets.
/**
* When the {@link Offer#getRequiresRelatedTargetAndQualifiers()} flag is set to true, we must make sure that we
* identify qualifiers and targets together, as they must be related to each other based on the
* {@link OrderItem#getParentOrderItem()} / {@link OrderItem#getChildOrderItems()} attributes.
*
* @param itemOffer
* @param order
* @return whether or not a suitable qualifier/target pair was found and marked
*/
protected boolean markRelatedQualifiersAndTargets(PromotableCandidateItemOffer itemOffer, PromotableOrder order) {
OrderItemHolder orderItemHolder = new OrderItemHolder(null);
for (Entry<OfferItemCriteria, List<PromotableOrderItem>> entry : itemOffer.getCandidateQualifiersMap().entrySet()) {
OfferItemCriteria itemCriteria = entry.getKey();
List<PromotableOrderItem> promotableItems = entry.getValue();
List<PromotableOrderItemPriceDetail> priceDetails = buildPriceDetailListFromOrderItems(promotableItems);
int qualifierQtyNeeded = offerServiceUtilities.markRelatedQualifiersAndTargetsForItemCriteria(itemOffer, order, orderItemHolder, itemCriteria, priceDetails, this);
if (qualifierQtyNeeded != 0) {
return false;
}
}
return markTargets(itemOffer, order, orderItemHolder.getOrderItem(), false);
}
Aggregations