Many features are included in Odoo by default, but occasionally you will need to modify it to suit your needs. The good news is that Odoo makes it easy to extend models and views without touching the core system.
In this guide, we’ll look at how to add a new field and a custom function to the Sales Order form in Odoo 19.
Step 1: Add a New Field in the Model
Let’s say we want to add a Reference Note field to Sales Orders so users can store extra information.
from odoo import models, fields
class SaleOrder(models.Model):
_inherit = 'sale.order'
reference_note = fields.Char(string="Reference Note")
Here:
- _inherit = 'sale.order' extends the Sales Order model.
- reference_note is our new custom field.
Step 2: Show the Field in the Form View
Now, let’s make the new field visible in the Sales Order form.
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="view_order_form_inherit_note" model="ir.ui.view">
<field name="name">sale.order.form.inherit.note</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<xpath expr="//sheet/notebook/page[@name='order_lines']" position="after">
<page string="Extra Info">
<group>
<field name="reference_note"/>
</group>
</page>
</xpath>
</field>
</record>
</odoo>
This adds a new Extra Info tab in the Sales Order form with our reference_note field.
Step 3: Add a New Function for Business Logic
Instead of overriding existing methods, we’ll add our own function.
This function will generate a quick summary message for the Sales Order.
from odoo import models, fields
class SaleOrder(models.Model):
_inherit = 'sale.order'
reference_note = fields.Char(string="Reference Note")
def generate_summary(self):
"""Return a custom summary message for the sales order."""
for order in self:
return f"Sales Order {order.name} - {order.reference_note or 'No note provided'}"
Now our Sales Order has a simple custom function we can call whenever needed.
Step 4: Add a Button to Trigger the Function
To make it user-friendly, we’ll add a button to the Sales Order form.
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="view_order_form_inherit_button" model="ir.ui.view">
<field name="name">sale.order.form.inherit.button</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<xpath expr="//header" position="inside">
<button name="generate_summary" type="object" string="Generate Summary" class="btn-primary"/>
</xpath>
</field>
</record>
</odoo>
This button will appear at the top of the Sales Order form. When clicked, it will run our custom function.
Conclusion
Customizing Odoo 19 is not as complicated as it may look. By inheriting models and views, you can easily extend existing screens without modifying the core code. In this example, we:
- Created a new field (reference_note).
- Displayed it in the Sales Order form.
- Added a brand-new function (generate_summary).
- Linked the function to a button so users can trigger it directly.
This same approach can be applied to almost any Odoo model or view. With just a few lines of code, you can adapt Odoo to fit your company’s unique workflows—while keeping the system clean, upgrade-friendly, and easy to maintain.
To read more about How to Add a Field to an Existing Model in Odoo 18, refer to our blog How to Add a Field to an Existing Model in Odoo 18.