diff --git a/addons/point_of_sale/static/src/css/pos.css b/addons/point_of_sale/static/src/css/pos.css
index dbe79703329..a727986bb1c 100644
--- a/addons/point_of_sale/static/src/css/pos.css
+++ b/addons/point_of_sale/static/src/css/pos.css
@@ -1102,6 +1102,81 @@
.point-of-sale .pos-actionbar .button.rightalign{
float:right;
}
+/* ********* The Debug Widget ********* */
+
+.point-of-sale .debug-widget{
+ z-index:100000;
+ position: absolute;
+ right: 10px;
+ top: 10px;
+ width: 200px;
+ font-size: 10px;
+
+ background: rgba(0,0,0,0.82);
+ color: white;
+ text-shadow: none;
+ padding-bottom: 10px;
+ box-shadow: 0px 3px 20px rgba(0,0,0,0.3);
+ cursor:move;
+}
+.point-of-sale .debug-widget .toggle{
+ position: absolute;
+ font-size: 16px;
+ cursor:pointer;
+ top:0px;
+ right:0px;
+ padding:10px;
+ padding-right:15px;
+}
+.point-of-sale .debug-widget .content{
+ overflow: hidden;
+}
+.point-of-sale .debug-widget h1{
+ background:black;
+ padding-top: 10px;
+ padding-left: 10px;
+ margin-top:0;
+ margin-bottom:0;
+}
+.point-of-sale .debug-widget .category{
+ background: black;
+ padding-left: 10px;
+ margin: 0px;
+ font-weight: bold;
+ padding-top:3px;
+ padding-bottom:3px;
+}
+.point-of-sale .debug-widget .button{
+ padding: 5px;
+ padding-left: 15px;
+ display: block;
+ cursor:pointer;
+}
+.point-of-sale .debug-widget .button:hover{
+ background: rgba(96,21,177,0.45);
+}
+.point-of-sale .debug-widget input{
+ margin-left:10px;
+ margin-top:7px;
+}
+.point-of-sale .debug-widget .status{
+ padding: 5px;
+ padding-left: 15px;
+ display: block;
+ cursor:default;
+}
+.point-of-sale .debug-widget .status.on{
+ padding: 5px;
+ padding-left: 15px;
+ display: block;
+ background-color: green;
+}
+.point-of-sale .debug-widget .status.on{
+ padding: 5px;
+ padding-left: 15px;
+ display: block;
+ background-color: #6cd11d;
+}
/* ********* The PopupWidgets ********* */
diff --git a/addons/point_of_sale/static/src/js/devices.js b/addons/point_of_sale/static/src/js/devices.js
index 46d11938128..65a28b5366a 100644
--- a/addons/point_of_sale/static/src/js/devices.js
+++ b/addons/point_of_sale/static/src/js/devices.js
@@ -1,26 +1,6 @@
function openerp_pos_devices(instance,module){ //module is instance.point_of_sale
- var debug_devices = new (instance.web.Class.extend({
- active: false,
- payment_status: 'waiting_for_payment',
- weight: 0,
- activate: function(){
- this.active = true;
- },
- deactivate: function(){
- this.active = false;
- },
- set_weight: function(weight){ this.activate(); this.weight = weight; },
- accept_payment: function(){ this.activate(); this.payment_status = 'payment_accepted'; },
- reject_payment: function(){ this.activate(); this.payment_status = 'payment_rejected'; },
- delay_payment: function(){ this.activate(); this.payment_status = 'waiting_for_payment'; },
- }))();
-
- if(jQuery.deparam(jQuery.param.querystring()).debug !== undefined){
- window.debug_devices = debug_devices;
- }
-
// this object interfaces with the local proxy to communicate to the various hardware devices
// connected to the Point of Sale. As the communication only goes from the POS to the proxy,
// methods are used both to signal an event, and to fetch information.
@@ -38,20 +18,34 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
this.connection = new instance.web.JsonRPC();
this.connection.setup(url);
+
+ this.bypass_proxy = false;
+ this.notifications = {};
},
message : function(name,params,success_callback, error_callback){
success_callback = success_callback || function(){};
error_callback = error_callback || function(){};
-
if(jQuery.deparam(jQuery.param.querystring()).debug !== undefined){
console.log('PROXY:',name,params);
}
- if(!(debug_devices && debug_devices.active)){
- this.connection.rpc('/pos/'+name, params || {}, success_callback, error_callback);
+ var callbacks = this.notifications[name] || [];
+ for(var i = 0; i < callbacks.length; i++){
+ callbacks[i](params);
}
+
+ this.connection.rpc('/pos/'+name, params || {}, success_callback, error_callback);
+ },
+
+ // this allows the client to be notified when a proxy call is made. The notification
+ // callback will be executed with the same arguments as the proxy call
+ add_notification: function(name, callback){
+ if(!this.notifications[name]){
+ this.notifications[name] = [];
+ }
+ this.notifications[name].push(callback);
},
//a product has been scanned and recognized with success
@@ -78,12 +72,12 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
//the client is starting to weight
weighting_start: function(){
- this.weight = 0;
- if(debug_devices){
- debug_devices.weigth = 0;
+ if(!this.weighting){
+ this.weight = 0;
+ this.weighting = true;
+ this.bypass_proxy = false;
+ this.message('weighting_start');
}
- this.weighting = true;
- this.message('weighting_start');
},
//returns the weight on the scale.
@@ -91,22 +85,29 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
// and a weighting_end()
weighting_read_kg: function(){
var self = this;
- if(debug_devices && debug_devices.active){
- return debug_devices.weight;
+ if(this.bypass_proxy){
+ return this.weight;
}else{
this.message('weighting_read_kg',{},function(weight){
- if(self.weighting){
+ if(self.weighting && !self.bypass_proxy){
self.weight = weight;
}
});
- return self.weight;
+ return this.weight;
}
},
+ // sets a custom weight, ignoring the proxy returned value until the next weighting_end
+ debug_set_weight: function(kg){
+ this.bypass_proxy = true;
+ this.weight = kg;
+ },
+
// the client has finished weighting products
weighting_end: function(){
this.weight = 0;
this.weighting = false;
+ this.bypass_proxy = false;
this.message('weighting_end');
},
@@ -116,9 +117,6 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
payment_request: function(price, method, info){
this.paying = true;
this.payment_status = 'waiting_for_payment';
- if(debug_devices){
- debug_devices.payment_status = 'waiting_for_payment';
- }
this.message('payment_request',{'price':price,'method':method,'info':info});
},
@@ -127,18 +125,30 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
// returns 'waiting_for_payment' | 'payment_accepted' | 'payment_rejected'
is_payment_accepted: function(){
var self = this;
- if(debug_devices.active){
- return debug_devices.payment_status;
+ if(this.bypass_proxy){
+ this.bypass_proxy = false;
+ return this.payment_status;
}else{
this.message('is_payment_accepted', {}, function(payment_status){
if(self.paying){
self.payment_status = payment_status;
}
});
- return self.payment_status;
+ return this.payment_status;
}
},
+
+ // override what the proxy says and accept the payment
+ debug_accept_payment: function(){
+ this.bypass_proxy = true;
+ this.payment_status = 'payment_accepted';
+ },
+ // override what the proxy says and reject the payment
+ debug_reject_payment: function(){
+ this.bypass_proxy = true;
+ this.payment_status = 'payment_rejected';
+ },
// the client cancels his payment
payment_canceled: function(){
this.paying = false;
@@ -241,18 +251,6 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
this.price_prefix_set = attributes.price_prefix_set || {'23':''};
this.cashier_prefix_set = attributes.cashier_prefix_set || {'041':''};
this.client_prefix_set = attributes.client_prefix_set || {'042':''};
-
- if(jQuery.deparam(jQuery.param.querystring()).debug !== undefined){
- var self = this;
- window.simulate_ean = function(ean,strict){
- ean = ean.toString();
- if(!strict){
- ean = self.sanitize_ean(ean);
- }
- console.log('SIMULATE EAN: ',ean);
- self.on_ean(ean);
- }
- }
},
save_callbacks: function(){
@@ -356,7 +354,6 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
value: 0,
unit: 'none',
};
- console.log('ean',ean);
function match_prefix(prefix_set, type){
for(prefix in prefix_set){
diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js
index 49521377ccb..5fbba5088d4 100644
--- a/addons/point_of_sale/static/src/js/models.js
+++ b/addons/point_of_sale/static/src/js/models.js
@@ -24,6 +24,8 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
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('products','categories');
+ this.debug = jQuery.deparam(jQuery.param.querystring()).debug !== undefined; //debug mode
+
// default attributes values. If null, it will be loaded below.
this.set({
diff --git a/addons/point_of_sale/static/src/js/screens.js b/addons/point_of_sale/static/src/js/screens.js
index 3b580868e6b..d2c79f19928 100644
--- a/addons/point_of_sale/static/src/js/screens.js
+++ b/addons/point_of_sale/static/src/js/screens.js
@@ -560,21 +560,21 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
//we get the first cashregister marked as self-checkout
var selfCheckoutRegisters = [];
- for(var i = 0; i < this.pos.get('cashRegisters').models.length; i++){
- var cashregister = this.pos.get('cashRegisters').models[i];
+ for(var i = 0; i < self.pos.get('cashRegisters').models.length; i++){
+ var cashregister = self.pos.get('cashRegisters').models[i];
if(cashregister.self_checkout_payment_method){
selfCheckoutRegisters.push(cashregister);
}
}
- var cashregister = selfCheckoutRegisters[0] || this.pos.get('cashRegisters').models[0];
+ var cashregister = selfCheckoutRegisters[0] || self.pos.get('cashRegisters').models[0];
currentOrder.addPaymentLine(cashregister);
self.pos.push_order(currentOrder.exportAsJSON())
currentOrder.destroy();
self.pos.proxy.transaction_end();
self.pos_widget.screen_selector.set_current_screen(self.next_screen);
}else if(payment === 'payment_rejected'){
- clearInterval(this.intervalID);
+ clearInterval(self.intervalID);
//TODO show a tryagain thingie ?
}
},500);
@@ -603,13 +603,14 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
show_numpad: false,
show_leftpane: false,
barcode_product_action: function(ean){
- self.pos.proxy.transaction_start();
+ this.pos.proxy.transaction_start();
this._super(ean);
},
barcode_client_action: function(ean){
- self.pos.proxy.transaction_start();
+ this.pos.proxy.transaction_start();
this._super(ean);
+ $('.goodbye-message').hide();
this.pos_widget.screen_selector.show_popup('choose-receipt');
},
diff --git a/addons/point_of_sale/static/src/js/widgets.js b/addons/point_of_sale/static/src/js/widgets.js
index 2aaf9098329..c8e03ccff08 100644
--- a/addons/point_of_sale/static/src/js/widgets.js
+++ b/addons/point_of_sale/static/src/js/widgets.js
@@ -694,6 +694,91 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
},
});
+ module.DebugWidget = module.PosBaseWidget.extend({
+ template: "DebugWidget",
+ eans:{
+ admin_badge: '0410300000004',
+ client_badge: '0420100000005',
+ invalid_ean: '1232456',
+ soda_33cl: '5449000000996',
+ oranges_kg: '2100002031410',
+ lemon_price: '2301000001560',
+ unknown_product: '9900000000004',
+ },
+ events:[
+ 'scan_item_success',
+ 'scan_item_error_unrecognized',
+ 'payment_request',
+ 'open_cashbox',
+ 'print_receipt',
+ 'print_pdf_invoice',
+ ],
+ minimized: false,
+ start: function(){
+ var self = this;
+
+ this.$el.draggable();
+ this.$('.toggle').click(function(){
+ var content = self.$('.content');
+ var bg = self.$el;
+ if(!self.minimized){
+ content.animate({'height':'0'},200);
+ }else{
+ content.css({'height':'auto'});
+ }
+ self.minimized = !self.minimized;
+ });
+ this.$('.button.accept_payment').click(function(){
+ self.pos.proxy.debug_accept_payment();
+ });
+ this.$('.button.reject_payment').click(function(){
+ self.pos.proxy.debug_reject_payment();
+ });
+ this.$('.button.set_weight').click(function(){
+ var kg = Number(self.$('input.weight').val());
+ if(!Number.isNaN(kg)){
+ self.pos.proxy.debug_set_weight(kg);
+ }
+ });
+ 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);
+ });
+ _.each(this.eans, function(ean, name){
+ self.$('.button.'+name).click(function(){
+ self.$('input.ean').val(ean);
+ self.pos.barcode_reader.on_ean(ean);
+ });
+ });
+ _.each(this.events, function(name){
+ self.pos.proxy.add_notification(name,function(){
+ console.log('Notification:',name);
+ self.$('.status.'+name).stop().clearQueue().css({'background-color':'#6CD11D'});
+ self.$('.status.'+name).animate({'background-color':'black'},2000);
+ });
+ });
+ self.pos.proxy.add_notification('help_needed',function(){
+ self.$('.status.help_needed').addClass('on');
+ });
+ self.pos.proxy.add_notification('help_canceled',function(){
+ self.$('.status.help_needed').removeClass('on');
+ });
+ self.pos.proxy.add_notification('transaction_start',function(){
+ self.$('.status.transaction').addClass('on');
+ });
+ self.pos.proxy.add_notification('transaction_end',function(){
+ self.$('.status.transaction').removeClass('on');
+ });
+ self.pos.proxy.add_notification('weighting_start',function(){
+ self.$('.status.weighting').addClass('on');
+ });
+ self.pos.proxy.add_notification('weighting_end',function(){
+ self.$('.status.weighting').removeClass('on');
+ });
+ },
+ });
+
// The PosWidget is the main widget that contains all other widgets in the PointOfSale.
// It is mainly composed of :
// - a header, containing the list of orders
@@ -718,14 +803,6 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
this.leftpane_width = '440px';
this.cashier_controls_visible = true;
this.image_cache = new module.ImageCache(); // for faster products image display
-
- /*
- //Epileptic mode
- setInterval(function(){
- $('body').css({'-webkit-filter':'hue-rotate('+Math.random()*360+'deg)' });
- },100);
- */
-
},
start: function() {
@@ -769,11 +846,6 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
self.$('.loader').animate({opacity:0},1500,'swing',function(){self.$('.loader').hide();});
self.$('.loader img').hide();
- if(jQuery.deparam(jQuery.param.querystring()).debug !== undefined){
- window.pos = self.pos;
- window.pos_widget = self.pos_widget;
- }
-
},function(){ // error when loading models data from the backend
self.$('.loader img').hide();
return new instance.web.Model("ir.model.data").get_func("search_read")([['name', '=', 'action_pos_session_opening']], ['res_id'])
@@ -898,6 +970,10 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
default_mode: this.pos.iface_self_checkout ? 'client' : 'cashier',
});
+ if(this.pos.debug){
+ this.debug_widget = new module.DebugWidget(this);
+ this.debug_widget.appendTo(this.$('#content'));
+ }
},
changed_pending_operations: function () {
diff --git a/addons/point_of_sale/static/src/xml/pos.xml b/addons/point_of_sale/static/src/xml/pos.xml
index a0b129da2f9..7c8b18a9bc3 100644
--- a/addons/point_of_sale/static/src/xml/pos.xml
+++ b/addons/point_of_sale/static/src/xml/pos.xml
@@ -414,6 +414,55 @@
+
+
+
+