[FIX] website_sale_coupon: merge 'sibling' discount lines in cart
A discount on products with different taxes will result in as many discount lines as there is different taxes. This commit will merge all these lines in a single one on the front-end (cart) to not change the behavior/display for the end user. This will be purely visual as it does not affect SO lines. task-1866977 Related to #2224
This commit is contained in:
@@ -6,6 +6,44 @@ from odoo.http import request
|
||||
class SaleOrder(models.Model):
|
||||
_inherit = "sale.order"
|
||||
|
||||
@api.one
|
||||
def _compute_website_order_line(self):
|
||||
""" This method will merge multiple discount lines generated by a same program
|
||||
into a single one (temporary line with `new()`).
|
||||
This case will only occur when the program is a discount applied on multiple
|
||||
products with different taxes.
|
||||
In this case, each taxes will have their own discount line. This is required
|
||||
to have correct amount of taxes according to the discount.
|
||||
But we wan't these lines to be `visually` merged into a single one in the
|
||||
e-commerce since the end user should only see one discount line.
|
||||
This is only possible since we don't show taxes in cart.
|
||||
eg:
|
||||
line 1: 10% discount on product with tax `A` - $15
|
||||
line 2: 10% discount on product with tax `B` - $11.5
|
||||
line 3: 10% discount on product with tax `C` - $10
|
||||
would be `hidden` and `replaced` by
|
||||
line 1: 10% discount - $36.5
|
||||
|
||||
Note: The line will be created without tax(es) and the amount will be computed
|
||||
depending if B2B or B2C is enabled.
|
||||
"""
|
||||
super(SaleOrder, self)._compute_website_order_line()
|
||||
for program in self._get_applied_programs_with_rewards_on_current_order():
|
||||
program_lines = self.order_line.filtered(lambda line: line.product_id == program.discount_line_product_id)
|
||||
if len(program_lines) > 1:
|
||||
price_unit = sum(l.price_subtotal if self.env.user.has_group('sale.group_show_price_subtotal') else l.price_total for l in program_lines)
|
||||
self.website_order_line += self.env['sale.order.line'].new({
|
||||
'product_id': program_lines[0].product_id.id,
|
||||
'price_unit': price_unit,
|
||||
'name': program_lines[0].name,
|
||||
'product_uom_qty': 1,
|
||||
'product_uom': program_lines[0].product_uom.id,
|
||||
'order_id': self.id,
|
||||
'is_reward_line': True,
|
||||
})
|
||||
self.website_order_line -= program_lines
|
||||
|
||||
|
||||
def _compute_cart_info(self):
|
||||
super(SaleOrder, self)._compute_cart_info()
|
||||
for order in self:
|
||||
|
||||
@@ -36,9 +36,9 @@ tour.register('shop_sale_coupon', {
|
||||
trigger: '.oe_product_cart a:contains("iPad Mini")',
|
||||
},
|
||||
{
|
||||
content: "add 3 iPad Mini into cart",
|
||||
content: "add 2 iPad Mini into cart",
|
||||
trigger: '#product_details input[name="add_qty"]',
|
||||
run: "text 3",
|
||||
run: "text 2",
|
||||
},
|
||||
{
|
||||
content: "click on 'Add to Cart' button",
|
||||
@@ -68,31 +68,79 @@ tour.register('shop_sale_coupon', {
|
||||
trigger: '.reward_product:contains("10.0 % discount on total amount")',
|
||||
run: function () {}, // it's a check
|
||||
},
|
||||
/* 2. Add some iPad to get a free one, play with quantity */
|
||||
/* 2. Add an Ice Cream in the cart (which has different tax than iPad) and ensure only one discount line is shown */
|
||||
{
|
||||
content: "go to shop",
|
||||
trigger: '.reward_product:contains("10.0 % discount on total amount")',
|
||||
run: function () {
|
||||
location.href = '/shop'
|
||||
},
|
||||
},
|
||||
{
|
||||
content: "type Ice Cream in search",
|
||||
trigger: 'form input[name="search"]',
|
||||
run: "text Ice Cream",
|
||||
},
|
||||
{
|
||||
content: "start search",
|
||||
trigger: 'form:has(input[name="search"]) .oe_search_button',
|
||||
},
|
||||
{
|
||||
content: "select Ice Cream",
|
||||
extra_trigger: '.oe_search_found', // Wait to be on search results or it sometimes throws concurent error (sent search form + click on product on /shop)
|
||||
trigger: '.oe_product_cart a:containsExact("Ice Cream")',
|
||||
},
|
||||
{
|
||||
content: "click on 'Add to Cart' button",
|
||||
trigger: "a:contains(Add to Cart)",
|
||||
},
|
||||
{
|
||||
content: "check reduction amount got recomputed and merged both discount lines into one only",
|
||||
extra_trigger: '.oe_currency_value:contains("‑74.00")',
|
||||
trigger: '.oe_website_sale .oe_cart',
|
||||
run: function () {}, // it's a check
|
||||
},
|
||||
/* 3. Add some iPad to get a free one, play with quantity */
|
||||
{
|
||||
content: "add one iPad",
|
||||
trigger: '#cart_products input.js_quantity',
|
||||
run: "text 3",
|
||||
},
|
||||
{
|
||||
content: "check reduction amount got recomputed when changing qty",
|
||||
trigger: '.oe_currency_value:contains("‑106.00")',
|
||||
run: function () {}, // it's a check
|
||||
},
|
||||
{
|
||||
content: "add more iPad Mini into cart",
|
||||
trigger: '#cart_products input.js_quantity',
|
||||
run: "text 4",
|
||||
},
|
||||
{
|
||||
content: "check reduction amount got recomputed",
|
||||
extra_trigger: '.oe_currency_value:contains("96.00")', // For some reason, "-96.00" won't work
|
||||
trigger: '.reward_product:contains("Free Product - iPad Mini")',
|
||||
content: "check free product is added",
|
||||
trigger: '#wrap:has(.reward_product:contains("Free Product - iPad Mini"))',
|
||||
run: function () {}, // it's a check
|
||||
},
|
||||
{
|
||||
content: "remove one iPad from cart",
|
||||
trigger: '#cart_products a.js_add_cart_json:first',
|
||||
trigger: '#cart_products input.js_quantity[value="4"]',
|
||||
run: "text 3",
|
||||
},
|
||||
{
|
||||
content: "check free product is removed",
|
||||
trigger: '#wrap:not(:has(.reward_product:contains("Free Product - iPad Mini")))',
|
||||
run: function () {}, // it's a check
|
||||
},
|
||||
/* 3. Empty cart and disable coupon */
|
||||
/* 4. Empty cart and disable coupon */
|
||||
{
|
||||
content: "remove iPad Mini from cart",
|
||||
trigger: '#cart_products input.js_quantity:first',
|
||||
trigger: '#cart_products input.js_quantity[value="3"]',
|
||||
run: "text 0",
|
||||
},
|
||||
{
|
||||
content: "remove Ice Cream from cart",
|
||||
extra_trigger: '#wrap:not(:has(.td-product_name:contains("iPad Mini")))', // wait iPad got removed
|
||||
trigger: '#cart_products input.js_quantity[value="1"]',
|
||||
run: "text 0",
|
||||
},
|
||||
{
|
||||
@@ -100,7 +148,7 @@ tour.register('shop_sale_coupon', {
|
||||
trigger: '#wrap:not(:has(#cart_products))',
|
||||
run: function () {}, // it's a check
|
||||
},
|
||||
/* 4. Disabled customize options coupon box & 'Show # found'*/
|
||||
/* 5. Disabled customize options coupon box & 'Show # found'*/
|
||||
{
|
||||
content: "open customize menu",
|
||||
extra_trigger: '.oe_website_sale .oe_cart',
|
||||
@@ -135,7 +183,6 @@ if ('website_sale_options.website_sale' in odoo.__DEBUG__.services) {
|
||||
content: "click in modal on 'Proceed to checkout' button",
|
||||
trigger: 'a:contains("Proceed to checkout")',
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user