diff --git a/addons/barcodes/static/src/js/barcode_parser.js b/addons/barcodes/static/src/js/barcode_parser.js index 38410f3adcd..0b98785cd8b 100644 --- a/addons/barcodes/static/src/js/barcode_parser.js +++ b/addons/barcodes/static/src/js/barcode_parser.js @@ -1,51 +1,33 @@ -/** @odoo-module alias=barcodes.BarcodeParser **/ +/** @odoo-module **/ -import Class from "web.Class"; -import rpc from "web.rpc"; +export class BarcodeParser { + static barcodeNomenclatureFields = ["name", "rule_ids", "upc_ean_conv"]; + static barcodeRuleFields = ["name", "sequence", "type", "encoding", "pattern", "alias"]; + static async fetchNomenclature(orm, id) { + const [nomenclature] = await orm.read( + "barcode.nomenclature", + [id], + this.barcodeNomenclatureFields + ); + let rules = await orm.searchRead( + "barcode.rule", + [["barcode_nomenclature_id", "=", id]], + this.barcodeRuleFields + ); + rules = rules.sort((a, b) => { + return a.sequence - b.sequence; + }); + nomenclature.rules = rules; + return nomenclature; + } -// The BarcodeParser is used to detect what is the category -// of a barcode (product, partner, ...) and extract an encoded value -// (like weight, price, etc.) -var BarcodeParser = Class.extend({ - init: function(attributes) { - this.nomenclature_id = attributes.nomenclature_id; - this.nomenclature = attributes.nomenclature; - this.loaded = this.load(); - }, + constructor() { + this.setup(...arguments); + } - // This loads the barcode nomenclature and barcode rules which are - // necessary to parse the barcodes. The BarcodeParser is operational - // only when those data have been loaded - load: function(){ - if (!this.nomenclature_id) { - return this.nomenclature ? Promise.resolve() : Promise.reject(); - } - var id = this.nomenclature_id[0]; - return rpc.query({ - model: 'barcode.nomenclature', - method: 'read', - args: [[id], this._barcodeNomenclatureFields()], - }).then(nomenclatures => { - this.nomenclature = nomenclatures[0]; - var args = [ - [['barcode_nomenclature_id', '=', this.nomenclature.id]], - this._barcodeRuleFields(), - ]; - return rpc.query({ - model: 'barcode.rule', - method: 'search_read', - args: args, - }); - }).then(rules => { - rules = rules.sort(function(a, b){ return a.sequence - b.sequence; }); - this.nomenclature.rules = rules; - }); - }, - - // resolves when the barcode parser is operational. - is_loaded: function() { - return this.loaded; - }, + setup({ nomenclature }) { + this.nomenclature = nomenclature; + } /** * This algorithm is identical for all fixed length numeric GS1 data structures. @@ -76,7 +58,7 @@ var BarcodeParser = Class.extend({ } total = evensum * 3 + oddsum; return (10 - total % 10) % 10; - }, + } /** * Checks if the barcode string is encoded with the provided encoding. @@ -85,7 +67,7 @@ var BarcodeParser = Class.extend({ * @param {String} encoding could be 'any' (no encoding rules), 'ean8', 'upca' or 'ean13' * @returns {boolean} */ - check_encoding: function(barcode, encoding) { + check_encoding(barcode, encoding) { if (encoding === 'any') { return true; } @@ -96,7 +78,7 @@ var BarcodeParser = Class.extend({ }; return barcode.length === barcodeSizes[encoding] && /^\d+$/.test(barcode) && this.get_barcode_check_digit(barcode) === parseInt(barcode[barcode.length - 1]); - }, + } /** * Sanitizes a EAN-13 prefix by padding it with chars zero. @@ -104,11 +86,11 @@ var BarcodeParser = Class.extend({ * @param {String} ean * @returns {String} */ - sanitize_ean: function(ean){ + sanitize_ean(ean) { ean = ean.substr(0, 13); ean = "0".repeat(13 - ean.length) + ean; return ean.substr(0, 12) + this.get_barcode_check_digit(ean); - }, + } /** * Sanitizes a UPC-A prefix by padding it with chars zero. @@ -116,9 +98,9 @@ var BarcodeParser = Class.extend({ * @param {String} upc * @returns {String} */ - sanitize_upc: function(upc) { + sanitize_upc(upc) { return this.sanitize_ean(upc).substr(1, 12); - }, + } // Checks if barcode matches the pattern // Additionnaly retrieves the optional numerical content in barcode @@ -126,7 +108,7 @@ var BarcodeParser = Class.extend({ // - value: the numerical value encoded in the barcode (0 if no value encoded) // - base_code: the barcode in which numerical content is replaced by 0's // - match: boolean - match_pattern: function (barcode, pattern, encoding){ + match_pattern(barcode, pattern, encoding) { var match = { value: 0, base_code: barcode, @@ -182,7 +164,7 @@ var BarcodeParser = Class.extend({ match.match = match.base_code.match(base_pattern); return match; - }, + } /** * Attempts to interpret a barcode (string encoding a barcode Code-128) @@ -194,7 +176,7 @@ var BarcodeParser = Class.extend({ * - value: if the barcode encodes a numerical value, it will be put there * - base_code: the barcode with all the encoding parts set to zero; the one put on the product in the backend */ - parse_barcode: function(barcode){ + parse_barcode(barcode) { var parsed_result = { encoding: '', type:'error', @@ -250,30 +232,5 @@ var BarcodeParser = Class.extend({ } } return parsed_result; - }, - - //-------------------------------------------------------------------------- - // Private - //-------------------------------------------------------------------------- - - _barcodeNomenclatureFields: function () { - return [ - 'name', - 'rule_ids', - 'upc_ean_conv', - ]; - }, - - _barcodeRuleFields: function () { - return [ - 'name', - 'sequence', - 'type', - 'encoding', - 'pattern', - 'alias', - ]; - }, -}); - -export default BarcodeParser; + } +} diff --git a/addons/barcodes/static/tests/basic/legacy/barcode_parser_tests.js b/addons/barcodes/static/tests/basic/legacy/barcode_parser_tests.js index 48cdad00dcf..cfcbad9004f 100644 --- a/addons/barcodes/static/tests/basic/legacy/barcode_parser_tests.js +++ b/addons/barcodes/static/tests/basic/legacy/barcode_parser_tests.js @@ -1,43 +1,29 @@ /** @odoo-module **/ -import BarcodeParser from "barcodes.BarcodeParser"; +import { BarcodeParser } from "@barcodes/js/barcode_parser"; QUnit.module('Barcodes', {}, function () { -QUnit.module('Barcode Parser', { - beforeEach: function () { - this.data = { - 'barcode.nomenclature': { - fields: { - name: {type: 'char', string: 'Barcode Nomenclature'}, - rule_ids: {type: 'one2many', relation: 'barcode.rule'}, - upc_ean_conv: {type: 'selection', string: 'UPC/EAN Conversion'}, - }, - records: [ - {id: 1, name: "normal", upc_ean_conv: "always"}, - ], - }, - 'barcode.rule': { - fields: { - name: {type: 'char', string: 'Barcode Nomenclature'}, - barcode_nomenclature_id: {type: 'many2one', relation: 'barcode.nomenclature'}, - sequence: {type: 'integer', string: 'Sequence'}, - encoding: {type: 'selection', string: 'Encoding'}, - type: {type: 'selection', string: 'Type'}, - pattern: {type: 'Char', string: 'Pattern'}, - alias: {type: 'Char', string: 'Alias'}, - }, - records: [ - {id: 1, name: "Product Barcodes", barcode_nomenclature_id: 1, sequence: 90, type: 'product', encoding: 'any', pattern: ".*"}, - ], - } - }; - } -}, function () { - QUnit.test('Test check digit', async function (assert) { +QUnit.module('Barcode Parser', function () { + QUnit.test('Test check digit', function (assert) { assert.expect(6); - const barcodeNomenclature = new BarcodeParser({'nomenclature_id': 1}); - await barcodeNomenclature.loaded; + const nomenclature = { + id: 1, + name: "normal", + upc_ean_conv: "always", + rules: [ + { + id: 1, + name: "Product Barcodes", + barcode_nomenclature_id: 1, + sequence: 90, + type: "product", + encoding: "any", + pattern: ".*", + }, + ], + }; + const barcodeNomenclature = new BarcodeParser({ nomenclature }); let ean8 = "87111125"; assert.equal(barcodeNomenclature.get_barcode_check_digit(ean8), ean8[ean8.length - 1]); 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 3561d1fd80b..9c8e28f8a6e 100644 --- a/addons/barcodes_gs1_nomenclature/static/src/js/barcode_parser.js +++ b/addons/barcodes_gs1_nomenclature/static/src/js/barcode_parser.js @@ -1,10 +1,26 @@ -/** @odoo-module alias=barcodes_gs1_nomenclature.barcode_parser **/ +/** @odoo-module **/ -import BarcodeParser from "barcodes.BarcodeParser"; -const FNC1_CHAR = String.fromCharCode(29); +import { patch } from "@web/core/utils/patch"; +import { BarcodeParser } from "@barcodes/js/barcode_parser"; import {_lt} from "web.core"; -BarcodeParser.include({ +export const FNC1_CHAR = String.fromCharCode(29); + +patch(BarcodeParser, "barcodes_gs1_nomenclature.BarcodeParser static", { + barcodeNomenclatureFields: [ + ...BarcodeParser.barcodeNomenclatureFields, + "is_gs1_nomenclature", + "gs1_separator_fnc1", + ], + barcodeRuleFields: [ + ...BarcodeParser.barcodeRuleFields, + "gs1_content_type", + "gs1_decimal_usage", + "associated_uom_id", + ], +}); + +patch(BarcodeParser.prototype, "barcodes_gs1_nomenclature.BarcodeParser", { /** * Convert YYMMDD GS1 date into a Date object * @@ -123,31 +139,4 @@ BarcodeParser.include({ } return this._super(...arguments); }, - - //-------------------------------------------------------------------------- - // Private - //-------------------------------------------------------------------------- - - /** - * @override - */ - _barcodeNomenclatureFields: function () { - const fieldNames = this._super(...arguments); - fieldNames.push('is_gs1_nomenclature', 'gs1_separator_fnc1'); - return fieldNames; - }, - - /** - * @override - */ - _barcodeRuleFields: function () { - const fieldNames = this._super(...arguments); - fieldNames.push('gs1_content_type', 'gs1_decimal_usage', 'associated_uom_id'); - return fieldNames; - }, }); - -export default { - BarcodeParser, - FNC1_CHAR, -}; diff --git a/addons/barcodes_gs1_nomenclature/static/src/js/barcode_service.js b/addons/barcodes_gs1_nomenclature/static/src/js/barcode_service.js index e74bff971ea..c657a280343 100644 --- a/addons/barcodes_gs1_nomenclature/static/src/js/barcode_service.js +++ b/addons/barcodes_gs1_nomenclature/static/src/js/barcode_service.js @@ -4,7 +4,7 @@ import { session } from "@web/session"; import { patch } from "@web/core/utils/patch"; import { barcodeService } from '@barcodes/barcode_service'; -import { FNC1_CHAR } from "barcodes_gs1_nomenclature.barcode_parser"; +import { FNC1_CHAR } from "@barcodes_gs1_nomenclature/js/barcode_parser"; patch(barcodeService, 'barcodes_gs1_nomenclature', { diff --git a/addons/barcodes_gs1_nomenclature/static/src/js/tests/barcode_parser_tests.js b/addons/barcodes_gs1_nomenclature/static/src/js/tests/barcode_parser_tests.js index 560bf099df9..d563f6c27c0 100644 --- a/addons/barcodes_gs1_nomenclature/static/src/js/tests/barcode_parser_tests.js +++ b/addons/barcodes_gs1_nomenclature/static/src/js/tests/barcode_parser_tests.js @@ -1,6 +1,6 @@ /** @odoo-module **/ -import BarcodeParser from "barcodes.BarcodeParser"; +import { BarcodeParser } from "@barcodes/js/barcode_parser"; import { barcodeService } from "@barcodes/barcode_service"; diff --git a/addons/point_of_sale/static/src/app/barcode_reader_service.js b/addons/point_of_sale/static/src/app/barcode_reader_service.js index d307cce8f6f..e361bb158b6 100644 --- a/addons/point_of_sale/static/src/app/barcode_reader_service.js +++ b/addons/point_of_sale/static/src/app/barcode_reader_service.js @@ -5,7 +5,7 @@ import { Mutex } from "@web/core/utils/concurrency"; import { session } from "@web/session"; import { ErrorPopup } from "@point_of_sale/js/Popups/ErrorPopup"; import { ErrorBarcodePopup } from "@point_of_sale/js/Popups/ErrorBarcodePopup"; -import BarcodeParser from "barcodes.BarcodeParser"; +import { BarcodeParser } from "@barcodes/js/barcode_parser"; export class BarcodeReader { static serviceDependencies = ["popup", "hardware_proxy"]; @@ -103,14 +103,17 @@ export class BarcodeReader { } export const barcodeReaderService = { - dependencies: [...BarcodeReader.serviceDependencies, "popup", "barcode"], + dependencies: [...BarcodeReader.serviceDependencies, "popup", "barcode", "orm"], async start(env, deps) { - const { popup, barcode } = deps; + const { popup, barcode, orm } = deps; let barcodeReader = null; if (session.nomenclature_id) { - const parser = new BarcodeParser({ nomenclature_id: [session.nomenclature_id] }); - await parser.is_loaded(); + const nomenclature = await BarcodeParser.fetchNomenclature( + orm, + session.nomenclature_id + ); + const parser = new BarcodeParser({ nomenclature }); barcodeReader = new BarcodeReader(parser, deps); }