Skip to main content
iVentureTeam

replenishment_graph_widget

The saw-tooth stock curve on a reordering rule, drawn against its minimum and maximum lines. New in Odoo 19, and it replaced a widget that showed history instead of a forecast.

Siddharth JambukiyaSiddharth JambukiyaOdoo Techno-Functional Consultant
August 27, 2026Updated September 2, 20266 min read
Technical namereplenishment_graph_widget
Field typeschar
Viewsform
Modulestock, the Inventory app
Used in core1 occurrence, the replenishment information dialog in stock
VersionsOdoo 20.0, Odoo 19.0
No-code setupNo. The chart payload has to be computed server side
Alternativeslead_days_widget, dashboard_graph, picking_type_dashboard_graph, forecast_widget

What the replenishment graph does

A reordering rule is two numbers, a minimum and a maximum, and the behavior they produce is a saw tooth: stock falls to the minimum, an order arrives, stock jumps to the maximum, and the cycle repeats. Explaining that from two numbers is hard; showing it is easy.

This widget draws that picture. It takes a JSON payload computed by the server and renders a chart with three lines: a horizontal maximum, a horizontal minimum, and the stock curve between them. The part of the curve that is a projection rather than a record is drawn dashed.

Around the chart, the same payload supplies the figures the dialog prints: quantity on hand, daily demand, average stock, ordering period, lead time and the unit of measure. All of that is decided in Python; the widget only renders.

What this means for your team

Reordering parameters are usually set once and then argued about. The curve is what turns that argument into a conversation, because everyone can see what a given minimum and maximum actually produce: how often you would order, how much stock you would carry on average, and how close to zero the trough gets.

The projection matters as much as the history. Buyers do not need to know what stock did last quarter so much as what the current parameters imply, which is why Odoo 19 replaced the older history widget with this forecast-shaped one. If your team learned the old panel, that change is worth pointing out during an upgrade.

The chart is deliberately not interactive. No tooltips, no legend, no zoom. It is there to make a shape obvious, and the precise numbers are printed beside it rather than hidden behind a hover.

Supported options in Odoo 19

There is nothing to configure. Like its sibling in the same file, it uses a shared JSON base that provides no options and no extractor, and declares a single supported type. The table below therefore lists the payload keys the chart reads, which are the real contract. Read from json_widget.js, Odoo 19.0.

OptionTypeWhat it does
x_axis_valskey in the JSON payloadThe category labels for the x axis. Its last value also decides where the curve starts being drawn dashed.(since Odoo 19.0)
max_line_valskey in the JSON payloadPoints for the horizontal maximum line.(since Odoo 19.0)
min_line_valskey in the JSON payloadPoints for the horizontal minimum line.(since Odoo 19.0)
curve_line_valskey in the JSON payloadPoints for the stock curve itself, dashed beyond the last recorded x value.(since Odoo 19.0)
product_min_qtykey in the JSON payloadInjected into the y axis tick list and printed beside the chart. Also sets the lower axis bound, padded ten percent.(since Odoo 19.0)
product_max_qtykey in the JSON payloadInjected into the y axis tick list and printed beside the chart. Also sets the upper axis bound, padded ten percent.(since Odoo 19.0)
qty_on_handkey in the JSON payloadPrinted beside the chart. Not used by the chart itself.(since Odoo 19.0)
daily_demandkey in the JSON payloadPrinted beside the chart as the consumption rate the curve assumes.(since Odoo 19.0)
average_stockkey in the JSON payloadPrinted beside the chart. The average the current parameters imply.(since Odoo 19.0)
ordering_periodkey in the JSON payloadPrinted beside the chart. How often the rule would order.(since Odoo 19.0)
lead_timekey in the JSON payloadPrinted beside the chart. The delay before a replenishment arrives.(since Odoo 19.0)
product_uom_namekey in the JSON payloadPrinted with the quantities when the user belongs to the unit of measure group, which the widget resolves at startup.(since Odoo 19.0)

The payload is the contract. The chart reads its x axis values and three line datasets by name, and the summary getters read six more keys. A missing key produces an empty line or a blank figure rather than an error, but a missing or malformed payload raises, because the shared base parses without a guard.

Working examples

The core usage

<field name="json_replenishment_graph" nolabel="1"
       colspan="2" widget="replenishment_graph_widget"/>

No options. The field holds the JSON the server computed for that reordering rule.

The chart part of the payload

{
  "x_axis_vals": ["W1", "W2", "W3"],
  "max_line_vals": [...],
  "min_line_vals": [...],
  "curve_line_vals": [...]
}

Three datasets plus the category labels. The dashed segment is decided from the last x value, not from a flag in the data.

The summary part

{
  "product_uom_name": "Units",
  "qty_on_hand": 120,
  "product_min_qty": 50,
  "product_max_qty": 200,
  "daily_demand": 8,
  "average_stock": 125,
  "ordering_period": 14,
  "lead_time": 5
}

Read by individual getters and printed by the template beside the chart.

A forced y axis and a geometric dash rule

Three details in the chart configuration are worth pulling out, because none of them is obvious from the rendered result.

The dashed projection is decided geometrically rather than by a flag. A segment callback compares each segment's first point against the last value on the x axis, and applies a dash pattern when they match. In other words, the dashing starts where the recorded data ends, and the server controls that boundary purely by how it orders the axis values.

The y axis is forced. Rather than letting the chart library choose ticks, the widget injects the minimum and maximum quantities into the tick list before labels are computed, and then a label callback prints a value only if it is one of those two. The axis bounds are padded ten percent beyond each, so the horizontal lines never sit on the frame.

Interaction is switched off deliberately: the legend is hidden and tooltips are disabled. Combined with the point style being suppressed on all three lines, the result reads as a diagram rather than a chart you can interrogate.

One more thing the widget does at startup: it resolves whether the user belongs to the unit of measure group, alongside loading the chart library, so the template can decide whether to print the unit beside the quantities.

The version story is a replacement rather than a rename. Odoo 16 through 18 registered a replenishment history widget in this same file and this same dialog; Odoo 19 removed it and registered this graph widget in its place. Anything referring to the old name will fall back to the field's type widget.

Version compatibility

VersionStatusNotes
Odoo 20.0Partial / changedNot released. The chart configuration is unchanged; the library loading moves to a shared chart hook.
Odoo 19.0VerifiedFirst version. Replaces the replenishment history widget used in the same dialog.
Odoo 18.0Not availableWidget does not exist. The dialog used a replenishment history widget instead.
Odoo 17.0Not availableWidget does not exist.
Odoo 16.0Not availableWidget does not exist.

Upgrade note. This widget is new in Odoo 19 and it replaces the replenishment history widget used in Odoo 16 through 18. The core dialog was updated with it, so a standard database needs nothing; a customized replenishment dialog referring to the old widget name should be updated, because an unknown widget name silently falls back to the field's type.

What is changing in Odoo 20

Odoo 20 is expected at Odoo Experience in Brussels, 24 to 26 September 2026. The development branch is unstable and this may still change; we re-verify the page after release.

Same chart, new plumbing. The manual library loading, canvas reference and destroy effect are replaced by a shared chart hook that takes the configuration getter. The scatter configuration itself, including the dash rule, the forced ticks and the disabled tooltips, is unchanged.

Common problems and fixes

SymptomCause and fix
An error about parsing JSONThe field is empty or malformed, and the shared base parses without a guard. Make sure the server computes the payload before the dialog renders.
The chart is blankThe payload parsed but the three dataset keys are missing or empty. Check the server-side computation; the widget reads them by name.
Nothing is dashedNo segment starts at the last x axis value, so the dash callback never applies. The boundary is controlled by how the server orders the axis values.
The y axis has no useful labelsOnly the minimum and maximum are labelled; every other tick prints blank by design. Expected. The precise figures are printed beside the chart.
No tooltips on hoverTooltips and the legend are both disabled in the configuration. Expected. The chart is an illustration, not an interactive report.
The old history panel disappeared after upgradingOdoo 19 replaced the replenishment history widget with this one. Update any customized dialog to the new widget name.

Replenishment graph vs the alternatives

WidgetBest forKey difference
replenishment_graph_widgetShowing what a reordering rule's minimum and maximum actually produceA scatter chart with forced min and max ticks and a projection dashed from the last recorded point
lead_days_widgetThe lead time breakdown in the same dialogA textual panel on the same shared base
dashboard_graphSmall charts on kanban cardsA much simpler payload and only line or bar
picking_type_dashboard_graphOperation type dashboardsIts own bucket coloring and click targets
forecast_widgetWhether a specific demand will be metA verdict badge rather than a curve

For a small chart on a kanban card, the dashboard graph widget is the right tool and takes a much simpler payload. This one is bound to the replenishment dialog's payload shape, so reusing it elsewhere means producing the same eight keys. For a purely textual breakdown, its sibling lead days widget in the same file is the lighter option.

Frequently asked questions

What does the replenishment curve show?+
The stock level a reordering rule produces, drawn against horizontal minimum and maximum lines. The projected part is dashed, and summary figures such as daily demand and ordering period are printed beside it.
Where does the dashing start?+
At the last value on the x axis. A segment callback compares each segment's first point against that value, so the server controls the boundary by how it orders the axis.
Why does the y axis only label two values?+
The minimum and maximum are injected into the tick list and every other tick prints blank. It keeps the chart readable and puts the emphasis on the two parameters being tuned.
Can I configure the chart?+
No. Like its sibling in the same file, it has no options and no extractor. Everything comes from the JSON payload and the template.
What happened to the replenishment history widget?+
Odoo 19 removed it and registered this graph widget in the same dialog. A customized dialog still using the old name will silently fall back to the field's type widget.

Stock parameters set from evidence, not habit

Minimums, maximums and lead times decide how much cash sits on your shelves. We tune Odoo replenishment against your real demand data, on versions 16 through 19.

Book a free consultation

How this page was produced

The three datasets, the segment dash rule, the injected y axis ticks, the disabled legend and tooltips, the unit of measure group check and the eight summary getters were read from json_widget.js on the Odoo 19.0 branch, with the usage taken from stock/wizard/stock_replenishment_info.xml. The replacement of the history widget was established by comparing the registrations in the same file across the 16.0, 17.0 and 18.0 branches, and the Odoo 20 notes come from the public development branch. Spotted an error? Tell us and we will correct the page.