[IMP] point_of_sale: DAO removed, db used for orders instead. Don't stop sending...
authorFrédéric van der Essen <fva@openerp.com>
Tue, 14 Aug 2012 15:21:12 +0000 (17:21 +0200)
committerFrédéric van der Essen <fva@openerp.com>
Tue, 14 Aug 2012 15:21:12 +0000 (17:21 +0200)
bzr revid: fva@openerp.com-20120814152112-vmitvbajx3r2mdeh

addons/point_of_sale/static/src/js/pos_db.js
addons/point_of_sale/static/src/js/pos_models.js
addons/point_of_sale/static/src/js/pos_screens.js

index 3dda03f..0992c66 100644 (file)
@@ -136,9 +136,10 @@ function openerp_pos_db(instance, module){
             this.save('categories',stored_categories);
         },
         /* removes all the data from the database. TODO : being able to selectively remove data */
-        clear: function(){
-            localStorage.removeItem(this.name + '_products');
-            localStorage.removeItem(this.name + '_categories');
+        clear: function(stores){
+            for(var i = 0, len = arguments.length; i < len; i++){
+                localStorage.removeItem(this.name + '_' + arguments[i]);
+            }
         },
         /* this internal methods returns the count of properties in an object. */
         _count_props : function(obj){
@@ -226,53 +227,4 @@ function openerp_pos_db(instance, module){
             return this.load('orders',[]);
         },
     });
-    /*
-    module.LocalStorageDAO = instance.web.Class.extend({
-        add_operation: function(operation) {
-            var self = this;
-            return $.async_when().pipe(function() {
-                var tmp = self._get('oe_pos_operations', []);
-                var last_id = self._get('oe_pos_operations_sequence', 1);
-                tmp.push({'id': last_id, 'data': operation});
-                self._set('oe_pos_operations', tmp);
-                self._set('oe_pos_operations_sequence', last_id + 1);
-            });
-        },
-        remove_operation: function(id) {
-            var self = this;
-            return $.async_when().pipe(function() {
-                var tmp = self._get('oe_pos_operations', []);
-                tmp = _.filter(tmp, function(el) {
-                    return el.id !== id;
-                });
-                self._set('oe_pos_operations', tmp);
-            });
-        },
-        get_operations: function() {
-            var self = this;
-            return $.async_when().pipe(function() {
-                return self._get('oe_pos_operations', []);
-            });
-        },
-        _get: function(key, default_) {
-            var txt = localStorage['oe_pos_dao_'+key];
-            if (! txt)
-                return default_;
-            return JSON.parse(txt);
-        },
-        _set: function(key, value) {
-            localStorage['oe_pos_dao_'+key] = JSON.stringify(value);
-        },
-        reset_stored_data: function(){
-            for(key in localStorage){
-                if(key.indexOf('oe_pos_dao_') === 0){
-                    delete localStorage[key];
-                }
-            }
-            0497 53 82 88
-        },
-    });
-    */
-
-    window.PosLS = module.PosLS;
 }
index 0f4d1b8..2be3043 100644 (file)
@@ -1,51 +1,6 @@
 function openerp_pos_models(instance, module){ //module is instance.point_of_sale
     var QWeb = instance.web.qweb;
 
-    module.LocalStorageDAO = instance.web.Class.extend({
-        add_operation: function(operation) {
-            var self = this;
-            return $.async_when().pipe(function() {
-                var tmp = self._get('oe_pos_operations', []);
-                var last_id = self._get('oe_pos_operations_sequence', 1);
-                tmp.push({'id': last_id, 'data': operation});
-                self._set('oe_pos_operations', tmp);
-                self._set('oe_pos_operations_sequence', last_id + 1);
-            });
-        },
-        remove_operation: function(id) {
-            var self = this;
-            return $.async_when().pipe(function() {
-                var tmp = self._get('oe_pos_operations', []);
-                tmp = _.filter(tmp, function(el) {
-                    return el.id !== id;
-                });
-                self._set('oe_pos_operations', tmp);
-            });
-        },
-        get_operations: function() {
-            var self = this;
-            return $.async_when().pipe(function() {
-                return self._get('oe_pos_operations', []);
-            });
-        },
-        _get: function(key, default_) {
-            var txt = localStorage['oe_pos_dao_'+key];
-            if (! txt)
-                return default_;
-            return JSON.parse(txt);
-        },
-        _set: function(key, value) {
-            localStorage['oe_pos_dao_'+key] = JSON.stringify(value);
-        },
-        reset_stored_data: function(){
-            for(key in localStorage){
-                if(key.indexOf('oe_pos_dao_') === 0){
-                    delete localStorage[key];
-                }
-            }
-        },
-    });
-
     var fetch = function(model, fields, domain, ctx){
         return new instance.web.Model(model).query(fields).filter(domain).context(ctx).all()
     };
@@ -58,7 +13,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
     // this is done asynchronously, a ready deferred alows the GUI to wait interactively 
     // for the loading to be completed 
     // There is a single instance of the PosModel for each Front-End instance, it is usually called
-    // 'pos' and is available to almost all widgets.
+    // 'pos' and is available to all widgets extending PosWidget.
 
     module.PosModel = Backbone.Model.extend({
         initialize: function(session, attributes) {
@@ -72,7 +27,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
             this.barcode_reader = new module.BarcodeReader({'pos': this});  // used to read barcodes
             this.proxy = new module.ProxyDevice();              // used to communicate to the hardware devices via a local proxy
             this.db = new module.PosLS();                       // a database used to store the products and categories
-            this.db.clear();
+            this.db.clear('products','categories');
 
             window.db = this.db;
 
@@ -309,10 +264,13 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
 
         // saves the order locally and try to send it to the backend. 'record' is a bizzarely defined JSON version of the Order
         push_order: function(record) {
-            var self = this;
+            this.db.add_order(record);
+            this.flush();
+            /*
             return this.dao.add_operation(record).pipe(function(){
                 return self.flush();
             });
+            */
         },
 
         //creates a new empty order and sets it as the current order
@@ -322,47 +280,40 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
             this.set('selectedOrder', order);
         },
 
-        // attemps to send all pending orders ( stored in the DAO ) to the server.
-        // it will do it one by one, and remove the successfully sent ones from the DAO once
-        // it has been confirmed that they have been received.
+        // attemps to send all pending orders ( stored in the pos_db ) to the server,
+        // and remove the successfully sent ones from the db once
+        // it has been confirmed that they have been sent correctly.
         flush: function() {
             //this makes sure only one _int_flush is called at the same time
             return this.flush_mutex.exec(_.bind(function() {
-                return this._int_flush();
+                return this._flush(0);
             }, this));
         },
-        _int_flush : function() {
+        // attempts to send an order of index 'index' in the list of order to send. The index
+        // is used to skip orders that failed. do not call this method outside the mutex provided
+        // by flush() 
+        _flush: function(index){
             var self = this;
+            var orders = this.db.get_orders();
+            self.set('nbr_pending_operations',orders.length);
 
-            this.dao.get_operations().pipe(function(operations) {
-                // operations are really Orders that are converted to json.
-                // they are saved to disk and then we attempt to send them to the backend so that they can
-                // be applied. 
-                // since the network is not reliable we potentially have many 'pending operations' that have not been sent.
-                self.set( {'nbr_pending_operations':operations.length} );
-                if(operations.length === 0){
-                    return $.when();
-                }
-                var order = operations[0];
-
-                 // we prevent the default error handler and assume errors
-                 // are a normal use case, except we stop the current iteration
-
-                 return (new instance.web.Model('pos.order')).get_func('create_from_ui')([order])
-                            .fail(function(unused, event){
-                                // wtf ask niv
-                                event.preventDefault();
-                            })
-                            .pipe(function(){
-                                // success: remove the successfully sent operation, and try to send the next one 
-                                self.dao.remove_operation(operations[0].id).pipe(function(){
-                                    return self._int_flush();
-                                });
-                            }, function(){
-                                // in case of error we just sit there and do nothing. wtf ask niv
-                                return $.when();
-                            });
-            });
+            var order  = orders[index];
+            if(!order){
+                return;
+            }
+            //try to push an order to the server
+            (new instance.web.Model('pos.order')).get_func('create_from_ui')([order])
+                .fail(function(unused, event){
+                    //don't show error popup if it fails (I guess, copy pasted from niv without understanding it completely)
+                    event.preventDefault();
+                    console.error('Failed to send order:',order);
+                    self._flush(index+1);
+                })
+                .done(function(){
+                    //remove from db if success
+                    self.db.remove_order(order.id);
+                    self._flush(index);
+                });
         },
 
         scan_product: function(parsed_ean){
index 659ee09..115c157 100644 (file)
@@ -748,26 +748,15 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
             this.pos_widget.screen_selector.set_current_screen(self.back_screen);
         },
         validateCurrentOrder: function() {
-            var self = this;
             var currentOrder = this.pos.get('selectedOrder');
-            if(this.busy){
-                return;
-            }else{
-                this.busy = true;
-            }
-            this.validate_button.$element.addClass('disabled');
 
             this.pos.push_order(currentOrder.exportAsJSON()) 
-                .then(function() {
-                    if(self.pos.use_proxy_printer){
-                        self.pos.proxy.print_receipt(currentOrder.export_for_printing());
-                        self.pos.get('selectedOrder').destroy();    //finish order and go back to scan screen
-                    }else{
-                        self.pos_widget.screen_selector.set_current_screen(self.next_screen);
-                    }
-                    self.validate_button.$element.removeClass('disabled');
-                    self.busy = false;
-                });
+            if(this.pos.use_proxy_printer){
+                this.pos.proxy.print_receipt(currentOrder.export_for_printing());
+                this.pos.get('selectedOrder').destroy();    //finish order and go back to scan screen
+            }else{
+                this.pos_widget.screen_selector.set_current_screen(this.next_screen);
+            }
         },
         bindPaymentLineEvents: function() {
             this.currentPaymentLines = (this.pos.get('selectedOrder')).get('paymentLines');