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