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 b727813e495..14bad1bebdc 100644 --- a/addons/barcodes_gs1_nomenclature/static/src/js/barcode_parser.js +++ b/addons/barcodes_gs1_nomenclature/static/src/js/barcode_parser.js @@ -61,7 +61,10 @@ patch(BarcodeParser.prototype, "barcodes_gs1_nomenclature.BarcodeParser", { 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/app/barcode/barcode_reader_service.js b/addons/point_of_sale/static/src/app/barcode/barcode_reader_service.js index ff01a4411fe..1a66c24c544 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 @@ -51,12 +51,10 @@ export class BarcodeReader { const cbMaps = this.exclusiveCbMap ? [this.exclusiveCbMap] : [...this.cbMaps]; - let parsedResult = this.parser.parse_barcode(code); - if (!Array.isArray(parsedResult)) { - parsedResult = [parsedResult]; - } - - for (const parseBarcode of parsedResult) { + let parseBarcode = this.parser.parse_barcode(code); + if (Array.isArray(parseBarcode)) { + cbMaps.map((cb) => cb.gs1?.(parseBarcode)); + } else { const cbs = cbMaps.map((cbMap) => cbMap[parseBarcode.type]).filter(Boolean); if (cbs.length === 0) { this.popup.add(ErrorBarcodePopup, { code: this.codeRepr(parseBarcode) }); diff --git a/addons/point_of_sale/static/src/app/screens/product_screen/product_screen.js b/addons/point_of_sale/static/src/app/screens/product_screen/product_screen.js index fd70c933378..4cd500acbaf 100644 --- a/addons/point_of_sale/static/src/app/screens/product_screen/product_screen.js +++ b/addons/point_of_sale/static/src/app/screens/product_screen/product_screen.js @@ -49,6 +49,7 @@ export class ProductScreen extends ControlButtonsMixin(Component) { price: this._barcodeProductAction, client: this._barcodePartnerAction, discount: this._barcodeDiscountAction, + gs1: this._barcodeGS1Action, }); // Call `resset` when the `onMounted` callback in `numberBuffer.use` is done. @@ -132,7 +133,7 @@ export class ProductScreen extends ControlButtonsMixin(Component) { } } } - async _barcodeProductAction(code) { + async _getProductByBarcode(code) { let product = this.pos.db.get_product_by_barcode(code.base_code); if (!product) { // find the barcode in the backend @@ -148,6 +149,13 @@ export class ProductScreen extends ControlButtonsMixin(Component) { return this.popup.add(ErrorBarcodePopup, { code: code.base_code }); } } + return product; + } + async _barcodeProductAction(code) { + const product = await this._getProductByBarcode(code); + if (!product) { + return; + } const options = await product.getAddProductOptions(code); // Do not proceed on adding the product when no options is returned. // This is consistent with clickProduct. @@ -193,6 +201,22 @@ export class ProductScreen extends ControlButtonsMixin(Component) { if (last_orderline) { 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 product.getAddProductOptions(lotBarcode); + await this.currentOrder.add_product(product, options); + this.numberBuffer.reset(); } async displayAllControlPopup() { await this.popup.add(ControlButtonPopup, { diff --git a/addons/point_of_sale/static/src/app/store/models.js b/addons/point_of_sale/static/src/app/store/models.js index e0e696e7fe5..e36ac3cc3c5 100644 --- a/addons/point_of_sale/static/src/app/store/models.js +++ b/addons/point_of_sale/static/src/app/store/models.js @@ -112,7 +112,7 @@ export class Product extends PosModel { get isScaleAvailable() { return true; } - async getAddProductOptions(base_code) { + async getAddProductOptions(code) { let price_extra = 0.0; let draftPackLotLines, weight, description, packLotLinesToEdit; let quantity = 1; @@ -158,26 +158,39 @@ export class Product extends PosModel { packLotLinesToEdit = []; } } - const { confirmed, payload } = await this.pos.env.services.popup.add(EditListPopup, { - title: this.pos.env._t("Lot/Serial Number(s) Required"), - name: this.display_name, - 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.pos.env.services.popup.add(EditListPopup, { + title: this.pos.env._t("Lot/Serial Number(s) Required"), + name: this.display_name, + 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; + } } + } // Take the weight if necessary. @@ -202,8 +215,8 @@ export class Product extends PosModel { } } - if (base_code && this.pos.db.product_packaging_by_barcode[base_code.code]) { - weight = this.pos.db.product_packaging_by_barcode[base_code.code].qty; + if (code && this.pos.db.product_packaging_by_barcode[code.code]) { + weight = this.pos.db.product_packaging_by_barcode[code.code].qty; } return { draftPackLotLines, quantity, weight, description, price_extra };