From f5f88c4fae5b72ee48daa0b835477d6f3a371f27 Mon Sep 17 00:00:00 2001 From: svs-odoo Date: Wed, 14 Dec 2022 12:01:16 +0000 Subject: [PATCH] [FIX] stock: change product's company Before this commit, there is no verification while changing a product's company. That can lead to issue where some operations cannot be done because of access errors. To avoid that, this commit prevents to change the product's company if some quants for this product exist in another company's location. How to reproduce: - Have at least two different companies (let say CompA and CompB); - Create a new product who belong to no company; - For this product, add quantity on hand in a CompA location; - Now, change the product's company for the CompB; - While selected only the CompA, go into the Inventory Adjustments and try to create a new inventory adjustment for the CompA location with this product's quant -> Access Error. opw-3095984 closes odoo/odoo#110810 X-original-commit: 46987e13f35dc140869c58f6c5a09d9c542c3ae5 Signed-off-by: Tiffany Chang Signed-off-by: Steve Van Essche --- addons/stock/i18n/stock.pot | 8 ++++++++ addons/stock/models/product.py | 12 ++++++++++++ addons/stock/tests/test_product.py | 28 ++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/addons/stock/i18n/stock.pot b/addons/stock/i18n/stock.pot index 42fb129524e..7f348c16a60 100644 --- a/addons/stock/i18n/stock.pot +++ b/addons/stock/i18n/stock.pot @@ -7964,6 +7964,14 @@ msgid "" "instead." msgstr "" +#. module: stock +#: code:addons/stock/models/product.py:0 +#, python-format +msgid "" +"This product's company cannot be changed as long as there are quantities of it" +" belonging to another company." +msgstr "" + #. module: stock #: model:ir.model.fields,help:stock.field_stock_change_product_qty__new_quantity msgid "" diff --git a/addons/stock/models/product.py b/addons/stock/models/product.py index 8d1b13b80b8..f25a143137b 100644 --- a/addons/stock/models/product.py +++ b/addons/stock/models/product.py @@ -837,6 +837,18 @@ class ProductTemplate(models.Model): def write(self, vals): self._sanitize_vals(vals) + if 'company_id' in vals and vals['company_id']: + products_changing_company = self.filtered(lambda product: product.company_id.id != vals['company_id']) + if products_changing_company: + # Forbid changing a product's company when quant(s) exist in another company. + quant = self.env['stock.quant'].sudo().search([ + ('product_id', 'in', products_changing_company.product_variant_ids.ids), + ('company_id', '!=', vals['company_id']), + ('quantity', '!=', 0), + ], order=None, limit=1) + if quant: + raise UserError(_("This product's company cannot be changed as long as there are quantities of it belonging to another company.")) + if 'uom_id' in vals: new_uom = self.env['uom.uom'].browse(vals['uom_id']) updated = self.filtered(lambda template: template.uom_id != new_uom) diff --git a/addons/stock/tests/test_product.py b/addons/stock/tests/test_product.py index 415910daae7..08e713c6155 100644 --- a/addons/stock/tests/test_product.py +++ b/addons/stock/tests/test_product.py @@ -5,6 +5,7 @@ # Copyright 2015 Camptocamp SA from odoo.addons.stock.tests.common2 import TestStockCommon +from odoo.exceptions import UserError from odoo.tests.common import Form @@ -102,6 +103,33 @@ class TestVirtualAvailable(TestStockCommon): self.product_3.active = False self.assertFalse(orderpoint.active) + def test_change_product_company(self): + """ Checks we can't change the product's company if this product has + quant in another company. """ + company1 = self.env.ref('base.main_company') + company2 = self.env['res.company'].create({'name': 'Second Company'}) + product = self.env['product.product'].create({ + 'name': 'Product [TEST - Change Company]', + 'type': 'product', + }) + # Creates a quant for productA in the first company. + self.env['stock.quant'].create({ + 'product_id': product.id, + 'product_uom_id': self.uom_unit.id, + 'location_id': self.location_1.id, + 'quantity': 7, + 'reserved_quantity': 0, + }) + # Assigns a company: should be OK for company1 but should raise an error for company2. + product.company_id = company1.id + with self.assertRaises(UserError): + product.company_id = company2.id + # Checks we can assing company2 for the product once there is no more quant for it. + quant = self.env['stock.quant'].search([('product_id', '=', product.id)]) + quant.quantity = 0 + self.env['stock.quant']._unlink_zero_quants() + product.company_id = company2.id # Should work this time. + def test_search_qty_available(self): product = self.env['product.product'].create({ 'name': 'Brand new product',