Class ExternalInventoryProvider

java.lang.Object
com.broadleafcommerce.cartoperation.service.provider.external.AbstractExternalProvider
com.broadleafcommerce.cartoperation.service.provider.external.ExternalInventoryProvider
All Implemented Interfaces:
InventoryProvider

public class ExternalInventoryProvider extends AbstractExternalProvider implements InventoryProvider
Component that, by default, attempts to invoke Broadleaf Inventorry Services to reserve inventory.
Author:
Kelly Tisdell (ktisdell)
See Also:
  • Field Details

    • SOFT_RESERVATION

      public static final String SOFT_RESERVATION
      Represents the soft inventory reservation type
      See Also:
    • DEFAULT_RESERVATION_REQUEST_TYPE

      protected static final String DEFAULT_RESERVATION_REQUEST_TYPE
      See Also:
    • DEFAULT_SKU_REF_FIELD_TYPE

      protected static final String DEFAULT_SKU_REF_FIELD_TYPE
      See Also:
    • INVENTORY_UNAVAILABLE

      protected static final String INVENTORY_UNAVAILABLE
      See Also:
    • CANNOT_DETERMINE_CART_ITEM_INVENTORY_ERROR_MSG

      protected static final String CANNOT_DETERMINE_CART_ITEM_INVENTORY_ERROR_MSG
      See Also:
    • UNAVAILABLE_CART_ITEM_INVENTORY_ERROR_MSG

      protected static final String UNAVAILABLE_CART_ITEM_INVENTORY_ERROR_MSG
      See Also:
    • AVAILABILITY_CHECK_UNEXPECTED_FAILURE_ERROR_MSG

      protected static final String AVAILABILITY_CHECK_UNEXPECTED_FAILURE_ERROR_MSG
      See Also:
  • Constructor Details

    • ExternalInventoryProvider

      public ExternalInventoryProvider(org.springframework.web.reactive.function.client.WebClient webClient, com.fasterxml.jackson.databind.ObjectMapper objectMapper, com.broadleafcommerce.common.extension.TypeFactory typeFactory, ExternalInventoryProperties properties)
  • Method Details

    • isInventoryAvailable

      public boolean isInventoryAvailable(@NonNull @NonNull InventoryAvailabilityRequest inventoryAvailabilityRequest, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Description copied from interface: InventoryProvider
      Determines whether Inventory is available for a particular catalog item.
      Specified by:
      isInventoryAvailable in interface InventoryProvider
      Parameters:
      inventoryAvailabilityRequest - the catalog item for which to check inventory availability
      contextInfo - context information surrounding sandboxing and multitenant state
      Returns:
      true if inventory is available for the catalog item and quantity, false otherwise
    • isInventoryAvailable

      public Map<String,Boolean> isInventoryAvailable(@NonNull @NonNull List<InventoryAvailabilityRequest> inventoryAvailabilityRequests, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Description copied from interface: InventoryProvider
      Determines whether Inventory is available for a list of catalog items.

      By default, if the catalog item is available for one of the SKU locations or vendors, then it's considered available overall.

      Use InventoryProvider.getInventorySummariesBySku(Map, ContextInfo) for custom logic on SKU inventory availability.

      Specified by:
      isInventoryAvailable in interface InventoryProvider
      Parameters:
      inventoryAvailabilityRequests - a list of inventory requests for which to check inventory availability
      contextInfo - context information surrounding sandboxing and multitenant state
      Returns:
      a map of the sku code with true if inventory is available for the SKU and quantity, and false otherwise
    • isInventoryAvailable

      public boolean isInventoryAvailable(String skuCode, int quantity, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Description copied from interface: InventoryProvider
      Determines whether Inventory is available for a particular SKU.
      Specified by:
      isInventoryAvailable in interface InventoryProvider
      Parameters:
      skuCode - the sku code for which to check inventory availability
      quantity - the quantity of the sku code that will be requested
      contextInfo - context information surrounding sandboxing and multitenant state
      Returns:
      true if inventory is available for the SKU and quantity, false otherwise
    • isInventoryAvailable

      public Map<String,Boolean> isInventoryAvailable(@NonNull @NonNull Map<String,Integer> skuCodesAndQuantity, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Description copied from interface: InventoryProvider
      Determines whether Inventory is available for a list of SKUs.

      By default, if the SKU is available for one of the SKU locations or vendors, then it's considered available overall.

      Use InventoryProvider.getInventorySummariesBySku(Map, ContextInfo) for custom logic on SKU inventory availability.

      Specified by:
      isInventoryAvailable in interface InventoryProvider
      Parameters:
      skuCodesAndQuantity - a map of the sku codes and quantity for which to check inventory availability
      contextInfo - context information surrounding sandboxing and multitenant state
      Returns:
      a map of the sku code with true if inventory is available for the SKU and quantity, and false otherwise
    • getInventorySummariesBySku

      public Map<String,List<SkuInventoryAvailabilitySummary>> getInventorySummariesBySku(@NonNull @NonNull Map<String,Integer> skuCodesAndQuantity, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Description copied from interface: InventoryProvider
      Gets a map of SkuInventoryAvailabilitySummaries by SKU.

      There can be multiple SkuInventoryAvailabilitySummaries for one SKU, if there are SKU inventories set up at multiple inventory locations or vendors.

      This is useful for custom SKU inventory availability logic.

      Specified by:
      getInventorySummariesBySku in interface InventoryProvider
      Parameters:
      skuCodesAndQuantity - a map of the sku codes and quantity for which to check inventory availability
      contextInfo - context information surrounding sandboxing and multitenant state
      Returns:
      a map of SkuInventoryAvailabilitySummaries by SKU
    • getInventorySummaries

      protected List<SkuInventoryAvailabilitySummary> getInventorySummaries(@NonNull @NonNull Map<String,Integer> skuCodesAndQuantity, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
    • getInventorySummaries

      protected List<SkuInventoryAvailabilitySummary> getInventorySummaries(@NonNull @NonNull List<SkuInventoryAvailabilityRequest> availabilityRequests, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
    • reserveInventory

      public void reserveInventory(@NonNull @NonNull com.broadleafcommerce.cart.client.domain.Cart cart, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Description copied from interface: InventoryProvider
      Decrement or otherwise "reserve" inventory for a cart during checkout.
      Specified by:
      reserveInventory in interface InventoryProvider
      Parameters:
      cart - The cart for which to decrement inventory.
      contextInfo - Context information around sandbox and multitenant state.
    • softReserveInventory

      public void softReserveInventory(com.broadleafcommerce.cart.client.domain.Cart cart, List<com.broadleafcommerce.cart.client.domain.CartItem> itemsToReserve, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Description copied from interface: InventoryProvider
      Perform a soft reservation on a specific item. Intended to be used if an item has an "Add to Cart" reservation strategy
      Specified by:
      softReserveInventory in interface InventoryProvider
      itemsToReserve - The items added to the cart to be soft reserved
      contextInfo - Context information around sandbox and multitenant state.
    • releaseSoftReservations

      public ReleaseSkuInventoryReservationResponse releaseSoftReservations(@NonNull @NonNull com.broadleafcommerce.cart.client.domain.Cart cart, @NonNull @NonNull List<com.broadleafcommerce.cart.client.domain.CartItem> itemsToRelease, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Description copied from interface: InventoryProvider
      Releases the inventory soft reservations for the given cart items, which is typically used when the items are removed from cart. Intended to be used for items that have an the InventoryReservationStrategy.ADD_TO_CART
      Specified by:
      releaseSoftReservations in interface InventoryProvider
      Parameters:
      cart - The cart containing the items
      itemsToRelease - The items removed from the cart and to release the soft reservation for
      contextInfo - Context information around sandbox and multitenant state.
      Returns:
      a ReleaseSkuInventoryReservationResponse
    • getQuantityBySkuMapFromSummaries

      protected Map<String,Boolean> getQuantityBySkuMapFromSummaries(List<SkuInventoryAvailabilitySummary> inventoryAvailabilitySummaries)
      Gets a map of quantity by SKU from the given SkuInventoryAvailabilitySummaries.

      Sometimes we can get duplicate SKU codes back in different SKU Locations or vendors. We always want to return true, if it's available for one vendor or another, which prevents the "java.lang.IllegalStateException: Duplicate key" error while returning true if the item is available for at least 1 location or vendor.

      Parameters:
      inventoryAvailabilitySummaries - a list of SkuInventoryAvailabilitySummaries to convert into a map for
      Returns:
      a map of quantity by SKU from the given SkuInventoryAvailabilitySummaries.
    • buildReservationResponseException

      protected Exception buildReservationResponseException(@NonNull @NonNull com.broadleafcommerce.cart.client.domain.Cart cart, @NonNull @NonNull org.springframework.web.reactive.function.client.WebClientResponseException ex)
      Builds the appropriate exception that should be thrown when a request to reserve inventory fails.

      By default, all errors (even those caused by unexpected issues) will result in an InventoryUnavailableException.

      Parameters:
      cart - the cart for which reservation was requested
      ex - the error that was encountered when making the request
      Returns:
      the appropriate exception that should be thrown when a request to reserve inventory fails
    • buildExceptionForUnexpectedReservationError

      protected InventoryUnavailableException buildExceptionForUnexpectedReservationError(@NonNull @NonNull com.broadleafcommerce.cart.client.domain.Cart cart, @NonNull @NonNull Exception ex)
      Parameters:
      cart - the cart for which inventory reservation was requested
      ex - the unexpected error that was encountered
      Returns:
      an exception that can be thrown when an inventory reservation request encounters an unexpected error
    • isInventoryUnavailableResponse

      protected boolean isInventoryUnavailableResponse(@NonNull @NonNull org.springframework.web.reactive.function.client.WebClientResponseException ex)
    • getErrorType

      @Nullable protected String getErrorType(@NonNull @NonNull org.springframework.web.reactive.function.client.WebClientResponseException ex)
    • buildSkuToCartItemIdMap

      protected org.springframework.util.MultiValueMap<String,String> buildSkuToCartItemIdMap(@NonNull @NonNull Collection<com.broadleafcommerce.cart.client.domain.CartItem> cartItems)
    • getSkuReferences

      protected List<String> getSkuReferences(@NonNull @NonNull org.springframework.web.reactive.function.client.WebClientResponseException ex)
    • getDocumentContext

      protected com.jayway.jsonpath.DocumentContext getDocumentContext(@NonNull @NonNull String payload)
    • buildInventoryReservationRequest

      protected Optional<SkuInventoryReservationRequest> buildInventoryReservationRequest(@NonNull @NonNull com.broadleafcommerce.cart.client.domain.Cart cart, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      This allows implementors to build a SkuInventoryReservationRequest or return an empty Optional if no external request should be made (e.g. if all items in the cart are considered implicitly available.
      Parameters:
      cart -
      contextInfo -
      Returns:
      Throws:
      InventoryUnavailableException - - if one or more items are in the cart that are unavailable.
    • buildInventoryReservationRequest

      protected Optional<SkuInventoryReservationRequest> buildInventoryReservationRequest(@NonNull @NonNull com.broadleafcommerce.cart.client.domain.Cart cart, @NonNull @NonNull List<com.broadleafcommerce.cart.client.domain.CartItem> cartItems, String inventoryReservationType, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
    • buildReleaseInventoryReservationRequest

      protected Optional<ReleaseSkuInventoryReservationRequest> buildReleaseInventoryReservationRequest(@NonNull @NonNull com.broadleafcommerce.cart.client.domain.Cart cart, @NonNull @NonNull List<com.broadleafcommerce.cart.client.domain.CartItem> cartItemsToRelease, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Builds an optional of ReleaseSkuInventoryReservationRequest based on the given cart and cart items. An Optional.empty() is returned if there are no items to release the reservations for.
      Parameters:
      cart - the Cart containing the items to build the request for
      cartItemsToRelease - the CartItems to release the soft reservations for
      contextInfo - context information surrounding multitenant state
      Returns:
      an optional of ReleaseSkuInventoryReservationRequest
    • getSkuReference

      protected String getSkuReference(com.broadleafcommerce.cart.client.domain.CartItem cartItem)
    • isSerialized

      protected boolean isSerialized(com.broadleafcommerce.cart.client.domain.CartItem cartItem)
      Determines whether the cart item has a serialized sku inventory object
      Parameters:
      cartItem - the cart item
      Returns:
      whether the cart item has a serialized sku inventory object
    • buildSerializedSku

      protected String buildSerializedSku(com.broadleafcommerce.cart.client.domain.CartItem cartItem)
      Builds a sku with an appended serialization value parameter
      Parameters:
      cartItem - cart item to access values from
      Returns:
      sku with an appended serialization value parameter
    • getInventorySerializationValue

      @Nullable protected String getInventorySerializationValue(com.broadleafcommerce.cart.client.domain.CartItem cartItem)
      Hook point to get the serialization value of a cart item

      By default, accesses a respective entry inside CartItem.getInternalAttributes().

      Parameters:
      cartItem - the cart item
      Returns:
      the serialization value
    • getProductType

      @Nullable protected Object getProductType(com.broadleafcommerce.cart.client.domain.CartItem cartItem)
    • getReservationUri

      protected String getReservationUri(@Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Return the POST URI for Inventory Reservations.
      Parameters:
      contextInfo -
      Returns:
    • getAvailabilityCheckUri

      protected String getAvailabilityCheckUri(@NonNull @NonNull String skuCode, int quantity, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Return the GET URI for Inventory Availability. By default, this looks for shipping locations only for the provided skuCode.
      Parameters:
      contextInfo -
      Returns:
    • getBulkAvailabilityCheckUri

      protected String getBulkAvailabilityCheckUri(@Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Return the GET URI for Inventory Availability. By default, this looks for shipping locations only for the provided skuCodes.
      Parameters:
      contextInfo - Context information around sandbox and multitenant state.
      Returns:
    • postProcessReservationResponse

      protected void postProcessReservationResponse(@NonNull @NonNull com.broadleafcommerce.cart.client.domain.Cart cart, @NonNull @NonNull SkuInventoryReservationResponse response, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Arbitrary hook point to allow for post processing of the Cart and/or the SkuInventoryReservationResponse.
      Parameters:
      cart -
      response -
      contextInfo -
    • postProcessReleaseReservationResponse

      protected ReleaseSkuInventoryReservationResponse postProcessReleaseReservationResponse(@NonNull @NonNull com.broadleafcommerce.cart.client.domain.Cart cart, @NonNull @NonNull ReleaseSkuInventoryReservationResponse response, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Arbitrary hook point to allow for post processing of the Cart and/or the ReleaseSkuInventoryReservationResponse.
    • getReservationRequestType

      protected String getReservationRequestType(@NonNull @NonNull com.broadleafcommerce.cart.client.domain.Cart cart, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Indicates the reservation request type (e.g. HARD or SOFT). The default is 'SOFT', meaning that the inventory reservation will be temporary to allow for a hard reservation later - usually after order submittal - which makes the reservation permanent.
      Parameters:
      cart -
      contextInfo -
      Returns:
    • getSkuReferenceFieldType

      protected String getSkuReferenceFieldType(@NonNull @NonNull com.broadleafcommerce.cart.client.domain.Cart cart, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      SkuInventory records can be looked up or reference by a number of field types, including:
      SKU_CODE - Identifies a CatalogItem.getSku() or Variant.getSku() by a unique SKU code
      SKU_EXTERNAL_ID - An ID in another 1st or 3rd party system (e.g. in an ERP)
      SKU_CODE - Arbitrary SKU code UPC - Universal Product
      Code EAN - European Article Number (aka International Article Number)
      GTIN - Global Trade Item Number

      The default is SKU_CODE.

      Parameters:
      cart -
      contextInfo -
      Returns:
    • getListType

      protected org.springframework.core.ParameterizedTypeReference<List<SkuInventoryAvailabilitySummary>> getListType()
      Gets the type reference for a list of sku availability.
      Returns:
      type reference for a list of sku availability
    • buildSkuInventoryAvailabilityRequests

      protected List<SkuInventoryAvailabilityRequest> buildSkuInventoryAvailabilityRequests(Map<String,Integer> skuCodesAndQuantity)
      Builds a list SkuInventoryAvailabilityRequest to verify the availability of the SKU for the provided quantity.
      Returns:
      a list of sku inventory availability requests
    • getServiceClient

      protected String getServiceClient()
    • getProperties

      protected ExternalInventoryProperties getProperties()