From cda132bba59a73aba1539094ad88d1a66e77d09e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Snauwaert?= Date: Wed, 17 Aug 2016 11:55:20 +0200 Subject: [PATCH] [FIX] account: fix several problem related to exchange rate entries. Was PR #13162 When an exchange rate entries was created, fields `exchange_move_id` and `exchange_partial_rec_id` were not set on account_full_reconcile. which implies that when unreconciling entries we had the exchange rate entry that was not reconciled with its reversal move. Another problem fixed is an infinite recursion loop that occured when trying to unreconcile entries with a `full_reconcile_id` and an exchange rate entry that is reconciled with more than one journal item. In that case, the unlink() of account.partial.reconcile has to be done before trying to reconcile the exchange rate entry with the reverse move otherwise as the exchange rate entry is still reconciled with another aml, `amount_residual_currency` is not correct and hence the program tries to create another exchange rate entry and loops. --- addons/account/models/account_move.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index 5676536425a..f8a5007c7e8 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -937,6 +937,8 @@ class AccountMoveLine(models.Model): currency = False aml_to_balance_currency = self.env['account.move.line'] partial_rec_set = self.env['account.partial.reconcile'] + aml_id = False + partial_rec_id = False maxdate = None for aml in self: total_debit += aml.debit @@ -957,6 +959,7 @@ class AccountMoveLine(models.Model): aml_id, partial_rec_id = partial_rec.with_context(skip_full_reconcile_check=True).create_exchange_rate_entry(aml_to_balance_currency, 0.0, total_amount_currency, currency, maxdate) self |= aml_id partial_rec_set |= partial_rec_id + total_amount_currency += aml_id.amount_currency partial_rec_ids = [x.id for x in list(partial_rec_set)] #if the total debit and credit are equal, and the total amount in currency is 0, the reconciliation is full @@ -966,7 +969,9 @@ class AccountMoveLine(models.Model): #in that case, mark the reference on the partial reconciliations and the entries self.env['account.full.reconcile'].with_context(check_move_validity=False).create({ 'partial_reconcile_ids': [(6, 0, partial_rec_ids)], - 'reconciled_line_ids': [(6, 0, self.ids)]}) + 'reconciled_line_ids': [(6, 0, self.ids)], + 'exchange_move_id': aml_id.move_id.id if aml_id else False, + 'exchange_partial_rec_id': partial_rec_id.id if partial_rec_id else False}) @api.multi def remove_move_reconcile(self): @@ -1426,8 +1431,9 @@ class AccountPartialReconcile(models.Model): def unlink(self): """ When removing a partial reconciliation, also unlink its full reconciliation if it exists """ to_unlink = self + full_to_unlink = self.env['account.full.reconcile'] + res = True if self._context.get('full_rec_lookup', True): - full_to_unlink = self.env['account.full.reconcile'] for rec in self: #exclude partial reconciliations related to an exchange rate entry, because the unlink of the full reconciliation will already do it if self.env['account.full.reconcile'].search([('exchange_partial_rec_id', '=', rec.id)]): @@ -1435,11 +1441,11 @@ class AccountPartialReconcile(models.Model): #without the deleted partial reconciliations, the full reconciliation won't be full anymore if rec.full_reconcile_id: full_to_unlink |= rec.full_reconcile_id - if full_to_unlink: - full_to_unlink.unlink() if to_unlink: - return super(AccountPartialReconcile, to_unlink).unlink() - return True + res = super(AccountPartialReconcile, to_unlink).unlink() + if full_to_unlink: + full_to_unlink.unlink() + return res class AccountFullReconcile(models.Model): _name = "account.full.reconcile" @@ -1470,7 +1476,8 @@ class AccountFullReconcile(models.Model): if aml.account_id.reconcile: break if aml: - if aml.debit: + precision = aml.currency_id and aml.currency_id.rounding or aml.company_id.currency_id.rounding + if aml.debit or float_compare(aml.amount_currency, 0, precision_rounding=precision) == 1: pair_to_rec = aml | rec.exchange_partial_rec_id.credit_move_id else: pair_to_rec = aml | rec.exchange_partial_rec_id.debit_move_id