Structured items
A structured item is an item that consists of other items — a gift package, a ski package, a meal deal. It is sold as one article, but the stock that moves is the stock of its components.
How it works
The relationship is defined in PnP as an item link of type STRUCTURE, with a quantity per component. STP
reads those links and expands the movement.
Selling one Ski Package consisting of 1 pair of skis and 2 poles produces:
| Transaction | Item | Quantity |
|---|---|---|
| the sale itself | Ski Package | −1 |
| expanded component | Skis | −1 |
| expanded component | Poles | −2 |
Component quantities are multiplied by the sold quantity, and the sign is preserved — so a return of one Ski
Package puts 1 pair of skis and 2 poles back, as Returned stock.
All the transactions from one expansion share a linkIdStructure, so a consumer can tell which component movements
came from which bundle sale. Every transaction also carries isStructuredItem, which is true on the parent.
Components are expanded one level. A component that is itself a structured item is not expanded again.
🛑 The bundle itself must not be stock handled
This is a master-data requirement, and getting it wrong silently double counts stock.
The bundle's own transaction is created alongside its components' — which is correct, because a business needs to see that a Ski Package was sold. But the stock that exists is the components' stock, not the bundle's.
The parent item must be configured with
Stp.StockHandlingType=NoStockHandling.If it is set to
DoStockHandlinginstead, STP moves stock for both the bundle and its components. The components are drawn down correctly, and the bundle is drawn down as though it were a separate physical article — so the same sale is counted twice.
Nothing in STP can detect this: both configurations are internally consistent, and the resulting quantities look plausible. Verify it before onboarding a tenant that uses bundles, and treat it as a checklist item whenever a new structured item is created.
Components need their own master data
Each component is a stock-handled item in its own right, so each one needs:
Stp.StockHandlingType=DoStockHandling- a costing method, if the default FIFO is not wanted — see Cost calculations
- its own purchase price in PnP. A component's cost is its own, never inherited from the bundle. A component with no purchase price produces movements costed at 0.
Read next
- Configuration — the item properties referenced here
- Data sources — how item links reach STP
- Cost calculations — how each component is costed