product_label_section_and_note_field_o2m
The one2many widget that renders invoice and bill lines in Odoo 19: sections, notes, merged product labels, and a column layout that reconfigures itself depending on document type.
| Technical name | product_label_section_and_note_field_o2m |
|---|---|
| Field types | one2many |
| Views | form (embedded list) |
| Module | account, installed with Invoicing or Accounting |
| Used in core | 2 occurrences across 2 modules: invoice_line_ids on the invoice form (account) and order lines in purchase |
| Versions | Odoo 20.0, Odoo 19.0 |
| No-code setup | No. Applied in view XML; Studio has no toggle for it |
| Alternatives | product_label_section_and_note_field, one2many, section_and_note_text, sol_product_many2one |
What the invoice lines widget does
What this means for your team
Supported options in Odoo 19
| Option | Type | What it does |
|---|---|---|
subsections | boolean | Enables the two-level section hierarchy: line_subsection rows render as semibold sub-headings under bold sections. Read in extractProps only; it appears in no options panel or documentation.(default: false)(since Odoo 19.0) |
hide_composition | boolean | Hides the composition details the section renderer can display under grouped lines. extractProps-only, undocumented.(default: false)(since Odoo 19.0) |
hide_prices | boolean | Suppresses price columns on section rows so structural rows stay clean. extractProps-only, undocumented.(default: false)(since Odoo 19.0) |
create | boolean or domain | Inherited from the x2many field. Gates the Add a line action; a domain is evaluated against the parent record. |
delete | boolean or domain | Inherited from the x2many field. Gates row deletion, boolean or parent-evaluated domain. |
write | boolean or domain | Inherited from the x2many field. When it resolves false the embedded rows become read only; core relies on this family to lock posted documents. |
The crud options accept domains, not just booleans. Because the x2many descriptor is inherited, create, delete, link, unlink and write can each be a domain evaluated against the parent record, the pattern core uses to lock line editing on posted documents. The optional="conditional" value, by contrast, is an attribute on the columns inside the sub-list, not an option on the field.
Working examples
Inside the conditional-column and readonly logic
Version compatibility
| Version | Status | Notes |
|---|---|---|
| Odoo 20.0 | In development | Not released. The widget survives but the optional=conditional column logic is deleted on the development branch. Re-verified after launch. |
| Odoo 19.0 | Verified | Introduced in Odoo 19; all behavior on this page verified against the shipped source. |
| Odoo 18.0 | Not available | The widget does not exist. Invoice lines render through the section-and-note family without the o2m product-label subclass. |
| Odoo 17.0 | Not available | The widget does not exist. |
| Odoo 16.0 | Not available | The widget does not exist. |
What is changing in Odoo 20
Common problems and fixes
| Symptom | Cause and fix |
|---|---|
| Product column missing on vendor bills | The renderer defaults optional=conditional product columns to hidden on in_invoice, in_refund and in_receipt documents. Reveal it from the optional-columns dropdown, or inherit the view and set optional="show". |
| Product, Quantity and Unit all missing on customer invoices | The Sale app is not installed, so the renderer hides all three conditional columns on out_ documents. Install Sale, or override the optional attributes in a view inheritance. |
| Conditional columns crash or behave randomly on a custom model | The logic reads parent.move_type and parent.is_sale_installed from the eval context; your parent model lacks them. Use optional="show"/"hide" instead of conditional outside account.move, or provide equivalent fields. |
| subsections or hide_prices seem to be ignored | Typo risk is high because no options panel validates them; they are extractProps-only keys. Check the exact snake_case spelling in options="{...}" and that the widget is the o2m variant, not the base label widget. |
| Section rows do not subtotal a custom amount column | aggregated_fields is an attribute on the field element, not an option. Set aggregated_fields="your_field" on the field tag. |
| Cells look editable on a posted invoice | Readonly styling on product and label cells is intentionally deferred until the parent is posted, cancel or locked. Expected before posting; the fields save-lock correctly regardless of styling. |
Invoice lines widget vs the alternatives
| Widget | Best for | Key difference |
|---|---|---|
product_label_section_and_note_field_o2m | Invoice and bill lines mixing products, sections and notes | Adds document-type-aware conditional columns and product-label cells on top of the section renderer |
| product_label_section_and_note_field | The product cell itself inside these grids | The many2one companion widget for a single cell, not the one2many grid |
| one2many | Plain child grids without sections or product labels | Standard embedded list; display_type rows render as ordinary lines |
| section_and_note_text | The description column inside section-capable grids | Cell-level widget that switches char and text rendering per row type |
| sol_product_many2one | Sale order lines with configurators | Sale's product cell built on the same label base, adding variant and combo configurators |
Frequently asked questions
Why does my vendor bill hide the Product column but my invoice shows it?+
What does optional="conditional" mean in Odoo views?+
Which fields must the parent form provide for the widget to work?+
How do I turn on subsections in invoice lines?+
Can I control which columns section rows aggregate?+
Is product_label_section_and_note_field_o2m available before Odoo 19?+
What changes for this widget in Odoo 20?+
Invoice lines that match how your business actually bills?
Column defaults, section structures, aggregated subtotals and locked-document behavior all live in this one widget family. We tune Odoo invoicing screens for finance teams on 16 through 19, without forking core views.
Fix my invoicing screens