[FIX] sale_loyalty: prevent coupon removal on double apply

Addresses the issue where reapplying an already applied coupon
in the website shop led to the disappearance of the discount.
With this fix, the discount remains applied, and the system
continues to inform the user that the coupon has already been
used, preventing confusion and maintaining consistency in the
discount application process.

task-3621246

closes odoo/odoo#153485

Signed-off-by: Victor Feyens (vfe) <vfe@odoo.com>
This commit is contained in:
mathysPaul
2024-03-28 18:06:43 +00:00
committed by Victor Feyens
parent 9cdeaf724c
commit 64d1febc43
2 changed files with 60 additions and 4 deletions
+2 -2
View File
@@ -992,7 +992,7 @@ class SaleOrder(models.Model):
if not program.filtered_domain(self._get_program_domain()):
return {'error': _('The program is not available for this order.')}
elif program in self._get_applied_programs():
return {'error': _('This program is already applied to this order.')}
return {'error': _('This program is already applied to this order.'), 'already_applied': True}
# Check for applicability from the program's triggers/rules.
# This step should also compute the amount of points to give for that program on that order.
status = self._program_check_compute_points(program)[program]
@@ -1058,7 +1058,7 @@ class SaleOrder(models.Model):
if 'error' in apply_result and (not program.is_nominative or (program.is_nominative and not coupon)):
if rule:
self.code_enabled_rule_ids -= rule
if coupon:
if coupon and not apply_result.get('already_applied', False):
self.applied_coupon_ids -= coupon
return apply_result
coupon = apply_result.get('coupon', self.env['loyalty.card'])
@@ -1,10 +1,14 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from datetime import timedelta
from odoo import fields
from odoo import fields, http
from odoo.exceptions import ValidationError
from odoo.tests import HttpCase, tagged, TransactionCase
from odoo.fields import Command
from odoo.tests import HttpCase, tagged
from odoo.addons.sale.tests.test_sale_product_attribute_value_config import TestSaleProductAttributeValueCommon
from odoo.addons.website.tools import MockRequest
from odoo.addons.website_sale_loyalty.controllers.main import WebsiteSale
@tagged('post_install', '-at_install')
@@ -366,3 +370,55 @@ class TestWebsiteSaleCoupon(HttpCase):
msg = "The coupon should've been removed from the order"
self.assertEqual(len(order.applied_coupon_ids), 0, msg=msg)
def test_04_apply_coupon_code_twice(self):
"""This test ensures that applying a coupon with code twice will:
1. Raise an error
2. Not delete the coupon
"""
website = self.env['website'].browse(1)
# Create product
product = self.env['product.product'].create({
'name': 'Product',
'list_price': 100,
'sale_ok': True,
'taxes_id': [],
})
order = self.empty_order
order.write({
'website_id': website.id,
'order_line': [
Command.create({
'product_id': product.id,
}),
]
})
WebsiteSaleController = WebsiteSale()
installed_modules = set(self.env['ir.module.module'].search([
('state', '=', 'installed'),
]).mapped('name'))
for _ in http._generate_routing_rules(installed_modules, nodb_only=False):
pass
with MockRequest(self.env, website=website, sale_order_id=order.id) as request:
# Check the base cart value
self.assertEqual(order.amount_total, 100.0, "The base cart value is incorrect.")
# Apply coupon for the first time
WebsiteSaleController.pricelist(promo=self.coupon.code)
# Check that the coupon has been applied
self.assertEqual(order.amount_total, 90.0, "The coupon is not applied.")
# Apply the coupon again
WebsiteSaleController.pricelist(promo=self.coupon.code)
WebsiteSaleController.cart()
error_msg = request.session.get('error_promo_code')
# Check that the coupon stay applied
self.assertEqual(bool(error_msg), True, "Apply a coupon twice should display an error message")
self.assertEqual(order.amount_total, 90.0, "Apply a coupon twice shouldn't delete it")