Skip to main content
iVentureTeam

counted_quantity_widget

The counted quantity cell in a physical inventory. The hard part is not the number, it is knowing the difference between counted zero and not counted at all.

Siddharth JambukiyaSiddharth JambukiyaOdoo Techno-Functional Consultant
August 27, 2026Updated September 7, 20266 min read
Technical namecounted_quantity_widget
Field typesfloat
Viewslist, form
Modulestock, the Inventory app
Used in core1 occurrence, the counted quantity on the physical inventory list in stock
VersionsOdoo 20.0, Odoo 19.0, Odoo 18.0, Odoo 17.0, Odoo 16.0
No-code setupNo. It writes a companion flag that has to exist on the model
Alternativesfloat, integer, qty_at_date_widget, forecast_widget

What the counted quantity field does

A physical inventory asks a warehouse to walk the shelves and write down what is there. The awkward case is zero: a line where somebody looked and found nothing is completely different from a line nobody has reached yet, and both would be a zero in a plain number field.

Odoo solves that with a companion flag on the quant, set when a count is genuinely entered. This widget is what sets it. When the user types a value and commits it, the widget writes the quantity and the flag together, so the record carries both the number and the fact that somebody produced it.

The display follows the same distinction. A read-only cell with no value and no flag renders empty rather than as zero, so an inventory in progress shows at a glance which lines have been counted and which have not.

What this means for your team

This is the difference between an inventory you can act on and one you cannot. Adjusting stock to zero because nobody visited that aisle is an expensive mistake, and it is invisible if the interface shows the same zero either way.

The Odoo 19 change matters operationally. In Odoo 18 the counted flag was set as soon as the user typed a character, so tabbing through a list and touching a cell without changing it marked the line as counted. On a large count that quietly converts unvisited lines into confirmed zeros. Odoo 19 defers the flag until a value is actually committed.

The keyboard handling is worth mentioning to anyone running a count: Enter and Tab both commit, so a counter can work down a list without touching the mouse, which is how counts are actually done.

Supported options in Odoo 19

The widget declares no options of its own. It spreads the decimal field's descriptor, so the options below are inherited. What it adds is a companion flag it writes, described in the note. Read from counted_quantity_widget.js and the float field, Odoo 19.0.

OptionTypeWhat it does
inventory_quantity_setcompanion fieldWritten by literal name alongside every committed value, and read to decide whether a read-only cell renders blank. Without it, counted zero and uncounted look identical.
digitslistInherited from the decimal field. Controls the displayed precision.
enable_formattingbooleanInherited. Set to false to remove locale formatting from the displayed value.(default: true)
typestringInherited. Set to number to render a real HTML number input.

It writes a second field by literal name. Every commit updates the counted quantity and the companion counted flag in the same operation, and the blank display also reads that flag. A model without it will still render, but the counted and uncounted states become indistinguishable.

Working examples

The core usage

<field name="inventory_quantity"
       widget="counted_quantity_widget"/>

No options. The companion flag is written automatically alongside the value.

The companion field it writes

# on the quant, written by literal name
inventory_quantity_set
# true once a count is committed

The same field drives the blank display in read-only mode.

Formatting the number

<field name="inventory_quantity"
       widget="counted_quantity_widget"
       options="{'digits': [16, 2]}"/>

Inherited from the decimal field, and unaffected by the counted-flag behavior.

Three listeners and one local flag

The source opens with a comment explaining why the widget exists in this shape: the standard input hook does not let it override the input and change handling it needs, so it installs its own listeners on the numeric input for input, keydown and blur, and removes them when the element goes away.

Those three handlers implement one rule between them. Typing sets a local flag saying the field has been touched. Blurring commits only if that local flag is set, then clears it. Pressing Enter, Tab or Shift+Tab commits and re-arms, so continuing to type in the next cell behaves the same way.

Committing parses the typed value and writes both the quantity and the counted flag in a single record update, with the parse wrapped so an unparseable entry is ignored here and handled by the normal validation path instead.

The display rule is a small override on the formatted value: when the field is read-only and both the value and the counted flag are falsy, it returns an empty string. Worth noting for anyone reading the code, the condition uses a bitwise operator between the two negations rather than a logical one; it evaluates the same way here, since both operands are booleans, but it is not the operator you would expect.

The Odoo 18 version wrote the counted flag directly from the input handler, on the first keystroke. That is the behavior Odoo 19 replaced with the local flag, and it is the single most consequential change in this widget's history.

Version compatibility

VersionStatusNotes
Odoo 20.0In developmentNot released. Same rules on the development branch; listener and state helpers modernized.
Odoo 19.0VerifiedVerified against the shipped source. The counted flag is written only when a value is committed.
Odoo 18.0Partial / changedSame purpose, but the counted flag was written on the first keystroke, so touching a cell marked the line as counted.
Odoo 17.0Partial / changedAs Odoo 18.
Odoo 16.0Partial / changedAs Odoo 18.

Upgrade note. No view change is needed, but the behavior differs. On Odoo 18 and earlier, touching a counted quantity cell marked the quant as counted immediately; from Odoo 19 the flag is written only when a value is committed. If your count procedures were written around the older behavior, they can be simplified.

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 rules, newer plumbing. The commit-on-blur behavior, the paired write of quantity and flag, and the blank display for uncounted lines are all unchanged. The listener and state handling move to the newer helpers, which affects code that patches the widget rather than views.

Common problems and fixes

SymptomCause and fix
Uncounted lines show zero instead of blankThe model does not carry the companion counted flag, or the cell is editable rather than read-only. Add the flag field; the blank display applies to read-only cells only.
A line was marked as counted without being countedOn Odoo 18 and earlier, typing anything set the flag immediately. Upgrade to Odoo 19, where the flag follows a committed value.
A typed value is not savedIt was not committed: the cell was left without blurring or pressing Enter or Tab. Press Enter or Tab, or click elsewhere in the list.
An invalid entry is silently ignoredThe commit wraps the parse and lets the normal validation path report the problem. Correct the entry; the error surfaces through standard validation.
Keyboard counting does not advanceSomething is intercepting Enter or Tab before the widget's handler. Check for a competing keyboard handler in a customization.
The flag is set but the quantity is emptyA counted zero, which is exactly what the flag exists to record. Nothing to fix; that is the case the widget was built for.

Counted quantity field vs the alternatives

WidgetBest forKey difference
counted_quantity_widgetPhysical inventory counts, where zero and not yet counted must differWrites a counted flag only on a committed value, and renders uncounted lines blank
floatOrdinary decimal quantitiesNo counted flag and no blank display for unset values
integerWhole number quantitiesDifferent type, same lack of counted semantics
qty_at_date_widgetForecast availability on a lineShows projected stock rather than recording a count
forecast_widgetWhether a demand will be fulfilledA verdict badge rather than an editable quantity

Use the plain decimal field anywhere the distinction between zero and unknown does not matter. Where it does, the pattern here is worth copying rather than the widget: a value plus a flag set only on real input, and a display that stays blank until the flag is set.

Frequently asked questions

Why does an uncounted line show blank rather than zero?+
Because the widget returns an empty string when the cell is read-only and both the quantity and the counted flag are unset. A counted zero, which has the flag, shows as zero.
When is the counted flag written?+
When a value is committed, by blurring after typing or by pressing Enter, Tab or Shift+Tab. The quantity and the flag are written in the same update.
What changed in Odoo 19?+
Odoo 18 wrote the counted flag on the first keystroke, so merely touching a cell marked the line as counted. Odoo 19 tracks that locally and only writes the flag with a committed value.
Why does it install its own listeners?+
The source comment says the standard input hook does not allow overriding the input and change handling it needs, so it attaches input, keydown and blur handlers to the numeric input itself.
Does it support the decimal field's options?+
Yes. It spreads that descriptor unchanged, so precision and formatting options behave normally.

Stock counts you can act on without second-guessing

Cycle counts, adjustment approvals and the valuation entries behind them only work if the data says what actually happened. We set up Odoo Inventory counting procedures on versions 16 through 19.

Book a free consultation

How this page was produced

The three installed listeners, the local touched flag, the paired write of value and counted flag, and the blank display rule were read from counted_quantity_widget.js on the Odoo 19.0 branch, with the inherited option set read from the float field in web. The usage comes from stock/views/stock_quant_views.xml. The Odoo 18 behavior was established by comparing the same file on that branch, and the Odoo 20 notes from the public development branch. Spotted an error? Tell us and we will correct the page.