diff --git a/addons/stock/i18n/stock.pot b/addons/stock/i18n/stock.pot index 7c59c42a62e..e837b78a557 100644 --- a/addons/stock/i18n/stock.pot +++ b/addons/stock/i18n/stock.pot @@ -7409,6 +7409,14 @@ msgid "" " on products and product categories" msgstr "" +#. module: stock +#. odoo-python +#: code:addons/stock/models/stock_location.py:0 +#: code:addons/stock/models/stock_rule.py:0 +#, python-format +msgid "Rule %s belongs to %s while the route belongs to %s." +msgstr "" + #. module: stock #: model:ir.model.fields,field_description:stock.field_stock_rule__rule_message msgid "Rule Message" diff --git a/addons/stock/models/stock_location.py b/addons/stock/models/stock_location.py index 1c9cbb19450..4609ef5090f 100644 --- a/addons/stock/models/stock_location.py +++ b/addons/stock/models/stock_location.py @@ -472,3 +472,13 @@ class StockRoute(models.Model): for route in self: route.with_context(active_test=False).rule_ids.filtered(lambda ru: ru.active == route.active).toggle_active() super().toggle_active() + + @api.constrains('company_id') + def _check_company_consistency(self): + for route in self: + if not route.company_id: + continue + + for rule in route.rule_ids: + if route.company_id.id != rule.company_id.id: + raise ValidationError(_("Rule %s belongs to %s while the route belongs to %s.", rule.display_name, rule.company_id.display_name, route.company_id.display_name)) diff --git a/addons/stock/models/stock_rule.py b/addons/stock/models/stock_rule.py index 0d5f58c0ad0..b46e15d1f15 100644 --- a/addons/stock/models/stock_rule.py +++ b/addons/stock/models/stock_rule.py @@ -7,7 +7,7 @@ from collections import defaultdict, namedtuple from dateutil.relativedelta import relativedelta from odoo import SUPERUSER_ID, _, api, fields, models, registry -from odoo.exceptions import UserError +from odoo.exceptions import UserError, ValidationError from odoo.osv import expression from odoo.tools import float_compare, float_is_zero, html_escape from odoo.tools.misc import split_every @@ -107,6 +107,13 @@ class StockRule(models.Model): default['name'] = _("%s (copy)", self.name) return super().copy(default=default) + @api.constrains('company_id') + def _check_company_consistency(self): + for rule in self: + route = rule.route_id + if route.company_id and rule.company_id.id != route.company_id.id: + raise ValidationError(_("Rule %s belongs to %s while the route belongs to %s.", rule.display_name, rule.company_id.display_name, route.company_id.display_name)) + @api.onchange('picking_type_id') def _onchange_picking_type(self): """ Modify locations to the default picking type's locations source and diff --git a/addons/stock/models/stock_warehouse.py b/addons/stock/models/stock_warehouse.py index 9959db6f942..540e6566a9a 100644 --- a/addons/stock/models/stock_warehouse.py +++ b/addons/stock/models/stock_warehouse.py @@ -797,7 +797,7 @@ class Warehouse(models.Model): 'product_categ_selectable': True, 'supplied_wh_id': self.id, 'supplier_wh_id': supplier_warehouse.id, - 'company_id': self.company_id.id, + 'company_id': (self.company_id & supplier_warehouse.company_id).id, } # Pull / Push tools diff --git a/addons/stock/tests/test_multicompany.py b/addons/stock/tests/test_multicompany.py index d7953544423..fb268c43a1a 100644 --- a/addons/stock/tests/test_multicompany.py +++ b/addons/stock/tests/test_multicompany.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo.exceptions import UserError +from odoo.exceptions import UserError, ValidationError from odoo.tests.common import TransactionCase, Form @@ -618,3 +618,32 @@ class TestMultiCompany(TransactionCase): self.assertEqual(lot_a.name, 'lot a') self.assertEqual(lot_b.company_id, self.company_b) self.assertEqual(lot_b.name, 'lot b') + + def test_route_rules_company_consistency(self): + route = self.env['stock.route'].create({ + 'name': 'Test Route', + 'company_id': self.company_a.id, + 'rule_ids': [ + (0, 0, { + 'name': 'Buy', + 'action': 'pull_push', + 'company_id': self.company_a.id, + 'location_dest_id': self.stock_location_a.id, + 'picking_type_id': self.warehouse_a.in_type_id.id, + }) + ] + }) + + with self.assertRaises(ValidationError): + route.write({'company_id': self.company_b.id}) + + with self.assertRaises(ValidationError): + route.write({'rule_ids': [ + (0, 0, { + 'name': 'Buy', + 'action': 'pull_push', + 'company_id': self.company_b.id, + 'location_dest_id': self.stock_location_b.id, + 'picking_type_id': self.warehouse_b.in_type_id.id, + }) + ]})