Skip to main content
iVentureTeam

forecast_widget

The green Available, orange Exp date and red Not Available pills on Odoo transfer lines are one widget reading five fields you cannot see. Here is exactly how forecast_widget decides which badge you get.

Siddharth JambukiyaSiddharth JambukiyaOdoo Techno-Functional Consultant
August 24, 2026Updated August 24, 20266 min read
Technical nameforecast_widget
Field typesfloat (inherits the float descriptor; core uses it on forecast_availability)
Viewslist (operation lines inside transfer forms)
Modulestock (Inventory)
Used in core3 occurrences across 3 modules: stock, mrp, repair
VersionsOdoo 20.0, Odoo 19.0, Odoo 18.0, Odoo 17.0, Odoo 16.0
No-code setupNo. Core applies it on transfer and production views; Studio does not offer it
Alternativesfloat, progressbar, stock_rescheduling_popover

What the Forecast badge does

On a delivery order or manufacturing order, each line answers one question: can this quantity ship? forecast_widget is the answer rendered as a pill badge on the line's forecast_availability field.

The decision tree, read directly from the component and its template, is short. If there is no forecast expected date and the forecast availability covers the demanded quantity, the badge is green and reads Available. If an expected date exists and the quantity will be covered, the badge shows Exp plus the date, orange normally, red when that expected date lands after the line's deadline. In every other case it is a red Not Available.

The number itself never renders. The float value drives the comparison against product_qty, and the badge communicates only the verdict.

What this means for your team

This badge is the fastest stock triage tool in Odoo: a warehouse manager scans a delivery's lines and instantly separates what ships today, what ships late, and what is blocked. The orange state deserves attention in training, because it does not mean trouble. It means replenishment is already scheduled and the line will be covered by the shown date; red on the same badge means that date breaks the customer deadline.

The click-through matters just as much: clicking the badge opens the product's Forecasted Report, the same screen behind the Forecast smart button, pre-focused on the product. That turns a red line into an immediate answer to "why not, and when."

Two silent rules avoid confusion. Nothing happens when clicking a line that has never been saved, and since 19.0, nothing happens for non-storable products either, because consumables and services have no stock forecast to show.

Working examples

How core applies it (delivery order lines)

<field name="forecast_availability" string="" widget="forecast_widget"
       column_invisible="parent.state in ('cancel', 'done') or parent.picking_type_code not in ['internal', 'outgoing']"/>

Core blanks the column label and hides the badge entirely on finished transfers and on receipts, where availability is meaningless.

Reusing it on a custom view

<field name="forecast_expected_date" column_invisible="True"/>
<field name="product_qty" column_invisible="True"/>
<field name="is_storable" column_invisible="True"/>
<field name="forecast_availability" widget="forecast_widget"/>

The invisible companions are the whole trick; see the deep dive for why.

No fieldDependencies: the view must carry the data

Most specialized widgets declare fieldDependencies so the framework fetches the extra fields they read. forecast_widget declares none. It reaches into the row's data for forecast_expected_date, date_deadline, forecast_availability, product_qty, is_storable and state, and silently gets undefined for any of them the view did not load. Core views therefore carry those fields as invisible columns, and a custom view that forgets one gets a badge that is wrong rather than broken: a missing product_qty makes every line look unfulfilled, and a missing is_storable makes the click do nothing.

The fulfillment comparison has a subtle guard against float noise: both forecast_availability and product_qty are run through the float formatter with the field's precision and parsed back before comparing, so a stored 4.999999999 demanded as 5.0 compares equal at precision instead of flagging a phantom shortage.

Version history of the fine print: 16.0 and 17.0 also formatted a reserved_availability field, 18.0 read quantity instead, and 19.0 dropped that side value entirely. The is_storable click gate is 19.0-only, matching the field that replaced product types in 18.0.

Version compatibility

VersionStatusNotes
Odoo 20.0In developmentProvisional: development branch removes the unsaved-line click guard and the stored state; badge logic unchanged. Re-verified after release.
Odoo 19.0VerifiedVerified against the shipped source. Adds the is_storable click gate; drops the side quantity formatting.
Odoo 18.0Partial / changedSame badge logic; click works on any saved line (no is_storable gate); formats quantity internally.
Odoo 17.0Partial / changedSame badge logic; reads reserved_availability instead of quantity.
Odoo 16.0Partial / changedSame badge logic and reserved_availability read; resId taken from data.id.

Upgrade note. The widget name and badge behavior are stable from 16.0 through 19.0, so views survive an Odoo migration untouched. Custom views built before 19.0 should add is_storable to the line fields when upgrading, or the report click-through dies silently on every line.

What is changing in Odoo 20

Odoo 20 is expected at Odoo Experience in Brussels, 24 to 26 September 2026. The notes below come from diffing this file against the public development branch, which is unstable until feature freeze; we re-verify once the release ships.

Two small changes are visible. The click guard loses its resId check: _openReport only verifies is_storable, so clicking the badge on a not-yet-saved line would attempt to open the report rather than doing nothing. And the component stops capturing the line's state, which 19.0 stored but the template already used only indirectly. No option changes, no registration changes, and the badge logic itself is untouched.

Common problems and fixes

SymptomCause and fix
Clicking the badge does nothingThe line is unsaved, or the product is not storable (19.0), or is_storable is not loaded in the view. Save the transfer first; for custom views, add is_storable as an invisible column.
Every line shows Not Available despite stockproduct_qty or forecast_expected_date is missing from the view, so the comparison runs against undefined. Add the missing fields as invisible columns, as the core views do.
Badge missing on receiptsCore hides the column when picking_type_code is not internal or outgoing. Expected behavior; incoming goods have no availability question.
Orange badge treated as a problem by usersExp plus a date means the line will be covered by that date; only red means late or unfulfilled. Train the distinction; red Exp specifically means the expected date breaks the deadline.
Setting digits or other float options changes nothingThe badge template never renders the number, so all inherited float options are inert. Show the raw field separately if you need the quantity visible.

Forecast badge vs the alternatives

WidgetBest forKey difference
forecast_widgetPer-line availability verdicts on transfers and manufacturing ordersRenders a colored verdict badge plus report click-through instead of the number
floatShowing the actual forecast quantityPrints the number, no color logic, no click-through
progressbarVisualizing partial progress toward a quantityContinuous bar instead of a three-state verdict
stock_rescheduling_popoverExplaining late chains on a movePopover with links to the blocking documents, JSON-driven

The badge answers "will it be covered"; the alternatives answer "how much" or "why". They complement rather than replace each other, and core actually ships several of them side by side on stock views.

Frequently asked questions

What do the forecast_widget badge colors mean?+
Green Available: forecast availability covers the demanded quantity with nothing scheduled. Orange Exp plus a date: the quantity will be covered by that date. Red: either that expected date is later than the line's deadline, or the quantity is not forecast to be covered at all.
Why does clicking the forecast badge do nothing?+
Three source-verified guards: the line must be saved (it has a resId), the product must be storable (19.0 rule via is_storable), and in custom views is_storable must actually be loaded. Consumables and services never open the report.
Which fields does forecast_widget need in the view?+
It reads forecast_expected_date, date_deadline, forecast_availability, product_qty, is_storable and state from the row without declaring fieldDependencies, so a custom view must include them (invisible is fine) or the badge logic runs on undefined values.
Can forecast_widget show the actual forecast number?+
No. The template renders only the verdict badge. The widget inherits the float descriptor, so options like digits are accepted, but none of them have any visible effect. Add the field again without the widget if you need the number.
Where does the badge click lead?+
To the product's Forecasted Report via stock.move.action_product_forecast_report, the same screen as the Forecast smart button on the product, showing on-hand, incoming and outgoing quantities and the documents behind them.
Does forecast_widget change in Odoo 20?+
The development branch shows two minor edits: the unsaved-line click guard is removed and the component stops storing the line state. Badge thresholds and colors are unchanged. Unstable until the September 2026 release; we re-verify after launch.

Deliveries stuck in red?

When half a delivery's lines show Not Available, the fix lives in routes, reordering rules and lead times, not in the badge. We tune Odoo inventory forecasting and replenishment for warehouses on Odoo 16 through 19, from MTO chains to buffer stock policies.

Get my forecast sorted

How this page was produced

This page was verified by reading forecast_widget.js and its template forecast_widget.xml on the Odoo 19.0 branch, diffing against 16.0, 18.0 and the public development branch, and checking the core usage in stock, mrp and repair views, including the column_invisible expression quoted above. The no-fieldDependencies behavior and the float-precision comparison were read from the source, not inferred. Found something we missed? Tell us.