[MERGE] point of sale fixes
bzr revid: chs@openerp.com-20140224172113-gj1t8hi7a8hr60gq
This commit is contained in:
commit
cde82643d0
|
@ -514,13 +514,18 @@ class pos_order(osv.osv):
|
|||
_order = "id desc"
|
||||
|
||||
def create_from_ui(self, cr, uid, orders, context=None):
|
||||
#_logger.info("orders: %r", orders)
|
||||
|
||||
# Keep only new orders
|
||||
submitted_references = [o['data']['name'] for o in orders]
|
||||
existing_orders = self.search_read(cr, uid, domain=[('pos_reference', 'in', submitted_references)], fields=['pos_reference'], context=context)
|
||||
existing_references = set([o['pos_reference'] for o in existing_orders])
|
||||
orders_to_save = [o for o in orders if o['data']['name'] not in existing_references]
|
||||
|
||||
order_ids = []
|
||||
for tmp_order in orders:
|
||||
for tmp_order in orders_to_save:
|
||||
to_invoice = tmp_order['to_invoice']
|
||||
order = tmp_order['data']
|
||||
|
||||
|
||||
order_id = self.create(cr, uid, {
|
||||
'name': order['name'],
|
||||
'user_id': order['user_id'] or False,
|
||||
|
@ -542,7 +547,6 @@ class pos_order(osv.osv):
|
|||
if order['amount_return']:
|
||||
session = self.pool.get('pos.session').browse(cr, uid, order['pos_session_id'], context=context)
|
||||
cash_journal = session.cash_journal_id
|
||||
cash_statement = False
|
||||
if not cash_journal:
|
||||
cash_journal_ids = filter(lambda st: st.journal_id.type=='cash', session.statement_ids)
|
||||
if not len(cash_journal_ids):
|
||||
|
@ -556,7 +560,11 @@ class pos_order(osv.osv):
|
|||
'journal': cash_journal.id,
|
||||
}, context=context)
|
||||
order_ids.append(order_id)
|
||||
self.signal_paid(cr, uid, [order_id])
|
||||
|
||||
try:
|
||||
self.signal_paid(cr, uid, [order_id])
|
||||
except Exception as e:
|
||||
_logger.error('Could not mark POS Order as Paid: %s', tools.ustr(e))
|
||||
|
||||
if to_invoice:
|
||||
self.action_invoice(cr, uid, [order_id], context)
|
||||
|
|
|
@ -672,7 +672,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
|
|||
// returns true if the ean is a valid EAN codebar number by checking the control digit.
|
||||
// ean must be a string
|
||||
check_ean: function(ean){
|
||||
return this.ean_checksum(ean) === Number(ean[ean.length-1]);
|
||||
return /^\d+$/.test(ean) && this.ean_checksum(ean) === Number(ean[ean.length-1]);
|
||||
},
|
||||
// returns a valid zero padded ean13 from an ean prefix. the ean prefix must be a string.
|
||||
sanitize_ean:function(ean){
|
||||
|
@ -757,8 +757,13 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
|
|||
scan: function(code){
|
||||
if(code.length < 3){
|
||||
return;
|
||||
}else if(code.length === 13 && /^\d+$/.test(code)){
|
||||
}else if(code.length === 13 && this.check_ean(code)){
|
||||
var parse_result = this.parse_ean(code);
|
||||
}else if(code.length === 12 && this.check_ean('0'+code)){
|
||||
// many barcode scanners strip the leading zero of ean13 barcodes.
|
||||
// This is because ean-13 are UCP-A with an additional zero at the beginning,
|
||||
// so by stripping zeros you get retrocompatibility with UCP-A systems.
|
||||
var parse_result = this.parse_ean('0'+code);
|
||||
}else if(this.pos.db.get_product_by_reference(code)){
|
||||
var parse_result = {
|
||||
encoding: 'reference',
|
||||
|
@ -767,12 +772,16 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
|
|||
prefix: '',
|
||||
};
|
||||
}else{
|
||||
var parse_result = {
|
||||
encoding: 'error',
|
||||
type: 'error',
|
||||
code: code,
|
||||
prefix: '',
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
if (parse_result.type === 'error') { //most likely a checksum error, raise warning
|
||||
console.warn('WARNING: barcode checksum error:',parse_result);
|
||||
}else if(parse_result.type in {'unit':'', 'weight':'', 'price':''}){ //ean is associated to a product
|
||||
if(parse_result.type in {'unit':'', 'weight':'', 'price':''}){ //ean is associated to a product
|
||||
if(this.action_callback['product']){
|
||||
this.action_callback['product'](parse_result);
|
||||
}
|
||||
|
|
|
@ -421,62 +421,67 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
// it is therefore important to only call this method from inside a mutex
|
||||
// this method returns a deferred indicating wether the sending was successful or not
|
||||
// there is a timeout parameter which is set to 2 seconds by default.
|
||||
_flush_order: function(order_id, options){
|
||||
var self = this;
|
||||
options = options || {};
|
||||
timeout = typeof options.timeout === 'number' ? options.timeout : 7500;
|
||||
|
||||
this.set('synch',{state:'connecting', pending: this.get('synch').pending});
|
||||
|
||||
var order = this.db.get_order(order_id);
|
||||
order.to_invoice = options.to_invoice || false;
|
||||
|
||||
if(!order){
|
||||
// flushing a non existing order always fails
|
||||
return (new $.Deferred()).reject();
|
||||
}
|
||||
|
||||
// we try to send the order. shadow prevents a spinner if it takes too long. (unless we are sending an invoice,
|
||||
// then we want to notify the user that we are waiting on something )
|
||||
var rpc = (new instance.web.Model('pos.order')).call('create_from_ui',[[order]],undefined,{shadow: !options.to_invoice, timeout:timeout});
|
||||
|
||||
rpc.fail(function(unused,event){
|
||||
// prevent an error popup creation by the rpc failure
|
||||
// we want the failure to be silent as we send the orders in the background
|
||||
event.preventDefault();
|
||||
console.error('Failed to send order:',order);
|
||||
});
|
||||
|
||||
rpc.done(function(){
|
||||
self.db.remove_order(order_id);
|
||||
var pending = self.db.get_orders().length;
|
||||
self.set('synch',{state: pending ? 'connecting' : 'connected', pending:pending});
|
||||
});
|
||||
|
||||
return rpc;
|
||||
_flush_order: function( order_id, options) {
|
||||
return this._flush_all_orders([this.db.get_order(order_id)], options);
|
||||
},
|
||||
|
||||
// attempts to send all the locally stored orders. As with _flush_order, it should only be
|
||||
// called from within a mutex.
|
||||
// this method returns a deferred that always succeeds when all orders have been tried to be sent,
|
||||
// even if none of them could actually be sent.
|
||||
_flush_all_orders: function(){
|
||||
_flush_all_orders: function () {
|
||||
var self = this;
|
||||
var orders = this.db.get_orders();
|
||||
var tried_all = new $.Deferred();
|
||||
self.set('synch', {
|
||||
state: 'connecting',
|
||||
pending: self.get('synch').pending
|
||||
});
|
||||
return self._save_to_server(self.db.get_orders()).done(function () {
|
||||
var pending = self.db.get_orders().length;
|
||||
self.set('synch', {
|
||||
state: pending ? 'connecting' : 'connected',
|
||||
pending: pending
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
function rec_flush(index){
|
||||
if(index < orders.length){
|
||||
self._flush_order(orders[index].id).always(function(){
|
||||
rec_flush(index+1);
|
||||
})
|
||||
}else{
|
||||
tried_all.resolve();
|
||||
}
|
||||
// send an array of orders to the server
|
||||
// available options:
|
||||
// - timeout: timeout for the rpc call in ms
|
||||
_save_to_server: function (orders, options) {
|
||||
if (!orders || !orders.length) {
|
||||
var result = $.Deferred();
|
||||
result.resolve();
|
||||
return result;
|
||||
}
|
||||
rec_flush(0);
|
||||
|
||||
options = options || {};
|
||||
|
||||
return tried_all;
|
||||
var self = this;
|
||||
var timeout = typeof options.timeout === 'number' ? options.timeout : 7500 * orders.length;
|
||||
|
||||
// we try to send the order. shadow prevents a spinner if it takes too long. (unless we are sending an invoice,
|
||||
// then we want to notify the user that we are waiting on something )
|
||||
var posOrderModel = new instance.web.Model('pos.order');
|
||||
return posOrderModel.call('create_from_ui',
|
||||
[_.map(orders, function (order) {
|
||||
order.to_invoice = options.to_invoice || false;
|
||||
return order;
|
||||
})],
|
||||
undefined,
|
||||
{
|
||||
shadow: !options.to_invoice,
|
||||
timeout: timeout
|
||||
}
|
||||
).then(function () {
|
||||
_.each(orders, function (order) {
|
||||
self.db.remove_order(order.id);
|
||||
});
|
||||
}).fail(function (unused, event){
|
||||
// prevent an error popup creation by the rpc failure
|
||||
// we want the failure to be silent as we send the orders in the background
|
||||
event.preventDefault();
|
||||
console.error('Failed to send orders:', orders);
|
||||
});
|
||||
},
|
||||
|
||||
scan_product: function(parsed_code){
|
||||
|
|
Loading…
Reference in New Issue