From 6c736a7795cc249c01b6ad44fb4246930472f796 Mon Sep 17 00:00:00 2001 From: "Levi Siuzdak (sile)" Date: Tue, 16 Jan 2024 15:38:59 +0000 Subject: [PATCH] [FIX] product: improve variant-template consistency in supplierinfo Versions -------- 15.0+ Steps ----- 1. Go to Purchase; 2. create a Vendor Pricelist; 3. select a Product, a Product Variant & a Unit Price; 4. empty the Product field & save; 5. create a RFQ; 6. add the Product Variant from the Vendor Pricelist. Issue ----- The product's price remains 0. Cause ----- The `seller_ids` field in `product.template` creates one-to-many relation with `product.supplierinfo`'s `product_tmpl_id` field. While it is possible to select a specific product variant and have the product field empty, this renders the Vendor Pricelist unavailable for Purchase Orders. Solution -------- Add a `_sanitize_vals` method to `product.supplierinfo` to be used on create/write, which ensures that if there's a `product_id`, the record's `product_tmpl_id` is consistent with it. This allows for record imports to be usable & consistent when only a variant is specified. Also backport a modified `onchange` method added in 5537090f1c688f0e1f9de366f83387277d60612a. Originally it only reset `product_id` if `product_tmpl_id` was changed to a different non-falsy value. Modified, it also resets `product_id` if `product_tmpl_id` is changed to a falsy value, as it would otherwise just re-add the removed value on create/write after this commit. opw-3664524 closes odoo/odoo#151210 X-original-commit: 572122335a04126385115d892b027371bbabbe7e Signed-off-by: Levi Siuzdak Signed-off-by: William Henrotin (whe) --- addons/product/models/product_supplierinfo.py | 19 ++++++++++++++++++- addons/product/tests/test_seller.py | 11 +++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/addons/product/models/product_supplierinfo.py b/addons/product/models/product_supplierinfo.py index b51dd15cbdf86..af0a94f6f2d3d 100644 --- a/addons/product/models/product_supplierinfo.py +++ b/addons/product/models/product_supplierinfo.py @@ -73,7 +73,8 @@ def _compute_price_discounted(self): @api.onchange('product_tmpl_id') def _onchange_product_tmpl_id(self): - if self.product_id and self.product_tmpl_id and self.product_id not in self.product_tmpl_id.product_variant_ids: + """Clear product variant if it no longer matches the product template.""" + if self.product_id and self.product_id not in self.product_tmpl_id.product_variant_ids: self.product_id = False @api.model @@ -82,3 +83,19 @@ def get_import_templates(self): 'label': _('Import Template for Vendor Pricelists'), 'template': '/product/static/xls/product_supplierinfo.xls' }] + + def _sanitize_vals(self, vals): + """Sanitize vals to sync product variant & template on read/write.""" + if 'product_id' in vals and 'product_tmpl_id' not in vals: + product = self.env['product.product'].browse(vals['product_id']) + vals['product_tmpl_id'] = product.product_tmpl_id.id + + @api.model_create_multi + def create(self, vals_list): + for vals in vals_list: + self._sanitize_vals(vals) + return super().create(vals_list) + + def write(self, vals): + self._sanitize_vals(vals) + return super().write(vals) diff --git a/addons/product/tests/test_seller.py b/addons/product/tests/test_seller.py index 1ed762efe017b..42deb5ec41020 100644 --- a/addons/product/tests/test_seller.py +++ b/addons/product/tests/test_seller.py @@ -135,3 +135,14 @@ def test_40_seller_min_qty_precision(self): # Assert: The set value is kept self.assertEqual(supplier_info.min_qty, precise_value) + + def test_50_seller_ids(self): + vendors = self.env['product.supplierinfo'].create([{ + 'partner_id': self.asustec.id, + 'product_tmpl_id': self.product_consu.product_tmpl_id.id, + }, { + 'partner_id': self.camptocamp.id, + 'product_id': self.product_consu.id, + }]) + self.assertEqual(vendors, self.product_consu.seller_ids, + "Sellers of a product should be listed in the product's seller_ids")