Phase 3 · Item Management · Oracle RMS Series

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.

14 min read📅April 23, 2026✍️Priyanshu Pandey📚Oracle RMS Series

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.

📦
Packs are full ITEM_MASTER citizens

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.

Pack Flags

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:

ColumnTypeDescription
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

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.

01Simple Pack
PACK_IND = 'Y', SIMPLE_PACK_IND = 'Y'

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 unit
  • SELLABLE_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.

💡
Simple packs are also used for supplier case packs

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

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.

02Complex Pack
PACK_IND = 'Y', SIMPLE_PACK_IND = 'N'

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 bundle
  • ORDERABLE_IND = 'N', SELLABLE_IND = 'Y' — assembled in-house from components already in stock, sold as a bundle
⚠️
Component SOH does not automatically decrease when a complex pack is sold

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

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:

03Buyer Pack
Complex pack with style-level components
ColumnTypeDescription
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).

PACKSKU Table

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.

04PACKSKU
Pack component breakdown
ColumnTypeDescription
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.

🔗
Simple packs: exactly one PACKSKU row. Complex packs: one row per distinct component.

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 and Sellable

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.

05ORDERABLE_IND = 'Y', SELLABLE_IND = 'Y'
Ordered and sold as a pack

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.

06ORDERABLE_IND = 'Y', SELLABLE_IND = 'N'
Ordered as pack, sold as components

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.

07ORDERABLE_IND = 'N', SELLABLE_IND = 'Y'
Assembled in-house, sold as a bundle

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

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.

⚠️
Never sum pack SOH and component SOH to get total available units

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

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:

B1Automatic Breakdown at Receiving
Triggered at PO receipt

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.

B2Manual Breakdown in SIM
Store Inventory Management

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.

B3Transformation in RMS
Item Xform — ITEM_XFORM_IND = 'Y'

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 · Multi-Channel Order Management
Selling bundles and multi-packs across Amazon, Flipkart and your own storefront?

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
Quick Reference

Key Tables — Quick Reference

Pack Item Tables — Oracle RMS
ITEM_MASTER
Pack item root record
PACKSKU
Component breakdown
V_PACKSKU_QTY
Component view (use for display)
ITEM_LOC_SOH
Pack SOH (independent)
ITEM_SUPPLIER
Pack supplier & cost
ITEM_LOC
Pack ranging
Practical SQL

Practical SQL Examples

1. List all components of a pack with quantities and component details

SQL
-- 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

SQL
-- 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

SQL

-- 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

SQL
-- 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

PL/SQL

-- 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;

Gotchas

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 in PACKSKU is 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 PACKSKU must 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_LOC records 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 no ITEM_LOC_SOH record 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 PACKSKU so 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 validate PACKSKU.QUANTITY 0 before activating a pack item.

  • !

    Discontinuing a component item without checking which packs use it. When an item is being set to STATUS = 'D' or STATUS = '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_QTY is 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 an ORA-00942 error referencing this view, fall back to querying PACKSKU directly with explicit joins to ITEM_MASTER and ITEM_DESC.

Key Takeaways

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.
RetailCoder
All systems operational
v1.0 Live

RC:OMS

Multi-channel order management with double-entry inventory ledger. Amazon, Flipkart, Shopify, WooCommerce — one source of truth.

Launch demo →
v1.0 Live

RC:Storefront

Self-hosted headless e-commerce. Your server, your data, zero transaction fees. Native RC:OMS inventory sync.

Visit Storefront →
Pipeline

RC:Pulse

AI-powered retail analytics and demand forecasting — built natively on top of your RC:OMS and Storefront data.

Request early access →
Built in India 🇮🇳  ·  Architected by Priyanshu PandeyTalk to an engineer →