Skip to content

Commit 87c54e2

Browse files
committed
[FIX] l10n_it_reverse_charge: force amount_currency set in line values
1 parent 1c059b9 commit 87c54e2

File tree

3 files changed

+133
-19
lines changed

3 files changed

+133
-19
lines changed

l10n_it_reverse_charge/models/account_move.py

+31-17
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# Copyright 2017 Lorenzo Battistini - Agile Business Group
44
# Copyright 2017 Marco Calcagni - Dinamiche Aziendali srl
55
# Copyright 2023 Simone Rubino - TAKOBI
6+
# Copyright 2024 Nextev Srl
67

78
from odoo import api, fields, models
89
from odoo.exceptions import UserError
@@ -180,16 +181,17 @@ def compute_rc_amount_tax_main_currency(self):
180181
The result is converted and rounded based on Company Currency
181182
because this value is used for credit/debit.
182183
"""
183-
rc_tax_amount = self.get_tax_amount_added_for_rc()
184+
rc_tax_amount_ic = self.get_tax_amount_added_for_rc()
185+
rc_tax_amount_cc = rc_tax_amount_ic
184186

185187
invoice_currency = self.currency_id
186188
company_currency = self.company_currency_id
187189
if invoice_currency != company_currency:
188-
rc_tax_amount = invoice_currency._convert(
189-
rc_tax_amount, company_currency, self.company_id, self.invoice_date
190+
rc_tax_amount_cc = invoice_currency._convert(
191+
rc_tax_amount_ic, company_currency, self.company_id, self.invoice_date
190192
)
191193

192-
return rc_tax_amount
194+
return rc_tax_amount_ic, rc_tax_amount_cc
193195

194196
def rc_payment_vals(self, rc_type):
195197
"""Values for the RC Payment Move."""
@@ -199,15 +201,20 @@ def rc_payment_vals(self, rc_type):
199201
"date": self.date,
200202
}
201203

202-
def _rc_line_values(self, account, credit, debit):
204+
def _rc_line_values(self, account, credit, debit, amount_currency):
203205
"""Base Values for the RC Payment Move lines."""
204-
return {
206+
values = {
205207
"name": self.name,
206208
"credit": credit,
207209
"debit": debit,
208210
"account_id": account.id,
209211
"currency_id": self.currency_id.id,
210212
}
213+
if amount_currency:
214+
sign = 1 if debit else -1
215+
amount_currency = abs(amount_currency) * sign
216+
values["amount_currency"] = amount_currency
217+
return values
211218

212219
def _rc_credit_line_amounts(self, amount):
213220
if self.is_inbound():
@@ -230,7 +237,9 @@ def rc_payment_credit_line_vals(self, line_to_reconcile):
230237
)
231238
account = line_to_reconcile.account_id
232239

233-
line_values = self._rc_line_values(account, credit, debit)
240+
line_values = self._rc_line_values(
241+
account, credit, debit, line_to_reconcile.amount_currency
242+
)
234243
line_values.update(
235244
{
236245
"partner_id": self.partner_id.id,
@@ -244,16 +253,18 @@ def rc_payment_debit_line_vals(self, line_to_reconcile, account):
244253
abs(line_to_reconcile.balance),
245254
)
246255

247-
line_values = self._rc_line_values(account, credit, debit)
256+
line_values = self._rc_line_values(
257+
account, credit, debit, line_to_reconcile.amount_currency
258+
)
248259
return line_values
249260

250-
def rc_credit_line_vals(self, account, amount):
251-
credit, debit = self._rc_credit_line_amounts(amount)
252-
return self._rc_line_values(account, credit, debit)
261+
def rc_credit_line_vals(self, account, amount_ic, amount_cc):
262+
credit, debit = self._rc_credit_line_amounts(amount_cc)
263+
return self._rc_line_values(account, credit, debit, amount_ic)
253264

254-
def rc_debit_line_vals(self, account, amount):
255-
credit, debit = self._rc_debit_line_amounts(amount)
256-
line_values = self._rc_line_values(account, credit, debit)
265+
def rc_debit_line_vals(self, account, amount_ic, amount_cc):
266+
credit, debit = self._rc_debit_line_amounts(amount_cc)
267+
line_values = self._rc_line_values(account, credit, debit, amount_ic)
257268
line_values.update(
258269
{
259270
"partner_id": self.partner_id.id,
@@ -277,6 +288,7 @@ def _prepare_rc_supplier_invoice_payment(self, rc_invoice, rc_type):
277288
line_to_reconcile = self._rc_get_move_line_to_reconcile()
278289
payment_debit_line_data = self.rc_debit_line_vals(
279290
line_to_reconcile.account_id,
291+
payment_credit_line_data["amount_currency"],
280292
payment_credit_line_data["credit"],
281293
)
282294
rc_payment_data["line_ids"] = [
@@ -318,15 +330,17 @@ def _prepare_rc_invoice_payment(self, rc_invoice, rc_type):
318330
)
319331

320332
# Lines to be reconciled with the original supplier Invoice (self)
321-
rc_tax_amount = self.compute_rc_amount_tax_main_currency()
333+
rc_tax_amount_ic, rc_tax_amount_cc = self.compute_rc_amount_tax_main_currency()
322334
payment_credit_line_data = self.rc_credit_line_vals(
323335
rc_type.transitory_account_id,
324-
rc_tax_amount,
336+
rc_tax_amount_ic,
337+
rc_tax_amount_cc,
325338
)
326339
line_to_reconcile = self._rc_get_move_line_to_reconcile()
327340
payment_debit_line_data = self.rc_debit_line_vals(
328341
line_to_reconcile.account_id,
329-
rc_tax_amount,
342+
rc_tax_amount_ic,
343+
rc_tax_amount_cc,
330344
)
331345

332346
rc_payment_data["line_ids"] = [

l10n_it_reverse_charge/tests/rc_common.py

+55-2
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,21 @@ def setUpClass(cls, chart_template_ref=None):
3535
cls._create_rc_types()
3636
cls._create_rc_type_taxes()
3737
cls._create_fiscal_position()
38+
cls._create_currency_rate(cls.env.ref("base.EUR").id, 1.1)
3839

3940
cls.supplier_extraEU = cls.partner_model.create(
4041
{
4142
"name": "Extra EU supplier",
4243
"property_account_position_id": cls.fiscal_position_extra.id,
4344
}
4445
)
46+
cls.supplier_extraEU_EUR = cls.partner_model.create(
47+
{
48+
"name": "Extra EU Euro supplier",
49+
"property_account_position_id": cls.fiscal_position_extra_no_si.id,
50+
"currency_id": cls.env.ref("base.EUR"),
51+
}
52+
)
4553
cls.supplier_intraEU = cls.partner_model.create(
4654
{
4755
"name": "Intra EU supplier",
@@ -102,9 +110,14 @@ def setUpClass(cls, chart_template_ref=None):
102110
)
103111

104112
@classmethod
105-
def create_invoice(cls, partner, amounts, taxes=None, post=True):
113+
def create_invoice(cls, partner, amounts, taxes=None, post=True, currency=None):
106114
invoice = cls.init_invoice(
107-
"in_invoice", partner=partner, post=post, amounts=amounts, taxes=taxes
115+
"in_invoice",
116+
partner=partner,
117+
post=post,
118+
amounts=amounts,
119+
taxes=taxes,
120+
currency=currency,
108121
)
109122
for line in invoice.invoice_line_ids:
110123
line.account_id = cls.invoice_line_account.id
@@ -224,6 +237,20 @@ def _create_rc_types(cls):
224237
}
225238
)
226239

240+
cls.rc_type_eeu_no_selfinvoice_extra = rc_type_model.create(
241+
{
242+
"name": "Extra EU (selfinvoice)",
243+
"method": "selfinvoice",
244+
"partner_type": "other",
245+
"with_supplier_self_invoice": False,
246+
"partner_id": cls.env.ref("base.main_partner").id,
247+
"journal_id": cls.journal_selfinvoice_extra.id,
248+
"supplier_journal_id": cls.journal_cee_extra.id,
249+
"payment_journal_id": cls.journal_reconciliation.id,
250+
"transitory_account_id": cls.account_selfinvoice.id,
251+
}
252+
)
253+
227254
cls.rc_type_exempt = rc_type_model.create(
228255
{
229256
"name": "Intra EU (exempt)",
@@ -255,6 +282,14 @@ def _create_rc_type_taxes(cls):
255282
}
256283
)
257284

285+
cls.rc_type_tax_eeu_no_selfinvoice_extra = rc_type_tax_model.create(
286+
{
287+
"rc_type_id": cls.rc_type_eeu_no_selfinvoice_extra.id,
288+
"purchase_tax_id": cls.tax_22ae.id,
289+
"sale_tax_id": cls.tax_22ve.id,
290+
}
291+
)
292+
258293
cls.rc_type_tax_exempt = rc_type_tax_model.create(
259294
{
260295
"rc_type_id": cls.rc_type_exempt.id,
@@ -274,6 +309,24 @@ def _create_fiscal_position(cls):
274309
{"name": "Extra EU", "rc_type_id": cls.rc_type_eeu.id}
275310
)
276311

312+
cls.fiscal_position_extra_no_si = model_fiscal_position.create(
313+
{
314+
"name": "Extra EU no extra self invoice",
315+
"rc_type_id": cls.rc_type_eeu_no_selfinvoice_extra.id,
316+
}
317+
)
318+
277319
cls.fiscal_position_exempt = model_fiscal_position.create(
278320
{"name": "Intra EU exempt", "rc_type_id": cls.rc_type_exempt.id}
279321
)
322+
323+
@classmethod
324+
def _create_currency_rate(cls, currency_id, rate, date="2016-01-01"):
325+
cls.env["res.currency.rate"].create(
326+
{
327+
"name": date,
328+
"currency_id": currency_id,
329+
"rate": rate,
330+
"company_id": cls.env.company.id,
331+
}
332+
)

l10n_it_reverse_charge/tests/test_rc.py

+47
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,53 @@ def test_supplier_extraEU_no_outstanding_payment(self):
171171
payments_lines = (self_purchase_payment | self_purchase_rc_payment).line_ids
172172
self.assertTrue(all(payments_lines.mapped("reconciled")))
173173

174+
def test_supplier_extraEU_no_outstanding_payment_different_currencies(self):
175+
"""
176+
Self invoice from Extra EU partner in a different currency
177+
"""
178+
invoice = self.create_invoice(
179+
self.supplier_extraEU_EUR,
180+
amounts=[100],
181+
taxes=self.tax_22ae,
182+
currency=self.env.ref("base.EUR"),
183+
)
184+
185+
self_invoice = invoice.rc_self_invoice_id
186+
self_payment = self_invoice.rc_payment_move_id
187+
# check self payment creation
188+
self.assertTrue(self_payment)
189+
# check self payment amount total
190+
self.assertEqual(self_payment.amount_total, 144.0)
191+
# check self payment amount total in currency
192+
self.assertEqual(self_payment.amount_total_signed, 130.91)
193+
# check self payment lines amount currency setting
194+
self.assertTrue(all(self_payment.line_ids.mapped("amount_currency")))
195+
196+
# check self invoice amount
197+
invoices_amounts_sum = (
198+
invoice.amount_untaxed_signed + self_invoice.amount_untaxed_signed
199+
)
200+
self.assertEqual(invoices_amounts_sum, 0.0)
201+
202+
# check amount conversion
203+
invoice_amount_untaxed_usd = invoice.currency_id._convert(
204+
invoice.amount_untaxed,
205+
invoice.company_id.currency_id,
206+
invoice.company_id,
207+
invoice.invoice_date,
208+
)
209+
self_invoice_test_line = self_invoice.line_ids.filtered(
210+
lambda x: x.name == "test line"
211+
)
212+
self.assertEqual(
213+
invoice_amount_untaxed_usd, abs(self_invoice_test_line.balance)
214+
)
215+
216+
# check amount_currency setting
217+
self.assertEqual(
218+
invoice.amount_untaxed, abs(self_invoice_test_line.amount_currency)
219+
)
220+
174221
def test_extra_EU_draft_and_reconfirm(self):
175222
"""Check that an invoice with RC Self Purchase Invoice
176223
can be reset to draft and confirmed again."""

0 commit comments

Comments
 (0)