Skip to main content
iVentureTeam

stock_action_field

A quantity or an amount that is also a link. Click the On Hand figure on a product list and it opens the stock view for that product, with context.

Siddharth JambukiyaSiddharth JambukiyaOdoo Techno-Functional Consultant
August 27, 2026Updated September 1, 20266 min read
Technical namestock_action_field
Field typesfloat, monetary
Viewslist, form
Modulestock, the Inventory app
Used in core1 occurrence, the On Hand column on the product list in stock
VersionsOdoo 20.0, Odoo 19.0
No-code setupNo. It needs an action name and usually a context expression
Alternativesfloat, monetary, statinfo, qty_at_date_widget

What the clickable amount does

A number in a list often answers one question and raises another. Seeing that a product has 42 on hand immediately prompts where, and the usual answer is to leave the list, open the product, and find the stock view from there.

This widget shortens that. It renders the value exactly as a decimal or currency field would, and makes it clickable: the click opens a named action, with additional context taken from the field's own context attribute and evaluated against the record.

Which renderer it uses is decided from the field's type rather than configured, so the same widget name serves a quantity column and an amount column. A per-record expression can disable the click where following it would make no sense.

What this means for your team

Clickable figures are one of the cheapest usability improvements available in an ERP, and inventory is where they pay off most, because almost every number invites a follow-up question. The alternative, teaching people a navigation path, costs training and gets forgotten.

The pattern is worth reusing beyond stock. Any list where a computed total should lead somewhere, a receivable balance, an open task count, a pending approval figure, can use the same idea. What makes it work is that the destination is an action name plus context, so the target screen opens already filtered to the record you clicked from.

The one caution is that clicking navigates away. On a form with unsaved changes that is disruptive, which is presumably why the widget is used on a list in core rather than on a form.

Supported options in Odoo 19

One option is declared, and two more are read without being declared. The declared list is also assembled in an unusual way, described in the note. Read from stock_action_field.js and the decimal and currency fields, Odoo 19.0.

OptionTypeWhat it does
action_namestringThe external identifier of the action opened on click. The only option the widget declares.(since Odoo 19.0)
disabledstring (expression)<strong>Read in the extractor but never declared.</strong> A Python expression evaluated against the record; when it is true the value is rendered without the click.(since Odoo 19.0)
contextstring (field attribute)<strong>Read in the extractor but never declared.</strong> The field's own context attribute, evaluated against the record and merged into the action's context.(since Odoo 19.0)
digitslistInherited, and applied when the field is a decimal. Controls displayed precision.
currency_fieldfieldInherited, and applied when the field is a currency amount. Names the currency field to format against.

The declared option list is malformed. It is built by pushing the merged decimal and currency options into the array as a single nested array, rather than spreading them, so anything reading the declarations finds an array where an option object is expected. Rendering is unaffected, because the extractor reads the options dictionary directly, but developer tooling will not present the inherited options usefully.

Working examples

The core usage, trimmed

<field name="qty_available"
       widget="stock_action_field"
       sum="Total On Hand"
       options="{'action_name': 'stock.dashboard_open_quants'}"
       context="{'search_default_product_id': id}"/>

The action opens the stock view, and the context expression pre-filters it to the clicked product.

Disabling the click per record

<field name="qty_available"
       widget="stock_action_field"
       options="{'action_name': 'stock.dashboard_open_quants',
                  'disabled': "is_storable == False"}"/>

The expression is evaluated against the record, so consumable products can be shown without a link.

On a currency column

<field name="stock_value"
       widget="stock_action_field"
       options="{'action_name': 'stock_account.action_valuation'}"/>

The renderer follows the field's type, so a currency field is formatted with its currency and no extra option is needed.

One widget, two renderers, three undeclared knobs

The component is a small wrapper rather than a subclass. It holds both the decimal and the currency components, reads the field's type when it starts, and renders whichever matches, forwarding every prop except its own three.

The extractor is where the type branching happens. It always builds the three action props: the action name from the options, the disabled expression from the options, and the context taken from the field's context attribute. It then merges in the decimal or currency extractor's own props depending on the field type. A field of any other type gets only the action props, which means the value renders without the formatting that widget would normally apply.

The click handler stops the event, evaluates the context expression against the record, and asks the action service to open the named action with that context merged into the record's own. Nothing is written and nothing is saved first, so a form with pending edits will navigate away with them pending.

Two details are worth flagging for anyone extending this. The disabled expression and the context are read in the extractor but never declared as supported options, so no tooling will suggest them. And there is a commented-out line in the source showing an earlier approach that called a method on the record instead of opening an action, which is a useful hint about where the design started.

Version compatibility

VersionStatusNotes
Odoo 20.0In developmentNot released. Behavior identical on the development branch.
Odoo 19.0VerifiedFirst version. Verified against the shipped source.
Odoo 18.0Not availableWidget does not exist. The On Hand column was a plain quantity.
Odoo 17.0Not availableWidget does not exist.
Odoo 16.0Not availableWidget does not exist.

Upgrade note. The widget is new in Odoo 19. On Odoo 18 and earlier the On Hand column was a plain quantity, so an upgrade makes the figure clickable with the standard product views and there is nothing to migrate.

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.

Behavior is unchanged. The action name option, the per-record disabling, the context evaluation and the type-driven renderer choice are all identical on the development branch. The differences follow the wider component migration and affect patches rather than views.

Common problems and fixes

SymptomCause and fix
Clicking does nothingThe action name option is missing, or the disabled expression evaluates to true for that record. Set action_name, and check the disabled expression against the record's data.
The target opens unfilteredThe field has no context attribute, so no additional context reaches the action. Add a context expression referencing the record, as the core view does.
The number is not formattedThe field is neither a decimal nor a currency amount, so only the action props are extracted. Use it on a float or monetary field, or format the value another way.
Unsaved changes are lost on clickThe click opens an action without saving first. Use the widget on lists rather than on forms with pending edits.
Developer tooling shows no inherited optionsThe declared option list nests the inherited options inside an array element instead of spreading them. Consult this page or the source; rendering itself is unaffected.
The disabled option is ignoredIt is read from the options dictionary as an expression string; a boolean will not evaluate as intended. Pass a quoted expression, not a Python boolean.

Clickable amount vs the alternatives

WidgetBest forKey difference
stock_action_fieldQuantities and amounts in a list that should lead to a filtered viewChooses its renderer from the field type and opens a named action with record-derived context
floatA plain decimal valueNo click and no action
monetaryA plain currency amountCurrency formatting without navigation
statinfoA figure in a stat buttonThe button carries the action, not the field
qty_at_date_widgetForecast availabilityExplains a quantity rather than linking from it

Use a plain decimal or currency field wherever the number does not need to lead anywhere. For a figure that belongs in a stat button rather than a column, the stat info widget is the conventional choice and gets its click from the button. And where the destination depends on more than context, a server action button is clearer than a clickable number.

Frequently asked questions

How does the widget know whether to format as a quantity or an amount?+
It reads the field's own type when it starts and renders the decimal or currency component accordingly. On any other type it renders without that formatting, because only the action props are extracted.
How do I filter the target view?+
Through the field's context attribute. It is evaluated against the record and merged into the action's context, which is how the core usage pre-filters the stock view to the clicked product.
Can I disable the link for some records?+
Yes, with the disabled option, which takes an expression evaluated against the record. It is read by the extractor but not declared, so no tooling will suggest it.
Why does developer tooling show odd options?+
The declared option list nests the merged decimal and currency options inside a single array element instead of spreading them. Rendering is unaffected; only the declarations are malformed.
Does clicking save the record first?+
No. The handler evaluates the context and opens the action directly, so pending changes on a form remain pending.

Numbers that answer the next question too

Clickable figures, filtered destinations and the reports behind them turn a list into a tool. We build that kind of navigation into Odoo on versions 16 through 19, without turning every column into a link.

Book a free consultation

How this page was produced

The type-driven renderer choice, the three action props, the malformed declared option list, the undeclared disabled and context reads and the commented-out earlier approach were read from stock_action_field.js on the Odoo 19.0 branch, with the inherited option sets read from the float and monetary fields in web. The usage comes from stock/views/product_views.xml. Version coverage comes from the absence of the file on 16.0, 17.0 and 18.0, and a comparison against the public development branch. Spotted an error? Tell us and we will correct the page.