NetSuite · Purchasing · Inventory · 20 October 2026

We ordered 25 dozen and received 300

A purchase order for 25 dozen jars was received as 300 dozen. The vendor bill was correct and the PO showed fully billed. Inventory was overstated by thousands of units, and nobody could say where the difference had gone.

Where did the variance go?

An item purchased by the dozen and stocked by the each. The PO said 25 dozen — 300 jars. The item receipt recorded 300 dozen — 3,600 jars. The vendor billed 300 jars at the right price and the PO closed as fully billed. So the bill was right, the receipt was wrong, and the general ledger had to put the difference somewhere.

It went to received not invoiced. The receipt credited that account for 3,600 jars at cost; the bill debited it for 300. The difference sat there, stranded, along with thousands of phantom jars on the shelf in inventory.

The cause

The receipts came from a custom receiving screen. It looked up the quantity left to receive with SuiteQL, which returns line quantities in the item’s stock unit. It then wrote that number into the receipt line, which is entered in the line’s purchase unit:

// remaining comes back in stock units (eaches): 300
const remaining = row.quantity_remaining;

// ...but the receipt line's unit is the PO line's unit (Dozen)
receipt.setSublistValue({ sublistId: 'item', fieldId: 'quantity',
                          line: i, value: remaining });   // 300 DOZEN

For items bought and stocked in the same unit, the two numbers are identical, which is why it went unnoticed. Only items with a different purchase unit were affected, and the error was exactly the conversion rate — twelve times, in this case.

The fix converts once, explicitly, using the unit conversion rate on the line:

const rate = Number(row.conversion_rate) || 1;    // eaches per purchase unit
const inPurchaseUnits = remaining / rate;          // 300 / 12 = 25

Finding every receipt it touched

One bad receipt usually means others. This finds receipt lines where the transaction unit differs from the item’s stock unit, which is the population the bug could have affected:

SELECT t.tranid, BUILTIN.DF(tl.item) AS item, tl.quantity,
       BUILTIN.DF(tl.units) AS line_unit, u.conversionrate
FROM transactionline tl
JOIN transaction t ON t.id = tl.transaction
JOIN item i ON i.id = tl.item
JOIN unitstypeuom u ON u.internalid = tl.units
WHERE t.type = 'ItemRcpt'
  AND tl.units IS NOT NULL AND tl.units <> i.stockunit

Two more receipts turned up. One was in an open period and was corrected directly. The other was in a closed period and needed an inventory adjustment.

The part a journal entry can’t fix

The adjustment relieved the extra units at the item’s current average cost, not the cost they were received at, which left a small residual in received-not-invoiced. The obvious fix is a journal entry to clear it. That clears the GL and leaves the item’s average cost wrong, so every future sale of that item carries the error into cost of goods.

The right tool was the inventory adjustment worksheet, used to revalue the item: same quantity, corrected total value. That recalculates the average cost and posts the offset that clears the variance in one step. One setting matters: run the worksheet against the last transaction of the day, or it counts the earlier adjustment twice.

The rule worth remembering: a journal entry fixes the general ledger; it never fixes an item’s cost. If the inventory value is wrong, correct it through an inventory transaction so the item record and the ledger move together.

Preventing the next one

Related: receiving a hundred packing lists from one scan, and blanket POs that reconcile.

New England Systems Group

If there's a process everyone works around instead of through, that's where we start.

SuiteScript development and back-office automation for manufacturers, distributors, producers and retailers. Danbury, Connecticut.

hello@nesystemsgroup.com