Oracle RMS Pack Items
Packs are one of the most misunderstood item structures in Oracle RMS. They look like regular items on the surface — their own item number, their own SOH, their own PO lines — but they have a component structure underneath that drives receiving, inventory allocation, and breakdown logic in ways that trip up developers who treat them like simple items.
What Are Pack Items in Oracle RMS?
In Oracle RMS, a pack item is an item that contains one or more component items at defined quantities. The pack has its own item number in ITEM_MASTER, its own stock on hand in ITEM_LOC_SOH, and can appear on purchase orders and transfers just like any regular item. What makes it different is the PACKSKU table — a component breakdown that says what is inside the pack and in what quantity.
Packs exist in retail for three main commercial reasons. First, suppliers often ship in pre-configured multi-unit cases that cannot be broken before receipt — a supplier may only sell a product in cartons of twelve. Second, retailers create bundled selling units — a gift set containing three related products sold together at a single price. Third, buyers consolidate replenishment orders into mixed-item vendor packs to take advantage of minimum order quantities or freight efficiency.
Oracle RMS models all three scenarios with the same underlying mechanism — a pack item record plus component rows in PACKSKU — but with different configurations of SIMPLE_PACK_IND, ORDERABLE_IND, and SELLABLE_IND that determine how the pack behaves operationally.
A pack item is not a special record type stored separately from regular items.
It is a row in ITEM_MASTER with PACK_IND = 'Y'. It has its
own ITEM_DESC, its own ITEM_SUPPLIER record, its own
ITEM_LOC ranging, and its own ITEM_LOC_SOH stock position.
The component breakdown in PACKSKU is additional metadata — it does
not replace the pack's own item identity.
The Pack Flags — PACK_IND and SIMPLE_PACK_IND
Two columns on ITEM_MASTER together determine whether an item is a pack and what kind of pack it is:
| Column | Type | Description |
|---|---|---|
PACK_IND | VARCHAR2(1) | N = regular item (not a pack). Y = this item is a pack of some kind. This is the root flag — if PACK_IND = 'N', no PACKSKU rows should exist. |
SIMPLE_PACK_IND | VARCHAR2(1) | Only relevant when PACK_IND = 'Y'. Y = simple pack — all units in the pack are the same component item. N = complex pack — the pack contains different component items. NULL or irrelevant when PACK_IND = 'N'. |
These two flags in combination produce three meaningful states:
Simple Packs — Same Component, Multiple Units
A simple pack is the most common pack type in Oracle RMS. It represents a pre-defined multi-unit grouping of a single sellable item — typically a supplier-defined carton or consumer multi-pack.
The pack item has its own item number (e.g. 'WATER-6PK') and the component item is the individual unit (e.g. 'WATER-500ML'). The PACKSKU table has exactly one row linking these two, with a QUANTITY of 6.
Common configurations:
ORDERABLE_IND = 'Y'— the pack is ordered from the supplier as a unitSELLABLE_IND = 'Y'— the pack can be sold to customers as-is (e.g. a multi-pack)SELLABLE_IND = 'N'— the pack is received as a unit but broken down before selling
When a simple pack is received against a purchase order, the pack's own SOH increases by the receipt quantity. If the pack is configured for breakdown at receiving (via item transformation), the component's SOH increases and the pack's SOH is reduced accordingly.
Retailers frequently create simple packs to model the supplier's minimum
orderable case quantity. If a supplier only ships bottled water in cartons of
24, a simple pack item with QUANTITY = 24 on PACKSKU
ensures that replenishment orders are raised in multiples of 24 units. The
pack is received as a case and immediately broken down into individual units
for store stock — the pack SOH never accumulates long-term.
Complex Packs — Mixed Components
A complex pack contains two or more different component items at specified quantities. Each component has its own ITEM_MASTER row and its own SOH tracking. The pack itself also has its own SOH. These two layers of inventory exist simultaneously and independently.
Example — Holiday Gift Set:
| Component | Item | Qty in Pack | |---|---|---| | Perfume 50ml | PERF-50ML | 1 | | Moisturiser 100ml | MOIS-100ML | 1 | | Lip Balm | LIP-BLSM | 2 |
The gift set pack item (e.g. 'GIFTSET-HOLIDAY') has three rows in PACKSKU, one per component. When the gift set is ordered on a PO and received, the pack's SOH increases. The individual component items' SOH does not change at receipt — it only changes if the pack is later broken down.
Common configurations:
ORDERABLE_IND = 'Y',SELLABLE_IND = 'Y'— ordered and sold as a bundleORDERABLE_IND = 'N',SELLABLE_IND = 'Y'— assembled in-house from components already in stock, sold as a bundle
When a complex pack is sold at the POS or reduced via a sales audit transaction, only the pack's own SOH decreases. The individual component items' SOH remains unchanged unless a pack breakdown transaction is explicitly processed. Inventory queries that sum component SOH without accounting for pack relationships will overstate the available component units if pack SOH is positive.
Buyer Packs — Vendor Pre-Packs
A buyer pack (sometimes called a vendor pack or pre-pack) is a specific sub-type of pack used in fashion and apparel retail. It is a supplier-defined assortment of the same style item across multiple sizes or colours — shipped as a single unit at a single cost.
A classic buyer pack example: a buyer orders a pre-pack of a polo shirt that contains 2 units of size S, 3 units of size M, 3 units of size L, and 2 units of size XL — all in the same colour. The supplier ships this as one "pack" of 10 units. The buyer's PO is raised against the pack item, not the individual SKUs.
In RMS terms, a buyer pack is structurally a complex pack (PACK_IND = 'Y', SIMPLE_PACK_IND = 'N') where all the component items are child SKUs of the same parent style. What distinguishes it commercially is:
| Column | Type | Description |
|---|---|---|
PACK_IND | VARCHAR2(1) | Y — this is a pack item |
SIMPLE_PACK_IND | VARCHAR2(1) | N — components are different SKUs (even though they share a parent style) |
ORDERABLE_IND | VARCHAR2(1) | Y — the pack is ordered from the supplier as a single unit at the pack cost |
SELLABLE_IND | VARCHAR2(1) | Usually N — the pack is for ordering/receiving only; individual SKUs are sold |
BUYER_PACK_IND | VARCHAR2(1) | Y — explicitly marks this as a buyer/vendor pre-pack in some RMS versions |
When a buyer pack is received, the pack SOH increases momentarily. The receiving process then immediately triggers a breakdown — each component SKU's SOH increases by its quantity from PACKSKU, and the pack SOH is reduced back to zero. This breakdown may be automatic (configured at the item or location level) or manual (requiring an explicit breakdown transaction in SIM or RMS).
The PACKSKU Table — Component Structure
The PACKSKU table is the structural backbone of every pack item. It defines what is inside a pack and in what quantity. Without at least one row here for a pack item, the pack has no defined contents — it is an empty shell that will fail receiving validation.
| Column | Type | Description |
|---|---|---|
PACK_NOPKFK | VARCHAR2(25) | FK → ITEM_MASTER.ITEM. The pack item's item number. Always VARCHAR2 — never cast to NUMBER. |
ITEMPKFK | VARCHAR2(25) | FK → ITEM_MASTER.ITEM. The component item's item number. For a simple pack, this is the single component. For complex packs, one row per distinct component. |
QUANTITY | NUMBER(12,4) | The number of this component item that is in one unit of the pack. Must be greater than zero. |
UOM | VARCHAR2(4) | Unit of measure for the QUANTITY. Usually matches the component item's UNIT_OF_MEASURE. |
Oracle RMS also ships the view V_PACKSKU_QTY which joins PACKSKU to ITEM_MASTER and ITEM_DESC for the component details. For display queries, always prefer the view — it is guaranteed to stay consistent across RMS versions.
For a simple pack the constraint is enforced commercially — there should be
exactly one PACKSKU row with PACK_NO = :pack_item. For
complex packs, the number of rows equals the number of distinct component
items. A complex pack with three components has three PACKSKU rows.
Always validate PACKSKU row count against expected component count
when creating packs via integration.
ORDERABLE_IND and SELLABLE_IND
These two indicators on ITEM_MASTER control how a pack participates in the supply chain. They are not pack-specific — they exist on all item types — but their combination has particularly important meaning for packs.
The pack can be placed on a purchase order AND sold to customers as a unit. This configuration is used for consumer multi-packs (e.g. a 3-for-2 bundle, a promotional twin-pack) that are ordered from the supplier and sold in the same pack format at the till.
The pack is ordered from the supplier as a unit but must be broken down before selling. This is the most common buyer pack and simple pack configuration. The pack appears on POs and receiving documents, but once received it is broken into its components and the individual items are what appear on till transactions.
The pack cannot be ordered from a supplier — it is assembled in-store or in the warehouse from individually-stocked component items. When a store sells this pack, the pack's SOH decreases. The component items are consumed from their own SOH separately via a pack creation (assembly) transaction. Gift sets assembled from shelf stock are the classic example.
Pack SOH vs Component SOH
This is the concept that causes the most inventory calculation errors when developers are new to RMS pack items. The pack item and its component items each maintain independent, separate stock on hand positions in ITEM_LOC_SOH. They do not automatically stay in sync.
If a location has 10 units of pack SOH (each pack containing 3 components) and 5 units of loose component SOH, the total available component units is NOT 35. The 10 packs represent 30 component units that are locked in pack format and require a breakdown transaction before they are available as loose units. Only add pack SOH × pack quantity to component SOH if you are specifically calculating theoretical availability including packed stock — and label it clearly as such.
Pack Breakdown — When Packs Are Opened
Pack breakdown is the transaction that converts pack stock into component stock. It reduces the pack's SOH by the number of packs being broken and increases each component item's SOH by the corresponding quantity from PACKSKU.
In Oracle RMS, pack breakdown can occur in three contexts:
If a pack item is configured with automatic breakdown (controlled by a receiving indicator on the item or the location), the breakdown occurs as part of the receiving process in the store or warehouse. The PO is received against the pack item number, the pack SOH briefly increases, then the breakdown immediately fires — increasing component SOH and zeroing the pack SOH.
This is the standard configuration for buyer packs and supplier case packs where the retailer never intends to sell or transfer the pack as a unit.
In configurations where breakdown is not automatic, store staff use Oracle Retail Store Inventory Management (SIM) to process the breakdown transaction manually. This applies to scenarios where the store may want to hold some packs intact (for display or promotional purposes) and break down only a portion.
For items flagged with ITEM_XFORM_IND = 'Y' on ITEM_MASTER, Oracle RMS supports a formal item transformation workflow. A transformation record defines the input item (the pack), the output items (the components), and the transformation ratios. This is more complex than a simple breakdown and is typically used for items that undergo processing — for example, a roll of fabric that is cut into individual garment panels.
RC:OMS handles multi-unit pack logic across all your channels — the same double-entry inventory accuracy that Oracle RMS brings to enterprise retail, sized for growing Indian sellers. Every pack receipt, every breakdown, every channel sale tracked with a full audit trail.
Launch RC:OMS Demo →Key Tables — Quick Reference
Practical SQL Examples
1. List all components of a pack with quantities and component details
-- Full component breakdown for a pack item
-- Use V_PACKSKU_QTY view for description joins (preferred over direct PACKSKU)
SELECT ps.pack_no,
im_pack.item_desc pack_desc,
im_pack.simple_pack_ind,
ps.item component_item,
im_comp.item_desc component_desc,
ps.quantity,
ps.uom,
im_comp.unit_of_measure component_uom,
im_comp.status component_status,
-- Implied total units in one pack
ps.quantity units_per_pack
FROM packsku ps
JOIN item_master im_pack ON im_pack.item = ps.pack_no
JOIN item_master im_comp ON im_comp.item = ps.item
WHERE ps.pack_no = :v_pack_item
ORDER BY ps.item;2. All packs that contain a specific component item
-- Find every pack that uses a given item as a component
-- Useful when discontinuing an item — must also handle all packs containing it
SELECT ps.pack_no,
im_pack.item_desc pack_desc,
im_pack.pack_ind,
im_pack.simple_pack_ind,
im_pack.orderable_ind,
im_pack.sellable_ind,
im_pack.status pack_status,
ps.quantity qty_in_pack
FROM packsku ps
JOIN item_master im_pack ON im_pack.item = ps.pack_no
WHERE ps.item = :v_component_item
ORDER BY im_pack.status, im_pack.item_desc;3. Pack SOH vs component SOH — theoretical availability comparison
-- Compare pack SOH vs loose component SOH at a location
-- Shows theoretical total availability (packs × qty + loose units)
SELECT ps.item component_item,
im_comp.item_desc component_desc,
-- Loose component SOH at this location
NVL(soh_comp.stock_on_hand, 0) loose_component_soh,
-- Pack SOH and implied component units locked in packs
ps.pack_no,
NVL(soh_pack.stock_on_hand, 0) pack_soh,
ps.quantity qty_per_pack,
NVL(soh_pack.stock_on_hand, 0)
- ps.quantity units_locked_in_packs,
-- Total theoretical (do NOT use for operational decisions without breakdown)
NVL(soh_comp.stock_on_hand, 0)
- NVL(soh_pack.stock_on_hand, 0)
- ps.quantity theoretical_total
FROM packsku ps
JOIN item_master im_comp ON im_comp.item = ps.item
-- Component SOH at the target location
LEFT JOIN item_loc_soh soh_comp ON soh_comp.item = ps.item
AND soh_comp.loc = :v_loc
AND soh_comp.loc_type = :v_loc_type
-- Pack SOH at the target location
LEFT JOIN item_loc_soh soh_pack ON soh_pack.item = ps.pack_no
AND soh_pack.loc = :v_loc
AND soh_pack.loc_type = :v_loc_type
WHERE ps.pack_no = :v_pack_item
ORDER BY ps.item;
4. Packs with missing PACKSKU rows — data integrity check
-- Pack items in ITEM_MASTER that have no component rows in PACKSKU
-- These are empty shells that will fail receiving and breakdown validation
SELECT im.item,
im.item_desc,
im.pack_ind,
im.simple_pack_ind,
im.orderable_ind,
im.sellable_ind,
im.status,
im.dept,
dp.dept_name
FROM item_master im
JOIN deps dp ON dp.dept = im.dept
WHERE im.pack_ind = 'Y'
AND NOT EXISTS (
SELECT 1
FROM packsku ps
WHERE ps.pack_no = im.item
)
ORDER BY im.status, im.dept, im.item_desc;5. PL/SQL — validate pack structure before activation
-- Validate a pack item has a complete and consistent PACKSKU structure
-- Returns an error message string, or 'OK' if all checks pass
FUNCTION validate_pack_structure (
p_pack_item IN item_master.item%TYPE
) RETURN VARCHAR2 IS
l_pack_ind item_master.pack_ind%TYPE;
l_simple_pack_ind item_master.simple_pack_ind%TYPE;
l_component_count PLS_INTEGER;
l_zero_qty_count PLS_INTEGER;
l_invalid_comp PLS_INTEGER;
BEGIN
-- 1. Confirm item is flagged as a pack
SELECT pack_ind, simple_pack_ind
INTO l_pack_ind, l_simple_pack_ind
FROM item_master
WHERE item = p_pack_item;
IF l_pack_ind != 'Y' THEN
RETURN 'NOT_A_PACK: PACK_IND is not Y for item ' || p_pack_item;
END IF;
-- 2. Must have at least one PACKSKU row
SELECT COUNT(1) INTO l_component_count
FROM packsku WHERE pack_no = p_pack_item;
IF l_component_count = 0 THEN
RETURN 'NO_COMPONENTS: PACKSKU has no rows for pack ' || p_pack_item;
END IF;
-- 3. Simple pack must have exactly one component row
IF l_simple_pack_ind = 'Y' AND l_component_count > 1 THEN
RETURN 'SIMPLE_PACK_MULTI_COMP: Simple pack has '
|| l_component_count || ' components — must be 1';
END IF;
-- 4. No zero or negative quantities
SELECT COUNT(1) INTO l_zero_qty_count
FROM packsku
WHERE pack_no = p_pack_item
AND 0>=quantity;
IF l_zero_qty_count > 0 THEN
RETURN 'ZERO_QTY: ' || l_zero_qty_count
|| ' component(s) have zero or negative quantity';
END IF;
-- 5. All component items must be Active and not themselves packs
SELECT COUNT(1) INTO l_invalid_comp
FROM packsku ps
JOIN item_master im ON im.item = ps.item
WHERE ps.pack_no = p_pack_item
AND (im.status != 'A' OR im.pack_ind = 'Y');
IF l_invalid_comp > 0 THEN
RETURN 'INVALID_COMPONENTS: ' || l_invalid_comp
|| ' component(s) are inactive or are themselves packs';
END IF;
RETURN 'OK';
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN 'ITEM_NOT_FOUND: ' || p_pack_item || ' not in ITEM_MASTER';
WHEN OTHERS THEN
RETURN 'ERROR: ' || SQLERRM;
END validate_pack_structure;
Common Gotchas for Developers
- !
Summing pack SOH and component SOH to get total units. Pack SOH and component SOH are independent positions. A pack of 6 bottles with 10 units of pack SOH represents 60 bottles locked in pack format — not 10. Adding pack SOH directly to the component's loose SOH without multiplying by the pack quantity produces an understated total. Multiplying by quantity and adding to loose SOH gives a theoretical total — but it is only operationally available after a breakdown transaction.
- !
Creating a pack item without any PACKSKU rows. A
PACK_IND = 'Y'item with no rows inPACKSKUis an empty shell. It can be ranged and may even be activated without error depending on the RMS version. But when a purchase order receipt tries to process a breakdown, or when a replenishment calculation tries to evaluate the pack cost vs component cost, it will find no component structure and either throw an error or produce a zero result silently. - !
Using a pack item as a component of another pack. Oracle RMS does not support nested packs — a pack item inside another pack. Components referenced in
PACKSKUmust be regular items (PACK_IND = 'N'). Attempting to reference a pack as a component will either fail at the application validation layer or produce receiving and breakdown logic that cannot resolve the nested structure. - !
Ranging the pack but not ranging the components (or vice versa).
For breakdown to work at a location, both the pack and its component items must have
ITEM_LOCrecords at that location. A pack ranged to Store 100 whose component items are not ranged to Store 100 cannot have a breakdown processed at that store — the system has noITEM_LOC_SOHrecord to credit the component inventory to. Always range pack and components together. - !
Setting QUANTITY = 0 on a PACKSKU row. A zero-quantity component is structurally invalid. The row exists in
PACKSKUso the pack appears to have a component, but any calculation that uses the quantity — breakdown, cost calculation, theoretical availability — produces a zero result for that component. This is usually a data migration error. Always validatePACKSKU.QUANTITY 0before activating a pack item. - !
Discontinuing a component item without checking which packs use it. When an item is being set to
STATUS = 'D'orSTATUS = 'I', any pack that contains it as a component is affected. If the component becomes unavailable, the pack cannot be properly received or broken down. Always run the "all packs containing a component" query (SQL example 2 above) before inactivating or deleting any item that might be a pack component. - !
Querying V_PACKSKU_QTY and expecting it to exist in all RMS versions. The view
V_PACKSKU_QTYis available in most standard RMS installations but is a database view, not a base table. In some customised environments or older versions, this view may have been dropped or altered. If you get anORA-00942error referencing this view, fall back to queryingPACKSKUdirectly with explicit joins toITEM_MASTERandITEM_DESC.
Key Takeaways
- ✓Pack items are full ITEM_MASTER citizens — their own item number, SOH, supplier record, and ranging. PACK_IND = 'Y' is the root flag. SIMPLE_PACK_IND = 'Y' means one component; 'N' means mixed components.
- ✓The PACKSKU table defines the component structure — one row per distinct component with its quantity in the pack. Simple packs have exactly one PACKSKU row. Complex and buyer packs have one row per distinct component.
- ✓Pack SOH and component SOH are completely independent positions in ITEM_LOC_SOH. They do not automatically sync. Receiving a pack increases pack SOH only — not component SOH. Breakdown is an explicit transaction.
- ✓Never sum pack SOH and loose component SOH without multiplying pack SOH by the PACKSKU quantity first. And never use that theoretical total as an operational quantity without confirming that breakdown has occurred.
- ✓Both the pack item and all its components must be ranged to a location (have ITEM_LOC rows) before breakdown can be processed at that location.
- ✓Components of a pack must be regular items (PACK_IND = 'N'). Nested packs — a pack inside another pack — are not supported by Oracle RMS.
- ✓Before discontinuing any item, check whether it is a component in any pack using the reverse PACKSKU lookup. Inactivating a component without handling the packs that contain it causes receiving and breakdown failures.
