From 2f0b503dc2873469668825cc1df54fb3683c2cd8 Mon Sep 17 00:00:00 2001 From: "Thomas Lefebvre (thle)" Date: Fri, 28 Apr 2023 10:07:56 +0000 Subject: [PATCH] [FIX] sale_loyalty_delivery: default sequence if no reward line The commit: https://github.com/odoo/odoo/commit/58a88b7731ace08ca106f3df47dd455520136248 prevents the deletion of a 'free shipping' line if it is not the last one in the cart. The fix: https://github.com/odoo/odoo/commit/7004b17ee5433e3b14561358348b42326f549261 calculates the sequence of the 'free shipping' line so that it is the last one in the cart. Issue: In case we have enough points to get the 'free shipping' reward without the actual products in the cart, if we want to delete the product, we raise an error. Cause: It is no longer possible to calculate the free shipping sequence as this is based on the non-reward lines (and we have just deleted this line). Solution: We have to add a default value for the sequence in case the 'free shipping' is the last item in the cart. opw-3269594 closes odoo/odoo#120749 X-original-commit: 67b3f6dee2e108c32ec561ed32734a147299d8d8 Signed-off-by: Lefebvre Thomas (thle) --- .../models/sale_order.py | 2 +- .../tests/test_free_shipping_reward.py | 40 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/addons/sale_loyalty_delivery/models/sale_order.py b/addons/sale_loyalty_delivery/models/sale_order.py index ff493696352..c2c24926ca3 100644 --- a/addons/sale_loyalty_delivery/models/sale_order.py +++ b/addons/sale_loyalty_delivery/models/sale_order.py @@ -30,7 +30,7 @@ class SaleOrder(models.Model): 'product_uom': reward.discount_line_product_id.uom_id.id, 'order_id': self.id, 'is_reward_line': True, - 'sequence': max(self.order_line.filtered(lambda x: not x.is_reward_line).mapped('sequence')) + 1, + 'sequence': max(self.order_line.filtered(lambda x: not x.is_reward_line).mapped('sequence'), default=0) + 1, 'tax_id': [(Command.CLEAR, 0, 0)] + [(Command.LINK, tax.id, False) for tax in taxes], }] diff --git a/addons/sale_loyalty_delivery/tests/test_free_shipping_reward.py b/addons/sale_loyalty_delivery/tests/test_free_shipping_reward.py index 8f37e582743..49dde39b5a9 100644 --- a/addons/sale_loyalty_delivery/tests/test_free_shipping_reward.py +++ b/addons/sale_loyalty_delivery/tests/test_free_shipping_reward.py @@ -277,3 +277,43 @@ class TestSaleCouponProgramRules(TestSaleCouponCommon): self._auto_rewards(order, programs) # 872.73 - (20% of 1 iPad) = 872.73 - 58.18 = 814.55 self.assertAlmostEqual(order.amount_untaxed, 1105.46, 2, "One large cabinet should be discounted by 20%") + + def test_free_shipping_reward_last_line(self): + """ + The free shipping reward cannot be removed if it is the last item in the sale order. + However, we calculate its sequence so that it is the last item in the sale order. + This can create an error if a default sequence is not determined. + """ + self.immediate_promotion_program.active = False + # Create a loyalty program + loyalty_program = self.env['loyalty.program'].create({ + 'name': 'GIFT Free Shipping', + 'program_type': 'loyalty', + 'applies_on': 'both', + 'trigger': 'auto', + 'rule_ids': [(0, 0, { + 'reward_point_mode': 'money', + 'reward_point_amount': 1, + })], + 'reward_ids': [(0, 0, { + 'reward_type': 'shipping', + 'required_points': 100, + })], + }) + # Add points to a partner to trigger the promotion + loyalty_card = self.env['loyalty.card'].create({ + 'program_id': loyalty_program.id, + 'partner_id': self.steve.id, + 'points': 250, + }) + order = self.env['sale.order'].create({ + 'partner_id': self.steve.id, + }) + # Check if we can claim the free shipping reward + order._update_programs_and_rewards() + claimable_rewards = order._get_claimable_rewards() + self.assertEqual(len(claimable_rewards), 1) + # Try to apply the loyalty card to the sale order + self._apply_promo_code(order, loyalty_card.code) + # Check if there is an error in the sequence + # via `_apply_program_reward` in `apply_promo_code` method