[FIX] point_of_sale: missing commits from last backport from trunk
authorFrédéric van der Essen <fva@openerp.com>
Mon, 18 Nov 2013 09:39:20 +0000 (10:39 +0100)
committerFrédéric van der Essen <fva@openerp.com>
Mon, 18 Nov 2013 09:39:20 +0000 (10:39 +0100)
bzr revid: fva@openerp.com-20131118093920-pz96e91clsfy6exd

addons/point_of_sale/static/src/css/pos.css
addons/point_of_sale/static/src/img/open-cashbox.png [new file with mode: 0644]
addons/point_of_sale/static/src/js/screens.js
addons/point_of_sale/static/src/js/widgets.js
addons/point_of_sale/static/src/xml/pos.xml

index da8325c..89ab429 100644 (file)
@@ -97,6 +97,9 @@
 .point-of-sale .pos-right-align {
     text-align: right;
 }
+.point-of-sale .pos-center-align {
+    text-align: center;
+}
 .point-of-sale .pos-right-align input {
     text-align: right;
     border: 1px solid #cecbcb;
 }
 
 @media print {
+    .point-of-sale{
+        background: white !important;
+    }
     .point-of-sale #topheader, .point-of-sale #leftpane {
         display: none !important;
     }
     .pos-actionbar {
         display: none !important;
     }
-    .pos-sale-ticket {
-        margin: 0;
-    }
     .debug-widget{
         display: none !important;
     }
         background: transparent !important;
     }
     .point-of-sale .pos-sale-ticket{
+        margin: 0;
         margin-left: auto !important;
         margin-right: auto !important;
-        border: solid 1px black !important;
+        border: none !important;
+        font-size: 13px !important;
+        width: 266px !important;
     }
 }
 
diff --git a/addons/point_of_sale/static/src/img/open-cashbox.png b/addons/point_of_sale/static/src/img/open-cashbox.png
new file mode 100644 (file)
index 0000000..1e07b0a
Binary files /dev/null and b/addons/point_of_sale/static/src/img/open-cashbox.png differ
index a5017d5..01ccd53 100644 (file)
@@ -160,29 +160,29 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
         // what happens when a product is scanned : 
         // it will add the product to the order and go to barcode_product_screen. Or show barcode_product_error_popup if 
         // there's an error.
-        barcode_product_action: function(ean){
+        barcode_product_action: function(code){
             var self = this;
-            if(self.pos.scan_product(ean)){
-                self.pos.proxy.scan_item_success(ean);
+            if(self.pos.scan_product(code)){
+                self.pos.proxy.scan_item_success(code);
                 if(self.barcode_product_screen){ 
                     self.pos_widget.screen_selector.set_current_screen(self.barcode_product_screen);
                 }
             }else{
-                self.pos.proxy.scan_item_error_unrecognized(ean);
+                self.pos.proxy.scan_item_error_unrecognized(code);
                 if(self.barcode_product_error_popup && self.pos_widget.screen_selector.get_user_mode() !== 'cashier'){
                     self.pos_widget.screen_selector.show_popup(self.barcode_product_error_popup);
                 }
             }
         },
-        
+
         // what happens when a cashier id barcode is scanned.
         // the default behavior is the following : 
         // - if there's a user with a matching ean, put it as the active 'cashier', go to cashier mode, and return true
         // - else : do nothing and return false. You probably want to extend this to show and appropriate error popup... 
-        barcode_cashier_action: function(ean){
+        barcode_cashier_action: function(code){
             var users = this.pos.get('user_list');
             for(var i = 0, len = users.length; i < len; i++){
-                if(users[i].ean13 === ean.ean){
+                if(users[i].ean13 === code.code){
                     this.pos.set('cashier',users[i]);
                     this.pos_widget.username.refresh();
                     this.pos.proxy.cashier_mode_activated();
@@ -190,7 +190,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
                     return true;
                 }
             }
-            this.pos.proxy.scan_item_error_unrecognized(ean);
+            this.pos.proxy.scan_item_error_unrecognized(code);
             return false;
         },
         
@@ -198,28 +198,28 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
         // the default behavior is the following : 
         // - if there's a user with a matching ean, put it as the active 'client' and return true
         // - else : return false. 
-        barcode_client_action: function(ean){
+        barcode_client_action: function(code){
             var partners = this.pos.get('partner_list');
             for(var i = 0, len = partners.length; i < len; i++){
-                if(partners[i].ean13 === ean.ean){
+                if(partners[i].ean13 === code.code){
                     this.pos.get('selectedOrder').set_client(partners[i]);
                     this.pos_widget.username.refresh();
-                    this.pos.proxy.scan_item_success(ean);
+                    this.pos.proxy.scan_item_success(code);
                     return true;
                 }
             }
-            this.pos.proxy.scan_item_error_unrecognized(ean);
+            this.pos.proxy.scan_item_error_unrecognized(code);
             return false;
             //TODO start the transaction
         },
         
         // what happens when a discount barcode is scanned : the default behavior
         // is to set the discount on the last order.
-        barcode_discount_action: function(ean){
-            this.pos.proxy.scan_item_success(ean);
+        barcode_discount_action: function(code){
+            this.pos.proxy.scan_item_success(code);
             var last_orderline = this.pos.get('selectedOrder').getLastOrderline();
             if(last_orderline){
-                last_orderline.set_discount(ean.value)
+                last_orderline.set_discount(code.value)
             }
         },
 
@@ -292,10 +292,10 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
             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(ean){ self.barcode_cashier_action(ean); } : undefined ,
-                'product': self.barcode_product_action ? function(ean){ self.barcode_product_action(ean); } : undefined ,
-                'client' : self.barcode_client_action ?  function(ean){ self.barcode_client_action(ean);  } : undefined ,
-                'discount': self.barcode_discount_action ? function(ean){ self.barcode_discount_action(ean); } : undefined,
+                '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 ,
+                'client' : self.barcode_client_action ?  function(code){ self.barcode_client_action(code);  } : undefined ,
+                'discount': self.barcode_discount_action ? function(code){ self.barcode_discount_action(code); } : undefined,
             });
         },
 
@@ -405,7 +405,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
             this.pos.barcode_reader.save_callbacks();
             this.pos.barcode_reader.reset_action_callbacks();
             this.pos.barcode_reader.set_action_callback({
-                'cashier': function(ean){
+                'cashier': function(code){
                     clearInterval(this.intervalID);
                     self.pos.proxy.cashier_mode_activated();
                     self.pos_widget.screen_selector.set_user_mode('cashier');
@@ -683,14 +683,14 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
 
         show_numpad:     false,
         show_leftpane:   false,
-        barcode_product_action: function(ean){
+        barcode_product_action: function(code){
             this.pos.proxy.transaction_start();
-            this._super(ean);
+            this._super(code);
         },
 
-        barcode_client_action: function(ean){
+        barcode_client_action: function(code){
             this.pos.proxy.transaction_start();
-            this._super(ean);
+            this._super(code);
             $('.goodbye-message').addClass('oe_hidden');
             this.pos_widget.screen_selector.show_popup('choose-receipt');
         },
@@ -873,8 +873,8 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
             this._super();
             var self = this;
 
-            if(this.pos.iface_cashdrawer){
-                this.pos.proxy.open_cashbox();
+            if( this.pos.iface_cashdrawer && this.pos.get('selectedOrder').get('paymentLines').find(                function(pl){ return pl.cashregister.get('journal').type === 'cash'; })){
+                    this.pos.proxy.open_cashbox();
             }
 
             this.set_numpad_state(this.pos_widget.numpad.state);
@@ -883,6 +883,11 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
                     label: _t('Back'),
                     icon: '/point_of_sale/static/src/img/icons/png48/go-previous.png',
                     click: function(){  
+                        _.each(self.paymentlinewidgets, function(widget){
+                            if( widget.payment_line.get_amount() === 0 ){
+                                widget.payment_line.destroy();
+                            }
+                        });
                         self.pos_widget.screen_selector.set_current_screen(self.back_screen);
                     },
                 });
@@ -907,6 +912,17 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
                     });
             }
 
+            if( this.pos.iface_cashdrawer ){
+                this.add_action_button({
+                        label: _t('Cash'),
+                        name: 'cashbox',
+                        icon: '/point_of_sale/static/src/img/open-cashbox.png',
+                        click: function(){
+                            self.pos.proxy.open_cashbox();
+                        },
+                    });
+            }
+
             this.updatePaymentSummary();
             this.line_refocus();
         },
index cfec71b..866e3c7 100644 (file)
@@ -143,7 +143,7 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
             var self = this;
             this._super();
             this.$el.click(function(){
-                self.order.selectLine(this.model);
+                self.order.selectLine(self.model);
                 self.trigger('order_line_selected');
             });
             if(this.model.is_selected()){
@@ -516,7 +516,6 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
                     var cat = self.pos.db.get_category_by_id(id);
                     self.set_category(cat);
                     self.renderElement();
-                    self.search_and_categories(cat);
                 });
             });
             // breadcrumb click actions
@@ -525,12 +524,13 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
                 var category = self.pos.db.get_category_by_id(id);
                 self.set_category(category);
                 self.renderElement();
-                self.search_and_categories(category);
             });
+
+            this.search_and_categories();
+
             if(this.pos.iface_vkeyboard && this.pos_widget.onscreen_keyboard){
                 this.pos_widget.onscreen_keyboard.connect(this.$('.searchbox input'));
             }
-            this.search_and_categories();
         },
         
         set_product_type: function(type){       // 'all' | 'weightable'
@@ -542,7 +542,14 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
         reset_category: function(){
             this.set_category();
             this.renderElement();
-            this.search_and_categories();
+        },
+
+        // empties the content of the search box
+        clear_search: function(){
+            var products = this.pos.db.get_product_by_category(this.category.id);
+            this.pos.get('products').reset(products);
+            this.$('.searchbox input').val('').focus();
+            this.$('.search-clear').fadeOut();
         },
 
         // filters the products, and sets up the search callbacks
@@ -553,28 +560,37 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
             var products = this.pos.db.get_product_by_category(this.category.id);
             self.pos.get('products').reset(products);
 
+
+            var searchtimeout = null;
             // filter the products according to the search string
-            this.$('.searchbox input').keyup(function(){
-                query = $(this).val().toLowerCase();
-                if(query){
-                    var products = self.pos.db.search_product_in_category(self.category.id, query);
-                    self.pos.get('products').reset(products);
-                    self.$('.search-clear').fadeIn();
-                }else{
-                    var products = self.pos.db.get_product_by_category(self.category.id);
-                    self.pos.get('products').reset(products);
-                    self.$('.search-clear').fadeOut();
-                }
-            });
+            this.$('.searchbox input').keyup(function(event){
+                clearTimeout(searchtimeout);
 
-            this.$('.searchbox input').click(function(){}); //Why ???
+                var query = $(this).val().toLowerCase();
+                
+                searchtimeout = setTimeout(function(){
+                    if(query){
+                        if(event.which === 13){
+                            if( self.pos.get('products').size() === 1 ){
+                                self.pos.get('selectedOrder').addProduct(self.pos.get('products').at(0));
+                                self.clear_search();
+                            }
+                        }else{
+                            var products = self.pos.db.search_product_in_category(self.category.id, query);
+                            self.pos.get('products').reset(products);
+                            self.$('.search-clear').fadeIn();
+                        }
+                    }else{
+                        var products = self.pos.db.get_product_by_category(self.category.id);
+                        self.pos.get('products').reset(products);
+                        self.$('.search-clear').fadeOut();
+                    }
+                },200);
+            });
 
             //reset the search when clicking on reset
             this.$('.search-clear').click(function(){
-                var products = self.pos.db.get_product_by_category(self.category.id);
-                self.pos.get('products').reset(products);
-                self.$('.searchbox input').val('').focus();
-                self.$('.search-clear').fadeOut();
+                self.clear_search();
             });
         },
     });
@@ -668,7 +684,9 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
             var self = this;
             this._super();
             if(this.action){
-                this.$el.click(function(){ self.action(); });
+                this.$el.click(function(){
+                    self.action();
+                });
             }
         },
         show: function(){ this.$el.removeClass('oe_hidden'); },
@@ -732,12 +750,15 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
             this.$('.button.custom_ean').click(function(){
                 var ean = self.pos.barcode_reader.sanitize_ean(self.$('input.ean').val() || '0');
                 self.$('input.ean').val(ean);
-                self.pos.barcode_reader.on_ean(ean);
+                self.pos.barcode_reader.scan('ean13',ean);
+            });
+            this.$('.button.reference').click(function(){
+                self.pos.barcode_reader.scan('reference',self.$('input.ean').val());
             });
             _.each(this.eans, function(ean, name){
                 self.$('.button.'+name).click(function(){
                     self.$('input.ean').val(ean);
-                    self.pos.barcode_reader.on_ean(ean);
+                    self.pos.barcode_reader.scan('ean13',ean);
                 });
             });
             _.each(this.events, function(name){
@@ -1082,15 +1103,29 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
         },
         close: function() {
             var self = this;
-            return new instance.web.Model("ir.model.data").get_func("search_read")([['name', '=', 'action_client_pos_menu']], ['res_id']).pipe(
-                    _.bind(function(res) {
-                return this.rpc('/web/action/load', {'action_id': res[0]['res_id']}).pipe(_.bind(function(result) {
-                    var action = result;
-                    action.context = _.extend(action.context || {}, {'cancel_action': {type: 'ir.actions.client', tag: 'reload'}});
-                    //self.destroy();
-                    this.do_action(action);
-                }, this));
-            }, this));
+
+            function close(){
+                return new instance.web.Model("ir.model.data").get_func("search_read")([['name', '=', 'action_client_pos_menu']], ['res_id']).pipe(
+                        _.bind(function(res) {
+                    return this.rpc('/web/action/load', {'action_id': res[0]['res_id']}).pipe(_.bind(function(result) {
+                        var action = result;
+                        action.context = _.extend(action.context || {}, {'cancel_action': {type: 'ir.actions.client', tag: 'reload'}});
+                        //self.destroy();
+                        this.do_action(action);
+                    }, this));
+                }, self));
+            }
+
+            var draft_order = _.find( self.pos.get('orders').models, function(order){
+                return order.get('orderLines').length !== 0 && order.get('paymentLines').length === 0;
+            });
+            if(draft_order){
+                if (confirm(_t("Pending orders will be lost.\nAre you sure you want to leave this session?"))) {
+                    return close();
+                }
+            }else{
+                return close();
+            }
         },
         destroy: function() {
             this.pos.destroy();
index 7456c29..742c823 100644 (file)
@@ -12,8 +12,8 @@
                 </div>
                 <div id="rightheader">
                     <div id="order-selector">
-                        <button class="neworder-button square">➕</button>
-                        <button class="deleteorder-button square">➖</button>
+                        <button class="neworder-button square"><img src='/point_of_sale/static/src/img/plus.png' /></button>
+                        <button class="deleteorder-button square"><img src='/point_of_sale/static/src/img/minus.png' /></button>
                         <ol id="orders"></ol>
                     </div>
                     <!-- here goes header buttons -->
                     <li class="button lemon_price">1.54€ Lemon</li>
                     <li class="button unknown_product">Unknown Product</li>
                     <li class="button invalid_ean">Invalid Ean</li>
+                    <li class="button reference">Reference</li>
                 </ul>
 
                 <p class="category">Hardware Status</p>
     <t t-name="PosTicket">
         <div class="pos-sale-ticket">
             
-            <div class="pos-right-align"><t t-esc="new Date().toString(Date.CultureInfo.formatPatterns.shortDate + ' ' +
+            <div class="pos-center-align"><t t-esc="new Date().toString(Date.CultureInfo.formatPatterns.shortDate + ' ' +
                 Date.CultureInfo.formatPatterns.longTime)"/> <t t-esc="widget.currentOrder.attributes.name"/></div>
             <br />
             <t t-esc="widget.company.name"/><br />