diff --git a/addons/delivery/models/__init__.py b/addons/delivery/models/__init__.py index ce55845c421..72fc7b3a04b 100644 --- a/addons/delivery/models/__init__.py +++ b/addons/delivery/models/__init__.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from . import res_config_settings from . import delivery_carrier from . import delivery_grid from . import product_packaging diff --git a/addons/delivery/models/res_config_settings.py b/addons/delivery/models/res_config_settings.py deleted file mode 100644 index 070f8dcdb29..00000000000 --- a/addons/delivery/models/res_config_settings.py +++ /dev/null @@ -1,13 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -from odoo import models - -class ResConfigSettings(models.TransientModel): - _inherit = 'res.config.settings' - - def set_values(self): - super(ResConfigSettings, self).set_values() - rule = self.env.ref('delivery.delivery_carrier_comp_rule', False) - if rule: - rule.write({'active': not bool(self.company_share_product)}) diff --git a/addons/delivery/security/delivery_carrier_security.xml b/addons/delivery/security/delivery_carrier_security.xml index e9e22c47088..4f60ee6d286 100644 --- a/addons/delivery/security/delivery_carrier_security.xml +++ b/addons/delivery/security/delivery_carrier_security.xml @@ -6,7 +6,6 @@ ['|', ('company_id', 'in', company_ids), ('company_id', '=', False)] - diff --git a/addons/product/models/product_template.py b/addons/product/models/product_template.py index 10d87c9c623..2a55e3fc9cc 100644 --- a/addons/product/models/product_template.py +++ b/addons/product/models/product_template.py @@ -107,8 +107,7 @@ class ProductTemplate(models.Model): default=_get_default_uom_id, required=True, help="Default unit of measure used for purchase orders. It must be in the same category as the default unit of measure.") company_id = fields.Many2one( - 'res.company', 'Company', - default=lambda self: self.env.company, index=1) + 'res.company', 'Company', index=1) packaging_ids = fields.One2many( 'product.packaging', string="Product Packages", compute="_compute_packaging_ids", inverse="_set_packaging_ids", help="Gives the different ways to package the same product.") diff --git a/addons/product/models/res_config_settings.py b/addons/product/models/res_config_settings.py index 03fb56aa1f7..f1c0c189ef1 100644 --- a/addons/product/models/res_config_settings.py +++ b/addons/product/models/res_config_settings.py @@ -7,11 +7,6 @@ from odoo import api, fields, models class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' - company_share_product = fields.Boolean( - 'Share product to all companies', - help="Share your product to all companies defined in your instance.\n" - " * Checked : Product are visible for every company, even if a company is defined on the partner.\n" - " * Unchecked : Each company can see only its product (product where company is defined). Product not related to a company are visible for all companies.") group_uom = fields.Boolean("Units of Measure", implied_group='uom.group_uom') group_product_variant = fields.Boolean("Variants", implied_group='product.group_product_variant') module_sale_product_configurator = fields.Boolean("Product Configurator") @@ -47,17 +42,3 @@ class ResConfigSettings(models.TransientModel): If the user enables the product configurator -> enable the product variants as well""" if self.module_sale_product_configurator and not self.group_product_variant: self.group_product_variant = True - - @api.model - def get_values(self): - res = super(ResConfigSettings, self).get_values() - product_rule = self.env.ref('product.product_comp_rule') - res.update( - company_share_product=not bool(product_rule.active), - ) - return res - - def set_values(self): - super(ResConfigSettings, self).set_values() - product_rule = self.env.ref('product.product_comp_rule') - product_rule.write({'active': not bool(self.company_share_product)}) diff --git a/addons/product/security/product_security.xml b/addons/product/security/product_security.xml index 4ef8ea822d0..3ee6d0294a2 100644 --- a/addons/product/security/product_security.xml +++ b/addons/product/security/product_security.xml @@ -35,7 +35,6 @@ ['|', ('company_id', 'in', company_ids), ('company_id', '=', False)] - diff --git a/addons/product/views/res_config_settings_views.xml b/addons/product/views/res_config_settings_views.xml index d56daf515d7..5852e218c5a 100644 --- a/addons/product/views/res_config_settings_views.xml +++ b/addons/product/views/res_config_settings_views.xml @@ -5,10 +5,6 @@ res.config.settings - - -

Products

diff --git a/addons/sale/models/sale.py b/addons/sale/models/sale.py index 598f457b8bb..cc39e0b881a 100644 --- a/addons/sale/models/sale.py +++ b/addons/sale/models/sale.py @@ -200,6 +200,14 @@ class SaleOrder(models.Model): ('confirmation_date_conditional_required', "CHECK( (state IN ('sale', 'done') AND confirmation_date IS NOT NULL) OR state NOT IN ('sale', 'done') )", "A confirmed sales order requires a confirmation date."), ] + @api.constrains('company_id', 'order_line') + def _check_order_line_company_id(self): + for order in self: + companies = order.order_line.product_id.company_id + if companies and companies != order.company_id: + bad_products = order.order_line.product_id.filtered(lambda p: p.company_id and p.company_id != order.company_id) + raise ValidationError((_("Your quotation contains products from company %s whereas your quotation belongs to company %s. \n Please change the company of your quotation or remove the products from other companies (%s).") % (', '.join(companies.mapped('display_name')), order.company_id.display_name, ', '.join(bad_products.mapped('display_name'))))) + @api.depends('pricelist_id', 'date_order', 'company_id') def _compute_currency_rate(self): for order in self: diff --git a/addons/sale/tests/test_access_rights.py b/addons/sale/tests/test_access_rights.py index 7bf99f104cd..98aec26b9cc 100644 --- a/addons/sale/tests/test_access_rights.py +++ b/addons/sale/tests/test_access_rights.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo.exceptions import AccessError, UserError +from odoo.exceptions import AccessError, UserError, ValidationError from odoo.tests import tagged from .test_sale_common import TestCommonSaleNoChart @@ -103,7 +103,8 @@ class TestAccessRights(TestCommonSaleNoChart): # Salesperson can change a Sales Team of SO self.order.with_user(self.user_salesperson_1).write({'team_id': self.sales_channel.id}) # Salesperson can't create the SO of other salesperson - with self.assertRaises(AccessError): + # raise ValidationError instead of AccessError due to constraint + with self.assertRaises(ValidationError): self.env['sale.order'].with_user(self.user_salesperson_1).create({ 'partner_id': self.partner_customer_usd.id, 'user_id': self.user_salesperson.id diff --git a/addons/sale/views/sale_views.xml b/addons/sale/views/sale_views.xml index 1efb27f088c..541855846b4 100644 --- a/addons/sale/views/sale_views.xml +++ b/addons/sale/views/sale_views.xml @@ -313,6 +313,7 @@ 0: diff --git a/addons/sale_management/models/sale_order_template.py b/addons/sale_management/models/sale_order_template.py index 8e3dc818ef4..ee21cbce5d6 100644 --- a/addons/sale_management/models/sale_order_template.py +++ b/addons/sale_management/models/sale_order_template.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo import api, fields, models -from odoo.exceptions import UserError +from odoo import api, fields, models, _ +from odoo.exceptions import UserError, ValidationError class SaleOrderTemplate(models.Model): @@ -28,6 +28,22 @@ class SaleOrderTemplate(models.Model): domain=[('model', '=', 'sale.order')], help="This e-mail template will be sent on confirmation. Leave empty to send nothing.") active = fields.Boolean(default=True, help="If unchecked, it will allow you to hide the quotation template without removing it.") + company_id = fields.Many2one('res.company', string='Company') + + @api.constrains('company_id', 'sale_order_template_line_ids', 'sale_order_template_option_ids') + def _check_company_id(self): + for template in self: + companies = template.mapped('sale_order_template_line_ids.product_id.company_id') | template.mapped('sale_order_template_option_ids.product_id.company_id') + if len(companies) > 1: + raise ValidationError(_("Your template cannot contain products from multiple companies.")) + elif companies and companies != template.company_id: + raise ValidationError((_("Your template contains products from company %s whereas your template belongs to company %s. \n Please change the company of your template or remove the products from other companies.") % (companies.mapped('display_name'), template.company_id.display_name))) + + @api.onchange('sale_order_template_line_ids', 'sale_order_template_option_ids') + def _onchange_template_line_ids(self): + companies = self.mapped('sale_order_template_option_ids.product_id.company_id') | self.mapped('sale_order_template_line_ids.product_id.company_id') + if companies and self.company_id not in companies: + self.company_id = companies[0] def write(self, vals): if 'active' in vals and not vals.get('active'): diff --git a/addons/sale_management/security/sale_management_security.xml b/addons/sale_management/security/sale_management_security.xml index 0d838862462..2ec489b6650 100644 --- a/addons/sale_management/security/sale_management_security.xml +++ b/addons/sale_management/security/sale_management_security.xml @@ -6,4 +6,11 @@ + + Quotation Template multi-company + + + ['|', ('company_id', '=', False), ('company_id', 'in', company_ids)] + + diff --git a/addons/sale_management/views/sale_order_template_views.xml b/addons/sale_management/views/sale_order_template_views.xml index 73c79688c53..16b282899cc 100644 --- a/addons/sale_management/views/sale_order_template_views.xml +++ b/addons/sale_management/views/sale_order_template_views.xml @@ -33,6 +33,9 @@ days
+ + + diff --git a/addons/sale_management/views/sale_order_views.xml b/addons/sale_management/views/sale_order_views.xml index e4e78db4a1b..94d5c1ca2c1 100644 --- a/addons/sale_management/views/sale_order_views.xml +++ b/addons/sale_management/views/sale_order_views.xml @@ -11,7 +11,7 @@
- + @@ -67,7 +67,7 @@ - +