diff --git a/addons/barcodes_gs1_nomenclature/static/src/js/barcode_parser.js b/addons/barcodes_gs1_nomenclature/static/src/js/barcode_parser.js index f7bbf51fb46f7a4afe36d6de94beb112be970ad5..ed0fb498dd05a5bf7a05ece102a876c876fe7e2a 100644 --- a/addons/barcodes_gs1_nomenclature/static/src/js/barcode_parser.js +++ b/addons/barcodes_gs1_nomenclature/static/src/js/barcode_parser.js @@ -46,7 +46,10 @@ BarcodeParser.include({ const result = { rule: Object.assign({}, rule), ai: match[1], - string_value: match[2] + string_value: match[2], + code: match[2], + base_code: match[2], + type: rule.type }; if (rule.gs1_content_type === 'measure'){ let decimalPosition = 0; // Decimal position begin at the end, 0 means no decimal diff --git a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ProductScreen.js b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ProductScreen.js index 473de510dd039dac5b8e99402f0f086d9d571a25..672b16b07184497b3c1d162ea4f64a5f4bf3700b 100644 --- a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ProductScreen.js +++ b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ProductScreen.js @@ -29,6 +29,7 @@ odoo.define('point_of_sale.ProductScreen', function(require) { client: this._barcodePartnerAction, discount: this._barcodeDiscountAction, error: this._barcodeErrorAction, + gs1: this._barcodeGS1Action, }); NumberBuffer.use({ nonKeyboardInputEvent: 'numpad-click-input', @@ -61,7 +62,7 @@ odoo.define('point_of_sale.ProductScreen', function(require) { get currentOrder() { return this.env.pos.get_order(); } - async _getAddProductOptions(product, base_code) { + async _getAddProductOptions(product, code) { let price_extra = 0.0; let draftPackLotLines, weight, description, packLotLinesToEdit; @@ -97,24 +98,36 @@ odoo.define('point_of_sale.ProductScreen', function(require) { packLotLinesToEdit = []; } } - const { confirmed, payload } = await this.showPopup('EditListPopup', { - title: this.env._t('Lot/Serial Number(s) Required'), - isSingleItem: isAllowOnlyOneLot, - array: packLotLinesToEdit, - }); - if (confirmed) { - // Segregate the old and new packlot lines + // if the lot information exists in the barcode, we don't need to ask it from the user. + if (code && code.type === 'lot') { + // consider the old and new packlot lines const modifiedPackLotLines = Object.fromEntries( - payload.newArray.filter(item => item.id).map(item => [item.id, item.text]) + packLotLinesToEdit.filter(item => item.id).map(item => [item.id, item.text]) ); - const newPackLotLines = payload.newArray - .filter(item => !item.id) - .map(item => ({ lot_name: item.text })); - + const newPackLotLines = [ + { lot_name: code.code }, + ]; draftPackLotLines = { modifiedPackLotLines, newPackLotLines }; } else { - // We don't proceed on adding product. - return; + const { confirmed, payload } = await this.showPopup('EditListPopup', { + title: this.env._t('Lot/Serial Number(s) Required'), + isSingleItem: isAllowOnlyOneLot, + array: packLotLinesToEdit, + }); + if (confirmed) { + // Segregate the old and new packlot lines + const modifiedPackLotLines = Object.fromEntries( + payload.newArray.filter(item => item.id).map(item => [item.id, item.text]) + ); + const newPackLotLines = payload.newArray + .filter(item => !item.id) + .map(item => ({ lot_name: item.text })); + + draftPackLotLines = { modifiedPackLotLines, newPackLotLines }; + } else { + // We don't proceed on adding product. + return; + } } } @@ -136,8 +149,8 @@ odoo.define('point_of_sale.ProductScreen', function(require) { } } - if (base_code && this.env.pos.db.product_packaging_by_barcode[base_code.code]) { - weight = this.env.pos.db.product_packaging_by_barcode[base_code.code].qty; + if (code && this.env.pos.db.product_packaging_by_barcode[code.code]) { + weight = this.env.pos.db.product_packaging_by_barcode[code.code].qty; } return { draftPackLotLines, quantity: weight, description, price_extra }; @@ -214,7 +227,7 @@ odoo.define('point_of_sale.ProductScreen', function(require) { } } } - async _barcodeProductAction(code) { + async _getProductByBarcode(code) { let product = this.env.pos.db.get_product_by_barcode(code.base_code); if (!product) { // find the barcode in the backend @@ -244,6 +257,13 @@ odoo.define('point_of_sale.ProductScreen', function(require) { return this._barcodeErrorAction(code); } } + return product + } + async _barcodeProductAction(code) { + const product = await this._getProductByBarcode(code); + if (!product) { + return; + } const options = await this._getAddProductOptions(product, code); // Do not proceed on adding the product when no options is returned. // This is consistent with _clickProduct. @@ -289,6 +309,22 @@ odoo.define('point_of_sale.ProductScreen', function(require) { last_orderline.set_discount(code.value); } } + /** + * Add a product to the current order using the product identifier and lot number from parsed results. + * This function retrieves the product identifier and lot number from the `parsed_results` parameter. + * It then uses these values to retrieve the product and add it to the current order. + */ + async _barcodeGS1Action(parsed_results) { + const productBarcode = parsed_results.find(element => element.type === 'product'); + const lotBarcode = parsed_results.find(element => element.type === 'lot'); + const product = await this._getProductByBarcode(productBarcode); + if (!product) { + return; + } + const options = await this._getAddProductOptions(product, lotBarcode); + await this.currentOrder.add_product(product, options); + NumberBuffer.reset(); + } // IMPROVEMENT: The following two methods should be in PosScreenComponent? // Why? Because once we start declaring barcode actions in different // screens, these methods will also be declared over and over. diff --git a/addons/point_of_sale/static/src/js/barcode_reader.js b/addons/point_of_sale/static/src/js/barcode_reader.js index 0a9c4b0f9083a113334d0f34035bb11382c623f6..6e2ec177f1c4f453f6a8beacbbbf3b1a02f6b21d 100644 --- a/addons/point_of_sale/static/src/js/barcode_reader.js +++ b/addons/point_of_sale/static/src/js/barcode_reader.js @@ -110,11 +110,10 @@ var BarcodeReader = core.Class.extend({ const callbacks = Object.keys(this.exclusive_callbacks).length ? this.exclusive_callbacks : this.action_callbacks; - let parsed_results = this.barcode_parser.parse_barcode(code); - if (! Array.isArray(parsed_results)) { - parsed_results = [parsed_results]; - } - for (const parsed_result of parsed_results) { + let parsed_result = this.barcode_parser.parse_barcode(code); + if (Array.isArray(parsed_result)) { + [...callbacks.gs1].map(cb => cb(parsed_result)); + } else { if (callbacks[parsed_result.type]) { for (const cb of callbacks[parsed_result.type]) { await cb(parsed_result);