[FIX] barcodes, point_of_sale: JS functions for parsing barcode moved to module barco...
authorAaron Bohy <aab@odoo.com>
Wed, 12 Nov 2014 09:25:59 +0000 (10:25 +0100)
committerFrédéric van der Essen <fvdessen@gmail.com>
Wed, 26 Nov 2014 11:06:20 +0000 (12:06 +0100)
addons/barcodes/static/src/js/barcode_parser.js [new file with mode: 0644]
addons/barcodes/static/src/js/barcode_reader.js [deleted file]
addons/barcodes/static/src/js/main.js
addons/barcodes/views/templates.xml
addons/point_of_sale/static/src/js/devices.js
addons/point_of_sale/static/src/js/models.js

diff --git a/addons/barcodes/static/src/js/barcode_parser.js b/addons/barcodes/static/src/js/barcode_parser.js
new file mode 100644 (file)
index 0000000..e3b9ae3
--- /dev/null
@@ -0,0 +1,248 @@
+function openerp_barcode_parser(instance,module){
+
+    module.BarcodeParser = instance.web.Class.extend({
+        init: function(attributes) {
+            var self = this;
+            this.nomenclature_id = attributes.nomenclature_id;
+            this.load_server_data();
+        },
+
+        models: [
+        {
+            model: 'barcode.nomenclature',
+            fields: ['name','rule_ids'],
+            domain: function(self){ return [] },
+            loaded: function(self,nomenclatures){
+                if (self.nomenclature_id) {
+                    for (var i = 0; i < nomenclatures.length; i++) {
+                        if (nomenclatures[i].id === self.nomenclature_id[0]) {
+                            self.nomenclature = nomenclatures[i];
+                        }
+                    }
+                }
+                self.nomenclature = self.nomenclature || null;
+            },
+        }, {
+            model: 'barcode.rule',
+            fields: ['name','sequence','type','encoding','pattern','alias'],
+            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;
+                }
+            },
+        },
+        ],
+
+        // loads all the needed data on the sever. returns a deferred indicating when all the data has loaded. 
+        load_server_data: function(){
+            var self = this;
+            var loaded = new $.Deferred();
+            var progress = 0;
+            var progress_step = 1.0 / self.models.length;
+            var tmp = {}; // this is used to share a temporary state between models loaders
+
+            function load_model(index){
+                if(index >= self.models.length){
+                    loaded.resolve();
+                }else{
+                    var model = self.models[index];
+                    //self.pos_widget.loading_message(_t('Loading')+' '+(model.label || model.model || ''), progress);
+
+                    var cond = typeof model.condition === 'function'  ? model.condition(self,tmp) : true;
+                    if (!cond) {
+                        load_model(index+1);
+                        return;
+                    }
+
+                    var fields =  typeof model.fields === 'function'  ? model.fields(self,tmp)  : model.fields;
+                    var domain =  typeof model.domain === 'function'  ? model.domain(self,tmp)  : model.domain;
+                    var context = typeof model.context === 'function' ? model.context(self,tmp) : model.context; 
+                    progress += progress_step;
+                    
+                    if( model.model ){
+                        new instance.web.Model(model.model).query(fields).filter(domain).context(context).all()
+                            .then(function(result){
+                                try{    // catching exceptions in model.loaded(...)
+                                    $.when(model.loaded(self,result,tmp))
+                                        .then(function(){ load_model(index + 1); },
+                                              function(err){ loaded.reject(err); });
+                                }catch(err){
+                                    console.error(err.stack);
+                                    loaded.reject(err);
+                                }
+                            },function(err){
+                                loaded.reject(err);
+                            });
+                    }else if( model.loaded ){
+                        try{    // catching exceptions in model.loaded(...)
+                            $.when(model.loaded(self,tmp))
+                                .then(  function(){ load_model(index +1); },
+                                        function(err){ loaded.reject(err); });
+                        }catch(err){
+                            loaded.reject(err);
+                        }
+                    }else{
+                        load_model(index + 1);
+                    }
+                }
+            }
+
+            try{
+                load_model(0);
+            }catch(err){
+                loaded.reject(err);
+            }
+            return 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]);
+                }
+            }
+            total = oddsum * 3 + evensum;
+            return Number((10 - total % 10) % 10);
+        },
+
+        // 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);
+        },
+                
+        // 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 self = this;
+            var parsed_result = {
+                encoding: '',
+                type:'error',  
+                code:barcode,
+                base_code: barcode,
+                value: 0,
+            };
+            if (!self.nomenclature) {
+                return parsed_result;
+            }
+
+            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];
+                    if(p === "{" || p === "}"){
+                        numerical_content = !numerical_content;
+                        j--;
+                        continue;
+                    }
+                    
+                    if(!numerical_content && p !== '*' && p !== barcode[j]){
+                        return false;
+                    }
+                }
+                return true;
+            }
+            
+            function get_value(barcode,pattern){
+                var value = 0;
+                var decimals = 0;
+                var numerical_content = false;
+                for(var i = 0, j = 0; i < pattern.length; i++, j++){
+                    var p = pattern[i];
+                    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 ....
+                        decimals += 1;
+                        value += v * Math.pow(10,-decimals);
+                    }
+                }
+                return value;
+            }
+
+            function get_basecode(barcode,pattern,encoding){
+                var base = '';
+                var numerical_content = false;
+                for(var i = 0, j = 0; i < pattern.length; i++, j++){
+                    var p = pattern[i];
+                    if(p === "{" || p === "}"){
+                        numerical_content = !numerical_content;
+                        j--;
+                        continue;
+                    }
+
+                    if(numerical_content){
+                        base += '0';
+                    }
+                    else{
+                        base += barcode[j];
+                    }
+                }
+                for(i=j; i<barcode.length; i++){ // Read the rest of the barcode
+                    base += barcode[i];
+                }
+                if(encoding === "ean13"){
+                    base = self.sanitize_ean(base);
+                }
+                return base;
+            }
+
+            var rules = self.nomenclature.rules;
+            for (var i = 0; i < rules.length; i++) {
+                if (match_pattern(barcode,rules[i].pattern)) {
+                    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     = get_value(barcode,rules[i].pattern);
+                        parsed_result.base_code = get_basecode(barcode,rules[i].pattern,parsed_result.encoding);
+                        return parsed_result;
+                    }
+                }
+            }
+            return parsed_result;
+        },
+    });
+}
\ No newline at end of file
diff --git a/addons/barcodes/static/src/js/barcode_reader.js b/addons/barcodes/static/src/js/barcode_reader.js
deleted file mode 100644 (file)
index bcf41f5..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-function openerp_barcode_reader(instance,module){
-
-    module.BarcodeReader = instance.web.Class.extend({
-        // 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]);
-                }
-            }
-            total = oddsum * 3 + evensum;
-            return Number((10 - total % 10) % 10);
-        },
-
-        // 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);
-        },
-                
-        // 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, nomenclature){
-            var self = this;
-            var parsed_result = {
-                encoding: '',
-                type:'error',  
-                code:barcode,
-                base_code: barcode,
-                value: 0,
-            };
-            
-            if (!nomenclature) {
-                return parsed_result;
-            }
-
-            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];
-                    if(p === "{" || p === "}"){
-                        numerical_content = !numerical_content;
-                        j--;
-                        continue;
-                    }
-                    
-                    if(!numerical_content && p !== '*' && p !== barcode[j]){
-                        return false;
-                    }
-                }
-                return true;
-            }
-            
-            function get_value(barcode,pattern){
-                var value = 0;
-                var decimals = 0;
-                var numerical_content = false;
-                for(var i = 0, j = 0; i < pattern.length; i++, j++){
-                    var p = pattern[i];
-                    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 ....
-                        decimals += 1;
-                        value += v * Math.pow(10,-decimals);
-                    }
-                }
-                return value;
-            }
-
-            function get_basecode(barcode,pattern,encoding){
-                var base = '';
-                var numerical_content = false;
-                for(var i = 0, j = 0; i < pattern.length; i++, j++){
-                    var p = pattern[i];
-                    if(p === "{" || p === "}"){
-                        numerical_content = !numerical_content;
-                        j--;
-                        continue;
-                    }
-
-                    if(numerical_content){
-                        base += '0';
-                    }
-                    else{
-                        base += barcode[j];
-                    }
-                }
-                for(i=j; i<barcode.length; i++){ // Read the rest of the barcode
-                    base += barcode[i];
-                }
-                if(encoding === "ean13"){
-                    base = self.sanitize_ean(base);
-                }
-                return base;
-            }
-
-            var rules = nomenclature.rules;
-            for (var i = 0; i < rules.length; i++) {
-                if (match_pattern(barcode,rules[i].pattern)) {
-                    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     = get_value(barcode,rules[i].pattern);
-                        parsed_result.base_code = get_basecode(barcode,rules[i].pattern,parsed_result.encoding);
-                        return parsed_result;
-                    }
-                }
-            }
-            return parsed_result;
-        },
-    });
-}
\ No newline at end of file
index d90d1ce..69e702e 100644 (file)
@@ -2,8 +2,8 @@
 openerp.barcodes = function(instance) {
     "use strict";
 
-    instance.barcode_reader = {};
-    var module = instance.barcode_reader;
+    instance.barcode_parser = {};
+    var module = instance.barcode_parser;
 
-    openerp_barcode_reader(instance,module);         // import barcodes.js
+    openerp_barcode_parser(instance,module);         // import barcodes.js
 };
index 257ac35..965eab7 100644 (file)
@@ -6,7 +6,7 @@
 
        <template id="assets_backend" name="barcodes assets" inherit_id="web.assets_backend">
             <xpath expr="." position="inside">
-                <script type="text/javascript" src="/barcodes/static/src/js/barcode_reader.js"></script>
+                <script type="text/javascript" src="/barcodes/static/src/js/barcode_parser.js"></script>
                 <script type="text/javascript" src="/barcodes/static/src/js/main.js"></script>
             </xpath>
         </template>
index 23934f0..7ca14d1 100644 (file)
@@ -3,7 +3,6 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
     "use strict";
 
        var _t = instance.web._t;
-    var barcode_reader_module = instance.barcode_reader;
 
     // the JobQueue schedules a sequence of 'jobs'. each job is
     // a function returning a deferred. the queue waits for each job to finish 
@@ -442,8 +441,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
     // is set-up to act like  a keyboard. Use connect() and disconnect() to activate 
     // and deactivate the barcode reader. Use set_action_callbacks to tell it
     // what to do when it reads a barcode.
-    //module.BarcodeReader = instance.web.Class.extend({
-    barcode_reader_module.BarcodeReader.include({
+    module.BarcodeReader = instance.web.Class.extend({
         actions:[
             'product',
             'cashier',
@@ -457,9 +455,15 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
             this.remote_scanning = false;
             this.remote_active = 0;
 
+            this.barcode_parser = attributes.barcode_parser;
+
             this.action_callback_stack = [];
         },
 
+        set_barcode_parser: function(barcode_parser) {
+            this.barcode_parser = barcode_parser;
+        },
+
         save_callbacks: function(){
             var callbacks = {};
             for(var name in this.action_callback){
@@ -504,8 +508,12 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
         },
 
         scan: function(code){
-            var parsed_result = this.pos.barcode_reader.parse_barcode(code, this.pos.nomenclature);
-
+            if(this.barcode_parser) {
+                var parsed_result = this.barcode_parser.parse_barcode(code);
+            }
+            else{
+                console.error("Barcode Parser not yet initialized!");
+            }
             if(parsed_result.type in {'product':'', 'weight':'', 'price':''}){    //barcode is associated to a product
                 if(this.action_callback['product']){
                     this.action_callback['product'](parsed_result);
index 2381734..39415f5 100644 (file)
@@ -3,7 +3,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
 
     var QWeb = instance.web.qweb;
        var _t = instance.web._t;
-    var barcode_reader_module = instance.barcode_reader;
+    var barcode_parser_module = instance.barcode_parser;
 
     var round_di = instance.web.round_decimals;
     var round_pr = instance.web.round_precision
@@ -27,8 +27,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
             this.pos_widget = attributes.pos_widget;
 
             this.proxy = new module.ProxyDevice(this);              // used to communicate to the hardware devices via a local proxy
-
-            this.barcode_reader = new barcode_reader_module.BarcodeReader({'pos': this, proxy:this.proxy});  // used to read barcodes
+            this.barcode_reader = new module.BarcodeReader({'pos': this, proxy:this.proxy});
 
             this.proxy_queue = new module.JobQueue();           // used to prevent parallels communications to the proxy
             this.db = new module.PosDB();                       // a local database used to search trough products and categories & store pending orders
@@ -81,6 +80,9 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
             // when all the data has loaded, we compute some stuff, and declare the Pos ready to be used. 
             this.ready = this.load_server_data()
                 .then(function(){
+                    var barcode_parser = new barcode_parser_module.BarcodeParser({'nomenclature_id': self.config.barcode_nomenclature_id});
+                    self.barcode_reader.set_barcode_parser(barcode_parser);
+                    
                     if(self.config.use_proxy){
                         return self.connect_to_proxy();
                     }
@@ -366,31 +368,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
 
                 return logo_loaded;
             },
-        }, {
-            model: 'barcode.nomenclature',
-            fields: ['name','rule_ids'],
-            domain: function(self){ return [] },
-            loaded: function(self,nomenclatures){
-                if (self.config.barcode_nomenclature_id) {
-                    for (var i = 0; i < nomenclatures.length; i++) {
-                        if (nomenclatures[i].id === self.config.barcode_nomenclature_id[0]) {
-                            self.nomenclature = nomenclatures[i];
-                        }
-                    }
-                }
-                self.nomenclature = self.nomenclature || null;
-            },
-        }, {
-            model: 'barcode.rule',
-            fields: ['name','sequence','type','encoding','pattern','alias'],
-            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;
-                }
-            },
-        },
+        }, 
         ],
 
         // loads all the needed data on the sever. returns a deferred indicating when all the data has loaded.