diff --git a/models/sale_order.py b/models/sale_order.py index 689920f9905..7152dd33d17 100644 --- a/models/sale_order.py +++ b/models/sale_order.py @@ -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() diff --git a/tests/test_program_numbers.py b/tests/test_program_numbers.py index 6b2c29d6050..9d4c34f8070 100644 --- a/tests/test_program_numbers.py +++ b/tests/test_program_numbers.py @@ -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