[FIX] account: fix reconciliation and creation of exchange rate entries
fixed cases:
1) having more than one account.move.line with a residual amount. This can easily be achieved by
-make a first invoice
-partially pay it
-make a second invoice
-partially pay it
-make a payment of the remaining amount
-reconcile the lines together
2) having more than one foreign currency involved, with several ecxhange difference to book
This commit is contained in:
@@ -246,11 +246,13 @@ class AccountMove(models.Model):
|
||||
#unreconcile all lines reversed
|
||||
aml = ac_move.line_ids.filtered(lambda x: x.account_id.reconcile or x.account_id.internal_type == 'liquidity')
|
||||
aml.remove_move_reconcile()
|
||||
#reconcile together the reconciliable and the liquidity aml and their newly created counterpart
|
||||
for account in [x.account_id for x in aml]:
|
||||
#reconcile together the reconciliable (or the liquidity aml) and their newly created counterpart
|
||||
for account in list(set([x.account_id for x in aml])):
|
||||
to_rec = aml.filtered(lambda y: y.account_id == account)
|
||||
to_rec |= reversed_move.line_ids.filtered(lambda y: y.account_id == account)
|
||||
to_rec.reconcile()
|
||||
#reconciliation will be full, so speed up the computation by using skip_full_reconcile_check in the context
|
||||
to_rec.with_context(skip_full_reconcile_check=True).reconcile()
|
||||
to_rec.force_full_reconcile()
|
||||
if reversed_moves:
|
||||
reversed_moves._post_validate()
|
||||
reversed_moves.post()
|
||||
@@ -319,8 +321,7 @@ class AccountMoveLine(models.Model):
|
||||
rate = line.currency_id.with_context(date=date).rate
|
||||
amount_residual_currency += sign_partial_line * line.currency_id.round(partial_line.amount * rate)
|
||||
|
||||
#computing the `reconciled` field. As we book exchange rate difference on each partial matching,
|
||||
#we can only check the amount in company currency
|
||||
#computing the `reconciled` field.
|
||||
reconciled = False
|
||||
digits_rounding_precision = line.company_id.currency_id.rounding
|
||||
if float_is_zero(amount, precision_rounding=digits_rounding_precision):
|
||||
@@ -889,9 +890,6 @@ class AccountMoveLine(models.Model):
|
||||
|
||||
if self._context.get('skip_full_reconcile_check') == 'amount_currency_excluded':
|
||||
amount_reconcile_currency = 0.0
|
||||
currency = self._context.get('manual_full_reconcile_currency')
|
||||
elif self._context.get('skip_full_reconcile_check') == 'amount_currency_only':
|
||||
currency = self._context.get('manual_full_reconcile_currency')
|
||||
|
||||
self.env['account.partial.reconcile'].create({
|
||||
'debit_move_id': sm_debit_move.id,
|
||||
@@ -1014,54 +1012,54 @@ class AccountMoveLine(models.Model):
|
||||
# Return the writeoff move.line which is to be reconciled
|
||||
return writeoff_move.line_ids.filtered(lambda r: r.account_id == self[0].account_id)
|
||||
|
||||
@api.model
|
||||
def compute_full_after_batch_reconcile(self):
|
||||
def force_full_reconcile(self):
|
||||
""" After running the manual reconciliation wizard and making full reconciliation, we need to run this method to create
|
||||
potentially an exchange rate entry that will balance the remaining amount_residual_currency (possibly several aml).
|
||||
potentially exchange rate entries that will balance the remaining amount_residual_currency (possibly several aml in
|
||||
different currencies).
|
||||
|
||||
This ensure that all aml in the full reconciliation are reconciled (amount_residual = amount_residual_currency = 0).
|
||||
"""
|
||||
total_debit = 0
|
||||
total_credit = 0
|
||||
total_amount_currency = 0
|
||||
currency = False
|
||||
aml_to_balance_currency = self.env['account.move.line']
|
||||
aml_to_balance_currency = {}
|
||||
partial_rec_set = self.env['account.partial.reconcile']
|
||||
aml_id = False
|
||||
partial_rec_id = False
|
||||
maxdate = '0000-00-00'
|
||||
|
||||
#gather the max date for the move creation, and all aml that are unbalanced
|
||||
for aml in self:
|
||||
total_debit += aml.debit
|
||||
total_credit += aml.credit
|
||||
if aml.amount_residual_currency:
|
||||
aml_to_balance_currency |= aml
|
||||
maxdate = max(aml.date, maxdate)
|
||||
if not currency and aml.currency_id:
|
||||
currency = aml.currency_id
|
||||
if aml.currency_id and aml.currency_id == currency:
|
||||
total_amount_currency += aml.amount_currency
|
||||
if aml.amount_residual_currency:
|
||||
if aml.currency_id not in aml_to_balance_currency:
|
||||
aml_to_balance_currency[aml.currency_id] = [self.env['account.move.line'], 0]
|
||||
aml_to_balance_currency[aml.currency_id][0] |= aml
|
||||
aml_to_balance_currency[aml.currency_id][1] += aml.amount_residual_currency
|
||||
partial_rec_set |= aml.matched_debit_ids | aml.matched_credit_ids
|
||||
|
||||
if currency and aml_to_balance_currency:
|
||||
aml = aml_to_balance_currency[0]
|
||||
#eventually create journal entries to book the difference due to foreign currency's exchange rate that fluctuates
|
||||
partial_rec = aml.credit and aml.matched_debit_ids[0] or aml.matched_credit_ids[0]
|
||||
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
|
||||
#create an empty move that will hold all the exchange rate adjustments
|
||||
exchange_move = False
|
||||
if aml_to_balance_currency:
|
||||
exchange_move = self.env['account.move'].create(
|
||||
self.env['account.full.reconcile']._prepare_exchange_diff_move(move_date=maxdate, company=self[0].company_id))
|
||||
|
||||
for currency, values in aml_to_balance_currency.items():
|
||||
aml_to_balance = values[0]
|
||||
total_amount_currency = values[1]
|
||||
#eventually create journal entries to book the difference due to foreign currency's exchange rate that fluctuates
|
||||
aml_recs, partial_recs = self.env['account.partial.reconcile'].create_exchange_rate_entry(aml_to_balance, 0.0, total_amount_currency, currency, exchange_move)
|
||||
|
||||
#add the ecxhange rate line and the exchange rate partial reconciliation in the et of the full reconcile
|
||||
self |= aml_recs
|
||||
partial_rec_set |= partial_recs
|
||||
|
||||
if exchange_move:
|
||||
exchange_move.post()
|
||||
|
||||
#mark the reference on the partial reconciliations and the entries
|
||||
#Note that we should always have all lines with an amount_residual and an amount_residual_currency equal to 0
|
||||
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
|
||||
digits_rounding_precision = self[0].company_id.currency_id.rounding
|
||||
if float_compare(total_debit, total_credit, precision_rounding=digits_rounding_precision) == 0 \
|
||||
and (not currency or float_is_zero(total_amount_currency, precision_rounding=currency.rounding)):
|
||||
#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)],
|
||||
'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})
|
||||
self.env['account.full.reconcile'].create({
|
||||
'partial_reconcile_ids': [(6, 0, partial_rec_ids)],
|
||||
'reconciled_line_ids': [(6, 0, self.ids)],
|
||||
'exchange_move_id': exchange_move.id if exchange_move else False,
|
||||
})
|
||||
|
||||
@api.multi
|
||||
def remove_move_reconcile(self):
|
||||
@@ -1455,49 +1453,8 @@ class AccountPartialReconcile(models.Model):
|
||||
fields.Datetime.from_string(rec.credit_move_id.date)
|
||||
)
|
||||
|
||||
@api.multi
|
||||
def _prepare_exchange_diff_line_to_reconcile(self, amount_diff, currency, diff_in_currency, move):
|
||||
self.ensure_one()
|
||||
return {
|
||||
'name': _('Currency exchange rate difference'),
|
||||
'debit': amount_diff < 0 and -amount_diff or 0.0,
|
||||
'credit': amount_diff > 0 and amount_diff or 0.0,
|
||||
'account_id': self.debit_move_id.account_id.id,
|
||||
'move_id': move.id,
|
||||
'currency_id': currency.id,
|
||||
'amount_currency': -diff_in_currency,
|
||||
'partner_id': self.debit_move_id.partner_id.id,
|
||||
}
|
||||
|
||||
@api.multi
|
||||
def _prepare_exchange_diff_move_line(self, amount_diff, currency, diff_in_currency, move):
|
||||
self.ensure_one()
|
||||
exchange_journal = self.company_id.currency_exchange_journal_id
|
||||
return {
|
||||
'name': _('Currency exchange rate difference'),
|
||||
'debit': amount_diff > 0 and amount_diff or 0.0,
|
||||
'credit': amount_diff < 0 and -amount_diff or 0.0,
|
||||
'account_id': amount_diff > 0 and exchange_journal.default_debit_account_id.id or exchange_journal.default_credit_account_id.id,
|
||||
'move_id': move.id,
|
||||
'currency_id': currency.id,
|
||||
'amount_currency': diff_in_currency,
|
||||
'partner_id': self.debit_move_id.partner_id.id,
|
||||
}
|
||||
|
||||
@api.multi
|
||||
def _prepare_exchange_diff_move(self, move_date):
|
||||
self.ensure_one()
|
||||
res = {'journal_id': self.company_id.currency_exchange_journal_id.id}
|
||||
# The move date should be the maximum date between payment and invoice
|
||||
# (in case of payment in advance). However, we should make sure the
|
||||
# move date is not recorded after the end of year closing.
|
||||
if (move_date or '0000-00-00' > self.company_id.fiscalyear_lock_date or '0000-00-00'):
|
||||
res['date'] = move_date
|
||||
return res
|
||||
|
||||
@api.multi
|
||||
@api.model
|
||||
def _prepare_exchange_diff_partial_reconcile(self, aml, line_to_reconcile, currency):
|
||||
self.ensure_one()
|
||||
return {
|
||||
'debit_move_id': aml.credit and line_to_reconcile.id or aml.id,
|
||||
'credit_move_id': aml.debit and line_to_reconcile.id or aml.id,
|
||||
@@ -1506,56 +1463,68 @@ class AccountPartialReconcile(models.Model):
|
||||
'currency_id': currency.id,
|
||||
}
|
||||
|
||||
def create_exchange_rate_entry(self, aml_to_fix, amount_diff, diff_in_currency, currency, move_date):
|
||||
@api.model
|
||||
def create_exchange_rate_entry(self, aml_to_fix, amount_diff, diff_in_currency, currency, move):
|
||||
"""
|
||||
Automatically create a journal entry to book the exchange rate
|
||||
difference. That new journal entry is made in the company
|
||||
`currency_exchange_journal_id` and one of its journal items is
|
||||
Automatically create a journal items to book the exchange rate
|
||||
differences that can occure in multi-currencies environment. That
|
||||
new journal item will be made into the given `move` in the company
|
||||
`currency_exchange_journal_id`, and one of its journal items is
|
||||
matched with the other lines to balance the full reconciliation.
|
||||
:param aml_to_fix: account.move.line
|
||||
:param amount_diff: float
|
||||
:param diff_in_currency: float
|
||||
|
||||
:param aml_to_fix: recordset of account.move.line (possible several
|
||||
but sharing the same currency)
|
||||
:param amount_diff: float. Amount in company currency to fix
|
||||
:param diff_in_currency: float. Amount in foreign currency `currency`
|
||||
to fix
|
||||
:param currency: res.currency
|
||||
:param move_date: date
|
||||
:return: account.move.line to reconcile and account.partial.reconcile
|
||||
:param move: account.move
|
||||
:return: tuple.
|
||||
[0]: account.move.line created to balance the `aml_to_fix`
|
||||
[1]: recordset of account.partial.reconcile created between the
|
||||
tuple first element and the `aml_to_fix`
|
||||
"""
|
||||
for rec in self:
|
||||
if not rec.company_id.currency_exchange_journal_id:
|
||||
raise UserError(_("You should configure the 'Exchange Rate Journal' in the accounting settings, to manage automatically the booking of accounting entries related to differences between exchange rates."))
|
||||
if not rec.company_id.income_currency_exchange_account_id.id:
|
||||
raise UserError(_("You should configure the 'Gain Exchange Rate Account' in the accounting settings, to manage automatically the booking of accounting entries related to differences between exchange rates."))
|
||||
if not rec.company_id.expense_currency_exchange_account_id.id:
|
||||
raise UserError(_("You should configure the 'Loss Exchange Rate Account' in the accounting settings, to manage automatically the booking of accounting entries related to differences between exchange rates."))
|
||||
partial_rec = self.env['account.partial.reconcile']
|
||||
aml_model = self.env['account.move.line']
|
||||
|
||||
move = rec.env['account.move'].create(
|
||||
rec._prepare_exchange_diff_move(move_date=move_date))
|
||||
amount_diff = move.company_id.currency_id.round(amount_diff)
|
||||
diff_in_currency = currency and currency.round(diff_in_currency) or 0
|
||||
|
||||
amount_diff = rec.company_id.currency_id.round(amount_diff)
|
||||
diff_in_currency = currency.round(diff_in_currency)
|
||||
aml_model = rec.env['account.move.line']
|
||||
aml_model.with_context(check_move_validity=False).create(
|
||||
rec._prepare_exchange_diff_move_line(
|
||||
amount_diff=amount_diff,
|
||||
currency=currency,
|
||||
diff_in_currency=diff_in_currency,
|
||||
move=move))
|
||||
created_lines = self.env['account.move.line']
|
||||
for aml in aml_to_fix:
|
||||
#create the line that will compensate all the aml_to_fix
|
||||
line_to_rec = aml_model.with_context(check_move_validity=False).create({
|
||||
'name': _('Currency exchange rate difference'),
|
||||
'debit': amount_diff < 0 and -aml.amount_residual or 0.0,
|
||||
'credit': amount_diff > 0 and aml.amount_residual or 0.0,
|
||||
'account_id': aml.account_id.id,
|
||||
'move_id': move.id,
|
||||
'currency_id': currency.id,
|
||||
'amount_currency': diff_in_currency and -aml.amount_residual_currency or 0.0,
|
||||
'partner_id': aml.partner_id.id,
|
||||
})
|
||||
#create the counterpart on exchange gain/loss account
|
||||
exchange_journal = move.company_id.currency_exchange_journal_id
|
||||
aml_model.with_context(check_move_validity=False).create({
|
||||
'name': _('Currency exchange rate difference'),
|
||||
'debit': amount_diff > 0 and aml.amount_residual or 0.0,
|
||||
'credit': amount_diff < 0 and -aml.amount_residual or 0.0,
|
||||
'account_id': amount_diff > 0 and exchange_journal.default_debit_account_id.id or exchange_journal.default_credit_account_id.id,
|
||||
'move_id': move.id,
|
||||
'currency_id': currency.id,
|
||||
'amount_currency': diff_in_currency and aml.amount_residual_currency or 0.0,
|
||||
'partner_id': aml.partner_id.id,
|
||||
})
|
||||
|
||||
line_to_reconcile = aml_model.create(
|
||||
rec._prepare_exchange_diff_line_to_reconcile(
|
||||
amount_diff=amount_diff,
|
||||
currency=currency,
|
||||
diff_in_currency=diff_in_currency,
|
||||
move=move))
|
||||
|
||||
for aml in aml_to_fix:
|
||||
partial_rec = rec.env['account.partial.reconcile'].create(
|
||||
rec._prepare_exchange_diff_partial_reconcile(
|
||||
#reconcile all aml_to_fix
|
||||
partial_rec |= self.with_context(skip_full_reconcile_check=True).create(
|
||||
self._prepare_exchange_diff_partial_reconcile(
|
||||
aml=aml,
|
||||
line_to_reconcile=line_to_reconcile,
|
||||
line_to_reconcile=line_to_rec,
|
||||
currency=currency)
|
||||
)
|
||||
move.post()
|
||||
return line_to_reconcile, partial_rec
|
||||
)
|
||||
created_lines |= line_to_rec
|
||||
return created_lines, partial_rec
|
||||
|
||||
def create_tax_cash_basis_entry(self, percentage_before_rec):
|
||||
self.ensure_one()
|
||||
@@ -1690,7 +1659,7 @@ class AccountPartialReconcile(models.Model):
|
||||
#possible to compute the exchange difference entry and it has to be done manually.
|
||||
currency = list(partial_rec_set)[0].currency_id
|
||||
maxdate = '0000-00-00'
|
||||
aml_to_balance = None
|
||||
aml_to_balance = self.env['account.move.line']
|
||||
for partial_rec in partial_rec_set:
|
||||
if partial_rec.currency_id != currency:
|
||||
#no exchange rate entry will be created
|
||||
@@ -1698,7 +1667,7 @@ class AccountPartialReconcile(models.Model):
|
||||
for aml in [partial_rec.debit_move_id, partial_rec.credit_move_id]:
|
||||
if aml not in aml_set:
|
||||
if aml.amount_residual or aml.amount_residual_currency:
|
||||
aml_to_balance = aml
|
||||
aml_to_balance |= aml
|
||||
maxdate = max(aml.date, maxdate)
|
||||
total_debit += aml.debit
|
||||
total_credit += aml.credit
|
||||
@@ -1716,22 +1685,23 @@ class AccountPartialReconcile(models.Model):
|
||||
aml_ids = aml_set.ids
|
||||
#then, if the total debit and credit are equal, or the total amount in currency is 0, the reconciliation is full
|
||||
digits_rounding_precision = aml_set[0].company_id.currency_id.rounding
|
||||
|
||||
if (currency and float_is_zero(total_amount_currency, precision_rounding=currency.rounding)) or float_compare(total_debit, total_credit, precision_rounding=digits_rounding_precision) == 0:
|
||||
exchange_move_id = False
|
||||
exchange_partial_rec_id = False
|
||||
if currency and aml_to_balance:
|
||||
exchange_move = self.env['account.move'].create(
|
||||
self.env['account.full.reconcile']._prepare_exchange_diff_move(move_date=maxdate, company=aml_to_balance[0].company_id))
|
||||
#eventually create a journal entry to book the difference due to foreign currency's exchange rate that fluctuates
|
||||
rate_diff_aml, rate_diff_partial_rec = partial_rec.create_exchange_rate_entry(aml_to_balance, total_debit - total_credit, total_amount_currency, currency, maxdate)
|
||||
aml_ids.append(rate_diff_aml.id)
|
||||
partial_rec_ids.append(rate_diff_partial_rec.id)
|
||||
exchange_move_id = rate_diff_aml.move_id.id
|
||||
exchange_partial_rec_id = rate_diff_partial_rec.id
|
||||
rate_diff_amls, rate_diff_partial_rec = self.create_exchange_rate_entry(aml_to_balance, total_debit - total_credit, total_amount_currency, currency, exchange_move)
|
||||
aml_ids += rate_diff_amls.ids
|
||||
partial_rec_ids += rate_diff_partial_rec.ids
|
||||
exchange_move.post()
|
||||
exchange_move_id = exchange_move.id
|
||||
#mark the reference of the full reconciliation on the partial ones and on the entries
|
||||
self.env['account.full.reconcile'].with_context(check_move_validity=False).create({
|
||||
'partial_reconcile_ids': [(4, p_id) for p_id in partial_rec_ids],
|
||||
'reconciled_line_ids': [(4, a_id) for a_id in aml_ids],
|
||||
self.env['account.full.reconcile'].create({
|
||||
'partial_reconcile_ids': [(6, 0, partial_rec_ids)],
|
||||
'reconciled_line_ids': [(6, 0, aml_ids)],
|
||||
'exchange_move_id': exchange_move_id,
|
||||
'exchange_partial_rec_id': exchange_partial_rec_id,
|
||||
})
|
||||
return res
|
||||
|
||||
@@ -1760,7 +1730,6 @@ class AccountFullReconcile(models.Model):
|
||||
partial_reconcile_ids = fields.One2many('account.partial.reconcile', 'full_reconcile_id', string='Reconciliation Parts')
|
||||
reconciled_line_ids = fields.One2many('account.move.line', 'full_reconcile_id', string='Matched Journal Items')
|
||||
exchange_move_id = fields.Many2one('account.move')
|
||||
exchange_partial_rec_id = fields.Many2one('account.partial.reconcile')
|
||||
|
||||
@api.multi
|
||||
def unlink(self):
|
||||
@@ -1778,3 +1747,19 @@ class AccountFullReconcile(models.Model):
|
||||
rec.exchange_move_id = False
|
||||
to_reverse.reverse_moves()
|
||||
return super(AccountFullReconcile, self).unlink()
|
||||
|
||||
@api.model
|
||||
def _prepare_exchange_diff_move(self, move_date, company):
|
||||
if not company.currency_exchange_journal_id:
|
||||
raise UserError(_("You should configure the 'Exchange Rate Journal' in the accounting settings, to manage automatically the booking of accounting entries related to differences between exchange rates."))
|
||||
if not company.income_currency_exchange_account_id.id:
|
||||
raise UserError(_("You should configure the 'Gain Exchange Rate Account' in the accounting settings, to manage automatically the booking of accounting entries related to differences between exchange rates."))
|
||||
if not company.expense_currency_exchange_account_id.id:
|
||||
raise UserError(_("You should configure the 'Loss Exchange Rate Account' in the accounting settings, to manage automatically the booking of accounting entries related to differences between exchange rates."))
|
||||
res = {'journal_id': company.currency_exchange_journal_id.id}
|
||||
# The move date should be the maximum date between payment and invoice
|
||||
# (in case of payment in advance). However, we should make sure the
|
||||
# move date is not recorded after the end of year closing.
|
||||
if move_date > company.fiscalyear_lock_date:
|
||||
res['date'] = move_date
|
||||
return res
|
||||
|
||||
@@ -520,7 +520,6 @@ class account_payment(models.Model):
|
||||
if counterpart_aml['credit']:
|
||||
counterpart_aml['credit'] += debit_wo - credit_wo
|
||||
counterpart_aml['amount_currency'] -= amount_currency_wo
|
||||
self.invoice_ids.register_payment(counterpart_aml)
|
||||
|
||||
#Write counterpart lines
|
||||
if not self.currency_id != self.company_id.currency_id:
|
||||
@@ -529,7 +528,12 @@ class account_payment(models.Model):
|
||||
liquidity_aml_dict.update(self._get_liquidity_move_line_vals(-amount))
|
||||
aml_obj.create(liquidity_aml_dict)
|
||||
|
||||
#validate the payment
|
||||
move.post()
|
||||
|
||||
#reconcile the invoice receivable/payable line(s) with the payment
|
||||
self.invoice_ids.register_payment(counterpart_aml)
|
||||
|
||||
return move
|
||||
|
||||
def _create_transfer_entry(self, amount):
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from odoo import models, fields, api, _
|
||||
from odoo.tools.float_utils import float_round
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class AccountMoveLineReconcile(models.TransientModel):
|
||||
@@ -56,25 +55,14 @@ class AccountMoveLineReconcile(models.TransientModel):
|
||||
@api.multi
|
||||
def trans_rec_reconcile_full(self):
|
||||
move_lines = self.env['account.move.line'].browse(self._context.get('active_ids', []))
|
||||
currency = False
|
||||
for aml in move_lines:
|
||||
if not currency and aml.currency_id.id:
|
||||
currency = aml.currency_id.id
|
||||
elif aml.currency_id:
|
||||
if aml.currency_id.id == currency:
|
||||
continue
|
||||
raise UserError(_('Operation not allowed. You can only reconcile entries that share the same secondary currency or that don\'t have one. Edit your journal items or make another selection before proceeding any further.'))
|
||||
#Don't consider entrires that are already reconciled
|
||||
move_lines_filtered = move_lines.filtered(lambda aml: not aml.reconciled)
|
||||
#Because we are making a full reconcilition in batch, we need to consider use cases as defined in the test test_manual_reconcile_wizard_opw678153
|
||||
#So we force the reconciliation in company currency only at first
|
||||
move_lines_filtered.with_context(skip_full_reconcile_check='amount_currency_excluded', manual_full_reconcile_currency=currency).reconcile()
|
||||
move_lines_filtered.with_context(skip_full_reconcile_check='amount_currency_excluded').reconcile()
|
||||
|
||||
#then in second pass the amounts in secondary currency, only if some lines are still not fully reconciled
|
||||
move_lines_filtered = move_lines.filtered(lambda aml: not aml.reconciled)
|
||||
if move_lines_filtered:
|
||||
move_lines_filtered.with_context(skip_full_reconcile_check='amount_currency_only', manual_full_reconcile_currency=currency).reconcile()
|
||||
move_lines.compute_full_after_batch_reconcile()
|
||||
#then in second pass, consider the amounts in secondary currency (only if some lines are still not fully reconciled)
|
||||
move_lines.force_full_reconcile()
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
|
||||
@@ -119,26 +107,14 @@ class AccountMoveLineReconcileWriteoff(models.TransientModel):
|
||||
if self.analytic_id:
|
||||
context['analytic_id'] = self.analytic_id.id
|
||||
move_lines = self.env['account.move.line'].browse(self._context.get('active_ids', []))
|
||||
currency = False
|
||||
for aml in move_lines:
|
||||
if not currency and aml.currency_id.id:
|
||||
currency = aml.currency_id.id
|
||||
elif aml.currency_id:
|
||||
if aml.currency_id.id == currency:
|
||||
continue
|
||||
raise UserError(_('Operation not allowed. You can only reconcile entries that share the same secondary currency or that don\'t have one. Edit your journal items or make another selection before proceeding any further.'))
|
||||
#Don't consider entrires that are already reconciled
|
||||
move_lines_filtered = move_lines.filtered(lambda aml: not aml.reconciled)
|
||||
#Because we are making a full reconcilition in batch, we need to consider use cases as defined in the test test_manual_reconcile_wizard_opw678153
|
||||
#So we force the reconciliation in company currency only at first,
|
||||
context['skip_full_reconcile_check'] = 'amount_currency_excluded'
|
||||
context['manual_full_reconcile_currency'] = currency
|
||||
writeoff = move_lines_filtered.with_context(context).reconcile(self.writeoff_acc_id, self.journal_id)
|
||||
#then in second pass the amounts in secondary currency, only if some lines are still not fully reconciled
|
||||
move_lines_filtered = move_lines.filtered(lambda aml: not aml.reconciled)
|
||||
if move_lines_filtered:
|
||||
move_lines_filtered.with_context(skip_full_reconcile_check='amount_currency_only', manual_full_reconcile_currency=currency).reconcile()
|
||||
#then in second pass, consider the amounts in secondary currency (only if some lines are still not fully reconciled)
|
||||
if not isinstance(writeoff, bool):
|
||||
move_lines += writeoff
|
||||
move_lines.compute_full_after_batch_reconcile()
|
||||
move_lines.force_full_reconcile()
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
Reference in New Issue
Block a user