Phase 3 · Item Management · Oracle RMS Series

Oracle RMS Transformable Items

Some items in retail do not arrive in the same form they are sold. A whole fish becomes fillets. A fabric roll becomes cut panels. A bulk bin of mixed sweets becomes individual bags of sorted varieties. Oracle RMS models this reality through item transformations — a formal mechanism for converting input items into output items with defined ratios, cost allocation, and full stock ledger accountability.

13 min read📅April 24, 2026✍️Priyanshu Pandey📚Oracle RMS Series

What Are Transformable Items?

In Oracle RMS, most items are static — they are received in the same unit they are stocked and sold. A shirt arrives as a shirt, is stocked as a shirt, and is sold as a shirt. The item number never changes from receiving dock to point of sale.

Some items do not work this way. In food retail, a whole salmon is purchased from a supplier but never sold as a whole fish — it is processed into salmon fillets, salmon steaks, and salmon skin-on portions, each with its own item number, its own price, and its own stock position. In textiles, a fabric roll is ordered by the metre and transformed into cut pattern pieces for garment assembly. In confectionery, a bulk sack of mixed sweets is received and repacked into individual 100g bags of sorted varieties.

Oracle RMS handles all of these scenarios through item transformations. A transformation is a formally defined rule that says: consuming a certain quantity of this input item produces certain quantities of these output items, with the input item's cost distributed across the outputs in a specified proportion.

🔄
Transformations are not the same as pack breakdowns

Pack breakdown (covered in the previous article) handles the splitting of a pre-defined pack into its known components — the structure is fixed in PACKSKU. Item transformation is a more powerful mechanism: it handles arbitrary conversion ratios, yield losses (the input quantity consumed may not equal the total output quantities), and full cost reallocation across outputs. The two features overlap in some use cases but are architecturally distinct. See the comparison section at the end of this article.

The Transformation Flag

ITEM_XFORM_IND — The Transformation Flag

The entry point into the transformation system is a single column on ITEM_MASTER: ITEM_XFORM_IND. Setting this to 'Y' on an item marks it as a participant in at least one transformation rule — either as an input item, an output item, or both.

ColumnTypeDescription
ITEM_XFORM_IND
VARCHAR2(1)

Y = this item participates in at least one transformation rule. N = standard item, no transformation logic applies. The flag must be 'Y' on both input and output items.

⚠️
ITEM_XFORM_IND must be 'Y' on both input and output items

Both the item being consumed (the input) and every item being produced (the outputs) must have ITEM_XFORM_IND = 'Y' on their respective ITEM_MASTER rows. If the flag is missing on any participant, the transformation rule cannot be saved and any attempt to process a transformation transaction against that item will fail at validation.

Input and Output Items

Input Items vs Output Items

Every transformation rule has exactly one input item and one or more output items. These roles are defined in the ITEM_TRANSFORM table, not on ITEM_MASTER — a single item can be an input in one transformation and an output in another.

💡
Output items are typically not ordered from suppliers

Since output items are produced internally from the input item, they should generally have ORDERABLE_IND = 'N' on ITEM_MASTER. This prevents replenishment batches from raising purchase orders for items that are never bought directly from a supplier. The only way stock of an output item increases is through a transformation transaction consuming the corresponding input item.

ITEM_TRANSFORM Structure

The ITEM_TRANSFORM Table Structure

Transformation rules are stored across two related tables in Oracle RMS: ITEM_TRANSFORM_HEAD (the header record for the rule) and ITEM_TRANSFORM_DETAIL (one row per output item in the rule). Some RMS versions also use the simpler ITEM_TRANSFORM table structure — check your instance version, as the schema can vary between RMS 13.x, 14.x, and 16.x.

01ITEM_TRANSFORM_HEAD
Transformation rule header

The header record defines the transformation rule itself — which item is consumed, at what base input quantity, and in which location context the rule applies.

ColumnTypeDescription
XFORM_IDPK
NUMBER(10)System-generated primary key for the transformation rule.
FROM_ITEMFK
VARCHAR2(25)The input item — FK → ITEM_MASTER.ITEM. Must have ITEM_XFORM_IND = 'Y'.
FROM_QTY
NUMBER(12,4)The base quantity of the input item consumed per transformation run. The ratio base.
FROM_UOM
VARCHAR2(4)Unit of measure for FROM_QTY — must match or be convertible to the input item's UOM.
LOC
NUMBER(10)Location where this transformation rule applies. NULL = applies at all locations.
LOC_TYPE
VARCHAR2(1)'S' or 'W' — store or warehouse. Required when LOC is populated.
EFFECTIVE_DATE
DATEDate from which this transformation rule is active.
END_DATE
DATEDate after which this transformation rule is no longer active. NULL = no end date.
02ITEM_TRANSFORM_DETAIL
Output item definition — one row per output

One row per output item produced by the transformation rule. The ratio here defines how many units of this output item are produced per FROM_QTY units of the input item consumed.

ColumnTypeDescription
XFORM_IDPKFK
NUMBER(10)FK → ITEM_TRANSFORM_HEAD.XFORM_ID.
TO_ITEMPKFK
VARCHAR2(25)The output item — FK → ITEM_MASTER.ITEM. Must have ITEM_XFORM_IND = 'Y'.
TO_QTY
NUMBER(12,4)Quantity of this output item produced per FROM_QTY units of the input consumed.
TO_UOM
VARCHAR2(4)Unit of measure for TO_QTY — must match or be convertible to the output item's UOM.
COST_ALLOC_PCT
NUMBER(12,4)Percentage of the input item's total cost allocated to this output item. All output rows for a rule must sum to 100.
Transformation Ratios

Transformation Ratios and Yield

The ratio between FROM_QTY and TO_QTY captures the yield of the transformation — how much output you get from a given input quantity. In ideal transformations the input quantity equals the sum of output quantities. In reality, most physical transformations have waste or yield loss, so the sum of all TO_QTY values will be less than FROM_QTY.

03Whole Salmon Example
1 kg input → three output items with yield loss

Transformation rule: 1 kg of Whole Salmon (input) produces:

| Output Item | TO_QTY | TO_UOM | COST_ALLOC_PCT | |---|---|---|---| | Salmon Fillet | 0.45 | KG | 60% | | Salmon Steak | 0.25 | KG | 30% | | Salmon Skin-on Portion | 0.15 | KG | 10% |

Total output: 0.85 kg from 1 kg input — 0.15 kg is yield loss (bones, skin, trim).

The yield loss is implicit — the TO_QTY values in ITEM_TRANSFORM_DETAIL simply do not add up to the FROM_QTY. Oracle RMS does not require them to. The cost allocated to the yield loss is absorbed by the cost allocation percentages across the outputs — there is no separate "waste item" entry unless the retailer explicitly models waste as an output item with a zero or near-zero cost allocation.

📐
Cost allocation percentages must sum to exactly 100

The COST_ALLOC_PCT values across all ITEM_TRANSFORM_DETAIL rows for a given XFORM_ID must sum to exactly 100. Oracle RMS validates this when the transformation rule is saved via the UI. Integration scripts that insert directly to the table must enforce this constraint themselves — the database does not always have a check constraint to catch rounding errors like 99.99 or 100.01.

Cost Allocation

Cost Allocation Across Output Items

When a transformation is processed, the cost of the input item consumed is distributed to the output items according to the COST_ALLOC_PCT values. This is how Oracle RMS maintains correct cost-of-goods accounting when one purchase becomes multiple sellable products.

The calculation is straightforward:

Cost allocated to output item X = (Input quantity consumed × Input item AV_COST) × (COST_ALLOC_PCT for output X ÷ 100)

This allocated cost becomes the new average cost for each output item at that location, blended into the existing ITEM_LOC_SOH.AV_COST using the standard weighted average cost formula.

04Cost Allocation Example
Continuing the salmon example

Suppose 10 kg of Whole Salmon is transformed. The input item's average cost is ₹400/kg.

  • Total input cost consumed: 10 kg × ₹400 = ₹4,000

| Output Item | COST_ALLOC_PCT | Cost Allocated | Units Produced | Implied Cost/Unit | |---|---|---|---|---| | Salmon Fillet (4.5 kg) | 60% | ₹2,400 | 4.5 kg | ₹533.33/kg | | Salmon Steak (2.5 kg) | 30% | ₹1,200 | 2.5 kg | ₹480.00/kg | | Salmon Skin-on (1.5 kg) | 10% | ₹400 | 1.5 kg | ₹266.67/kg |

The allocated costs are then used to update the AV_COST in ITEM_LOC_SOH for each output item at the location where the transformation occurred. If the output items already had existing stock at an existing average cost, the WAC formula blends the new units with the existing position.

⚠️
Wrong COST_ALLOC_PCT values silently distort margin reporting

The cost allocation percentages are the most business-critical configuration in a transformation rule. If the percentages do not reflect the true commercial value split between output items, the average costs assigned to each output will be wrong. A salmon fillet should carry a higher cost than a skin-on portion because it commands a higher retail price and represents a more valuable yield. Retailers who set equal cost allocation across all outputs will see systematically incorrect margins on every output item for as long as those transformations run.

Transformation Workflow

The Transformation Transaction Workflow

A transformation transaction is the operational event that triggers the actual SOH and cost changes. It can be initiated from the RMS back-office or from a store/warehouse system. The workflow is the same regardless of where it originates.

Calendar Rollup Hierarchy
Step 1 — Select transformation ruleITEM_TRANSFORM_HEAD

The operator selects the input item and the applicable transformation rule. RMS validates that the rule is effective (within EFFECTIVE_DATE and END_DATE) and that the input item is ranged at the location with sufficient SOH to support the transformation quantity.

Step 2 — Specify input quantityMultiple of FROM_QTY

The operator enters the quantity of the input item to be transformed. This must be a positive multiple of FROM_QTY — or FROM_QTY itself for a single run. RMS validates that the input item's SOH at the location is ≥ the specified quantity.

Step 3 — Calculate output quantitiesRatio applied automatically

RMS calculates the output quantities automatically from the TO_QTY ratios in ITEM_TRANSFORM_DETAIL. If transforming 5× the base quantity, all output quantities are multiplied by 5. Output quantities are rounded to the output item's precision if they are not whole numbers.

Step 4 — SOH adjustmentITEM_LOC_SOH updated

Input item SOH is reduced by the transformation quantity. Each output item's SOH is increased by its calculated output quantity. Both adjustments post to ITEM_LOC_SOH simultaneously in the same transaction.

Step 5 — Cost allocation and stock ledgerAV_COST recalculated

The input item's cost contribution is calculated and distributed to output items per COST_ALLOC_PCT. Each output item's AV_COST in ITEM_LOC_SOH is recalculated using WAC. Stock ledger entries are created for both the input reduction and each output increase.

Stock Ledger Impact

Stock Ledger Impact

Every transformation transaction writes to the Oracle RMS stock ledger (STKLEDGR), creating a full audit trail of what was consumed and what was produced. This is essential for inventory accounting, shrinkage analysis, and reconciliation.

05Stock Ledger Entries Created
STKLEDGR — one set per transformation

For a single transformation transaction, Oracle RMS creates the following stock ledger entries:

ColumnTypeDescription
Input item reduction
TRAN_CODE = 'XF'One ledger entry reducing the input item's SOH and crediting its cost contribution to the transformation. Reason code identifies it as a transformation-out event.
Output item increases
TRAN_CODE = 'XF'One ledger entry per output item increasing SOH and debiting the allocated cost. Together these entries balance the transformation financially.
Net cost movement
Zero net impactThe total cost credited for the input reduction equals the total cost debited across all output increases (COST_ALLOC_PCT sums to 100). The transformation is cost-neutral to the stock ledger overall.
Transformations are financially self-balancing

Because COST_ALLOC_PCT values must sum to 100%, the total cost removed from the input item's position exactly equals the total cost added to all output items' positions. A transformation never creates or destroys financial value in the stock ledger — it only redistributes cost from one item to others. This makes the stock ledger reconciliation straightforward: transformation entries should always net to zero across all participants.

Transformation vs Pack Breakdown

Transformation vs Pack Breakdown — Key Differences

Both transformations and pack breakdowns convert one item's stock into another item's stock. Developers new to Oracle RMS often ask when to use each. The distinction is architectural and commercial:

RC:OMS · Multi-Channel Order Management
Selling processed or bundled products across multiple channels?

Whether you are processing raw materials into finished goods or selling pre-assembled bundles across Amazon, Flipkart, and your own store, RC:OMS tracks every inventory movement with double-entry accuracy. Every transformation, every channel, one source of truth.

Launch RC:OMS Demo
Quick Reference

Key Tables — Quick Reference

Item Transformation Tables — Oracle RMS
ITEM_MASTER
ITEM_XFORM_IND flag
ITEM_TRANSFORM_HEAD
Transformation rule header
ITEM_TRANSFORM_DETAIL
Output item definition
ITEM_LOC_SOH
SOH updated at transaction
STKLEDGR
Stock ledger audit trail
Practical SQL

Practical SQL Examples

1. All transformation rules for an input item

SQL
-- All transformation rules where a given item is the input
-- Shows what outputs are produced and in what ratio
SELECT h.xform_id,
h.from_item,
im_from.item_desc               input_desc,
h.from_qty,
h.from_uom,
h.loc,
h.loc_type,
h.effective_date,
h.end_date,
d.to_item,
im_to.item_desc                 output_desc,
d.to_qty,
d.to_uom,
d.cost_alloc_pct,
-- Implied yield ratio for this output
ROUND(d.to_qty / h.from_qty, 4) yield_ratio
FROM   item_transform_head   h
JOIN   item_transform_detail d   ON d.xform_id = h.xform_id
JOIN   item_master           im_from ON im_from.item = h.from_item
JOIN   item_master           im_to   ON im_to.item   = d.to_item
WHERE  h.from_item = :v_input_item
AND  (h.end_date IS NULL OR h.end_date > SYSDATE)
ORDER BY h.xform_id, d.to_item;

2. Transformation rules where an item appears as an output

SQL
-- Find which transformation rules produce a given output item
-- Critical check before discontinuing — must handle upstream input items too
SELECT h.xform_id,
h.from_item,
im_from.item_desc               input_desc,
im_from.status                  input_status,
h.from_qty,
d.to_qty,
d.cost_alloc_pct,
h.effective_date,
h.end_date
FROM   item_transform_detail d
JOIN   item_transform_head   h      ON h.xform_id   = d.xform_id
JOIN   item_master           im_from ON im_from.item = h.from_item
WHERE  d.to_item = :v_output_item
AND  (h.end_date IS NULL OR h.end_date > SYSDATE)
ORDER BY h.from_item;

3. Validate cost allocation percentages sum to 100 for all active rules

SQL
-- Data integrity check — transformation rules where COST_ALLOC_PCT != 100
-- A rule that does not sum to 100 will misallocate cost on every transaction
SELECT h.xform_id,
h.from_item,
im.item_desc                    input_desc,
SUM(d.cost_alloc_pct)           total_alloc_pct,
COUNT(d.to_item)                output_count,
CASE
WHEN ABS(SUM(d.cost_alloc_pct) - 100) < 0.01 THEN 'OK'
ELSE 'INVALID — does not sum to 100'
END                             alloc_status
FROM   item_transform_head   h
JOIN   item_transform_detail d   ON d.xform_id = h.xform_id
JOIN   item_master           im  ON im.item     = h.from_item
WHERE  (h.end_date IS NULL OR h.end_date > SYSDATE)
GROUP BY h.xform_id, h.from_item, im.item_desc
HAVING ABS(SUM(d.cost_alloc_pct) - 100) >= 0.01
ORDER BY h.from_item;

4. SOH and cost position across input and output items at a location

SQL

-- Current SOH and average cost for all items in a transformation rule at a location -- Use to monitor transformation pipeline inventory at a specific store or warehouse SELECT 'INPUT' item_role, h.from_item item, im_f.item_desc, soh_f.stock_on_hand, soh_f.av_cost, ROUND(soh_f.stock_on_hand

  • soh_f.av_cost, 2) total_cost_value FROM item_transform_head h JOIN item_master im_f ON im_f.item = h.from_item JOIN item_loc_soh soh_f ON soh_f.item = h.from_item AND soh_f.loc = :v_loc AND soh_f.loc_type = :v_loc_type WHERE h.xform_id = :v_xform_id

UNION ALL

SELECT 'OUTPUT' item_role, d.to_item item, im_t.item_desc, soh_t.stock_on_hand, soh_t.av_cost, ROUND(soh_t.stock_on_hand

  • soh_t.av_cost, 2) total_cost_value FROM item_transform_detail d JOIN item_master im_t ON im_t.item = d.to_item LEFT JOIN item_loc_soh soh_t ON soh_t.item = d.to_item AND soh_t.loc = :v_loc AND soh_t.loc_type = :v_loc_type WHERE d.xform_id = :v_xform_id ORDER BY item_role DESC, item;

5. PL/SQL — validate a transformation rule before processing a transaction

PL/SQL

-- Validate all pre-conditions for processing a transformation at a location -- Call before any programmatic transformation transaction FUNCTION validate_transformation ( p_xform_id IN item_transform_head.xform_id%TYPE, p_loc IN item_transform_head.loc%TYPE, p_loc_type IN item_transform_head.loc_type%TYPE, p_xform_qty IN NUMBER -- multiples of FROM_QTY to transform ) RETURN VARCHAR2 IS l_from_item item_transform_head.from_item%TYPE; l_from_qty item_transform_head.from_qty%TYPE; l_soh item_loc_soh.stock_on_hand%TYPE; l_alloc_sum NUMBER; l_output_cnt PLS_INTEGER; l_end_date item_transform_head.end_date%TYPE; BEGIN -- 1. Rule must exist and be currently effective SELECT from_item, from_qty, end_date INTO l_from_item, l_from_qty, l_end_date FROM item_transform_head WHERE xform_id = p_xform_id AND SYSDATE >= effective_date;

IF l_end_date IS NOT NULL AND l_end_date < SYSDATE THEN RETURN 'RULE_EXPIRED: end_date ' || TO_CHAR(l_end_date, 'YYYY-MM-DD'); END IF;

-- 2. Input item must have sufficient SOH at this location SELECT NVL(stock_on_hand, 0) INTO l_soh FROM item_loc_soh WHERE item = l_from_item AND loc = p_loc AND loc_type = p_loc_type;

IF l_soh < (l_from_qty * p_xform_qty) THEN RETURN 'INSUFFICIENT_SOH: available=' || l_soh || ' required=' || (l_from_qty * p_xform_qty); END IF;

-- 3. Cost allocation must sum to 100 SELECT SUM(cost_alloc_pct), COUNT(to_item) INTO l_alloc_sum, l_output_cnt FROM item_transform_detail WHERE xform_id = p_xform_id;

IF l_output_cnt = 0 THEN RETURN 'NO_OUTPUTS: transformation rule has no output items'; END IF;

IF ABS(l_alloc_sum - 100) >= 0.01 THEN RETURN 'ALLOC_INVALID: cost_alloc_pct sums to ' || l_alloc_sum; END IF;

RETURN 'OK';

EXCEPTION WHEN NO_DATA_FOUND THEN RETURN 'RULE_NOT_FOUND: xform_id=' || p_xform_id || ' not effective or does not exist'; WHEN OTHERS THEN RETURN 'ERROR: ' || SQLERRM; END validate_transformation;

Gotchas

Common Gotchas for Developers

  • !

    ITEM_XFORM_IND = 'N' on either the input or an output item. The flag must be 'Y' on every item that participates in a transformation — both the item being consumed and every item being produced. A transformation rule that references an item with ITEM_XFORM_IND = 'N' cannot be saved via the RMS UI, and a programmatic insert to ITEM_TRANSFORM_DETAIL for such an item will fail at transaction processing time even if the insert itself succeeds.

  • !

    COST_ALLOC_PCT not summing to exactly 100 due to rounding. When entering percentages like 33.33%, 33.33%, 33.34% for three outputs, integration scripts that calculate these values programmatically often introduce floating-point rounding errors that leave the sum at 99.99 or 100.01. Oracle RMS validates this at save time in the UI. Direct inserts to ITEM_TRANSFORM_DETAIL may not be validated until the first transaction is processed — at which point cost allocation produces incorrect results. Always verify the sum before inserting.

  • !

    Setting output items as ORDERABLE_IND = 'Y' when they should never be purchased.

    Output items — salmon fillets, cut panels, repacked bags — are produced through transformation, not purchased from suppliers. Setting ORDERABLE_IND = 'Y' on them allows replenishment to raise purchase orders for items that no supplier actually sells. Always set ORDERABLE_IND = 'N' on output items unless there is a deliberate dual-source strategy where the item can be both produced and purchased.

  • !

    Processing a transformation at a location where output items are not ranged.

    When a transformation transaction increases the SOH of an output item, the system needs an ITEM_LOC_SOH record to credit the inventory to. If the output item is not ranged at the location (ITEM_LOC row missing), the transformation will either fail entirely or post the inventory to a location-level holding account, depending on RMS version configuration. Always ensure all output items are ranged at every location where transformations will be processed.

  • !

    Using the same item as both input and output in the same transformation rule.

    A transformation where the same item appears in both FROM_ITEM and TO_ITEM creates a circular reference — consuming an item to produce itself. This is not a meaningful operation and will produce incorrect SOH and cost results. Oracle RMS may or may not prevent this at the UI level depending on version. Always validate that no item appears on both sides of a transformation rule in integration scripts.

  • !

    Not end-dating expired transformation rules. Active transformation rules with no END_DATE remain permanently available for selection. When product specifications change — a different portioning method, new output items, revised yield percentages — the old rule must be explicitly end-dated before the new rule is created. Without this, both the old and new rules are presented as valid options, and operators may accidentally process transformations against the outdated ratios and cost allocation percentages.

  • !

    Querying only ITEM_TRANSFORM (the older table name) in mixed-version RMS environments.

    Older RMS versions (13.x and earlier) stored transformation rules in a single ITEM_TRANSFORM table rather than the head-detail split of newer versions. If your queries use ITEM_TRANSFORM and get an ORA-00942, the instance uses the newer schema. If you query ITEM_TRANSFORM_HEAD and get ORA-00942, you are on an older version. Always verify the actual table names present in your specific RMS instance before building any transformation-related queries.

Key Takeaways

Key Takeaways
  • ITEM_XFORM_IND = 'Y' must be set on ITEM_MASTER for every item that participates in a transformation — both the input item being consumed and every output item being produced.
  • Transformation rules are defined in ITEM_TRANSFORM_HEAD (input item, base quantity, location scope) and ITEM_TRANSFORM_DETAIL (one row per output with TO_QTY ratio and COST_ALLOC_PCT).
  • Yield loss is implicit — TO_QTY values across all outputs do not need to sum to FROM_QTY. The difference is the waste or trim that the retailer accepts as part of the processing step.
  • COST_ALLOC_PCT values across all ITEM_TRANSFORM_DETAIL rows for a rule must sum to exactly 100. A rule that does not sum to 100 misallocates cost on every transaction it processes.
  • Transformations are financially self-balancing: cost removed from the input item equals the total cost added to all output items. Transformation entries in STKLEDGR always net to zero.
  • Output items should have ORDERABLE_IND = 'N' — they are produced through transformation, not purchased from suppliers. All output items must also be ranged at any location where transformations will be processed.
  • Transformation differs from pack breakdown: transformations support yield loss and explicit cost allocation percentages; pack breakdowns use a fixed component structure in PACKSKU with no yield loss concept.
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 →