From f40e9ecfc30ba93a2b931a485565660f819436ad Mon Sep 17 00:00:00 2001 From: Joren Van Onder Date: Wed, 6 Apr 2016 15:24:30 +0200 Subject: [PATCH] [FIX] point_of_sale: match payment to order amount when invoicing The POS generates journal entries for both the amount of money the customer pays and the amount of money the POS user returns to the customer (the 'change'). Whether or not this is the correct thing to do is up for debate, but we can't change that in stable anyway. One of the main issues is that in 9.0 accounting will propose unreconciled payments belonging to the customer on open, unpaid invoices. This does not work well with the account entries generated by the POS. Accounting will propose the amount the customer paid, without taking into account the change. Example: a customer buys $7 worth of products and pays with a $10 bill. The customer gets $3 change. The invoice will propose the $10 payment. When you add that payment to the invoice a residual amount ($3 in the example) will remain on the paymentline, complicating everything even more. Although we cannot change how the POS does accounting in a stable release, we at least want people to be able to easily handle invoices generated through the POS. To achieve that this patch will make the backend match the payment to the total amount of the invoice removing any potential change. opw-671486 --- addons/point_of_sale/point_of_sale.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/addons/point_of_sale/point_of_sale.py b/addons/point_of_sale/point_of_sale.py index 2115fdd5249..5d0b3526740 100644 --- a/addons/point_of_sale/point_of_sale.py +++ b/addons/point_of_sale/point_of_sale.py @@ -701,6 +701,23 @@ class pos_order(osv.osv): return new_session_id + def _match_payment_to_invoice(self, cr, uid, order, context=None): + account_precision = self.pool.get('decimal.precision').precision_get(cr, uid, 'Account') + + # ignore orders with an amount_paid of 0 because those are returns through the POS + if not float_is_zero(order['amount_return'], account_precision) and not float_is_zero(order['amount_paid'], account_precision): + cur_amount_paid = 0 + payments_to_keep = [] + for payment in order.get('statement_ids'): + if cur_amount_paid + payment[2]['amount'] > order['amount_total']: + payment[2]['amount'] = order['amount_total'] - cur_amount_paid + payments_to_keep.append(payment) + break + cur_amount_paid += payment[2]['amount'] + payments_to_keep.append(payment) + order['statement_ids'] = payments_to_keep + order['amount_return'] = 0 + def _process_order(self, cr, uid, order, context=None): session = self.pool.get('pos.session').browse(cr, uid, order['pos_session_id'], context=context) @@ -757,6 +774,10 @@ class pos_order(osv.osv): for tmp_order in orders_to_save: to_invoice = tmp_order['to_invoice'] order = tmp_order['data'] + + if to_invoice: + self._match_payment_to_invoice(cr, uid, order, context=context) + order_id = self._process_order(cr, uid, order, context=context) order_ids.append(order_id)