java.lang.Object
com.broadleafcommerce.catalogbrowse.service.provider.external.AbstractExternalProvider
com.broadleafcommerce.catalogbrowse.service.provider.external.pricing.ExternalPricingProvider
All Implemented Interfaces:
PricingProvider

public class ExternalPricingProvider extends AbstractExternalProvider implements PricingProvider
Connects to an external pricing service.
Author:
Nathan Moore (nathandmoore)
  • Constructor Details

    • ExternalPricingProvider

      public ExternalPricingProvider(@Qualifier("catalogBrowseWebClient") org.springframework.web.reactive.function.client.WebClient catalogBrowseWebClient, com.fasterxml.jackson.databind.ObjectMapper mapper, com.broadleafcommerce.common.extension.TypeFactory typeFactory, List<ProductPriceableTargetsBuilder> productPriceableTargetsBuilders, com.broadleafcommerce.resource.security.utils.service.AuthenticationUtils authenticationUtils)
  • Method Details

    • priceProduct

      public Product priceProduct(@NonNull @NonNull Product product, @Nullable com.broadleafcommerce.pricing.client.domain.context.PriceContext priceContext, @Nullable com.broadleafcommerce.pricing.client.domain.context.PriceInfoContext priceInfoContext, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Populates pricing info for the provided Product and its related priceable entities: Variant, IncludedProduct, SpecificItemChoice.

      This implementation will mutate the given product if price infos are returned.
      Specified by:
      priceProduct in interface PricingProvider
      Parameters:
      product - The product to price
      priceContext - PriceContext from the original request containing general pricing info
      priceInfoContext - PriceInfoContext from the original request containing info specific for getting PriceInfos such as prefetched PriceLists.
      contextInfo - ContextInfo from the original request containing tenant info
      Returns:
      The product with pricing attached.
    • priceTargets

      public List<com.broadleafcommerce.pricing.client.domain.PriceInfo> priceTargets(@NonNull @NonNull Map<Object,Set<com.broadleafcommerce.pricing.client.domain.PriceableTarget>> targetsMap, @Nullable com.broadleafcommerce.pricing.client.domain.context.PriceContext priceContext, @Nullable com.broadleafcommerce.pricing.client.domain.context.PriceInfoContext priceInfoContext, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Description copied from interface: PricingProvider
      Populates pricing info for the provided targetsMap
      Specified by:
      priceTargets in interface PricingProvider
      Parameters:
      targetsMap - The targets to price
      priceContext - PriceContext from the original request containing general pricing info
      priceInfoContext - PriceInfoContext from the original request containing info specific for getting PriceInfos such as prefetched PriceLists.
      contextInfo - ContextInfo from the original request containing tenant info
      Returns:
      The price infos for the targets
    • priceProducts

      public <P extends Product> List<P> priceProducts(@NonNull @NonNull Collection<P> products, @Nullable com.broadleafcommerce.pricing.client.domain.context.PriceContext priceContext, @Nullable com.broadleafcommerce.pricing.client.domain.context.PriceInfoContext priceInfoContext, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Populates pricing info for the provided Products and their related priceable entities: Variant, IncludedProduct, SpecificItemChoice.

      This implementation will mutate the given products if price infos are returned.
      Specified by:
      priceProducts in interface PricingProvider
      Parameters:
      products - The products to price
      priceContext - PriceContext from the original request containing general pricing info
      priceInfoContext - PriceInfoContext from the original request containing info specific for getting PriceInfos such as prefetched PriceLists.
      contextInfo - ContextInfo from the original request containing tenant info
      Returns:
      The products with pricing attached.
    • makeRequest

      protected SimplePage<com.broadleafcommerce.pricing.client.domain.PriceInfo> makeRequest(@NonNull @NonNull Map<Object,Set<com.broadleafcommerce.pricing.client.domain.PriceableTarget>> targetsMap, @Nullable com.broadleafcommerce.pricing.client.domain.context.PriceContext priceContext, @Nullable com.broadleafcommerce.pricing.client.domain.context.PriceInfoContext priceInfoContext, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Handles making the actual request to the pricing service.
      Parameters:
      targetsMap - A map of entities to the PriceableTargets based upon them
      priceContext - PriceContext from the original request containing general pricing info
      priceInfoContext - PriceInfoContext from the original request containing info specific for getting PriceInfos such as prefetched PriceLists.
      contextInfo - ContextInfo from the original request containing tenant info
      Returns:
      The response from the pricing service
    • addUserTargets

      @Deprecated(forRemoval=true) protected void addUserTargets(@Nullable com.broadleafcommerce.pricing.client.domain.context.PriceContext priceContext)
      Deprecated, for removal: This API element is subject to removal in a future version.
    • addUserTargets

      protected void addUserTargets(@Nullable com.broadleafcommerce.pricing.client.domain.context.PriceContext priceContext, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Add customer and customer segment user targets to PriceContext.getUserTargets(). Uses the current authentication token to determine principal and details.
      Parameters:
      priceContext - The priceContext to add user targets to
      contextInfo - Additional tenant and sandbox info
    • getCustomerTargetRefs

      protected List<com.broadleafcommerce.pricing.client.domain.UserTargetRef> getCustomerTargetRefs()
    • getCustomerSegmentTargetRefs

      protected List<com.broadleafcommerce.pricing.client.domain.UserTargetRef> getCustomerSegmentTargetRefs(@Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
    • attachPricingToProduct

      @Deprecated(since="1.8.2") protected Product attachPricingToProduct(@NonNull @NonNull Product product, @NonNull @NonNull Map<Object,Set<com.broadleafcommerce.pricing.client.domain.PriceableTarget>> targetsMap, @NonNull @NonNull SimplePage<com.broadleafcommerce.pricing.client.domain.PriceInfo> priceInfos)
      Deprecated.
      Use attachPricingToProduct(Product, Map, SimplePage, PriceContext) Passing the PriceContext supports proper filtering of PriceInfo results that are in the proper currency.
    • attachPricingToProduct

      protected Product attachPricingToProduct(@NonNull @NonNull Product product, @NonNull @NonNull Map<Object,Set<com.broadleafcommerce.pricing.client.domain.PriceableTarget>> targetsMap, @NonNull @NonNull SimplePage<com.broadleafcommerce.pricing.client.domain.PriceInfo> priceInfos, @Nullable com.broadleafcommerce.pricing.client.domain.context.PriceContext priceContext)
      Handles attaching the PriceInfos returned by the pricing service onto the Product and its related entities. For convenience, all of them should already be present as the keys of targetsMap.

      By default, the product is merely passed through since all the price infos are attached to their respective owners via references in targetsMap. However, product is provided if implementors want to use a non-mutating method of attaching the price infos.
      Parameters:
      product - Product onto which to attach pricing info
      targetsMap - A map of entities to the PriceableTargets based upon them
      priceInfos - PriceInfos returned from the pricing service
      Returns:
      The product with price infos attached
    • attachPricingToProducts

      @Deprecated(since="1.8.2") protected <P extends Product> List<P> attachPricingToProducts(@NonNull @NonNull Collection<P> products, @NonNull @NonNull Map<Object,Set<com.broadleafcommerce.pricing.client.domain.PriceableTarget>> targetsMap, @NonNull @NonNull SimplePage<com.broadleafcommerce.pricing.client.domain.PriceInfo> priceInfos)
      Deprecated.
      Use attachPricingToProducts(Collection, Map, SimplePage, PriceContext) Passing the PriceContext supports proper filtering of PriceInfo results that are in the proper currency.
    • attachPricingToProducts

      protected <P extends Product> List<P> attachPricingToProducts(@NonNull @NonNull Collection<P> products, @NonNull @NonNull Map<Object,Set<com.broadleafcommerce.pricing.client.domain.PriceableTarget>> targetsMap, @NonNull @NonNull SimplePage<com.broadleafcommerce.pricing.client.domain.PriceInfo> priceInfos, @Nullable com.broadleafcommerce.pricing.client.domain.context.PriceContext priceContext)
      Handles attaching the PriceInfos returned by the pricing service onto the Products and their related entities. For convenience, all of them should already be present as the keys of targetsMap.

      By default, the products is merely passed through since all the price infos are attached to their respective owners via references in targetsMap. However, products is provided if implementors want to use a non-mutating method of attaching the price infos.
      Parameters:
      products - Products onto which to attach pricing info
      targetsMap - A map of entities to the PriceableTargets based upon them
      priceInfos - PriceInfos returned from the pricing service
      Returns:
      The product with price infos attached
    • doAttachPricing

      @Deprecated(since="1.8.2") protected final void doAttachPricing(@NonNull @NonNull Map<Object,Set<com.broadleafcommerce.pricing.client.domain.PriceableTarget>> targetsMap, @NonNull @NonNull SimplePage<com.broadleafcommerce.pricing.client.domain.PriceInfo> priceInfos)
      Deprecated.
      Use doAttachPricing(Map, SimplePage, PriceContext) Passing the PriceContext supports proper filtering of PriceInfo results that are in the proper currency.
    • doAttachPricing

      protected final void doAttachPricing(@NonNull @NonNull Map<Object,Set<com.broadleafcommerce.pricing.client.domain.PriceableTarget>> targetsMap, @NonNull @NonNull SimplePage<com.broadleafcommerce.pricing.client.domain.PriceInfo> priceInfos, @Nullable com.broadleafcommerce.pricing.client.domain.context.PriceContext priceContext)
    • getPriceInfoForPriceableEntity

      @Deprecated(since="1.8.2") protected <T extends com.broadleafcommerce.pricing.client.domain.PriceInfo> Optional<T> getPriceInfoForPriceableEntity(Priceable entity, List<T> candidatePriceInfos)
      Deprecated.
      Use getPriceInfoForPriceableEntity(Priceable, List, PriceContext) Passing the PriceContext supports proper filtering of PriceInfo results that are in the proper currency.
    • getPriceInfoForPriceableEntity

      protected <T extends com.broadleafcommerce.pricing.client.domain.PriceInfo> Optional<T> getPriceInfoForPriceableEntity(Priceable entity, List<T> candidatePriceInfos, @Nullable com.broadleafcommerce.pricing.client.domain.context.PriceContext priceContext)
      Picks the appropriate PriceInfo for the Priceable entity. The candidates are all the infos that matched the PriceableTargets created for the entity in the pricing request.

      Multiple targets will be created for a single Product, one targeting Product.getSku() and one targeting Product.getPricingKey(). In this case, whichever has the lower price will be selected.

      When a Variant does not have a default or sale price, multiple targets will be created, one targeting Variant.getSku() and one targeting Product.getPricingKey(). In this case, if there is a SKU-targeted price that is not a base price, such as price data from a price list, it will always be selected. Otherwise, it will use the price targeting Product.getPricingKey(), so that the product's best price based on Product.getPricingKey() would be used for the Variant.

      However, if a Variant does have a default or sale price, then only one target will be created, based on Variant.getSku(). This way, the Variant's own pricing will always be used and never be affected by product's pricing.

      In some cases, multiple targets will be created for a single entity such as for SpecificItemChoice, which may have pricing targeting it specifically, or, instead, its underlying Product or Variant.

      Default is to just choose the first match except in the case of IncludedProduct and SpecificItemChoice where we check for an info targeting them directly. For IncludedProducts if not present, then we choose the first candidate. For SpecificItemChoice, we check that it hasn't already inherited its parent ItemChoice's pricing, which should be retained; otherwise, we choose the first candidate.

      Parameters:
      entity - Entity for which to determine the appropriate candidatePriceInfos to attach.
      candidatePriceInfos - The PriceInfos matching the targets made for the entity.
      priceContext - The PriceContext with the requested currency.
      Returns:
      The chosen PriceInfo.
    • filterPriceInfosForCurrency

      protected <T extends com.broadleafcommerce.pricing.client.domain.PriceInfo> List<T> filterPriceInfosForCurrency(List<T> priceInfos, @Nullable com.broadleafcommerce.pricing.client.domain.context.PriceContext priceContext)
    • fixStandardPriceIfNeeded

      protected <T extends com.broadleafcommerce.pricing.client.domain.PriceInfo> void fixStandardPriceIfNeeded(T variantPriceInfo, List<T> candidatePriceInfos)
    • variantHasPrice

      protected boolean variantHasPrice(Variant variant)
    • checkForPriceInfoForVariantFromPriceList

      protected <T extends com.broadleafcommerce.pricing.client.domain.PriceInfo> Optional<T> checkForPriceInfoForVariantFromPriceList(List<T> candidatePriceInfos, Variant variant)
    • hasPriceInfoFromPriceList

      protected <T extends com.broadleafcommerce.pricing.client.domain.PriceInfo> Optional<T> hasPriceInfoFromPriceList(List<T> candidatePriceInfos)
    • bequeathItemChoicePricingToSpecificChoices

      protected void bequeathItemChoicePricingToSpecificChoices(ItemChoice itemChoice)
      If an ItemChoice has a PriceInfo, then it needs to be inherited by all of its SpecificItemChoices unless they have an explicit override.
      Parameters:
      itemChoice - The ItemChoice whose specific choices need to inherit pricing from.
    • isDirectVariantPrice

      protected boolean isDirectVariantPrice(com.broadleafcommerce.pricing.client.domain.PriceInfo priceInfo, Variant variant)
    • isBasePrice

      protected boolean isBasePrice(com.broadleafcommerce.pricing.client.domain.PriceInfo priceInfo)
    • isBaseSalePrice

      protected boolean isBaseSalePrice(com.broadleafcommerce.pricing.client.domain.PriceInfo priceInfo)
    • isTargetingVariantSku

      protected boolean isTargetingVariantSku(com.broadleafcommerce.pricing.client.domain.PriceInfo priceInfo, Variant variant)
    • attachPriceInfosOnOtherEntity

      protected void attachPriceInfosOnOtherEntity(@NonNull @NonNull Object entity, @NonNull @NonNull Collection<? extends com.broadleafcommerce.pricing.client.domain.PriceInfo> priceInfos)
      Extension point to use to handle attaching pricing info onto a non-default type of priceable entity. Default entities are Product, Variant, IncludedProduct, ItemChoice, and SpecificItemChoice.
      Parameters:
      entity - Entity to attach priceInfo onto
      priceInfos - PriceInfos that match the PriceableTarget(s) created for the entity
    • attachPriceInfoOnOtherEntity

      @Deprecated protected void attachPriceInfoOnOtherEntity(@NonNull @NonNull Object entity, @NonNull @NonNull com.broadleafcommerce.pricing.client.domain.PriceInfo priceInfo)
    • getServiceClient

      public String getServiceClient()
    • getPriceInfosUri

      public String getPriceInfosUri()
    • getUrl

      public String getUrl()
    • setPriceInfosUri

      public void setPriceInfosUri(String priceInfosUri)
    • setServiceClient

      public void setServiceClient(String serviceClient)
    • setUrl

      public void setUrl(String url)
    • getCatalogBrowseWebClient

      protected org.springframework.web.reactive.function.client.WebClient getCatalogBrowseWebClient()
    • getTypeFactory

      protected com.broadleafcommerce.common.extension.TypeFactory getTypeFactory()
    • getProductPriceableTargetsBuilders

      protected List<ProductPriceableTargetsBuilder> getProductPriceableTargetsBuilders()
    • getProperties

      protected ExternalPricingProviderProperties getProperties()
    • setProperties

      @Autowired public void setProperties(ExternalPricingProviderProperties properties)
    • getExternalClient

      protected com.broadleafcommerce.common.extension.intercommunication.ExternalClient getExternalClient()
    • setExternalClient

      @Autowired @Qualifier("browsePricingExternalClient") public void setExternalClient(com.broadleafcommerce.common.extension.intercommunication.ExternalClient externalClient)