Inventory Batch Pre-Processing: Technical Guide with Examples
Author:
Fluent Commerce
Changed on:
11 Feb 2025
Overview
This page describes how Inventory Batch Pre-Processing (BPP) works and what technical aspects need to be considered as part of an implementation.
Key points
- Optimize Inventory Updates: Batch Pre-Processing enhances system efficiency by processing only necessary changes, reducing unnecessary load on the workflow engine.
- Structured Batch Updates: Properly structuring your batch updates with the correct use of fields like ,
`ref`
, and`type`
is essential for accurate change detection and effective use of Batch Pre-Processing.`status`
- Essential Knowledge: Even if you don't delve into all the details, remember that precise batch update structures are crucial. Pay special attention to how the field is constructed and the default behaviors when certain fields are not specified.
`ref`
- New Fields and Defaults: Be aware of the new fields introduced by this feature and understand the default transient types and statuses. This knowledge will help you implement Batch Pre-Processing correctly and avoid potential pitfalls.
Pre-Requisites:
Batch Pre-Processing optimizes the inventory update process by analyzing batch updates before they reach the workflow engine. This ensures that only necessary changes are processed, improving efficiency and performance.
This guide aims to help you understand:
- How Batch Pre-Processing works.
- How to structure your batch updates.
- How different scenarios are handled.
- The default behaviors when certain fields are not specified.
Change Detection Criteria
The following criteria to determine if an inventory update represents a change:
- Inventory Quantity Identification
- Quantity and Status Comparison
- Transient Inventory Quantities Check
1. Inventory Quantity Identification
Determines how each inventory quantity (IQ) is identified for comparison.
Aspect | Description | Default Behavior | Notes |
Type Handling | - Default Type: If
- Specified Type: Uses provided
|
| Ensures consistent identification when
|
Reference ( | - Optional: When provided,
- Behavior: - If Provided: Searches for existing IQ with matching
- If Not Found: Marks update as changed and processes it as a new record. | Constructed using
| Facilitates precise IQ identification and de-duplication. |
Example of Reference (`ref`
`ref = <skuRef>:<locationRef>:<catalogueType>:<type>`
Components
Component | Description | Default |
| Product reference | Provided in the update |
| Location reference | Provided in the update |
| Catalogue type |
|
| IQ type |
|
Example
Given:
- :
`skuRef`
`SKU12345`
- :
`locationRef`
`LOC67890`
- :
`catalogueRef`
(type:`CAT54321`
)`"BACK_ORDER"`
- : Not provided
`type`
Sample Constructed `ref`
`SKU12345:LOC67890:BACK_ORDER:LAST_ON_HAND`
2. Quantity and Status Comparison
Compares the updated quantities and statuses against existing inventory data.
Comparison Type | Description | Outcome if Different |
Quantity ( | Compares the
| The update is marked as changed. |
Status ( | If
| The update is marked as changed. |
Notes:
- If the field is not provided in the update, the status comparison is skipped.
`status`
3. Transient Inventory Quantities Check
Ensures that temporary inventory quantities are factored in to determine change criteria
Aspect | Description | Outcome if Condition Met |
Transient Types | Includes temporary types such as
| |
Matching Transients | Checks for any matching transient IQs of designated types and statuses associated with the inventory position. Do note for performance reasons, any condition with the status "INACTIVE" is ignored | If matching transients exist, the update is marked as changed. |
Notes:
- Matching transients indicate ongoing temporary changes that may affect the accuracy of the update.
Summary of Change Detection Process
- Identify IQ:
- Use the provided or construct it based on
`ref`
,`skuRef`
,`locationRef`
, and`catalogueType`
.`type`
- Use the provided
- Compare Quantities and Statuses:
- Check if differs.
`qty`
- If is provided, check if it differs.
`status`
- Check if
- Check for Matching Transients:
- Determine if there are matching transient IQs that could affect the update.
- Mark as Changed:
- If any of the above comparisons indicate a difference, mark the update as changed.
Result
Only updates that are marked as changed based on the above criteria are forwarded to the Inventory Queue for further processing. This ensures that only relevant and necessary updates impact the inventory system, maintaining data integrity and operational efficiency.
Below are examples of batch payloads and how the system processes them.
Example 1 - Update with Provided `ref`
and `type`
(PURCHASE_ORDER)
`ref`
`type`
Batch Payload:
1{
2 "action": "UPSERT",
3 "entityType": "INVENTORY",
4 "entities": [
5 {
6 "ref": "SKU-001:LOC-001:DEFAULT:PURCHASE_ORDER",
7 "type": "PURCHASE_ORDER",
8 "skuRef": "SKU-001",
9 "locationRef": "LOC-001",
10 "qty": 100,
11 "retailerId": 1
12 }
13 ]
14}
Language: json
Name: Update with Provided ref and type (PURCHASE_ORDER)
Description:
Update with Provided
`ref`
`type`
Explanation:
- Ref Provided:
`"SKU-001:LOC-001:DEFAULT:PURCHASE_ORDER"`
- Process:
- Find IQ with provided .
`ref`
- Quantity Comparison:
- If the existing ≠
`qty`
, the update is changed.`100`
- If the existing
- Transient Check:
- Uses default transient types and statuses.
- If No IQ Found:
- The update is changed and processed as a new IQ.
- Find IQ with provided
Example 2 - Update with `status`
Change and Provided `ref`
and `type`
`status`
`ref`
`type`
Batch Payload:
1{
2 "action": "UPSERT",
3 "entityType": "INVENTORY",
4 "entities": [
5 {
6 "ref": "SKU-002:LOC-002:DEFAULT:PURCHASE_ORDER",
7 "type": "PURCHASE_ORDER",
8 "status": "INACTIVE",
9 "skuRef": "SKU-002",
10 "locationRef": "LOC-002",
11 "qty": 50,
12 "retailerId": 1
13 }
14 ]
15}
Language: json
Name: Update with status Change and Provided ref and type
Description:
Update with
`status`
`ref`
`type`
Explanation:
- Ref Provided:
`"SKU-002:LOC-002:DEFAULT:PURCHASE_ORDER"`
- Status Provided:
`"INACTIVE"`
- Process:
- Find IQ with provided .
`ref`
- Quantity and Status Comparison:
- If the existing qty ≠ 50 OR the existing status ≠ "INACTIVE", the update is changed.
- Transient Check:
- Uses default transient types and statuses.
- If No IQ Found:
- The update is changed and processed as a new IQ.
- Find IQ with provided
Example 3 - Update with Custom `catalogueRef`
and Custom Transient Types
`catalogueRef`
Batch Payload:
1{
2 "action": "UPSERT",
3 "entityType": "INVENTORY",
4 "catalogueRef": "CATALOG-001",
5 "conditions": {
6 "hasRelatedInventoryQuantities": [
7 {"type": "RESERVATION", "status": "ACTIVE"},
8 {"type": "RETURN", "status": "CREATED"}
9 ]
10 },
11 "entities": [
12 {
13 "ref": "SKU-003:LOC-003:BACK_ORDER:LAST_ON_HAND",
14 "type": "LAST_ON_HAND",
15 "status": "INACTIVE",
16 "skuRef": "SKU-003",
17 "locationRef": "LOC-003",
18 "qty": 200,
19 "retailerId": 1
20 }
21 ]
22}
Language: json
Name: Update with Custom catalogueRef and Custom Transient Types
Description:
Update with Custom
`catalogueRef`
Explanation:
- CatalogueRef Provided:
`"CATALOG-001"`
- Catalogue Type: Suppose
`"BACK_ORDER"`
- Ref Provided:
`"SKU-003:LOC-003:BACK_ORDER:LAST_ON_HAND"`
- Conditions Provided:
- Transient types: and
`"RESERVATION"`
`"RETURN"`
- Statuses: and
`"ACTIVE"`
`"CREATED"`
- Transient types:
- Process:
- Find IQ with the provided in
`ref`
.`CATALOG-001`
- Quantity and Status Comparison.
- Transient Check:
- Uses provided transient types and statuses.
- Find IQ with the provided
Example 4 - Update with Custom `catalogueRef`
, Provided `ref`
, and Custom Transient Types
`catalogueRef`
`ref`
Batch Payload:
1{
2 "action": "UPSERT",
3 "entityType": "INVENTORY",
4 "catalogueRef": "CATALOG-002",
5 "conditions": {
6 "hasRelatedInventoryQuantities": [
7 {"type": "ON_HOLD", "status": "ACTIVE"},
8 {"type": "ON_HOLD", "status": "CREATED"}
9 ]
10 },
11 "entities": [
12 {
13 "ref": "SKU-004:LOC-004:FUTURE:PURCHASE_ORDER",
14 "type": "PURCHASE_ORDER",
15 "skuRef": "SKU-004",
16 "locationRef": "LOC-004",
17 "qty": 75,
18 "retailerId": 1
19 }
20 ]
21}
Language: json
Name: Update with Custom catalogueRef, Provided ref, and Custom Transient Types
Description:
Update with Custom
`catalogueRef`
`ref`
Explanation:
- CatalogueRef Provided:
`"CATALOG-002"`
- Catalogue Type: Suppose
`"FUTURE"`
- Ref Provided:
`"SKU-004:LOC-004:FUTURE:PURCHASE_ORDER"`
- Process:
- Find IQ with the provided in
`ref`
.`CATALOG-002`
- Quantity Comparison.
- Transient Check:
- Uses provided transient types and statuses.
- Find IQ with the provided
Example 5 - Update Without `ref`
or `type`
, Using Custom Transient Types
`ref`
`type`
Batch Payload:
1{
2 "action": "UPSERT",
3 "entityType": "INVENTORY",
4 "catalogueRef": "DEFAULT:1",
5 "conditions": {
6 "hasRelatedInventoryQuantities": [
7 {"type": "SALE", "status": "ACTIVE"},
8 {"type": "SALE", "status": "CREATED"},
9 {"type": "DELTA", "status": "ACTIVE"},
10 {"type": "DELTA", "status": "CREATED"}
11 ]
12 },
13 "entities": [
14 {
15 "skuRef": "SKU-005",
16 "locationRef": "LOC-005",
17 "qty": 60,
18 "retailerId": 1
19 }
20 ]
21}
Language: json
Name: Update Without ref or type, Using Custom Transient Types
Description:
Update Without
`ref`
`type`
Explanation:
- Type Defaulted to:
`"LAST_ON_HAND"`
- Catalogue Type:
`"DEFAULT"`
- Ref Constructed as:
`"SKU-005:LOC-005:DEFAULT:LAST_ON_HAND"`
- Process:
- Find IQ with constructed ref in the default catalog.
- Quantity Comparison.
- Transient Check:
- Uses provided transient types and statuses.
Example 6 - Basic Update Without `ref`
, `type`
, or Custom Transient Types
`ref`
`type`
Batch Payload:
1{
2 "action": "UPSERT",
3 "entityType": "INVENTORY",
4 "entities": [
5 {
6 "skuRef": "SKU-006",
7 "locationRef": "LOC-006",
8 "qty": 90,
9 "retailerId": 1
10 }
11 ]
12}
Language: json
Name: Basic Update Without ref, type, or Custom Transient Types
Description:
Basic Update Without
`ref`
`type`
Explanation:
- Type Defaulted to:
`"LAST_ON_HAND"`
- Catalogue Type:
`"DEFAULT"`
- Ref Constructed as:
`"SKU-006:LOC-006:DEFAULT:LAST_ON_HAND"`
- Process:
- Find IQ with constructed ref in the default catalog.
- Quantity Comparison.
- Transient Check:
- Uses default transient types and statuses.
Example 7 - Update with Provided `ref`
and Default `type`
(`LAST_ON_HAND`
)
`ref`
`type`
`LAST_ON_HAND`
Batch Payload:
1{
2 "action": "UPSERT",
3 "entityType": "INVENTORY",
4 "entities": [
5 {
6 "ref": "SKU-007:LOC-007:DEFAULT:LAST_ON_HAND",
7 "type": "LAST_ON_HAND",
8 "skuRef": "SKU-007",
9 "locationRef": "LOC-007",
10 "qty": 110,
11 "retailerId": 1
12 }
13 ]
14}
Language: json
Name: Update with Provided ref and Default type (LAST_ON_HAND)
Description:
Update with Provided
`ref`
`type`
`LAST_ON_HAND`
Explanation:
- Ref Provided:
`"SKU-007:LOC-007:DEFAULT:LAST_ON_HAND"`
- Process:
- Find IQ with the provided ref in the default catalogue.
- Quantity Comparison.
- Transient Check:
- Uses default transient types and statuses.
Example 8 - Update with Provided `ref`
Without Specifying `type`
`ref`
`type`
Batch Payload:
1{
2 "action": "UPSERT",
3 "entityType": "INVENTORY",
4 "entities": [
5 {
6 "ref": "SKU-008:LOC-008:DEFAULT:LAST_ON_HAND",
7 "skuRef": "SKU-008",
8 "locationRef": "LOC-008",
9 "qty": 130,
10 "retailerId": 1
11 }
12 ]
13}
Language: json
Name: Update with Provided ref Without Specifying type
Description:
Update with Provided
`ref`
`type`
Explanation:
- Ref Provided:
`"SKU-008:LOC-008:DEFAULT:LAST_ON_HAND"`
- Process:
- Find IQ with the provided ref in the default catalogue.
- Quantity Comparison.
- Transient Check:
- Uses default transient types and statuses.
Example 9 - Update with Provided `ref`
, `type`
, and `status`
`ref`
`type`
`status`
Batch Payload:
1{
2 "action": "UPSERT",
3 "entityType": "INVENTORY",
4 "entities": [
5 {
6 "ref": "SKU-009:LOC-009:DEFAULT:LAST_ON_HAND",
7 "status": "ACTIVE",
8 "type": "LAST_ON_HAND",
9 "skuRef": "SKU-009",
10 "locationRef": "LOC-009",
11 "qty": 150,
12 "retailerId": 1
13 }
14 ]
15}
Language: json
Name: Update with Provided ref, type, and status
Description:
Update with Provided
`ref`
`type`
`status`
Explanation:
- Ref Provided:
`"SKU-009:LOC-009:DEFAULT:LAST_ON_HAND"`
- Status Provided:
`"ACTIVE"`
- Process:
- Find IQ with provided .
`ref`
- Quantity and Status Comparison.
- Transient Check:
- Uses default transient types and statuses.
- Find IQ with provided
Example 10 - Update with Provided `type`
and `status`
, Without `ref`
`type`
`status`
`ref`
Batch Payload:
1{
2 "action": "UPSERT",
3 "entityType": "INVENTORY",
4 "entities": [
5 {
6 "status": "ACTIVE",
7 "type": "LAST_ON_HAND",
8 "skuRef": "SKU-010",
9 "locationRef": "LOC-010",
10 "qty": 170,
11 "retailerId": 1
12 }
13 ]
14}
Language: json
Name: Update with Provided type and status, Without ref
Description:
Update with Provided
`type`
`status`
`ref`
Explanation:
- Ref Constructed as:
`"SKU-010:LOC-010:DEFAULT:LAST_ON_HAND"`
- Status Provided:
`"ACTIVE"`
- Process:
- Find IQ with constructed .
`ref`
- Quantity and Status Comparison.
- Transient Check.
- Find IQ with constructed
Example 11 - Update with Provided `type`
(`PURCHASE_ORDER`
) and `status`
, Without `ref`
`type`
`PURCHASE_ORDER`
`status`
`ref`
Batch Payload:
1{
2 "action": "UPSERT",
3 "entityType": "INVENTORY",
4 "entities": [
5 {
6 "status": "ACTIVE",
7 "type": "PURCHASE_ORDER",
8 "skuRef": "SKU-011",
9 "locationRef": "LOC-011",
10 "qty": 190,
11 "retailerId": 1
12 }
13 ]
14}
Language: json
Name: Update with Provided type (PURCHASE_ORDER) and status, Without ref
Description:
Update with Provided
`type`
`PURCHASE_ORDER`
`status`
`ref`
Explanation:
- Ref Constructed as:
`"SKU-011:LOC-011:DEFAULT:PURCHASE_ORDER"`
- Status Provided:
`"ACTIVE"`
- Type Provided:
`"PURCHASE_ORDER"`
- Process:
- Find IQ with constructed .
`ref`
- Quantity and Status Comparison.
- Transient Check.
- Find IQ with constructed
Best Practices
- Include When Possible:
`ref`
- Providing a unique ensures precise identification of the IQ and avoids unnecessary processing.
`ref`
- Providing a unique
- Specify and
`type`
as Needed:`status`
- Explicitly specifying and
`type`
allows the system to target the correct IQ and reflect the intended changes.`status`
- Explicitly specifying
- Use when there are multiple Catalogues:
`catalogueRef`
- Ensure updates are applied to the correct inventory catalogue by providing the appropriate .
`catalogueRef`
- Remember that the catalogue type is also used in the construction.
`ref`
- Ensure you have the workflow ready for different Inventory catalogue types
- Ensure updates are applied to the correct inventory catalogue by providing the appropriate
- Define Custom Transient Types and Statuses:
- Use to customize transient checks based on your business needs.
`conditions.hasRelatedInventoryQuantities`
- Use
- Monitor Processing Using Recommended Tools:
- Utilize the Metrics API and orchestration audit events for real-time monitoring and error detection.
- Use Different Rulesets for Entry Points Based on IQ Types:
- Assign different rulesets as entry points for various IQ types. This enables precise control over behavior and the ruleset flow for each type if you need custom logic to handle IQ-specific input attributes
- Explicitly Bypass Transient Checks if Necessary:
- To bypass transient checks entirely, set:
`"conditions": {`
"hasRelatedInventoryQuantities": []
} - This ensures no default transient IQ types are applied.
- To bypass transient checks entirely, set:
- Include Relevant Fields:
- When submitting batch updates, include ,
`ref`
,`type`
, and attributes if applicable. This ensures the system identifies the right record and processes changes accurately.`status`
- When submitting batch updates, include
- Understand Default Behaviors:
- If is not provided, it defaults to
`type`
.`"LAST_ON_HAND"`
- If is not provided, the system constructs it based on
`ref`
,`skuRef`
, and`locationRef`
.`type`
- If
Frequently Asked Questions (FAQ)
Q1: What happens if I don't provide the new optional fields in my batch updates?
A: The system will default to using standard identification methods based on
`skuRef`
`locationRef`
`type`
`"LAST_ON_HAND"`
Q2: Can I update inventory quantities other than `"LAST_ON_HAND"`
A: Yes, by specifying the
`type`
`"PURCHASE_ORDER", "DELTA", "FUTURE" etc`
Q3: How does the system handle the `ref`
A: If you provide a reference, the system will use it to identify the specific inventory quantity. If the
`ref`
Q4: What should I do if I need to monitor the processing of a specific batch?
A: Since batches are merged during processing, use the Metrics API and orchestration audit events to monitor individual updates and identify any issues.
Q5: How can I bypass transient checks in my updates?
A: To skip transient checks, explicitly set:
`"conditions": {`
"hasRelatedInventoryQuantities": []
}
This prevents the system from applying default transient IQ types during processing.
Q6: Why should I use different rulesets as entry points for IQ types?
A: Assigning different rulesets for various IQ types allows you to control the behavior and flow of rulesets effectively. This approach ensures that each IQ type is processed according to its unique requirements.
Q7: Are there any changes required on my end to start using Batch Pre-Processing?
A: Ensure that your batch updates are formatted correctly and include the new optional fields for better control. Also, adjust your monitoring practices to use the recommended tools.