diff --git a/sale_loyalty_criteria_multi_product/README.rst b/sale_loyalty_criteria_multi_product/README.rst index 01b3d7ba..8ba8236e 100644 --- a/sale_loyalty_criteria_multi_product/README.rst +++ b/sale_loyalty_criteria_multi_product/README.rst @@ -1,5 +1,5 @@ ====================================== -Coupons multi product criteria in sale +Loyalty multi product criteria in sale ====================================== .. @@ -7,7 +7,7 @@ Coupons multi product criteria in sale !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:5608f6887448744476c7634f8c9ea1bbe696e6fb56c02e60ebaad6680f5d5e98 + !! source digest: sha256:60ab5d35e66cdbb4502d15ae37cbc061c3f9e9f571ef60d08c78e9d98b0154ad !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png @@ -17,18 +17,18 @@ Coupons multi product criteria in sale :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsale--promotion-lightgray.png?logo=github - :target: https://github.com/OCA/sale-promotion/tree/15.0/sale_coupon_criteria_multi_product + :target: https://github.com/OCA/sale-promotion/tree/16.0-mig-sale_coupon_criteria_multi_product/sale_loyalty_criteria_multi_product :alt: OCA/sale-promotion .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/sale-promotion-15-0/sale-promotion-15-0-sale_coupon_criteria_multi_product + :target: https://translation.odoo-community.org/projects/sale-promotion-16-0-mig-sale_coupon_criteria_multi_product/sale-promotion-16-0-mig-sale_coupon_criteria_multi_product-sale_loyalty_criteria_multi_product :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/sale-promotion&target_branch=15.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/sale-promotion&target_branch=16.0-mig-sale_coupon_criteria_multi_product :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| -Module that extends from *coupon_criteria_multi_product* and allows to +Module that extends from *loyalty_criteria_multi_product* and allows to use it's configuration in sale orders. **Table of contents** @@ -52,7 +52,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. @@ -99,6 +99,6 @@ Current `maintainer `__: |maintainer-chienandalu| -This module is part of the `OCA/sale-promotion `_ project on GitHub. +This module is part of the `OCA/sale-promotion `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/sale_loyalty_criteria_multi_product/__manifest__.py b/sale_loyalty_criteria_multi_product/__manifest__.py index ce89230f..775ee687 100644 --- a/sale_loyalty_criteria_multi_product/__manifest__.py +++ b/sale_loyalty_criteria_multi_product/__manifest__.py @@ -1,14 +1,14 @@ # Copyright 2021 Tecnativa - David Vidal # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). { - "name": "Coupons multi product criteria in sale", + "name": "Loyalty multi product criteria in sale", "summary": "Allows to set as promotion criteria multi-product conditions", - "version": "15.0.1.0.0", + "version": "16.0.1.0.0", "development_status": "Production/Stable", "category": "Sale", "website": "https://github.com/OCA/sale-promotion", "author": "Tecnativa, Odoo Community Association (OCA)", "maintainers": ["chienandalu"], "license": "AGPL-3", - "depends": ["coupon_criteria_multi_product", "sale_coupon"], + "depends": ["loyalty_criteria_multi_product", "sale_loyalty"], } diff --git a/sale_loyalty_criteria_multi_product/i18n/es.po b/sale_loyalty_criteria_multi_product/i18n/es.po index b65c3ad8..af4c8d83 100644 --- a/sale_loyalty_criteria_multi_product/i18n/es.po +++ b/sale_loyalty_criteria_multi_product/i18n/es.po @@ -1,6 +1,6 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * sale_coupon_criteria_multi_product +# * sale_loyalty_criteria_multi_product # msgid "" msgstr "" @@ -17,8 +17,8 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 3.2.2\n" -#. module: sale_coupon_criteria_multi_product -#: model:ir.model,name:sale_coupon_criteria_multi_product.model_coupon_program +#. module: sale_loyalty_criteria_multi_product +#: model:ir.model,name:sale_loyalty_criteria_multi_product.model_coupon_program msgid "Coupon display on a website" msgstr "" diff --git a/sale_loyalty_criteria_multi_product/i18n/sale_coupon_criteria_multi_product.pot b/sale_loyalty_criteria_multi_product/i18n/sale_loyalty_criteria_multi_product.pot similarity index 69% rename from sale_loyalty_criteria_multi_product/i18n/sale_coupon_criteria_multi_product.pot rename to sale_loyalty_criteria_multi_product/i18n/sale_loyalty_criteria_multi_product.pot index 718b1ab3..6ac54768 100644 --- a/sale_loyalty_criteria_multi_product/i18n/sale_coupon_criteria_multi_product.pot +++ b/sale_loyalty_criteria_multi_product/i18n/sale_loyalty_criteria_multi_product.pot @@ -1,6 +1,6 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * sale_coupon_criteria_multi_product +# * sale_loyalty_criteria_multi_product # msgid "" msgstr "" @@ -13,7 +13,7 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: \n" -#. module: sale_coupon_criteria_multi_product -#: model:ir.model,name:sale_coupon_criteria_multi_product.model_coupon_program +#. module: sale_loyalty_criteria_multi_product +#: model:ir.model,name:sale_loyalty_criteria_multi_product.model_coupon_program msgid "Coupon display on a website" msgstr "" diff --git a/sale_loyalty_criteria_multi_product/models/__init__.py b/sale_loyalty_criteria_multi_product/models/__init__.py index e74b5d25..f668597f 100644 --- a/sale_loyalty_criteria_multi_product/models/__init__.py +++ b/sale_loyalty_criteria_multi_product/models/__init__.py @@ -1 +1,2 @@ -from . import coupon_program +from . import loyalty_program +from . import sale_order diff --git a/sale_loyalty_criteria_multi_product/models/coupon_program.py b/sale_loyalty_criteria_multi_product/models/coupon_program.py deleted file mode 100644 index 246af91c..00000000 --- a/sale_loyalty_criteria_multi_product/models/coupon_program.py +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright 2021 Tecnativa - David Vidal -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -from odoo import models - - -class CouponProgram(models.Model): - _inherit = "coupon.program" - - def _filter_programs_on_products(self, order): - """ - After splitting the programs according to their criteria, we'll check the rules - on the multi-product ones to filter those that fulfill all the conditions. - Depending on the Repeat Product setting a valid criteria will be: - - Repeat: at least one of the products in the criteria and the minimum qty - - No repeat: one unit every product in the criteria. - All the criterias defined in a program must be fulfilled. - """ - domain_programs = self.filtered(lambda x: x.coupon_criteria == "domain") - multi_product_programs = (self - domain_programs).filtered( - "coupon_criteria_ids" - ) - # We'll return them altogether - valid_domain_criteria_programs = super( - CouponProgram, domain_programs - )._filter_programs_on_products(order) - order_lines = ( - order.order_line.filtered(lambda line: line.product_id) - - order._get_reward_lines() - ) - products = order_lines.mapped("product_id") - products_qties = dict.fromkeys(products, 0) - for line in order_lines: - products_qties[line.product_id] += line.product_uom_qty - valid_multi_product_criteria_programs = multi_product_programs - for program in multi_product_programs: - criterias_are_valid = True - for criteria in program.coupon_criteria_ids: - valid_products = program._get_valid_products_multi_product( - products, criteria - ) - if not valid_products: - criterias_are_valid = False - break - ordered_rule_products_qty = sum( - products_qties[p] for p in valid_products - ) - # Avoid program if 1 ordered foo on a program '1 foo, 1 free foo' - # as it's done in the standard - if ( - program.promo_applicability == "on_current_order" - and program.reward_type == "product" - and program.reward_product_id in criteria.product_ids - ): - ordered_rule_products_qty -= program.reward_product_quantity - if ordered_rule_products_qty < criteria.rule_min_quantity: - criterias_are_valid = False - break - if not criterias_are_valid: - valid_multi_product_criteria_programs -= program - return valid_domain_criteria_programs + valid_multi_product_criteria_programs diff --git a/sale_loyalty_criteria_multi_product/models/loyalty_program.py b/sale_loyalty_criteria_multi_product/models/loyalty_program.py new file mode 100644 index 00000000..a3476d53 --- /dev/null +++ b/sale_loyalty_criteria_multi_product/models/loyalty_program.py @@ -0,0 +1,16 @@ +# Copyright 2021 Tecnativa - David Vidal +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import models + + +class LoyaltyProgram(models.Model): + _inherit = "loyalty.program" + + def _get_valid_products_multi_product(self, products, rule): + """Return valid products depending on the rule repeat product setting. Then + the main method will check if the minimum quantities are acomplished.""" + if rule.repeat_product: + return products.browse([x.id for x in rule.product_ids if x in products]) + if not all([x in products for x in rule.product_ids]): + return self.env["product.product"] + return rule.product_ids diff --git a/sale_loyalty_criteria_multi_product/models/sale_order.py b/sale_loyalty_criteria_multi_product/models/sale_order.py new file mode 100644 index 00000000..3b485382 --- /dev/null +++ b/sale_loyalty_criteria_multi_product/models/sale_order.py @@ -0,0 +1,61 @@ +# Copyright 2021 Tecnativa - David Vidal +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import models + + +class SaleOrder(models.Model): + _inherit = "sale.order" + + def _program_check_compute_points(self, programs): + """ + Updates applied programs's given points with the current state of the order. + Checks automatic programs for applicability. + Updates applied rewards using the new points and the current state of the order + (for example with % discounts). + """ + self.ensure_one() + domain_programs = programs.filtered(lambda x: x.loyalty_criteria == "domain") + multi_product_programs = (programs - domain_programs).filtered( + "loyalty_criteria_ids" + ) + # We'll return them altogether + valid_domain_criteria_programs = super()._program_check_compute_points( + domain_programs + ) + order_lines = self.order_line.filtered( + lambda line: line.product_id + ) - self.order_line.filtered("is_reward_line") + products = order_lines.mapped("product_id") + products_qties = dict.fromkeys(products, 0) + for line in order_lines: + products_qties[line.product_id] += line.product_uom_qty + valid_multi_product_criteria_programs = dict.fromkeys( + multi_product_programs, dict() + ) + + for program in multi_product_programs: + criterias_are_valid = True + for criteria in program.loyalty_criteria_ids: + valid_products = program._get_valid_products_multi_product( + products, criteria + ) + if not valid_products: + criterias_are_valid = False + ordered_rule_products_qty = sum( + products_qties[p] for p in valid_products + ) + if ordered_rule_products_qty < criteria.criterian_min_quantity: + criterias_are_valid = False + if not criterias_are_valid: + valid_multi_product_criteria_programs[program] = { + "error": "You don't have the required " + "product quantities on your sales order." + } + else: + # bypass: forced the points of program + # because the original function takes this from rules + valid_multi_product_criteria_programs[program] = {"points": [1]} + return { + **valid_domain_criteria_programs, + **valid_multi_product_criteria_programs, + } diff --git a/sale_loyalty_criteria_multi_product/readme/DESCRIPTION.rst b/sale_loyalty_criteria_multi_product/readme/DESCRIPTION.rst index 77fc1e41..70e26980 100644 --- a/sale_loyalty_criteria_multi_product/readme/DESCRIPTION.rst +++ b/sale_loyalty_criteria_multi_product/readme/DESCRIPTION.rst @@ -1,2 +1,2 @@ -Module that extends from *coupon_criteria_multi_product* and allows to +Module that extends from *loyalty_criteria_multi_product* and allows to use it's configuration in sale orders. diff --git a/sale_loyalty_criteria_multi_product/static/description/index.html b/sale_loyalty_criteria_multi_product/static/description/index.html index 611ee128..4ecf1333 100644 --- a/sale_loyalty_criteria_multi_product/static/description/index.html +++ b/sale_loyalty_criteria_multi_product/static/description/index.html @@ -4,7 +4,7 @@ -Coupons multi product criteria in sale +Loyalty multi product criteria in sale -
-

Coupons multi product criteria in sale

+
+

Loyalty multi product criteria in sale

-

Production/Stable License: AGPL-3 OCA/sale-promotion Translate me on Weblate Try me on Runboat

-

Module that extends from coupon_criteria_multi_product and allows to +

Production/Stable License: AGPL-3 OCA/sale-promotion Translate me on Weblate Try me on Runboat

+

Module that extends from loyalty_criteria_multi_product and allows to use it’s configuration in sale orders.

Table of contents

@@ -399,7 +399,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.

@@ -435,7 +435,7 @@

Maintainers

promote its widespread use.

Current maintainer:

chienandalu

-

This module is part of the OCA/sale-promotion project on GitHub.

+

This module is part of the OCA/sale-promotion project on GitHub.

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

diff --git a/sale_loyalty_criteria_multi_product/tests/__init__.py b/sale_loyalty_criteria_multi_product/tests/__init__.py index 5372ce41..ecfbbfbb 100644 --- a/sale_loyalty_criteria_multi_product/tests/__init__.py +++ b/sale_loyalty_criteria_multi_product/tests/__init__.py @@ -1 +1 @@ -from . import test_sale_coupon_criteria_multi_product +from . import test_sale_loyalty_criteria_multi_product diff --git a/sale_loyalty_criteria_multi_product/tests/test_sale_coupon_criteria_multi_product.py b/sale_loyalty_criteria_multi_product/tests/test_sale_loyalty_criteria_multi_product.py similarity index 86% rename from sale_loyalty_criteria_multi_product/tests/test_sale_coupon_criteria_multi_product.py rename to sale_loyalty_criteria_multi_product/tests/test_sale_loyalty_criteria_multi_product.py index 13d709ad..02a2da0c 100644 --- a/sale_loyalty_criteria_multi_product/tests/test_sale_coupon_criteria_multi_product.py +++ b/sale_loyalty_criteria_multi_product/tests/test_sale_loyalty_criteria_multi_product.py @@ -2,12 +2,12 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from odoo.tests import Form -from odoo.addons.coupon_criteria_multi_product.tests import ( - TestCouponCriteriaMultiProduct, +from odoo.addons.loyalty_criteria_multi_product.tests import ( + TestLoyaltyCriteriaMultiProduct, ) -class TestSaleCouponCriteriaMultiProduct(TestCouponCriteriaMultiProduct): +class TestSaleLoyaltyCriteriaMultiProduct(TestLoyaltyCriteriaMultiProduct): @classmethod def setUpClass(cls): super().setUpClass() @@ -31,18 +31,19 @@ def setUpClass(cls): def test_sale_coupon_test_criteria_multi_product(self): """Only when all the criterias are matched we can apply the program""" # The discount is correctly applied - self.sale.recompute_coupon_lines() + self.sale.action_open_reward_wizard() discount_line = self.sale.order_line.filtered("is_reward_line") self.assertTrue(bool(discount_line)) # We can change product E by product D as the criteria is set to repeat line_e = self.sale.order_line.filtered(lambda x: x.product_id == self.product_e) line_e.product_id = self.product_d - self.sale.recompute_coupon_lines() + self.sale.action_open_reward_wizard() discount_line = self.sale.order_line.filtered("is_reward_line") self.assertTrue(bool(discount_line)) # If the order doesn't fulfill all the criterias, the discount isn't applied + line_e.product_uom_qty = 2 - self.sale.recompute_coupon_lines() + self.sale.action_open_reward_wizard() discount_line = self.sale.order_line.filtered("is_reward_line") self.assertFalse(discount_line) # If the criteria doesn't repeat, all the products must be in the cart @@ -50,6 +51,6 @@ def test_sale_coupon_test_criteria_multi_product(self): line_e.product_uom_qty = 3 # And now we'll remove B, that should be present self.sale.order_line.filtered(lambda x: x.product_id == self.product_b).unlink() - self.sale.recompute_coupon_lines() + self.sale.action_open_reward_wizard() discount_line = self.sale.order_line.filtered("is_reward_line") self.assertFalse(discount_line) diff --git a/setup/sale_coupon_criteria_multi_product/odoo/addons/sale_coupon_criteria_multi_product b/setup/sale_coupon_criteria_multi_product/odoo/addons/sale_coupon_criteria_multi_product deleted file mode 120000 index e853b8c2..00000000 --- a/setup/sale_coupon_criteria_multi_product/odoo/addons/sale_coupon_criteria_multi_product +++ /dev/null @@ -1 +0,0 @@ -../../../../sale_coupon_criteria_multi_product \ No newline at end of file diff --git a/setup/sale_loyalty_criteria_multi_product/odoo/addons/sale_loyalty_criteria_multi_product b/setup/sale_loyalty_criteria_multi_product/odoo/addons/sale_loyalty_criteria_multi_product new file mode 120000 index 00000000..70a7d556 --- /dev/null +++ b/setup/sale_loyalty_criteria_multi_product/odoo/addons/sale_loyalty_criteria_multi_product @@ -0,0 +1 @@ +../../../../sale_loyalty_criteria_multi_product \ No newline at end of file diff --git a/setup/sale_coupon_criteria_multi_product/setup.py b/setup/sale_loyalty_criteria_multi_product/setup.py similarity index 100% rename from setup/sale_coupon_criteria_multi_product/setup.py rename to setup/sale_loyalty_criteria_multi_product/setup.py