From 32e7dfe0c4f33cdd76ed186500b5982ca3d3fb48 Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Tue, 24 Apr 2018 10:59:18 +0200 Subject: [PATCH] [FIX] account: unreconcile payment - Company currency in EUR - Create 2 rates for USD: 1.0 on 2018-01-01 0.5 on 2018-02-01 - Create an invoice on 2018-01-02 of 111 USD - Register a payment on 2018-02-02 of 111 USD - Unreconcile the payment An error occurs: 'You are trying to reconcile some entries that are already reconciled!' In this specific case where the rate decreases, the exchange rate entry is reconciled with the payment, so we need to keep the payment entries. --- addons/account/models/account_move.py | 3 +- addons/account/tests/test_reconciliation.py | 48 +++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index 727bdf298ae..fe5e0564e30 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -1175,8 +1175,9 @@ class AccountMoveLine(models.Model): rec_move_ids += account_move_line.matched_credit_ids if self.env.context.get('invoice_id'): current_invoice = self.env['account.invoice'].browse(self.env.context['invoice_id']) + aml_to_keep = current_invoice.move_id.line_ids | current_invoice.move_id.line_ids.mapped('full_reconcile_id.exchange_move_id.line_ids') rec_move_ids = rec_move_ids.filtered( - lambda r: (r.debit_move_id + r.credit_move_id) & current_invoice.move_id.line_ids + lambda r: (r.debit_move_id + r.credit_move_id) & aml_to_keep ) return rec_move_ids.unlink() diff --git a/addons/account/tests/test_reconciliation.py b/addons/account/tests/test_reconciliation.py index 84c8092234b..286e623c0da 100644 --- a/addons/account/tests/test_reconciliation.py +++ b/addons/account/tests/test_reconciliation.py @@ -657,3 +657,51 @@ class TestReconciliation(AccountingTestCase): credit_aml.with_context(invoice_id=inv2.id).remove_move_reconcile() self.assertAlmostEquals(inv1.residual, 10) self.assertAlmostEquals(inv2.residual, 20) + + def test_unreconcile_exchange(self): + # Use case: + # - Company currency in EUR + # - Create 2 rates for USD: + # 1.0 on 2018-01-01 + # 0.5 on 2018-02-01 + # - Create an invoice on 2018-01-02 of 111 USD + # - Register a payment on 2018-02-02 of 111 USD + # - Unreconcile the payment + + self.env['res.currency.rate'].create({ + 'name': time.strftime('%Y') + '-07-01', + 'rate': 1.0, + 'currency_id': self.currency_usd_id, + 'company_id': self.env.ref('base.main_company').id + }) + self.env['res.currency.rate'].create({ + 'name': time.strftime('%Y') + '-08-01', + 'rate': 0.5, + 'currency_id': self.currency_usd_id, + 'company_id': self.env.ref('base.main_company').id + }) + inv = self.create_invoice(invoice_amount=111, currency_id=self.currency_usd_id) + payment = self.env['account.payment'].create({ + 'payment_type': 'inbound', + 'payment_method_id': self.env.ref('account.account_payment_method_manual_in').id, + 'partner_type': 'customer', + 'partner_id': self.partner_agrolait_id, + 'amount': 111, + 'currency_id': self.currency_usd_id, + 'journal_id': self.bank_journal_usd.id, + 'payment_date': time.strftime('%Y') + '-08-01', + }) + payment.post() + credit_aml = payment.move_line_ids.filtered('credit') + + # Check residual before assignation + self.assertAlmostEquals(inv.residual, 111) + + # Assign credit, check exchange move and residual + inv.assign_outstanding_credit(credit_aml.id) + self.assertEqual(len(payment.move_line_ids.mapped('full_reconcile_id').exchange_move_id), 1) + self.assertAlmostEquals(inv.residual, 0) + + # Unreconcile invoice and check residual + credit_aml.with_context(invoice_id=inv.id).remove_move_reconcile() + self.assertAlmostEquals(inv.residual, 111)