Skip to main content
iVentureTeam

generate_serials

The button that generates a run of lot or serial numbers for a move, and writes the resulting lines in one go.

Siddharth JambukiyaSiddharth JambukiyaOdoo Techno-Functional Consultant
August 27, 2026Updated September 7, 20264 min read
Technical namegenerate_serials
Viewsform (view widget, <widget> element)
Modulestock, the Inventory app
Used in coreStock move forms in stock
VersionsOdoo 20.0, Odoo 19.0, Odoo 18.0, Odoo 17.0, Odoo 16.0
No-code setupNo. It is set in view XML and depends on module-specific data
Alternativesimport_lots, sml_x2_many, stock_move_one2many

What the generate serials does

Receiving a hundred tracked units means a hundred move lines, each with its own number. Typing them is not a realistic option, so Odoo offers two ways to fill them: generate a run of numbers, or paste a list you already have.

Both go through the same dialog, and both of these widgets are the buttons that open it. They differ only in the mode they pass, which decides the dialog's title and which controls it shows.

The generated or pasted lines are then pushed into the move's line relation directly, deliberately bypassing the usual field change handlers.

What this means for your team

Serial and lot tracking is a compliance requirement in food, pharmaceuticals and regulated manufacturing, and an operational one anywhere returns and recalls matter. The reason it fails in practice is data entry volume at receipt.

These two paths cover the two realistic sources of numbers: your own sequence, or the supplier's list from a packing slip. Deciding which of the two your process uses is worth doing before go live, because the warehouse workflow differs.

Supported options in Odoo 19

The widget itself takes the standard view widget props and declares no options. The controls listed below belong to the dialog it opens. Read from the generate serial source, Odoo 19.0.

OptionTypeWhat it does
modeprop passed to the dialogEither generate or import. Decides the dialog's title and which inputs are shown.
has_trackingfield read from the moveLot or serial. Changes the title, the parsing and whether a total received field appears.
the keep lines checkboxcontrol in the dialogWhen unchecked, delete commands are issued for every existing line before the new ones are added.
lot_sequence_idfield read from the productRead when suggesting a starting number, then advanced through the sequence.

The starting number can come from your sequence. When the product has a lot sequence configured, the widget reads the next value from it and fills the field, which also advances that sequence.

Working examples

Placing it

<widget name="generate_serials"/>

No attributes. It passes the move to the dialog.

What the dialog defaults to

count = the move's demand, or 2

Filled on opening.

The import path instead

<widget name="import_lots"/>

Same dialog, pasting a list rather than generating.

Writing a hundred lines without a hundred round trips

The dialog is where everything happens, and the part worth understanding is how it writes the lines.

It calls a server method to build the line values, passing the product, both locations, the tracking type and the quantity, plus the mode and whichever inputs that mode uses. What comes back is a list of value dictionaries.

Then, rather than adding records through the normal path, it creates data points directly from those values and pushes them into the relation's internal record list, command list and identifier list by hand. The source says why: to bypass the field change handlers. On a hundred lines those handlers would fire a hundred times.

A checkbox decides whether existing lines survive. When it is unchecked the dialog issues delete commands for every current identifier before adding the new ones, which is what makes a second generation replace rather than append.

One asymmetry worth knowing: for lot tracking the count and quantity are read as decimals and a total received field is offered, while for serial tracking the count is read as an integer and the quantity comes from the move. That follows from what the two tracking modes mean.

Version compatibility

VersionStatusNotes
Odoo 20.0In developmentNot released. Substantially reworked on the development branch.
Odoo 19.0VerifiedVerified against the shipped source.
Odoo 18.0VerifiedSame dialog and both registrations.
Odoo 17.0VerifiedSame approach with older component conventions.
Odoo 16.0VerifiedSame approach with older component conventions.

Upgrade note. Present since Odoo 16 with the same two registrations in one file. The dialog has gained controls across those versions but the approach is unchanged.

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 this page after the release.

Substantially reworked. The development branch rewrites the file with a large diff. The two buttons and the shared dialog are what to expect to survive; the line writing mechanics are being reshaped.

Common problems and fixes

SymptomCause and fix
Existing lines disappearedThe keep lines checkbox was unchecked, so delete commands were issued first. Check the box to append instead of replace.
The next number is not from my sequenceThe product has no lot sequence configured. Set one on the product; the widget reads it before suggesting a number.
Field change handlers did not fireThe lines are created directly from values to bypass them. Expected, and deliberate for performance.
The dialog title says lots not serialsThe title follows the product's tracking type. Check the product's tracking setting.
A decimal count is rejectedSerial tracking parses the count as an integer. Expected. Lot tracking accepts decimals.
The unit of measure column is missingThe dialog checks a user group before showing it. Enable units of measure in settings.

Generate serials vs the alternatives

WidgetBest forKey difference
generate_serialsGenerating a run of lot or serial numbers on a stock moveWrites the resulting lines straight into the relation, bypassing field change handlers
import_lotsPasting numbers from a supplierThe same dialog in import mode
sml_x2_manyPicking from existing stockSelects quants rather than creating numbers
stock_move_one2manyThe move lines themselvesA relation field rather than a generator

The import path is the sibling to reach for when the numbers come from a supplier rather than from your own sequence. Entering lines by hand remains correct for small quantities where a dialog is more friction than help.

Frequently asked questions

Where does the first number come from?+
The product's lot sequence when one is configured. The widget reads the next value and fills the field, which advances that sequence.
Why are field change handlers skipped?+
Because generating a hundred lines would fire them a hundred times. The dialog creates data points directly from the returned values, which the source notes is deliberate.
Does generating twice append or replace?+
It depends on the keep lines checkbox. Unchecked, delete commands are issued for every existing line before the new ones are added.
Why does lot tracking behave differently?+
Lots can be fractional, so the count and quantity are parsed as decimals and a total received field is offered. Serial tracking parses an integer instead.
Which versions have it?+
Odoo 16 onwards. The development branch reworks the file substantially.

Traceability that does not slow the warehouse down

Lot and serial tracking are only sustainable when receiving is fast. We implement Odoo Inventory tracking with the entry paths your team will actually use, on versions 16 through 19.

Book a free consultation

How this page was produced

The two registrations sharing one file, the mode passed to the dialog, the direct data point creation bypassing field change handlers, the delete commands issued when existing lines are not kept and the decimal versus integer parsing by tracking type were read from the generate serial source on the Odoo 19.0 branch. Version coverage comes from comparing the file across the 16.0, 17.0 and 18.0 branches and against the public development branch. Spotted an error? Tell us and we will correct the page.