Oracle RMS Purchase Orders
Purchase Orders are the engine of retail buying in Oracle RMS. From a buyer manually placing a seasonal order to the replenishment engine raising hundreds of automated POs overnight — every order travels through the same three-table structure, the same status lifecycle, and the same approval and transmission pathway. This guide covers all of it.
What Is a Purchase Order in Oracle RMS?
A Purchase Order in Oracle RMS is the formal record of a buying commitment between a retailer and a supplier. It specifies what items are being ordered, in what quantities, at what cost, and for delivery to which locations. Every unit of stock that arrives at a store or warehouse enters the system through a purchase order receipt — there is no other way to introduce new inventory into the RMS stock ledger.
Purchase orders in RMS are created in two fundamentally different ways. Manual POs are created by buyers working in the RMS buying screen — selecting a supplier, adding items, specifying quantities, and setting delivery dates. Automated POs are generated by the replenishment engine, which calculates required quantities based on sales patterns, min/max thresholds, and lead times, then creates POs without buyer intervention subject to the AUTO_APPR_IND configuration on ITEM_LOC.
Both types produce identical records in the same three tables: ORDHEAD, ORDSKU, and ORDLOC. The distinction between manual and automated is carried in the ORDER_TYPE column on ORDHEAD and in workflow attributes — it does not change the fundamental data structure.
There is no mechanism in Oracle RMS to receive stock without a corresponding purchase order. Even inventory adjustments, transfers, and returns use different transaction types. The purchase order is the only pathway for new inventory to enter the system from an external supplier. This is a fundamental design constraint — it means every unit of supplier-sourced stock has a complete audit trail from order to receipt to stock ledger.
The Three-Table PO Structure
Every purchase order in Oracle RMS is represented by three related records that form a parent-child-grandchild hierarchy:
The top-level record. Identifies the supplier, the overall PO status, the currency and exchange rate, payment terms, shipping method, and all header-level dates. Every ORDSKU and ORDLOC row for the order references this via ORDER_NO.
One row per distinct item ordered on the PO. Holds the agreed unit cost for that item on this specific order, the total ordered quantity rolled up from ORDLOC, and item-level attributes like origin country and supplier reference number. A PO with 50 different items has 50 ORDSKU rows.
The most granular level. One row per item per delivery location on the PO. This is where the actual ordered quantity and received quantity live. A PO for 10 items each destined for 20 stores has 200 ORDLOC rows. All inventory movement calculations reference ORDLOC — it is the source of STOCK_ON_ORDER in ITEM_LOC_SOH.
PO Types — Regular, Replenishment, Distribution
The ORDER_TYPE column on ORDHEAD classifies the purpose of the purchase order. This drives workflow routing, approval rules, and how the order is handled in downstream systems.
Created manually by a buyer for planned purchases — seasonal buys, promotional stock, new item introductions, or opportunistic buys outside the automated replenishment cycle. The buyer selects supplier, items, quantities, and delivery dates explicitly. These orders typically go through a full approval workflow before transmission.
Generated by the Oracle RMS replenishment engine based on calculated demand, current stock levels, and supplier lead times. Replenishment POs are the most common PO type in a live RMS environment — they run overnight in batch and can create hundreds of orders per run. Whether they are auto-approved or require buyer review is controlled by AUTO_APPR_IND on ITEM_LOC.
A distribution order moves stock from a warehouse to one or more stores as a pre-distribution — allocating inventory before it arrives at the warehouse rather than through a separate transfer after receipt. The warehouse receives against the distribution order, and the system simultaneously allocates the received stock to the destination stores. Used heavily in fashion and seasonal retail where pre-season allocations need to be committed ahead of delivery.
For consignment stock (where ownership transfers only on sale, not on receipt) and concession arrangements (where a third party sells on the retailer's premises), Oracle RMS uses a modified PO workflow indicated by PURCHASE_TYPE on ORDSKU: 1 = consignment, 2 = concession. The structural tables are the same; the cost accounting and settlement logic differs.
The Status Lifecycle — Worksheet to Closed
Every Oracle RMS purchase order progresses through a defined status lifecycle. Status transitions are governed by business rules that the application enforces — an order cannot jump from Worksheet to Closed, for example, because receiving cannot occur against an unapproved order.
The starting state for all manually created POs. The buyer can add items, change quantities, and modify costs freely. Worksheet POs have no commitment to the supplier. Replenishment-generated POs skip this state if AUTO_APPR_IND = 'Y' — they are created directly in Approved status.
The buyer has completed the PO and submitted it for approval. The order can no longer be freely edited — changes require it to be returned to Worksheet. For orders where AUTO_APPR_IND = 'Y', this state is bypassed automatically.
The PO has been approved by an authorised buyer. From here it can be transmitted to the supplier via EDI, email, or print. Once Approved, ORDLOC quantities contribute to ITEM_LOC_SOH.STOCK_ON_ORDER — the stock is committed and affects replenishment calculations.
At least one ORDLOC line has received some quantity but not the full ordered quantity. The PO remains open for further receipts. STOCK_ON_ORDER in ITEM_LOC_SOH decreases by the received quantity as each receipt is processed.
All ORDLOC lines have been fully received, or the PO was manually closed by a buyer after all viable receipts were completed. Stock on order for all lines drops to zero. The PO is a read-only historical record.
The PO was cancelled before all lines were received. Any quantities already received remain in stock. Outstanding undelivered quantities are removed from STOCK_ON_ORDER. A PO with any receipt quantity cannot be fully cancelled — partial cancellation applies to undelivered lines only.
The moment a PO reaches STATUS = 'A', all ORDLOC.QTY_ORDERED
values for that order are added to ITEM_LOC_SOH.STOCK_ON_ORDER at
each delivery location. Replenishment calculations subtract STOCK_ON_ORDER from
the calculated need before raising new orders. An Approved PO that is never
transmitted or received ties up stock-on-order capacity and suppresses future
replenishment orders — a common cause of understocking when old approved POs
are left open.
ORDHEAD — PO Header Deep Dive
| Column | Type | Description |
|---|---|---|
ORDER_NOPK | NUMBER(10) | System-generated PO number. The primary key referenced by all ORDSKU and ORDLOC rows. |
SUPPLIERFK | NUMBER(10) | FK → SUPS.SUPPLIER. The supplier this order is placed with. |
STATUS | VARCHAR2(1) | W = Worksheet · S = Submitted · A = Approved · I = In Progress · C = Closed · X = Cancelled. |
ORDER_TYPE | VARCHAR2(1) | N/R = Regular · B = Replenishment · D = Distribution. Controls workflow and downstream processing. |
WRITTEN_DATE | DATE | Date the PO was created. Populated at INSERT time. |
ORIG_APPROVAL_DATE | DATE | Date the PO was first approved. Set when STATUS transitions to 'A'. |
NOT_BEFORE_DATE | DATE | Earliest date the supplier should ship. Also called the earliest ship date. |
NOT_AFTER_DATE | DATE | Latest date the supplier should ship. Orders arriving after this date may be subject to penalties. |
OTB_EDATE | DATE | The Open to Buy end date — identifies which OTB period this order's cost commits against. |
CURRENCY_CODE | VARCHAR2(3) | Trading currency of the order. Usually the supplier's default currency from SUPS. |
EXCHANGE_RATE | NUMBER(20,10) | Exchange rate applied to convert PO currency to primary currency at the time of order creation. |
TERMS | VARCHAR2(30) | Payment terms code for this order. Defaults from SUPS.PAYMENT_TERMS but can be overridden per PO. |
SHIP_METHOD | VARCHAR2(30) | Shipping method — AIR, SEA, ROAD, etc. |
IMPORT_IND | VARCHAR2(1) | Y = import order (cross-border). Triggers additional import management and duty calculation workflows. |
DEPTFK | NUMBER(4) | FK → DEPS.DEPT. Department-level association. Relevant for department-level OTB tracking. |
QC_IND | VARCHAR2(1) | Y = this order requires quality control inspection on receipt before stock is posted to sellable SOH. |
COMMENT_DESC | VARCHAR2(4000) | Free-text buyer notes and order comments. Not transmitted to suppliers unless explicitly included in EDI. |
ORDSKU — Item Line Details
| Column | Type | Description |
|---|---|---|
ORDER_NOPKFK | NUMBER(10) | FK → ORDHEAD.ORDER_NO. |
ITEMPKFK | VARCHAR2(25) | FK → ITEM_MASTER.ITEM. Always VARCHAR2 — never cast to NUMBER. |
UNIT_COST | NUMBER(20,4) | Agreed unit cost for this item on this order. Defaults from ITEM_SUPPLIER.UNIT_COST but can be overridden per PO line. |
ORIGIN_COUNTRY_ID | VARCHAR2(3) | Country of origin for this item on this order. Drives duty and landed cost calculations. |
SUPP_PACK_SIZE | NUMBER(12,4) | Outer case pack size as agreed for this order. Defaults from ITEM_SUPPLIER.SUPP_PACK_SIZE. |
INNER_PACK_SIZE | NUMBER(12,4) | Inner pack size for this order. Defaults from ITEM_SUPPLIER.INNER_PACK_SIZE. |
PURCHASE_TYPE | NUMBER(1) | 0 = standard purchase · 1 = consignment · 2 = concession. Controls cost accounting on receipt. |
SUPP_REF_NUM | VARCHAR2(30) | Supplier's reference number for this item — the supplier's own SKU code. Used in EDI and supplier communications. |
COMMENT_DESC | VARCHAR2(4000) | Item-level order notes. Visible to the buyer; may be included in PO transmission depending on EDI configuration. |
ORDLOC — Location-Level Quantities
ORDLOC is the most operationally active of the three PO tables. It holds the quantity ordered and quantity received per item per delivery location, and is the table directly read by receiving processes, replenishment calculations, and stock-on-order reporting.
| Column | Type | Description |
|---|---|---|
ORDER_NOPKFK | NUMBER(10) | FK → ORDHEAD.ORDER_NO. |
ITEMPKFK | VARCHAR2(25) | FK → ITEM_MASTER.ITEM. Part of composite PK with ORDER_NO and LOC. |
LOCPK | NUMBER(10) | Delivery location number — STORE.STORE or WH.WH. Combined with LOC_TYPE to identify the receiving location. |
LOC_TYPEPK | VARCHAR2(1) | 'S' = store · 'W' = warehouse. Always filter on LOC and LOC_TYPE together. |
QTY_ORDERED | NUMBER(12,4) | Quantity ordered for this item at this location. The original committed quantity. |
QTY_RECEIVED | NUMBER(12,4) | Quantity received so far. Updated by each receipt transaction. When QTY_RECEIVED = QTY_ORDERED, this line is fulfilled. |
QTY_CANCELLED | NUMBER(12,4) | Quantity cancelled on this line. QTY_ORDERED - QTY_RECEIVED - QTY_CANCELLED = outstanding quantity. |
UNIT_COST | NUMBER(20,4) | Unit cost at delivery location level. Usually matches ORDSKU.UNIT_COST but can differ for location-specific pricing. |
CANCEL_DATE | DATE | Date this specific line was cancelled. NULL if not cancelled. |
EARLIEST_SHIP_DATE | DATE | Location-level earliest ship date override. NULL if inheriting from ORDHEAD.NOT_BEFORE_DATE. |
LATEST_SHIP_DATE | DATE | Location-level latest ship date override. NULL if inheriting from ORDHEAD.NOT_AFTER_DATE. |
When an ORDLOC row is created for an Approved PO (or when a PO
transitions to Approved status), Oracle RMS adds QTY_ORDERED to
ITEM_LOC_SOH.STOCK_ON_ORDER for the corresponding item-location
combination. Each receipt against the PO reduces QTY_RECEIVED on
ORDLOC and correspondingly reduces STOCK_ON_ORDER. This
keeps the stock-on-order position in ITEM_LOC_SOH always in sync
with the outstanding committed quantity across all open ORDLOC lines.
The Approval and Transmission Workflow
The path from a Worksheet PO to a transmitted order involves distinct steps that Oracle RMS either automates or routes to a buyer queue depending on configuration.
- Buyer creates PO →
STATUS = 'W'(Worksheet). Items, quantities, and costs are entered. - Buyer submits for approval →
STATUS = 'S'. PO is locked from editing and appears in the approver's queue. - Approver reviews and approves →
STATUS = 'A'.ORIG_APPROVAL_DATEis set.STOCK_ON_ORDERis updated across all ORDLOC locations. - PO is transmitted to supplier → via EDI, email, or printed document. The transmission event is recorded but does not change STATUS.
- Supplier acknowledges and ships → no direct RMS status change unless EDI acknowledgement processing is active.
- Stock arrives and is received → STATUS moves to 'I' (first receipt) and eventually 'C' (fully received).
- Replenishment batch calculates need → based on SOH, STOCK_ON_ORDER, min/max thresholds, and lead times.
- PO created directly in Approved status →
STATUS = 'A'set at creation. Worksheet and Submitted states are skipped. - STOCK_ON_ORDER updated immediately at the ORDLOC locations.
- PO transmitted via EDI → automated transmission batch sends the PO to the supplier without buyer intervention.
- Receipt processed on delivery → STATUS transitions through 'I' to 'C'.
When AUTO_APPR_IND = 'N' on ITEM_LOC, replenishment-generated
POs are created with STATUS = 'W' (Worksheet), not 'S' or 'A'. They
appear in the buyer's to-do queue for manual review and approval. If the buyer's
queue is not monitored, these POs sit as Worksheets indefinitely —
STOCK_ON_ORDER is not updated until they reach Approved status, so
replenishment will keep trying to generate new POs for the same items.
Open to Buy — OTB_EDATE and Cost Impact
Oracle RMS integrates with an Open to Buy (OTB) framework that tracks buying commitments against budget periods. The OTB_EDATE column on ORDHEAD identifies which OTB period a purchase order's cost commitment falls within.
When a PO is approved, its total cost (sum of ORDLOC.UNIT_COST × QTY_ORDERED across all lines) is committed against the OTB budget for the OTB_EDATE period in the item's department. This is how buyers track whether they have sufficient budget headroom before approving additional orders.
| Column | Type | Description |
|---|---|---|
OTB_EDATE on ORDHEAD | DATE | The end date of the OTB period this order falls within. Set by the buyer at order creation — usually the planned delivery period end date. |
OTB commitment | On Approval | When STATUS changes to 'A', the PO's total cost is committed against OTB for ORDHEAD.DEPT in the OTB_EDATE period. |
OTB release | On Receipt or Cancellation | When lines are received or cancelled, the committed OTB is released proportionally, freeing budget for future orders in the same period. |
Partial Receipts and the In Progress State
Real-world supplier deliveries are rarely exactly the ordered quantity. Suppliers often deliver in multiple shipments, deliver short due to production issues, or deliver in a different quantity than ordered. Oracle RMS handles this through the In Progress ('I') status and the QTY_RECEIVED column on ORDLOC.
Each receipt transaction against a PO line:
- Increases
ORDLOC.QTY_RECEIVEDby the receipt quantity - Increases
ITEM_LOC_SOH.STOCK_ON_HANDat the receiving location by the receipt quantity - Decreases
ITEM_LOC_SOH.STOCK_ON_ORDERby the receipt quantity - Updates
ITEM_LOC_SOH.AV_COSTusing the weighted average cost formula - Creates stock ledger entries in
STKLEDGRfor the inventory movement
The PO transitions to 'I' (In Progress) on the first partial receipt and remains there until all lines are fully received or the PO is manually closed.
Outstanding quantity per ORDLOC line:
QTY_ORDERED - QTY_RECEIVED - QTY_CANCELLED
When this value reaches zero for all lines on the PO, the PO is eligible for closure. Oracle RMS can auto-close POs when the last receipt brings the outstanding to zero, or buyers can manually close POs with outstanding quantities that the supplier will not deliver.
RC:OMS brings the same double-entry inventory accuracy as Oracle RMS to multi-channel stock management. Every purchase receipt, every channel sale, every stock movement tracked with full audit trail. Built for Indian multi-channel sellers — no overselling, no reconciliation gaps.
Launch RC:OMS Demo →Key Tables — Quick Reference
Practical SQL Examples
1. Full PO summary — header, items, quantities and delivery locations
-- Complete PO view from header through to location quantities
SELECT oh.order_no,
oh.status,
oh.order_type,
s.supp_name,
oh.currency_code,
oh.written_date,
oh.orig_approval_date,
oh.not_before_date,
oh.not_after_date,
os.item,
im.item_desc,
os.unit_cost,
ol.loc,
ol.loc_type,
CASE ol.loc_type
WHEN 'S' THEN st.store_name
WHEN 'W' THEN w.wh_name
END loc_name,
ol.qty_ordered,
ol.qty_received,
ol.qty_cancelled,
ol.qty_ordered
- ol.qty_received
- NVL(ol.qty_cancelled, 0) qty_outstanding,
ROUND(ol.qty_ordered * os.unit_cost, 2) line_cost
FROM ordhead oh
JOIN sups s ON s.supplier = oh.supplier
JOIN ordsku os ON os.order_no = oh.order_no
JOIN item_master im ON im.item = os.item
JOIN ordloc ol ON ol.order_no = os.order_no
AND ol.item = os.item
LEFT JOIN store st ON st.store = ol.loc AND ol.loc_type = 'S'
LEFT JOIN wh w ON w.wh = ol.loc AND ol.loc_type = 'W'
WHERE oh.order_no = :v_order_no
ORDER BY os.item, ol.loc;
2. Open POs by supplier — outstanding stock on order
-- All open Approved and In Progress POs for a supplier
-- Shows total outstanding value and quantity per item
SELECT oh.order_no,
oh.status,
oh.currency_code,
oh.not_before_date,
os.item,
im.item_desc,
SUM(ol.qty_ordered) total_ordered,
SUM(ol.qty_received) total_received,
SUM(ol.qty_ordered
- ol.qty_received
- NVL(ol.qty_cancelled, 0)) total_outstanding,
SUM((ol.qty_ordered
- ol.qty_received
- NVL(ol.qty_cancelled, 0))
- os.unit_cost) outstanding_cost
FROM ordhead oh
JOIN ordsku os ON os.order_no = oh.order_no
JOIN item_master im ON im.item = os.item
JOIN ordloc ol ON ol.order_no = os.order_no
AND ol.item = os.item
WHERE oh.supplier = :v_supplier
AND oh.status IN ('A', 'I')
GROUP BY oh.order_no, oh.status, oh.currency_code,
oh.not_before_date, os.item, im.item_desc
HAVING SUM(ol.qty_ordered
- ol.qty_received
- NVL(ol.qty_cancelled, 0)) > 0
ORDER BY oh.not_before_date, os.item;
3. Approved POs older than lead time — overdue delivery check
-- Approved POs where NOT_AFTER_DATE has passed and no receipt has occurred
-- These represent overdue deliveries that are still holding STOCK_ON_ORDER
SELECT oh.order_no,
oh.written_date,
oh.not_after_date,
SYSDATE - oh.not_after_date days_overdue,
s.supp_name,
s.contact_name,
s.contact_phone,
COUNT(DISTINCT os.item) item_count,
SUM(ol.qty_ordered - NVL(ol.qty_received, 0)
- NVL(ol.qty_cancelled, 0)) total_outstanding_units,
SUM((ol.qty_ordered - NVL(ol.qty_received, 0)
- NVL(ol.qty_cancelled, 0))
- os.unit_cost) outstanding_cost
FROM ordhead oh
JOIN sups s ON s.supplier = oh.supplier
JOIN ordsku os ON os.order_no = oh.order_no
JOIN ordloc ol ON ol.order_no = os.order_no
AND ol.item = os.item
WHERE oh.status IN ('A', 'I')
AND oh.not_after_date < SYSDATE
AND ol.qty_received = 0
GROUP BY oh.order_no, oh.written_date, oh.not_after_date,
s.supp_name, s.contact_name, s.contact_phone
ORDER BY days_overdue DESC;
4. Worksheet POs that AUTO_APPR_IND should have auto-approved — replenishment queue check
-- Replenishment POs sitting in Worksheet status when they should be auto-approved
-- Indicates AUTO_APPR_IND configuration issue or a batch failure
SELECT oh.order_no,
oh.written_date,
oh.supplier,
s.supp_name,
COUNT(DISTINCT os.item) item_count,
MIN(oh.written_date) oldest_po_date
FROM ordhead oh
JOIN sups s ON s.supplier = oh.supplier
JOIN ordsku os ON os.order_no = oh.order_no
WHERE oh.status = 'W'
AND oh.order_type = 'B' -- replenishment-generated
AND oh.written_date < SYSDATE - 1 -- older than 1 day
GROUP BY oh.order_no, oh.written_date, oh.supplier, s.supp_name
ORDER BY oh.written_date;5. PL/SQL — check whether a PO can be cancelled
-- Validate whether a PO is eligible for cancellation
-- Returns 'OK' or a description of the blocking condition
FUNCTION can_cancel_po (
p_order_no IN ordhead.order_no%TYPE
) RETURN VARCHAR2 IS
l_status ordhead.status%TYPE;
l_recv_count PLS_INTEGER;
BEGIN
SELECT status INTO l_status
FROM ordhead
WHERE order_no = p_order_no;
-- Cannot cancel a Closed PO
IF l_status = 'C' THEN
RETURN 'BLOCKED: PO is already Closed';
END IF;
-- Cannot cancel an already-Cancelled PO
IF l_status = 'X' THEN
RETURN 'BLOCKED: PO is already Cancelled';
END IF;
-- If In Progress, check for any received quantities
IF l_status = 'I' THEN
SELECT COUNT(1) INTO l_recv_count
FROM ordloc
WHERE order_no = p_order_no
AND qty_received > 0;
IF l_recv_count > 0 THEN
RETURN 'PARTIAL_CANCEL_ONLY: PO has ' || l_recv_count
|| ' line(s) with receipts — only outstanding lines can be cancelled';
END IF;
END IF;
RETURN 'OK';
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN 'NOT_FOUND: ORDER_NO ' || p_order_no || ' does not exist';
WHEN OTHERS THEN
RETURN 'ERROR: ' || SQLERRM;
END can_cancel_po;
Common Gotchas for Developers
- !
Querying ORDLOC without LOC_TYPE and getting duplicate location results. Store 200 and Warehouse 200 both appear as
LOC = 200inORDLOC. TheLOC_TYPEcolumn is the only discriminator. Filtering byLOCalone in PO queries will return rows for both location types when the numbers collide — silently doubling quantities in aggregated reports. - !
Leaving Approved POs open after the supplier confirms non-delivery.
Approved POs with no receipts continue to hold
STOCK_ON_ORDERinITEM_LOC_SOHindefinitely. The replenishment engine subtracts this stock-on-order from calculated need, so it will not raise replacement orders for items it believes are already on the way. When a supplier confirms they cannot deliver, POs must be explicitly cancelled or closed to release the stock-on-order commitment. - !
Treating ORDSKU.UNIT_COST as the definitive cost for all locations.
ORDLOCalso has aUNIT_COSTcolumn that can differ fromORDSKU.UNIT_COSTwhen location-specific pricing is configured. The receiving process usesORDLOC.UNIT_COSTto calculate the WAC update forITEM_LOC_SOH.AV_COST. Reporting queries that calculate total order value using onlyORDSKU.UNIT_COST × ORDLOC.QTY_ORDEREDmay produce incorrect figures if the two cost columns differ. - !
Creating POs for items not ranged at the delivery location.
Oracle RMS validates on PO approval that the delivery location in
ORDLOChas a correspondingITEM_LOCrecord for the item. If the item is not ranged at that location, the approval will fail. Direct SQL inserts toORDLOCthat bypass this check will create PO lines that cannot be received — the receiving process will fail when it tries to updateITEM_LOC_SOHand finds no SOH record. - !
Using ORDSKU for total order quantities without summing ORDLOC.
The canonical source for ordered and received quantities is
ORDLOC, notORDSKU. Some implementations store a rolled-up total quantity onORDSKUas a convenience column, but it may not be kept perfectly in sync with ORDLOC in all RMS versions. Always sumORDLOC.QTY_ORDEREDaggregated byORDER_NO + ITEMwhen you need the accurate total ordered quantity per item per PO. - !
Not accounting for QTY_CANCELLED when calculating outstanding quantity.
The formula for outstanding quantity on an
ORDLOCline isQTY_ORDERED - QTY_RECEIVED - QTY_CANCELLED. Queries that calculate outstanding as simplyQTY_ORDERED - QTY_RECEIVEDwill overstate outstanding for partially cancelled lines, producing incorrect stock-on-order totals and misleading replenishment calculations. - !
Raising a PO to a supplier with SUP_STATUS = 'I' (Inactive). Oracle RMS blocks PO creation against an inactive supplier through the UI. Integration scripts that create
ORDHEADrecords via direct SQL bypass this check. An inactive supplier's PO will pass insertion but fail when the EDI transmission batch tries to resolve the supplier's communication details — causing a silent transmission failure that leaves the supplier unaware of the order.
Key Takeaways
- ✓Every purchase order in Oracle RMS spans three tables: ORDHEAD (one per PO), ORDSKU (one per item on the PO), and ORDLOC (one per item per delivery location). The outstanding quantity per line is QTY_ORDERED - QTY_RECEIVED - QTY_CANCELLED.
- ✓The PO status lifecycle has six states: Worksheet (W) → Submitted (S) → Approved (A) → In Progress (I) → Closed (C) or Cancelled (X). STOCK_ON_ORDER in ITEM_LOC_SOH is only committed when the PO reaches Approved status.
- ✓Approved POs that are never received continue to hold STOCK_ON_ORDER indefinitely, suppressing future replenishment orders for the same items. Overdue POs must be explicitly cancelled or closed to release their commitment.
- ✓Always filter ORDLOC on both LOC and LOC_TYPE together — Store 200 and Warehouse 200 share the same LOC value; LOC_TYPE is the only discriminator.
- ✓ORDLOC.UNIT_COST drives WAC updates at receipt — not ORDSKU.UNIT_COST. The two can differ when location-specific pricing is configured. Always use ORDLOC.UNIT_COST in receiving cost calculations.
- ✓AUTO_APPR_IND = 'N' on ITEM_LOC creates replenishment POs in Worksheet status, not Approved — they require buyer action before STOCK_ON_ORDER is committed. Unmonitored approval queues are a common cause of stockouts.
- ✓OTB_EDATE on ORDHEAD identifies which Open to Buy period the order's cost commits against. Cost is committed on Approval and released on receipt or cancellation.
