[FIX] website_sale_loyalty: add product when exists as reward in cart

Issue:
======
When we have a product as a free product reward in cart and we want to
add the same product from the shop nothing will happen and the cart
stays the same.

Steps to reproduce the issue:
=============================
- Create a loyalty program with the following options:
type: pormotions
rule: minimum quantity :1 , gran 1, minimum purchase 0, per order,
product:  select anyone
reward: type : free product , quantity rewarded : 1, product : select
any other product
- Go to website and add the product from the rule to cart
- Go to cart and claim reward
- Go back to shop and add the product from the reward to cart
- Go to cart
- The cart stays the same

Issue:
======
When searching for the `line` it doesn't consider if the line is a
reward or not.

Solution:
=========
We filter the reward lines if `line_id=False`

opw-3550585

closes odoo/odoo#143581

X-original-commit: 2b97bb83b312f553d3ec1b6e96a74c744955aed6
Signed-off-by: Morgane Demesmaeker <edm@odoo.com>
This commit is contained in:
Mahdi Cheikh Rouhou (macr)
2023-11-25 05:41:43 +00:00
parent bab7119b70
commit 2a84495a47
3 changed files with 91 additions and 0 deletions
@@ -220,3 +220,12 @@ class SaleOrder(models.Model):
else:
res[coupon] = reward
return res
def _cart_find_product_line(self, product_id, line_id=None, **kwargs):
""" Override to filter out reward lines from the cart lines.
These are handled by the _update_programs_and_rewards and _auto_apply_rewards methods.
"""
lines = super()._cart_find_product_line(product_id, line_id, **kwargs)
lines = lines.filtered(lambda l: not l.is_reward_line) if not line_id else lines
return lines
@@ -4,3 +4,4 @@ from . import test_apply_pending_coupon
from . import test_sale_coupon_multiwebsite
from . import test_shop_sale_coupon
from . import test_website_sale_loyalty_delivery
from . import test_free_product_reward
@@ -0,0 +1,81 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import http
from odoo.tests.common import HttpCase
from odoo.tests import tagged
from odoo.addons.website.tools import MockRequest
from odoo.addons.website_sale_loyalty.controllers.main import WebsiteSale
@tagged('post_install', '-at_install')
class TestFreeProductReward(HttpCase):
def setUp(self):
super().setUp()
self.WebsiteSaleController = WebsiteSale()
self.website = self.env['website'].browse(1)
self.sofa = self.env['product.product'].create({
'name': 'Test Sofa',
'list_price': 2950.0,
'website_published': True,
})
self.carpet = self.env['product.product'].create({
'name': 'Test Carpet',
'list_price': 500.0,
'website_published': True,
})
# Disable any other program
self.program = self.env['loyalty.program'].search([]).write({'active': False})
self.program = self.env['loyalty.program'].create({
'name': 'Get a product for free',
'program_type': 'promotion',
'applies_on': 'current',
'trigger': 'auto',
'rule_ids': [(0, 0, {
'minimum_qty': 1,
'minimum_amount': 0.00,
'reward_point_amount': 1,
'reward_point_mode': 'order',
'product_ids': self.sofa,
})],
'reward_ids': [(0, 0, {
'reward_type': 'product',
'reward_product_id': self.carpet.id,
'reward_product_qty': 1,
'required_points': 1,
})],
})
self.steve = self.env['res.partner'].create({
'name': 'Steve Bucknor',
'email': 'steve.bucknor@example.com',
})
self.empty_order = self.env['sale.order'].create({
'partner_id': self.steve.id
})
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
def test_add_product_to_cart_when_it_exist_as_free_product(self):
# This test the flow when we claim a reward in the cart page and then we
# want to add the product again
order = self.empty_order
with MockRequest(self.env, website=self.website, sale_order_id=order.id, website_sale_current_pl=1):
self.WebsiteSaleController.cart_update_json(self.sofa.id, set_qty=1)
self.WebsiteSaleController.claim_reward(self.program.reward_ids[0].id)
self.WebsiteSaleController.cart_update_json(self.carpet.id, set_qty=1)
sofa_line = order.order_line.filtered(lambda line: line.product_id.id == self.sofa.id)
carpet_reward_line = order.order_line.filtered(lambda line: line.product_id.id == self.carpet.id and line.is_reward_line)
carpet_line = order.order_line.filtered(lambda line: line.product_id.id == self.carpet.id and not line.is_reward_line)
self.assertEqual(sofa_line.product_uom_qty, 1, "Should have only 1 qty of Sofa")
self.assertEqual(carpet_reward_line.product_uom_qty, 1, "Should have only 1 qty for the carpet as reward")
self.assertEqual(carpet_line.product_uom_qty, 1, "Should have only 1 qty for carpet as non reward")