diff --git a/pricelist_brand/README.rst b/pricelist_brand/README.rst index c67362290..8b1da6bb2 100644 --- a/pricelist_brand/README.rst +++ b/pricelist_brand/README.rst @@ -7,7 +7,7 @@ Pricelist Brand !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:7344b7bbb6969b50fd2aeb490f098a230dfdd3248822e53802788dfee0904269 + !! source digest: sha256:1da3e6535ebeeecede9d443275f9f2f0e2e2dcfd6309f236f3e961bfe38522f7 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png @@ -17,13 +17,13 @@ Pricelist Brand :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fbrand-lightgray.png?logo=github - :target: https://github.com/OCA/brand/tree/13.0/pricelist_brand + :target: https://github.com/OCA/brand/tree/16.0/pricelist_brand :alt: OCA/brand .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/brand-13-0/brand-13-0-pricelist_brand + :target: https://translation.odoo-community.org/projects/brand-16-0/brand-16-0-pricelist_brand :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/brand&target_branch=13.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/brand&target_branch=16.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| @@ -53,7 +53,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -83,6 +83,6 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -This module is part of the `OCA/brand `_ project on GitHub. +This module is part of the `OCA/brand `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/pricelist_brand/__manifest__.py b/pricelist_brand/__manifest__.py index 1645144c1..49fdd4771 100644 --- a/pricelist_brand/__manifest__.py +++ b/pricelist_brand/__manifest__.py @@ -4,7 +4,7 @@ { "name": "Pricelist Brand", "summary": """This module allows to apply pricelist items on brand""", - "version": "13.0.1.0.0", + "version": "16.0.1.0.0", "license": "AGPL-3", "author": "ACSONE SA/NV,Odoo Community Association (OCA)", "website": "https://github.com/OCA/brand", diff --git a/pricelist_brand/models/product_pricelist.py b/pricelist_brand/models/product_pricelist.py index 24f0106ed..a286ba597 100644 --- a/pricelist_brand/models/product_pricelist.py +++ b/pricelist_brand/models/product_pricelist.py @@ -3,47 +3,34 @@ from odoo import _, api, fields, models from odoo.exceptions import ValidationError +from odoo.osv import expression class ProductPricelist(models.Model): _inherit = "product.pricelist" - def _compute_price_rule_get_items( - self, products_qty_partner, date, uom_id, prod_tmpl_ids, prod_ids, categ_ids - ): - self.ensure_one() - product_tmpls = self.env["product.template"].browse(prod_tmpl_ids) - brand_ids = product_tmpls.mapped("product_brand_id").ids - # Load all rules - self.env["product.pricelist.item"].flush(["price", "currency_id", "company_id"]) - self.env.cr.execute( - """ - SELECT - item.id - FROM - product_pricelist_item AS item - LEFT JOIN product_category AS categ ON item.categ_id = categ.id - LEFT JOIN product_brand AS brand ON item.product_brand_id = brand.id - WHERE - (item.product_tmpl_id IS NULL OR item.product_tmpl_id = any(%s)) - AND (item.product_id IS NULL OR item.product_id = any(%s)) - AND (item.categ_id IS NULL OR item.categ_id = any(%s)) - AND (item.product_brand_id IS NULL OR item.product_brand_id = any(%s)) - AND (item.pricelist_id = %s) - AND (item.date_start IS NULL OR item.date_start<=%s) - AND (item.date_end IS NULL OR item.date_end>=%s) - ORDER BY - item.applied_on, item.min_quantity desc, - categ.complete_name desc, item.id desc - """, - (prod_tmpl_ids, prod_ids, categ_ids, brand_ids, self.id, date, date), + def _get_applicable_rules_domain(self, products, date, **kwargs): + res = super()._get_applicable_rules_domain(products, date) + if products._name == "product.template": + brand_domain = ("product_brand_id", "in", products.product_brand_id.ids) + else: + brand_domain = ( + "product_brand_id", + "in", + products.product_tmpl_id.product_brand_id.ids, + ) + res = expression.AND( + [ + res, + [ + ("|"), + ("product_brand_id", "=", False), + (brand_domain), + ], + ] ) - # NOTE: if you change `order by` on that query, make sure it matches - # _order from model to avoid inconstencies and undeterministic issues. - - item_ids = [x[0] for x in self.env.cr.fetchall()] - return self.env["product.pricelist.item"].browse(item_ids) + return res class ProductPricelistItem(models.Model): @@ -57,16 +44,18 @@ class ProductPricelistItem(models.Model): help="Specify a brand if this rule only applies to products" "belonging to this brand. Keep empty otherwise.", ) - applied_on = fields.Selection(selection_add=[("25_brand", "Brand")]) + applied_on = fields.Selection( + selection_add=[("25_brand", "Brand")], ondelete={"25_brand": "set default"} + ) @api.constrains("product_id", "product_tmpl_id", "categ_id", "product_brand_id") def _check_product_consistency(self): - super(ProductPricelistItem, self)._check_product_consistency() for item in self: if item.applied_on == "25_brand" and not item.product_brand_id: raise ValidationError( _("Please specify the brand for which this rule should be applied") ) + return super()._check_product_consistency() @api.depends( "applied_on", @@ -82,14 +71,14 @@ def _check_product_consistency(self): "product_brand_id", ) def _get_pricelist_item_name_price(self): - super(ProductPricelistItem, self)._get_pricelist_item_name_price() for item in self: if item.product_brand_id and item.applied_on == "25_brand": item.name = _("Brand: %s") % (item.product_brand_id.display_name) + return super()._get_pricelist_item_name_price() @api.onchange("product_id", "product_tmpl_id", "categ_id", "product_brand_id") - def _onchane_rule_content(self): - super(ProductPricelistItem, self)._onchane_rule_content() + def _onchange_rule_content(self): + return super()._onchange_rule_content() @api.model_create_multi def create(self, vals_list): @@ -109,7 +98,7 @@ def create(self, vals_list): values.update(dict(product_brand_id=None)) elif applied_on == "0_product_variant": values.update(dict(product_brand_id=None)) - return super(ProductPricelistItem, self).create(vals_list) + return super().create(vals_list) def write(self, values): if values.get("applied_on", False): @@ -127,4 +116,4 @@ def write(self, values): values.update(dict(product_brand_id=None)) elif applied_on == "0_product_variant": values.update(dict(product_brand_id=None)) - return super(ProductPricelistItem, self).write(values) + return super().write(values) diff --git a/pricelist_brand/static/description/index.html b/pricelist_brand/static/description/index.html index 0529023c8..3e2d8b8de 100644 --- a/pricelist_brand/static/description/index.html +++ b/pricelist_brand/static/description/index.html @@ -9,10 +9,11 @@ /* :Author: David Goodger (goodger@python.org) -:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $ +:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $ :Copyright: This stylesheet has been placed in the public domain. Default cascading style sheet for the HTML output of Docutils. +Despite the name, some widely supported CSS2 features are used. See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to customize this style sheet. @@ -275,7 +276,7 @@ margin-left: 2em ; margin-right: 2em } -pre.code .ln { color: grey; } /* line numbers */ +pre.code .ln { color: gray; } /* line numbers */ pre.code, code { background-color: #eeeeee } pre.code .comment, code .comment { color: #5C6576 } pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold } @@ -301,7 +302,7 @@ span.pre { white-space: pre } -span.problematic { +span.problematic, pre.problematic { color: red } span.section-subtitle { @@ -367,9 +368,9 @@

Pricelist Brand

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:7344b7bbb6969b50fd2aeb490f098a230dfdd3248822e53802788dfee0904269 +!! source digest: sha256:1da3e6535ebeeecede9d443275f9f2f0e2e2dcfd6309f236f3e961bfe38522f7 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Beta License: AGPL-3 OCA/brand Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/brand Translate me on Weblate Try me on Runboat

This module allows to configure pricelist items so that they are applied on products of specific brands.

Table of contents

@@ -401,7 +402,7 @@

Bug Tracker

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -feedback.

+feedback.

Do not contact contributors directly about support or help with technical issues.

@@ -421,11 +422,13 @@

Contributors

Maintainers

This module is maintained by the OCA.

-Odoo Community Association + +Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.

-

This module is part of the OCA/brand project on GitHub.

+

This module is part of the OCA/brand project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

diff --git a/pricelist_brand/tests/test_product_pricelist.py b/pricelist_brand/tests/test_product_pricelist.py index 56bd87d90..98d8bf590 100644 --- a/pricelist_brand/tests/test_product_pricelist.py +++ b/pricelist_brand/tests/test_product_pricelist.py @@ -7,18 +7,19 @@ class TestProductPricelist(TransactionCase): - def setUp(self): - super(TestProductPricelist, self).setUp() - self.product_brand_obj = self.env["product.brand"] - self.product_brand = self.env["product.brand"].create( + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.product_brand_obj = cls.env["product.brand"] + cls.product_brand = cls.env["product.brand"].create( {"name": "Test Brand", "description": "Test brand description"} ) - self.product = self.env.ref("product.product_product_4") - self.product.write({"product_brand_id": self.product_brand.id}) - self.product_2 = self.env.ref("product.product_product_5") + cls.product = cls.env.ref("product.product_product_4") + cls.product.write({"product_brand_id": cls.product_brand.id}) + cls.product_2 = cls.env.ref("product.product_product_5") - self.list0 = self.ref("product.list0") - self.pricelist = self.env["product.pricelist"].create( + cls.list0 = cls.env.ref("product.list0") + cls.pricelist = cls.env["product.pricelist"].create( { "name": "Test Pricelist", "item_ids": [ @@ -29,7 +30,7 @@ def setUp(self): "name": "Default pricelist", "compute_price": "formula", "base": "pricelist", - "base_pricelist_id": self.list0, + "base_pricelist_id": cls.list0.id, }, ), ( @@ -38,7 +39,7 @@ def setUp(self): { "name": "10% Discount on Test Brand", "applied_on": "25_brand", - "product_brand_id": self.product_brand.id, + "product_brand_id": cls.product_brand.id, "compute_price": "formula", "base": "list_price", "price_discount": 10, @@ -108,14 +109,13 @@ def test_ensure_pricelist_item_consistency(self): def test_calculation_price_of_products_pricelist(self): """Test calculation of product price based on pricelist""" - context = {} - context.update({"pricelist": self.pricelist.id, "quantity": 1}) - # Check sale price of branded product - product_with_context = self.product.with_context(context) + product_with_context = self.product.with_context( + pricelist=self.pricelist.id, quantity=1 + ) self.assertEqual( float_compare( - product_with_context.price, + product_with_context._get_contextual_price(), ( product_with_context.lst_price - product_with_context.lst_price * (0.10) @@ -126,10 +126,12 @@ def test_calculation_price_of_products_pricelist(self): ) # Check sale price of not branded product (should not change) - product_2_with_context = self.product_2.with_context(context) + product_2_with_context = self.product_2.with_context( + pricelist=self.pricelist.id, quantity=1 + ) self.assertEqual( float_compare( - product_2_with_context.price, + product_2_with_context._get_contextual_price(), product_2_with_context.lst_price, precision_digits=2, ),