[FIX] account: correctly reconcile refund from PoS

Current behavior:
In the PoS if you use 2 differents payment methods (cash and customer
account), and that the cash amount given by the client require you to
give some money back, the amount due on the customer account would be
incorrect on the invoice.

Steps to reproduce:
- Start a PoS session
- Add the 750$ desk to the order
- Go in the payment screen
- Add customer account with 300$
- Add cash with 460$
- Click on invoice
- The invoice show that the client need to pay 290$ which is not
  correct

Before the fix calling `_prepare_reconciliation_partials()`
with the sorted lines we had 2 credit lines (750€ and 10€)
and 1 debit line (460€).

Debit lines     |   Credit lines
460€            |   750€
                |   10€

The function would reconcile the 2 first lines and stop after that
because the only debit line was fully reconciled

After the fix we have this

Debit lines     |   Credit lines
460€            |   10€
                |   750€

After reconciling the 2 first lines we have this

Debit lines     |   Credit lines
450€            |   750€

And after reconciling the 2 last lines we have the correct amount left
to pay by the customer (300€)

opw-2857064

closes odoo/odoo#98828

X-original-commit: 1201123e272012b7b5ab65eebfd12a911ecc6c1a
Signed-off-by: William André (wan) <wan@odoo.com>
Signed-off-by: Engels Robin (roen) <roen@odoo.com>
This commit is contained in:
roen-odoo
2022-08-25 10:32:12 +02:00
parent 55b5f3d7d9
commit f373482b29
3 changed files with 62 additions and 3 deletions
+1 -1
View File
@@ -2140,7 +2140,7 @@ class AccountMoveLine(models.Model):
raise UserError(_("Entries are not from the same account: %s != %s")
% (account.display_name, line.account_id.display_name))
sorted_lines = self.sorted(key=lambda line: (line.date_maturity or line.date, line.currency_id))
sorted_lines = self.sorted(key=lambda line: (line.date_maturity or line.date, line.currency_id, line.amount_currency))
# ==== Collect all involved lines through the existing reconciliation ====
@@ -1154,3 +1154,62 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
refund.action_pos_order_invoice()
self.assertEqual(refund.picking_count, 1)
def test_order_with_different_payments_and_refund(self):
"""
Test that all the payments are correctly taken into account when the order contains multiple payments and money refund.
In this example, we create an order with two payments for a product of 750$:
- one payment of $300 with customer account
- one payment of $460 with cash
Then, we refund the order with $10, and check that the amount still due is 300$.
"""
product5 = self.env['product.product'].create({
'name': 'product5',
'type': 'product',
'categ_id': self.env.ref('product.product_category_all').id,
})
# sell product thru pos
self.pos_config.open_ui()
pos_session = self.pos_config.current_session_id
product5_order = {'data':
{'amount_paid': 750,
'amount_return': 10,
'amount_tax': 0,
'amount_total': 750,
'creation_date': fields.Datetime.to_string(fields.Datetime.now()),
'fiscal_position_id': False,
'pricelist_id': self.pos_config.available_pricelist_ids[0].id,
'lines': [[0, 0, {
'discount': 0,
'id': 42,
'pack_lot_ids': [],
'price_unit': 750.0,
'product_id': product5.id,
'price_subtotal': 750.0,
'price_subtotal_incl': 750.0,
'tax_ids': [[6, False, []]],
'qty': 1,
}]],
'name': 'Order 12345-123-1234',
'partner_id': self.partner1.id,
'pos_session_id': pos_session.id,
'sequence_number': 2,
'statement_ids': [[0, 0, {
'amount': 460,
'name': fields.Datetime.now(),
'payment_method_id': self.cash_payment_method.id
}], [0, 0, {
'amount': 300,
'name': fields.Datetime.now(),
'payment_method_id': self.credit_payment_method.id
}]],
'uid': '12345-123-1234',
'user_id': self.env.uid,
'to_invoice': True, }
}
pos_order_id = self.PosOrder.create_from_ui([product5_order])[0]['id']
pos_order = self.PosOrder.search([('id', '=', pos_order_id)])
#assert account_move amount_residual is 300
self.assertEqual(pos_order.account_move.amount_residual, 300)
@@ -1095,8 +1095,8 @@ class TestStockValuationWithCOA(AccountTestInvoicingCommon):
self.assertRecordValues(inv.line_ids.full_reconcile_id.reconciled_line_ids, [
# pylint: disable=C0326
# Exchange difference lines:
{'balance': 46.43, 'amount_currency': 0.0},
{'balance': 92.86, 'amount_currency': 0.0},
{'balance': 46.43, 'amount_currency': 0.0},
# Other lines:
{'balance': 50.0, 'amount_currency': 100.0},
{'balance': 25.0, 'amount_currency': 50.0},
@@ -1119,8 +1119,8 @@ class TestStockValuationWithCOA(AccountTestInvoicingCommon):
# pylint: disable=C0326
# Other lines:
{'balance': -187.5, 'amount_currency': -150.0},
{'balance': 90.91, 'amount_currency': 200.0},
{'balance': -22.73, 'amount_currency': -50.0},
{'balance': 90.91, 'amount_currency': 200.0},
# Exchange difference lines:
{'balance': 119.32, 'amount_currency': 0.0},
])