From a31ad57791e81a4e43f4dfbf2b635c5213bf38a1 Mon Sep 17 00:00:00 2001 From: roen-odoo Date: Wed, 15 Mar 2023 15:18:02 +0000 Subject: [PATCH] [FIX] point_of_sale: display default pricelist price as base price MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Current behavior: When a discount is applied on a product because of a pricelist. The base price is displayed without applying the default pricelist on it. Steps to reproduce: - Create product A with price of 10€ - Create pricelsit PL1 that change price of product A to 7€(fixed price) - Create pricelist PL2 based on PL1 that use a formula to apply 10% on all products. - Change PoS default pricelist to PL1 and make PL1 and PL2 available on the PoS. - Open a PoS session and add product A to the order. Price should be 7€. - Apply PL2 on the order. - The product line shows that the price was 10€ has been discounted to 6.30€. The base price should be 7€. opw-3200027 closes odoo/odoo#117273 X-original-commit: 395235f202513267fcf3cde28ae51fa0a5caeb42 Signed-off-by: Trinh Jacky (trj) Signed-off-by: Engels Robin (roen) --- addons/point_of_sale/static/src/js/models.js | 23 +++++----- .../static/tests/tours/ReceiptScreen.tour.js | 14 ++++++ .../tours/helpers/ProductScreenTourMethods.js | 9 ++++ .../tours/helpers/ReceiptScreenTourMethods.js | 9 ++++ addons/point_of_sale/tests/test_frontend.py | 43 +++++++++++++++++++ 5 files changed, 86 insertions(+), 12 deletions(-) diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js index d45ea19f59f75..893abdec2a8fc 100644 --- a/addons/point_of_sale/static/src/js/models.js +++ b/addons/point_of_sale/static/src/js/models.js @@ -2409,26 +2409,25 @@ export class Orderline extends PosModel { } } get_taxed_lst_unit_price(){ - var base_price = this.compute_fixed_price(this.get_base_price()); - if (this.pos.config.iface_tax_included === "total") { - var product = this.get_product(); + var lst_price = this.compute_fixed_price(this.get_lst_price()); + if (this.pos.config.iface_tax_included === 'total') { + var product = this.get_product(); var taxes_ids = product.taxes_id; var product_taxes = this.pos.get_taxes_after_fp(taxes_ids); - return this.compute_all(product_taxes, base_price, 1, this.pos.currency.rounding) - .total_included; + return this.compute_all(product_taxes, lst_price, 1, this.pos.currency.rounding).total_included; } - return base_price; + return lst_price; } - get_price_without_tax() { + get_price_without_tax(){ return this.get_all_prices().priceWithoutTax; } - get_price_with_tax() { + get_price_with_tax(){ return this.get_all_prices().priceWithTax; } - get_price_with_tax_before_discount() { + get_price_with_tax_before_discount () { return this.get_all_prices().priceWithTaxBeforeDiscount; } - get_tax() { + get_tax(){ return this.get_all_prices().tax; } get_applicable_taxes() { @@ -2582,8 +2581,8 @@ export class Orderline extends PosModel { get_fixed_lst_price() { return this.compute_fixed_price(this.get_lst_price()); } - get_lst_price() { - return this.product.lst_price; + get_lst_price(){ + return this.product.get_price(this.pos.default_pricelist, 1, 0) } set_lst_price(price) { this.order.assert_editable(); diff --git a/addons/point_of_sale/static/tests/tours/ReceiptScreen.tour.js b/addons/point_of_sale/static/tests/tours/ReceiptScreen.tour.js index a67136dc8a06b..6cb5ac0e4dad7 100644 --- a/addons/point_of_sale/static/tests/tours/ReceiptScreen.tour.js +++ b/addons/point_of_sale/static/tests/tours/ReceiptScreen.tour.js @@ -65,3 +65,17 @@ PaymentScreen.do.clickValidate(); ReceiptScreen.check.customerNoteIsThere("Test customer note"); registry.category("web_tour.tours").add("ReceiptScreenTour", { test: true, url: "/pos/ui", steps: getSteps() }); + +startSteps(); + +ProductScreen.do.clickHomeCategory(); +ProductScreen.exec.addOrderline('Test Product', '1'); +ProductScreen.do.clickPricelistButton(); +ProductScreen.do.selectPriceList('special_pricelist'); +ProductScreen.check.discountOriginalPriceIs('7.0'); +ProductScreen.do.clickPayButton(); +PaymentScreen.do.clickPaymentMethod('Cash'); +PaymentScreen.do.clickValidate(); +ReceiptScreen.check.discountAmountIs('0.7'); + +registry.category("web_tour.tours").add("ReceiptScreenDiscountWithPricelistTour", { test: true, url: "/pos/ui", steps: getSteps() }); \ No newline at end of file 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 3b81a3ff3cd93..c11979aa54c37 100644 --- a/addons/point_of_sale/static/tests/tours/helpers/ProductScreenTourMethods.js +++ b/addons/point_of_sale/static/tests/tours/helpers/ProductScreenTourMethods.js @@ -282,6 +282,15 @@ class Check { }, ]; } + discountOriginalPriceIs(original_price) { + return [ + { + content: `discount original price is shown`, + trigger: `s:contains('${original_price}')`, + run: function () {}, + }, + ]; + } } class Execute { diff --git a/addons/point_of_sale/static/tests/tours/helpers/ReceiptScreenTourMethods.js b/addons/point_of_sale/static/tests/tours/helpers/ReceiptScreenTourMethods.js index 1d5928aa6e727..5706e43106773 100644 --- a/addons/point_of_sale/static/tests/tours/helpers/ReceiptScreenTourMethods.js +++ b/addons/point_of_sale/static/tests/tours/helpers/ReceiptScreenTourMethods.js @@ -81,6 +81,15 @@ class Check { }, ]; } + + discountAmountIs(value) { + return [ + { + trigger: `.pos-receipt>div:contains("Discounts")>span:contains("${value}")`, + run: () => {}, + }, + ]; + } } class Execute { diff --git a/addons/point_of_sale/tests/test_frontend.py b/addons/point_of_sale/tests/test_frontend.py index f6ca0805c99d9..9eb5e6449b26a 100644 --- a/addons/point_of_sale/tests/test_frontend.py +++ b/addons/point_of_sale/tests/test_frontend.py @@ -730,3 +730,46 @@ def test_fiscal_position_no_tax(self): }) self.main_pos_config.open_ui() self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'FiscalPositionNoTax', login="accountman") + + def test_06_pos_discount_display_with_multiple_pricelist(self): + """ Test the discount display on the POS screen when multiple pricelists are used.""" + test_product = self.env['product.product'].create({ + 'name': 'Test Product', + 'available_in_pos': True, + 'list_price': 10, + 'taxes_id': False, + }) + + base_pricelist = self.env['product.pricelist'].create({ + 'name': 'base_pricelist', + 'discount_policy': 'without_discount', + }) + + self.env['product.pricelist.item'].create({ + 'pricelist_id': base_pricelist.id, + 'product_tmpl_id': test_product.product_tmpl_id.id, + 'compute_price': 'fixed', + 'applied_on': '1_product', + 'fixed_price': 7, + }) + + special_pricelist = self.env['product.pricelist'].create({ + 'name': 'special_pricelist', + 'discount_policy': 'without_discount', + }) + self.env['product.pricelist.item'].create({ + 'pricelist_id': special_pricelist.id, + 'base': 'pricelist', + 'base_pricelist_id': base_pricelist.id, + 'compute_price': 'formula', + 'applied_on': '3_global', + 'price_discount': 10, + }) + + self.main_pos_config.write({ + 'pricelist_id': base_pricelist.id, + 'available_pricelist_ids': [(6, 0, [base_pricelist.id, special_pricelist.id])], + }) + + self.main_pos_config.open_ui() + self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'ReceiptScreenDiscountWithPricelistTour', login="accountman")