[MERGE] from master
[odoo/odoo.git] / addons / point_of_sale / static / src / js / screens.js
index 956adbd..092c85a 100644 (file)
@@ -15,7 +15,7 @@
 // that only one screen is shown at the same time and that show() is called after all
 // hide()s
 
-function openerp_pos_screens(instance, module){ //module is instance.point_of_sale
+openerp.point_of_sale.load_screens = function load_screens(instance, module){ //module is instance.point_of_sale
     "use strict";
 
     var QWeb = instance.web.qweb,
@@ -174,14 +174,14 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
 
         // 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
+        // - if there's a user with a matching barcode, 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(code){
             var users = this.pos.users;
             for(var i = 0, len = users.length; i < len; i++){
-                if(users[i].ean13 === code.code){
-                    this.pos.cashier = users[i];
-                    this.pos_widget.username.refresh();
+                if(users[i].barcode === code.code){
+                    this.pos.set_cashier(users[i]);
+                    this.pos_widget.username.renderElement();
                     return true;
                 }
             }
@@ -191,13 +191,12 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
         
         // what happens when a client id barcode is scanned.
         // the default behavior is the following : 
-        // - if there's a user with a matching ean, put it as the active 'client' and return true
+        // - if there's a user with a matching barcode, put it as the active 'client' and return true
         // - else : return false. 
         barcode_client_action: function(code){
-            var partner = this.pos.db.get_partner_by_ean13(code.code);
+            var partner = this.pos.db.get_partner_by_barcode(code.code);
             if(partner){
                 this.pos.get_order().set_client(partner);
-                this.pos_widget.username.refresh();
                 return true;
             }
             this.pos_widget.screen_selector.show_popup('error-barcode',code.code);
@@ -207,7 +206,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
         // what happens when a discount barcode is scanned : the default behavior
         // is to set the discount on the last order.
         barcode_discount_action: function(code){
-            var last_orderline = this.pos.get_order().getLastOrderline();
+            var last_orderline = this.pos.get_order().get_last_orderline();
             if(last_orderline){
                 last_orderline.set_discount(code.value)
             }
@@ -233,7 +232,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 ,
@@ -357,6 +355,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
     module.ConfirmPopupWidget = module.PopUpWidget.extend({
         template: 'ConfirmPopupWidget',
         show: function(options){
+            options = options || {};
             var self = this;
             this._super();
 
@@ -402,6 +401,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
     module.SelectionPopupWidget = module.PopUpWidget.extend({
         template: 'SelectionPopupWidget',
         show: function(options){
+            options = options || {};
             var self = this;
             this._super();
 
@@ -416,7 +416,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
                 }
             });
 
-            this.$('.button.item').click(function(){
+            this.$('.selection-item').click(function(){
                 self.pos_widget.screen_selector.close_popup();
                 if (options.confirm) {
                     var item = self.list[parseInt($(this).data('item-index'))];
@@ -430,6 +430,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
     module.TextInputPopupWidget = module.PopUpWidget.extend({
         template: 'TextInputPopupWidget',
         show: function(options){
+            options = options || {};
             var self = this;
             this._super();
 
@@ -437,7 +438,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
             this.comment = options.comment || '';
             this.value   = options.value   || '';
             this.renderElement();
-            this.$('input').focus();
+            this.$('input,textarea').focus();
             
             this.$('.button.cancel').click(function(){
                 self.pos_widget.screen_selector.close_popup();
@@ -448,7 +449,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
 
             this.$('.button.confirm').click(function(){
                 self.pos_widget.screen_selector.close_popup();
-                var value = self.$('input').val();
+                var value = self.$('input,textarea').val();
                 if( options.confirm ){
                     options.confirm.call(self,value);
                 }
@@ -456,26 +457,109 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
         },
     });
 
-    module.ErrorNoClientPopupWidget = module.ErrorPopupWidget.extend({
-        template: 'ErrorNoClientPopupWidget',
+    module.TextAreaPopupWidget = module.TextInputPopupWidget.extend({
+        template: 'TextAreaPopupWidget',
     });
 
-    module.ErrorInvoiceTransferPopupWidget = module.ErrorPopupWidget.extend({
-        template: 'ErrorInvoiceTransferPopupWidget',
-    });
+    module.NumberPopupWidget = module.PopUpWidget.extend({
+        template: 'NumberPopupWidget',
+        click_numpad_button: function($el,event){
+            this.numpad_input($el.data('action'));
+        },
+        numpad_input: function(input) { //FIXME -> Deduplicate code
+            var oldbuf = this.inputbuffer.slice(0);
 
-    module.UnsentOrdersPopupWidget = module.PopUpWidget.extend({
-        template: 'UnsentOrdersPopupWidget',
+            if (input === '.') {
+                if (this.firstinput) {
+                    this.inputbuffer = "0.";
+                }else if (!this.inputbuffer.length || this.inputbuffer === '-') {
+                    this.inputbuffer += "0.";
+                } else if (this.inputbuffer.indexOf('.') < 0){
+                    this.inputbuffer = this.inputbuffer + '.';
+                }
+            } else if (input === 'CLEAR') {
+                this.inputbuffer = ""; 
+            } else if (input === 'BACKSPACE') { 
+                this.inputbuffer = this.inputbuffer.substring(0,this.inputbuffer.length - 1);
+            } else if (input === '+') {
+                if ( this.inputbuffer[0] === '-' ) {
+                    this.inputbuffer = this.inputbuffer.substring(1,this.inputbuffer.length);
+                }
+            } else if (input === '-') {
+                if ( this.inputbuffer[0] === '-' ) {
+                    this.inputbuffer = this.inputbuffer.substring(1,this.inputbuffer.length);
+                } else {
+                    this.inputbuffer = '-' + this.inputbuffer;
+                }
+            } else if (input[0] === '+' && !isNaN(parseFloat(input))) {
+                this.inputbuffer = '' + ((parseFloat(this.inputbuffer) || 0) + parseFloat(input));
+            } else if (!isNaN(parseInt(input))) {
+                if (this.firstinput) {
+                    this.inputbuffer = '' + input;
+                } else {
+                    this.inputbuffer += input;
+                }
+            }
+
+            this.firstinput = this.inputbuffer.length === 0;
+
+            if (this.inputbuffer !== oldbuf) {
+                this.$('.value').text(this.inputbuffer);
+            }
+        },
         show: function(options){
+            options = options || {};
             var self = this;
-            this._super(options);
+            this._super();
+
+            this.message = options.message || '';
+            this.comment = options.comment || '';
+            this.inputbuffer = options.value   || '';
             this.renderElement();
+            this.firstinput = true;
+            
+            this.$('.input-button,.mode-button').click(function(event){
+                self.click_numpad_button($(this),event);
+            });
+            this.$('.button.cancel').click(function(){
+                self.pos_widget.screen_selector.close_popup();
+                if( options.cancel ){
+                    options.cancel.call(self);
+                }
+            });
+
             this.$('.button.confirm').click(function(){
                 self.pos_widget.screen_selector.close_popup();
+                if( options.confirm ){
+                    options.confirm.call(self,self.inputbuffer);
+                }
             });
         },
     });
 
+    module.PasswordPopupWidget = module.NumberPopupWidget.extend({
+        renderElement: function(){
+            this._super();
+            this.$('.popup').addClass('popup-password');    // HELLO HACK !
+        },
+    });
+
+    module.ErrorNoClientPopupWidget = module.ErrorPopupWidget.extend({
+        template: 'ErrorNoClientPopupWidget',
+    });
+
+    module.ErrorInvoiceTransferPopupWidget = module.ErrorPopupWidget.extend({
+        template: 'ErrorInvoiceTransferPopupWidget',
+    });
+
+    module.UnsentOrdersPopupWidget = module.ConfirmPopupWidget.extend({
+        template: 'UnsentOrdersPopupWidget',
+    });
+
+    module.UnpaidOrdersPopupWidget = module.ConfirmPopupWidget.extend({
+        template: 'UnpaidOrdersPopupWidget',
+    });
+
     module.ScaleScreenWidget = module.ScreenWidget.extend({
         template:'ScaleScreenWidget',
 
@@ -528,7 +612,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
             }
         },
         order_product: function(){
-            this.pos.get_order().addProduct(this.get_product(),{ quantity: this.weight });
+            this.pos.get_order().add_product(this.get_product(),{ quantity: this.weight });
         },
         get_product_name: function(){
             var product = this.get_product();
@@ -585,7 +669,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
                     if(product.to_weight && self.pos.config.iface_electronic_scale){
                         self.pos_widget.screen_selector.set_current_screen('scale',{product: product});
                     }else{
-                        self.pos.get_order().addProduct(product);
+                        self.pos.get_order().add_product(product);
                     }
                 },
                 product_list: this.pos.db.get_product_by_category(0)
@@ -690,8 +774,8 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
         barcode_client_action: function(code){
             if (this.editing_client) {
                 this.$('.detail.barcode').val(code.code);
-            } else if (this.pos.db.get_partner_by_ean13(code.code)) {
-                this.display_client_details('show',this.pos.db.get_partner_by_ean13(code.code));
+            } else if (this.pos.db.get_partner_by_barcode(code.code)) {
+                this.display_client_details('show',this.pos.db.get_partner_by_barcode(code.code));
             }
         },
         perform_search: function(query, associate_result){
@@ -824,10 +908,16 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
 
             fields.id           = partner.id || false;
             fields.country_id   = fields.country_id || false;
-            fields.ean13        = fields.ean13 ? this.pos.barcode_reader.sanitize_ean(fields.ean13) : false; 
+            fields.barcode        = fields.barcode ? this.pos.barcode_reader.sanitize_ean(fields.barcode) : false; 
 
             new instance.web.Model('res.partner').call('create_from_ui',[fields]).then(function(partner_id){
                 self.saved_client_details(partner_id);
+            },function(err,event){
+                event.preventDefault();
+                self.pos_widget.screen_selector.show_popup('error',{
+                    'message':_t('Error: Could not Save Changes'),
+                    'comment':_t('Your Internet connection is probably down.'),
+                });
             });
         },
         
@@ -1004,7 +1094,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
 
             this.refresh();
 
-            if (!this.pos.get_order()._printed) {
+            if (!this.pos.get_order()._printed && this.pos.config.iface_print_auto) {
                 this.print();
             }
 
@@ -1061,8 +1151,9 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
             this.$('.pos-receipt-container').html(QWeb.render('PosTicket',{
                     widget:this,
                     order: order,
-                    orderlines: order.get('orderLines').models,
-                    paymentlines: order.get('paymentLines').models,
+                    receipt: order.export_for_printing(),
+                    orderlines: order.get_orderlines(),
+                    paymentlines: order.get_paymentlines(),
                 }));
         },
     });
@@ -1157,7 +1248,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
                 }
             }
 
-            this.firstinput = false;
+            this.firstinput = this.inputbuffer.length === 0;
 
             if (this.inputbuffer !== oldbuf) {
                 var order = this.pos.get_order();
@@ -1181,10 +1272,10 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
             return numpad;
         },
         click_delete_paymentline: function(cid){
-            var lines = this.pos.get_order().get('paymentLines').models;
+            var lines = this.pos.get_order().get_paymentlines();
             for ( var i = 0; i < lines.length; i++ ) {
                 if (lines[i].cid === cid) {
-                    this.pos.get_order().removePaymentline(lines[i]);
+                    this.pos.get_order().remove_paymentline(lines[i]);
                     this.reset_input();
                     this.render_paymentlines();
                     return;
@@ -1192,10 +1283,10 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
             }
         },
         click_paymentline: function(cid){
-            var lines = this.pos.get_order().get('paymentLines').models;
+            var lines = this.pos.get_order().get_paymentlines();
             for ( var i = 0; i < lines.length; i++ ) {
                 if (lines[i].cid === cid) {
-                    this.pos.get_order().selectPaymentline(lines[i]);
+                    this.pos.get_order().select_paymentline(lines[i]);
                     this.reset_input();
                     this.render_paymentlines();
                     return;
@@ -1209,7 +1300,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
                 return;
             }
 
-            var lines = order.get('paymentLines').models;
+            var lines = order.get_paymentlines();
 
             this.$('.paymentlines-container').empty();
             var lines = $(QWeb.render('PaymentScreen-Paymentlines', { 
@@ -1236,7 +1327,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
                     break;
                 }
             }
-            this.pos.get_order().addPaymentline( cashregister );
+            this.pos.get_order().add_paymentline( cashregister );
             this.reset_input();
             this.render_paymentlines();
         },
@@ -1325,12 +1416,23 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
             var order = this.pos.get_order();
             if (!order) {
                 return;
-            } else if (order.isPaid()) {
+            } else if (order.is_paid()) {
                 self.$('.next').addClass('highlight');
             }else{
                 self.$('.next').removeClass('highlight');
             }
         },
+        print_escpos_receipt: function(){
+            var env = {
+                widget:  this,
+                pos:     this.pos,
+                order:   this.pos.get_order(),
+                receipt: this.pos.get_order().export_for_printing(),
+            };
+
+            this.pos.proxy.print_receipt(QWeb.render('XmlReceipt',env));
+        },
+
         // Check if the order is paid, then sends it to the backend,
         // and complete the sale process
         validate_order: function() {
@@ -1340,7 +1442,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
 
             // FIXME: this check is there because the backend is unable to
             // process empty orders. This is not the right place to fix it.
-            if(order.get_orderlines().length === 0){
+            if (order.get_orderlines().length === 0) {
                 this.pos_widget.screen_selector.show_popup('error',{
                     'message': _t('Empty Order'),
                     'comment': _t('There must be at least one product in your order before it can be validated'),
@@ -1348,12 +1450,12 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
                 return;
             }
 
-            if (!order.isPaid() || this.invoicing) {
+            if (!order.is_paid() || this.invoicing) {
                 return;
             }
 
             // The exact amount must be paid if there is no cash payment method defined.
-            if (Math.abs(order.getTotalTaxIncluded() - order.getPaidTotal()) > 0.00001) {
+            if (Math.abs(order.get_total_with_tax() - order.get_total_paid()) > 0.00001) {
                 var cash = false;
                 for (var i = 0; i < this.pos.cashregisters.length; i++) {
                     cash = cash || (this.pos.cashregisters[i].journal.type === 'cash');
@@ -1367,7 +1469,8 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
                 }
             }
 
-            if (order.isPaidWithCash() && this.pos.config.iface_cashdrawer) { 
+            if (order.is_paid_with_cash() && this.pos.config.iface_cashdrawer) { 
+
                     this.pos.proxy.open_cashbox();
             }
 
@@ -1400,10 +1503,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
             } else {
                 this.pos.push_order(order) 
                 if (this.pos.config.iface_print_via_proxy) {
-                    var receipt = currentOrder.export_for_printing();
-                    this.pos.proxy.print_receipt(QWeb.render('XmlReceipt',{
-                        receipt: receipt, widget: self,
-                    }));
+                    this.print_escpos_receipt();
                     order.finalize();    //finish order and go back to scan screen
                 } else {
                     this.pos_widget.screen_selector.set_current_screen(this.next_screen);