diff options
| author | Aaron Bohy <aab@odoo.com> | 2014-11-13 17:22:56 +0100 |
|---|---|---|
| committer | Frédéric van der Essen <fvdessen@gmail.com> | 2014-11-26 12:06:23 +0100 |
| commit | aae9dfe4e70c4a17764ad7810fd5d6293a689741 (patch) | |
| tree | 5a1deb9cf79f94c12d7d4268cc1c8033b0fd3ef4 /addons/barcodes | |
| parent | 825a938d0f673580f3d2a57932a1d5cfe741347d (diff) | |
[FIX] barcodes: prepend a zero to ean13 barcodes scanned before looking for a match
Diffstat (limited to 'addons/barcodes')
| -rw-r--r-- | addons/barcodes/barcodes.py | 38 | ||||
| -rw-r--r-- | addons/barcodes/barcodes_view.xml | 1 | ||||
| -rw-r--r-- | addons/barcodes/static/src/js/barcode_parser.js | 25 |
3 files changed, 52 insertions, 12 deletions
diff --git a/addons/barcodes/barcodes.py b/addons/barcodes/barcodes.py index 9b2161c738d..5e2bf61a56b 100644 --- a/addons/barcodes/barcodes.py +++ b/addons/barcodes/barcodes.py @@ -33,10 +33,19 @@ _logger = logging.getLogger(__name__) class barcode_nomenclature(osv.osv): _name = 'barcode.nomenclature' _columns = { - 'name': fields.char('Nomenclature Name', size=32, required=True, help='An internal identification of the barcode nomenclature'), - 'rule_ids': fields.one2many('barcode.rule','barcode_nomenclature_id','Rules', help='The list of barcode rules'), + 'name': fields.char('Nomenclature Name', size=32, required=True, help='An internal identification of the barcode nomenclature'), + 'rule_ids': fields.one2many('barcode.rule','barcode_nomenclature_id','Rules', help='The list of barcode rules'), + 'strict_ean': fields.boolean('Use strict EAN13', + help='Many barcode scanners strip the leading zero of EAN13 barcodes. By using strict EAN13, we consider the scanned barcode directly. Otherwise, we prepend scanned barcodes of length 12 by a zero before looking for the associated item.') } + _defaults = { + 'strict_ean': False, + } + + def use_strict_ean(self): + return self.strict_ean + # returns the checksum of the ean13, or -1 if the ean has not the correct length, ean must be a string def ean_checksum(self, ean): code = list(ean) @@ -52,6 +61,10 @@ class barcode_nomenclature(osv.osv): oddsum += int(code[i]) total = oddsum * 3 + evensum return int((10 - total % 10) % 10) + + # returns true if the barcode is a valid EAN barcode + def check_ean(self, ean): + return re.match("^\d+$", ean) and self.ean_checksum(ean) == int(ean[len(ean)-1]) # Returns a valid zero padded ean13 from an ean prefix. the ean prefix must be a string. def sanitize_ean(self, ean): @@ -64,8 +77,6 @@ class barcode_nomenclature(osv.osv): # most importantly : # - code : the barcode # - type : the type of the barcode: - # 'price' | 'weight' | 'product' | 'cashier' | 'client' | 'discount' | 'lot' | - # 'package' | 'location' | 'error' # - value : if the id encodes a numerical value, it will be put there # - base_code : the barcode code with all the encoding parts set to zero; the one put on # the product in the backend @@ -76,7 +87,7 @@ class barcode_nomenclature(osv.osv): 'code': barcode, 'base_code': barcode, 'value': 0} - + def match_pattern(barcode,pattern): if(len(barcode) < len(pattern.replace('{','').replace('}',''))): return False # match of this pattern is impossible @@ -145,17 +156,28 @@ class barcode_nomenclature(osv.osv): for rule in self.rule_ids: rules.append({'type': rule.type, 'encoding': rule.encoding, 'sequence': rule.sequence, 'pattern': rule.pattern, 'alias': rule.alias}) + # If the nomenclature does not use strict EAN, prepend the barcode with a 0 if it seems + # that it has been striped by the barcode scanner, when trying to match an EAN13 rule + prepend_zero = False + if not self.strict_ean and len(barcode) == 12 and self.check_ean("0"+barcode): + prepend_zero = True + for rule in rules: - if match_pattern(barcode, rule['pattern']): + cur_barcode = barcode + if prepend_zero and rule['encoding'] == "ean13": + cur_barcode = '0'+cur_barcode + if match_pattern(cur_barcode, rule['pattern']): if rule['type'] == 'alias': barcode = rule['alias'] parsed_result['code'] = barcode else: parsed_result['encoding'] = rule['encoding'] parsed_result['type'] = rule['type'] - parsed_result['value'] = get_value(barcode, rule['pattern']) - parsed_result['base_code'] = get_basecode(barcode, rule['pattern'], parsed_result['encoding']) + parsed_result['value'] = get_value(cur_barcode, rule['pattern']) + parsed_result['code'] = cur_barcode + parsed_result['base_code'] = get_basecode(cur_barcode, rule['pattern'], parsed_result['encoding']) return parsed_result + return parsed_result class barcode_rule(models.Model): diff --git a/addons/barcodes/barcodes_view.xml b/addons/barcodes/barcodes_view.xml index e799ab43563..7667a3dc492 100644 --- a/addons/barcodes/barcodes_view.xml +++ b/addons/barcodes/barcodes_view.xml @@ -10,6 +10,7 @@ <sheet> <group col="4"> <field name="name" /> + <field name="strict_ean"/> </group> <field name="rule_ids"> <tree string='Tables'> diff --git a/addons/barcodes/static/src/js/barcode_parser.js b/addons/barcodes/static/src/js/barcode_parser.js index 8a8c2ff5399..18823d645de 100644 --- a/addons/barcodes/static/src/js/barcode_parser.js +++ b/addons/barcodes/static/src/js/barcode_parser.js @@ -18,7 +18,7 @@ openerp.barcodes = function(instance) { models: [ { model: 'barcode.nomenclature', - fields: ['name','rule_ids'], + fields: ['name','rule_ids', 'strict_ean'], domain: function(self){ return [] }, loaded: function(self,nomenclatures){ if (self.nomenclature_id) { @@ -124,6 +124,12 @@ openerp.barcodes = function(instance) { 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 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); @@ -233,9 +239,19 @@ openerp.barcodes = function(instance) { return base; } + // If the nomenclature does not use strict EAN, prepend the barcode with a 0 if it seems + // that it has been striped by the barcode scanner, when trying to match an EAN13 rule + var prepend_zero = false; + if(!self.strict_ean && barcode.length === 12 && self.check_ean("0"+barcode)){ + prepend_zero = true; + } var rules = self.nomenclature.rules; for (var i = 0; i < rules.length; i++) { - if (match_pattern(barcode,rules[i].pattern)) { + var cur_barcode = barcode; + if (prepend_zero && rules[i].encoding == 'ean13'){ + cur_barcode = '0'+cur_barcode; + } + if (match_pattern(cur_barcode,rules[i].pattern)) { if(rules[i].type === 'alias') { barcode = rules[i].alias; parsed_result.code = barcode; @@ -244,8 +260,9 @@ openerp.barcodes = function(instance) { else { parsed_result.encoding = rules[i].encoding; parsed_result.type = rules[i].type; - parsed_result.value = get_value(barcode,rules[i].pattern); - parsed_result.base_code = get_basecode(barcode,rules[i].pattern,parsed_result.encoding); + parsed_result.value = get_value(cur_barcode,rules[i].pattern); + parsed_result.code = cur_barcode; + parsed_result.base_code = get_basecode(cur_barcode,rules[i].pattern,parsed_result.encoding); return parsed_result; } } |
