name: fsl-inventory-management description: "Configure and manage Field Service Lightning inventory: ProductItem (stock at locations), ProductTransfer (stock movement), ProductConsumed (parts used on work orders), ProductRequest/ProductRequestLineItem (replenishment ordering), and ProductItemTransaction (audit trail). NOT for CPQ product catalog management, OCI (Omnichannel Inventory), or B2B Commerce warehouse integration." category: admin salesforce-version: "Spring '25+" well-architected-pillars:
- Reliability
- Operational Excellence triggers:
- "technician cannot see van stock or parts inventory in FSL mobile app"
- "how to track parts consumed on a work order in Field Service"
- "ProductItemTransaction records are being created incorrectly and QuantityOnHand is wrong"
- "how to move stock between warehouse and technician van in Field Service Lightning"
- "ProductConsumed not reducing inventory after work order completion"
- "set up product requests and product transfers for FSL replenishment"
- "how to build cycle count or inventory reconciliation in Field Service" tags:
- field-service
- fsl
- inventory
- product-item
- product-transfer
- product-consumed
- van-stock
- parts-management inputs:
- FSL managed package installed and Field Service enabled in org
- Confirmation of which Location records exist (warehouse, van, depot) and their types
- List of products that technicians carry or consume in the field
- Business rules for replenishment ordering thresholds and approval flows
- Whether mobile technicians require on-device inventory visibility (offline) outputs:
- Configured Location records with Mobile Location flag set for van stock
- ProductItem records representing on-hand stock per location
- ProductTransfer records and workflow for moving stock between locations
- ProductConsumed records attached to Work Orders for parts traceability
- ProductRequest/ProductRequestLineItem records for replenishment ordering
- Verification that ProductItemTransaction audit trail is intact and untouched
- Configuration checklist confirming all FSL inventory objects are wired correctly dependencies: [] version: 1.0.0 author: Pranav Nagrecha updated: 2026-04-10
FSL Inventory Management
This skill activates when a practitioner needs to configure or troubleshoot the Field Service Lightning inventory object model — covering stock locations, stock movement, parts consumption on work orders, replenishment ordering, and the auto-generated audit trail. It does NOT cover CPQ product catalog configuration, OCI (Omnichannel Inventory) for B2B Commerce, or ERP warehouse integration patterns.
Before Starting
Gather this context before working on anything in this domain:
- Confirm the Field Service managed package is installed and Field Service is enabled under Setup > Field Service Settings. The inventory objects (ProductItem, ProductTransfer, ProductRequest, ProductConsumed, ProductItemTransaction) are part of the FSL data model and do not exist without the package.
- Identify all Location record types in use: fixed warehouses, depots, and technician vans. Van locations must have the Mobile Location checkbox enabled or field technicians cannot see their own stock in the FSL mobile app.
- Confirm whether ProductItemTransaction records are being managed manually anywhere — they are auto-generated by the platform and must never be directly created or deleted. Manual DML on these records corrupts QuantityOnHand on the linked ProductItem.
- Understand the replenishment trigger: is it manual (dispatcher creates ProductRequest), threshold-based (custom automation), or driven by work order completion events?
Core Concepts
The Six Core Inventory Objects
The FSL inventory data model has six primary objects. Each has a distinct role and must not be confused with the others.
ProductItem — represents a quantity of a specific Product2 stored at a specific Location. QuantityOnHand is the live count. This is the master stock record. Do not manually update QuantityOnHand — it is maintained by the platform as ProductTransfer and ProductConsumed records are created and updated.
ProductTransfer — records the movement of stock from one Location to another (e.g., warehouse → technician van). QuantityOnHand on the source ProductItem does NOT decrease when the transfer is created. It decreases only when the transfer status is set to Received. This is the single most common source of incorrect inventory counts.
ProductRequest / ProductRequestLineItem — ProductRequest is the replenishment order header (equivalent to a purchase order request). ProductRequestLineItem is the individual line specifying which Product2, what quantity, and which destination Location. These drive the ordering workflow but do not themselves move stock — a ProductTransfer must be created when the order is fulfilled.
ProductConsumed — records which products and quantities were used on a specific Work Order. Creating a ProductConsumed record decrements QuantityOnHand on the linked ProductItem. This is the field service equivalent of "booking out" parts to a job.
ProductItemTransaction — an auto-generated, read-only audit record created by the platform every time QuantityOnHand on a ProductItem changes (via ProductTransfer Received or ProductConsumed). Manual DML against this object is not supported and corrupts the inventory ledger. It cannot be disabled.
ReturnOrder / ReturnOrderLineItem — records stock returned from a technician or customer back to a Location. Creating a ReturnOrderLineItem increments QuantityOnHand on the target ProductItem.
Location Records and Mobile Location Flag
Every ProductItem is linked to a Location record. The Location record type controls what technicians can see:
- Standard locations (warehouses, depots) are visible in the Salesforce UI and accessible via API.
- Mobile Locations are van/truck locations used by field technicians. A Location must have
IsMobile = true(the "Mobile Location" checkbox) to appear in the FSL mobile app inventory view. Without this flag, technicians cannot see or consume parts from that location on the mobile app, even if ProductItem records exist for it.
There is no limit enforced on how many ProductItem records a Location can have, but large product catalogs at a location should be filtered using the FSL mobile app's search rather than pre-loading everything.
QuantityOnHand Is Platform-Managed
QuantityOnHand on ProductItem is a system-managed field. The platform updates it automatically when:
- A ProductTransfer linked to this ProductItem is marked Received (decrements source, increments destination)
- A ProductConsumed is created against a Work Order with this ProductItem as the source
- A ReturnOrderLineItem credits stock back to this ProductItem
Direct field updates to QuantityOnHand via Apex DML, Data Loader, or Flow are not supported. Attempting it either fails validation or produces a divergence between the ledger (ProductItemTransaction records) and the displayed count.
No Native Cycle-Count UI
Salesforce Field Service has no native cycle-count or physical inventory reconciliation user interface. Organizations that require periodic stock counts must build a custom solution — typically a screen Flow, a custom LWC, or an external app — that compares a technician's submitted count against the current QuantityOnHand on each ProductItem, then creates an adjusting ProductTransfer (with a special-purpose "adjustment" location as source or destination) to reconcile the difference.
Common Patterns
Pattern 1: Van Stock Replenishment via ProductRequest and ProductTransfer
When to use: A field technician's van is running low on a part and needs stock transferred from a warehouse.
How it works:
- A dispatcher or the technician creates a ProductRequest record with
DestinationLocationIdset to the technician's van Location andShipToStreet/Citypopulated if needed for shipping logistics. - Add one or more ProductRequestLineItem records specifying
Product2Id,QuantityRequested, andSourceLocationId(the warehouse). - The warehouse fulfills the request by creating a ProductTransfer record linked to the ProductRequestLineItem, with
SourceLocationId = warehouseandDestinationLocationId = van,Quantity = fulfilled amount. - When the stock physically arrives at the van, the ProductTransfer status is set to Received. At this moment,
QuantityOnHanddecrements on the warehouse ProductItem and increments on the van ProductItem.
Why not the alternative: Directly editing QuantityOnHand bypasses the ProductItemTransaction audit trail, violates referential integrity in the inventory ledger, and is unsupported by Salesforce.
Pattern 2: Recording Parts Consumption on a Work Order
When to use: A technician uses a physical part to complete a work order and the inventory must be decremented.
How it works:
- The technician (or dispatcher) creates a ProductConsumed record from the Work Order related list.
- Set
WorkOrderId(orWorkOrderLineItemIdfor WOLI-level tracking),Product2Id,QuantityConsumed, andSourceLocationId(the technician's van ProductItem location). - On save, Salesforce finds the ProductItem for that Product2 + Location combination and decrements
QuantityOnHandbyQuantityConsumed. - A ProductItemTransaction record is auto-generated as an audit entry.
Why not the alternative: Manually creating a ProductTransfer from van to a dummy "consumed" location is an anti-pattern — it generates incorrect transfer records, adds noise to the audit trail, and does not associate the consumption with the Work Order for job cost reporting.
Pattern 3: Custom Cycle Count Reconciliation
When to use: Organization requires periodic physical inventory counts and needs to reconcile against system QuantityOnHand.
How it works:
- Build a Screen Flow or custom LWC that queries ProductItem records for a given Location and displays current
QuantityOnHandalongside a text input for the technician's physical count. - For each line where physical count differs from
QuantityOnHand, calculate the delta. - Create a ProductTransfer record with a dedicated "adjustment" Location (e.g., "Inventory Adjustment Bin") as source or destination to represent the positive or negative adjustment.
- Set the transfer status to Received immediately (or trigger a Flow to do so) to apply the QuantityOnHand correction.
- Optionally create a custom record to log the count date, technician, and discrepancy for audit purposes.
Decision Guidance
| Situation | Recommended Approach | Reason |
|---|---|---|
| Technician cannot see van stock in FSL mobile | Check Location record — enable Mobile Location (IsMobile = true) | Mobile app only shows IsMobile locations |
| QuantityOnHand is incorrect | Inspect ProductItemTransaction audit trail; trace which transfer or consumed record caused divergence | Do not directly edit QuantityOnHand |
| Moving stock from warehouse to van | ProductRequest + ProductRequestLineItem + ProductTransfer (Received) | Maintains full audit trail; triggers correct QuantityOnHand updates |
| Parts used on a job | ProductConsumed linked to WorkOrder + source ProductItem | Decrements stock and associates consumption to job for cost reporting |
| Stock returned from technician | ReturnOrder + ReturnOrderLineItem with destination Location | Increments QuantityOnHand on target ProductItem; maintains ledger |
| Periodic physical inventory reconciliation | Custom Screen Flow or LWC + adjusting ProductTransfer | No native cycle-count UI; ProductTransfer is the only supported adjustment mechanism |
| Investigate who consumed stock and when | Query ProductItemTransaction for the ProductItem | Auto-generated, tamper-evident audit trail |
Recommended Workflow
Step-by-step instructions for configuring FSL inventory management:
- Verify the FSL managed package is installed. Confirm Field Service is enabled under Setup > Field Service Settings. Confirm that ProductItem, ProductTransfer, ProductRequest, ProductConsumed, and ProductItemTransaction objects are present in Object Manager.
- Create or audit all Location records. Each physical stocking point (warehouse, depot, technician van) needs a Location record. Set
IsMobile = trueon every van/truck location so technicians can see their own stock in the FSL mobile app. - Create ProductItem records for each Product2 at each Location where it is stocked. Set an accurate opening
QuantityOnHandusing a ProductTransfer from an "opening balance" source location (not via direct field edit). Confirm a ProductItemTransaction record was auto-created. - Configure ProductRequest and ProductRequestLineItem records (and any approval or notification Flow) for the replenishment workflow. Test end-to-end: create a request, fulfill it with a ProductTransfer, mark it Received, and verify QuantityOnHand updated on both source and destination ProductItems.
- Add ProductConsumed records to the Work Order page layout (or verify they are already on the layout via the FSL managed package). Test: create a ProductConsumed on a work order and confirm QuantityOnHand on the van ProductItem decrements.
- Validate the ProductItemTransaction trail by querying the object for a sample ProductItem and confirming every expected change (opening balance, transfers received, consumed) is represented. If records are missing or show unexpected changes, trace which DML operation caused the divergence.
- If cycle counts are required, design and build the custom reconciliation solution (Screen Flow + adjusting ProductTransfer pattern) and document the reconciliation process for operations teams.
Review Checklist
Run through these before marking work in this area complete:
- All van/truck Location records have
IsMobile = true(Mobile Location checkbox enabled) - ProductItem records exist for every Product2/Location combination that field technicians stock or consume
- Opening QuantityOnHand was set via ProductTransfer (Received), not via direct field edit
- ProductItemTransaction records exist and match expected audit history for all tested ProductItems
- ProductConsumed on Work Orders decrements the correct ProductItem QuantityOnHand
- ProductTransfer QuantityOnHand update fires on Received status, not on creation
- No custom Apex, Flow, or Data Loader jobs are directly writing to QuantityOnHand or ProductItemTransaction
- Replenishment workflow (ProductRequest → ProductTransfer → Received) has been end-to-end tested
- Cycle count process is documented if physical inventory reconciliation is a business requirement
Salesforce-Specific Gotchas
Non-obvious platform behaviors that cause real production problems:
- ProductItemTransaction is Auto-Generated and Must Not Be Touched — Every QuantityOnHand change on a ProductItem creates an auto-generated ProductItemTransaction record. Directly creating, updating, or deleting these records via Apex, Data Loader, or Flow corrupts the inventory ledger. There is no native UI or support mechanism to repair a corrupted transaction history.
- ProductTransfer Received — Not Created — Triggers QuantityOnHand — QuantityOnHand on the source ProductItem does NOT decrease when a ProductTransfer is created. It decreases only when the ProductTransfer status is set to Received. Organizations that log transfers but never mark them Received end up with perpetually incorrect on-hand counts.
- Mobile Location Flag Is Required for Technician Visibility — A Location record without
IsMobile = truedoes not appear in the FSL mobile app inventory experience. Technicians with van stock at a standard location cannot see or consume parts from the mobile app. This setting must be set at Location creation or retroactively updated. - No Native Cycle-Count UI — Field Service Lightning has no built-in screen for recording physical inventory counts or reconciling discrepancies. Any cycle-count or auditing capability must be custom-built (Screen Flow, LWC, or external integration).
- ProductConsumed Source Must Match a Real ProductItem — ProductConsumed requires a valid
SourceProductItemId(or the combo of Product2 + Location that resolves to a ProductItem). If no ProductItem exists for the technician's current van location and the consumed product, the record creation fails. Practitioners who skip creating ProductItems for van locations encounter this failure when technicians try to log parts usage.
Output Artifacts
| Artifact | Description |
|---|---|
| Location records | One per stocking point; vans flagged with IsMobile = true |
| ProductItem records | One per Product2/Location combination representing on-hand stock |
| ProductTransfer records | Movement records for stock between locations; triggers QuantityOnHand on Received |
| ProductRequest / ProductRequestLineItem | Replenishment order header and line items |
| ProductConsumed records | Parts usage linked to Work Orders for cost tracking |
| ProductItemTransaction records | Auto-generated audit trail (read-only; never hand-edited) |
| Cycle-count Flow or LWC | Custom solution for physical inventory reconciliation |
| Configuration checklist | Completed template confirming all FSL inventory objects are wired correctly |
Related Skills
fsl-work-order-management— for configuring the Work Order and Work Order Line Item objects that ProductConsumed records are linked tofsl-mobile-app-setup— for configuring how technicians access inventory and log parts from the FSL mobile appfsl-resource-management— for managing Location records in the context of service territories and technician assignments
Official Sources Used
- Field Service Inventory Management Data Model — https://developer.salesforce.com/docs/atlas.en-us.field_service_dev.meta/field_service_dev/fsl_dev_overview_inventory.htm
- Common Field Service Inventory Tasks — https://help.salesforce.com/s/articleView?id=sf.fs_inventory.htm&type=5
- ProductItem Object Reference — https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_productitem.htm
- ProductTransfer Object Reference — https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_producttransfer.htm
- ProductConsumed Object Reference — https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_productconsumed.htm
- ProductItemTransaction Object Reference — https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_productitemtransaction.htm
- Salesforce Well-Architected Overview — https://architect.salesforce.com/docs/architect/well-architected/guide/overview.html