From 421b9dfe211ac1a71b35f150768cbc90fb55efb7 Mon Sep 17 00:00:00 2001 From: Hetashree Chauhan Date: Tue, 25 Jun 2019 06:41:16 +0000 Subject: [PATCH] [IMP] delivery, product, sale(_management): make company consistence Purpose of the commit is to make the multi company consistence with product, sale order and order template. So the Common Product Catalog setting is removed from generel settings because its behavior wasn't really clean from a technical point of view (disabling the rule on products access) and wouldn't work as well with new multi-company logic. The default logic of sharing products will be kept, but when someone wants to limit products sharing, he will do so product by product, by setting the company_id. Also the default company_id on product will be blank so default product will be a sharable by multi company. and added company_id on sale templates so user can select his/her own company or the templates which are common. task-2025168 Closes: #34342 --- addons/delivery/models/__init__.py | 1 - addons/delivery/models/res_config_settings.py | 13 ------------ .../security/delivery_carrier_security.xml | 1 - addons/product/models/product_template.py | 3 +-- addons/product/models/res_config_settings.py | 19 ------------------ addons/product/security/product_security.xml | 1 - .../views/res_config_settings_views.xml | 4 ---- addons/sale/models/sale.py | 8 ++++++++ addons/sale/tests/test_access_rights.py | 5 +++-- addons/sale/views/sale_views.xml | 3 +++ addons/sale_management/models/sale_order.py | 13 ++++++++++-- .../models/sale_order_template.py | 20 +++++++++++++++++-- .../security/sale_management_security.xml | 7 +++++++ .../views/sale_order_template_views.xml | 3 +++ .../views/sale_order_views.xml | 4 ++-- 15 files changed, 56 insertions(+), 49 deletions(-) delete mode 100644 addons/delivery/models/res_config_settings.py 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 @@ - +