From 97039fb5918426ac8cdd8c44bd46a42ebba8fdb7 Mon Sep 17 00:00:00 2001 From: Aaron Bohy Date: Wed, 5 Nov 2014 09:26:37 +0100 Subject: [PATCH] [FIX] Barcode nomenclature generalized to Code128 in PoS --- addons/point_of_sale/static/src/js/db.js | 10 +- addons/point_of_sale/static/src/js/devices.js | 180 +++++++++--------- addons/point_of_sale/static/src/js/models.js | 14 +- addons/point_of_sale/static/src/js/screens.js | 1 - addons/pos_barcodes/barcodes.py | 5 +- addons/pos_barcodes/barcodes_view.xml | 2 + addons/pos_barcodes/data/barcodes_data.xml | 55 ++++-- 7 files changed, 155 insertions(+), 112 deletions(-) diff --git a/addons/point_of_sale/static/src/js/db.js b/addons/point_of_sale/static/src/js/db.js index 90955b84149..baddf660bed 100644 --- a/addons/point_of_sale/static/src/js/db.js +++ b/addons/point_of_sale/static/src/js/db.js @@ -24,7 +24,7 @@ function openerp_pos_db(instance, module){ this.product_by_id = {}; this.product_by_ean13 = {}; this.product_by_category_id = {}; - this.product_by_reference = {}; + //this.product_by_reference = {}; this.partner_sorted = []; this.partner_by_id = {}; @@ -201,9 +201,9 @@ function openerp_pos_db(instance, module){ if(product.ean13){ this.product_by_ean13[product.ean13] = product; } - if(product.default_code){ + /*if(product.default_code){ this.product_by_reference[product.default_code] = product; - } + }*/ } }, add_packagings: function(packagings){ @@ -354,9 +354,9 @@ function openerp_pos_db(instance, module){ } return undefined; }, - get_product_by_reference: function(ref){ + /*get_product_by_reference: function(ref){ return this.product_by_reference[ref]; - }, + },*/ get_product_by_category: function(category_id){ var product_ids = this.product_by_category_id[category_id]; var list = []; diff --git a/addons/point_of_sale/static/src/js/devices.js b/addons/point_of_sale/static/src/js/devices.js index f7d25074350..ec4a50a46a7 100644 --- a/addons/point_of_sale/static/src/js/devices.js +++ b/addons/point_of_sale/static/src/js/devices.js @@ -473,17 +473,16 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal } }, - // when an ean is scanned and parsed, the callback corresponding - // to its type is called with the parsed_ean as a parameter. - // (parsed_ean is the result of parse_ean(ean)) + // when a barcode is scanned and parsed, the callback corresponding + // to its type is called with the parsed_barcode as a parameter. + // (parsed_barcode is the result of parse_barcode(barcode)) // - // callbacks is a Map of 'actions' : callback(parsed_ean) + // callbacks is a Map of 'actions' : callback(parsed_barcode) // that sets the callback for each action. if a callback for the // specified action already exists, it is replaced. // // possible actions include : // 'product' | 'cashier' | 'client' | 'discount' - set_action_callback: function(action, callback){ if(arguments.length == 2){ this.action_callback[action] = callback; @@ -501,6 +500,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal this.action_callback[action] = undefined; } }, + // returns the checksum of the ean, or -1 if the ean has not the correct length, ean must be a string ean_checksum: function(ean){ var code = ean.split(''); @@ -519,11 +519,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal total = oddsum * 3 + evensum; return Number((10 - total % 10) % 10); }, - // returns true if the ean is a valid EAN codebar 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); @@ -533,63 +529,80 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal } return ean.substr(0,12) + this.ean_checksum(ean); }, - - // attempts to interpret an ean (string encoding an ean) - // it will check its validity then return an object containing various - // information about the ean. + + // 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 ean - // - type : the type of the ean: - // 'price' | 'weight' | 'product' | 'cashier' | 'client' | 'discount' | 'error' + // - 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 ean code with all the encoding parts set to zero; the one put on + // - 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_ean: function(ean){ + parse_barcode: function(barcode){ var self = this; - var parse_result = { - encoding: 'ean13', + var parsed_result = { + encoding: '', type:'error', - code:ean, - base_code: ean, + code:barcode, + base_code: barcode, value: 0, }; if (!this.pos.nomenclature) { - return parse_result; + return parsed_result; } - if (!this.check_ean(ean)){ - return parse_result; - } + // The barcode can contain any alphanumerical character, including ( and ) + /*if (!/^[A-Za-z0-9()]+$/.test(barcode)){ + return parsed_result; + }*/ - function is_number(char){ - var n = char.charCodeAt(0); - return n >= 48 && n <= 57; - } - - function match_pattern(ean,pattern){ - for(var i = 0; i < pattern.length; i++){ + function match_pattern(barcode,pattern){ + if(barcode.length < pattern.replace(/[{}]/g, '').length){ + return false; // Match of this pattern is impossible + } + var numerical_content = false; // Used to detect when we are between { } + for(var i = 0, j = 0; i < pattern.length; i++, j++){ var p = pattern[i]; - var e = ean[i]; - if( is_number(p) && p !== e ){ + if(p === "{" || p === "}"){ + numerical_content = !numerical_content; + j--; + continue; + } + + if(!numerical_content && p !== '*' && p !== barcode[j]){ return false; } } return true; } - function get_value(ean,pattern){ + function get_value(barcode,pattern){ var value = 0; var decimals = 0; - for(var i = 0; i < pattern.length; i++){ + var numerical_content = false; + for(var i = 0, j = 0; i < pattern.length; i++, j++){ var p = pattern[i]; - var v = parseInt(ean[i]); - if( p === 'N'){ + if(!numerical_content && p !== "{"){ + continue; + } + else if(p === "{"){ + numerical_content = true; + j--; + continue; + } + else if(p === "}"){ + break; + } + + var v = parseInt(barcode[j]); + if(p === 'N'){ value *= 10; value += v; - }else if( p === 'D'){ // FIXME precision .... + }else if(p === 'D'){ // FIXME precision .... decimals += 1; value += v * Math.pow(10,-decimals); } @@ -597,65 +610,58 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal return value; } - function get_basecode(ean,pattern){ + function get_basecode(barcode,pattern,encoding){ var base = ''; - for(var i = 0; i < pattern.length; i++){ + var numerical_content = false; + for(var i = 0, j = 0; i < pattern.length; i++, j++){ var p = pattern[i]; - var v = ean[i]; - if( p === 'x' || is_number(p)){ - base += v; - }else{ + if(p === "{" || p === "}"){ + numerical_content = !numerical_content; + j--; + continue; + } + + if(numerical_content){ base += '0'; } + else{ + base += barcode[j]; + } } - return self.sanitize_ean(base); + for(i=j; i= 3){ + self.scan(code); + } code = ""; onlynumbers = true; },100); diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js index 48c26923462..debd14a5330 100644 --- a/addons/point_of_sale/static/src/js/models.js +++ b/addons/point_of_sale/static/src/js/models.js @@ -322,21 +322,21 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal }, }, { model: 'barcode.rule', - fields: ['name','sequence','type','pattern'], + fields: ['name','sequence','type','encoding','pattern'], domain: function(self){ return [['barcode_nomenclature_id','=',self.nomenclature ? self.nomenclature.id : 0]]; }, loaded: function(self,rules){ if (self.nomenclature) { rules = rules.sort(function(a,b){ return a.sequence - b.sequence; }); self.nomenclature.rules = rules; - for (var i = 0; i < rules.length; i++) { + /*for (var i = 0; i < rules.length; i++) { var pattern = rules[i].pattern; pattern = pattern.replace(/[x\*]/gi,'x'); while (pattern.length < 12) { - pattern += 'x'; + pattern += ''; } rules[i].pattern = pattern; - } + }*/ } }, }, { @@ -719,11 +719,11 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal scan_product: function(parsed_code){ var self = this; var selectedOrder = this.get_order(); - if(parsed_code.encoding === 'ean13'){ + //if(parsed_code.encoding === 'barcode'){ var product = this.db.get_product_by_ean13(parsed_code.base_code); - }else if(parsed_code.encoding === 'reference'){ + /*}else if(parsed_code.encoding === 'reference'){ var product = this.db.get_product_by_reference(parsed_code.code); - } + }*/ if(!product){ return false; diff --git a/addons/point_of_sale/static/src/js/screens.js b/addons/point_of_sale/static/src/js/screens.js index 1f577b48149..7803caa31be 100644 --- a/addons/point_of_sale/static/src/js/screens.js +++ b/addons/point_of_sale/static/src/js/screens.js @@ -233,7 +233,6 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa this.pos_widget.set_leftpane_visible(this.show_leftpane); this.pos_widget.username.set_user_mode(this.pos_widget.screen_selector.get_user_mode()); - this.pos.barcode_reader.set_action_callback({ 'cashier': self.barcode_cashier_action ? function(code){ self.barcode_cashier_action(code); } : undefined , 'product': self.barcode_product_action ? function(code){ self.barcode_product_action(code); } : undefined , diff --git a/addons/pos_barcodes/barcodes.py b/addons/pos_barcodes/barcodes.py index 481d5743a3a..6de89d53ea5 100644 --- a/addons/pos_barcodes/barcodes.py +++ b/addons/pos_barcodes/barcodes.py @@ -138,7 +138,8 @@ class barcode_rule(osv.osv): 'barcode_nomenclature_id': fields.many2one('barcode.nomenclature','Barcode Nomenclature'), 'sequence': fields.integer('Sequence', help='Used to order rules such that rules with a smaller sequence match first'), #'encoding': fields.selection([('any','Any'),('ean13','EAN-13'),('ean8','EAN-8'),('codabar','Codabar'),('upca','UPC-A'),('upce','UPC-E')],'Encoding',help='This rule will apply only if the barcode is encoded with the specified encoding'), - 'type': fields.selection([('product','Unit Product'),('weight','Weighted Product'),('price','Priced Product'),('discount','Discounted Product'),('client','Client'),('cashier','Cashier')],'Type', required=True), + 'encoding': fields.selection([('any','Any'),('ean13','EAN-13')],'Encoding',required=True,help='This rule will apply only if the barcode is encoded with the specified encoding'), + 'type': fields.selection([('product','Unit Product'),('weight','Weighted Product'),('price','Priced Product'),('discount','Discounted Product'),('client','Client'),('cashier','Cashier'),('location','Location'),('lot','Lot'),('package','Package')],'Type', required=True), 'pattern': fields.char('Barcode Pattern', size=32, help="The barcode matching pattern"), #'alias': fields.char('Alias',size=32,help='The matched pattern will alias to this barcode'), } @@ -146,5 +147,5 @@ class barcode_rule(osv.osv): _defaults = { 'type': 'product', 'pattern': '*', - #'encoding': 'any', + 'encoding': 'any', } \ No newline at end of file diff --git a/addons/pos_barcodes/barcodes_view.xml b/addons/pos_barcodes/barcodes_view.xml index d5f04fd7935..d5c68547c01 100644 --- a/addons/pos_barcodes/barcodes_view.xml +++ b/addons/pos_barcodes/barcodes_view.xml @@ -15,6 +15,7 @@ + @@ -58,6 +59,7 @@ + diff --git a/addons/pos_barcodes/data/barcodes_data.xml b/addons/pos_barcodes/data/barcodes_data.xml index 9157ed969ef..cee84980cc7 100644 --- a/addons/pos_barcodes/data/barcodes_data.xml +++ b/addons/pos_barcodes/data/barcodes_data.xml @@ -8,8 +8,9 @@ Product Barcodes - 60 + 90 product + ean13 * @@ -18,23 +19,26 @@ 50 cashier + any 041 - Client Barcodes + Customer Barcodes 40 client + any 042 - - Weight Barcodes + + Weight Barcodes 3 Decimals - 30 + 36 weight - 21*****NNDDD* + ean13 + 21*****{NNDDD}* @@ -42,15 +46,44 @@ 20 discount - 22********NN* + any + 22{NN}* - - Price Barcodes + + Price Barcodes 2 Decimals - 10 + 14 price - 23*****NNNDD* + ean13 + 23*****{NNNDD}* + + + + Package barcodes + + 70 + package + any + PACK* + + + + Lot barcodes + + 80 + lot + any + 10* + + + + Location barcodes + + 60 + location + any + 414* \ No newline at end of file