With version 19, Odoo made a significant change to how the system accounts for inventory movements. What appears to be a technical simplification actually affects the accuracy of financial reporting for any company operating under National Accounting Standards or International Financial Reporting Standards.
What Changed in Odoo 19
Until version 18, Odoo followed established accounting logic: when goods were physically received into the warehouse, the system automatically created a journal entry. Inventory was recorded in the appropriate stock accounts (e.g. raw materials, finished goods, or merchandise), with the corresponding entry posted to an interim account — essentially a clearing account for deliveries where the vendor invoice had not yet been received.
When the vendor invoice subsequently arrived, this interim account was closed against the accounts payable balance. This ensured full traceability: every physical movement of goods had its own accounting entry, and any differences between the purchase order price and the invoice price were reflected separately and transparently.
In Odoo 19, this logic has been removed. The system no longer creates journal entries when goods are received. Instead, all accounting happens only when the vendor invoice is posted. The interim accounts have been eliminated, and the Stock Valuation Layers that previously preserved the valuation history no longer exist.
Why This Is a Problem
Violation of the Historical Cost Principle
National Accounting Standards (BG NAS 2 "Accounting for Inventories") and International Standards (IAS 2) require inventories to be measured at cost of acquisition at the time of receipt. This is the historical cost principle — goods are recorded in the balance sheet at the value at which they were actually acquired, not at the value from an invoice that may arrive days or weeks later.
When accounting is deferred to invoice posting, the historical cost is effectively bypassed. If the invoice price differs from the price agreed in the purchase order, the system does not reflect this difference as a variance — it simply records the invoice value as if no other price had ever existed.
Missing Audit Trail
Auditors in Bulgaria expect to see a specific journal entry from the date of goods receipt: a debit to inventory accounts and a credit to an interim clearing account. If such an entry is missing, legitimate questions arise about the accuracy of the financial reporting. This is not a theoretical concern — in BL Consulting's practice of over 10 years of audit engagements with clients, this entry is among the first things auditors verify.
The Problem with Delayed Invoices
In practice, vendor invoices do not arrive immediately. Sometimes weeks pass between receiving goods and receiving the invoice. During this period, the goods are physically in the warehouse — they may have already been used in production or sold — yet in the accounting records they simply do not exist. The balance sheet value of inventories does not reflect reality.
The Additional Complication in Manufacturing
The problem deepens for companies with active production. Consider a typical scenario:
A company orders raw material at an agreed price of 10 BGN per unit and receives 100 units into the warehouse. Part of the material — say 70 units — goes into production and becomes finished goods. Of the finished goods, 40 units have already been sold to customers.
A week later, the vendor invoice arrives at 10.50 BGN per unit instead of 10 BGN. The total difference is 50 BGN.
The question is: where should this 50 BGN difference be allocated?
The correct answer, according to accounting standards, is proportional distribution:
- The 30 units still in the warehouse as raw material — adjustment to the raw materials valuation account.
- The 30 units that have become finished goods still in the warehouse — adjustment to the finished goods valuation account.
- The 40 units already sold — adjustment to cost of goods sold.
Standard Odoo behavior (including in V19) posts the entire difference to a single price variance account. This is a crude simplification that does not reflect the actual flow of materials and leads to inaccuracies in product cost, inventory valuation, and ultimately the financial result.
Our Solution
BL Consulting has developed two modules that restore proper accounting behavior, aligned both with Bulgarian standards and with Odoo 19's new architecture.
Goods receipt accounting module — l10n_bg_stock_account
This module restores the creation of journal entries at the moment of warehouse receipt validation. When goods are received, the system automatically debits the appropriate inventory account (302, 303, 304 — depending on the type of goods) at the purchase order value and credits an interim clearing account (301 "Deliveries") — an account that is closed when the vendor invoice is received and posted.
From the moment of physical receipt, the goods are correctly reflected in the balance sheet. When the invoice arrives, the interim account is closed against the accounts payable balance. If there is a price difference between the purchase order and the invoice, it is clearly visible and can be properly processed.
The module is open source (LGPL-3) and available in the repository l10n-bulgaria (branch 19.0).
Manufacturing price difference distribution — l10n_bg_stock_price_diff
The second module addresses the manufacturing problem described above. When a vendor invoice reveals a price difference from the purchase order, the module automatically traces the path of the raw material — whether it is still in the warehouse, whether it has been consumed in production, whether the finished goods have been sold.
Based on this tracing, a single correcting journal entry is created that distributes the difference proportionally: to raw materials valuation if the material has not yet been consumed; to finished goods valuation if it has gone through production; to cost of goods sold if the product has already been shipped.
The algorithm works recursively — tracing chains of manufacturing orders up to 10 levels deep, which covers complex production processes with intermediate semi-finished products.
The module is licensed under OPL-1 and available in the repository l10n-bulgaria-ee (branch 19.0).
Who Needs This
These modules are essential for any Bulgarian company using Odoo 19 that falls into at least one of the following categories:
- Companies subject to audit — auditors expect accounting entries to reflect the physical movements of goods, not just invoices.
- Manufacturing companies — without proper distribution of price differences, production cost is inaccurate.
- Companies with active import operations — delays between goods receipt and invoice can be substantial, and currency and price differences are frequent.
- Any company committed to accurate financial reporting — the standards are clear, and compliance is not optional.
Conclusion
The change in Odoo 19 is motivated by a desire for simplification that works for straightforward trading operations. For the Bulgarian market, however, where National Accounting Standards require real-time inventory accounting, this simplification creates genuine compliance issues.
The modules we offer do not work against Odoo 19's new architecture — they build on top of it, adding the accounting logic necessary for proper reporting under Bulgarian standards. The result is a system where physical goods movements, accounting entries, and invoices are correctly linked and fully traceable.
If you are planning a migration to Odoo 19 or already working with this version, contact us — we will help you ensure accurate inventory accounting from day one.
OCA maintainer l10n-bulgaria · 10+ years of Odoo implementations · bl-consulting.net