Odoo Inventory Valuation Report Does Not Match the Balance Sheet
Odoo inventory valuation does not match balance sheet
Also searched as
- odoo stock valuation report vs accounting difference
- odoo automated inventory valuation mismatch stock interim account
- odoo inventory valuation negative stock fix
- odoo stock valuation account not balanced with inventory report
Short answer
In Odoo with automated inventory valuation, the stock valuation report should equal the balance of the stock valuation account. Differences nearly always come from manual journal entries to that account, products with manual valuation, costing method changes, landed costs, negative stock, or vendor bills posted at a different price than the receipt.
Applies to: Odoo 15, 16, 17 (stock.valuation.layer based) and the reworked valuation in Odoo 18, Inventory + Accounting with perpetual (automated) valuation
How to reconcile stock valuation to the ledger
- 1Run Inventory > Reporting > Valuation (Stock Valuation) as of the balance sheet date and note the total value. Set the same company and date on the accounting side.
- 2Open Accounting > Reporting > General Ledger or Trial Balance, filter on the Stock Valuation account from the product category, and compare the balance at the same date.
- 3Confirm every product category uses the same Costing Method and Inventory Valuation: Inventory > Configuration > Product Categories. Products on Manual valuation do not post journal entries.
- 4In the General Ledger, filter the stock valuation account for entries whose journal is not Stock Valuation, such as miscellaneous operations. These are manual postings that have no layer behind them.
- 5Check the Stock Input (stock interim received) and Stock Output (interim delivered) accounts. Residual balances there are receipts not yet billed or deliveries not yet invoiced, and not a valuation error.
- 6Search for negative quantity layers: Inventory > Reporting > Valuation filtered by quantity less than 0. Negative stock values at the wrong cost produce differences once restocked.
- 7Use a SQL comparison per product to find which products differ, then trace those moves.
Where the two numbers come from
The Valuation report in Odoo 15 to 17 sums value on stock.valuation.layer records. Each validated receipt, delivery, inventory adjustment or landed cost writes a layer with quantity and value. With automated valuation, each layer also has a linked account.move that posts to the stock valuation account against the stock input, output or expense account.
The balance sheet shows the GL account balance, which includes anything posted to the account, with or without a layer. That is why a manual journal entry correcting inventory shows up on the balance sheet but never on the valuation report, and the two diverge by exactly its value.
Odoo 18 moved to a revised model where valuation is computed from stock moves and the new cost and lot-level valuation, but the reconciliation approach is the same: compare per product value to the GL by product.
-- Valuation layers vs ledger lines by product (Odoo 15-17, adjust company_id)
SELECT t.default_code,
SUM(l.value) AS layer_value,
SUM(l.quantity) AS layer_qty
FROM stock_valuation_layer l
JOIN product_product p ON p.id = l.product_id
JOIN product_template t ON t.id = p.product_tmpl_id
WHERE l.company_id = 1
GROUP BY t.default_code
HAVING SUM(l.value) <> 0
ORDER BY ABS(SUM(l.value)) DESC;The usual suspects, in order of frequency
Manual journal entries to the stock account are number one. Accountants post adjustments directly to the asset account without a stock move. They are visible in the General Ledger by journal. Reverse them and make the correction through an inventory adjustment so a layer is created.
Products on a different valuation setting come second. A category switched from Manual to Automated mid-year leaves earlier moves with no journal entries. Odoo does not backfill them. Accountants typically post one correcting entry as of the changeover date.
Changing the costing method (Standard, Average, FIFO) after moves exist. Changing standard price on a Standard product creates revaluation layers when the category is automated, but historical differences can persist if the change happened before a unit was received or sold.
Landed costs, bills and price differences
Landed costs add layers with value but no quantity, and they post to the stock account against the landed cost expense account. If the landed cost is validated after stock has been sold, part of the value goes to cost of goods sold, not to remaining inventory. This is by design with FIFO and average cost, and it can look like a mismatch if you expect the whole cost to remain in stock.
Bill price versus receipt price differences go to the price difference account for Standard cost products. For average and FIFO, the receipt value is fixed at receipt and the bill does not change it unless you use landed costs or a manual revaluation.
Stock Input balances are often mistaken for a valuation error. They are the offset to receipts not yet billed. Reconcile them with the vendor bills, not the valuation report.
Negative stock and backdated moves
Delivering stock you have not received yet creates a negative layer valued at the current cost. When the receipt arrives later at a different cost, Odoo corrects the difference with a revaluation layer on the next receipt only if costs diverge for average or FIFO. Backdating a move date after the period closed shifts value across periods and breaks reports as of an earlier date.
Use the lock dates under Accounting > Configuration > Settings and the inventory Lock Date in Inventory settings to block backdated moves in closed periods.
Common pitfalls
- !Fixing the difference with a manual journal entry to the stock account, which hides the problem and creates the next mismatch.
- !Comparing valuation at today's date with a balance sheet dated last month-end.
- !Mixing categories on Manual and Automated valuation and reporting only on one total.
- !Treating Stock Input or Output balances as a valuation error.
- !Changing costing method on a category with open moves without a documented revaluation entry.
How an ERP-grounded AI assistant handles this
Reconciling valuation is a lot of grouping and comparing: layers by product, ledger lines by journal, and anything posted outside the stock journal. An assistant grounded in your Odoo database can produce that comparison as a table with the SQL visible, flag products where layer value and GL differ, and list manual entries on the stock account. ERPray runs read-only, so the finance team reviews findings and makes any correcting entries themselves.
Frequently asked questions
Does Odoo require automated valuation to match the balance sheet?
Only automated (perpetual) valuation posts journal entries for each stock move. With Manual valuation, the stock account is updated by manual entries, so the valuation report and the ledger will naturally differ until you post an adjustment.
How do I correct the difference?
First identify its cause. If a manual journal caused it, reverse it. If products lack layers, use inventory adjustments or revaluation in the product form (Inventory Valuation, Update Cost for average cost products) so layers and entries are created consistently.
Why does the report change when I change the date?
The report is computed as of the date on valuation layers, which uses move dates. Backdated validations insert layers into earlier periods, changing prior reports. Lock dates prevent this after period close.
Is the stock valuation account the same for all products?
No. It is set on the product category, with an optional override per category. Several categories can use different accounts, so compare the GL by account and match it to the right categories.
Related
Odoo Manufacturing Order: Components Not Available or Will Not Reserve
An Odoo manufacturing order stays in Confirmed with components marked Not Available when stock.move lines for the raw materials cannot be reserved from the quantity actually sitting in the MO's source location. The usual causes are stock in the wrong location, stock already reserved by another document, lot or tracking mismatches, and a unit of measure difference between the BoM and the product.
How-toOdoo Reordering Rule Not Creating Manufacturing Orders: Causes and Fixes
Odoo creates a manufacturing order from a reordering rule only when the rule's forecast quantity falls below its minimum, the product has the Manufacture route with an active BoM, and the replenishment scheduler actually runs. Check the rule's route and warehouse, the product's forecast, the BoM, and the scheduler cron, in that order.
Error fixFix Odoo AccessError: You Are Not Allowed to Access Records
Odoo raises AccessError when a user's security groups do not grant a CRUD right on a model through ir.model.access.csv, or when an ir.rule record rule filters the specific record out for that user or company. Fix it by adding the user to the group named in the error, editing the model's access rights, or reviewing the record rule's domain under Settings > Technical > Security.
How-toHow to Create a Generic Inquiry in Acumatica
Generic Inquiries (GI) are Acumatica's no-code query builder for joining tables, adding filters, and exposing the result as an inquiry screen, dashboard data source, or API endpoint. Open System > Customization > Generic Inquiry, add your base table, define joins and conditions, then run and save. No SQL or customization project is required.
How-toHow to Void a Check in Sage 100
Sage 100 voids checks through Accounts Payable > Main > Check and Payment Voiding. Select the bank code, choose the check number, and Sage reverses the Cash Disbursements Journal entry and reopens the invoice it paid. A check that already cleared in Bank Reconciliation or falls in a closed period needs an extra step before it can be voided cleanly.
How-toHow to Run Requirements Planning (MRP) in SYSPRO
SYSPRO's MRP engine lives under Planning and Scheduling > Requirements Planning. Set planning parameters per warehouse, run the Requirements Calculation to net demand against supply, then review and release the resulting suggestions as purchase requisitions or work orders. A full regenerative run typically runs on a schedule, with net change runs in between to pick up new activity.
AI for ERPAI for quote-to-cash in manufacturing and job shop ERPs
AI reads incoming RFQs, drafts quotes from your ERP's own cost and pricing history, and flags parts your shop has never quoted before, keeping the estimator in control.
AI for ERPAI for Odoo Manufacturing That Reads Your Own Database, Not a Vendor's Cloud
Add grounded, natural-language AI to Odoo Manufacturing without sending MRP, BoM, or work order data to a public model. On-prem or private cloud, ORM-native.
Stuck on Odoo?
Talk to engineers who work inside Odoo every week, and who build private AI that answers these questions from your own ERP data.