[FIX] sale_coupon: delete 'sibling' lines when deleting a reward line
A discount on products with different taxes will result in as many discount lines as there is different taxes. Before this commit, removing one of these lines would not do anything else. Then, recomputing the coupon would regenerate/add back this line. On e-commerce, it means you would never be able to remove the program by deleting its reward lines if there are multiple taxes (and so multiple lines) since it would `recompute_coupon_lines` right away, adding it back directly. Now, this commit will ensure that removing one of these lines will also remove the other ones coming from this program on other taxes. It means removing a regular product will remove it's reward line that will also now remove the other program's discount line on other taxes and ultimately will remove the program from the SO since all the program reward lines got removed. (It won't affect auto applied program since it will be regenerated afterward) task-1866977 Related to #2224
This commit is contained in:
@@ -346,6 +346,7 @@ class SaleOrderLine(models.Model):
|
||||
is_reward_line = fields.Boolean('Is a program reward line')
|
||||
|
||||
def unlink(self):
|
||||
related_program_lines = self.env['sale.order.line']
|
||||
# Reactivate coupons related to unlinked reward line
|
||||
for line in self.filtered(lambda line: line.is_reward_line):
|
||||
coupons_to_reactivate = line.order_id.applied_coupon_ids.filtered(
|
||||
@@ -354,10 +355,10 @@ class SaleOrderLine(models.Model):
|
||||
coupons_to_reactivate.write({'state': 'new'})
|
||||
line.order_id.applied_coupon_ids -= coupons_to_reactivate
|
||||
# Remove the program from the order if the deleted line is the reward line of the program
|
||||
# And if there is no other lines from this program (It's the case when discount is split per different taxes)
|
||||
# And delete the other lines from this program (It's the case when discount is split per different taxes)
|
||||
related_program = self.env['sale.coupon.program'].search([('discount_line_product_id', '=', line.product_id.id)])
|
||||
related_program_lines = line.order_id.order_line.filtered(lambda l: l.product_id.id == related_program.discount_line_product_id.id) - line
|
||||
if related_program and not related_program_lines:
|
||||
if related_program:
|
||||
line.order_id.no_code_promo_program_ids -= related_program
|
||||
line.order_id.code_promo_program_id -= related_program
|
||||
return super(SaleOrderLine, self).unlink()
|
||||
related_program_lines |= line.order_id.order_line.filtered(lambda l: l.product_id.id == related_program.discount_line_product_id.id) - line
|
||||
return super(SaleOrderLine, self | related_program_lines).unlink()
|
||||
|
||||
@@ -376,11 +376,16 @@ class TestSaleCouponProgramNumbers(TestSaleCouponCommon):
|
||||
self.assertEqual(order.amount_untaxed, 1355.46, "The order untaxed total with programs should be 1435.45")
|
||||
self.assertEqual(len(order.order_line.ids), 13, "Order should have a new discount line for 20% on iPad")
|
||||
|
||||
# Check that if you delete one of the discount tax line and recompute, it got added back.
|
||||
# Check that if you delete one of the discount tax line, the others tax lines from the same promotion got deleted as well.
|
||||
order.order_line.filtered(lambda l: '10%' in l.name)[0].unlink()
|
||||
self.assertEqual(len(order.order_line.ids), 12, "One of the 10% discount line per tax should be removed")
|
||||
self.assertEqual(len(order.order_line.ids), 9, "All of the 10% discount line per tax should be removed")
|
||||
# At this point, removing the iPod's discount line (split per tax) removed also the others discount lines
|
||||
# linked to the same program (eg: other taxes lines). So the coupon got removed from the SO since there were no discount lines left
|
||||
|
||||
# Add back the coupon to continue the test flow
|
||||
self.env['sale.coupon.apply.code'].sudo().apply_coupon(order, 'test_10pc')
|
||||
order.recompute_coupon_lines()
|
||||
self.assertEqual(len(order.order_line.ids), 13, "The 10% discount line that got removed should be recomputed and added back")
|
||||
self.assertEqual(len(order.order_line.ids), 13, "The 10% discount line should be back")
|
||||
|
||||
# Check that if you change a product qty, his discount tax line got updated
|
||||
sol2.product_uom_qty = 7
|
||||
@@ -412,16 +417,12 @@ class TestSaleCouponProgramNumbers(TestSaleCouponCommon):
|
||||
# 50% excl
|
||||
# Free Keyboard | 5 | -100.00 | / | -500.00 | -500.00 | /
|
||||
# Free iPad | 3 | -100.00 | 15% excl | -300.00 | -345.00 | -45.00
|
||||
# 10% on no tax | 1 | -50.00 | / | -50.00 | -50.00 | /
|
||||
# 10% on tax 15% excl | 1 | -40.00 | 15% excl | -60.00 | -69.00 | -9.00
|
||||
# 10% on tax 35%+50% | 1 | -30.00 | 35% incl | -22.22 | -45.00 | -22.78
|
||||
# 50% excl
|
||||
# 20% on iPad | 1 | -80.00 | 15% excl | -80.00 | -92.00 | -12.00
|
||||
# --------------------------------------------------------------------------------
|
||||
# TOTAL | 1110.00 | 1384.00 | 274.00
|
||||
self.assertEqual(order.amount_total, 1384, "The order total with programs should be 1654")
|
||||
self.assertEqual(order.amount_untaxed, 1110, "The order untaxed total with programs should be 1435.45")
|
||||
self.assertEqual(len(order.order_line.ids), 10, "Order should contains 10 lines: 4 products lines, 2 free products lines, 3 10% discount lines and a 20% discount line")
|
||||
# TOTAL | 1242.22 | 1548.00 | 305.78
|
||||
self.assertEqual(order.amount_total, 1548, "The order total with programs should be 1548")
|
||||
self.assertEqual(order.amount_untaxed, 1242.22, "The order untaxed total with programs should be 1242.22")
|
||||
self.assertEqual(len(order.order_line.ids), 7, "Order should contains 7 lines: 4 products lines, 2 free products lines and a 20% discount line")
|
||||
|
||||
def test_program_numbers_extras(self):
|
||||
# Check that you can't apply a global discount promo code if there is already an auto applied global discount
|
||||
|
||||
Reference in New Issue
Block a user