Complete Guide
Introduction
Configure Odoo Serial Numbers right away to track every item uniquely and avoid losses. In this tutorial, we show you how to set up Odoo serial numbers, manage lot & serial tracking, and automate serial assignment. Moreover, we share code examples in Python and XML, and we link to the official Odoo documentation for deeper insights. First, you will enable traceability features in Odoo Inventory. Then, you will learn how to assign and auto‑generate serial numbers. Finally, you will validate tracking and generate detailed traceability reports.
Prerequisites for Serial Number Configuration in Odoo
Before you begin, ensure you meet these prerequisites:
- You have Odoo 12 to 17 installed and running.
- You hold admin access to the Odoo database.
- You have basic knowledge of Python, XML, and Odoo module structure.
- You use PostgreSQL, Git, and a Linux/Ubuntu environment for development.
Enable Lot & Serial Tracking in Odoo
First, you must activate the core tracking feature. Follow these steps:
Access Inventory Settings
- Log in as an administrator.
- Go to Inventory > Configuration > Settings.
- Scroll to the Traceability section.
Activate Lots & Serial Numbers
- Check Lots & Serial Numbers.
- Click Save.
Now, Odoo displays lot and serial options on each storable product.
Set Tracking Method on Products
Next, you choose how you track each product: by lot or by serial number.
Open a Product
- Go to Inventory > Products > Products.
- Select a storable product (e.g., Vinyl Record).
Configure Tracking
- In the Inventory tab, find Traceability:
- Select By Unique Serial Number for serial.
- Select By Lots for batch tracking.
- Save your changes.
Now, your product uses serial‑level traceability.
Configure Odoo Serial Numbers
At this stage, you have enabled tracking. However, you can improve the setup by creating a dedicated serial sequence.
Create a New Sequence
First, define an IR sequence in XML under a custom module:
<!-- file: serial_auto/data/serial_sequence.xml -->
<odoo xmlns="http://www.w3.org/2000/xmlns/">
<data noupdate="1">
<record id="seq_serial_auto" model="ir.sequence">
<field name="name">Serial Number Sequence</field>
<field name="code">serial.auto</field>
<field name="prefix">SN%(year)s-</field>
<field name="padding">5</field>
<field name="number_next">1</field>
</record>
</data>
</odoo>
Explanation
- prefix: Adds
SN2025-by default. - padding: Ensures five‑digit numbers (e.g.,
SN2025-00001).
Link Sequence to Product Template
Then, add the sequence reference in your module’s manifest:
# file: serial_auto/__manifest__.py
{
'name': 'Serial Auto',
'version': '1.0',
'category': 'Inventory',
'summary': 'Auto‑assign serial numbers',
'depends': ['stock', 'product'],
'data': [
'data/serial_sequence.xml',
'views/product_template_views.xml',
],
'installable': True,
}
Next, extend product.template to store the sequence:
<!-- file: serial_auto/views/product_template_views.xml -->
<odoo xmlns="http://www.w3.org/2000/xmlns/">
<record id="view_product_template_form_serial" model="ir.ui.view">
<field name="name">product.template.form.serial</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_form_view"/>
<field name="arch" type="xml">
<field name="tracking" position="after">
<field name="serial_sequence_id"
widget="selection"
options="{'no_create': False}"
context="{'default_code':'serial.auto'}"/>
</field>
</field>
</record>
</odoo>
H4: Explanation
- We insert
serial_sequence_idaftertracking. - We let users pick or create a sequence.
Automate Serial Number Generation
You can now write Python code to assign serials automatically when you receive a product.
Create a Model Extension
Add a model that hooks into stock moves:
# file: serial_auto/models/stock_move.py
from odoo import models, api
class StockMove(models.Model):
_inherit = 'stock.move'
@api.model
def _generate_serial_number(self, product, qty):
"""Generate serial numbers for incoming moves."""
seq = product.serial_sequence_id
numbers = []
for _ in range(int(qty)):
num = seq.next_by_id()
numbers.append(num)
return numbers
def _onchange_quantity(self):
for move in self:
if move.product_id.tracking == 'serial':
move.move_line_ids = [(5,)]
serials = self._generate_serial_number(move.product_id, move.product_qty)
for sn in serials:
move.move_line_ids |= move.move_line_ids.new({
'product_id': move.product_id.id,
'qty_done': 1,
'lot_name': sn,
})
return super()._onchange_quantity()
Explanation
- We inherit
stock.move. - We define
_generate_serial_number(). - We override
_onchange_quantityto fillmove_line_ids.
Inclusion in Manifest
Don’t forget to update the manifest:
# file: serial_auto/__manifest__.py
'data': [
'data/serial_sequence.xml',
'views/product_template_views.xml',
],
'auto_install': False,
Add Serial Numbers via UI
Alternatively, you can add serials manually or import a list.
Manual Entry
- When you receive items, open the receipt.
- Click the Tracking hamburger icon beside Quantity.
- Choose Manually and add each Serial Number.
- Click Save.
Import Serial List
- Click Import in the serial input window.
- Paste or upload a CSV list of serials.
- Confirm Import.
Validate and Verify Traceability
After assignment, validate your receipts or deliveries.
Validate Receipt
- Click Validate on the receipt.
- Ensure no errors appear (e.g., missing serial).
- If prompted, add any missing serials.
Use Smart Traceability
Next, view the Smart Traceability report:
- Open the product form.
- Click Smart Traceability.
- Observe purchase, stock moves, and sales for each lot/serial.
Generate Traceability Reports
To audit or recall, you can export traceability logs.
Access Reporting
- Go to Inventory > Reporting > Lots & Serials.
- Filter by product or date.
- Export to CSV for analysis.
Tips and Best Practices
- Always activate Lots & Serial Numbers before creating products.
- Use clear prefixes (
SN2025-) to simplify lookup. - Automate generation to reduce human error.
- Regularly back up your database before module updates.
- Train end users on scanning hardware (printers, scanners).
Configure Odoo Serial Numbers – Advanced Scanner Integration
First, you can automate serial entry by integrating USB barcode scanners. Consequently, you reduce manual errors and speed up operations.
Connect a USB Scanner
- Plug the scanner into your Linux/Ubuntu server.
- Verify it appears in
/dev/input/event*. - Next, configure Odoo to listen to keyboard events.
Configure Scanner Shortcut
<!-- file: serial_auto/data/ir_actions.xml -->
<odoo>
<data>
<record id="action_scanner_listener" model="ir.actions.server">
<field name="name">Scanner Listener</field>
<field name="model_id" ref="stock.model_stock_move_line"/>
<field name="code">
if record.product_id.tracking == 'serial':
record.lot_name = env['ir.sequence'].next_by_code('serial.auto')
</field>
</record>
</data>
</odoo>
Moreover, this server action assigns a scanned code as lot_name when you scan a product in the transfer screen. For further details, see the Odoo Keyboard Shortcuts guide.
Troubleshooting Serial Number Configuration
However, you can face issues when serials fail to generate or import. Below we cover common pitfalls and fixes.
Missing Sequence Error
If Odoo raises KeyError: 'serial.auto':
- First, ensure your IR sequence code matches your model field.
- Next, update the module and restart the server:
docker-compose restart odoo
odoo -u serial_auto -d your_db
Import Fails at CSV
When ImportError: invalid literal appears:
- Check your CSV encoding (must be UTF-8).
- Then, ensure your header uses
lot_nameorserial_numberexactly. - Finally, use the Odoo import preview to map fields correctly.
Best Practices for Configure Odoo Serial Numbers Policies
Therefore, you maintain consistent traceability by defining clear naming conventions and retention rules.
Naming Conventions
- Use a fixed prefix per product line (e.g.,
PRD-). - Then, include a date marker (
PRD-2025MMDD-). - Finally, pad your sequence to four digits:
PRD-20250315-0001
Retention and Archiving
Moreover, you can archive old serial records:
# file: serial_auto/models/stock_lot.py
from odoo import models, api
class StockLot(models.Model):
_inherit = 'stock.production.lot'
@api.model
def archive_old_serials(self, days=180):
"""Archive serials older than `days` days."""
threshold = fields.Date.today() - timedelta(days=days)
old = self.search([('create_date', '<', threshold)])
old.write({'active': False})
This script deactivates lots older than six months, thereby improving performance.
Real‑World Case Study: Configure Odoo Serial Numbers in Manufacturing
For example, a small electronics manufacturer reduced recalls by 60% after implementing serial tracking.
- They configured
serial_sequence_idper product type. - Next, they automated scanner input during production.
- Afterwards, they generated weekly traceability reports.
Moreover, they integrated with their CRM via REST APIs:
# file: serial_auto/models/crm_integration.py
import requests
class CRMIntegration(models.Model):
_name = 'serial.crm.integration'
def push_serial(self, lot):
payload = {'serial': lot.name, 'sold_to': lot.partner_id.email}
requests.post('https://crm.example.com/api/serials', json=payload)
Consequently, both sales and support teams now access real‑time serial data in their CRM dashboards.
Optimize Performance for High‑Volume Serial Tracking
Next, you can tune your database to handle thousands of serial operations per minute.
Add PostgreSQL Indexes
-- file: serial_auto/data/sql/stock_lot_index.sql
CREATE INDEX IF NOT EXISTS idx_lot_name ON stock_production_lot (name);
CREATE INDEX IF NOT EXISTS idx_lot_date ON stock_production_lot (create_date);
Furthermore, run VACUUM ANALYZE regularly to maintain index efficiency.
Batch Processing
Instead of creating serials one by one, batch‑generate:
# file: serial_auto/models/stock_move.py (batch update)
@api.model
def batch_generate_serials(self, moves):
for move in moves:
if move.product_id.tracking == 'serial':
sns = move.product_id.serial_sequence_id.next_by_id(int(move.product_qty))
move.message_post(body=f"Generated Serials: {sns}")
Therefore, you prevent performance drops during mass receipts.
Conclusion
By following these extended best practices, you can fully Configure Odoo Serial Numbers for robust traceability. First, you integrated barcode scanners. Then, you troubleshot common errors. Afterwards, you defined naming conventions and retention policies. Next, you applied real‑world manufacturing insights. Finally, you optimized performance with database tuning. Altogether, these steps ensure your inventory stays accurate and auditable. For more examples, explore the Odoo Community Association (OCA) modules.
In this step‑by‑step guide, you learned to Configure Odoo Serial Numbers effectively. First, you enabled tracking. Then, you set tracking per product. After that, you created a custom serial auto‑generation module. Finally, you validated and reported traceability. Moreover, you saw code in XML and Python along with clear explanations. Now, you can manage serial numbers like a pro. For more tips, visit the Odoo Inventory docs.
Discover more from teguhteja.id
Subscribe to get the latest posts sent to your email.


Pingback: Expert Odoo Sequence Setup: 5 Amazing Tips