TMForum API Version Support | Required Broadleaf Service(s) |
---|---|
v4 |
TMForum Resource | Description | Endpoints |
---|---|---|
|
|
|
|
|
|
Broadleaf supports TMF687 Stock Management via an Extension Model on top of Broadleaf’s existing Inventory Microservice. This extension model works by defining an extension library alongside Broadleaf’s default inventory service dependency which will enable additional TMForum specific capabilities.
InventoryLocation
and SkuInventory
The core Broadleaf concepts that underpin TMF687 are the InventoryLocation
and SkuInventory
domains. In Broadleaf, every SkuInventory
record is associated with an InventoryLocation
(i.e. a location like a warehouse, shipping location, pickup location, etc…)
In TMForum 687, the analogous relationship identifier is surfaced by the RelatedPlaceRefOrValue
which is used to define a place where the product stock is located. Broadleaf currently does not map or implement the concept of Place
(TMF673
/TMF674
) nor do we assume that a reference value passed into this RefOrValue
entity refers back to a Broadleaf managed resource.
Instead, Broadleaf supports an extended JSON property: blcInventoryLocationContextId
on the default ProductStock
and ReserveProductStock
payloads which can properly identify the Broadleaf Inventory Location a certain stock request is associated with. Note that this field is optional and the system will default to a particular value specified in the API Context attributes if not in the request payload.
Broadleaf’s TMForum Extensions library provides several Spring utility components that are responsible for assisting in conversions between TMForum Concepts and Broadleaf Concepts. The following components can be extended to support a different mapping strategy if needed.
com.broadleafcommerce.tmforum.inventory.tmf687.service.mapping.ProductStockIdProcessingUtility
ProductStock.id
is derived from Broadleaf’s SkuInventory.id
, and this component is responsible for handling the conversion from both directions
com.broadleafcommerce.tmforum.inventory.tmf687.service.mapping.ProductStockMappingUtility
The conversion logic between ProductStock
and Broadleaf’s SkuInventory
is handled in multiple places. For 'read' operations, the mapping is handled by ModelMapperMappable
logic in JpaSkuInventoryProductStockView
to go from the Broadleaf representation to the TMF representation. For modification operations like creates and updates, ProductStockMappingUtility
is where the conversion from TMF representation to Broadleaf representation is defined.
Filtration and Sort
ProductStock
com.broadleafcommerce.tmforum.inventory.tmf687.web.attributefiltration.ProductStockAttributeFiltersRequestResolver
Handles resolving the supported filtration parameters for requests against ProductStock
com.broadleafcommerce.tmforum.inventory.tmf687.provider.jpa.filtering.JpaSkuInventoryProductStockViewRsqlAndSortTransformer
Handles field transformations for filter and sort requests against ProductStock
The following fields are supported for filtration/sort on ProductStock
id
name
replenishmentDate
productStockStatusType
lastUpdate
blcInventoryLocationContextId
productStockLevel.amount
stockedProduct.productSerialNumber
ReserveProductStock
com.broadleafcommerce.tmforum.inventory.tmf687.web.attributefiltration.ReserveProductStockAttributeFiltersRequestResolver
Handles resolving the supported filtration parameters for requests against ReserveProductStock
The following fields are supported for filtration/sort on ReserveProductStock
id
creationDate
reserveProductStockState
blcInventoryLocationContextId
com.broadleafcommerce.tmforum.inventory.tmf687.service.validation.ProductStockValidator
This component implements first-class validations on ProductStock
request payloads to ensure API consumers cannot create an invalid state.
com.broadleafcommerce.tmforum.inventory.tmf687.service.mapping.ReserveProductStockMappingUtility
This handles the conversion logic between ReserveProductStock
and Broadleaf’s SkuInventoryReservationRequest
.
com.broadleafcommerce.tmforum.inventory.tmf687.service.validation.ReserveProductStockValidator
This component implements first-class validations on ReserveProductStock
request payloads to ensure API consumers cannot create an invalid state.
com.broadleafcommerce.tmforum.inventory.tmf687.service.DefaultProductStockService
This is the top-level service component responsible for handling management of ProductStock
. It orchestrates the main flow for CRUD operations, delegating specific responsibilities like validation and mapping to the other components as appropriate.
com.broadleafcommerce.tmforum.inventory.tmf687.service.DefaultReserveProductStockService
This is the top-level service component responsible for handling management of ReserveProductStock
. It orchestrates the main flow for CRUD operations, delegating specific responsibilities like validation and mapping to the other components as appropriate.
com.broadleafcommerce.tmforum.inventory.tmf687.service.apicontext.InventoryCommonTMFApiContextKeys
shows which fields can be defaulted via API Context attributes out-of-box
com.broadleafcommerce.tmforum.inventory.tmf687.jackson.autoconfigure.TMForumInventoryJacksonAutoConfiguration
Defines JacksonAnnotationMixinMapping
beans for ProductStock
and ReserveProductStock
to drive behaviors such as attribute selection
ProductStock
The TMForum ProductStock
resource conceptually maps to Broadleaf’s SkuInventory
resource, the main difference being that Broadleaf aggregates specific ProductStock
inventory counts into a single SkuInventory
record whereas TMForum defines each individual quantity count as being a separate entry.
In order to conform to the TMForum’s pagination, filtration, and sorting intent, Broadleaf employs a read-only database view (BLC_SKU_INV_PROD_STOCK
) to expand a single SkuInventory
entry into multiple rows to achieve conformance with TMForum’s API.
The create/update/delete operations follow a tailored flow to preserve the external 'separate entity' abstraction.
Internally, the flow will make determinations about whether the operation needs to result in a net-new SkuInventory
record or if it should update an existing SkuInventory
record with the requested state.
For example, if a TMF request comes in to create a 'reserved' ProductStock
for SKU ABC123
, and there is already a SkuInventory
for ABC123
that does not have a 'reserved' quantity, the system may update that existing SkuInventory
record instead of creating a net new one.
Below is a high level diagram describing the concept mapping strategies Broadleaf has employed to support this translation:
ProductStock
The productStockStatusType
is the primary field on which a SkuInventory
is split into ProductStock
.
The ProductStock.id
is built from a combination of the SkuInventory.id
and a productStockStatusType
.
In Broadleaf, quantities in a SkuInventory
must always result in a valid state - for example, you cannot have an inventory that has more items reserved than are available (if backorder is disabled).
Because of this, in TMF, an API consumer cannot, for example, create 'reserved' ProductStock
for a SKU if they have not already created enough 'available' ProductStock
for that SKU.
The order of creation matters to ensure the backing SkuInventory
remains valid.
TMF requires that the productStockStatusType
value be PATCH
-able.
In Broadleaf, this creates a special case, since productStockStatusType
is used to identify a ProductStock
in the first place.
Semantically, mutation of the productStockStatusType
is equivalent to 'deleting' the ProductStock
of the existing type and then creating a new ProductStock
for the requested type (potentially migrating the quantity for the existing type to the new type).
In the response, the new ProductStock.id
will be returned so consumers can see the difference.
While some fields on SkuInventory
are only used by a particular productStockStatusType
(ex: only the 'preorder' or 'backorder' ProductStock
will deal with the SkuInventory.expectedFutureRestockDate
field), others like SkuRef.skuName
are shared by all ProductStock
instances backed by the same SkuInventory
.
In the interest of remaining flexible instead of rejecting mutation attempts altogether, any update to such a 'shared' field will implicitly result in updating all ProductStock
instances backed by the same SkuInventory
.
Note that blcInventoryLocationContextId
is intentionally not honored as part of ProductStock
update requests, as modification of this value would implicitly make a significant change to all ProductStock
instances backed by the same SkuInventory
.
ReserveProductStock
Broadleaf supports the concept of reserving inventory through reservation requests that are already facilitated through core "task-based" inventory service methods. TMForum ReserveProductStock
APIs assume the management of a persisted reservation request resource which is asynchronously executed.
Broadleaf TMForum Extensions introduces a BLC_RESERVE_PRODUCT_STOCK
table to conform with the "resource-based" TMF687 ReserveProductStock
intent.
Broadleaf provides a ReserveProductStockService
which synchronously executes a stock reservation request and creates a corresponding new ReserveProductStock
in the datastore. From the perspective of the API consumer, this is no different from an asynchronous execution, as the results are surfaced and retrieved in the same way.
Below is a high level diagram describing the concept mapping strategies Broadleaf has employed to support this API:
Ultimately, creation of a ReserveProductStock
involves building and submitting Broadleaf’s SkuInventoryReservationRequest
to the internal reservation logic, at which point InventoryTransaction
instances representing the reserved stock are created and tracked.