diff --git a/sale_loyalty_discount_attribute/README.rst b/sale_loyalty_discount_attribute/README.rst new file mode 100644 index 000000000..ac365b5d9 --- /dev/null +++ b/sale_loyalty_discount_attribute/README.rst @@ -0,0 +1 @@ +To be Generated diff --git a/sale_loyalty_discount_attribute/__init__.py b/sale_loyalty_discount_attribute/__init__.py new file mode 100644 index 000000000..3275ac2ad --- /dev/null +++ b/sale_loyalty_discount_attribute/__init__.py @@ -0,0 +1,2 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from . import models diff --git a/sale_loyalty_discount_attribute/__manifest__.py b/sale_loyalty_discount_attribute/__manifest__.py new file mode 100644 index 000000000..43dc939a7 --- /dev/null +++ b/sale_loyalty_discount_attribute/__manifest__.py @@ -0,0 +1,16 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +{ + "name": "Promotion Discounts on Selected Attributes", + "summary": "Allow attribute prices to not be subject to promotion discounts", + "version": "16.0.0.0.0", + "maintainers": ["diogocsc"], + "category": "Sales", + "author": "Open Source Integrators, Odoo Community Association (OCA)", + "license": "AGPL-3", + "application": False, + "installable": True, + "depends": ["sale_loyalty"], + "data": [ + "views/loyalty_reward_views.xml" + ], +} diff --git a/sale_loyalty_discount_attribute/models/__init__.py b/sale_loyalty_discount_attribute/models/__init__.py new file mode 100644 index 000000000..55faa4616 --- /dev/null +++ b/sale_loyalty_discount_attribute/models/__init__.py @@ -0,0 +1,2 @@ +from . import loyalty_reward, sale_order + diff --git a/sale_loyalty_discount_attribute/models/loyalty_reward.py b/sale_loyalty_discount_attribute/models/loyalty_reward.py new file mode 100644 index 000000000..965330356 --- /dev/null +++ b/sale_loyalty_discount_attribute/models/loyalty_reward.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- + + +from odoo import _, api, fields, models + + +class LoyaltyReward(models.Model): + _inherit = 'loyalty.reward' + + limit_discounted_attributes = fields.Selection([ + ('disabled', ''), + ('list_price', 'On List Price and Attributes'), + ('attributes', 'On Attributes Only')], default='disabled', + ) + discount_attribute_ids = fields.Many2many('product.attribute', string="Discounted Attributes") diff --git a/sale_loyalty_discount_attribute/models/sale_order.py b/sale_loyalty_discount_attribute/models/sale_order.py new file mode 100644 index 000000000..76b348f93 --- /dev/null +++ b/sale_loyalty_discount_attribute/models/sale_order.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models, _ + + +class SaleOrder(models.Model): + _inherit = "sale.order" + + def _get_reward_values_discount(self, reward, coupon, **kwargs): + # recalculates the reward discount + # + self.ensure_one() + res = super()._get_reward_values_discount(reward, coupon, **kwargs) + return_res = [] + LoyaltyReward = self.env["loyalty.reward"] + for discount in res: + price_unit = discount.get("price_unit") + reward = LoyaltyReward.browse(discount.get("reward_id")) + discount_value = reward.discount/100 # implies that discount is a percentage + # if product has an attribute selected on the discount + reward_attributes = reward.discount_attribute_ids + reward_products = reward.discount_product_ids + # get the matching sale order lines for the current discount + so_lines = self.order_line.filtered(lambda sol: sol.product_id in reward_products) + if reward.limit_discounted_attributes != "disabled": + for value_line in so_lines.product_no_variant_attribute_value_ids: + if value_line.attribute_id not in reward_attributes: + price_unit += value_line.price_extra * discount_value + # if limit discounted attributes is set to attributes, + # sales list price should not be considered for discount as well + # and is counted as many times as the product repeats itself in the lines + if reward.limit_discounted_attributes == "attributes": + price_unit += so_lines.product_id.list_price * len(so_lines) * discount_value + discount.update({"price_unit": price_unit}) + return_res.append(discount) + + return return_res + + + + diff --git a/sale_loyalty_discount_attribute/readme/CONTRIBUTORS.rst b/sale_loyalty_discount_attribute/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..d95bfe076 --- /dev/null +++ b/sale_loyalty_discount_attribute/readme/CONTRIBUTORS.rst @@ -0,0 +1,2 @@ +* Diogo Cordeiro +* Daniel Reis diff --git a/sale_loyalty_discount_attribute/readme/DESCRIPTION.rst b/sale_loyalty_discount_attribute/readme/DESCRIPTION.rst new file mode 100644 index 000000000..d69cd6703 --- /dev/null +++ b/sale_loyalty_discount_attribute/readme/DESCRIPTION.rst @@ -0,0 +1,2 @@ +When applying promotion discounts, there may be the discount should not apply if the prices of some of the extra options are selected. +This feature allows to enable this on the promotion setup, and identify the product Variant Attributes to consider or ignore. diff --git a/sale_loyalty_discount_attribute/readme/USAGE.rst b/sale_loyalty_discount_attribute/readme/USAGE.rst new file mode 100644 index 000000000..95a52e742 --- /dev/null +++ b/sale_loyalty_discount_attribute/readme/USAGE.rst @@ -0,0 +1,4 @@ +On the Discount & Loyalty form, in the Rewards popup screen, a "Limit Discounted Attributes" selection list enables this feature. +Options are: empty (disabled), "On List Price and Attributes", or "On Attributes Only". +This makes available a "Discounted Attributes" field, to select zero or more Attributes that will have the discount applied. + diff --git a/sale_loyalty_discount_attribute/views/loyalty_reward_views.xml b/sale_loyalty_discount_attribute/views/loyalty_reward_views.xml new file mode 100644 index 000000000..7f5b918b2 --- /dev/null +++ b/sale_loyalty_discount_attribute/views/loyalty_reward_views.xml @@ -0,0 +1,14 @@ + + + + loyalty.reward.form.view.inherit + loyalty.reward + + + + + + + + +