[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:
@@ -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});
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
@@ -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 ...'));
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user