[FIX] account: Fix the register payment wizard in multi-currencies
- Create an invoice of 1200 MXN = 300 USD - Register a payment, select USD at a date at which 1200 MXN = 400 USD => The amount is incorrect, a difference is computed but it should be zero. closes odoo/odoo#91634 X-original-commit: d88f630dcb7f98a45c9efe7f2439a8732832c77c Signed-off-by: Quentin De Paoli <qdp@odoo.com>
This commit is contained in:
@@ -364,13 +364,8 @@ class TestAccountPaymentRegister(AccountTestInvoicingCommon):
|
||||
'group_payment': False,
|
||||
'amount': 1200.0
|
||||
})
|
||||
self.assertRecordValues(payment_register, [{'payment_difference': 1800.0}])
|
||||
payments = payment_register._create_payments()
|
||||
self.assertRecordValues(payment_register, [
|
||||
{
|
||||
'payment_difference': 1800.0 # Test _compute_payment_difference
|
||||
}
|
||||
])
|
||||
|
||||
self.assertRecordValues(payments, [
|
||||
{
|
||||
'ref': 'INV/2017/00001',
|
||||
@@ -1041,11 +1036,20 @@ class TestAccountPaymentRegister(AccountTestInvoicingCommon):
|
||||
|
||||
# Payment of 600 USD (equivalent to 1200 Gol in 2017).
|
||||
# 600.0 USD should be computed correctly to fully paid the invoices.
|
||||
payment = self.env['account.payment.register']\
|
||||
wizard = self.env['account.payment.register']\
|
||||
.with_context(active_model='account.move', active_ids=invoice.ids)\
|
||||
.create({'currency_id': self.company_data['currency'].id})\
|
||||
._create_payments()
|
||||
.create({
|
||||
'currency_id': self.company_data['currency'].id,
|
||||
'payment_date': '2017-01-01',
|
||||
})
|
||||
|
||||
self.assertRecordValues(wizard, [{
|
||||
'amount': 600.0,
|
||||
'payment_difference': 0.0,
|
||||
'currency_id': self.company_data['currency'].id,
|
||||
}])
|
||||
|
||||
payment = wizard._create_payments()
|
||||
lines = (invoice + payment.move_id).line_ids.filtered(lambda x: x.account_internal_type == 'receivable')
|
||||
self.assertRecordValues(lines, [
|
||||
{'amount_residual': 0.0, 'amount_residual_currency': 0.0, 'currency_id': self.currency_data['currency'].id, 'reconciled': True},
|
||||
@@ -1066,11 +1070,20 @@ class TestAccountPaymentRegister(AccountTestInvoicingCommon):
|
||||
|
||||
# Payment of 600 USD = 1200 Gol.
|
||||
# 1200.0 Gol should be computed correctly to fully paid the invoices.
|
||||
payment = self.env['account.payment.register']\
|
||||
wizard = self.env['account.payment.register']\
|
||||
.with_context(active_model='account.move', active_ids=invoice.ids)\
|
||||
.create({'currency_id': self.currency_data['currency'].id})\
|
||||
._create_payments()
|
||||
.create({
|
||||
'currency_id': self.currency_data['currency'].id,
|
||||
'payment_date': '2017-01-01',
|
||||
})
|
||||
|
||||
self.assertRecordValues(wizard, [{
|
||||
'amount': 1200.0,
|
||||
'payment_difference': 0.0,
|
||||
'currency_id': self.currency_data['currency'].id,
|
||||
}])
|
||||
|
||||
payment = wizard._create_payments()
|
||||
lines = (invoice + payment.move_id).line_ids.filtered(lambda x: x.account_internal_type == 'receivable')
|
||||
self.assertRecordValues(lines, [
|
||||
{'amount_residual': 0.0, 'amount_residual_currency': 0.0, 'currency_id': self.company_data['currency'].id, 'reconciled': True},
|
||||
|
||||
@@ -414,42 +414,52 @@ class AccountPaymentRegister(models.TransientModel):
|
||||
wizard.show_partner_bank_account = wizard.payment_method_line_id.code in self.env['account.payment']._get_method_codes_using_bank_account()
|
||||
wizard.require_partner_bank_account = wizard.payment_method_line_id.code in self.env['account.payment']._get_method_codes_needing_bank_account()
|
||||
|
||||
def _get_total_amount_in_wizard_currency_to_full_reconcile(self, batch_result):
|
||||
""" Compute the total amount needed in the currency of the wizard to fully reconcile the batch of journal
|
||||
items passed as parameter.
|
||||
|
||||
:param batch_result: A batch returned by '_get_batches'.
|
||||
:return: An amount in the currency of the wizard.
|
||||
"""
|
||||
self.ensure_one()
|
||||
comp_curr = self.company_id.currency_id
|
||||
if self.source_currency_id == self.currency_id:
|
||||
# Same currency.
|
||||
return self.source_amount_currency
|
||||
elif self.source_currency_id != comp_curr and self.currency_id == comp_curr:
|
||||
# Foreign currency on source line but the company currency one on the opposite line.
|
||||
return self.source_currency_id._convert(
|
||||
self.source_amount_currency,
|
||||
comp_curr,
|
||||
self.company_id,
|
||||
self.payment_date,
|
||||
)
|
||||
elif self.source_currency_id == comp_curr and self.currency_id != comp_curr:
|
||||
# Company currency on source line but a foreign currency one on the opposite line.
|
||||
return abs(sum(
|
||||
comp_curr._convert(
|
||||
aml.amount_residual,
|
||||
self.currency_id,
|
||||
self.company_id,
|
||||
aml.date,
|
||||
)
|
||||
for aml in batch_result['lines']
|
||||
))
|
||||
else:
|
||||
# Foreign currency on payment different than the one set on the journal entries.
|
||||
return comp_curr._convert(
|
||||
self.source_amount,
|
||||
self.currency_id,
|
||||
self.company_id,
|
||||
self.payment_date,
|
||||
)
|
||||
|
||||
@api.depends('can_edit_wizard', 'source_amount', 'source_amount_currency', 'source_currency_id', 'company_id', 'currency_id', 'payment_date')
|
||||
def _compute_amount(self):
|
||||
for wizard in self:
|
||||
if wizard.source_currency_id and wizard.can_edit_wizard:
|
||||
comp_curr = wizard.company_id.currency_id
|
||||
if wizard.source_currency_id == wizard.currency_id:
|
||||
# Same currency.
|
||||
wizard.amount = wizard.source_amount_currency
|
||||
elif wizard.source_currency_id != comp_curr and wizard.currency_id == comp_curr:
|
||||
# Foreign currency on source line but the company currency one on the opposite line.
|
||||
wizard.amount = wizard.source_currency_id._convert(
|
||||
wizard.source_amount_currency,
|
||||
comp_curr,
|
||||
wizard.company_id,
|
||||
wizard.payment_date,
|
||||
)
|
||||
elif wizard.source_currency_id == comp_curr and wizard.currency_id != comp_curr:
|
||||
# Company currency on source line but a foreign currency one on the opposite line.
|
||||
batch = wizard._get_batches()[0]
|
||||
wizard.amount = abs(sum(
|
||||
comp_curr._convert(
|
||||
aml.amount_residual,
|
||||
wizard.currency_id,
|
||||
wizard.company_id,
|
||||
aml.date,
|
||||
)
|
||||
for aml in batch['lines']
|
||||
))
|
||||
else:
|
||||
# Foreign currency on payment different than the one set on the journal entries.
|
||||
wizard.amount = comp_curr._convert(
|
||||
wizard.source_amount,
|
||||
wizard.currency_id,
|
||||
wizard.company_id,
|
||||
wizard.payment_date,
|
||||
)
|
||||
batch_result = wizard._get_batches()[0]
|
||||
wizard.amount = wizard._get_total_amount_in_wizard_currency_to_full_reconcile(batch_result)
|
||||
else:
|
||||
# The wizard is not editable so no partial payment allowed and then, 'amount' is not used.
|
||||
wizard.amount = None
|
||||
@@ -458,35 +468,9 @@ class AccountPaymentRegister(models.TransientModel):
|
||||
def _compute_payment_difference(self):
|
||||
for wizard in self:
|
||||
if wizard.can_edit_wizard:
|
||||
comp_curr = wizard.company_id.currency_id
|
||||
if wizard.source_currency_id == wizard.currency_id:
|
||||
# Same currency.
|
||||
wizard.payment_difference = wizard.source_amount_currency - wizard.amount
|
||||
elif wizard.source_currency_id != comp_curr and wizard.currency_id == comp_curr:
|
||||
# Foreign currency on source line but the company currency one on the opposite line.
|
||||
rate = self.env['res.currency']._get_conversion_rate(
|
||||
wizard.company_id.currency_id,
|
||||
wizard.source_currency_id,
|
||||
wizard.company_id,
|
||||
wizard.payment_date,
|
||||
)
|
||||
amount_payment_foreign_curr = wizard.source_currency_id.round(wizard.amount * rate)
|
||||
residual_foreign_curr = wizard.source_amount_currency - amount_payment_foreign_curr
|
||||
wizard.payment_difference = wizard.company_id.currency_id.round(residual_foreign_curr / rate)
|
||||
elif wizard.source_currency_id == comp_curr and wizard.currency_id != comp_curr:
|
||||
# Company currency on source line but a foreign currency one on the opposite line.
|
||||
rate = self.env['res.currency']._get_conversion_rate(
|
||||
wizard.company_id.currency_id,
|
||||
wizard.source_currency_id,
|
||||
wizard.company_id,
|
||||
wizard.payment_date,
|
||||
)
|
||||
amount_to_pay_foreign_curr = wizard.currency_id.round(wizard.source_amount * rate)
|
||||
wizard.payment_difference = amount_to_pay_foreign_curr - wizard.amount
|
||||
else:
|
||||
# Foreign currency on payment different than the one set on the journal entries.
|
||||
amount_payment_currency = wizard.company_id.currency_id._convert(wizard.source_amount, wizard.currency_id, wizard.company_id, wizard.payment_date)
|
||||
wizard.payment_difference = amount_payment_currency - wizard.amount
|
||||
batch_result = wizard._get_batches()[0]
|
||||
total_amount_residual_in_wizard_currency = wizard._get_total_amount_in_wizard_currency_to_full_reconcile(batch_result)
|
||||
wizard.payment_difference = total_amount_residual_in_wizard_currency - wizard.amount
|
||||
else:
|
||||
wizard.payment_difference = 0.0
|
||||
|
||||
|
||||
Reference in New Issue
Block a user