From 8ac36dc7b572080795706bed7eafc1ae13c7443e Mon Sep 17 00:00:00 2001 From: "r.perez" Date: Mon, 4 May 2026 15:09:10 -0400 Subject: [PATCH 1/5] [IMP] sale_order_type: warn about partner and sale_order_type pricelist mismatch --- sale_order_type/README.rst | 73 ++++++++++-------- sale_order_type/models/res_partner.py | 6 ++ sale_order_type/readme/DESCRIPTION.md | 7 ++ sale_order_type/static/description/index.html | 36 +++++---- .../pricelist_conflict_warning_note.png | Bin 0 -> 109597 bytes sale_order_type/tests/test_sale_order_type.py | 20 +++++ sale_order_type/views/res_partner_view.xml | 21 +++++ 7 files changed, 113 insertions(+), 50 deletions(-) create mode 100644 sale_order_type/static/description/pricelist_conflict_warning_note.png diff --git a/sale_order_type/README.rst b/sale_order_type/README.rst index b6d4ed23729..231fc05cfd7 100644 --- a/sale_order_type/README.rst +++ b/sale_order_type/README.rst @@ -1,7 +1,3 @@ -.. image:: https://odoo-community.org/readme-banner-image - :target: https://odoo-community.org/get-involved?utm_source=readme - :alt: Odoo Community Association - =============== Sale Order Type =============== @@ -17,7 +13,7 @@ Sale Order Type .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsale--workflow-lightgray.png?logo=github @@ -42,6 +38,17 @@ You can see sale types as lines of business. You are able to select a sales order type by partner so that when you add a partner to a sales order it will get the related info to it. +Additionally, it adds a warning message to notify users when there is a +mismatch between the partner's default pricelist and the effective +pricelist set by the sales order type. This ensures clarity when +creating sales orders, as the effective pricelist (determined by the +sales order type) will take precedence over the partner's default +pricelist. The warning is only visible for companies without a parent +and when there is a mismatch between the two pricelists. + +.. image:: https://raw.githubusercontent.com/OCA/sale-workflow/18.0/sale_order_type/static/description/pricelist_conflict_warning_note.png + :alt: Pricelist Conflict Warning Note + **Table of contents** .. contents:: @@ -89,50 +96,50 @@ Authors Contributors ------------ -- `Vermon `__ +- `Vermon `__ - - Carlos Sánchez Cifuentes + - Carlos Sánchez Cifuentes -- `AvanzOsc `__ +- `AvanzOsc `__ - - Oihane Crucelaegui - - Ana Juaristi - - Daniel Campos - - Ainara Galdona + - Oihane Crucelaegui + - Ana Juaristi + - Daniel Campos + - Ainara Galdona -- `Agile Business Group `__ +- `Agile Business Group `__ - - Lorenzo Battistini + - Lorenzo Battistini -- `Niboo `__ +- `Niboo `__ - - Samuel Lefever - - Pierre Faniel + - Samuel Lefever + - Pierre Faniel -- `Tecnativa `__ +- `Tecnativa `__ - - Pedro M. Baeza - - David Vidal - - Carlos Dauden - - Sergio Teruel + - Pedro M. Baeza + - David Vidal + - Carlos Dauden + - Sergio Teruel -- `Pesol `__ +- `Pesol `__ - - Angel Moya Pardo - - Antonio J Rubio Lorente + - Angel Moya Pardo + - Antonio J Rubio Lorente -- Rattapong Chokmasermkul -- `Druidoo `__ +- Rattapong Chokmasermkul +- `Druidoo `__ - - Iván Todorovich + - Iván Todorovich -- `GSLab.it `__ +- `GSLab.it `__ - - Giovanni Serra + - Giovanni Serra -- Tharathip Chaweewongphan -- Isaac Gallart -- Denis Rousse +- Tharathip Chaweewongphan +- Isaac Gallart +- Denis Rousse Do not contact contributors directly about support or help with technical issues. diff --git a/sale_order_type/models/res_partner.py b/sale_order_type/models/res_partner.py index ee6360a70ba..b91a63a4303 100644 --- a/sale_order_type/models/res_partner.py +++ b/sale_order_type/models/res_partner.py @@ -13,6 +13,12 @@ class ResPartner(models.Model): copy=True, ) + effective_pricelist_id = fields.Many2one( + comodel_name="product.pricelist", + string="Sale Effective Pricelist", + related="sale_type.pricelist_id", + ) + def copy_data(self, default=None): result = super().copy_data(default=default) for idx, partner in enumerate(self): diff --git a/sale_order_type/readme/DESCRIPTION.md b/sale_order_type/readme/DESCRIPTION.md index a57daa01e42..a110fe4f9d7 100644 --- a/sale_order_type/readme/DESCRIPTION.md +++ b/sale_order_type/readme/DESCRIPTION.md @@ -7,3 +7,10 @@ You can see sale types as lines of business. You are able to select a sales order type by partner so that when you add a partner to a sales order it will get the related info to it. + +Additionally, it adds a warning message to notify users when there is a mismatch between the partner's default pricelist +and the effective pricelist set by the sales order type. This ensures clarity when creating sales orders, as the +effective pricelist (determined by the sales order type) will take precedence over the partner's default pricelist. +The warning is only visible for companies without a parent and when there is a mismatch between the two pricelists. + +![Pricelist Conflict Warning Note](../static/description/pricelist_conflict_warning_note.png) diff --git a/sale_order_type/static/description/index.html b/sale_order_type/static/description/index.html index 69ddf450bff..a183822c91f 100644 --- a/sale_order_type/static/description/index.html +++ b/sale_order_type/static/description/index.html @@ -3,7 +3,7 @@ -README.rst +Sale Order Type -
+
+

Sale Order Type

- - -Odoo Community Association - -
-

Sale Order Type

-

Beta License: AGPL-3 OCA/sale-workflow Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/sale-workflow Translate me on Weblate Try me on Runboat

This module adds a typology for the sales orders. In each different type, you can define, invoicing and refunding journal, a warehouse, a stock route, a sequence, the shipping policy, the invoicing policy, a @@ -382,6 +377,14 @@

Sale Order Type

You can see sale types as lines of business.

You are able to select a sales order type by partner so that when you add a partner to a sales order it will get the related info to it.

+

Additionally, it adds a warning message to notify users when there is a +mismatch between the partner’s default pricelist and the effective +pricelist set by the sales order type. This ensures clarity when +creating sales orders, as the effective pricelist (determined by the +sales order type) will take precedence over the partner’s default +pricelist. The warning is only visible for companies without a parent +and when there is a mismatch between the two pricelists.

+Pricelist Conflict Warning Note

Table of contents

    @@ -397,7 +400,7 @@

    Sale Order Type

-

Configuration

+

Configuration

To configure Sale Order Types you need to:

  1. Go to Sales > Configuration > Sales Orders Types
  2. @@ -405,7 +408,7 @@

    Configuration

-

Usage

+

Usage

  1. Go to Sales > Sales Orders and create a new sale order. Select the new type you have created before and all settings will be @@ -415,7 +418,7 @@

    Usage

-

Bug Tracker

+

Bug Tracker

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed @@ -423,9 +426,9 @@

Bug Tracker

Do not contact contributors directly about support or help with technical issues.

-

Credits

+

Credits

-

Authors

+

Authors

  • Grupo Vermon
  • AvanzOSC
  • @@ -435,7 +438,7 @@

    Authors

-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -499,6 +502,5 @@

Maintainers

-
diff --git a/sale_order_type/static/description/pricelist_conflict_warning_note.png b/sale_order_type/static/description/pricelist_conflict_warning_note.png new file mode 100644 index 0000000000000000000000000000000000000000..57dfd271e55a58d3e7fb460143fe804fbfc1d4e5 GIT binary patch literal 109597 zcmb@ubx>SO^e##a5;VBOVQ`n=n!w=h?(VLGge15HcL?qf+y{3H?hG!2y9^AEoO6Hm z{=0Q=z1KBW)3bN)-K)D-_v-bnuP01NK@ts_2pItZ0Zm#8sDgm-wg~~@&FuTvFIS+* zy(lkVZ(K#C)!x5O1OfG1@aO zv$Upzh8pHp$Do=G9@_OaqsxUT>GQoPbh%%DeFa3W^asWo8>Iv`lRiGZBKrQz>Z48e z?T9Apu3oll)~D(FtUXZHUKWo<1?7u?O|gl~csFS^CN~ep^dArqI+a?H0s${KUec8r z&&s?1vR{``UW@;i{T=uj^S_+kKT2=^%MriFdG&9u6Y>ABnB^}N{vnf7(hWPvQjX;Nk^E7o)L zV$?M9O5_#8ISV!Fhg5h7A!}7;>y_tZ7mFAA-%3058YMIO@I&Nd$dcCqu`YxS(@xT5 zO#A_6no)(OO(@(ryssPCFj60moRUqo&ikqrX~ffp!LXLyXgLLNz05YUpy|rn*=uAj z0nWaM=JR&J*Mg(!;zZc8z+UI`tP8y#>rM`HUozdBMm!jS4%M|1L+a+s+?;WGR-EY0 zT-RVSf(gR{xtOUF_??>k;hz)2zs(6oB%;$1NSh!po_SnQmNzXMU$K>um9?y*4}P`E z>>_j;B`b?b7n8|aGGFiUo1}V1RdmMt)4=&aW zo1dG7Feeiq_;qvH;Bu{}0GF^w_0a3q{+tgu%~^y)t`>v$KwxGtVnvNsY)93u$>ASy zfk-L_Gtr-==Wd?AthhX^pzg1u?)PG__*`O~Ybhzks6=53s$%iE#WVp`xyk|Y#Lif) zAJEK^aJXcW68K#%q@MIM+Soi{WXC^ACb{Onf2pungIt_5is-E>@tu9K(|)Rjdco1EX}#v>Y+IlQVC z4(GyT&-$cN1ezLwnC_Zvr %_W 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

hv;@VSj;na=Hn>1UizbHR|X(~ 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

;^Uv7bVk-fbLL&e)Z}S;#GHpW0{qy|leB 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.partner.sale_type.form res.partner + + + +

+ From 4937508a6a92a06d69e9513ff4788011b9a76ab9 Mon Sep 17 00:00:00 2001 From: Don Kendall Date: Sat, 16 May 2026 15:39:45 -0400 Subject: [PATCH 2/5] [18.0][IMP] sale_order_type: flexible pricelist precedence (type/partner/none) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three precedence modes configurable per `sale.order.type`, exposed in developer mode only: - `type_first` (default — preserves legacy behavior) - `partner_first` — partner's value wins; type fills gaps - `partner_only` — type's propagated fields are ignored A `_sot_resolve` helper consolidates the resolution rule for the seven fields the module propagates (pricelist, payment term, warehouse, picking_policy, incoterm, route, invoice journal). Existing computes collapse to a one-line call into the helper. Adds sibling `effective_*` related fields on `res.partner` for full symmetry with the `effective_pricelist_id` introduced in PR #4328. Adapts the partner-form alert to the active mode and adds a subtle SO form caption when precedence is non-default. Manual edits to SO fields are preserved across recomputes via trigger narrowing — re-firing only on `type_id` / `partner_id` change (matches the lef-adhoc #4273 intent). Tests: new `TestPrecedence` class — six unit tests on `_sot_resolve` plus integration tests across the seven fields and `effective_*` related fields. Existing 24 tests unaffected. No migration script needed: the new `precedence` field defaults to `type_first`, preserving behavior on upgrade. A company-level `sale_order_type_default_precedence` is exposed in Settings as the default-for-new-types convenience knob. --- sale_order_type/README.rst | 133 ++++++--- sale_order_type/__manifest__.py | 2 +- sale_order_type/models/res_company.py | 12 + sale_order_type/models/res_config_settings.py | 4 + sale_order_type/models/res_partner.py | 33 +++ sale_order_type/models/sale.py | 66 +++-- sale_order_type/models/sale_order_type.py | 21 ++ sale_order_type/readme/CONFIGURE.md | 19 +- sale_order_type/readme/DESCRIPTION.md | 26 +- sale_order_type/readme/USAGE.md | 6 +- sale_order_type/static/description/index.html | 89 ++++-- sale_order_type/tests/test_sale_order_type.py | 266 +++++++++++++++++- sale_order_type/views/res_config_settings.xml | 8 + sale_order_type/views/res_partner_view.xml | 40 ++- .../views/sale_order_type_view.xml | 1 + sale_order_type/views/sale_order_view.xml | 14 + 16 files changed, 658 insertions(+), 82 deletions(-) diff --git a/sale_order_type/README.rst b/sale_order_type/README.rst index 231fc05cfd7..797efcfc12f 100644 --- a/sale_order_type/README.rst +++ b/sale_order_type/README.rst @@ -40,14 +40,48 @@ add a partner to a sales order it will get the related info to it. Additionally, it adds a warning message to notify users when there is a mismatch between the partner's default pricelist and the effective -pricelist set by the sales order type. This ensures clarity when -creating sales orders, as the effective pricelist (determined by the -sales order type) will take precedence over the partner's default -pricelist. The warning is only visible for companies without a parent -and when there is a mismatch between the two pricelists. - -.. image:: https://raw.githubusercontent.com/OCA/sale-workflow/18.0/sale_order_type/static/description/pricelist_conflict_warning_note.png - :alt: Pricelist Conflict Warning Note +pricelist set by the sales order type. The warning text adapts to the +type's configured precedence mode (see below) so that the user knows +which value will actually be applied on new sales orders. The warning is +only visible for companies without a parent and when there is a mismatch +between the two pricelists. + +|Pricelist Conflict Warning Note| + +Precedence modes (per sale.order.type) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Each ``sale.order.type`` declares how its propagated fields interact +with the partner's defaults. The setting is exposed in developer mode on +the type form (Sales > Configuration > Sales Order Types > *type* > +Precedence) and applies uniformly to the pricelist, payment term, +warehouse, shipping policy, incoterm, route and invoice journal. + +- **Sale type wins** (``type_first``, default): the type's value + overrides whatever the partner derives. This is the legacy behavior + that has existed in this module since it was first published. +- **Partner wins; type fills gaps** (``partner_first``): the partner's + value is used; the type's value only applies when the partner has no + value for that field. Use this for customers who maintain + authoritative partner-level defaults and treat sale order types + primarily as labeling / reporting / sequence-numbering devices. +- **Ignore type for propagation** (``partner_only``): the type's + pricelist / payment term / warehouse etc. are never pushed onto the + sales order. The type record remains useful for grouping, filtering, + sequences and the per-type invoice journal logic, but its other fields + are decorative. Use this when you want a sale order type purely as a + reporting axis. + +A company-wide default is configurable in *Settings → Sales* and is +applied when new types are created. Changing the default does not modify +existing types; their precedence is preserved. + +Manual edits on a sale order are preserved across recomputes: once a +user sets the pricelist (or payment term, etc.) directly on a SO, the +value will not be overwritten unless ``type_id`` or ``partner_id`` +actually changes. + +.. |Pricelist Conflict Warning Note| image:: https://raw.githubusercontent.com/OCA/sale-workflow/18.0/sale_order_type/static/description/pricelist_conflict_warning_note.png **Table of contents** @@ -60,16 +94,39 @@ Configuration To configure Sale Order Types you need to: 1. Go to **Sales > Configuration > Sales Orders Types** -2. Create a new sale order type with all the settings you want + +2. Create a new sale order type with all the settings you want. + +3. *(Optional, developer mode only)* on each type, set the *Precedence* + field to control how its own pricelist / payment term / warehouse / + etc. interact with the partner's defaults when a sales order is + created: + + - ``Sale type wins`` — legacy behavior; the type overrides whatever + the partner derives. + - ``Partner wins; type fills gaps`` — the partner's value is used; + the type only fills fields the partner leaves empty. + - ``Ignore type for propagation`` — the type's fields are never + applied to new sales orders; the type acts as a label only. + + The default for newly-created types is set in *Settings > Sales > + Quotations & Orders > Default precedence for new Sale Order Types*. + Existing types keep their current value when this default changes — + upgrading the module preserves legacy behavior (``Sale type wins``) + for any type that hasn't been touched. Usage ===== 1. Go to **Sales > Sales Orders** and create a new sale order. Select the new type you have created before and all settings will be - propagated. + propagated. How they're propagated depends on the type's *Precedence* + setting (see CONFIGURE). 2. You can also define a type for a particular partner if you go to *Sales & Purchases* and set a sale order type. +3. When the type's precedence differs from the legacy ``Sale type wins`` + mode, a small caption appears under the SO's pricelist explaining + what behavior to expect. Bug Tracker =========== @@ -96,50 +153,50 @@ Authors Contributors ------------ -- `Vermon `__ +- `Vermon `__ - - Carlos Sánchez Cifuentes + - Carlos Sánchez Cifuentes -- `AvanzOsc `__ +- `AvanzOsc `__ - - Oihane Crucelaegui - - Ana Juaristi - - Daniel Campos - - Ainara Galdona + - Oihane Crucelaegui + - Ana Juaristi + - Daniel Campos + - Ainara Galdona -- `Agile Business Group `__ +- `Agile Business Group `__ - - Lorenzo Battistini + - Lorenzo Battistini -- `Niboo `__ +- `Niboo `__ - - Samuel Lefever - - Pierre Faniel + - Samuel Lefever + - Pierre Faniel -- `Tecnativa `__ +- `Tecnativa `__ - - Pedro M. Baeza - - David Vidal - - Carlos Dauden - - Sergio Teruel + - Pedro M. Baeza + - David Vidal + - Carlos Dauden + - Sergio Teruel -- `Pesol `__ +- `Pesol `__ - - Angel Moya Pardo - - Antonio J Rubio Lorente + - Angel Moya Pardo + - Antonio J Rubio Lorente -- Rattapong Chokmasermkul -- `Druidoo `__ +- Rattapong Chokmasermkul +- `Druidoo `__ - - Iván Todorovich + - Iván Todorovich -- `GSLab.it `__ +- `GSLab.it `__ - - Giovanni Serra + - Giovanni Serra -- Tharathip Chaweewongphan -- Isaac Gallart -- Denis Rousse +- Tharathip Chaweewongphan +- Isaac Gallart +- Denis Rousse Do not contact contributors directly about support or help with technical issues. diff --git a/sale_order_type/__manifest__.py b/sale_order_type/__manifest__.py index 8bdabb3c21f..efee05ee233 100644 --- a/sale_order_type/__manifest__.py +++ b/sale_order_type/__manifest__.py @@ -8,7 +8,7 @@ { "name": "Sale Order Type", - "version": "18.0.1.2.2", + "version": "18.0.2.0.0", "category": "Sales Management", "author": "Grupo Vermon," "AvanzOSC," diff --git a/sale_order_type/models/res_company.py b/sale_order_type/models/res_company.py index 4a6f7130ebd..ea40408e2d3 100644 --- a/sale_order_type/models/res_company.py +++ b/sale_order_type/models/res_company.py @@ -9,3 +9,15 @@ class ResCompany(models.Model): sale_order_type_required = fields.Boolean( default=True, help="If checked, the sale orders will require a type." ) + sale_order_type_default_precedence = fields.Selection( + [ + ("type_first", "Sale type wins"), + ("partner_first", "Partner wins; type fills gaps"), + ("partner_only", "Ignore type for propagation"), + ], + default="type_first", + required=True, + help="Default precedence applied to newly-created sale order types. " + "The actual behavior is set per-type and visible only in developer mode " + "on the sale.order.type form.", + ) diff --git a/sale_order_type/models/res_config_settings.py b/sale_order_type/models/res_config_settings.py index 503c984f242..27bf8d081b0 100644 --- a/sale_order_type/models/res_config_settings.py +++ b/sale_order_type/models/res_config_settings.py @@ -10,3 +10,7 @@ class ResConfigSettings(models.TransientModel): related="company_id.sale_order_type_required", readonly=False, ) + sale_order_type_default_precedence = fields.Selection( + related="company_id.sale_order_type_default_precedence", + readonly=False, + ) diff --git a/sale_order_type/models/res_partner.py b/sale_order_type/models/res_partner.py index b91a63a4303..70d38507cd5 100644 --- a/sale_order_type/models/res_partner.py +++ b/sale_order_type/models/res_partner.py @@ -18,6 +18,39 @@ class ResPartner(models.Model): string="Sale Effective Pricelist", related="sale_type.pricelist_id", ) + effective_payment_term_id = fields.Many2one( + comodel_name="account.payment.term", + string="Sale Effective Payment Term", + related="sale_type.payment_term_id", + ) + effective_warehouse_id = fields.Many2one( + comodel_name="stock.warehouse", + string="Sale Effective Warehouse", + related="sale_type.warehouse_id", + ) + effective_incoterm_id = fields.Many2one( + comodel_name="account.incoterms", + string="Sale Effective Incoterm", + related="sale_type.incoterm_id", + ) + effective_route_id = fields.Many2one( + comodel_name="stock.route", + string="Sale Effective Route", + related="sale_type.route_id", + ) + effective_picking_policy = fields.Selection( + string="Sale Effective Shipping Policy", + related="sale_type.picking_policy", + ) + effective_journal_id = fields.Many2one( + comodel_name="account.journal", + string="Sale Effective Billing Journal", + related="sale_type.journal_id", + ) + effective_precedence = fields.Selection( + string="Sale Effective Precedence", + related="sale_type.precedence", + ) def copy_data(self, default=None): result = super().copy_data(default=default) diff --git a/sale_order_type/models/sale.py b/sale_order_type/models/sale.py index 02e53041874..b9e19a2aebe 100644 --- a/sale_order_type/models/sale.py +++ b/sale_order_type/models/sale.py @@ -22,6 +22,11 @@ class SaleOrder(models.Model): check_company=True, ) order_type_required = fields.Boolean(related="company_id.sale_order_type_required") + type_precedence = fields.Selection( + related="type_id.precedence", + help="The active precedence mode of this order's type — exposed for " + "view-level hints, not user-editable here.", + ) # Fields converted to computed writable picking_policy = fields.Selection( compute="_compute_picking_policy", store=True, readonly=False @@ -50,6 +55,21 @@ def _default_sequence_id(self): limit=1, ) + def _sot_resolve(self, type_value, current_value): + """Apply the active precedence mode of this order's `type_id`. + + Returns the value that the caller (a `_compute_*` body) should write + to the order's field. `current_value` is whatever `super()` already + set (usually the partner-derived default). + """ + mode = self.type_id.precedence or "type_first" + if mode == "partner_only": + return current_value + if mode == "partner_first": + return current_value or type_value + # type_first (legacy) + return type_value or current_value + @api.depends("partner_id", "company_id") @api.depends_context("partner_id", "company_id", "company") def _compute_sale_type_id(self): @@ -73,9 +93,9 @@ def _compute_sale_type_id(self): def _compute_warehouse_id(self): res = super()._compute_warehouse_id() for order in self.filtered("type_id"): - order_type = order.type_id - if order_type.warehouse_id: - order.warehouse_id = order_type.warehouse_id + order.warehouse_id = order._sot_resolve( + order.type_id.warehouse_id, order.warehouse_id + ) return res def _depends_picking_policy(self): @@ -91,27 +111,27 @@ def _compute_picking_policy(self): if hasattr(super(), "_compute_picking_policy"): res = super()._compute_picking_policy() for order in self.filtered("type_id"): - order_type = order.type_id - if order_type.picking_policy: - order.picking_policy = order_type.picking_policy + order.picking_policy = order._sot_resolve( + order.type_id.picking_policy, order.picking_policy + ) return res @api.depends("type_id") def _compute_payment_term_id(self): res = super()._compute_payment_term_id() for order in self.filtered("type_id"): - order_type = order.type_id - if order_type.payment_term_id: - order.payment_term_id = order_type.payment_term_id + order.payment_term_id = order._sot_resolve( + order.type_id.payment_term_id, order.payment_term_id + ) return res @api.depends("type_id") def _compute_pricelist_id(self): res = super()._compute_pricelist_id() for order in self.filtered("type_id"): - order_type = order.type_id - if order_type.pricelist_id: - order.pricelist_id = order_type.pricelist_id + order.pricelist_id = order._sot_resolve( + order.type_id.pricelist_id, order.pricelist_id + ) return res @api.depends("type_id") @@ -120,9 +140,9 @@ def _compute_incoterm(self): if hasattr(super(), "_compute_incoterm"): res = super()._compute_incoterm() for order in self.filtered("type_id"): - order_type = order.type_id - if order_type.incoterm_id: - order.incoterm = order_type.incoterm_id + order.incoterm = order._sot_resolve( + order.type_id.incoterm_id, order.incoterm + ) return res @api.depends("type_id") @@ -179,7 +199,15 @@ def write(self, vals): def _prepare_invoice(self): res = super()._prepare_invoice() - if self.type_id.journal_id: + # Journal: + # - `type_first`: legacy — type's journal overrides super's choice. + # - `partner_first` / `partner_only`: leave whatever super chose. + # We don't use `_sot_resolve` here: super() may leave `journal_id` + # implicit (the account.move._get_default_journal logic fills it), + # so a three-way merge would spuriously fall back to the type's + # journal in non-type_first modes. + mode = self.type_id.precedence or "type_first" + if mode == "type_first" and self.type_id.journal_id: res["journal_id"] = self.type_id.journal_id.id if self.type_id: res["sale_type_id"] = self.type_id.id @@ -197,7 +225,7 @@ def _compute_route_id(self): if hasattr(super(), "_compute_route_id"): res = super()._compute_route_id() for line in self.filtered("order_id.type_id"): - order_type = line.order_id.type_id - if order_type.route_id: - line.route_id = order_type.route_id + line.route_id = line.order_id._sot_resolve( + line.order_id.type_id.route_id, line.route_id + ) return res diff --git a/sale_order_type/models/sale_order_type.py b/sale_order_type/models/sale_order_type.py index 4c4e86e6ee8..c2c33fe2ef7 100644 --- a/sale_order_type/models/sale_order_type.py +++ b/sale_order_type/models/sale_order_type.py @@ -59,6 +59,27 @@ class SaleOrderTypology(models.Model): ) active = fields.Boolean(default=True) quotation_validity_days = fields.Integer(string="Quotation Validity (Days)") + precedence = fields.Selection( + [ + ("type_first", "Sale type wins"), + ("partner_first", "Partner wins; type fills gaps"), + ("partner_only", "Ignore type for propagation"), + ], + required=True, + default=lambda self: ( + self.env.company.sale_order_type_default_precedence or "type_first" + ), + help="How this type resolves conflicts between its own pricelist / " + "payment_term / warehouse / etc. and the partner's defaults when a " + "sale order is created.\n" + "- Sale type wins: legacy behavior. The type's value overrides the " + "partner's whenever both are set.\n" + "- Partner wins; type fills gaps: the partner's default is used; the " + "type only fills fields the partner leaves empty.\n" + "- Ignore type for propagation: fields on this type are not pushed " + "onto sale orders at all; the type is then a labeling / reporting " + "construct only.", + ) @api.model def _get_domain_sequence_id(self): diff --git a/sale_order_type/readme/CONFIGURE.md b/sale_order_type/readme/CONFIGURE.md index ffd7a4bd0b2..28690469ba3 100644 --- a/sale_order_type/readme/CONFIGURE.md +++ b/sale_order_type/readme/CONFIGURE.md @@ -1,4 +1,21 @@ To configure Sale Order Types you need to: 1. Go to **Sales \> Configuration \> Sales Orders Types** -2. Create a new sale order type with all the settings you want +2. Create a new sale order type with all the settings you want. +3. *(Optional, developer mode only)* on each type, set the *Precedence* + field to control how its own pricelist / payment term / warehouse / + etc. interact with the partner's defaults when a sales order is + created: + + - `Sale type wins` — legacy behavior; the type overrides whatever + the partner derives. + - `Partner wins; type fills gaps` — the partner's value is used; + the type only fills fields the partner leaves empty. + - `Ignore type for propagation` — the type's fields are never + applied to new sales orders; the type acts as a label only. + + The default for newly-created types is set in *Settings \> Sales \> + Quotations & Orders \> Default precedence for new Sale Order + Types*. Existing types keep their current value when this default + changes — upgrading the module preserves legacy behavior + (`Sale type wins`) for any type that hasn't been touched. diff --git a/sale_order_type/readme/DESCRIPTION.md b/sale_order_type/readme/DESCRIPTION.md index a110fe4f9d7..82550bd5150 100644 --- a/sale_order_type/readme/DESCRIPTION.md +++ b/sale_order_type/readme/DESCRIPTION.md @@ -9,8 +9,30 @@ You are able to select a sales order type by partner so that when you add a partner to a sales order it will get the related info to it. Additionally, it adds a warning message to notify users when there is a mismatch between the partner's default pricelist -and the effective pricelist set by the sales order type. This ensures clarity when creating sales orders, as the -effective pricelist (determined by the sales order type) will take precedence over the partner's default pricelist. +and the effective pricelist set by the sales order type. The warning text adapts to the type's configured precedence mode +(see below) so that the user knows which value will actually be applied on new sales orders. The warning is only visible for companies without a parent and when there is a mismatch between the two pricelists. ![Pricelist Conflict Warning Note](../static/description/pricelist_conflict_warning_note.png) + +### Precedence modes (per sale.order.type) + +Each `sale.order.type` declares how its propagated fields interact with the partner's defaults. The setting is exposed +in developer mode on the type form (Sales > Configuration > Sales Order Types > *type* > Precedence) and applies +uniformly to the pricelist, payment term, warehouse, shipping policy, incoterm, route and invoice journal. + +- **Sale type wins** (`type_first`, default): the type's value overrides whatever the partner derives. This is the + legacy behavior that has existed in this module since it was first published. +- **Partner wins; type fills gaps** (`partner_first`): the partner's value is used; the type's value only applies + when the partner has no value for that field. Use this for customers who maintain authoritative partner-level + defaults and treat sale order types primarily as labeling / reporting / sequence-numbering devices. +- **Ignore type for propagation** (`partner_only`): the type's pricelist / payment term / warehouse etc. are never + pushed onto the sales order. The type record remains useful for grouping, filtering, sequences and the per-type + invoice journal logic, but its other fields are decorative. Use this when you want a sale order type purely as a + reporting axis. + +A company-wide default is configurable in *Settings → Sales* and is applied when new types are created. Changing the +default does not modify existing types; their precedence is preserved. + +Manual edits on a sale order are preserved across recomputes: once a user sets the pricelist (or payment term, etc.) +directly on a SO, the value will not be overwritten unless `type_id` or `partner_id` actually changes. diff --git a/sale_order_type/readme/USAGE.md b/sale_order_type/readme/USAGE.md index 94f740421e5..63f85d8be6b 100644 --- a/sale_order_type/readme/USAGE.md +++ b/sale_order_type/readme/USAGE.md @@ -1,5 +1,9 @@ 1. Go to **Sales \> Sales Orders** and create a new sale order. Select the new type you have created before and all settings will be - propagated. + propagated. How they're propagated depends on the type's *Precedence* + setting (see CONFIGURE). 2. You can also define a type for a particular partner if you go to *Sales & Purchases* and set a sale order type. +3. When the type's precedence differs from the legacy `Sale type wins` + mode, a small caption appears under the SO's pricelist explaining + what behavior to expect. diff --git a/sale_order_type/static/description/index.html b/sale_order_type/static/description/index.html index a183822c91f..e6c89da2080 100644 --- a/sale_order_type/static/description/index.html +++ b/sale_order_type/static/description/index.html @@ -379,12 +379,42 @@

Sale Order Type

add a partner to a sales order it will get the related info to it.

Additionally, it adds a warning message to notify users when there is a mismatch between the partner’s default pricelist and the effective -pricelist set by the sales order type. This ensures clarity when -creating sales orders, as the effective pricelist (determined by the -sales order type) will take precedence over the partner’s default -pricelist. The warning is only visible for companies without a parent -and when there is a mismatch between the two pricelists.

-Pricelist Conflict Warning Note +pricelist set by the sales order type. The warning text adapts to the +type’s configured precedence mode (see below) so that the user knows +which value will actually be applied on new sales orders. The warning is +only visible for companies without a parent and when there is a mismatch +between the two pricelists.

+

Pricelist Conflict Warning Note

+
+

Precedence modes (per sale.order.type)

+

Each sale.order.type declares how its propagated fields interact +with the partner’s defaults. The setting is exposed in developer mode on +the type form (Sales > Configuration > Sales Order Types > type > +Precedence) and applies uniformly to the pricelist, payment term, +warehouse, shipping policy, incoterm, route and invoice journal.

+
    +
  • Sale type wins (type_first, default): the type’s value +overrides whatever the partner derives. This is the legacy behavior +that has existed in this module since it was first published.
  • +
  • Partner wins; type fills gaps (partner_first): the partner’s +value is used; the type’s value only applies when the partner has no +value for that field. Use this for customers who maintain +authoritative partner-level defaults and treat sale order types +primarily as labeling / reporting / sequence-numbering devices.
  • +
  • Ignore type for propagation (partner_only): the type’s +pricelist / payment term / warehouse etc. are never pushed onto the +sales order. The type record remains useful for grouping, filtering, +sequences and the per-type invoice journal logic, but its other fields +are decorative. Use this when you want a sale order type purely as a +reporting axis.
  • +
+

A company-wide default is configurable in Settings → Sales and is +applied when new types are created. Changing the default does not modify +existing types; their precedence is preserved.

+

Manual edits on a sale order are preserved across recomputes: once a +user sets the pricelist (or payment term, etc.) directly on a SO, the +value will not be overwritten unless type_id or partner_id +actually changes.

Table of contents

    @@ -400,25 +430,49 @@

    Sale Order Type

-

Configuration

+

Configuration

To configure Sale Order Types you need to:

-
    -
  1. Go to Sales > Configuration > Sales Orders Types
  2. -
  3. Create a new sale order type with all the settings you want
  4. +
      +
    1. Go to Sales > Configuration > Sales Orders Types

      +
    2. +
    3. Create a new sale order type with all the settings you want.

      +
    4. +
    5. (Optional, developer mode only) on each type, set the Precedence +field to control how its own pricelist / payment term / warehouse / +etc. interact with the partner’s defaults when a sales order is +created:

      +
        +
      • Sale type wins — legacy behavior; the type overrides whatever +the partner derives.
      • +
      • Partner wins; type fills gaps — the partner’s value is used; +the type only fills fields the partner leaves empty.
      • +
      • Ignore type for propagation — the type’s fields are never +applied to new sales orders; the type acts as a label only.
      • +
      +

      The default for newly-created types is set in Settings > Sales > +Quotations & Orders > Default precedence for new Sale Order Types. +Existing types keep their current value when this default changes — +upgrading the module preserves legacy behavior (Sale type wins) +for any type that hasn’t been touched.

      +
-

Usage

+

Usage

  1. Go to Sales > Sales Orders and create a new sale order. Select the new type you have created before and all settings will be -propagated.
  2. +propagated. How they’re propagated depends on the type’s Precedence +setting (see CONFIGURE).
  3. You can also define a type for a particular partner if you go to Sales & Purchases and set a sale order type.
  4. +
  5. When the type’s precedence differs from the legacy Sale type wins +mode, a small caption appears under the SO’s pricelist explaining +what behavior to expect.
-

Bug Tracker

+

Bug Tracker

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed @@ -426,9 +480,9 @@

Bug Tracker

Do not contact contributors directly about support or help with technical issues.

-

Credits

+

Credits

-

Authors

+

Authors

  • Grupo Vermon
  • AvanzOSC
  • @@ -438,7 +492,7 @@

    Authors

-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -502,5 +556,6 @@

Maintainers

+
diff --git a/sale_order_type/tests/test_sale_order_type.py b/sale_order_type/tests/test_sale_order_type.py index 73c3fbff211..3ca03158c3c 100644 --- a/sale_order_type/tests/test_sale_order_type.py +++ b/sale_order_type/tests/test_sale_order_type.py @@ -5,7 +5,7 @@ from freezegun import freeze_time from odoo import fields -from odoo.tests import Form +from odoo.tests import Form, tagged from odoo.addons.base.tests.common import BaseCommon @@ -361,3 +361,267 @@ def test_credit_note_preserves_sale_type_from_sale_order(self): "not use partner's default sale type " f"(partner has: {sale_order.partner_id.sale_type.name})", ) + + +@tagged("post_install", "-at_install") +class TestPrecedence(BaseCommon): + """Cover the three precedence modes on `sale.order.type`. + + Strategy: unit-test the resolver helper directly with synthetic + inputs, then a handful of full-flow integration tests for the + cases we can drive without fighting Odoo's per-company property + field plumbing. + """ + + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.partner = cls.env["res.partner"].create( + { + "name": "Precedence Test Partner", + "is_company": True, + "country_id": cls.env.ref("base.us").id, + } + ) + cls.pl_partner = cls.env["product.pricelist"].create( + {"name": "Partner Pricelist", "company_id": False} + ) + cls.pl_type = cls.env["product.pricelist"].create( + {"name": "Type Pricelist", "company_id": False} + ) + cls.pt_type = cls.env["account.payment.term"].create( + {"name": "Type Payment Term"} + ) + cls.wh_type = cls.env["stock.warehouse"].create( + {"name": "Type Warehouse", "code": "TYP"} + ) + cls.inc_type = cls.env.ref("account.incoterm_EXW") + cls.route_type = cls.env["stock.route"].create( + {"name": "Type Route", "sale_selectable": True} + ) + cls.journal_type = cls.env["account.journal"].create( + {"name": "Type Journal", "type": "sale", "code": "TYPJ"} + ) + + cls.type_full = cls.env["sale.order.type"].create( + { + "name": "Full Type", + "pricelist_id": cls.pl_type.id, + "payment_term_id": cls.pt_type.id, + "warehouse_id": cls.wh_type.id, + "picking_policy": "one", + "incoterm_id": cls.inc_type.id, + "route_id": cls.route_type.id, + "journal_id": cls.journal_type.id, + } + ) + cls.product = cls.env["product.product"].create( + {"type": "service", "invoice_policy": "order", "name": "P"} + ) + + def _set_mode(self, mode): + self.type_full.precedence = mode + + def _new_so(self): + f = Form(self.env["sale.order"]) + f.partner_id = self.partner + f.type_id = self.type_full + with f.order_line.new() as line: + line.product_id = self.product + line.product_uom_qty = 1.0 + return f.save() + + # ----- _sot_resolve helper (unit) ---------------------------------- + + def test_sot_resolve_type_first_picks_type(self): + self._set_mode("type_first") + order = self.env["sale.order"].new({"type_id": self.type_full.id}) + self.assertEqual(order._sot_resolve("type-val", "current-val"), "type-val") + + def test_sot_resolve_type_first_falls_back_to_current(self): + """type_first: when type is empty, keep super's value.""" + self._set_mode("type_first") + order = self.env["sale.order"].new({"type_id": self.type_full.id}) + self.assertEqual(order._sot_resolve(False, "current-val"), "current-val") + + def test_sot_resolve_partner_first_picks_current(self): + self._set_mode("partner_first") + order = self.env["sale.order"].new({"type_id": self.type_full.id}) + self.assertEqual(order._sot_resolve("type-val", "current-val"), "current-val") + + def test_sot_resolve_partner_first_fills_gap_with_type(self): + self._set_mode("partner_first") + order = self.env["sale.order"].new({"type_id": self.type_full.id}) + self.assertEqual(order._sot_resolve("type-val", False), "type-val") + + def test_sot_resolve_partner_only_ignores_type(self): + self._set_mode("partner_only") + order = self.env["sale.order"].new({"type_id": self.type_full.id}) + self.assertEqual(order._sot_resolve("type-val", "current-val"), "current-val") + + def test_sot_resolve_partner_only_leaves_empty(self): + self._set_mode("partner_only") + order = self.env["sale.order"].new({"type_id": self.type_full.id}) + self.assertFalse(order._sot_resolve("type-val", False)) + + # ----- integration: type_first end-to-end --------------------------- + + def test_type_first_pricelist(self): + self._set_mode("type_first") + order = self._new_so() + self.assertEqual(order.pricelist_id, self.pl_type) + + def test_type_first_payment_term(self): + self._set_mode("type_first") + order = self._new_so() + self.assertEqual(order.payment_term_id, self.pt_type) + + def test_type_first_warehouse(self): + self._set_mode("type_first") + order = self._new_so() + self.assertEqual(order.warehouse_id, self.wh_type) + + def test_type_first_picking_policy(self): + self._set_mode("type_first") + order = self._new_so() + self.assertEqual(order.picking_policy, "one") + + def test_type_first_incoterm(self): + self._set_mode("type_first") + order = self._new_so() + self.assertEqual(order.incoterm, self.inc_type) + + def test_type_first_route(self): + self._set_mode("type_first") + order = self._new_so() + self.assertEqual(order.order_line.route_id, self.route_type) + + def test_type_first_invoice_journal(self): + self._set_mode("type_first") + order = self._new_so() + self.assertEqual(order._prepare_invoice()["journal_id"], self.journal_type.id) + + # ----- integration: partner_only end-to-end ------------------------- + # (No need for partner.property_product_pricelist setup — the test + # asserts that the type's value is NOT propagated regardless of + # partner state.) + + def test_partner_only_no_invoice_journal_override(self): + self._set_mode("partner_only") + order = self._new_so() + self.assertNotEqual( + order._prepare_invoice().get("journal_id"), self.journal_type.id + ) + + def test_partner_only_warehouse_not_propagated(self): + self._set_mode("partner_only") + order = self._new_so() + # Whatever warehouse super() chose, it should not be the type's. + self.assertNotEqual(order.warehouse_id, self.wh_type) + + def test_partner_only_picking_policy_not_propagated(self): + self._set_mode("partner_only") + order = self._new_so() + # Default picking_policy is 'direct'; type carries 'one'. + self.assertEqual(order.picking_policy, "direct") + + def test_partner_only_incoterm_not_propagated(self): + self._set_mode("partner_only") + order = self._new_so() + self.assertFalse(order.incoterm) + + def test_partner_only_route_not_propagated(self): + self._set_mode("partner_only") + order = self._new_so() + self.assertFalse(order.order_line.route_id) + + # ----- cross-cutting ------------------------------------------------ + + def test_per_type_precedence_independent(self): + """Two types with different precedence yield different SO results. + Asserts on warehouse_id which is reliably propagated without + needing partner-property setup. + """ + other_type = self.type_full.copy( + {"name": "Partner-only Twin", "precedence": "partner_only"} + ) + self.type_full.precedence = "type_first" + + f1 = Form(self.env["sale.order"]) + f1.partner_id = self.partner + f1.type_id = self.type_full + with f1.order_line.new() as line: + line.product_id = self.product + so1 = f1.save() + self.assertEqual(so1.warehouse_id, self.wh_type) + + f2 = Form(self.env["sale.order"]) + f2.partner_id = self.partner + f2.type_id = other_type + with f2.order_line.new() as line: + line.product_id = self.product + so2 = f2.save() + self.assertNotEqual(so2.warehouse_id, self.wh_type) + + def test_new_type_inherits_company_default(self): + self.env.company.sale_order_type_default_precedence = "partner_first" + new_type = self.env["sale.order.type"].create({"name": "Inheritor"}) + self.assertEqual(new_type.precedence, "partner_first") + # Reset for downstream tests. + self.env.company.sale_order_type_default_precedence = "type_first" + + def test_existing_default_type_is_type_first(self): + """The seed `default_type` ships with type_first to preserve behavior.""" + default_type = self.env.ref( + "sale_order_type.default_type", raise_if_not_found=False + ) + if default_type: + self.assertEqual(default_type.precedence, "type_first") + + def test_manual_pricelist_edit_preserved_after_unrelated_write(self): + self._set_mode("type_first") + order = self._new_so() + order.pricelist_id = self.pl_partner + order.note = "Some unrelated edit" + self.assertEqual(order.pricelist_id, self.pl_partner) + + def test_manual_pricelist_edit_overridden_on_type_change(self): + self._set_mode("type_first") + order = self._new_so() + order.pricelist_id = self.pl_partner + other_type = self.type_full.copy( + {"name": "Trigger", "precedence": "type_first"} + ) + order.type_id = other_type + self.assertEqual(order.pricelist_id, self.pl_type) + + # ----- effective_* related fields on res.partner ------------------- + + def test_effective_pricelist_id_related(self): + self.partner.sale_type = self.type_full + self.assertEqual(self.partner.effective_pricelist_id, self.pl_type) + + def test_effective_payment_term_id_related(self): + self.partner.sale_type = self.type_full + self.assertEqual(self.partner.effective_payment_term_id, self.pt_type) + + def test_effective_warehouse_id_related(self): + self.partner.sale_type = self.type_full + self.assertEqual(self.partner.effective_warehouse_id, self.wh_type) + + def test_effective_incoterm_id_related(self): + self.partner.sale_type = self.type_full + self.assertEqual(self.partner.effective_incoterm_id, self.inc_type) + + def test_effective_route_id_related(self): + self.partner.sale_type = self.type_full + self.assertEqual(self.partner.effective_route_id, self.route_type) + + def test_effective_journal_id_related(self): + self.partner.sale_type = self.type_full + self.assertEqual(self.partner.effective_journal_id, self.journal_type) + + def test_effective_precedence_related(self): + self.partner.sale_type = self.type_full + self.type_full.precedence = "partner_first" + self.assertEqual(self.partner.effective_precedence, "partner_first") diff --git a/sale_order_type/views/res_config_settings.xml b/sale_order_type/views/res_config_settings.xml index 76734bdbd4e..26da693c481 100644 --- a/sale_order_type/views/res_config_settings.xml +++ b/sale_order_type/views/res_config_settings.xml @@ -14,6 +14,14 @@ > + + + diff --git a/sale_order_type/views/res_partner_view.xml b/sale_order_type/views/res_partner_view.xml index 8f333018a2d..30c4cb93e4d 100644 --- a/sale_order_type/views/res_partner_view.xml +++ b/sale_order_type/views/res_partner_view.xml @@ -10,13 +10,15 @@ + + + + + + diff --git a/sale_order_type/views/sale_order_type_view.xml b/sale_order_type/views/sale_order_type_view.xml index 7b494a1afe8..fce8a6a5b33 100644 --- a/sale_order_type/views/sale_order_type_view.xml +++ b/sale_order_type/views/sale_order_type_view.xml @@ -49,6 +49,7 @@ groups="product.group_product_pricelist" /> + diff --git a/sale_order_type/views/sale_order_view.xml b/sale_order_type/views/sale_order_view.xml index f8f6835918a..d709546f475 100644 --- a/sale_order_type/views/sale_order_view.xml +++ b/sale_order_type/views/sale_order_view.xml @@ -11,6 +11,20 @@ required="order_type_required" readonly="state in ['sale', 'cancel'] or locked" /> + +
+ + Pricelist / payment term / warehouse from the partner take precedence over this type's values; the type only fills gaps. + + + This type's pricelist / payment term / warehouse are ignored when computing sales-order fields — the type is a labeling construct only. + +
From bef06115444512530f2e56c9b74c497578d8fa4b Mon Sep 17 00:00:00 2001 From: Don Kendall Date: Sat, 16 May 2026 16:02:16 -0400 Subject: [PATCH 3/5] [18.0][IMP] sale_order_type: forward-compat hooks for web_field_provenance (Huly OCA-23) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `_sot_resolve` now accepts an optional `fname` argument; when the companion module `web_field_provenance` is installed, manual user edits to that field win over the precedence rules regardless of mode. Falls through silently when `_user_set` is not on the record, so this module continues to work standalone. Threads field names through the seven existing call sites (warehouse_id, picking_policy, payment_term_id, pricelist_id, incoterm, route_id). The integration is one `hasattr` check inside the helper — zero behavior change without OCA-23 installed. Documents the pattern in DESCRIPTION.md so reviewers see the upstream roadmap and the standalone vs. composed semantics. --- sale_order_type/README.rst | 21 ++++++++--- sale_order_type/models/sale.py | 35 +++++++++++++++---- sale_order_type/readme/DESCRIPTION.md | 20 +++++++++-- sale_order_type/static/description/index.html | 20 ++++++++--- 4 files changed, 79 insertions(+), 17 deletions(-) diff --git a/sale_order_type/README.rst b/sale_order_type/README.rst index 797efcfc12f..e123f69c9dd 100644 --- a/sale_order_type/README.rst +++ b/sale_order_type/README.rst @@ -76,10 +76,23 @@ A company-wide default is configurable in *Settings → Sales* and is applied when new types are created. Changing the default does not modify existing types; their precedence is preserved. -Manual edits on a sale order are preserved across recomputes: once a -user sets the pricelist (or payment term, etc.) directly on a SO, the -value will not be overwritten unless ``type_id`` or ``partner_id`` -actually changes. +Manual edits on a sale order are preserved across recomputes by trigger +narrowing: once a user sets the pricelist (or payment term, etc.) +directly on a SO, the value will not be overwritten unless ``type_id`` +or ``partner_id`` actually changes. A ``type_id`` change *does* re-fire +the type's value in ``type_first`` mode — this is the documented legacy +behavior and matches user expectations for an explicit type change. + +For stricter dirty-state preservation (preserve user edits even on a +type change, with a Salesforce/SAP-style badge to surface "this value is +anchored by the user"), install the companion module +``web_field_provenance`` when it's available (see Huly OCA-23 / ledoent +initiative). This module's ``record._user_set(fname)`` API is consulted +automatically by ``sale.order._sot_resolve`` — when installed and the +user has manually set a field, the precedence rules are bypassed and the +manual value wins regardless of mode. The integration is a soft +dependency: this module works standalone and behaves identically when +``web_field_provenance`` is not installed. .. |Pricelist Conflict Warning Note| image:: https://raw.githubusercontent.com/OCA/sale-workflow/18.0/sale_order_type/static/description/pricelist_conflict_warning_note.png diff --git a/sale_order_type/models/sale.py b/sale_order_type/models/sale.py index b9e19a2aebe..912c19f8110 100644 --- a/sale_order_type/models/sale.py +++ b/sale_order_type/models/sale.py @@ -2,10 +2,13 @@ # Copyright 2023 Tecnativa - Sergio Teruel # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +import logging from datetime import datetime, timedelta from odoo import _, api, fields, models +_logger = logging.getLogger(__name__) + class SaleOrder(models.Model): _inherit = "sale.order" @@ -55,13 +58,29 @@ def _default_sequence_id(self): limit=1, ) - def _sot_resolve(self, type_value, current_value): + def _sot_resolve(self, type_value, current_value, fname=None): """Apply the active precedence mode of this order's `type_id`. Returns the value that the caller (a `_compute_*` body) should write to the order's field. `current_value` is whatever `super()` already set (usually the partner-derived default). + + `fname` (optional) — the name of the field being resolved. When the + `web_field_provenance` module (Huly OCA-23) is installed and the + user has manually edited this field on the order, the manual value + is preserved regardless of precedence mode. This integration is a + soft dependency: `_user_set` is only consulted if `record._user_set` + exists, so installs without the provenance module behave exactly + as before. """ + if fname and hasattr(self, "_user_set"): + try: + if self._user_set(fname): + return current_value + except Exception as exc: + # Provenance lookup must never break the compute; fall + # through to the regular precedence resolution. + _logger.debug("_user_set lookup failed for %s: %s", fname, exc) mode = self.type_id.precedence or "type_first" if mode == "partner_only": return current_value @@ -94,7 +113,7 @@ def _compute_warehouse_id(self): res = super()._compute_warehouse_id() for order in self.filtered("type_id"): order.warehouse_id = order._sot_resolve( - order.type_id.warehouse_id, order.warehouse_id + order.type_id.warehouse_id, order.warehouse_id, "warehouse_id" ) return res @@ -112,7 +131,7 @@ def _compute_picking_policy(self): res = super()._compute_picking_policy() for order in self.filtered("type_id"): order.picking_policy = order._sot_resolve( - order.type_id.picking_policy, order.picking_policy + order.type_id.picking_policy, order.picking_policy, "picking_policy" ) return res @@ -121,7 +140,9 @@ def _compute_payment_term_id(self): res = super()._compute_payment_term_id() for order in self.filtered("type_id"): order.payment_term_id = order._sot_resolve( - order.type_id.payment_term_id, order.payment_term_id + order.type_id.payment_term_id, + order.payment_term_id, + "payment_term_id", ) return res @@ -130,7 +151,7 @@ def _compute_pricelist_id(self): res = super()._compute_pricelist_id() for order in self.filtered("type_id"): order.pricelist_id = order._sot_resolve( - order.type_id.pricelist_id, order.pricelist_id + order.type_id.pricelist_id, order.pricelist_id, "pricelist_id" ) return res @@ -141,7 +162,7 @@ def _compute_incoterm(self): res = super()._compute_incoterm() for order in self.filtered("type_id"): order.incoterm = order._sot_resolve( - order.type_id.incoterm_id, order.incoterm + order.type_id.incoterm_id, order.incoterm, "incoterm" ) return res @@ -226,6 +247,6 @@ def _compute_route_id(self): res = super()._compute_route_id() for line in self.filtered("order_id.type_id"): line.route_id = line.order_id._sot_resolve( - line.order_id.type_id.route_id, line.route_id + line.order_id.type_id.route_id, line.route_id, "route_id" ) return res diff --git a/sale_order_type/readme/DESCRIPTION.md b/sale_order_type/readme/DESCRIPTION.md index 82550bd5150..23efc4f912e 100644 --- a/sale_order_type/readme/DESCRIPTION.md +++ b/sale_order_type/readme/DESCRIPTION.md @@ -34,5 +34,21 @@ uniformly to the pricelist, payment term, warehouse, shipping policy, incoterm, A company-wide default is configurable in *Settings → Sales* and is applied when new types are created. Changing the default does not modify existing types; their precedence is preserved. -Manual edits on a sale order are preserved across recomputes: once a user sets the pricelist (or payment term, etc.) -directly on a SO, the value will not be overwritten unless `type_id` or `partner_id` actually changes. +Manual edits on a sale order are preserved across recomputes by trigger +narrowing: once a user sets the pricelist (or payment term, etc.) +directly on a SO, the value will not be overwritten unless `type_id` or +`partner_id` actually changes. A `type_id` change *does* re-fire the +type's value in `type_first` mode — this is the documented legacy +behavior and matches user expectations for an explicit type change. + +For stricter dirty-state preservation (preserve user edits even on a +type change, with a Salesforce/SAP-style badge to surface "this value +is anchored by the user"), install the companion module +`web_field_provenance` when it's available +(see Huly OCA-23 / ledoent initiative). This module's +`record._user_set(fname)` API is consulted automatically by +`sale.order._sot_resolve` — when installed and the user has manually +set a field, the precedence rules are bypassed and the manual value +wins regardless of mode. The integration is a soft dependency: this +module works standalone and behaves identically when +`web_field_provenance` is not installed. diff --git a/sale_order_type/static/description/index.html b/sale_order_type/static/description/index.html index e6c89da2080..6fbc58fdd0e 100644 --- a/sale_order_type/static/description/index.html +++ b/sale_order_type/static/description/index.html @@ -411,10 +411,22 @@

Precedence modes (per sale.order.type)

A company-wide default is configurable in Settings → Sales and is applied when new types are created. Changing the default does not modify existing types; their precedence is preserved.

-

Manual edits on a sale order are preserved across recomputes: once a -user sets the pricelist (or payment term, etc.) directly on a SO, the -value will not be overwritten unless type_id or partner_id -actually changes.

+

Manual edits on a sale order are preserved across recomputes by trigger +narrowing: once a user sets the pricelist (or payment term, etc.) +directly on a SO, the value will not be overwritten unless type_id +or partner_id actually changes. A type_id change does re-fire +the type’s value in type_first mode — this is the documented legacy +behavior and matches user expectations for an explicit type change.

+

For stricter dirty-state preservation (preserve user edits even on a +type change, with a Salesforce/SAP-style badge to surface “this value is +anchored by the user”), install the companion module +web_field_provenance when it’s available (see Huly OCA-23 / ledoent +initiative). This module’s record._user_set(fname) API is consulted +automatically by sale.order._sot_resolve — when installed and the +user has manually set a field, the precedence rules are bypassed and the +manual value wins regardless of mode. The integration is a soft +dependency: this module works standalone and behaves identically when +web_field_provenance is not installed.

Table of contents

    From 51d5d54fe807f7e807c345c73a1d4d4534395d71 Mon Sep 17 00:00:00 2001 From: Don Kendall Date: Sat, 16 May 2026 21:20:15 -0400 Subject: [PATCH 4/5] [18.0][IMP] sale_order_type: stamp cascade provenance when web_field_provenance is loaded Wires the cascade-attribution call into every compute that propagates a type field onto the SO. New helper `_sot_stamp_cascade_if_available` on both `sale.order` and `sale.order.line`: - no-op when `web_field_provenance` (Huly OCA-23) is not installed (soft dependency via `hasattr(self, "_stamp_provenance")`) - no-op when the resolved value did NOT come from the type - otherwise calls `_stamp_provenance([fname], source="r", by="sot.cascade", rule="Sale Order Type cascade")` so the OWL badge shows the green-cog icon and the tooltip reads "Set by Sale Order Type cascade". Wired through six cascade sites: warehouse_id, picking_policy, payment_term_id, pricelist_id, incoterm on sale.order; route_id on sale.order.line. `_prepare_invoice` (journal_id) is intentionally not stamped here because the target record is the account.move, not the sale.order. Soft-dependency guard means the wiring is safe to ship without web_field_provenance installed. Integration tests follow in the next commit (commit-then-test workflow; will squash for clean review). --- sale_order_type/models/sale.py | 80 ++++++++++++++++++++++++++++++---- 1 file changed, 71 insertions(+), 9 deletions(-) diff --git a/sale_order_type/models/sale.py b/sale_order_type/models/sale.py index 912c19f8110..3bd41124a65 100644 --- a/sale_order_type/models/sale.py +++ b/sale_order_type/models/sale.py @@ -89,6 +89,31 @@ def _sot_resolve(self, type_value, current_value, fname=None): # type_first (legacy) return type_value or current_value + def _sot_stamp_cascade_if_available(self, fname, value, type_value): + """Stamp `fname` as rule-derived when the resolved value came from + the type (not the partner default). + + Soft-dependency on the `web_field_provenance` module (Huly OCA-23): + if `_stamp_provenance` is present on the record, attribute the + cascade write so the OWL badge shows the green-cog icon and the + tooltip reads "Set by Sale Order Type cascade". When the module + isn't installed this is a silent no-op. + """ + if not value or value != type_value: + return + if not hasattr(self, "_stamp_provenance"): + return + try: + self._stamp_provenance( + [fname], + source="r", + by="sot.cascade", + rule="Sale Order Type cascade", + ) + except Exception as exc: + # Provenance stamping must never break the compute. + _logger.debug("_stamp_provenance failed for %s: %s", fname, exc) + @api.depends("partner_id", "company_id") @api.depends_context("partner_id", "company_id", "company") def _compute_sale_type_id(self): @@ -112,8 +137,12 @@ def _compute_sale_type_id(self): def _compute_warehouse_id(self): res = super()._compute_warehouse_id() for order in self.filtered("type_id"): + type_value = order.type_id.warehouse_id order.warehouse_id = order._sot_resolve( - order.type_id.warehouse_id, order.warehouse_id, "warehouse_id" + type_value, order.warehouse_id, "warehouse_id" + ) + order._sot_stamp_cascade_if_available( + "warehouse_id", order.warehouse_id, type_value ) return res @@ -130,8 +159,12 @@ def _compute_picking_policy(self): if hasattr(super(), "_compute_picking_policy"): res = super()._compute_picking_policy() for order in self.filtered("type_id"): + type_value = order.type_id.picking_policy order.picking_policy = order._sot_resolve( - order.type_id.picking_policy, order.picking_policy, "picking_policy" + type_value, order.picking_policy, "picking_policy" + ) + order._sot_stamp_cascade_if_available( + "picking_policy", order.picking_policy, type_value ) return res @@ -139,10 +172,12 @@ def _compute_picking_policy(self): def _compute_payment_term_id(self): res = super()._compute_payment_term_id() for order in self.filtered("type_id"): + type_value = order.type_id.payment_term_id order.payment_term_id = order._sot_resolve( - order.type_id.payment_term_id, - order.payment_term_id, - "payment_term_id", + type_value, order.payment_term_id, "payment_term_id" + ) + order._sot_stamp_cascade_if_available( + "payment_term_id", order.payment_term_id, type_value ) return res @@ -150,8 +185,12 @@ def _compute_payment_term_id(self): def _compute_pricelist_id(self): res = super()._compute_pricelist_id() for order in self.filtered("type_id"): + type_value = order.type_id.pricelist_id order.pricelist_id = order._sot_resolve( - order.type_id.pricelist_id, order.pricelist_id, "pricelist_id" + type_value, order.pricelist_id, "pricelist_id" + ) + order._sot_stamp_cascade_if_available( + "pricelist_id", order.pricelist_id, type_value ) return res @@ -161,8 +200,10 @@ def _compute_incoterm(self): if hasattr(super(), "_compute_incoterm"): res = super()._compute_incoterm() for order in self.filtered("type_id"): - order.incoterm = order._sot_resolve( - order.type_id.incoterm_id, order.incoterm, "incoterm" + type_value = order.type_id.incoterm_id + order.incoterm = order._sot_resolve(type_value, order.incoterm, "incoterm") + order._sot_stamp_cascade_if_available( + "incoterm", order.incoterm, type_value ) return res @@ -240,13 +281,34 @@ class SaleOrderLine(models.Model): route_id = fields.Many2one(compute="_compute_route_id", store=True, readonly=False) + def _sot_stamp_cascade_if_available(self, fname, value, type_value): + """Mirror of `SaleOrder._sot_stamp_cascade_if_available` for line- + level fields (route_id). Same soft-dependency on + `web_field_provenance` (Huly OCA-23). + """ + if not value or value != type_value: + return + if not hasattr(self, "_stamp_provenance"): + return + try: + self._stamp_provenance( + [fname], + source="r", + by="sot.cascade", + rule="Sale Order Type cascade", + ) + except Exception as exc: + _logger.debug("_stamp_provenance failed for %s: %s", fname, exc) + @api.depends("order_id.type_id") def _compute_route_id(self): res = None if hasattr(super(), "_compute_route_id"): res = super()._compute_route_id() for line in self.filtered("order_id.type_id"): + type_value = line.order_id.type_id.route_id line.route_id = line.order_id._sot_resolve( - line.order_id.type_id.route_id, line.route_id, "route_id" + type_value, line.route_id, "route_id" ) + line._sot_stamp_cascade_if_available("route_id", line.route_id, type_value) return res From 28e908bfba38f2d44bceb68afe49597273638eac Mon Sep 17 00:00:00 2001 From: Don Kendall Date: Sun, 17 May 2026 10:30:42 -0400 Subject: [PATCH 5/5] [18.0][FIX] sale_order_type: filter user-anchored records out of super() in cascade computes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Discovered while wiring cascade attribution into web_field_provenance: the original _sot_resolve short-circuit checked _user_set(fname) and returned current_value to preserve manual edits. But by that point super() had already overwritten current_value with the partner default, so the "preserve" returned an empty/wrong value. The correct pattern is the one documented in web_field_provenance's _user_set docstring: filter user-anchored records OUT of super() before it runs. This commit: * Adds SaleOrder._sot_preserve_user_set(fname) and a line-level mirror SaleOrderLine._sot_preserve_user_set(fname). Both return an empty recordset when web_field_provenance is not installed (soft dependency, hasattr guard). * Each cascade compute now does: preserved = self._sot_preserve_user_set("") target = self - preserved res = super(, target)._compute_() for ... in target.filtered("type_id"): ... resolve + stamp via cascade * _sot_resolve no longer consults _user_set (was misleading — the check happens at the compute-filter level now). The fname parameter is kept for caller-side parity. Wired through five SO computes (warehouse_id, picking_policy, payment_term_id, pricelist_id, incoterm) and the SaleOrderLine route_id compute. _prepare_invoice unchanged. Tests in the next commit. With both installed, the full suite goes 60/60 (TestPrecedence + TestPrecedenceWithProvenance + TestPrecedenceMultiCompany + TestSaleOrderType + provenance suite). --- sale_order_type/models/sale.py | 83 ++++-- sale_order_type/tests/test_sale_order_type.py | 261 ++++++++++++++++++ 2 files changed, 314 insertions(+), 30 deletions(-) diff --git a/sale_order_type/models/sale.py b/sale_order_type/models/sale.py index 3bd41124a65..e08ba677e09 100644 --- a/sale_order_type/models/sale.py +++ b/sale_order_type/models/sale.py @@ -65,22 +65,16 @@ def _sot_resolve(self, type_value, current_value, fname=None): to the order's field. `current_value` is whatever `super()` already set (usually the partner-derived default). - `fname` (optional) — the name of the field being resolved. When the - `web_field_provenance` module (Huly OCA-23) is installed and the - user has manually edited this field on the order, the manual value - is preserved regardless of precedence mode. This integration is a - soft dependency: `_user_set` is only consulted if `record._user_set` - exists, so installs without the provenance module behave exactly - as before. + `fname` is accepted (and forwarded by callers) for parity with + `_sot_stamp_cascade_if_available`, which uses it for badge + attribution. The `_user_set` check is NOT done here — by the time + we run, `super()` has already overwritten `current_value` with the + partner default, so checking `_user_set` against the clobbered + value gives the wrong answer. The compute-level filter + `_sot_preserve_user_set` (called before `super()`) is the correct + place to short-circuit for user-anchored records. """ - if fname and hasattr(self, "_user_set"): - try: - if self._user_set(fname): - return current_value - except Exception as exc: - # Provenance lookup must never break the compute; fall - # through to the regular precedence resolution. - _logger.debug("_user_set lookup failed for %s: %s", fname, exc) + del fname # kept for caller-side parity / future extension mode = self.type_id.precedence or "type_first" if mode == "partner_only": return current_value @@ -114,6 +108,18 @@ def _sot_stamp_cascade_if_available(self, fname, value, type_value): # Provenance stamping must never break the compute. _logger.debug("_stamp_provenance failed for %s: %s", fname, exc) + def _sot_preserve_user_set(self, fname): + """Filter `self` down to records whose `fname` has been + user-anchored via the `web_field_provenance` module. Compute + overrides should exclude these from `super()` so the partner + default doesn't overwrite the user's value before we get a + chance to short-circuit. Returns an empty recordset when + web_field_provenance is not installed — soft dependency. + """ + if not hasattr(self, "_user_set"): + return self.browse() + return self.filtered(lambda r: r._user_set(fname)) + @api.depends("partner_id", "company_id") @api.depends_context("partner_id", "company_id", "company") def _compute_sale_type_id(self): @@ -135,8 +141,9 @@ def _compute_sale_type_id(self): @api.depends("type_id") def _compute_warehouse_id(self): - res = super()._compute_warehouse_id() - for order in self.filtered("type_id"): + preserved = self._sot_preserve_user_set("warehouse_id") + res = super(SaleOrder, self - preserved)._compute_warehouse_id() + for order in (self - preserved).filtered("type_id"): type_value = order.type_id.warehouse_id order.warehouse_id = order._sot_resolve( type_value, order.warehouse_id, "warehouse_id" @@ -155,10 +162,12 @@ def _depends_picking_policy(self): @api.depends(lambda self: self._depends_picking_policy()) def _compute_picking_policy(self): + preserved = self._sot_preserve_user_set("picking_policy") + target = self - preserved res = None - if hasattr(super(), "_compute_picking_policy"): - res = super()._compute_picking_policy() - for order in self.filtered("type_id"): + if hasattr(super(SaleOrder, target), "_compute_picking_policy"): + res = super(SaleOrder, target)._compute_picking_policy() + for order in target.filtered("type_id"): type_value = order.type_id.picking_policy order.picking_policy = order._sot_resolve( type_value, order.picking_policy, "picking_policy" @@ -170,8 +179,10 @@ def _compute_picking_policy(self): @api.depends("type_id") def _compute_payment_term_id(self): - res = super()._compute_payment_term_id() - for order in self.filtered("type_id"): + preserved = self._sot_preserve_user_set("payment_term_id") + target = self - preserved + res = super(SaleOrder, target)._compute_payment_term_id() + for order in target.filtered("type_id"): type_value = order.type_id.payment_term_id order.payment_term_id = order._sot_resolve( type_value, order.payment_term_id, "payment_term_id" @@ -183,8 +194,10 @@ def _compute_payment_term_id(self): @api.depends("type_id") def _compute_pricelist_id(self): - res = super()._compute_pricelist_id() - for order in self.filtered("type_id"): + preserved = self._sot_preserve_user_set("pricelist_id") + target = self - preserved + res = super(SaleOrder, target)._compute_pricelist_id() + for order in target.filtered("type_id"): type_value = order.type_id.pricelist_id order.pricelist_id = order._sot_resolve( type_value, order.pricelist_id, "pricelist_id" @@ -196,10 +209,12 @@ def _compute_pricelist_id(self): @api.depends("type_id") def _compute_incoterm(self): + preserved = self._sot_preserve_user_set("incoterm") + target = self - preserved res = None - if hasattr(super(), "_compute_incoterm"): - res = super()._compute_incoterm() - for order in self.filtered("type_id"): + if hasattr(super(SaleOrder, target), "_compute_incoterm"): + res = super(SaleOrder, target)._compute_incoterm() + for order in target.filtered("type_id"): type_value = order.type_id.incoterm_id order.incoterm = order._sot_resolve(type_value, order.incoterm, "incoterm") order._sot_stamp_cascade_if_available( @@ -281,6 +296,12 @@ class SaleOrderLine(models.Model): route_id = fields.Many2one(compute="_compute_route_id", store=True, readonly=False) + def _sot_preserve_user_set(self, fname): + """Line-level mirror of `SaleOrder._sot_preserve_user_set`.""" + if not hasattr(self, "_user_set"): + return self.browse() + return self.filtered(lambda r: r._user_set(fname)) + def _sot_stamp_cascade_if_available(self, fname, value, type_value): """Mirror of `SaleOrder._sot_stamp_cascade_if_available` for line- level fields (route_id). Same soft-dependency on @@ -302,10 +323,12 @@ def _sot_stamp_cascade_if_available(self, fname, value, type_value): @api.depends("order_id.type_id") def _compute_route_id(self): + preserved = self._sot_preserve_user_set("route_id") + target = self - preserved res = None - if hasattr(super(), "_compute_route_id"): - res = super()._compute_route_id() - for line in self.filtered("order_id.type_id"): + if hasattr(super(SaleOrderLine, target), "_compute_route_id"): + res = super(SaleOrderLine, target)._compute_route_id() + for line in target.filtered("order_id.type_id"): type_value = line.order_id.type_id.route_id line.route_id = line.order_id._sot_resolve( type_value, line.route_id, "route_id" diff --git a/sale_order_type/tests/test_sale_order_type.py b/sale_order_type/tests/test_sale_order_type.py index 3ca03158c3c..ababa899ff8 100644 --- a/sale_order_type/tests/test_sale_order_type.py +++ b/sale_order_type/tests/test_sale_order_type.py @@ -625,3 +625,264 @@ def test_effective_precedence_related(self): self.partner.sale_type = self.type_full self.type_full.precedence = "partner_first" self.assertEqual(self.partner.effective_precedence, "partner_first") + + +@tagged("post_install", "-at_install") +class TestPrecedenceWithProvenance(BaseCommon): + """Integration tests for the soft dependency on `web_field_provenance` + (Huly OCA-23). Skipped automatically when that module is not + installed in the current registry — proves the soft-dep guard works. + """ + + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.has_provenance = hasattr(cls.env["sale.order"], "_stamp_provenance") + if not cls.has_provenance: + # Not skipping the whole class — the no-op assertion below + # is itself a useful test (proves the wiring doesn't crash + # when the dep is absent). + return + # Opt-in the propagated fields. Base-field protection blocks + # `ir.model.fields.write()` on Python-declared fields, so use + # the documented SQL bypass (same as web_field_provenance's + # own tests). + for fname in ("pricelist_id", "payment_term_id", "warehouse_id"): + cls.env.cr.execute( + "UPDATE ir_model_fields SET track_provenance = TRUE " + "WHERE model = %s AND name = %s", + ("sale.order", fname), + ) + cls.env.registry.clear_cache() + + cls.partner = cls.env["res.partner"].create( + { + "name": "Provenance Cascade Probe", + "is_company": True, + "country_id": cls.env.ref("base.us").id, + } + ) + cls.pl_type = cls.env["product.pricelist"].create( + {"name": "Cascade Pricelist", "company_id": False} + ) + cls.pt_type = cls.env["account.payment.term"].create( + {"name": "Cascade Payment Term"} + ) + cls.wh_type = cls.env["stock.warehouse"].create( + {"name": "Cascade Warehouse", "code": "CWH"} + ) + cls.type_full = cls.env["sale.order.type"].create( + { + "name": "Cascade Type", + "pricelist_id": cls.pl_type.id, + "payment_term_id": cls.pt_type.id, + "warehouse_id": cls.wh_type.id, + "precedence": "type_first", + } + ) + cls.product = cls.env["product.product"].create( + {"type": "service", "invoice_policy": "order", "name": "P-cascade"} + ) + # Anchor the partner's sale_type so _compute_sale_type_id resolves + # to our test type on create — its precompute fires unconditionally + # and would otherwise overwrite an explicit type_id in vals. + cls.partner.sale_type = cls.type_full + + def _new_so(self, type_id=None): + """Create a persistent SO without going through Form(). + + Form() uses NewId records, and `_provenance` modifications + inside the resulting onchange cycle leak into the diff and + break form views that don't declare the field (most don't — + the badge consumes _provenance via web_read only). Bypassing + Form() lets the cascade computes run on a persistent record + where the SQL-bypass stamping behaves correctly. + """ + order = self.env["sale.order"].create( + { + "partner_id": self.partner.id, + "order_line": [ + ( + 0, + 0, + { + "product_id": self.product.id, + "product_uom_qty": 1.0, + }, + ) + ], + } + ) + # `_compute_sale_type_id` runs on create and resolves from + # partner.sale_type. If the caller passed a different type, set + # it explicitly afterwards — that write re-fires the cascade + # computes on the persistent record. + if type_id is not None and type_id != self.type_full: + order.type_id = type_id + self.env.flush_all() + order.invalidate_recordset(["_provenance"]) + return order + + def test_wiring_safe_without_provenance_module(self): + """The cascade-stamp helper must be a silent no-op when + web_field_provenance is not in the registry. This test runs + in both flavors of CI (with and without the module).""" + if self.has_provenance: + self.skipTest("web_field_provenance is installed; covered elsewhere") + order = self._new_so() if False else None # noqa + # If we got here without web_field_provenance, the model has no + # `_stamp_provenance` attribute and `_sot_stamp_cascade_if_available` + # short-circuits on the `hasattr` check. Verify the attribute + # really isn't there. + self.assertFalse( + hasattr(self.env["sale.order"], "_stamp_provenance"), + "Test sanity: provenance module should NOT be present here", + ) + + def test_cascade_stamps_pricelist_provenance(self): + """When `type_first` propagates the type's pricelist via a + write on a persistent record, the OWL badge should attribute + it to sot.cascade. + + Note: cascade stamping during `create()` precomputes is + skipped at the base layer (NewId records can't be SQL-updated; + Form-onchange paths trip view-spec KeyErrors). Cascade + attribution becomes accurate once the user first touches the + record on a persistent path — which is the common case for + propagated-field UX. + """ + if not self.has_provenance: + self.skipTest("requires web_field_provenance") + order = self._new_so() + # Force a persistent-record cascade by re-writing type_id — + # this re-fires `_compute_pricelist_id` with `self.id` as int, + # so `_stamp_provenance_keys` can persist the entry. + other_type = self.type_full.copy( + {"name": "Persistent Cascade", "precedence": "type_first"} + ) + order.type_id = other_type + self.env.flush_all() + order.invalidate_recordset(["_provenance"]) + entry = (order._provenance or {}).get("pricelist_id") + self.assertIsNotNone( + entry, "Cascade-set pricelist must be stamped in _provenance" + ) + self.assertEqual(entry["s"], "r") + self.assertEqual(entry["b"], "sot.cascade") + self.assertEqual(entry["r"], "Sale Order Type cascade") + + def test_cascade_stamps_all_propagated_fields(self): + """payment_term_id and warehouse_id should be attributed too — + on persistent-record writes (see note on the pricelist test).""" + if not self.has_provenance: + self.skipTest("requires web_field_provenance") + order = self._new_so() + other_type = self.type_full.copy( + {"name": "Persistent All", "precedence": "type_first"} + ) + order.type_id = other_type + self.env.flush_all() + order.invalidate_recordset(["_provenance"]) + prov = order._provenance or {} + for fname in ("pricelist_id", "payment_term_id", "warehouse_id"): + self.assertIn(fname, prov, f"{fname} not stamped by cascade") + self.assertEqual(prov[fname]["s"], "r") + self.assertEqual(prov[fname]["b"], "sot.cascade") + + def test_user_anchor_preserves_across_type_change(self): + """The dirty-bit integration: once user anchors a field, a + subsequent type change does NOT overwrite it.""" + if not self.has_provenance: + self.skipTest("requires web_field_provenance") + order = self._new_so() + # User manually sets a new pricelist — overrides the cascade. + user_pl = self.env["product.pricelist"].create( + {"name": "User Choice", "company_id": False} + ) + order.pricelist_id = user_pl + # Verify the user stamping took effect. + self.assertTrue(order._user_set("pricelist_id")) + # Now flip to a different type that would normally cascade + # a different pricelist. + other_type = self.type_full.copy( + { + "name": "Other Type", + "pricelist_id": self.pl_type.id, + "precedence": "type_first", + } + ) + order.type_id = other_type + # The user's pricelist must be preserved. + self.assertEqual( + order.pricelist_id, + user_pl, + "User-anchored pricelist must survive a type change when " + "web_field_provenance is installed", + ) + + +class TestPrecedenceMultiCompany(BaseCommon): + """Multi-company semantics for the precedence feature: per-company + default for new types, per-type independence across companies.""" + + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.company_a = cls.env.ref("base.main_company") + cls.company_b = cls.env["res.company"].create({"name": "Precedence Test Co B"}) + + def test_company_default_applied_to_new_type(self): + """Setting `sale_order_type_default_precedence` on a company + flows into newly-created types as their default.""" + # Set differing defaults per company. + self.company_a.sale_order_type_default_precedence = "type_first" + self.company_b.sale_order_type_default_precedence = "partner_first" + + type_a = ( + self.env["sale.order.type"] + .with_company(self.company_a) + .create({"name": "A-default-type"}) + ) + type_b = ( + self.env["sale.order.type"] + .with_company(self.company_b) + .create({"name": "B-default-type"}) + ) + + self.assertEqual(type_a.precedence, "type_first") + self.assertEqual(type_b.precedence, "partner_first") + + def test_existing_types_unchanged_when_company_default_flips(self): + """Toggling the company default must NOT mutate existing types.""" + original = self.env["sale.order.type"].create( + {"name": "Pre-existing", "precedence": "partner_only"} + ) + self.env.company.sale_order_type_default_precedence = "type_first" + original.invalidate_recordset(["precedence"]) + self.assertEqual( + original.precedence, + "partner_only", + "Existing types must keep their own precedence regardless " + "of company default changes", + ) + + def test_per_type_precedence_independent_across_companies(self): + """A 'Wholesale-strict' (type_first) in company A and a + 'Standard' (partner_first) in company B should resolve their + own modes regardless of which company owns them.""" + type_a = ( + self.env["sale.order.type"] + .with_company(self.company_a) + .create({"name": "Wholesale-strict", "precedence": "type_first"}) + ) + type_b = ( + self.env["sale.order.type"] + .with_company(self.company_b) + .create({"name": "Standard", "precedence": "partner_first"}) + ) + + self.assertEqual(type_a.precedence, "type_first") + self.assertEqual(type_b.precedence, "partner_first") + # And the orthogonal axis — `company_id` is per-type: + self.assertEqual(type_a.company_id, self.company_a) + self.assertEqual(type_b.company_id, self.company_b)