[FIX] sale_coupon: Allow coupons to correctly allow several free products
What are the steps to reproduce your issue ?
1. Add a coupon program with the following condition sale_ok == True & name == 'Large Desk'
2. Add 'Buy 1 get 2 free' 'Large Cabinet'
3. Create a quotation with 1 Large Desk and 2 Large Cabinet
4. Add the coupon code
What is currently happening ?
Promotion will only remove one * Large Cabinet price instead of 2
What are you expecting to happen ?
Promotion remove two * Large Cabinet price
Why is this happening ?
The products quantity was mixed with the reward products quantity
opw-2496940
closes odoo/odoo#69671
X-original-commit: 5c4785212fce2c97047d97e96ccbbe32e3681f59
Signed-off-by: Achraf <abz-odoo@users.noreply.github.com>
This commit is contained in:
@@ -95,7 +95,7 @@ class SaleOrder(models.Model):
|
||||
order_total = sum(order_lines.mapped('price_total')) - (program.reward_product_quantity * program.reward_product_id.lst_price)
|
||||
reward_product_qty = min(reward_product_qty, order_total // program.rule_minimum_amount)
|
||||
else:
|
||||
reward_product_qty = min(max_product_qty, total_qty)
|
||||
reward_product_qty = min(program.reward_product_quantity, total_qty)
|
||||
|
||||
reward_qty = min(int(int(max_product_qty / program.rule_min_quantity) * program.reward_product_quantity), reward_product_qty)
|
||||
# Take the default taxes on the reward product, mapped with the fiscal position
|
||||
|
||||
@@ -1019,3 +1019,87 @@ class TestSaleCouponProgramNumbers(TestSaleCouponCommon):
|
||||
order.recompute_coupon_lines()
|
||||
self.assertEqual(order.amount_total, 1486.80, "Discount improperly applied")
|
||||
self.assertEqual(len(order.order_line.ids), 2, "No discount applied while it should")
|
||||
|
||||
def test_program_free_prods_with_min_qty_and_reward_qty_and_rule(self):
|
||||
order = self.empty_order
|
||||
coupon_program = self.env['coupon.program'].create({
|
||||
'name': '2 free conference chair if at least 1 large cabinet',
|
||||
'promo_code_usage': 'code_needed',
|
||||
'program_type': 'promotion_program',
|
||||
'reward_type': 'product',
|
||||
'reward_product_quantity': 2,
|
||||
'reward_product_id': self.conferenceChair.id,
|
||||
'rule_min_quantity': 1,
|
||||
'rule_products_domain': '["&", ["sale_ok","=",True], ["name","ilike","large cabinet"]]',
|
||||
})
|
||||
# set large cabinet and conference chair prices
|
||||
self.largeCabinet.write({'list_price': 500, 'sale_ok': True,})
|
||||
self.conferenceChair.write({'list_price': 100, 'sale_ok': True})
|
||||
|
||||
# create SOL
|
||||
self.env['sale.order.line'].create({
|
||||
'product_id': self.largeCabinet.id,
|
||||
'name': 'Large Cabinet',
|
||||
'product_uom_qty': 1.0,
|
||||
'order_id': order.id,
|
||||
})
|
||||
sol2 = self.env['sale.order.line'].create({
|
||||
'product_id': self.conferenceChair.id,
|
||||
'name': 'Conference chair',
|
||||
'product_uom_qty': 2.0,
|
||||
'order_id': order.id,
|
||||
})
|
||||
|
||||
self.assertEqual(len(order.order_line), 2, 'The order must contain 2 order lines since the coupon is not yet applied')
|
||||
self.assertEqual(order.amount_total, 700.0, 'The price must be 500.0 since the coupon is not yet applied')
|
||||
|
||||
# generate and apply coupon
|
||||
self.env['coupon.generate.wizard'].with_context(active_id=coupon_program.id).create({
|
||||
'generation_type': 'nbr_coupon',
|
||||
'nbr_coupons': 1,
|
||||
}).generate_coupon()
|
||||
coupon = coupon_program.coupon_ids
|
||||
self.env['sale.coupon.apply.code'].with_context(active_id=order.id).create({
|
||||
'coupon_code': coupon.code
|
||||
}).process_coupon()
|
||||
|
||||
# Name | Qty | price_unit | Tax | HTVA | TVAC | TVA |
|
||||
# --------------------------------------------------------------------------------
|
||||
# Conference Chair | 2 | 100.00 | / | 200.00 | 200.00 | /
|
||||
# Large Cabinet | 1 | 500.00 | / | 500.00 | 500.00 | /
|
||||
#
|
||||
# Free Conference Chair | 2 | -100.00 | / | -200.00 | -200.00 | /
|
||||
# --------------------------------------------------------------------------------
|
||||
# TOTAL | 500.00 | 500.00 | /
|
||||
|
||||
self.assertEqual(len(order.order_line), 3, 'The order must contain 3 order lines including one for free conference chair')
|
||||
self.assertEqual(order.amount_total, 500.0, 'The price must be 500.0 since two conference chairs are free')
|
||||
self.assertEqual(order.order_line[2].price_total, -200.0, 'The last order line should apply a reduction of 200.0 since there are two conference chairs that cost 100.0 each')
|
||||
|
||||
# prevent user to get illicite discount by decreasing the to 1 the reward product qty after applying the coupon
|
||||
sol2.product_uom_qty = 1.0
|
||||
order.recompute_coupon_lines()
|
||||
|
||||
# in this case user should not have -200.0
|
||||
# Name | Qty | price_unit | Tax | HTVA | TVAC | TVA |
|
||||
# --------------------------------------------------------------------------------
|
||||
# Conference Chair | 1 | 100.00 | / | 100.00 | 100.00 | /
|
||||
# Large Cabine | 1 | 500.00 | / | 500.00 | 500.00 | /
|
||||
#
|
||||
# Free Conference Chair | 2 | -100.00 | / | -200.00 | -200.00 | /
|
||||
# --------------------------------------------------------------------------------
|
||||
# TOTAL | 400.00 | 400.00 | /
|
||||
|
||||
|
||||
# he should rather have this one
|
||||
# Name | Qty | price_unit | Tax | HTVA | TVAC | TVA |
|
||||
# --------------------------------------------------------------------------------
|
||||
# Conference Chair | 1 | 100.00 | / | 100.00 | 100.00 | /
|
||||
# Large Cabinet | 1 | 500.00 | / | 500.00 | 500.00 | /
|
||||
#
|
||||
# Free Conference Chair | 1 | -100.00 | / | -100.00 | -100.00 | /
|
||||
# --------------------------------------------------------------------------------
|
||||
# TOTAL | 500.00 | 500.00 | /
|
||||
|
||||
self.assertEqual(order.amount_total, 500.0, 'The price must be 500.0 since two conference chairs are free and the user only bought one')
|
||||
self.assertEqual(order.order_line[2].price_total, -100.0, 'The last order line should apply a reduction of 100.0 since there is one conference chair that cost 100.0')
|
||||
|
||||
Reference in New Issue
Block a user