Class BaseCandidateOffer

java.lang.Object
com.broadleafcommerce.promotion.offer.service.dto.BaseCandidateOffer
All Implemented Interfaces:
Serializable
Direct Known Subclasses:
CandidateFulfillmentGroupOffer, CandidateItemOffer, CandidateOrderOffer

public class BaseCandidateOffer extends Object implements Serializable
Author:
Chad Harchar (charchar)
See Also:
  • Constructor Details

    • BaseCandidateOffer

      public BaseCandidateOffer()
  • Method Details

    • populateCombinabilityStructures

      public void populateCombinabilityStructures(CandidateOffers candidateOffers)
    • populateCombinabilityStructuresUsedBySameTargetType

      protected void populateCombinabilityStructuresUsedBySameTargetType(CandidateOffers candidateOffers)
    • updateOfferCombinabilityCriteria

      public void updateOfferCombinabilityCriteria(CandidateOffers candidateOffers)
    • getDiscountTargetType

      public String getDiscountTargetType()
      Convenience method to access this property to improve code readability
    • getDiscountMethodType

      public String getDiscountMethodType()
      Convenience method to access this property to improve code readability
    • getDiscountAmount

      public BigDecimal getDiscountAmount()
      Convenience method to access this property to improve code readability
    • getOfferId

      public String getOfferId()
      When processing the same offer more than once due to the offer applying to more than one segment, we need to override its id as part of the offer copy.
    • isApplicableToDependentItems

      public boolean isApplicableToDependentItems()
    • validateCodesMatchOfferSegments

      public boolean validateCodesMatchOfferSegments()
      Using the structure stored by populatePropertiesFromCodeData(OfferCodeData) this method verifies that segments (if used) are valid for the backing Offer
    • segmentIsValid

      protected boolean segmentIsValid(String offerSegment, OfferCode offerCd, com.broadleafcommerce.promotion.offer.client.web.context.OfferCodeDto ocDto)
    • normalizeSegment

      protected String normalizeSegment(String segment)
    • calculateOverrideSegment

      protected Optional<String> calculateOverrideSegment(String offerSegment, OfferCode offerCd, com.broadleafcommerce.promotion.offer.client.web.context.OfferCodeDto ocDto)
      Determines the segment to use for this offer based on the passed in codes.
      Parameters:
      offerSegment - The value of Offer.getSegment() after calling normalizeSegment(String)
      offerCd - The OfferCode which can narrow the segment
      ocDto - The OfferCodeDto which can further narrow the segment
      Returns:
    • getAllValidSegments

      public Set<String> getAllValidSegments()
    • initializeExcludedCartItemIds

      public void initializeExcludedCartItemIds()
      Using the structure stored by populatePropertiesFromCodeData(OfferCodeData) this method updates the excludedIds for this offer if present on the OfferCodeDto.
    • populatePropertiesFromCodeData

      public void populatePropertiesFromCodeData(OfferCodeData codeData)
    • getSegment

      public String getSegment()
    • isNotExcludedFromOffer

      public boolean isNotExcludedFromOffer(EnhancedOrder order, EnhancedLineItem item)
      Returns true if the passed in item is NOT excluded from this offer.
      Parameters:
      order -
      item -
      Returns:
      true if the passed in item is not excluded from this offer.
    • excludeDiscountedItemsFromTotal

      public boolean excludeDiscountedItemsFromTotal()
    • updateMonetaryAmountCurrencyIfNeeded

      public void updateMonetaryAmountCurrencyIfNeeded()
      Updates the CurrencySupplier.getCurrency() of all the MonetaryAmount fields for the getOffer(), if the Offer.getCurrency() is null.

      This is only needed when Offer.getCurrency() is null, because that means the offer doesn't care about the currency and should use the EnhancedOrder.getCurrency() instead. However, the CurrencySupplier.getCurrency() of those fields were resolved in JpaOffer.preFromMe(ContextInfo, Object) based on the ContextInfo, which does not have context of the EnhancedOrder.getCurrency(), it would cause currency mismatch MonetaryException if the currency is not updated accordingly.

    • updateAmountCurrency

      protected void updateAmountCurrency(@NonNull @NonNull Offer offer, @NonNull @NonNull javax.money.CurrencyUnit currencyToSet, @NonNull @NonNull Function<Offer,javax.money.MonetaryAmount> amountGetter, @NonNull @NonNull BiConsumer<Offer,javax.money.MonetaryAmount> amountSetter)
      Updates the Currency of the MonetaryAmount fields in the given Offer.
      Parameters:
      offer - the Offer to update its MonetaryAmount field for
      currencyToSet - the CurrencyUnit to update the CurrencySupplier.getCurrency() to
      amountGetter - the getter to get the MonetaryAmount from the Offer
      amountSetter - the setter to set the MonetaryAmount with the updated currency to the Offer
    • getOffer

      public Offer getOffer()
      The candidate Offer.
      Returns:
      The candidate Offer.
    • getPotentialSavings

      public javax.money.MonetaryAmount getPotentialSavings()
      The total potential amount saved by applying this offer to its targets.
      Returns:
      The total potential amount saved by applying this offer to its targets.
    • getCurrency

      public javax.money.CurrencyUnit getCurrency()
      Offer.getCurrency() if specified, otherwise EnhancedOrder.getCurrency() is used.
      Returns:
      The Offer.getCurrency() or EnhancedOrder.getCurrency() order's currency}.
      See Also:
    • isRoundOfferValues

      public boolean isRoundOfferValues()

      Determines whether to round potentialSavings. Default is false. Note: This is only relevant for adjustments that apply to items. The additional precision is important when multiplying by a "qty". Order and fulfillment group adjustments will always be rounded in the default implementations.

      It is sometimes problematic to use DiscountMethodType.PERCENT_OFF offers with regards to rounding. For example, consider an item that costs $9.99 and has a 50% discount. To be precise, the offer value is 4.995, but this may be a strange value to display to the user depending on the currency being used. Keeping this false produces more accurate results when using quantities > 1. For example, 20% off of $9.99 with a quantity of 5 will produce a savings of exactly $9.99 which would be expected. The savings will always be rounded to the correct precision of the currency, however the S "totalSavings" will always be displays may want to round the value unit adjustment will be up to 5 digits of precision if roundOfferValues is false. Client displays may with to round the adjustment amount if showing per quantity level adjustments.

      Returns:
      whether to round potentialSavings.
    • getRoundingMode

      public RoundingMode getRoundingMode()
      The RoundingMode to use when rounding. Default is RoundingMode.HALF_EVEN.
      Returns:
      The RoundingMode to use when rounding.
    • getOfferCombinabilityCriteriaKey

      public OfferCombinabilityCriteriaKey getOfferCombinabilityCriteriaKey()
      Holds the combinability criteria for this offer. The offer domain contains combinability flags and rules but the criteria will vary with each execution of the offer engine. For example, if "item offer a" can be combined with any "order offer except b" and b is not in the scope of the current offer engine execution, then we can say that "item offer a" can be combined with ANY order offer. Practically, this allows us to reduce the overall complexity of offer engine by getting rid of scenarios that are irrelevant to the current execution.
    • getCombinableOverrides

      public Set<String> getCombinableOverrides()
      Convert offer data into easier structures for combinability algorithms
    • getNonCombinableOverrides

      public Set<String> getNonCombinableOverrides()
    • getStackableOverrides

      public Set<String> getStackableOverrides()
    • getOverrideOfferId

      public String getOverrideOfferId()
      When processing the same offer for more than one segment, we need to override the id used for the underlying offer id temporarily.
    • getExcludedItemIds

      public Set<String> getExcludedItemIds()
      Store the list of excludedItemIds included which can be passed in via the OfferCodeDto
      See Also:
    • getOfferCodesMap

      public Map<String,OfferCode> getOfferCodesMap()
    • getOfferDtosMap

      public Map<String,com.broadleafcommerce.promotion.offer.client.web.context.OfferCodeDto> getOfferDtosMap()
    • setOffer

      public void setOffer(Offer offer)
      The candidate Offer.
      Parameters:
      offer - The candidate Offer.
    • setPotentialSavings

      public void setPotentialSavings(javax.money.MonetaryAmount potentialSavings)
      The total potential amount saved by applying this offer to its targets.
      Parameters:
      potentialSavings - The total potential amount saved by applying this offer to its targets.
    • setCurrency

      public void setCurrency(javax.money.CurrencyUnit currency)
      Offer.getCurrency() if specified, otherwise EnhancedOrder.getCurrency() is used.
      Parameters:
      currency - The Offer.getCurrency() or EnhancedOrder.getCurrency() order's currency}.
      See Also:
    • setRoundOfferValues

      public void setRoundOfferValues(boolean roundOfferValues)

      Determines whether to round potentialSavings. Default is false. Note: This is only relevant for adjustments that apply to items. The additional precision is important when multiplying by a "qty". Order and fulfillment group adjustments will always be rounded in the default implementations.

      It is sometimes problematic to use DiscountMethodType.PERCENT_OFF offers with regards to rounding. For example, consider an item that costs $9.99 and has a 50% discount. To be precise, the offer value is 4.995, but this may be a strange value to display to the user depending on the currency being used. Keeping this false produces more accurate results when using quantities > 1. For example, 20% off of $9.99 with a quantity of 5 will produce a savings of exactly $9.99 which would be expected. The savings will always be rounded to the correct precision of the currency, however the S "totalSavings" will always be displays may want to round the value unit adjustment will be up to 5 digits of precision if roundOfferValues is false. Client displays may with to round the adjustment amount if showing per quantity level adjustments.

      Parameters:
      roundOfferValues - whether to round potentialSavings.
    • setRoundingMode

      public void setRoundingMode(RoundingMode roundingMode)
      The RoundingMode to use when rounding. Default is RoundingMode.HALF_EVEN.
      Parameters:
      roundingMode - The RoundingMode to use when rounding.
    • setOfferCombinabilityCriteriaKey

      public void setOfferCombinabilityCriteriaKey(OfferCombinabilityCriteriaKey offerCombinabilityCriteriaKey)
      Holds the combinability criteria for this offer. The offer domain contains combinability flags and rules but the criteria will vary with each execution of the offer engine. For example, if "item offer a" can be combined with any "order offer except b" and b is not in the scope of the current offer engine execution, then we can say that "item offer a" can be combined with ANY order offer. Practically, this allows us to reduce the overall complexity of offer engine by getting rid of scenarios that are irrelevant to the current execution.
    • setCombinableOverrides

      public void setCombinableOverrides(Set<String> combinableOverrides)
      Convert offer data into easier structures for combinability algorithms
    • setNonCombinableOverrides

      public void setNonCombinableOverrides(Set<String> nonCombinableOverrides)
    • setStackableOverrides

      public void setStackableOverrides(Set<String> stackableOverrides)
    • setSegment

      public void setSegment(String segment)
      Store the effective segment for this Offer. The segment can be narrowed by the use of an OfferCode or OfferCodeDto.
    • setOverrideOfferId

      public void setOverrideOfferId(String overrideOfferId)
      When processing the same offer for more than one segment, we need to override the id used for the underlying offer id temporarily.
    • setExcludedItemIds

      public void setExcludedItemIds(Set<String> excludedItemIds)
      Store the list of excludedItemIds included which can be passed in via the OfferCodeDto
      See Also:
    • setOfferCodesMap

      public void setOfferCodesMap(Map<String,OfferCode> offerCodesMap)
    • setOfferDtosMap

      public void setOfferDtosMap(Map<String,com.broadleafcommerce.promotion.offer.client.web.context.OfferCodeDto> offerDtosMap)
    • equals

      public boolean equals(Object o)
      Overrides:
      equals in class Object
    • canEqual

      protected boolean canEqual(Object other)
    • hashCode

      public int hashCode()
      Overrides:
      hashCode in class Object
    • toString

      public String toString()
      Overrides:
      toString in class Object