Fatouraty
Inventory9 min read

Inventory costing: the weighted-average rule, landed costs, and batch expiry

A weighted-average cost is not a number Fatouraty stores and looks up. It is recomputed from a running total quantity and a running total value, on purpose — because a stored rate rounds twice, and the second rounding is the one that quietly breaks a balance sheet.

The Fatouraty team

The easiest way to break inventory valuation is to store a "unit cost" as a number in its own right, updated now and then. The problem is that this rounds twice — once computing the rate, once multiplying it by a later quantity — and each of those roundings leaves a small fraction with nowhere to go. Fatouraty keeps inventory pooled rather than priced: a running total quantity and a running total value for each item in each warehouse, with a unit cost derived only for display and never fed back into any later calculation.

The pool: a quantity and a value, not a rate

The pool is keyed by item and warehouse together, not by item alone — the same item genuinely carries a different cost in each warehouse, based on what actually entered that warehouse. On every receipt, quantity and value are added to the pool directly, and the value is a real figure from the purchase bill, not an estimate. On every sale, cost of goods sold is computed as the sold quantity's share of the pool's total value, rounded to the nearest unit away from zero.

One deliberate exception: a sale that would empty the pool exactly or take it below zero is not charged its computed proportional share — it is charged whatever value remains in the pool, in full. The ordinary proportional charge is recomputed from the live balance on every sale, not from a stored rate, which alone prevents most rounding drift; the "last sale takes exactly what's left" rule on top of that guarantees the pool reaches exactly zero every time, regardless of how the rounding fell on the sales before it.

A return does not come back at today's average; it comes back at the exact cost it left at. If a unit sold at a cost of 100 and the average later rose to 200, the return books at 100, not 200 — otherwise returning something that already left generates a profit of 100 out of nothing.

A transfer between warehouses creates or destroys no value

Transferring an item between two warehouses is two linked movements: an exit from the source at its current average cost, and an entry into the destination pinned to that exact same value — so the destination pool honestly re-averages against its own existing stock rather than importing a foreign number. For a batch-tracked item, the exit is split across lots first-expired-first, the same as a sale, and the entering movement carries that same lot id forward, so its trail is not broken by crossing a warehouse.

Backdated entries, and recomputing the cost

Some receipts arrive after their real date, and some corrections aren't discovered for weeks. There are two policies a workspace can choose between: "Block", the default, refuses any movement dated earlier than the pool's most recent one; "Recompute" accepts it and automatically corrects the pool.

Recomputing does not rewrite history. The pool's entire movement history is replayed from scratch under the same rules, and the result is compared with what is actually posted. If they differ, exactly one correction movement and one balanced journal entry are added — never a rewrite of an earlier movement. The ledger stays what it has always been in accounting: an append-only record, with a correction added when one is needed.

Landed costs: a voucher tied to a bill, not a free journal entry

Freight, insurance, customs duty and clearance are part of the real cost of the goods, not a separate expense — and Fatouraty treats them that way through a dedicated voucher, not a journal entry someone builds by hand. The voucher ties to a specific, already-finalized bill, and refuses to run against a draft one, or at a date earlier than that bill's own issue date: cost follows the goods, and cannot predate their arrival.

The charge lines themselves are free-text — freight, insurance, customs duty, or whatever the shipment actually carried — and are spread across that bill's items on one of two bases, chosen per voucher:

Allocation basisSpread in proportion toBest for
By valueEach receipt line's own valueMost shipments — a charge proportional to what the goods are worth
By quantityThe number of units receivedA charge that is per-carton or per-container regardless of value

The split is computed so the shares sum to exactly the original charge, with no leftover fraction. And because some units may already be sold by the time the landed cost is recorded, each pool's share is itself divided by what remains on hand today: the portion for units still in stock is capitalized, raising the pool's average cost, and the portion for units already sold is charged straight to cost of goods sold — it is too late to add it to inventory that is no longer there. The credit side sits in a dedicated clearing account until the freight forwarder's or broker's own bill arrives, so the cost is never counted as both an expense and part of inventory at once.

Batches and expiry dates

For a batch-tracked item, the lot code and expiry date are recorded with every receipt. Receiving a lot code already on file adds to that existing lot rather than creating a parallel one; if a second receipt supplies an expiry date the first one lacked, it fills it in. Two conflicting expiry dates under the same lot code are refused outright — that is a genuine data-entry error worth surfacing, not one worth silently resolving.

A lot does not carry its own separate cost — valuation stays at the item-and-warehouse level exactly as elsewhere, and a lot is a traceability record, not a parallel valuation. Costing each lot independently would, in effect, be first-in-first-out wearing a different name, and running two valuation methods behind one inventory account produces two competing numbers rather than one you can trust.

Issuing follows first-expired-first-out automatically whenever no specific lot is named: the earliest-expiring lot is consumed first, and a lot with no recorded expiry sorts last, since it cannot be shown to be the most urgent. On a sale specifically, that ordering also excludes any lot already expired as of the sale date — expired stock has to be written off, not sold. A sale can still name a specific lot directly instead of leaving the choice to FEFO, though, and doing so bypasses both the ordering and the expiry exclusion together — the safeguard applies to the automatic path, not to a deliberate override of it. Write-offs and transfers go through that same automatic path today with no way to target one lot directly — which suits a write-off well enough, since clearing the oldest or already-expired stock first is usually the point.

Why the month won't close if inventory doesn't tie to the ledger

Before a period or fiscal year can be locked, a tie-out check runs two separate comparisons. First: does the stock subledger's total equal the balance of the inventory account — or accounts, where separate ones exist per warehouse or item — on the general ledger? Second: does the sum of every pool balance equal the sum of every recorded movement? The first catches inventory drifting from the ledger; the second catches a posting path that updated one without the other.

Any mismatch stops the lock entirely, with a message stating the exact two figures rather than just "something is wrong." The same two checks also surface as high-severity findings in the AI auditor before anyone even attempts to close a period — so a break is visible on the dashboard well before it blocks anything.

What this does not do today

Weighted average is the only valuation method available, and it cannot be switched after inventory is activated for a workspace — first-in-first-out is not an option today. Batch tracking covers lot numbers and expiry dates only, not individual per-unit serial numbers. And quantities post in the item's base unit; buying in one unit and selling in another — a carton in, a piece out — needs both transactions entered in that same base unit today rather than an automatic conversion between the two.

Frequently asked questions

What inventory costing method does Fatouraty use?

Weighted average only. A running quantity and value are kept for each item in each warehouse, and a unit cost is derived only for display, never fed back into a later calculation. FIFO is not available today, and the method cannot be switched once inventory is activated.

Can I enter a movement dated before ones I've already posted?

If you choose the "recompute" policy instead of "block", yes — the pool's whole history replays and one correction movement is added if the result differs, without rewriting any earlier movement and without reaching into a period that is already locked.

How are freight and customs duty added to inventory cost?

Through a landed-cost voucher tied to a finalized bill, allocated by value or by quantity across its items. The share for units already sold charges straight to cost of goods sold, and the share for units still on hand is capitalized, raising the pool's average cost.

Does the system pick which batch to sell automatically?

By default, yes — first-expired-first-out, and never selling from stock already expired within that automatic path. A sale can still name a specific lot instead, though, and doing so overrides both the ordering and the expiry exclusion. Write-offs and transfers always go through that same automatic path today, with no option yet to target a specific lot directly.

What stops a period from closing with a broken inventory number?

A tie-out check that compares the stock subledger's total against the inventory account balance on the ledger, and the sum of pool balances against the sum of recorded movements. Any mismatch stops the lock entirely, stating the exact two figures.

Can I buy by the carton and sell by the piece?

Not automatically today. Quantities post in the item's base unit, so enter both the purchase and the sale in that same unit until automatic unit conversion is added.

Read next

All articles

Put this to work on your own books

Compliant e-invoicing, a real double-entry ledger, and tax reporting — in Arabic and English.

Start free