diff --git a/addons/website_sale_loyalty/controllers/main.py b/addons/website_sale_loyalty/controllers/main.py index d6e64e3e20b..c79ea86bbd8 100644 --- a/addons/website_sale_loyalty/controllers/main.py +++ b/addons/website_sale_loyalty/controllers/main.py @@ -87,3 +87,13 @@ class WebsiteSale(main.WebsiteSale): order._apply_program_reward(reward, coupon) except UserError as e: request.session['error_promo_code'] = str(e) + + @http.route() + def cart_update_json(self, *args, set_qty=None, **kwargs): + # When a reward line is deleted we remove it from the auto claimable rewards + if set_qty == 0: + request.update_context(website_sale_loyalty_delete=True) + # We need to update the website since `get_sale_order` is called on the website + # and does not follow the request's context + request.website = request.website.with_context(website_sale_loyalty_delete=True) + return super().cart_update_json(*args, set_qty=set_qty, **kwargs) diff --git a/addons/website_sale_loyalty/models/sale_order.py b/addons/website_sale_loyalty/models/sale_order.py index f6d27097ace..31f28875eda 100644 --- a/addons/website_sale_loyalty/models/sale_order.py +++ b/addons/website_sale_loyalty/models/sale_order.py @@ -11,6 +11,9 @@ from odoo.http import request class SaleOrder(models.Model): _inherit = "sale.order" + # List of disabled rewards for automatic claim + disabled_auto_rewards = fields.Many2many("loyalty.reward", relation="sale_order_disabled_auto_rewards_rel") + def _get_program_domain(self): res = super()._get_program_domain() # Replace `sale_ok` leaf with `ecommerce_ok` if order is linked to a website @@ -72,7 +75,8 @@ class SaleOrder(models.Model): for coupon, rewards in claimable_rewards.items(): if len(coupon.program_id.reward_ids) != 1 or\ coupon.program_id.is_nominative or\ - (rewards.reward_type == 'product' and rewards.multi_product): + (rewards.reward_type == 'product' and rewards.multi_product) or\ + rewards in self.disabled_auto_rewards: continue try: res = self._apply_program_reward(rewards, coupon) diff --git a/addons/website_sale_loyalty/models/sale_order_line.py b/addons/website_sale_loyalty/models/sale_order_line.py index 9071d613819..b6a4a595ad6 100644 --- a/addons/website_sale_loyalty/models/sale_order_line.py +++ b/addons/website_sale_loyalty/models/sale_order_line.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +from collections import defaultdict from odoo import models class SaleOrderLine(models.Model): @@ -9,3 +10,13 @@ class SaleOrderLine(models.Model): def _show_in_cart(self): # Hide discount lines from website_order_line, see `order._compute_website_order_line` return self.reward_id.reward_type != 'discount' and super()._show_in_cart() + + def unlink(self): + if self.env.context.get('website_sale_loyalty_delete', False): + disabled_rewards_per_order = defaultdict(lambda: self.env['loyalty.reward']) + for line in self: + if line.reward_id: + disabled_rewards_per_order[line.order_id] |= line.reward_id + for order, rewards in disabled_rewards_per_order.items(): + order.disabled_auto_rewards += rewards + return super().unlink()