Class DefaultItemOfferProcessor
java.lang.Object
com.broadleafcommerce.promotion.offer.service.engine.application.processor.DefaultItemOfferProcessor
- All Implemented Interfaces:
ItemOfferProcessor
- Author:
- Chad Harchar (charchar)
-
Field Summary
FieldsModifier and TypeFieldDescriptionprotected final OrderAndItemOfferHelperprotected final PotentialSavingsCalculatorprotected final QualifierAndTargetMarker -
Constructor Summary
ConstructorsConstructorDescriptionDefaultItemOfferProcessor(PotentialSavingsCalculator potentialSavingsCalculator, QualifierAndTargetMarker qualifierAndTargetMarker, OrderAndItemOfferHelper helper, boolean isForFulfillment) -
Method Summary
Modifier and TypeMethodDescriptionprotected voidaddCodeResponseToPermutationResult(EnhancedOrder order, Offer offer, ItemOfferPermutationResult result, com.broadleafcommerce.promotion.offer.client.web.context.discounts.CodeResponse codeResponse) Adds theCodeResponseto theItemOfferPermutationResultfor the provided offer.protected voidaddFreeGiftsToResult(OfferProcessingContext context, ItemOfferPermutationResult result) protected voidaddOrderCodeToAdjustmentIfUsed(@NonNull Offer offer, @NonNull com.broadleafcommerce.promotion.offer.client.web.context.info.Adjustment adjustment, @NonNull Set<String> allOrderCodes) Adds an offer code to the givenAdjustmentif it is present on the order.protected voidapplyAdjustments(EnhancedOrder order, CandidateItemOffer itemOffer) protected voidapplyCandidateOffers(EnhancedOrder order, List<CandidateItemOffer> candidateOffers) Deprecated.protected voidapplyCandidateOffers(EnhancedOrder order, List<CandidateItemOffer> candidateOffers, ItemOfferPermutationResult result) protected voidapplyFreeGift(EnhancedOrder order, CandidateItemOffer itemOffer) Builds and adds aFreeGiftItemtoEnhancedOrder.getFreeGiftItems()based onCandidateItemOffer.getCandidateQualifiersMap()if the givenitemOfferis a free gift offer.voidapplyItemAdjustments(OfferProcessingContext context, ItemOfferPermutationResult result) For item processing, the adjustments are stored onLineItemOfferDetailrecords.protected voidapplyItemOffer(EnhancedOrder order, CandidateItemOffer itemOffer) protected voidapplyItemQualifiersAndTargets(EnhancedOrder order, CandidateItemOffer itemOffer) protected voidapplyLineItemAdjustment(@NonNull CandidateItemOffer itemOffer, @NonNull LineItemOfferDetail offerDetail, @NonNull OfferDiscount offerDiscount) Adds anItemOfferAdjustmentto the givenLineItemOfferDetail.protected voidassertCandidateOffersNotNull(CandidateOffers candidateOffers) protected voidassertCommonParamsNotNull(EnhancedOrder order, CandidateOffers candidateOffers) protected com.broadleafcommerce.promotion.offer.client.web.context.info.AdjustmentbuildAdjustmentForFreeGift(EnhancedOrder order, CandidateItemOffer itemOffer) Builds anAdjustmentfor aFreeGiftItem.protected com.broadleafcommerce.promotion.offer.client.web.context.info.FreeGiftItembuildFreeGiftItem(Offer offer, int quantityToAdd, com.broadleafcommerce.promotion.offer.client.web.context.info.Adjustment adjustment) Builds aFreeGiftItemfrom the givenOffer, quantity, and qualifier item ids.protected javax.money.MonetaryAmountcalculatePartialSavingsAmountForDiscount(CandidateItemOffer itemOffer, OfferDiscount discount) protected voidcalculatePotentialSavings(EnhancedOrder order, List<CandidateItemOffer> candidateItemOffers) protected javax.money.MonetaryAmountprotected booleancanOfferBeApplied(EnhancedOrder order, CandidateItemOffer itemOffer, List<LineItemOfferDetail> itemDetails) Deprecated.protected booleancanOfferBeApplied(EnhancedOrder order, CandidateItemOffer itemOffer, List<LineItemOfferDetail> itemDetails, ItemOfferPermutationResult result) Determines whether theOffercan be applied by making sure it is the order meets the total requirements.protected voidSomeOfferscan only apply to theEnhancedLineItem.getStandardPrice().protected voidclearStateBetweenPermutations(EnhancedOrder order, List<CandidateItemOffer> candidateOffers) protected booleancompatibleWithSegment(String offerSegment, String itemSegment) protected ItemOfferPermutationResultcomputeOfferPermutationValue(OfferProcessingContext context, List<CandidateItemOffer> candidateItemOffers, OrderTotals orderTotals) protected javax.money.MonetaryAmountcomputeSaleAdjustmentValue(CandidateItemOffer itemOffer, LineItemOfferDetail offerDetail) protected javax.money.MonetaryAmountcomputeStandardAdjustmentValue(CandidateItemOffer itemOffer, LineItemOfferDetail offerDetail) protected com.broadleafcommerce.promotion.offer.client.web.context.info.OfferItemDetailcreateOfferItemDetail(CandidateItemOffer itemOffer, String itemId, int quantityPerUsage) Creates anOfferItemDetailbased on the given fields.protected com.broadleafcommerce.promotion.offer.client.web.context.info.OfferItemDetailcreateOfferItemDetailAndDetermineQualifierQuantity(@NonNull CandidateItemOffer itemOffer, @NonNull EnhancedLineItem lineItem, OfferDiscount offerDiscount, int quantityPerUsage) Creates anOfferItemDetailbased on the given fields.protected ItemOfferPermutationResultdetermineBestPermutationGivenEqualAdjustmentValues(AtomicReference<ItemOfferPermutationResult> bestPermutation, ItemOfferPermutationResult result) Hook point where both permutations offering the same discount, which permutation should be chosen.protected List<List<CandidateItemOffer>>expandPermutations(List<CandidateItemOffer> itemOffers) This method takes a list of item offers that are compatible with each other and share the same combinability characteristics with other types like order offers and builds additional permutations that influence the order that the offers will be run.voidfindBestItemOffersForPermutation(OfferProcessingContext context, CombinedTypesOfferPermutation ctop) protected Optional<List<CandidateItemOffer>>findBestPermutation(EnhancedOrder order, List<List<CandidateItemOffer>> permutations) Determines the best permutation by comparing the resulting total discounts of each permutations.protected List<CandidateItemOffer>protected javax.money.MonetaryAmountgetEstimatedFreeGiftValue(EnhancedOrder order, Offer offer) protected intgetFreeGiftQuantityToAdd(CandidateItemOffer itemOffer) Gets the quantity of the free gift items to be added from the givenCandidateItemOffer.protected List<CandidateItemOffer>getPermutationByComparator(List<CandidateItemOffer> rootPremutation, Comparator<CandidateItemOffer> comparator) Uses aComparatorto sortcandidate offers.protected List<com.broadleafcommerce.promotion.offer.client.web.context.info.OfferItemDetail>getQualifierDetails(@NonNull CandidateItemOffer itemOffer, OfferDiscount offerDiscount) Gets a list ofOfferItemDetailsrepresenting qualifiers.protected booleanisAdjustmentGoodEnough(CandidateItemOffer itemOffer, LineItemOfferDetail detail) Checking to make sure that an offer's adjustment to an item's price is actually better than the original price, especially if the item is on sale since not all offers can apply to a sale price.protected booleanitemHasQualifierOfferDetails(@NonNull EnhancedLineItem item, @NonNull CandidateItemOffer itemOffer, OfferDiscount offerDiscount) Determines whether the givenEnhancedLineItemhas anyOfferItemDetailsthat has anyOfferQualifiersmatching the givenCandidateItemOffer.protected voidlogIfDebugOn(String message, Object... formatArgs) Checks ifdebug is enabled, then wraps the message inString.format(String, Object...)with the givenformatArgsand logs it.protected voidlogIfTraceOn(String message, Object... formatArgs) Checks ifLog.isTraceEnabled()trace is enabled}, then wraps the message inString.format(String, Object...)with the givenformatArgsand logs it.protected voidmergePriceDetails(EnhancedOrder order) Checks to see if anyLineItemOfferDetailsneed to be combined and if so, combines them.voidprepareForItemOfferProcessing(EnhancedOrder order, List<CandidateItemOffer> candidateItemOffers) Item offer processing can benefit from setup activities that are used by all of the permutations.protected voidremoveDuplicatePermutations(List<List<CandidateItemOffer>> permutations) A duplicate permutation means that the permutations have the same offers in the same order.protected voidsetCandidateItemOffers(CandidateOffers candidateOffers, List<CandidateItemOffer> candidateItemOffers) protected voidsort(List<CandidateItemOffer> candidateItemOffers) The default based on theCandidateItemOfferComparatorprotected voidsplitDetailsIfNecessary(List<LineItemOfferDetail> offerDetails, CandidateItemOffer itemOffer) Checks if the discount quantity matches the detail quantity.protected voidupdateBestPermutation(CombinedTypesOfferPermutation ctop, ItemOfferPermutationResult bestPermutation)
-
Field Details
-
potentialSavingsCalculator
-
qualifierAndTargetMarker
-
helper
-
-
Constructor Details
-
DefaultItemOfferProcessor
public DefaultItemOfferProcessor(PotentialSavingsCalculator potentialSavingsCalculator, QualifierAndTargetMarker qualifierAndTargetMarker, OrderAndItemOfferHelper helper, boolean isForFulfillment)
-
-
Method Details
-
findBestItemOffersForPermutation
public void findBestItemOffersForPermutation(OfferProcessingContext context, CombinedTypesOfferPermutation ctop) - Specified by:
findBestItemOffersForPermutationin interfaceItemOfferProcessor
-
determineBestPermutationGivenEqualAdjustmentValues
protected ItemOfferPermutationResult determineBestPermutationGivenEqualAdjustmentValues(AtomicReference<ItemOfferPermutationResult> bestPermutation, ItemOfferPermutationResult result) Hook point where both permutations offering the same discount, which permutation should be chosen. By default, this returns the existing best permutation.- Parameters:
bestPermutation- Current best permutation result during evaluationresult- The permutation result to check against the best permutation- Returns:
- The determined best permutation
-
updateBestPermutation
protected void updateBestPermutation(CombinedTypesOfferPermutation ctop, ItemOfferPermutationResult bestPermutation) -
applyItemAdjustments
Description copied from interface:ItemOfferProcessorFor item processing, the adjustments are stored onLineItemOfferDetailrecords. These detail records are stored in theItemOfferPermutationResult.getLineItemDetailMap()- Specified by:
applyItemAdjustmentsin interfaceItemOfferProcessor
-
prepareForItemOfferProcessing
public void prepareForItemOfferProcessing(EnhancedOrder order, List<CandidateItemOffer> candidateItemOffers) Description copied from interface:ItemOfferProcessorItem offer processing can benefit from setup activities that are used by all of the permutations. Most notably, finding the maximum savings for a given offer which can be used to prioritize the order in which offers are attempted within a cart.- Specified by:
prepareForItemOfferProcessingin interfaceItemOfferProcessor
-
clearStateBetweenPermutations
protected void clearStateBetweenPermutations(EnhancedOrder order, List<CandidateItemOffer> candidateOffers) -
computeOfferPermutationValue
protected ItemOfferPermutationResult computeOfferPermutationValue(OfferProcessingContext context, List<CandidateItemOffer> candidateItemOffers, OrderTotals orderTotals) -
calculatePotentialSavings
protected void calculatePotentialSavings(EnhancedOrder order, List<CandidateItemOffer> candidateItemOffers) -
sort
The default based on theCandidateItemOfferComparator- Parameters:
candidateItemOffers-
-
applyCandidateOffers
protected void applyCandidateOffers(@NonNull EnhancedOrder order, @NonNull List<CandidateItemOffer> candidateOffers, ItemOfferPermutationResult result) -
applyCandidateOffers
protected void applyCandidateOffers(@NonNull EnhancedOrder order, @NonNull List<CandidateItemOffer> candidateOffers) Deprecated. -
expandPermutations
This method takes a list of item offers that are compatible with each other and share the same combinability characteristics with other types like order offers and builds additional permutations that influence the order that the offers will be run.
Even though two offers are compatible to be in the same offer, the results of the offer engine can be different depending on the order they are applied due to complexities involving qualifiers and bundle offers.
For most scenarios, these complexities can be managed with using explicit priorities, exclusions and stacking rules.
<By default, this method expands the included permutation into at most three additional permutations as follows:
- A permutation based on default sorting rules and potential savings
- A permutation based on considering savings on weighted potential savings
- A permutation based on savings tied to qty 1
-
getPermutationByComparator
protected List<CandidateItemOffer> getPermutationByComparator(List<CandidateItemOffer> rootPremutation, Comparator<CandidateItemOffer> comparator) Uses aComparatorto sortcandidate offers. The default comparators to use areItemOfferQtyOneComparatorandItemOfferWeightedPercentSavedComparator. Each ordering is considered its own permutation since the order in which offers are applied affects the end price. -
removeDuplicatePermutations
A duplicate permutation means that the permutations have the same offers in the same order.- Parameters:
permutations- contains lists of compatibleCandidateItemOffers
-
findBestPermutation
protected Optional<List<CandidateItemOffer>> findBestPermutation(EnhancedOrder order, List<List<CandidateItemOffer>> permutations) Determines the best permutation by comparing the resulting total discounts of each permutations. -
applyItemOffer
-
canOfferBeApplied
protected boolean canOfferBeApplied(EnhancedOrder order, CandidateItemOffer itemOffer, List<LineItemOfferDetail> itemDetails, ItemOfferPermutationResult result) Determines whether theOffercan be applied by making sure it is the order meets the total requirements.- Returns:
- whether the offer can be applied.
-
canOfferBeApplied
protected boolean canOfferBeApplied(EnhancedOrder order, CandidateItemOffer itemOffer, List<LineItemOfferDetail> itemDetails) Deprecated. -
applyItemQualifiersAndTargets
-
splitDetailsIfNecessary
protected void splitDetailsIfNecessary(List<LineItemOfferDetail> offerDetails, CandidateItemOffer itemOffer) Checks if the discount quantity matches the detail quantity. If not, splits the price detail. -
calculatePartialSavingsAmountForDiscount
protected javax.money.MonetaryAmount calculatePartialSavingsAmountForDiscount(CandidateItemOffer itemOffer, OfferDiscount discount) -
applyAdjustments
-
compatibleWithSegment
-
calculatePriceForBundleRatio
-
applyFreeGift
Builds and adds aFreeGiftItemtoEnhancedOrder.getFreeGiftItems()based onCandidateItemOffer.getCandidateQualifiersMap()if the givenitemOfferis a free gift offer.- Parameters:
order- order to apply the free gift offers toitemOffer- offer to build theFreeGiftItemand get the qualifiers from
-
getFreeGiftQuantityToAdd
Gets the quantity of the free gift items to be added from the givenCandidateItemOffer.- Parameters:
itemOffer- thefree gift offerto calculate the quantity of free gift items for- Returns:
- the quantity of the free gift items to be added
-
buildFreeGiftItem
protected com.broadleafcommerce.promotion.offer.client.web.context.info.FreeGiftItem buildFreeGiftItem(Offer offer, int quantityToAdd, com.broadleafcommerce.promotion.offer.client.web.context.info.Adjustment adjustment) Builds aFreeGiftItemfrom the givenOffer, quantity, and qualifier item ids.- Parameters:
offer- the free gift offer to build theFreeGiftItemfromquantityToAdd- the quantity of theFreeGiftItemadjustment- theItemAdjustmentof theFreeGiftItem- Returns:
FreeGiftItemfrom the givenOffer, quantity, and adjustment
-
buildAdjustmentForFreeGift
protected com.broadleafcommerce.promotion.offer.client.web.context.info.Adjustment buildAdjustmentForFreeGift(EnhancedOrder order, CandidateItemOffer itemOffer) Builds anAdjustmentfor aFreeGiftItem.- Parameters:
order- theEnhancedOrdertheFreeGiftItemwill be added toitemOffer- theCandidateItemOfferfor the free gift- Returns:
- an
Adjustmentfor then free gift offer
-
addOrderCodeToAdjustmentIfUsed
protected void addOrderCodeToAdjustmentIfUsed(@NonNull @NonNull Offer offer, @NonNull @NonNull com.broadleafcommerce.promotion.offer.client.web.context.info.Adjustment adjustment, @NonNull @NonNull Set<String> allOrderCodes) Adds an offer code to the givenAdjustmentif it is present on the order.- Parameters:
offer-Offerfrom which theadjustmentis derived.adjustment- Adjustment TheAdjustmentfor which an offer code may applyallOrderCodes- Set of all of the shared or campaign codes set on the order. These may have been used to apply an offer and should be recorded on anyAdjustments.
-
isAdjustmentGoodEnough
Checking to make sure that an offer's adjustment to an item's price is actually better than the original price, especially if the item is on sale since not all offers can apply to a sale price. -
applyLineItemAdjustment
protected void applyLineItemAdjustment(@NonNull @NonNull CandidateItemOffer itemOffer, @NonNull @NonNull LineItemOfferDetail offerDetail, @NonNull @NonNull OfferDiscount offerDiscount) Adds anItemOfferAdjustmentto the givenLineItemOfferDetail.- Parameters:
itemOffer- theCandidateItemOfferto build theItemOfferAdjustmentfromofferDetail- theLineItemOfferDetailto add theItemOfferAdjustmenttoofferDiscount- theOfferDiscountto get the target criteria rule from
-
getQualifierDetails
protected List<com.broadleafcommerce.promotion.offer.client.web.context.info.OfferItemDetail> getQualifierDetails(@NonNull @NonNull CandidateItemOffer itemOffer, @Nullable OfferDiscount offerDiscount) Gets a list ofOfferItemDetailsrepresenting qualifiers.- Parameters:
itemOffer- theCandidateItemOfferto get the qualifier items fromofferDiscount- optional offer discount in order to filter usage details- Returns:
- a list of
OfferItemDetailsrepresenting qualifiers
-
itemHasQualifierOfferDetails
protected boolean itemHasQualifierOfferDetails(@NonNull @NonNull EnhancedLineItem item, @NonNull @NonNull CandidateItemOffer itemOffer, @Nullable OfferDiscount offerDiscount) Determines whether the givenEnhancedLineItemhas anyOfferItemDetailsthat has anyOfferQualifiersmatching the givenCandidateItemOffer.- Parameters:
item- theEnhancedLineItemto check againstitemOffer- theCandidateItemOfferto matchofferDiscount- optional offer discount in order to filter usage details- Returns:
- true if the given
EnhancedLineItemhas anyOfferItemDetailsthat has anyOfferQualifiersmatching the givenCandidateItemOffer, otherwise false
-
createOfferItemDetailAndDetermineQualifierQuantity
protected com.broadleafcommerce.promotion.offer.client.web.context.info.OfferItemDetail createOfferItemDetailAndDetermineQualifierQuantity(@NonNull @NonNull CandidateItemOffer itemOffer, @NonNull @NonNull EnhancedLineItem lineItem, @Nullable OfferDiscount offerDiscount, int quantityPerUsage) Creates anOfferItemDetailbased on the given fields.- Parameters:
itemOffer- theCandidateItemOfferto build the details fromlineItem- the qualifier item candidateofferDiscount- optional offer discount in order to filter on usage detailsquantityPerUsage- the quantity per usage- Returns:
- an
OfferItemDetailbased on the given fields
-
createOfferItemDetail
protected com.broadleafcommerce.promotion.offer.client.web.context.info.OfferItemDetail createOfferItemDetail(CandidateItemOffer itemOffer, String itemId, int quantityPerUsage) Creates anOfferItemDetailbased on the given fields.- Parameters:
itemOffer- theCandidateItemOfferto build the details fromitemId- the item idquantityPerUsage- the quantity per usage- Returns:
- an
OfferItemDetailbased on the given fields
-
computeStandardAdjustmentValue
protected javax.money.MonetaryAmount computeStandardAdjustmentValue(CandidateItemOffer itemOffer, LineItemOfferDetail offerDetail) -
computeSaleAdjustmentValue
protected javax.money.MonetaryAmount computeSaleAdjustmentValue(CandidateItemOffer itemOffer, LineItemOfferDetail offerDetail) -
chooseSaleOrStandardAdjustments
SomeOfferscan only apply to theEnhancedLineItem.getStandardPrice(). This method determines whether standard-price-only promotions should be used instead of those that can apply to the sale price as well. -
addFreeGiftsToResult
protected void addFreeGiftsToResult(OfferProcessingContext context, ItemOfferPermutationResult result) -
getEstimatedFreeGiftValue
-
mergePriceDetails
Checks to see if anyLineItemOfferDetailsneed to be combined and if so, combines them. -
getCandidateItemOffers
-
setCandidateItemOffers
protected void setCandidateItemOffers(CandidateOffers candidateOffers, List<CandidateItemOffer> candidateItemOffers) -
assertCommonParamsNotNull
-
assertCandidateOffersNotNull
-
addCodeResponseToPermutationResult
protected void addCodeResponseToPermutationResult(EnhancedOrder order, Offer offer, ItemOfferPermutationResult result, com.broadleafcommerce.promotion.offer.client.web.context.discounts.CodeResponse codeResponse) Adds theCodeResponseto theItemOfferPermutationResultfor the provided offer.- Parameters:
order- provides context information around offers and offer codesoffer- the offer to add the code responses forresult- the permutation result to add the code response tocodeResponse- the code response to be added
-
logIfDebugOn
Checks ifdebug is enabled, then wraps the message inString.format(String, Object...)with the givenformatArgsand logs it. -
logIfTraceOn
Checks ifLog.isTraceEnabled()trace is enabled}, then wraps the message inString.format(String, Object...)with the givenformatArgsand logs it.
-
applyCandidateOffers(EnhancedOrder, List, ItemOfferPermutationResult)