Automated Stock Valuation Engine
by Abdelrahman Ashraf https://www.linkedin.com/in/abdelrahman-ashraf-ahmed-ahmed/
Odoo
Automated Stock Valuation Engine
Odoo 19 Community Edition — Full perpetual inventory accounting without Enterprise license.
Automatically generates all stock valuation journal entries for purchases, sales, manufacturing, inventory adjustments, and landed costs. Replaces the valuation entries normally only available in the Enterprise edition.
Video Demo
Features
- Purchase Receipt — DR Stock Valuation / CR Stock Input (GR/IR)
- Vendor Bill — GR/IR clearing bridge entry
- Sale Delivery — DR Stock Output / CR Stock Valuation
- Customer Invoice — COGS recognition (DR COGS / CR Stock Output)
- Manufacturing — Raw material consumption (WIP) + finished goods receipt
- Inventory Adjustments — Loss/gain entries with correct directional posting
- Landed Costs — Capitalisation into stock valuation asset
- Purchase/Sale Returns — Automatic reversal entries
- Multi-currency — PO currency conversion to company currency
Accounting Flows
| Operation | DR | CR | Trigger |
|---|---|---|---|
| Purchase Receipt | Stock Valuation | Stock Input / GR-IR | Receipt validation |
| Vendor Bill | Stock Input / GR-IR | Purchase Expense | Bill posting |
| Sale Delivery | Stock Output | Stock Valuation | Delivery validation |
| Customer Invoice | COGS | Stock Output | Invoice posting |
| MFG Raw Material | Production / WIP | Stock Valuation | Consumption |
| MFG Finished Goods | Stock Valuation | Production / WIP | Finished goods receipt |
| Inventory Loss | Inventory Loss | Stock Valuation | Adjustment/Scrap |
| Inventory Gain | Stock Valuation | Inventory Loss | Adjustment |
| Landed Costs | Stock Valuation | LC Clearing | LC validation |
Configuration
⚠ Important: Set your product category's
Costing Method to Periodic (not
Perpetual/Automated) to prevent the standard Odoo engine from interfering
with this module's journal entries. The module handles all valuation
posting itself.
Step-by-step
- Install the module (dependencies: stock, account, purchase, sale_management, mrp, stock_landed_costs)
-
Post-install hook automatically creates 6 accounts with
default codes (adjustable in
hooks.py):
| Account | Default Code | Type |
|---|---|---|
| Stock Valuation | 151000 | Asset (Current) |
| Stock Input (GRNI) | 251000 | Liability (Current) |
| Stock Output (Interim) | 152000 | Asset (Current) |
| Cost of Goods Sold | 600000 | Expense |
| Production / WIP | 153000 | Asset (Current) |
| Inventory Loss | 620000 | Expense |
- Verify accounts in Accounting → Settings → Automated Stock Valuation
- Set per-category overrides (optional) in Inventory → Configuration → Product Categories
- Set costing method to Periodic on each product category
- Done! Entries generate automatically on stock moves, vendor bills, customer invoices, and landed cost validation
Idempotency & Duplicate Protection
Every generated journal entry uses a structured ref to
prevent duplicates:
| Operation | Ref Pattern |
|---|---|
| Purchase Receipt | GR/<picking_name> |
| Sale Delivery | DO/<picking_name> |
| MFG Consumption | MFG-IN/<picking_name> |
| MFG Finished Goods | MFG-OUT/<picking_name> |
| Inventory Adjustment | INV-ADJ/<picking_name> |
| GR/IR Clearing | GRIR/CLR/<bill_name>/L<line_id> |
| COGS | COGS/<invoice_name>/L<line_id> |
| Landed Cost | LC/<lc_name>/L<line_id> |
Dependencies
stock— Inventoryaccount— Accountingpurchase— Purchase managementsale_management— Sales managementmrp— Manufacturingstock_landed_costs— Landed costs
Compatibility
Odoo 19 Community Edition only. Not needed for Enterprise (built-in).
-
account.account.company_idsis Many2many (notcompany_id) -
stock.move.quantityreplacesquantity_done -
product.template.type == 'consu'means storable (was'product'pre-Odoo 16) post_init_hookreceivesenvdirectly
License: LGPL-3
Author: Abdelrahman Ashraf
| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Inventory (stock)
• Invoicing (account) • Manufacturing (mrp) • Purchase (purchase) • Sales (sale_management) • Discuss (mail) |
| Lines of code | 853 |
| Technical Name |
custom_stock_valuation |
| License | LGPL-3 |
| Website | https://www.linkedin.com/in/abdelrahman-ashraf-ahmed-ahmed/ |
Please log in to comment on this module
Error whe tried to install the modul
Odoo Server Error
RPC_ERROR
Odoo Server Error
Occured on localhost:8069 on model ir.module.module on 2026-07-11 17:10:33 GMT
Traceback (most recent call last): File "D:\Program Files\Odoo 19\server\odoo\http.py", line 2329, in _serve_db return service_model.retrying(serve_func, env=self.env) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\Program Files\Odoo 19\server\odoo\service\model.py", line 188, in retrying result = func() ^^^^^^ File "D:\Program Files\Odoo 19\server\odoo\http.py", line 2384, in _serve_ir_http response = self.dispatcher.dispatch(rule.endpoint, args) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\Program Files\Odoo 19\server\odoo\http.py", line 2599, in dispatch result = self.request.registry['ir.http']._dispatch(endpoint) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\Program Files\Odoo 19\server\odoo\addons\base\models\ir_http.py", line 353, in _dispatch result = endpoint(**request.params) ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\Program Files\Odoo 19\server\odoo\http.py", line 838, in route_wrapper result = endpoint(self, *args, **params_ok) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\Program Files\Odoo 19\server\odoo\addons\web\controllers\dataset.py", line 38, in call_button action = call_kw(request.env[model], method, args, kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\Program Files\Odoo 19\server\odoo\service\model.py", line 97, in call_kw result = method(recs, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\Program Files\Odoo 19\server\odoo\addons\base\models\ir_module.py", line 72, in check_and_log return method(self, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\Program Files\Odoo 19\server\odoo\addons\base\models\ir_module.py", line 492, in button_immediate_install return self._button_immediate_function(self.env.registry[self._name].button_install) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\Program Files\Odoo 19\server\odoo\addons\base\models\ir_module.py", line 637, in _button_immediate_function registry = modules.registry.Registry.new(self.env.cr.dbname, update_module=True) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\Program Files\Odoo 19\server\odoo\tools\func.py", line 88, in locked return func(inst, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\Program Files\Odoo 19\server\odoo\orm\registry.py", line 183, in new load_modules( File "D:\Program Files\Odoo 19\server\odoo\modules\loading.py", line 464, in load_modules load_module_graph( File "D:\Program Files\Odoo 19\server\odoo\modules\loading.py", line 217, in load_module_graph load_data(env, idref, 'init', kind='data', package=package) File "D:\Program Files\Odoo 19\server\odoo\modules\loading.py", line 59, in load_data convert_file(env, package.name, filename, idref, mode, noupdate=kind == 'demo') File "D:\Program Files\Odoo 19\server\odoo\tools\convert.py", line 689, in convert_file convert_csv_import(env, module, pathname, fp.read(), idref, mode, noupdate) File "D:\Program Files\Odoo 19\server\odoo\tools\convert.py", line 750, in convert_csv_import result = env[model].with_context(**context).load(fields, datas) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\Program Files\Odoo 19\server\odoo\orm\models.py", line 1047, in load for id, xid, record, info in converted: File "D:\Program Files\Odoo 19\server\odoo\orm\models.py", line 1230, in _convert_records for stream_index, (record, extras) in enumerate(records): File "D:\Program Files\Odoo 19\server\odoo\orm\models.py", line 1113, in _extract_records raise ValueError(f'Invalid field name {fname!r}') ValueError: Invalid field name '# No ACL rules needed — this module only adds fields to existing models' The above server error caused the following client error: RPC_ERROR: Odoo Server Error RPC_ERROR at makeErrorFromResponse (http://localhost:8069/web/assets/6e07740/web.assets_web.min.js:3184:165) at XMLHttpRequest.<anonymous> (http://localhost:8069/web/assets/6e07740/web.assets_web.min.js:3191:13)There are no comments yet!