Oracle Retail19 min readBy Priyanshu Pandey

WAC (Weighted Average Cost) and Cost Accounting

Understand Weighted Average Cost (WAC) in Oracle RMS. Learn the mathematical formula behind WAC calculations, how ITEM_LOC_SOH.UNIT_COST is updated during receiving, and how Tran Code 70 (Cost Variance) keeps the ledger balanced.

Phase 5 · Inventory Management · Oracle RMS Series

WAC Accounting: The Math Behind Inventory Valuation

If you buy 10 shirts at $5 today, and 10 shirts at $7 tomorrow, what is the cost of the shirt sitting on your shelf? In Oracle RMS Cost Accounting, the answer is $6. Learn the math behind Weighted Average Cost (WAC), how RMS recalculates it upon receipt, and how late invoices cause Cost Variances.

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

Retailers buy the same items from the same suppliers repeatedly. Over time, the cost of manufacturing, raw materials, and shipping fluctuates. If you have a bin of 100 identical widgets, but you bought 50 of them for $1.00 last month and 50 of them for $1.50 this week, how do you value the asset?

Oracle RMS solves this using Weighted Average Cost (WAC). This guide breaks down the math, the database triggers, and how the system prevents financial collapse when negative inventory occurs.



1. The WAC Formula

WAC is tracked at the Item/Location level. The WAC for a t-shirt in the New York store might be $10, while the WAC for the identical t-shirt in the London store is $12 (due to higher landed costs).

The value is stored in ITEM_LOC_SOH.UNIT_COST.

When new inventory is received, RMS blends the incoming cost with the existing cost using this formula:

New WAC = [ (Current SOH * Current WAC) + (Incoming Qty * Incoming Cost) ] / (Current SOH + Incoming Qty)

Example Scenario

  • Current State: You have 10 units in stock. ITEM_LOC_SOH.UNIT_COST is $5.00. (Total Inventory Value = $50.00).
  • The Receipt: You receive 5 new units. The Purchase Order ORDLOC.UNIT_COST is $8.00. (Total Incoming Value = $40.00).

The Calculation: [ (10 * $5.00) + (5 * $8.00) ] / (10 + 5) [ 50 + 40 ] / 15 90 / 15 = $6.00

The new ITEM_LOC_SOH.UNIT_COST becomes $6.00.


2. The Recalculation Trigger

WAC is not calculated in a nightly batch. It is calculated synchronously, in real-time, the exact millisecond the receiving transaction is processed (Tran Code 20).

When a warehouse receives an ASN or a store confirms a delivery, the PL/SQL receiving packages immediately lock the ITEM_LOC_SOH row, perform the WAC math, and update the UNIT_COST.

Any sales (Tran Code 1) processed immediately after that receipt will book their Cost of Goods Sold (COGS) at the newly calculated $6.00 rate.


3. Negative Inventory & WAC Corruption

The WAC formula works perfectly—until STOCK_ON_HAND drops below zero.

If a location has -5 units at $10 WAC, and they receive 5 units at $15... the math breaks. [ (-5 * 10) + (5 * 15) ] / 0 = Divide by Zero Error.

To prevent the database from crashing, RMS implements a strict failsafe: If a receipt causes STOCK_ON_HAND to equal zero or go negative, WAC is NOT recalculated. It simply inherits the incoming PO cost, or remains frozen at the previous value, depending on system options. Negative inventory is the primary cause of WAC corruption in RMS.


4. Cost Variances (Tran Code 70)

What happens if you receive goods at an Estimated Landed Cost of $10, RMS updates the WAC to $10, but three weeks later the actual supplier invoice arrives for $12?

RMS handles this via Actual Landed Cost (ALC) true-ups, writing a TRAN_DATA record with Tran Code 70 (Cost Variance).

  1. RMS calculates that it undervalued the receipt by $2 per unit.
  2. It looks at the current STOCK_ON_HAND.
  3. If the units are still in the building, RMS updates the WAC to reflect the true cost.
  4. If the units have already been sold, RMS writes a financial adjustment (Tran Code 70) directly to the General Ledger to adjust the Cost of Goods Sold (COGS) for the previous fiscal period.

5. Core Tables Reference

ITEM_LOC_SOH
Stores the current UNIT_COST (WAC) for the item at the specific location.
TRAN_DATA
Captures the total cost of receipts (Tran 20) and cost variances (Tran 70).

6. SQL Deep Dives

Monitoring WAC Volatility

If a buyer makes a typo on a PO (entering $1000 instead of $10), the WAC will skyrocket upon receipt. This query finds items where the WAC jumped by more than 50% in a single day.

Detect WAC Spikes
sql
SELECT 
    td.item,
    td.location,
    td.tran_date,
    td.tran_code,
    ils.unit_cost AS current_wac,
    (td.total_cost / td.units) AS receipt_cost,
    ROUND((((td.total_cost / td.units) - ils.unit_cost) / ils.unit_cost) * 100, 2) AS variance_pct
FROM tran_data td
JOIN item_loc_soh ils ON td.item = ils.item AND td.location = ils.loc
WHERE td.tran_code = 20 -- Receipts
  AND td.tran_date = TRUNC(SYSDATE)
  AND td.units > 0
  AND ROUND((((td.total_cost / td.units) - ils.unit_cost) / ils.unit_cost) * 100, 2) > 50;

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