diff --git a/addons/point_of_sale/models/res_config_settings.py b/addons/point_of_sale/models/res_config_settings.py index cda8fe38f76..2cfe0fc0a36 100644 --- a/addons/point_of_sale/models/res_config_settings.py +++ b/addons/point_of_sale/models/res_config_settings.py @@ -8,36 +8,3 @@ class ResConfigSettings(models.TransientModel): sale_tax_id = fields.Many2one('account.tax', string="Default Sale Tax", related='company_id.account_sale_tax_id', readonly=False) module_pos_mercury = fields.Boolean(string="Integrated Card Payments", help="The transactions are processed by Vantiv. Set your Vantiv credentials on the related payment journal.") - pos_sales_price = fields.Boolean("Multiple Product Prices", config_parameter='point_of_sale.pos_sales_price') - pos_pricelist_setting = fields.Selection([ - ('percentage', 'Multiple prices per product (e.g. customer segments, currencies)'), - ('formula', 'Price computed from formulas (discounts, margins, roundings)') - ], string="POS Pricelists", config_parameter='point_of_sale.pos_pricelist_setting') - - @api.onchange('pos_sales_price') - def _onchange_pos_sales_price(self): - if not self.pos_sales_price: - self.pos_pricelist_setting = False - if self.pos_sales_price and not self.pos_pricelist_setting: - self.pos_pricelist_setting = 'percentage' - - @api.onchange('pos_pricelist_setting') - def _onchange_pos_pricelist_setting(self): - if self.pos_pricelist_setting == 'percentage': - self.update({ - 'group_product_pricelist': True, - 'group_sale_pricelist': True, - 'group_pricelist_item': False, - }) - elif self.pos_pricelist_setting == 'formula': - self.update({ - 'group_product_pricelist': False, - 'group_sale_pricelist': True, - 'group_pricelist_item': True, - }) - else: - self.update({ - 'group_product_pricelist': False, - 'group_sale_pricelist': False, - 'group_pricelist_item': False, - }) diff --git a/addons/point_of_sale/views/res_config_settings_views.xml b/addons/point_of_sale/views/res_config_settings_views.xml index 0f8076d74ed..e943c95dbb9 100644 --- a/addons/point_of_sale/views/res_config_settings_views.xml +++ b/addons/point_of_sale/views/res_config_settings_views.xml @@ -29,24 +29,21 @@

Pricing

-
+
- +
-
diff --git a/addons/product/models/product.py b/addons/product/models/product.py index a0bfee330d7..83e39d887b0 100644 --- a/addons/product/models/product.py +++ b/addons/product/models/product.py @@ -113,8 +113,7 @@ class ProductProduct(models.Model): volume = fields.Float('Volume') weight = fields.Float('Weight', digits='Stock Weight') - pricelist_item_ids = fields.Many2many( - 'product.pricelist.item', 'Pricelist Items', compute='_get_pricelist_items') + pricelist_item_count = fields.Integer("Number of price rules", compute="_compute_variant_item_count") packaging_ids = fields.One2many( 'product.packaging', 'product_id', 'Product Packages', @@ -317,12 +316,12 @@ class ProductProduct(models.Model): else: product.product_template_attribute_value_ids += values_per_template[product.product_tmpl_id.id][pav.id] - def _get_pricelist_items(self): + def _compute_variant_item_count(self): for product in self: - product.pricelist_item_ids = self.env['product.pricelist.item'].search([ - '|', - ('product_id', '=', product.id), - ('product_tmpl_id', '=', product.product_tmpl_id.id)]).ids + domain = ['|', + '&', ('product_tmpl_id', '=', product.product_tmpl_id.id), ('applied_on', '=', '1_product'), + '&', ('product_id', '=', product.id), ('applied_on', '=', '0_product_variant')] + product.pricelist_item_count = self.env['product.pricelist.item'].search_count(domain) @api.constrains('attribute_value_ids') def _check_attribute_value_ids(self): @@ -581,6 +580,25 @@ class ProductProduct(models.Model): return _('Products: ') + self.env['product.category'].browse(self._context['categ_id']).name return res + def open_pricelist_rules(self): + self.ensure_one() + domain = ['|', + '&', ('product_tmpl_id', '=', self.product_tmpl_id.id), ('applied_on', '=', '1_product'), + '&', ('product_id', '=', self.id), ('applied_on', '=', '0_product_variant')] + return { + 'name': _('Price Rules'), + 'view_mode': 'tree,form', + 'views': [(self.env.ref('product.product_pricelist_item_tree_view_from_product').id, 'tree'), (False, 'form')], + 'res_model': 'product.pricelist.item', + 'type': 'ir.actions.act_window', + 'target': 'current', + 'domain': domain, + 'context': { + 'default_product_id': self.id, + 'default_applied_on': '0_product_variant', + } + } + def open_product_template(self): """ Utility method used to add an "Open Template" button in product views """ self.ensure_one() diff --git a/addons/product/models/product_pricelist.py b/addons/product/models/product_pricelist.py index dd0dbec8fab..584ec39f27d 100644 --- a/addons/product/models/product_pricelist.py +++ b/addons/product/models/product_pricelist.py @@ -7,7 +7,6 @@ from odoo import api, fields, models, tools, _ from odoo.exceptions import UserError, ValidationError - class Pricelist(models.Model): _name = "product.pricelist" _description = "Pricelist" @@ -46,7 +45,7 @@ class Pricelist(models.Model): FROM (( SELECT pr.id, pr.name FROM product_pricelist pr JOIN - res_currency cur ON + res_currency cur ON (pr.currency_id = cur.id) WHERE pr.name || ' (' || cur.name || ')' = %(name)s ) @@ -59,7 +58,7 @@ class Pricelist(models.Model): tr.name = 'product.pricelist,name' AND tr.lang = %(lang)s ) JOIN - res_currency cur ON + res_currency cur ON (pr.currency_id = cur.id) WHERE tr.value || ' (' || cur.name || ')' = %(name)s ) @@ -374,20 +373,22 @@ class ResCountryGroup(models.Model): class PricelistItem(models.Model): _name = "product.pricelist.item" - _description = "Pricelist Item" + _description = "Pricelist Rule" _order = "applied_on, min_quantity desc, categ_id desc, id desc" # NOTE: if you change _order on this model, make sure it matches the SQL # query built in _compute_price_rule() above in this file to avoid # inconstencies and undeterministic issues. - def _get_default_applied_on(self): - return self.env.user.has_group('product.group_product_pricelist') and '1_product' or '3_global' + def _default_pricelist_id(self): + return self.env['product.pricelist'].search([ + '|', ('company_id', '=', False), + ('company_id', '=', self.env.company.id)], limit=1) product_tmpl_id = fields.Many2one( - 'product.template', 'Product Template', ondelete='cascade', + 'product.template', 'Product', ondelete='cascade', help="Specify a template if this rule only applies to one product template. Keep empty otherwise.") product_id = fields.Many2one( - 'product.product', 'Product', ondelete='cascade', + 'product.product', 'Product Variant', ondelete='cascade', help="Specify a product if this rule only applies to one product. Keep empty otherwise.") categ_id = fields.Many2one( 'product.category', 'Product Category', ondelete='cascade', @@ -398,11 +399,11 @@ class PricelistItem(models.Model): "than or equal to the minimum quantity specified in this field.\n" "Expressed in the default unit of measure of the product.") applied_on = fields.Selection([ - ('3_global', 'Global'), + ('3_global', 'All Products'), ('2_product_category', ' Product Category'), ('1_product', 'Product'), ('0_product_variant', 'Product Variant')], "Apply On", - default=_get_default_applied_on, required=True, + default='3_global', required=True, help='Pricelist Item applicable on selected option') base = fields.Selection([ ('list_price', 'Sales Price'), @@ -414,7 +415,7 @@ class PricelistItem(models.Model): 'Cost Price : The base price will be the cost price.\n' 'Other Pricelist : Computation of the base price based on another Pricelist.') base_pricelist_id = fields.Many2one('product.pricelist', 'Other Pricelist') - pricelist_id = fields.Many2one('product.pricelist', 'Pricelist', index=True, ondelete='cascade', required=True) + pricelist_id = fields.Many2one('product.pricelist', 'Pricelist', index=True, ondelete='cascade', required=True, default=_default_pricelist_id) price_surcharge = fields.Float( 'Price Surcharge', digits='Product Price', help='Specify the fixed amount to add or substract(if negative) to the amount calculated with the discount.') @@ -436,13 +437,15 @@ class PricelistItem(models.Model): currency_id = fields.Many2one( 'res.currency', 'Currency', readonly=True, related='pricelist_id.currency_id', store=True) + active = fields.Boolean( + readonly=True, related="pricelist_id.active", store=True) date_start = fields.Date('Start Date', help="Starting date for the pricelist item validation") date_end = fields.Date('End Date', help="Ending valid for the pricelist item validation") compute_price = fields.Selection([ - ('fixed', 'Fix Price'), + ('fixed', 'Fixed Price'), ('percentage', 'Percentage (discount)'), - ('formula', 'Formula')], index=True, default='fixed') - fixed_price = fields.Float('Fixed Price', digits='Product Price') + ('formula', 'Formula')], index=True, default='fixed', required=True) + fixed_price = fields.Monetary('Fixed Price') percent_price = fields.Float('Percentage Price') # functional fields used for usability purposes name = fields.Char( @@ -464,35 +467,39 @@ class PricelistItem(models.Model): raise ValidationError(_('The minimum margin should be lower than the maximum margin.')) return True - @api.depends('categ_id', 'product_tmpl_id', 'product_id', 'compute_price', 'fixed_price', \ + @api.constrains('product_id', 'product_tmpl_id', 'categ_id') + def _check_product_consistency(self): + for item in self: + if item.applied_on == "2_product_category" and not item.categ_id: + raise ValidationError(_("Please specify the category for which this rule should be applied")) + elif item.applied_on == "1_product" and not item.product_tmpl_id: + raise ValidationError(_("Please specify the product for which this rule should be applied")) + elif item.applied_on == "0_product_variant" and not item.product_id: + raise ValidationError(_("Please specify the product variant for which this rule should be applied")) + + @api.depends('applied_on', 'categ_id', 'product_tmpl_id', 'product_id', 'compute_price', 'fixed_price', \ 'pricelist_id', 'percent_price', 'price_discount', 'price_surcharge') def _get_pricelist_item_name_price(self): for item in self: - if item.categ_id: - item.name = _("Category: %s") % (item.categ_id.name) - elif item.product_tmpl_id: - item.name = item.product_tmpl_id.name - elif item.product_id: - item.name = item.product_id.display_name.replace('[%s]' % item.product_id.code, '') + if item.categ_id and item.applied_on == '2_product_category': + item.name = _("Category: %s") % (item.categ_id.display_name) + elif item.product_tmpl_id and item.applied_on == '1_product': + item.name = _("Product: %s") % (item.product_tmpl_id.display_name) + elif item.product_id and item.applied_on == '0_product_variant': + item.name = _("Variant: %s") % (item.product_id.with_context(display_default_code=False).display_name) else: item.name = _("All Products") if item.compute_price == 'fixed': - item.price = ("%s %s") % (item.fixed_price, item.pricelist_id.currency_id.name) + if item.currency_id.position == 'after': + item.price = "%s %s" % (item.fixed_price, item.currency_id.symbol) + else: + item.price = "%s %s" % (item.currency_id.symbol, item.fixed_price) elif item.compute_price == 'percentage': item.price = _("%s %% discount") % (item.percent_price) else: item.price = _("%s %% discount and %s surcharge") % (item.price_discount, item.price_surcharge) - @api.onchange('applied_on') - def _onchange_applied_on(self): - if self.applied_on != '0_product_variant': - self.product_id = False - if self.applied_on != '1_product': - self.product_tmpl_id = False - if self.applied_on != '2_product_category': - self.categ_id = False - @api.onchange('compute_price') def _onchange_compute_price(self): if self.compute_price != 'fixed': @@ -508,14 +515,65 @@ class PricelistItem(models.Model): 'price_max_margin': 0.0, }) + @api.onchange('product_id') + def _onchange_product_id(self): + has_product_id = self.filtered('product_id') + for item in has_product_id: + item.product_tmpl_id = item.product_id.product_tmpl_id + if self.env.context.get('default_applied_on', False) == '1_product': + # If a product variant is specified, apply on variants instead + # Reset if product variant is removed + has_product_id.update({'applied_on': '0_product_variant'}) + (self - has_product_id).update({'applied_on': '1_product'}) + + @api.onchange('product_tmpl_id') + def _onchange_product_tmpl_id(self): + has_tmpl_id = self.filtered('product_tmpl_id') + for item in has_tmpl_id: + if item.product_id and item.product_id.product_tmpl_id != item.product_tmpl_id: + item.product_id = None + + @api.onchange('product_id', 'product_tmpl_id', 'categ_id') + def _onchane_rule_content(self): + if not self.user_has_groups('product.group_sale_pricelist') and not self.env.context.get('default_applied_on', False): + # If advanced pricelists are disabled (applied_on field is not visible) + # AND we aren't coming from a specific product template/variant. + variants_rules = self.filtered('product_id') + template_rules = (self-variants_rules).filtered('product_tmpl_id') + variants_rules.update({'applied_on': '0_product_variant'}) + template_rules.update({'applied_on': '1_product'}) + (self-variants_rules-template_rules).update({'applied_on': '3_global'}) + + @api.model_create_multi + def create(self, vals_list): + for values in vals_list: + if values.get('applied_on', False): + # Ensure item consistency for later searches. + applied_on = values['applied_on'] + if applied_on == '3_global': + values.update(dict(product_id=None, product_tmpl_id=None, categ_id=None)) + elif applied_on == '2_product_category': + values.update(dict(product_id=None, product_tmpl_id=None)) + elif applied_on == '1_product': + values.update(dict(product_id=None, categ_id=None)) + elif applied_on == '0_product_variant': + values.update(dict(categ_id=None)) + return super(PricelistItem, self).create(vals_list) + def write(self, values): + if values.get('applied_on', False): + # Ensure item consistency for later searches. + applied_on = values['applied_on'] + if applied_on == '3_global': + values.update(dict(product_id=None, product_tmpl_id=None, categ_id=None)) + elif applied_on == '2_product_category': + values.update(dict(product_id=None, product_tmpl_id=None)) + elif applied_on == '1_product': + values.update(dict(product_id=None, categ_id=None)) + elif applied_on == '0_product_variant': + values.update(dict(categ_id=None)) res = super(PricelistItem, self).write(values) # When the pricelist changes we need the product.template price # to be invalided and recomputed. self.invalidate_cache() return res - - @api.onchange('product_tmpl_id') - def _onchange_product_tmpl_id(self): - if self.user_has_groups('product.group_product_variant'): - self.product_id = False diff --git a/addons/product/models/product_template.py b/addons/product/models/product_template.py index 17e8594b006..1fb7484598c 100644 --- a/addons/product/models/product_template.py +++ b/addons/product/models/product_template.py @@ -148,11 +148,17 @@ class ProductTemplate(models.Model): 'Internal Reference', compute='_compute_default_code', inverse='_set_default_code', store=True) - item_ids = fields.One2many('product.pricelist.item', 'product_tmpl_id', 'Pricelist Items') + pricelist_item_count = fields.Integer("Number of price rules", compute="_compute_item_count") can_image_1024_be_zoomed = fields.Boolean("Can Image 1024 be zoomed", compute='_compute_can_image_1024_be_zoomed', store=True) has_configurable_attributes = fields.Boolean("Is a configurable product", compute='_compute_has_configurable_attributes', store=True) + def _compute_item_count(self): + for template in self: + # Pricelist item count counts the rules applicable on current template or on its variants. + template.pricelist_item_count = template.env['product.pricelist.item'].search_count([ + '|', ('product_tmpl_id', '=', template.id), ('product_id', 'in', template.product_variant_ids.ids)]) + @api.depends('image_1920', 'image_1024') def _compute_can_image_1024_be_zoomed(self): for template in self: @@ -454,6 +460,26 @@ class ProductTemplate(models.Model): '', args=[('id', 'in', list(searched_ids))], operator='ilike', limit=limit, name_get_uid=name_get_uid) + def open_pricelist_rules(self): + self.ensure_one() + domain = ['|', + ('product_tmpl_id', '=', self.id), + ('product_id', 'in', self.product_variant_ids.ids)] + return { + 'name': _('Price Rules'), + 'view_mode': 'tree,form', + 'views': [(self.env.ref('product.product_pricelist_item_tree_view_from_product').id, 'tree'), (False, 'form')], + 'res_model': 'product.pricelist.item', + 'type': 'ir.actions.act_window', + 'target': 'current', + 'domain': domain, + 'context': { + 'default_product_tmpl_id': self.id, + 'default_applied_on': '1_product', + 'product_without_variants': self.product_variant_count == 1, + }, + } + def price_compute(self, price_type, uom=False, currency=False, company=False): # TDE FIXME: delegate to template or not ? fields are reencoded here ... # compatibility about context keys used a bit everywhere in the code diff --git a/addons/product/models/res_config_settings.py b/addons/product/models/res_config_settings.py index 6ff32bd8f6b..3606c5806c7 100644 --- a/addons/product/models/res_config_settings.py +++ b/addons/product/models/res_config_settings.py @@ -14,14 +14,17 @@ class ResConfigSettings(models.TransientModel): module_sale_product_matrix = fields.Boolean("Product Grid Configurator") group_stock_packaging = fields.Boolean('Product Packagings', implied_group='product.group_stock_packaging') - group_sale_pricelist = fields.Boolean("Use pricelists to adapt your price per customers", + group_product_pricelist = fields.Boolean("Pricelists", + implied_group='product.group_product_pricelist') + group_sale_pricelist = fields.Boolean("Advanced Pricelists", implied_group='product.group_sale_pricelist', help="""Allows to manage different prices based on rules per category of customers. Example: 10% for retailers, promotion of 5 EUR on this product, etc.""") - group_product_pricelist = fields.Boolean("Show pricelists On Products", - implied_group='product.group_product_pricelist') - group_pricelist_item = fields.Boolean("Show pricelists to customers", - implied_group='product.group_pricelist_item') + product_pricelist_setting = fields.Selection([ + ('basic', 'Multiple prices per product'), + ('advanced', 'Advanced price rules (discounts, formulas)') + ], default='basic', string="Pricelists Method", config_parameter='product.product_pricelist_setting', + help="Multiple prices: Pricelists with fixed price rules by product,\nAdvanced rules: enables advanced price rules for pricelists.") product_weight_in_lbs = fields.Selection([ ('0', 'Kilogram'), ('1', 'Pound'), @@ -47,6 +50,23 @@ class ResConfigSettings(models.TransientModel): if self.module_sale_product_configurator and not self.group_product_variant: self.group_product_variant = True + @api.onchange('group_multi_currency') + def _onchange_group_multi_currency(self): + if self.group_product_pricelist and not self.group_sale_pricelist and self.group_multi_currency: + self.group_sale_pricelist = True + + @api.onchange('group_product_pricelist') + def _onchange_group_sale_pricelist(self): + if not self.group_product_pricelist and self.group_sale_pricelist: + self.group_sale_pricelist = False + + @api.onchange('product_pricelist_setting') + def _onchange_product_pricelist_setting(self): + if self.product_pricelist_setting == 'basic': + self.group_sale_pricelist = False + else: + self.group_sale_pricelist = True + def set_values(self): super(ResConfigSettings, self).set_values() if not self.group_discount_per_so_line: diff --git a/addons/product/security/product_security.xml b/addons/product/security/product_security.xml index bb995448b1f..f10acf38bd2 100644 --- a/addons/product/security/product_security.xml +++ b/addons/product/security/product_security.xml @@ -7,11 +7,6 @@ - - Manage Pricelist Items - - - Pricelists On Product diff --git a/addons/product/tests/test_product_pricelist.py b/addons/product/tests/test_product_pricelist.py index 43db6f7c49b..cb13db1b327 100644 --- a/addons/product/tests/test_product_pricelist.py +++ b/addons/product/tests/test_product_pricelist.py @@ -33,14 +33,14 @@ class TestProductPricelist(TransactionCase): }), (0, 0, { 'name': '10% Discount on Assemble Computer', 'applied_on': '1_product', - 'product_id': self.ipad_retina_display.id, + 'product_tmpl_id': self.ipad_retina_display.product_tmpl_id.id, 'compute_price': 'formula', 'base': 'list_price', 'price_discount': 10 }), (0, 0, { 'name': '1 surchange on Laptop', 'applied_on': '1_product', - 'product_id': self.laptop_E5023.id, + 'product_tmpl_id': self.laptop_E5023.product_tmpl_id.id, 'compute_price': 'formula', 'base': 'list_price', 'price_surcharge': 1 @@ -54,7 +54,7 @@ class TestProductPricelist(TransactionCase): 'price_discount': 5 }), (0, 0, { 'name': '30% Discount on all products', - 'applied_on': '0_product_variant', + 'applied_on': '3_global', 'date_start': '2011-12-27', 'date_end': '2011-12-31', 'compute_price': 'formula', diff --git a/addons/product/views/product_pricelist_views.xml b/addons/product/views/product_pricelist_views.xml index ce292af8749..7a019c7480f 100644 --- a/addons/product/views/product_pricelist_views.xml +++ b/addons/product/views/product_pricelist_views.xml @@ -2,18 +2,87 @@ - - product.pricelist.item.tree + + product.pricelist.item.search product.pricelist.item - - - - - - - - + + + + + + + + + + + + + + + + + + + product.pricelist.item.tree + product.pricelist.item + 10 + + + + + + + + + + + + + + + + product.pricelist.item.tree + product.pricelist.item + 100 + + + + + + + + + + + + + + + @@ -23,61 +92,79 @@ product.pricelist.item
-

- - - - - - - - - - - - - - - - - - -
-

The computed price is expressed in the default Unit of Measure of the product.

-
- - + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

The computed price is expressed in the default Unit of Measure of the product.

+
+ + + + + +
+
@@ -142,28 +229,44 @@

- - - - - + + + + + -
- - - - - - - - - - - - - - -
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -173,21 +276,25 @@ product.pricelist.form.inherit product.pricelist - + + - - - - - - - - - - - - + + + + + + + + + + + + + @@ -221,5 +328,11 @@ + + Price Rules + ir.actions.act_window + product.pricelist.item + tree,form + diff --git a/addons/product/views/product_views.xml b/addons/product/views/product_views.xml index cbf96de83f0..2e142610399 100644 --- a/addons/product/views/product_views.xml +++ b/addons/product/views/product_views.xml @@ -45,7 +45,20 @@ - +
-
+
- +
-
diff --git a/addons/sale/views/sale_views.xml b/addons/sale/views/sale_views.xml index a5be726630c..cfe127a9442 100644 --- a/addons/sale/views/sale_views.xml +++ b/addons/sale/views/sale_views.xml @@ -91,7 +91,7 @@ - + sale.order.activity @@ -308,7 +308,7 @@
- + diff --git a/addons/sale_product_configurator/tests/test_sale_product_configurator_ui.py b/addons/sale_product_configurator/tests/test_sale_product_configurator_ui.py index 21565e631f7..9a06417a432 100644 --- a/addons/sale_product_configurator/tests/test_sale_product_configurator_ui.py +++ b/addons/sale_product_configurator/tests/test_sale_product_configurator_ui.py @@ -19,7 +19,7 @@ class TestUi(odoo.tests.HttpCase): self.env.ref('base.user_admin').write({ 'groups_id': [ (4, self.env.ref('product.group_product_variant').id), - (4, self.env.ref('product.group_sale_pricelist').id), + (4, self.env.ref('product.group_product_pricelist').id), ], }) @@ -88,7 +88,7 @@ class TestUi(odoo.tests.HttpCase): self.env.ref('base.user_admin').write({ 'groups_id': [ (4, self.env.ref('product.group_product_variant').id), - (4, self.env.ref('product.group_sale_pricelist').id), + (4, self.env.ref('product.group_product_pricelist').id), ], }) @@ -131,7 +131,7 @@ class TestUi(odoo.tests.HttpCase): self.env.ref('account.group_show_line_subtotals_tax_included').users |= admin # Active pricelist on SO - self.env.ref('product.group_sale_pricelist').users |= admin + self.env.ref('product.group_product_pricelist').users |= admin # Add a 15% tax on desk tax = self.env['account.tax'].create({'name': "Test tax", 'amount': 15}) @@ -145,7 +145,7 @@ class TestUi(odoo.tests.HttpCase): product_template = self.env.ref('product.product_product_4_product_template') pricelist = self.env.ref('product.list0') - if not pricelist.item_ids.filtered(lambda i: i.product_tmpl_id == product_template and i.price_discount == 20): + if not pricelist.item_ids.filtered(lambda i: i.product_tmpl_id == product_template and i.applied_on == '1_product' and i.price_discount == 20): self.env['product.pricelist.item'].create({ 'base': 'list_price', 'applied_on': '1_product', diff --git a/addons/website_sale/models/res_config_settings.py b/addons/website_sale/models/res_config_settings.py index 2322645b4e1..8e951a95cfc 100644 --- a/addons/website_sale/models/res_config_settings.py +++ b/addons/website_sale/models/res_config_settings.py @@ -76,5 +76,5 @@ class ResConfigSettings(models.TransientModel): def _onchange_group_discount_per_so_line(self): if self.group_discount_per_so_line: self.update({ - 'multi_sales_price': True, + 'group_product_pricelist': True, }) diff --git a/addons/website_sale/views/product_views.xml b/addons/website_sale/views/product_views.xml index 60d1b50aa90..d8f937e94b4 100644 --- a/addons/website_sale/views/product_views.xml +++ b/addons/website_sale/views/product_views.xml @@ -12,17 +12,6 @@ - - product.pricelist.website.form - product.pricelist - - - - - - - - product.product.website.tree product.product @@ -188,11 +177,14 @@ product.pricelist - - - - - + + + + + + + + diff --git a/addons/website_sale/views/res_config_settings_views.xml b/addons/website_sale/views/res_config_settings_views.xml index bb82764a9d6..787b830bfca 100644 --- a/addons/website_sale/views/res_config_settings_views.xml +++ b/addons/website_sale/views/res_config_settings_views.xml @@ -102,20 +102,19 @@
- +
-