[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) <thle@odoo.com>
This commit is contained in:
Thomas Lefebvre (thle)
2023-05-09 00:41:08 +02:00
parent e4fe9c60a4
commit 2f0b503dc2
2 changed files with 41 additions and 1 deletions
@@ -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],
}]
@@ -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