TIP: You can type at any time to perform a new search.

Security findings

Repository
OCA/stock-logistics-workflow · module folder · Try on Runboat
Module version
3.0.0
Category
Stock
Folder size
0.18 MB
License
AGPL-3
Application
No
Auto-installable
No
Website
https://github.com/OCA/stock-logistics-workflow
Last tracking update
2026-10-03 23:56:57
Authors
Odoo Community Association (OCA), Tecnativa
Maintainers
Odoo Community Association (OCA), Tecnativa
Committers
Carlos Dauden, sergio-teruel, LauraCForgeFlow, Weblate, OCA-git-bot, oca-ci
Odoo dependencies
Python dependencies
None
System dependencies
None
Required by
None
Description
Odoo works out the average cost of a product from its stock valuation layers,
and never restates one once it is written: a correction is always booked as a
new layer, dated the day it is made, and everything that was valued in between
keeps the figures it was given. That is a sound rule when the stock valuation is
posted movement by movement, and it is exactly what falls short when it is not.

This module restates the layer instead. When the cost or the quantity of an
already validated valuation layer is corrected, the layer is rewritten as if it
had always held the corrected figures, and the whole chain is replayed from
there on. That is what it buys:

- **A mistake made on a receipt can really be undone.** Somebody types the price
  of a purchase wrong, or enters the quantity in the wrong unit, and it is only
  noticed days later. Correcting the receipt is enough: the layer, the cost of
  the product and everything valued afterwards line up with what actually
  happened.

- **The outgoing moves valued in between are re-priced.** The units that left
  stock while the mistake was in place had been valued with the wrong average.
  They are given the cost they should have had, so the cost of goods sold stops
  carrying the error, and anything that reads the cost of an outgoing layer
  follows along. The margin `sale_margin_sync` writes on the sale order line is
  one such reader.

- **A stock valuation asked for a past date comes out corrected.** The valuation
  report adds up the current value of the layers created up to the requested
  date, so restating them is what makes a valuation as of last month right once
  a mistake made last month is fixed this one. Where the stock valuation is
  posted periodically rather than movement by movement, this is what allows the
  period to be closed with corrected figures instead of dragging the error into
  the next one.

- **The cost of an oversold product or lot doesn't run away.** With no units
  left to average against, Odoo still weighs the incoming cost against the
  negative quantity, and dividing by it returns a price that is not an average
  of anything and that can even be negative, which every outgoing move then
  copies. Here the cost of the receipt becomes the new average, which is also
  the cost Odoo's own negative stock vacuum uses to settle the deficit once
  enough real stock arrives, so both ends agree and the cost is always a price
  that was really paid.

- **Products valuated by lot are supported.** Each lot is replayed as its own
  chain, so a correction only re-prices what left that very lot and the other
  lots keep their own cost. Products valuated as a whole and products valuated
  by lot can coexist, and a product can be switched from one to the other at any
  time.

Code Analysis info_outline

Views touched (0)

No views found for this module.

HTTP endpoints (0)

No HTTP endpoints found for this module.

Models touched (8)

New fields (0)

No new fields.

Public methods (1)
  • write(self, vals)
    Discard the cost core's negative stock vacuum computes for the records still flagged to keep their price. See `product.product._run_fifo_vacuum`, which sets the flag.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • write(self, vals)
    Enabling or disabling the valuation by lot moves every product to a different set of valuation chains, so the layers core writes to empty the stock out and put it back must not trigger a resync in between.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • product_price_update_before_done(self, forced_qty=None)
    Don't let a receipt validated on negative stock wreck the cost price. Core weights the incoming cost against the accumulated quantity even when that quantity is negative, and dividing by a negative denominator returns a price that is not an average of anything: a receipt at a higher cost can lower the average or even turn it negative, and every outgoing layer created afterwards copies that broken cost. It repeats the very same computation per lot for the products valuated by lot, with the very same missing guard. Whoever is oversold, product or lot, takes its cost from `_get_avco_svl_price` instead, which sets the incoming cost as the new average.

New fields (0)

No new fields.

Public methods (1)
  • create(self, vals_list)
    @api.model_create_multi
    Flag the creation so a correction that comes from a brand new line is left to Odoo: there is no previous layer of its own to restate.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (2)
  • action_force_avco_sync(self)
    Replay the valuation chain of the selected layers. Meant for the times a correction could not run on its own, such as layers written while the module was not installed, or a product whose cost drifted for any other reason.
  • write(self, vals)
    Update cost price avco

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…