From 36dc1fce19403935770eaaaf5c1177fc8c1ef2bb Mon Sep 17 00:00:00 2001
From: roen-odoo <roen@odoo.com>
Date: Fri, 18 Nov 2022 14:43:55 +0000
Subject: [PATCH] [FIX] point_of_sale: recompute reward after pricelist change
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Current behavior:
In the PoS if you apply a coupon on an order that contains 2 products
with different taxes, it will create 2 discount lines on the order.
If you change the pricelist, the discount lines won't have the correct
values.

Steps to reproduce:
- Create 2 different products with different taxes.
- Create a pricelist with a discount on the 2 products.
- Create a coupon that apply a 100% discount on the order.
- Start a PoS session
- Add the 2 products to the order and apply the coupon.
- The order total is now 0€.
- Change the pricelist to the one with the discount.
- The order total is different than 0€.

opw-3049098

closes odoo/odoo#106612

X-original-commit: 2f29ca9311bd5c63e9419069088ce1475a124005
Signed-off-by: Trinh Jacky (trj) <trj@odoo.com>
Signed-off-by: Engels Robin (roen) <roen@odoo.com>
---
 .../tours/helpers/ProductScreenTourMethods.js | 11 +++
 addons/pos_loyalty/static/src/js/Loyalty.js   |  6 +-
 .../static/src/tours/PosLoyaltyTour.js        | 17 ++++
 addons/pos_loyalty/tests/test_frontend.py     | 89 +++++++++++++++++++
 4 files changed, 122 insertions(+), 1 deletion(-)

diff --git a/addons/point_of_sale/static/tests/tours/helpers/ProductScreenTourMethods.js b/addons/point_of_sale/static/tests/tours/helpers/ProductScreenTourMethods.js
index 51799e5517b5..f082dd8bf5a6 100644
--- a/addons/point_of_sale/static/tests/tours/helpers/ProductScreenTourMethods.js
+++ b/addons/point_of_sale/static/tests/tours/helpers/ProductScreenTourMethods.js
@@ -130,6 +130,17 @@ odoo.define('point_of_sale.tour.ProductScreenTourMethods', function (require) {
         confirmOpeningPopup() {
             return [{ trigger: '.opening-cash-control .button:contains("Open session")' }];
         }
+        clickPricelistButton() {
+            return [{ trigger: '.o_pricelist_button' }];
+        }
+        selectPriceList(name) {
+            return [
+                {
+                    content: `select price list '${name}'`,
+                    trigger: `.selection-item:contains("${name}")`,
+                },
+            ];
+        }
     }
 
     class Check {
diff --git a/addons/pos_loyalty/static/src/js/Loyalty.js b/addons/pos_loyalty/static/src/js/Loyalty.js
index 9751fe2e1096..327961de9ba8 100644
--- a/addons/pos_loyalty/static/src/js/Loyalty.js
+++ b/addons/pos_loyalty/static/src/js/Loyalty.js
@@ -253,7 +253,7 @@ const PosLoyaltyOrderline = (Orderline) => class PosLoyaltyOrderline extends Ord
     }
     ignoreLoyaltyPoints({ program }) {
         return (
-            ['gift_card', 'ewallet'].includes(program.program_type) &&
+            ['gift_card', 'ewallet'].includes(program.program_type) && this.eWalletGiftCardProgram &&
             this.eWalletGiftCardProgram.id !== program.id
         );
     }
@@ -382,6 +382,10 @@ const PosLoyaltyOrder = (Order) => class PosLoyaltyOrder extends Order {
         const orderLines = super.get_orderlines(...arguments).filter((line) => !line.is_reward_line);
         return orderLines[orderLines.length - 1];
     }
+    set_pricelist(pricelist) {
+        super.set_pricelist(...arguments);
+        this._updateRewards();
+    }
     set_orderline_options(line, options) {
         super.set_orderline_options(...arguments);
         if (options && options.is_reward_line) {
diff --git a/addons/pos_loyalty/static/src/tours/PosLoyaltyTour.js b/addons/pos_loyalty/static/src/tours/PosLoyaltyTour.js
index c7012c41e6cd..5f279731bcd3 100644
--- a/addons/pos_loyalty/static/src/tours/PosLoyaltyTour.js
+++ b/addons/pos_loyalty/static/src/tours/PosLoyaltyTour.js
@@ -178,3 +178,20 @@ PosLoyalty.check.orderTotalIs('49.50');
 
 
 Tour.register('PosLoyaltyTour3', { test: true, url: '/pos/web' }, getSteps());
+
+startSteps();
+
+ProductScreen.do.confirmOpeningPopup();
+ProductScreen.do.clickHomeCategory();
+
+ProductScreen.exec.addOrderline('Test Product 1', '1');
+ProductScreen.exec.addOrderline('Test Product 2', '1');
+ProductScreen.do.clickPricelistButton();
+ProductScreen.do.selectPriceList('Public Pricelist');
+PosLoyalty.do.enterCode('abcda');
+PosLoyalty.check.orderTotalIs('0.00');
+ProductScreen.do.clickPricelistButton();
+ProductScreen.do.selectPriceList('Test multi-currency');
+PosLoyalty.check.orderTotalIs('0.00');
+
+Tour.register('PosLoyaltyTour4', { test: true, url: '/pos/web' }, getSteps());
diff --git a/addons/pos_loyalty/tests/test_frontend.py b/addons/pos_loyalty/tests/test_frontend.py
index 798931f95269..628537c43fe1 100644
--- a/addons/pos_loyalty/tests/test_frontend.py
+++ b/addons/pos_loyalty/tests/test_frontend.py
@@ -581,3 +581,92 @@ class TestUi(TestPointOfSaleHttpCommon):
         ewallet_2_bbb = self.env['loyalty.card'].search([('partner_id', '=', partner_bbb.id), ('program_id', '=', programs['ewallet_2'].id)])
         self.assertEqual(len(ewallet_2_bbb), 1)
         self.assertAlmostEqual(ewallet_2_bbb.points, 0, places=2)
+
+    def test_coupon_change_pricelist(self):
+        """Test coupon program with different pricelists."""
+
+        product_1 = self.env["product.product"].create(
+            {
+                "name": "Test Product 1",
+                "type": "product",
+                "list_price": 25,
+                "available_in_pos": True,
+            }
+        )
+
+        tax01 = self.env["account.tax"].create({
+            "name": "C01 Tax",
+            "amount": "0.00",
+        })
+
+        product_2 = self.env["product.product"].create(
+            {
+                "name": "Test Product 2",
+                "type": "product",
+                "list_price": 25,
+                "available_in_pos": True,
+                "taxes_id": [(6, 0, [tax01.id])],
+            }
+        )
+
+        pricelist = self.env["product.pricelist"].create({
+            "name": "Test multi-currency",
+            "discount_policy": "without_discount",
+            "currency_id": self.env.ref("base.USD").id,
+            "item_ids": [
+                (0, 0, {
+                    "base": "standard_price",
+                    "product_id": product_1.id,
+                    "compute_price": "percentage",
+                    "percent_price": 50,
+                }),
+                (0, 0, {
+                    "base": "standard_price",
+                    "product_id": product_2.id,
+                    "compute_price": "percentage",
+                    "percent_price": 50,
+                })
+            ]
+        })
+
+        self.main_pos_config2 = self.main_pos_config.copy()
+
+        loyalty_program = self.env['loyalty.program'].create({
+            'name': 'Coupon Program - Pricelist',
+            'program_type': 'coupons',
+            'trigger': 'with_code',
+            'applies_on': 'current',
+            'pos_ok': True,
+            'pos_config_ids': [Command.link(self.main_pos_config2.id)],
+            'rule_ids': [(0, 0, {
+                'reward_point_mode': 'order',
+                'reward_point_amount': 1,
+                'minimum_amount': 0,
+            })],
+            'reward_ids': [(0, 0, {
+                'reward_type': 'discount',
+                'required_points': 1,
+                'discount': 100,
+                'discount_mode': 'percent',
+                'discount_applicability': 'order',
+            })],
+        })
+
+        self.env["loyalty.generate.wizard"].with_context(
+            {"active_id": loyalty_program.id}
+        ).create({"coupon_qty": 1, 'points_granted': 4.5}).generate_coupons()
+        self.coupon1 = loyalty_program.coupon_ids
+        self.coupon1.write({"code": "abcda"})
+
+        self.main_pos_config2.write({
+            'use_pricelist': True,
+            'available_pricelist_ids': [(4, pricelist.id), (4, self.main_pos_config.pricelist_id.id)],
+            'pricelist_id': pricelist.id,
+        })
+
+        self.main_pos_config2.open_ui()
+        self.start_tour(
+            "/pos/web?config_id=%d" % self.main_pos_config2.id,
+            "PosLoyaltyTour4",
+            login="accountman",
+        )
-- 
GitLab