diff options
Diffstat (limited to 'addons/barcodes/static/src/js/barcode_parser.js')
| -rw-r--r-- | addons/barcodes/static/src/js/barcode_parser.js | 439 |
1 files changed, 222 insertions, 217 deletions
diff --git a/addons/barcodes/static/src/js/barcode_parser.js b/addons/barcodes/static/src/js/barcode_parser.js index f7dcd96c201..e208257cd11 100644 --- a/addons/barcodes/static/src/js/barcode_parser.js +++ b/addons/barcodes/static/src/js/barcode_parser.js @@ -1,229 +1,234 @@ -openerp.barcodes = function(instance) { - "use strict"; - - instance.barcodes = {}; - var module = instance.barcodes; - - // The BarcodeParser is used to detect what is the category - // of a barcode (product, partner, ...) and extract an encoded value - // (like weight, price, etc.) - module.BarcodeParser = instance.web.Class.extend({ - init: function(attributes) { - var self = this; - this.nomenclature_id = attributes.nomenclature_id; - this.loaded = this.load(); - }, - - // 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(){ - var self = this; - return new instance.web.Model('barcode.nomenclature') - .query(['name','rule_ids','upc_ean_conv']) - .filter([['id','=',this.nomenclature_id[0]]]) - .first() - .then(function(nomenclature){ - self.nomenclature = nomenclature; - - return new instance.web.Model('barcode.rule') - .query(['name','sequence','type','encoding','pattern','alias']) - .filter([['barcode_nomenclature_id','=',self.nomenclature.id ]]) - .all() - }).then(function(rules){ - rules = rules.sort(function(a,b){ return a.sequence - b.sequence; }); - self.nomenclature.rules = rules; - }); - }, - - // resolves when the barcode parser is operational. - is_loaded: function() { - return self.loaded; - }, - - // returns the checksum of the ean13, or -1 if the ean has not the correct length, ean must be a string - ean_checksum: function(ean){ - var code = ean.split(''); - if(code.length !== 13){ - return -1; +odoo.define('barcodes.BarcodeParser', ['web.Class', 'web.Model'], function (require) { +"use strict"; + +var Class = require('web.Class'); +var Model = require('web.Model'); + +// 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.loaded = this.load(); + }, + + // 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(){ + var self = this; + return new Model('barcode.nomenclature') + .query(['name','rule_ids','upc_ean_conv']) + .filter([['id','=',this.nomenclature_id[0]]]) + .first() + .then(function(nomenclature){ + self.nomenclature = nomenclature; + + return new Model('barcode.rule') + .query(['name','sequence','type','encoding','pattern','alias']) + .filter([['barcode_nomenclature_id','=',self.nomenclature.id ]]) + .all(); + }).then(function(rules){ + rules = rules.sort(function(a,b){ return a.sequence - b.sequence; }); + self.nomenclature.rules = rules; + }); + }, + + // resolves when the barcode parser is operational. + is_loaded: function() { + return this.loaded; + }, + + // returns the checksum of the ean13, or -1 if the ean has not the correct length, ean must be a string + ean_checksum: function(ean){ + var code = ean.split(''); + if(code.length !== 13){ + return -1; + } + var oddsum = 0, evensum = 0, total = 0; + code = code.reverse().splice(1); + for(var i = 0; i < code.length; i++){ + if(i % 2 === 0){ + oddsum += Number(code[i]); + }else{ + evensum += Number(code[i]); } - var oddsum = 0, evensum = 0, total = 0; - code = code.reverse().splice(1); - for(var i = 0; i < code.length; i++){ - if(i % 2 == 0){ - oddsum += Number(code[i]); - }else{ - evensum += Number(code[i]); - } - } - total = oddsum * 3 + evensum; - return Number((10 - total % 10) % 10); - }, - - // returns the checksum of the ean8, or -1 if the ean has not the correct length, ean must be a string - ean8_checksum: function(ean){ - var code = ean.split(''); - if (code.length !== 8) { - return -1; + } + total = oddsum * 3 + evensum; + return Number((10 - total % 10) % 10); + }, + + // returns the checksum of the ean8, or -1 if the ean has not the correct length, ean must be a string + ean8_checksum: function(ean){ + var code = ean.split(''); + if (code.length !== 8) { + return -1; + } + var sum1 = Number(code[1]) + Number(code[3]) + Number(code[5]); + var sum2 = Number(code[0]) + Number(code[2]) + Number(code[4]) + Number(code[6]); + var total = sum1 + 3 * sum2; + return Number((10 - total % 10) % 10); + }, + + + // returns true if the ean is a valid EAN barcode number by checking the control digit. + // ean must be a string + check_ean: function(ean){ + return /^\d+$/.test(ean) && this.ean_checksum(ean) === Number(ean[ean.length-1]); + }, + + // returns true if the barcode string is encoded with the provided encoding. + check_encoding: function(barcode, encoding) { + var len = barcode.length; + var allnum = /^\d+$/.test(barcode); + var check = Number(barcode[len-1]); + + if (encoding === 'ean13') { + return len === 13 && allnum && this.ean_checksum(barcode) === check; + } else if (encoding === 'ean8') { + return len === 8 && allnum && this.ean8_checksum(barcode) === check; + } else if (encoding === 'upca') { + return len === 12 && allnum && this.ean_checksum('0'+barcode) === check; + } else if (encoding === 'any') { + return true; + } else { + return false; + } + }, + + // returns a valid zero padded ean13 from an ean prefix. the ean prefix must be a string. + sanitize_ean: function(ean){ + ean = ean.substr(0,13); + + for(var n = 0, count = (13 - ean.length); n < count; n++){ + ean = ean + '0'; + } + return ean.substr(0,12) + this.ean_checksum(ean); + }, + + // Returns a valid zero padded UPC-A from a UPC-A prefix. the UPC-A prefix must be a string. + sanitize_upc: function(upc) { + return this.sanitize_ean('0'+upc).substr(1,12); + }, + + // Checks if barcode matches the pattern + // Additionnaly retrieves the optional numerical content in barcode + // Returns an object containing: + // - 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){ + var match = { + value: 0, + base_code: barcode, + match: false, + }; + barcode = barcode.replace("\\", "\\\\").replace("{", '\{').replace("}", "\}").replace(".", "\."); + + var numerical_content = pattern.match(/[{][N]*[D]*[}]/); // look for numerical content in pattern + var base_pattern = pattern; + if(numerical_content){ // the pattern encodes a numerical content + var num_start = numerical_content.index; // start index of numerical content + var num_length = numerical_content[0].length; // length of numerical content + var value_string = barcode.substr(num_start, num_length-2); // numerical content in barcode + var whole_part_match = numerical_content[0].match("[{][N]*[D}]"); // looks for whole part of numerical content + var decimal_part_match = numerical_content[0].match("[{N][D]*[}]"); // looks for decimal part + var whole_part = value_string.substr(0, whole_part_match.index+whole_part_match[0].length-2); // retrieve whole part of numerical content in barcode + var decimal_part = "0." + value_string.substr(decimal_part_match.index, decimal_part_match[0].length-1); // retrieve decimal part + if (whole_part === ''){ + whole_part = '0'; } - var sum1 = Number(code[1]) + Number(code[3]) + Number(code[5]); - var sum2 = Number(code[0]) + Number(code[2]) + Number(code[4]) + Number(code[6]); - var total = sum1 + 3 * sum2; - return Number((10 - total % 10) % 10); - }, - - - // returns true if the ean is a valid EAN barcode number by checking the control digit. - // ean must be a string - check_ean: function(ean){ - return /^\d+$/.test(ean) && this.ean_checksum(ean) === Number(ean[ean.length-1]); - }, - - // returns true if the barcode string is encoded with the provided encoding. - check_encoding: function(barcode, encoding) { - var len = barcode.length; - var allnum = /^\d+$/.test(barcode); - var check = Number(barcode[len-1]); - - if (encoding === 'ean13') { - return len === 13 && allnum && this.ean_checksum(barcode) === check; - } else if (encoding === 'ean8') { - return len === 8 && allnum && this.ean8_checksum(barcode) === check; - } else if (encoding === 'upca') { - return len === 12 && allnum && this.ean_checksum('0'+barcode) === check; - } else if (encoding === 'any') { - return true; - } else { - return false; + match['value'] = parseInt(whole_part) + parseFloat(decimal_part); + + // replace numerical content by 0's in barcode and pattern + match['base_code'] = barcode.substr(0,num_start); + var base_pattern = pattern.substr(0,num_start); + for(var i=0;i<(num_length-2);i++) { + match['base_code'] += "0"; + base_pattern += "0"; } - }, - - // returns a valid zero padded ean13 from an ean prefix. the ean prefix must be a string. - sanitize_ean: function(ean){ - ean = ean.substr(0,13); - - for(var n = 0, count = (13 - ean.length); n < count; n++){ - ean = ean + '0'; - } - return ean.substr(0,12) + this.ean_checksum(ean); - }, - - // Returns a valid zero padded UPC-A from a UPC-A prefix. the UPC-A prefix must be a string. - sanitize_upc: function(upc) { - return this.sanitize_ean('0'+upc).substr(1,12); - }, - - // Checks if barcode matches the pattern - // Additionnaly retrieves the optional numerical content in barcode - // Returns an object containing: - // - 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){ - var match = { - value: 0, - base_code: barcode, - match: false, - }; - barcode = barcode.replace("\\", "\\\\").replace("{", '\{').replace("}", "\}").replace(".", "\."); - - var numerical_content = pattern.match(/[{][N]*[D]*[}]/); // look for numerical content in pattern - var base_pattern = pattern; - if(numerical_content){ // the pattern encodes a numerical content - var num_start = numerical_content.index; // start index of numerical content - var num_length = numerical_content[0].length; // length of numerical content - var value_string = barcode.substr(num_start, num_length-2); // numerical content in barcode - var whole_part_match = numerical_content[0].match("[{][N]*[D}]"); // looks for whole part of numerical content - var decimal_part_match = numerical_content[0].match("[{N][D]*[}]"); // looks for decimal part - var whole_part = value_string.substr(0, whole_part_match.index+whole_part_match[0].length-2); // retrieve whole part of numerical content in barcode - var decimal_part = "0." + value_string.substr(decimal_part_match.index, decimal_part_match[0].length-1); // retrieve decimal part - if (whole_part === ''){ - whole_part = '0'; - } - match['value'] = parseInt(whole_part) + parseFloat(decimal_part); - - // replace numerical content by 0's in barcode and pattern - match['base_code'] = barcode.substr(0,num_start); - var base_pattern = pattern.substr(0,num_start); - for(var i=0;i<(num_length-2);i++) { - match['base_code'] += "0"; - base_pattern += "0"; - } - match['base_code'] += barcode.substr(num_start+num_length-2,barcode.length-1); - base_pattern += pattern.substr(num_start+num_length,pattern.length-1); - - match['base_code'] = match['base_code'].replace("\\\\", "\\").replace("\{", "{").replace("\}","}").replace("\.","."); + match['base_code'] += barcode.substr(num_start+num_length-2,barcode.length-1); + base_pattern += pattern.substr(num_start+num_length,pattern.length-1); + + match['base_code'] = match['base_code'] + .replace("\\\\", "\\") + .replace("\{", "{") + .replace("\}","}") + .replace("\.","."); + } + + match['match'] = match['base_code'].substr(0,base_pattern.length).match(base_pattern); + return match; + }, + + // attempts to interpret a barcode (string encoding a barcode Code-128) + // it will return an object containing various information about the barcode. + // most importantly : + // - code : the barcode + // - type : the type of the barcode (e.g. alias, unit product, weighted product...) + // + // - 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){ + var parsed_result = { + encoding: '', + type:'error', + code:barcode, + base_code: barcode, + value: 0, + }; + + if (!this.nomenclature) { + return parsed_result; + } + + var rules = this.nomenclature.rules; + for (var i = 0; i < rules.length; i++) { + var rule = rules[i]; + var cur_barcode = barcode; + + if ( rule.encoding === 'ean13' && + this.check_encoding(barcode,'upca') && + this.nomenclature.upc_ean_conv in {'upc2ean':'','always':''} ){ + cur_barcode = '0' + cur_barcode; + } else if (rule.encoding === 'upca' && + this.check_encoding(barcode,'ean13') && + barcode[0] === '0' && + this.upc_ean_conv in {'ean2upc':'','always':''} ){ + cur_barcode = cur_barcode.substr(1,12); } - match['match'] = match['base_code'].substr(0,base_pattern.length).match(base_pattern); - return match; - }, - - // attempts to interpret a barcode (string encoding a barcode Code-128) - // it will return an object containing various information about the barcode. - // most importantly : - // - code : the barcode - // - type : the type of the barcode (e.g. alias, unit product, weighted product...) - // - // - 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){ - var parsed_result = { - encoding: '', - type:'error', - code:barcode, - base_code: barcode, - value: 0, - }; - - if (!this.nomenclature) { - return parsed_result; + if (!this.check_encoding(cur_barcode,rule.encoding)) { + continue; } - var rules = this.nomenclature.rules; - for (var i = 0; i < rules.length; i++) { - var rule = rules[i]; - var cur_barcode = barcode; - - if ( rule.encoding === 'ean13' && - this.check_encoding(barcode,'upca') && - this.nomenclature.upc_ean_conv in {'upc2ean':'','always':''} ){ - cur_barcode = '0' + cur_barcode; - } else if (rule.encoding === 'upca' && - this.check_encoding(barcode,'ean13') && - barcode[0] === '0' && - this.upc_ean_conv in {'ean2upc':'','always':''} ){ - cur_barcode = cur_barcode.substr(1,12); - } - - if (!this.check_encoding(cur_barcode,rule.encoding)) { - continue; + var match = this.match_pattern(cur_barcode,rules[i].pattern); + if (match.match) { + if(rules[i].type === 'alias') { + barcode = rules[i].alias; + parsed_result.code = barcode; + parsed_result.type = 'alias'; } - - var match = this.match_pattern(cur_barcode,rules[i].pattern); - if (match.match) { - if(rules[i].type === 'alias') { - barcode = rules[i].alias; - parsed_result.code = barcode; - parsed_result.type = 'alias'; + else { + parsed_result.encoding = rules[i].encoding; + parsed_result.type = rules[i].type; + parsed_result.value = match.value; + parsed_result.code = cur_barcode; + if (rules[i].encoding === "ean13"){ + parsed_result.base_code = this.sanitize_ean(match.base_code); } - else { - parsed_result.encoding = rules[i].encoding; - parsed_result.type = rules[i].type; - parsed_result.value = match.value - parsed_result.code = cur_barcode; - if (rules[i].encoding === "ean13"){ - parsed_result.base_code = this.sanitize_ean(match.base_code); - } - else{ - parsed_result.base_code = match.base_code; - } - return parsed_result; + else{ + parsed_result.base_code = match.base_code; } + return parsed_result; } } - return parsed_result; - }, - }); -} + } + return parsed_result; + }, +}); + +return BarcodeParser; +}); |
