From 79f85ab312db02706b1ff3c9b40b78752841199d Mon Sep 17 00:00:00 2001 From: "Touati Djamel (otd)" Date: Thu, 6 Apr 2023 13:58:20 +0000 Subject: [PATCH] [FIX] purchase: add the supplier list of the product in each company MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Steps to reproduce the bug: - Create a storable product “P1” 1:/ - Select the company A - Create a purchase order: - product: “P1” - vendor: “V1” - confirm the PO The vendor “V1” is added to the supplier list of “P1” 2:/ - Select the company B - Create a purchase order: - product: “P1” - vendor: “V2” - confirm the PO Problem: The vendor “V2” is added to the list but “V1” is deleted from the list in company A The “seller_ids” field is in the “product.template” model, we try to modify it in the “_add_supplier_to_product” function from the “product_id”(product.product) field which inherits from the “product.Template” model: https://github.com/odoo/odoo/blob/3b88ed5ea458a37ee4d440f83bab45bd0fb13845/addons/purchase/models/purchase.py#L531-L532 So the function “inverse_related” will be called, in which the function “__set__” will be triggered: In the values, the command for the create will be added but the command for the set will be added as well while it shouldn't. So in the `write_real` function a search will be done to get all `product.supplierinfo` with the same product_tmpl_id: https://github.com/odoo/odoo/blob/36544651f2049bcf18777091dbf02c9631b33243/odoo/fields.py#L4415-L4417 but as we are in sudo, those of company “A” will also be recovered, so they will be unlinked since they are not in the command.set opw-3251941 closes odoo/odoo#117985 X-original-commit: 78f803f3c1963711e2a5541f913f030da4f06fb7 Signed-off-by: William Henrotin (whe) Signed-off-by: Djamel Touati (otd) --- addons/purchase/models/purchase.py | 2 +- addons/purchase/tests/test_purchase.py | 47 ++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/addons/purchase/models/purchase.py b/addons/purchase/models/purchase.py index 1e98c038495..12ea0583cc5 100644 --- a/addons/purchase/models/purchase.py +++ b/addons/purchase/models/purchase.py @@ -548,7 +548,7 @@ class PurchaseOrder(models.Model): 'seller_ids': [(0, 0, supplierinfo)], } # supplier info should be added regardless of the user access rights - line.product_id.sudo().write(vals) + line.product_id.product_tmpl_id.sudo().write(vals) def action_create_invoice(self): """Create the invoice associated to the PO. diff --git a/addons/purchase/tests/test_purchase.py b/addons/purchase/tests/test_purchase.py index decb799cbee..966f75366b1 100644 --- a/addons/purchase/tests/test_purchase.py +++ b/addons/purchase/tests/test_purchase.py @@ -372,3 +372,50 @@ class TestPurchase(AccountTestInvoicingCommon): po.button_confirm() self.assertEqual(po.order_line.product_id.seller_ids.mapped('partner_id'), delivery_address) + + def test_supplier_list_in_product_with_multicompany(self): + """ + Check that a different supplier list can be added to a product for each company. + """ + company_a = self.company_data['company'] + company_b = self.company_data_2['company'] + product = self.env['product.product'].create({ + 'name': 'product_test', + 'type': 'product', + }) + # create a purchase order in the company A + self.env['purchase.order'].with_company(company_a).create({ + 'partner_id': self.partner_a.id, + 'order_line': [(0, 0, { + 'product_id': product.id, + 'product_qty': 1, + 'product_uom': self.env.ref('uom.product_uom_unit').id, + 'price_unit': 1, + })], + }).button_confirm() + + self.assertEqual(product.seller_ids[0].partner_id, self.partner_a) + self.assertEqual(product.seller_ids[0].company_id, company_a) + + # switch to the company B + self.env['purchase.order'].with_company(company_b).create({ + 'partner_id': self.partner_b.id, + 'order_line': [(0, 0, { + 'product_id': product.id, + 'product_qty': 1, + 'product_uom': self.env.ref('uom.product_uom_unit').id, + 'price_unit': 2, + })], + }).button_confirm() + product = product.with_company(company_b) + self.assertEqual(product.seller_ids[0].partner_id, self.partner_b) + self.assertEqual(product.seller_ids[0].company_id, company_b) + + # Switch to the company A and check that the vendor list is still the same + product = product.with_company(company_a) + self.assertEqual(product.seller_ids[0].partner_id, self.partner_a) + self.assertEqual(product.seller_ids[0].company_id, company_a) + + product._invalidate_cache() + self.assertEqual(product.seller_ids[0].partner_id, self.partner_a) + self.assertEqual(product.seller_ids[0].company_id, company_a)