[FIX] barcodes_gs1_nomenclature: custom separators

Since https://github.com/odoo/odoo/pull/104287 the GS1 separator defined
in the nomenclature is no more used in `BarcodeParser`
`gs1_decompose_extanded` but it is used in `barcodeService`
`cleanBarcode` instead. The issue with that is `cleanBarcode` is not
called in every case.
It will if the barcode is actually scanned but it won't if the barcode
is decoded from a picture (using the device's camera) or triggered
through an event directly (thanks to the debug console and the manual
entry available in the Barcode App.)
That means if we want to support custom separators, we have to clean the
barcode also in `parse_gs1_rule_pattern`.

How to reproduce:
- Activate `stock_barcode` and chose the GS1 nomenclature;
- Create a product and set a valid barcode (right checksum, eg.:
  00000000012348);
- In the Barcode App, create a new receipt and scan a GS1 barcode for
  this product containing also a quantity and using a custom separator
  (`#` can be use aswell by default, eg.: 3008#0100000000012348 for 8x
  this product) with using the device camera or by trigger the event
  through the console:
odoo.__WOWL_DEBUG__.root.env.services.barcode.bus.trigger(
    "barcode_scanned",
    { barcode: "3008#0100000000012348" },
);
-> Issue: the barcode is not recognized.

With this commit, the parser will get the nomenclature's separator and
will use it like before in `gs1_decompose_extanded`.

Also, this commit slightly changes the separator regex (from '\x1D?' to
'(?:\x1D+)?') in case multiple separators follow each other.

OPW-3439905

closes odoo/odoo#138420

X-original-commit: 39ecbf9d93d465533619aa32e127331a0307c3a9
Related: odoo/enterprise#48811
Signed-off-by: Quentin Wolfs (quwo) <quwo@odoo.com>
Signed-off-by: Steve Van Essche <svs@odoo.com>
This commit is contained in:
svs-odoo
2023-10-18 13:39:09 +00:00
parent 10b855ea87
commit a2f985a84d
2 changed files with 28 additions and 3 deletions
@@ -22,6 +22,13 @@ patch(BarcodeParser, {
});
patch(BarcodeParser.prototype, {
setup(attributes) {
super.setup(...arguments);
// Use the nomenclature's separaor regex, else use an impossible one.
const nomenclatureSeparator = this.nomenclature && this.nomenclature.gs1_separator_fnc1;
this.gs1SeparatorRegex = new RegExp(nomenclatureSeparator || '.^', 'g');
},
/**
* Convert YYMMDD GS1 date into a Date object
*
@@ -106,7 +113,8 @@ patch(BarcodeParser.prototype, {
gs1_decompose_extanded(barcode) {
const results = [];
const rules = this.nomenclature.rules.filter(rule => rule.encoding === 'gs1-128');
const separatorReg = FNC1_CHAR + "?";
const separatorReg = `(?:${FNC1_CHAR}+)?`;
barcode = this._convertGS1Separators(barcode);
while (barcode.length > 0) {
const barcodeLength = barcode.length;
@@ -143,4 +151,17 @@ patch(BarcodeParser.prototype, {
}
return super.parse_barcode(...arguments);
},
/**
* The FNC1 is the default GS1 separator character, but through the field `gs1_separator_fnc1`,
* the user has the possibility to define one or multiple characters to use as separator as
* a regex. This method replaces all of the matches in the given barcode by the FNC1.
*
* @param {string} barcode
* @returns {string}
*/
_convertGS1Separators: function (barcode) {
barcode = barcode.replace(this.gs1SeparatorRegex, FNC1_CHAR);
return barcode;
},
});
@@ -224,7 +224,8 @@ QUnit.module('Barcode GS1 Parser', {
QUnit.test('Test Alternative GS1 Separator (fnc1)', async function (assert) {
assert.expect(6);
const barcodeNomenclature = new BarcodeParser({nomenclature: this.nomenclature});
let barcodeNomenclature = new BarcodeParser({ nomenclature: this.nomenclature });
await barcodeNomenclature.loaded;
// (21)12345(15)090101(16)100101
const code128 = "2112345#1509010116100101";
@@ -238,7 +239,10 @@ QUnit.module('Barcode GS1 Parser', {
);
}
barcodeService.gs1SeparatorRegex = '#';
// Reload the nomenclature but this time using '#' as separator.
this.nomenclature.gs1_separator_fnc1 = '#';
barcodeNomenclature = new BarcodeParser({ nomenclature: this.nomenclature });
await barcodeNomenclature.loaded;
res = barcodeNomenclature.gs1_decompose_extanded(barcodeService.cleanBarcode(code128));
assert.equal(res.length, 3);
assert.equal(res[0].ai, "21");