Skip to Content

l10n_bg_stock_account: Restoring picking-level accounting in Odoo 19

A module for real-time inventory accounting, adapted to Odoo 19's new model
April 18, 2026 by
l10n_bg_stock_account: Restoring picking-level accounting in Odoo 19
ТЕРАРОС КОМЕРС ЕООД, Росен Владимиров

Odoo 19 removed picking-level accounting, interim accounts, and Stock Valuation Layers (SVL). This creates serious problems for Bulgarian companies - violation of BG NAS 2, lack of audit trail, and historical cost issues. BL Consulting developed two modules that restore proper behavior, adapted to Odoo 19's new architecture.

Recap: The Problem

In our previous article, we examined the fundamental issue with Odoo 19: removal of stock.valuation.layer, interim accounts (Stock Input/Output), and shifting all accounting to the invoice level.

In brief:

  • Historical cost gets overwritten by the invoice price — violating the historical cost principle (IAS 2 / BG NAS 2).
  • Audit trail disappears — there's no longer a document linking physical movement to accounting entries.
  • Auditors expect Dr. 302 / Cr. 301 at goods receipt, not at invoice posting.

This is blocking for any Bulgarian company subject to audit. Therefore, BL Consulting developed two modules that restore proper behavior — but adapted to Odoo 19's new architecture.

The Solution: Two Modules

1. l10n_bg_stock_account — picking-level accounting

Repository: rosenvladimirov/l10n-bulgaria/tree/19.0/l10n_bg_stock_account
License: LGPL-3 (OCA l10n-bulgaria)
Version: 19.0

The module generates journal entries at picking validation — as expected by Bulgarian accounting legislation.

2. l10n_bg_stock_price_diff — MO chain price difference (Enterprise)

Repository: rosenvladimirov/l10n-bulgaria-ee/tree/19.0/l10n_bg_stock_price_diff
License: OPL-1
Version: 19.0.1.0.1

An extension that solves the secondary problem: what happens when the invoice price differs from the PO price, and the raw material has already been consumed in production with finished goods partially sold.

How l10n_bg_stock_account Works

V19 Adaptation: Direct stock.move Integration

Since Odoo 19 removed stock.valuation.layer, the module has been rewritten to read valuation fields directly from stock.moveremaining_qty, value, and the new valuation fields that replaced SVL.

This is not a simple backport of the old V18 module. The data model is different and the journal item creation logic has been rewritten.

Example: Goods Receipt

Scenario: Vendor delivers 100 pcs of raw material at 10 BGN/pc (PO value 1000 BGN).

Standard Odoo 19 behavior: no entry until invoice posting.

With l10n_bg_stock_account — at picking validation:

Dr. 302 Materials                    1000.00
    Cr. 301 Goods Received Not 
         Invoiced (GRNI)              1000.00
    

After receiving invoice (PO=Invoice):

Dr. 301 GRNI                         1000.00
    Cr. 401 Accounts Payable         1000.00
    

Result: The valuation account is hit at physical receipt, as the auditor expects. The GRNI account serves as a clearing account between receipt and invoice.

How l10n_bg_stock_price_diff Works

This is a separate Enterprise module for the more complex scenario: price differences in manufacturing.

The Algorithm: Recursive MO Chain Traversal

At vendor bill _post(), the module:

  1. Detects differences between PO and Invoice for each line.
  2. Recursively traverses the MO chain — from raw material down to finished goods, with maximum depth of 10 levels.
  3. For each quantity, tracks destiny — whether it's in warehouse, in WIP, in FG, or in COGS.
  4. Creates ONE journal entry with proportional distribution.

Three New Models

Model Role
l10n.bg.price.diff Document with sequence (analog to Price Variance document)
l10n.bg.price.diff.line PO↔Invoice difference for specific receipt move
l10n.bg.price.diff.correction Recursive correction tree with depth and destiny tracking

Why This Matters for Bulgarian Context

BG NAS 2 Compliance

BG NAS 2 (and IAS 2) require stock to be valued in real time, with movements creating accounting entries at physical movement. Without l10n_bg_stock_account, Odoo 19 doesn't meet this requirement.

Auditor Expectations

Every Bulgarian auditor will ask: "Show me the Dr. 302 / Cr. 301 entry from the receipt date." If no such entry exists — questions follow. The module closes this expectation without manual corrections.

Manufacturing Companies

For MRP Design Matrix pilot clients (canning factory, bags, security doors, roller shutters) — all with active production — l10n_bg_stock_price_diff is mandatory. Without it, COGS values will systematically differ from actual costs with every PO↔Invoice difference.

Installation and Configuration

Repositories

Community module:
Repository: rosenvladimirov/l10n-bulgaria (19.0 branch)
Module: l10n_bg_stock_account

Enterprise module:
Repository: rosenvladimirov/l10n-bulgaria-ee (19.0 branch)
Module: l10n_bg_stock_price_diff

Conclusion

Odoo 19 made architectural simplifications that work for simple trading companies but violate basic requirements for manufacturing firms and any business under audit. l10n_bg_stock_account and l10n_bg_stock_price_diff restore correct behavior — not by working against V19's new architecture, but by cleanly integrating with the new stock.move-based valuation model.

If you have a manufacturing company or are under audit — these two modules are not optional.

Rosen Vladimirov · Senior Partner, BL Consulting · Odoo Silver Partner
OCA maintainer l10n-bulgaria · 10+ years of Odoo implementations · bl-consulting.net
Share this post
Tags
l10n_bg_stock_account: връщаме осчетоводяването на пикинга в Odoo 19
Модул за реално-времево складово осчетоводяване, адаптиран към новия модел на Odoo 19