analytic_distribution
The field that splits a journal item across analytic accounts by percentage is one widget: analytic_distribution. Eight options, a tag-based editor, and a type change in 19 worth knowing about.
| Technical name | analytic_distribution |
|---|---|
| Field types | json |
| Views | form, list (journal items, expenses, order lines) |
| Module | analytic, installed with Accounting, Projects and other analytic users |
| Used in core | 22 occurrences across 7 modules, including account, analytic, hr_expense, purchase, l10n_account_withholding_tax, sale |
| Versions | Odoo 20.0, Odoo 19.0, Odoo 18.0, Odoo 17.0, Odoo 16.0 |
| No-code setup | No. The widget is placed in view XML; the analytic plans and distribution models it uses are configured in Accounting settings without code |
| Alternatives | many2many_tags, percentage, Separate analytic account fields (pre-16 pattern) |
What the Analytic Distribution field does
What this means for your team
Supported options in Odoo 19
| Option | Type | What it does |
|---|---|---|
disable_save | boolean | Switches the widget's own save behavior off; the source inverts it into an internal allow_save flag. Used where the surrounding flow, a wizard for instance, owns persistence. |
multi_edit | boolean | Enables list multi-edit behavior, applying one distribution to every selected line in a single edit. |
force_applicability | string (declared boolean) | Declared boolean in the options metadata, but the prop is typed string and passed through as-is, overriding how plan applicability is considered for this field. The implementation wins over the declaration. |
business_domain | string | Business context string passed into the widget's account lookup logic, letting the same field behave per document family. Its attribute-based sibling business_domain_compute is separate; see the deep dive. |
product_field | field name (many2one) | Field on the current record holding the product, part of the context the widget reads for distribution suggestions. |
amount_field | field name (monetary) | Field on the current record holding the line amount the distribution applies to. |
account_field | field name (many2one) | Field on the current record holding the financial account, the third piece of matching context. |
placeholder_field | field name (char) | Char field on the record supplying a dynamic placeholder while the distribution is empty. New in 19; the option does not exist in the 18.0 source. |
One quirk read from the source: force_applicability is declared as a boolean in the options metadata, but the component types the prop as a string and passes the option value through untouched. Treat it as a string-valued setting aligned with analytic applicability values, and test what you pass; the declaration and the implementation disagree, and the implementation wins.
Working examples
Precision, create-only templates, and the attribute in disguise
Version compatibility
| Version | Status | Notes |
|---|---|---|
| Odoo 20.0 | In development | Not released. The development branch keeps the entire option surface unchanged; internals rebuilt. See below. |
| Odoo 19.0 | Verified | All eight options verified against the shipped source. Declared type is json. |
| Odoo 18.0 | Partial / changed | Same widget, but declared types are char and text, no placeholder_field option, and a company_id dependency that 19 dropped. |
| Odoo 17.0 | Verified | Widget present with the same registry name. Not re-verified line by line for this page. |
| Odoo 16.0 | Verified | Widget present with the same registry name, introduced with the analytic plans redesign. Not re-verified line by line for this page. |
Upgrade note for 18 to 19. Two mechanical changes, both verified: the declared field type moved from char and text to json, and the company_id fieldDependency was dropped while placeholder_field was added to the options. Standard views migrate untouched, but custom models mirroring the 18 declaration and JavaScript patches around the widget deserve a check during an Odoo migration.
What is changing in Odoo 20
Common problems and fixes
| Symptom | Cause and fix |
|---|---|
| Percentages keep rounding to whole numbers | The analytic precision fetched through the widget's field dependency is set low. Raise the percentage decimal precision in Accounting settings. |
| A plan column is missing from the editor | The plan's applicability rules exclude this document context. Review plan applicability in Accounting configuration, or set force_applicability on the field. |
| Users cannot edit an existing distribution model from the line | By design: the widget opens templates create-only, with in-place editing disabled in the source. Manage existing models under Accounting configuration instead. |
| business_domain_compute set as an option does nothing | It is an XML attribute, not an option; extractProps reads it from attrs. Move it onto the field element as an attribute. |
| Suggestions ignore the line's product or account | The mapping options are not wired, so the widget cannot see that context. Set product_field, account_field and amount_field as in the example. |
| Custom model's distribution field broke moving 18 to 19 | The widget's declared type changed from char and text to json. Store the distribution in a Json field, matching core's account.move.line. |
Analytic Distribution field vs the alternatives
| Widget | Best for | Key difference |
|---|---|---|
analytic_distribution | Splitting journal items, expenses and order lines across analytic accounts | Percentage tags plus a plan-aware editor on a json field; the only core UI for analytic distributions |
| many2many_tags | Tagging lines with analytic-like labels without percentages | Plain relation, no splits, no plan logic |
| percentage | A single stored percentage with no accounts involved | Formats one number; carries no distribution semantics |
Separate analytic account fields (pre-16 pattern) | Legacy databases predating analytic plans | One many2one per dimension instead of a JSON split; superseded by plans since 16 |
Frequently asked questions
What does the analytic_distribution widget do in Odoo?+
Which field type does analytic_distribution need?+
How do I make the widget suggest the right distribution automatically?+
Can users save their own distribution templates?+
What is the difference between business_domain and business_domain_compute?+
Why will percentages not accept more decimals?+
Does analytic_distribution change in Odoo 20?+
Analytic reports with an empty Unallocated column?
That takes distribution models tuned to your document flows, plans with the right applicability, and this widget wired with full context per view. We set up analytic accounting that people actually fill in, on Odoo 16 through 19.
Book a free consultation