[IMP] point_of_sale: various improvements for failed orders handling

- The POS will retry sending unsent orders before closing the pos.
 - A warning is emitted before closing the POS with unsent orders.
 - Errors message will not be repeated on each order posting.
 - The status widget shows a different icon for offline and server
   crashes.
This commit is contained in:
Frédéric van der Essen
2015-05-04 14:13:45 +02:00
parent 9d253eefa7
commit 5979662ea8
4 changed files with 57 additions and 17 deletions
+2 -2
View File
@@ -316,7 +316,7 @@ var DebugWidget = PosBaseWidget.extend({
// status in the point of sale header.
var StatusWidget = PosBaseWidget.extend({
status: ['connected','connecting','disconnected','warning'],
status: ['connected','connecting','disconnected','warning','error'],
set_status: function(status,msg){
for(var i = 0; i < this.status.length; i++){
this.$('.js_'+this.status[i]).addClass('oe_hidden');
@@ -344,7 +344,7 @@ var SynchNotificationWidget = StatusWidget.extend({
self.set_status(synch.state, synch.pending);
});
this.$el.click(function(){
self.pos.push_order();
self.pos.push_order(null,{'show_error':true});
});
},
});
+32
View File
@@ -265,6 +265,38 @@ var Gui = core.Class.extend({
/* ---- Gui: CLOSING THE POINT OF SALE ---- */
close: function() {
var self = this;
var pending = this.pos.db.get_orders().length;
if (!pending) {
this._close();
} else {
this.pos.push_order().always(function() {
var pending = self.pos.db.get_orders().length;
if (!pending) {
self._close();
} else {
var reason = self.pos.get('failed') ?
'configuration errors' :
'internet connection issues';
self.show_popup('confirm', {
'title': _t('Offline Orders'),
'body': _t(['Some orders could not be submitted to',
'the server due to ' + reason + '.',
'You can exit the Point of Sale, but do',
'not close the session before the issue',
'has been resolved.'].join(' ')),
'confirm': function() {
self._close();
},
});
}
});
}
},
_close: function() {
var self = this;
this.chrome.loading_show();
this.chrome.loading_message(_t('Closing ...'));
+20 -15
View File
@@ -71,15 +71,6 @@ exports.PosModel = Backbone.Model.extend({
'selectedOrder': null,
});
this.bind('change:synch',function(pos,synch){
clearTimeout(self.synch_timeout);
self.synch_timeout = setTimeout(function(){
if(synch.state !== 'disconnected' && synch.pending > 0){
self.set('synch',{state:'disconnected', pending:synch.pending});
}
},3000);
});
this.get('orders').bind('remove', function(order,_unused_,options){
self.on_removed_order(order,options.index,options.reason);
});
@@ -617,7 +608,8 @@ exports.PosModel = Backbone.Model.extend({
// saves the order locally and try to send it to the backend.
// it returns a deferred that succeeds after having tried to send the order and all the other pending orders.
push_order: function(order) {
push_order: function(order, opts) {
opts = opts || {};
var self = this;
if(order){
@@ -627,7 +619,7 @@ exports.PosModel = Backbone.Model.extend({
var pushed = new $.Deferred();
this.flush_mutex.exec(function(){
var flushed = self._flush_orders(self.db.get_orders());
var flushed = self._flush_orders(self.db.get_orders(), opts);
flushed.always(function(ids){
pushed.resolve();
@@ -705,6 +697,13 @@ exports.PosModel = Backbone.Model.extend({
});
return server_ids;
}).fail(function(error, event){
var pending = self.db.get_orders().length;
if (self.get('failed')) {
self.set('synch', { state: 'error', pending: pending });
} else {
self.set('synch', { state: 'disconnected', pending: pending });
}
});
},
@@ -742,6 +741,7 @@ exports.PosModel = Backbone.Model.extend({
_.each(orders, function (order) {
self.db.remove_order(order.id);
});
self.set('failed',false);
return server_ids;
}).fail(function (error, event){
if(error.code === 200 ){ // Business Logic Error, not a connection problem
@@ -749,10 +749,15 @@ exports.PosModel = Backbone.Model.extend({
if (error.data.exception_type == 'warning') {
delete error.data.debug;
}
self.gui.show_popup('error-traceback',{
'title': error.data.message,
'body': error.data.debug
});
// Hide error if already shown before ...
if ((!self.get('failed') || options.show_error) && !options.to_invoice) {
self.gui.show_popup('error-traceback',{
'title': error.data.message,
'body': error.data.debug
});
}
self.set('failed',error)
}
// prevent an error popup creation by the rpc failure
// we want the failure to be silent as we send the orders in the background
@@ -60,6 +60,9 @@
<div class="js_disconnected oe_icon oe_red oe_hidden">
<i class='fa fa-fw fa-wifi'></i>
</div>
<div class="js_error oe_icon oe_red oe_hidden">
<i class='fa fa-fw fa-warning'></i>
</div>
</div>
</t>