diff --git a/addons/point_of_sale/static/src/app/barcode/barcode_reader_service.js b/addons/point_of_sale/static/src/app/barcode/barcode_reader_service.js index 61f6b8d5d8e..ea9822872f3 100644 --- a/addons/point_of_sale/static/src/app/barcode/barcode_reader_service.js +++ b/addons/point_of_sale/static/src/app/barcode/barcode_reader_service.js @@ -56,6 +56,9 @@ export class BarcodeReader { let parseBarcode; try { parseBarcode = this.parser.parse_barcode(code); + if (Array.isArray(parseBarcode) && !parseBarcode.some(element => element.type === 'product')) { + throw new GS1BarcodeError('The GS1 barcode must contain a product.'); + } } catch (error) { if (this.fallbackParser && error instanceof GS1BarcodeError) { parseBarcode = this.fallbackParser.parse_barcode(code); diff --git a/addons/point_of_sale/static/tests/tours/BarcodeScanning.tour.js b/addons/point_of_sale/static/tests/tours/BarcodeScanning.tour.js index 9a28db2baa9..bbfa4bd0c6c 100644 --- a/addons/point_of_sale/static/tests/tours/BarcodeScanning.tour.js +++ b/addons/point_of_sale/static/tests/tours/BarcodeScanning.tour.js @@ -65,3 +65,35 @@ registry return getSteps(); } }); + +registry + .category("web_tour.tours") + .add("GS1BarcodeScanningTour", { + test: true, + url: "/pos/ui", + steps: () => { + startSteps(); + + ProductScreen.do.confirmOpeningPopup(); + + // Add the Product 1 with GS1 barcode + ProductScreen.do.scan_barcode("0108431673020125100000001"); + ProductScreen.check.selectedOrderlineHas('Product 1'); + ProductScreen.do.scan_barcode("0108431673020125100000001"); + ProductScreen.check.selectedOrderlineHas('Product 1', 2); + + // Add the Product 2 with normal barcode + ProductScreen.do.scan_barcode("08431673020126"); + ProductScreen.check.selectedOrderlineHas('Product 2'); + ProductScreen.do.scan_barcode("08431673020126"); + ProductScreen.check.selectedOrderlineHas('Product 2', 2); + + // Add the Product 3 with normal barcode + ProductScreen.do.scan_barcode("3760171283370"); + ProductScreen.check.selectedOrderlineHas('Product 3'); + ProductScreen.do.scan_barcode("3760171283370"); + ProductScreen.check.selectedOrderlineHas('Product 3', 2); + + return getSteps(); + } + }); diff --git a/addons/point_of_sale/tests/test_frontend.py b/addons/point_of_sale/tests/test_frontend.py index 112d18563f5..bc23496c3e0 100644 --- a/addons/point_of_sale/tests/test_frontend.py +++ b/addons/point_of_sale/tests/test_frontend.py @@ -941,6 +941,40 @@ class TestUi(TestPointOfSaleHttpCommon): self.main_pos_config.with_user(self.pos_user).open_ui() self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'BarcodeScanningProductPackagingTour', login="pos_user") + def test_GS1_pos_barcodes_scan(self): + barcodes_gs1_nomenclature = self.env.ref("barcodes_gs1_nomenclature.default_gs1_nomenclature") + self.main_pos_config.company_id.write({ + 'nomenclature_id': barcodes_gs1_nomenclature.id + }) + + self.env['product.product'].create({ + 'name': 'Product 1', + 'available_in_pos': True, + 'list_price': 10, + 'taxes_id': False, + 'barcode': '08431673020125', + }) + + self.env['product.product'].create({ + 'name': 'Product 2', + 'available_in_pos': True, + 'list_price': 10, + 'taxes_id': False, + 'barcode': '08431673020126', + }) + + # 3760171283370 can be parsed with GS1 rules but it's not GS1 + self.env['product.product'].create({ + 'name': 'Product 3', + 'available_in_pos': True, + 'list_price': 10, + 'taxes_id': False, + 'barcode': '3760171283370', + }) + + self.main_pos_config.open_ui() + self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'GS1BarcodeScanningTour', login="accountman") + # This class just runs the same tests as above but with mobile emulation class MobileTestUi(TestUi): browser_size = '375x667'