 
| 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 SkuInventoryThe 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
ProductStockThe 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:
 
ProductStockThe 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.
ReserveProductStockBroadleaf 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.