[FIX] sale_coupon: fix the unexpired_promotions filter

Expected behaviour

When having multiple promotions with, for example, a promotion of X% for the
first order and a promotion of Y% (Y<X), we should apply the first promotion
on the first order and then don't get this promotion into account to choose
the best promotion for a future order, so that we have:
1. A promotion of X% on the first order
2. A promotion of Y% on every other order

Observed behaviour

When trying to apply promotion on other order, nothing seems to happen, as
Odoo take the already-used X% promotion into account, being the most
interesting promotion, select it as the best promotion to apply and then
apply it to finally get a result of a 0% discount as the promotion has
already been used.

Problem Root Cause

As it can be seen in the commit, the error comes from the fact we filtered
the available promotion with a non-strict inequality.

Validation

A test has been added in test_program_numbers.py to validate our fix

Related issue

- opw-2674681

closes odoo/odoo#81633

X-original-commit: 9bade951570d79e2623d3bf548df445c22c31034
Signed-off-by: Romain Derie (rde) <rde@odoo.com>
Signed-off-by: Hendrickx Anthony (anhe) <anhe@odoo.com>
This commit is contained in:
anhe-odoo
2021-12-20 09:58:54 +00:00
parent 98b8479585
commit a38a0caa0e
2 changed files with 34 additions and 1 deletions
+1 -1
View File
@@ -102,7 +102,7 @@ class CouponProgram(models.Model):
return self.filtered(lambda program: program.promo_code_usage == 'code_needed' and program.promo_code != order.promo_code)
def _filter_unexpired_programs(self, order):
return self.filtered(lambda program: program.maximum_use_number == 0 or program.total_order_count <= program.maximum_use_number)
return self.filtered(lambda program: program.maximum_use_number == 0 or program.total_order_count < program.maximum_use_number)
def _filter_programs_on_partners(self, order):
return self.filtered(lambda program: program._is_valid_partner(order.partner_id))
@@ -1167,3 +1167,36 @@ class TestSaleCouponProgramNumbers(TestSaleCouponCommon):
self.assertEqual(len(order.order_line), 2, 'The order must contain 2 order lines: 1x Product F and 1x 5$ discount')
self.assertEqual(order.amount_total, 190.0, 'The price must be 190.0 since there is now 2x 5$ discount and 2x Product F')
self.assertEqual(order.order_line.filtered(lambda x: x.is_reward_line).price_unit, -5, 'The discount unit price should still be -5 after the quantity was manually changed')
def test_program_maximum_use_number_with_other_promo(self):
self.env['coupon.program'].create({
'name': '20% discount on first order',
'promo_code_usage': 'no_code_needed',
'program_type': 'promotion_program',
'discount_type': 'percentage',
'discount_percentage': 20.0,
'maximum_use_number': 1,
})
self.p1.promo_code_usage = 'no_code_needed'
#check that 20% is applied at first order
order = self.empty_order
self.env['sale.order.line'].create({
'product_id': self.drawerBlack.id,
'product_uom_qty': 1.0,
'order_id': order.id,
})
order.recompute_coupon_lines()
self.assertEqual(order.amount_total, 20.0, "20% discount should be applied")
self.assertEqual(len(order.order_line.ids), 2, "discount should be applied")
#check that 10% is applied at second order
order2 = self.env['sale.order'].create({'partner_id': self.steve.id})
self.env['sale.order.line'].create({
'product_id': self.drawerBlack.id,
'product_uom_qty': 1.0,
'order_id': order2.id,
})
order2.recompute_coupon_lines()
self.assertEqual(order2.amount_total, 22.5, "10% discount should be applied")
self.assertEqual(len(order2.order_line.ids), 2, "discount should be applied")