Oracle Retail18 min readBy Priyanshu Pandey

Order Management: Approval, Revision & Cancellation in RMS

A deep dive into the Oracle RMS Purchase Order lifecycle. Master the data model behind PO approvals (ORDHEAD, ORDLOC), the revision tracking mechanics (REV_NO), and the cascading ledger impact of cancelling lines vs closing orders.

Phase 4 · Purchasing · Oracle RMS Series

Order Management: Approval, Revision & Cancellation

Creating a PO is only the beginning. Moving an order through its lifecycle—handling approvals, tracking buyer revisions, and executing partial cancellations—requires a deep understanding of RMS status triggers. Learn how ORDHEAD states dictate inventory commitments (STOCK_ON_ORDER) and financial liability.

18 min read📅August 8, 2026✍️Priyanshu Pandey📚Oracle RMS Series

Creating a Purchase Order (PO) in Oracle Retail Merchandising System (RMS) sets the stage, but the true complexity of purchasing lies in Order Management. This covers the lifecycle changes a PO undergoes: moving from a draft state into an approved commitment, handling mid-flight buyer revisions, and cleanly cancelling orders when vendors fail to deliver.

This guide explores the database mechanics behind PO approvals, the critical role of order revisions (REV_NO), and how cancellations cascade through the inventory ledger to release STOCK_ON_ORDER.



1. The PO Approval Workflow

When a PO is initially created (either manually via the UI or automatically via Replenishment batches), it typically starts in Worksheet (W) status. In this state, it is essentially a draft. It has no impact on inventory systems, does not trigger EDI transmissions, and represents zero financial liability.

The critical pivot point is the Approval process.

State Transition: W -> A

When a buyer clicks "Approve" (or an automated batch approves the order), RMS executes a massive cascading transaction. The order's status in ORDHEAD.STATUS flips from W (Worksheet) to A (Approved).

⚠️

The Inventory Trigger

The moment a PO becomes Approved, RMS calculates the QTY_ORDERED at the location level and adds this exact amount to the STOCK_ON_ORDER column in ITEM_LOC_SOH. This tells the replenishment engine that inventory is inbound, preventing duplicate orders.

OTB (Open to Buy) Commitment

Approval also triggers a financial commitment against the Open to Buy (OTB) budget. The ORDHEAD.OTB_EDATE (Open to Buy End Date) determines which fiscal period the financial liability falls into. If the budget for that period is exhausted, RMS will block the approval (unless the buyer has explicit override privileges).


2. Revision Tracking Mechanics

Retail is dynamic. After a PO is approved and transmitted to the supplier, circumstances change. The buyer might negotiate a lower unit cost, increase the ordered quantity, or change the delivery dates.

Once a PO is Approved, any structural change to the order must be tracked as a formal Revision.

The Revision Lifecycle

To change an Approved PO, the buyer must transition the order back to Worksheet status. However, it's not a simple rollback.

  1. The PO is placed into Worksheet (W). The ORDHEAD.REV_NO (Revision Number) is incremented by 1.
  2. RMS takes a snapshot of the current approved state and writes it to the Revision History tables (e.g., ORDHEAD_REV, ORDSKU_REV, ORDLOC_REV).
  3. The buyer makes the modifications (e.g., increasing QTY_ORDERED in ORDLOC).
  4. The buyer re-approves the PO. The status returns to Approved (A).

Inventory and Financial Adjustments

When the revised PO is re-approved, RMS calculates the delta. If QTY_ORDERED increased by 50 units, STOCK_ON_ORDER is increased by 50. If the unit cost decreased, the OTB commitment is reduced by the difference.

Querying Order Revisions — Compare current order quantities against previous revisions
sql
SELECT 
    o.order_no,
    o.item,
    o.qty_ordered AS current_qty,
    r.qty_ordered AS previous_qty,
    (o.qty_ordered - r.qty_ordered) AS revision_delta
FROM ordsku o
JOIN ordsku_rev r 
  ON o.order_no = r.order_no 
 AND o.item = r.item
 AND r.rev_no = (SELECT MAX(rev_no) FROM ordsku_rev WHERE order_no = o.order_no);

3. Cancellation and Closure

Not all orders are fulfilled perfectly. Suppliers short-ship, items are discontinued, or shipments are lost. To maintain accurate inventory records, outstanding PO quantities must be managed through Cancellation or Closure.

Order Cancellation (Status 'X')

Cancellation explicitly voids the remaining unreceived quantity on an order.

  • Line Level: A specific item/location (ORDLOC) can be cancelled by updating QTY_CANCELLED. The remaining STOCK_ON_ORDER for that specific line is subtracted from ITEM_LOC_SOH.
  • Header Level: If the entire order is cancelled, ORDHEAD.STATUS becomes X (Cancelled). RMS iterates through all ORDLOC records, sets QTY_CANCELLED equal to the outstanding quantity, and releases all associated STOCK_ON_ORDER and OTB commitments.

Order Closure (Status 'C')

Closure indicates the order has naturally reached the end of its lifecycle. When a PO is fully received (QTY_ORDERED = QTY_RECEIVED), it automatically transitions to Closed (C). However, buyers can manually close a partially received PO (e.g., if the supplier shipped 98 out of 100 units and the buyer decides not to wait for the remaining 2). Manually closing a PO functions identically to cancelling the remaining balance: the unreceived 2 units are marked as cancelled, and STOCK_ON_ORDER is released.

🚨

The Phantom Inventory Trap

A common failure in retail operations is leaving old, partially received POs in Approved status indefinitely. These "zombie POs" hold STOCK_ON_ORDER hostage. The replenishment system sees inbound inventory that will never arrive, causing chronic stockouts in stores. Implementing automated PO closure batches (closing POs X days past their Not After Date) is critical for supply chain health.


4. Core Tables Reference

ORDHEAD_REV
Header-level revision tracking. Stores the snapshot of the order header before the revision began.
ORDSKU_REV
Item-level revision tracking. Stores the snapshot of item costs and totals.
ORDLOC_REV
Location-level revision tracking. Stores the snapshot of ordered quantities per location.
PO_APPROVAL_HIST
Audit trail of which user approved the PO and when.

Revision Table Columns (ORDLOC_REV)

ColumnTypeDescription
ORDER_NO
NUMBER(12)The unique identifier of the purchase order.
ITEM
VARCHAR2(25)The specific item being tracked.
LOCATION
NUMBER(10)The store or warehouse location.
LOC_TYPE
VARCHAR2(1)'S' (Store) or 'W' (Warehouse).
REV_NO
NUMBER(4)The revision number of this snapshot (1, 2, 3...).
QTY_ORDERED
NUMBER(12,4)The quantity ordered at the time of this revision.
UNIT_COST
NUMBER(20,4)The unit cost at the time of this revision.

5. SQL Deep Dives

Identifying Zombie POs

This query identifies Approved POs that are significantly past their "Not After Date" but still holding STOCK_ON_ORDER, suppressing replenishment.

Find overdue POs blocking replenishment
sql
SELECT 
    oh.order_no,
    oh.supplier,
    oh.not_after_date,
    ol.item,
    ol.location,
    (ol.qty_ordered - ol.qty_received - ol.qty_cancelled) AS outstanding_qty,
    ol.unit_cost
FROM ordhead oh
JOIN ordloc ol ON oh.order_no = ol.order_no
WHERE oh.status = 'A'
  AND oh.not_after_date < SYSDATE - 30 -- More than 30 days overdue
  AND (ol.qty_ordered - ol.qty_received - ol.qty_cancelled) > 0
ORDER BY oh.not_after_date ASC;

Cancelling a PO Line via PL/SQL API

When building custom extensions, never update ORDLOC.QTY_CANCELLED directly via SQL. Always use the Oracle-provided API packages to ensure OTB, STOCK_ON_ORDER, and EDI triggers fire correctly.

Cancelling PO lines using the RMS API
sql
DECLARE
    L_error_message VARCHAR2(255);
    L_return_status VARCHAR2(1);
BEGIN
    -- Cancel 50 units of item '10012345' on order 998877 at store 200
    ORDER_SQL.CANCEL_LINE (
        O_error_message => L_error_message,
        O_return_status => L_return_status,
        I_order_no      => 998877,
        I_item          => '10012345',
        I_location      => 200,
        I_loc_type      => 'S',
        I_cancel_qty    => 50
    );

    IF L_return_status != 'S' THEN
        DBMS_OUTPUT.PUT_LINE('Cancellation Failed: ' || L_error_message);
        ROLLBACK;
    ELSE
        DBMS_OUTPUT.PUT_LINE('Line cancelled successfully.');
        COMMIT;
    END IF;
END;
/

6. Common Gotchas

Important Gotchas

  • !

    Approving un-costed items. If an item has a zero unit cost on the PO (due to missing supplier cost setup), approving the PO will commit an OTB value of $0.00. This wreaks havoc on financial reporting and weighted average cost calculations at receipt.

  • !

    Direct SQL updates to QTY_CANCELLED. Running UPDATE ordloc SET qty_cancelled = qty_ordered WHERE order_no = 123; will immediately corrupt your inventory. The PO appears cancelled, but the STOCK_ON_ORDER in ITEM_LOC_SOH remains permanently inflated because the database triggers that cascade the changes were bypassed.

  • !

    Revising POs during EDI transmission. If a buyer forces a PO into Worksheet status while the EDI batch is mid-transmission, the supplier will receive the original EDI file, but RMS will treat the order as unapproved. The supplier will ship the goods, but RMS won't allow them to be received because the PO status isn't Approved.

7. Key Takeaways

Key Takeaways

  • The Approved (A) status is the single most critical pivot in the PO lifecycle. It triggers financial OTB commitments and updates physical inventory tracking via STOCK_ON_ORDER.
  • Order Revisions (REV_NO) provide a strict audit trail. Changes cannot be made silently; the order must be un-approved, modified, and re-approved, tracking deltas in the _REV tables.
  • Zombie POs are silent killers of supply chain efficiency. Partially received, abandoned POs hold STOCK_ON_ORDER hostage and block automatic replenishment. Implement aggressive automated closure policies.
  • Never use direct SQL UPDATE statements to cancel orders. Always leverage ORDER_SQL or RMSSUB_ORDER packages to ensure the cascading ledger updates execute correctly.

8. Official Oracle Resources

For further reading, consult the official Oracle documentation:

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 →