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()
      Return the dynamic amount for a dynamic offer; otherwise, return the discount amount of the offer.
    • getDiscountAmountTypeHolder

      public DiscountAmountTypeHolder getDiscountAmountTypeHolder()
      Return the dynamic amount for a dynamic offer; otherwise, return the discount amount of the offer.
    • 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 MonetaryAmount fields for the getOffer() if the Offer.getCurrency() is null or convertedCurrencyDetail is present

      In the former case, this is needed 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.

      In the latter case, this means that the offer did not match the order's currency but one of the items had a ConvertedCurrencyDetail whose source currency matched the offer's allowing conversion. This method will multiply the MonetaryAmount fields by the rate in the convertedCurrencyDetail and also convert the BigDecimal fields as applicable, e.g., convert the Discount.getAmount() if the discount is amount off or fixed price. This should only happen if the offer target's order items.

    • 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. If a convertedCurrencyDetail is present, also adjusts the amounts accordingly.
      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
    • updateBigDecimalForCurrencyChange

      protected Optional<BigDecimal> updateBigDecimalForCurrencyChange(@Nullable BigDecimal oldAmount)
      Updates the given BigDecimal amount for currency change if the convertedCurrencyDetail is present. This will multiply the amount by the rate in the convertedCurrencyDetail.
      Parameters:
      oldAmount - The BigDecimal amount to update
      Returns:
      The updated BigDecimal amount if the convertedCurrencyDetail is present, otherwise Optional.empty()
      Since:
      Offer Services 3.2.0, Release Train 2.3.0
    • 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:
    • getConvertedCurrencyDetail

      public com.broadleafcommerce.promotion.offer.client.web.context.discounts.ConvertedCurrencyDetail getConvertedCurrencyDetail()
      Represents the details of the exchange rate used to convert a MonetaryAmount from one currency to another. This is used to describe the price fields of the underlying offer if they were converted from a base currency, i.e., Offer.getCurrency(), into the order's currency. This is only possible if one of the item's was also converted and will simply be a copy of EnhancedOrderLineItem.getConvertedCurrencyDetail().
      Since:
      Offer Services 3.2.0, Release Train 2.3.0
    • 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()
    • getDynamicOfferAmount

      public javax.money.MonetaryAmount getDynamicOfferAmount()
    • getExistingOfferRef

      @Nullable public com.broadleafcommerce.promotion.offer.client.web.context.info.ExistingOfferRef getExistingOfferRef()
      When this is set, it means that the offer is already applied to the order prior to the offer engine logic. This contains details about how the existing offer has been applied.

      This is only relevant for post-purchase subscription flows, such as DefaultOrderFlow.SUBSCRIPTION_EDIT or DefaultOrderFlow.SUBSCRIPTION_UPGRADE, and is used to determine how many more periods the offer should be applied to the subscription and to compare against other new offer candidates to determine the best offer.

      Since:
      Offer Services 3.2.0, Release Train 2.3.0
      See Also:
    • getDiscountParameters

      @Nullable public DiscountParameters getDiscountParameters()
      Represents the actual discount parameters used to calculate the discount for this offer. This takes into account the method type and amount based on the DiscountTier if used rather than just relying on the Offer.getDiscount().
      Since:
      Offer Services 3.2.0, Release Train 2.3.0
    • 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:
    • setConvertedCurrencyDetail

      public void setConvertedCurrencyDetail(com.broadleafcommerce.promotion.offer.client.web.context.discounts.ConvertedCurrencyDetail convertedCurrencyDetail)
      Represents the details of the exchange rate used to convert a MonetaryAmount from one currency to another. This is used to describe the price fields of the underlying offer if they were converted from a base currency, i.e., Offer.getCurrency(), into the order's currency. This is only possible if one of the item's was also converted and will simply be a copy of EnhancedOrderLineItem.getConvertedCurrencyDetail().
      Since:
      Offer Services 3.2.0, Release Train 2.3.0
    • 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)
    • setDynamicOfferAmount

      public void setDynamicOfferAmount(javax.money.MonetaryAmount dynamicOfferAmount)
    • setExistingOfferRef

      public void setExistingOfferRef(@Nullable com.broadleafcommerce.promotion.offer.client.web.context.info.ExistingOfferRef existingOfferRef)
      When this is set, it means that the offer is already applied to the order prior to the offer engine logic. This contains details about how the existing offer has been applied.

      This is only relevant for post-purchase subscription flows, such as DefaultOrderFlow.SUBSCRIPTION_EDIT or DefaultOrderFlow.SUBSCRIPTION_UPGRADE, and is used to determine how many more periods the offer should be applied to the subscription and to compare against other new offer candidates to determine the best offer.

      Since:
      Offer Services 3.2.0, Release Train 2.3.0
      See Also:
    • setDiscountParameters

      public void setDiscountParameters(@Nullable DiscountParameters discountParameters)
      Represents the actual discount parameters used to calculate the discount for this offer. This takes into account the method type and amount based on the DiscountTier if used rather than just relying on the Offer.getDiscount().
      Since:
      Offer Services 3.2.0, Release Train 2.3.0
    • 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