[FIX] sale_coupon_delivery: never include the delivery into the order's base for coupon
before this commit, the delivery was included into the base of computation for coupon programs meaning that: have a program free shipping for orders above 50$ have a product with price included 48$ let's shipping costs be 9$ total price is 57$. The program used to apply in that case, giving a total discounted price of 48$, when it should be 57$ with no discounts after this commit, deliveries are excluded from the computation OPW 766661 closes #1311
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
|
||||
from odoo import models, _
|
||||
from odoo import models, _, api
|
||||
|
||||
|
||||
class SaleCouponProgram(models.Model):
|
||||
@@ -22,3 +22,20 @@ class SaleCouponProgram(models.Model):
|
||||
if self.reward_type == 'free_shipping' and not order.order_line.filtered(lambda line: line.is_delivery):
|
||||
return {'error': _('The shipping costs are not in the order lines.')}
|
||||
return super(SaleCouponProgram, self)._check_promo_code(order, coupon_code)
|
||||
|
||||
@api.model
|
||||
def _filter_on_mimimum_amount(self, order):
|
||||
# To get actual total amount of SO without any reward or discount
|
||||
# We exclude any line of the order that is a delivery
|
||||
# get the round function of the currency: we want to imitate what the sale.order.amount is (computed field)
|
||||
round_curr = order.pricelist_id.currency_id.round
|
||||
order_lines = order.order_line.filtered(lambda l: not l.is_delivery)
|
||||
order_amount = round_curr(sum(order_lines.mapped('price_subtotal')))
|
||||
order_tax = round_curr(sum(order_lines.mapped('price_tax')))
|
||||
discounted_amount = sum(order_lines.filtered(lambda line: line.is_reward_line).mapped('price_total'))
|
||||
untaxed_amount = order_amount - discounted_amount
|
||||
return self.filtered(lambda program:
|
||||
program.rule_minimum_amount_tax_inclusion == 'tax_included' and
|
||||
program._compute_program_amount('rule_minimum_amount', order.currency_id) <= untaxed_amount + order_tax or
|
||||
program.rule_minimum_amount_tax_inclusion == 'tax_excluded' and
|
||||
program._compute_program_amount('rule_minimum_amount', order.currency_id) <= untaxed_amount)
|
||||
|
||||
@@ -24,6 +24,7 @@ class TestSaleCouponProgramRules(TestSaleCouponCommon):
|
||||
'partner_id': self.steve.id,
|
||||
})
|
||||
|
||||
# Price of order will be 5*1.15 = 5.75 (tax included)
|
||||
order.write({'order_line': [
|
||||
(0, False, {
|
||||
'product_id': self.product_B.id,
|
||||
@@ -40,6 +41,24 @@ class TestSaleCouponProgramRules(TestSaleCouponCommon):
|
||||
order.recompute_coupon_lines()
|
||||
self.assertEqual(len(order.order_line.ids), 2)
|
||||
|
||||
# Test Case 1b: amount is not reached but is on a threshold
|
||||
# The amount of deliverable product + the one of the delivery exceeds the minimum amount
|
||||
# yet the program shouldn't be applied
|
||||
|
||||
# Order price will be 5.75 + 81.74*1.15 = 99.75
|
||||
order.write({'order_line': [
|
||||
(0, False, {
|
||||
'product_id': self.product_B.id,
|
||||
'name': 'Product 1B',
|
||||
'product_uom': self.uom_unit.id,
|
||||
'product_uom_qty': 1.0,
|
||||
'price_unit': 81.74,
|
||||
})
|
||||
]})
|
||||
|
||||
order.recompute_coupon_lines()
|
||||
self.assertEqual(len(order.order_line.ids), 3)
|
||||
|
||||
# Test case 2: the amount is sufficient, the shipping should
|
||||
# be reimbursed
|
||||
order.write({'order_line': [
|
||||
@@ -53,11 +72,11 @@ class TestSaleCouponProgramRules(TestSaleCouponCommon):
|
||||
]})
|
||||
|
||||
order.recompute_coupon_lines()
|
||||
self.assertEqual(len(order.order_line.ids), 4)
|
||||
self.assertEqual(len(order.order_line.ids), 5)
|
||||
|
||||
# Test case 3: the amount is not sufficient now, the reward should be removed
|
||||
order.write({'order_line': [
|
||||
(2, order.order_line.filtered(lambda line: line.product_id.id == self.product_A.id).id, False)
|
||||
]})
|
||||
order.recompute_coupon_lines()
|
||||
self.assertEqual(len(order.order_line.ids), 2)
|
||||
self.assertEqual(len(order.order_line.ids), 3)
|
||||
|
||||
Reference in New Issue
Block a user