Skip to content

Commit

Permalink
[FIX] l10n_it_reverse_charge: force amount_currency set in line values
Browse files Browse the repository at this point in the history
  • Loading branch information
odooNextev committed Aug 2, 2024
1 parent 1c059b9 commit 87c54e2
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 19 deletions.
48 changes: 31 additions & 17 deletions l10n_it_reverse_charge/models/account_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# Copyright 2017 Lorenzo Battistini - Agile Business Group
# Copyright 2017 Marco Calcagni - Dinamiche Aziendali srl
# Copyright 2023 Simone Rubino - TAKOBI
# Copyright 2024 Nextev Srl

from odoo import api, fields, models
from odoo.exceptions import UserError
Expand Down Expand Up @@ -180,16 +181,17 @@ def compute_rc_amount_tax_main_currency(self):
The result is converted and rounded based on Company Currency
because this value is used for credit/debit.
"""
rc_tax_amount = self.get_tax_amount_added_for_rc()
rc_tax_amount_ic = self.get_tax_amount_added_for_rc()
rc_tax_amount_cc = rc_tax_amount_ic

invoice_currency = self.currency_id
company_currency = self.company_currency_id
if invoice_currency != company_currency:
rc_tax_amount = invoice_currency._convert(
rc_tax_amount, company_currency, self.company_id, self.invoice_date
rc_tax_amount_cc = invoice_currency._convert(
rc_tax_amount_ic, company_currency, self.company_id, self.invoice_date
)

return rc_tax_amount
return rc_tax_amount_ic, rc_tax_amount_cc

def rc_payment_vals(self, rc_type):
"""Values for the RC Payment Move."""
Expand All @@ -199,15 +201,20 @@ def rc_payment_vals(self, rc_type):
"date": self.date,
}

def _rc_line_values(self, account, credit, debit):
def _rc_line_values(self, account, credit, debit, amount_currency):
"""Base Values for the RC Payment Move lines."""
return {
values = {
"name": self.name,
"credit": credit,
"debit": debit,
"account_id": account.id,
"currency_id": self.currency_id.id,
}
if amount_currency:
sign = 1 if debit else -1
amount_currency = abs(amount_currency) * sign
values["amount_currency"] = amount_currency
return values

def _rc_credit_line_amounts(self, amount):
if self.is_inbound():
Expand All @@ -230,7 +237,9 @@ def rc_payment_credit_line_vals(self, line_to_reconcile):
)
account = line_to_reconcile.account_id

line_values = self._rc_line_values(account, credit, debit)
line_values = self._rc_line_values(
account, credit, debit, line_to_reconcile.amount_currency
)
line_values.update(
{
"partner_id": self.partner_id.id,
Expand All @@ -244,16 +253,18 @@ def rc_payment_debit_line_vals(self, line_to_reconcile, account):
abs(line_to_reconcile.balance),
)

line_values = self._rc_line_values(account, credit, debit)
line_values = self._rc_line_values(
account, credit, debit, line_to_reconcile.amount_currency
)
return line_values

def rc_credit_line_vals(self, account, amount):
credit, debit = self._rc_credit_line_amounts(amount)
return self._rc_line_values(account, credit, debit)
def rc_credit_line_vals(self, account, amount_ic, amount_cc):
credit, debit = self._rc_credit_line_amounts(amount_cc)
return self._rc_line_values(account, credit, debit, amount_ic)

def rc_debit_line_vals(self, account, amount):
credit, debit = self._rc_debit_line_amounts(amount)
line_values = self._rc_line_values(account, credit, debit)
def rc_debit_line_vals(self, account, amount_ic, amount_cc):
credit, debit = self._rc_debit_line_amounts(amount_cc)
line_values = self._rc_line_values(account, credit, debit, amount_ic)
line_values.update(
{
"partner_id": self.partner_id.id,
Expand All @@ -277,6 +288,7 @@ def _prepare_rc_supplier_invoice_payment(self, rc_invoice, rc_type):
line_to_reconcile = self._rc_get_move_line_to_reconcile()
payment_debit_line_data = self.rc_debit_line_vals(
line_to_reconcile.account_id,
payment_credit_line_data["amount_currency"],
payment_credit_line_data["credit"],
)
rc_payment_data["line_ids"] = [
Expand Down Expand Up @@ -318,15 +330,17 @@ def _prepare_rc_invoice_payment(self, rc_invoice, rc_type):
)

# Lines to be reconciled with the original supplier Invoice (self)
rc_tax_amount = self.compute_rc_amount_tax_main_currency()
rc_tax_amount_ic, rc_tax_amount_cc = self.compute_rc_amount_tax_main_currency()
payment_credit_line_data = self.rc_credit_line_vals(
rc_type.transitory_account_id,
rc_tax_amount,
rc_tax_amount_ic,
rc_tax_amount_cc,
)
line_to_reconcile = self._rc_get_move_line_to_reconcile()
payment_debit_line_data = self.rc_debit_line_vals(
line_to_reconcile.account_id,
rc_tax_amount,
rc_tax_amount_ic,
rc_tax_amount_cc,
)

rc_payment_data["line_ids"] = [
Expand Down
57 changes: 55 additions & 2 deletions l10n_it_reverse_charge/tests/rc_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,21 @@ def setUpClass(cls, chart_template_ref=None):
cls._create_rc_types()
cls._create_rc_type_taxes()
cls._create_fiscal_position()
cls._create_currency_rate(cls.env.ref("base.EUR").id, 1.1)

cls.supplier_extraEU = cls.partner_model.create(
{
"name": "Extra EU supplier",
"property_account_position_id": cls.fiscal_position_extra.id,
}
)
cls.supplier_extraEU_EUR = cls.partner_model.create(
{
"name": "Extra EU Euro supplier",
"property_account_position_id": cls.fiscal_position_extra_no_si.id,
"currency_id": cls.env.ref("base.EUR"),
}
)
cls.supplier_intraEU = cls.partner_model.create(
{
"name": "Intra EU supplier",
Expand Down Expand Up @@ -102,9 +110,14 @@ def setUpClass(cls, chart_template_ref=None):
)

@classmethod
def create_invoice(cls, partner, amounts, taxes=None, post=True):
def create_invoice(cls, partner, amounts, taxes=None, post=True, currency=None):
invoice = cls.init_invoice(
"in_invoice", partner=partner, post=post, amounts=amounts, taxes=taxes
"in_invoice",
partner=partner,
post=post,
amounts=amounts,
taxes=taxes,
currency=currency,
)
for line in invoice.invoice_line_ids:
line.account_id = cls.invoice_line_account.id
Expand Down Expand Up @@ -224,6 +237,20 @@ def _create_rc_types(cls):
}
)

cls.rc_type_eeu_no_selfinvoice_extra = rc_type_model.create(
{
"name": "Extra EU (selfinvoice)",
"method": "selfinvoice",
"partner_type": "other",
"with_supplier_self_invoice": False,
"partner_id": cls.env.ref("base.main_partner").id,
"journal_id": cls.journal_selfinvoice_extra.id,
"supplier_journal_id": cls.journal_cee_extra.id,
"payment_journal_id": cls.journal_reconciliation.id,
"transitory_account_id": cls.account_selfinvoice.id,
}
)

cls.rc_type_exempt = rc_type_model.create(
{
"name": "Intra EU (exempt)",
Expand Down Expand Up @@ -255,6 +282,14 @@ def _create_rc_type_taxes(cls):
}
)

cls.rc_type_tax_eeu_no_selfinvoice_extra = rc_type_tax_model.create(
{
"rc_type_id": cls.rc_type_eeu_no_selfinvoice_extra.id,
"purchase_tax_id": cls.tax_22ae.id,
"sale_tax_id": cls.tax_22ve.id,
}
)

cls.rc_type_tax_exempt = rc_type_tax_model.create(
{
"rc_type_id": cls.rc_type_exempt.id,
Expand All @@ -274,6 +309,24 @@ def _create_fiscal_position(cls):
{"name": "Extra EU", "rc_type_id": cls.rc_type_eeu.id}
)

cls.fiscal_position_extra_no_si = model_fiscal_position.create(
{
"name": "Extra EU no extra self invoice",
"rc_type_id": cls.rc_type_eeu_no_selfinvoice_extra.id,
}
)

cls.fiscal_position_exempt = model_fiscal_position.create(
{"name": "Intra EU exempt", "rc_type_id": cls.rc_type_exempt.id}
)

@classmethod
def _create_currency_rate(cls, currency_id, rate, date="2016-01-01"):
cls.env["res.currency.rate"].create(
{
"name": date,
"currency_id": currency_id,
"rate": rate,
"company_id": cls.env.company.id,
}
)
47 changes: 47 additions & 0 deletions l10n_it_reverse_charge/tests/test_rc.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,53 @@ def test_supplier_extraEU_no_outstanding_payment(self):
payments_lines = (self_purchase_payment | self_purchase_rc_payment).line_ids
self.assertTrue(all(payments_lines.mapped("reconciled")))

def test_supplier_extraEU_no_outstanding_payment_different_currencies(self):
"""
Self invoice from Extra EU partner in a different currency
"""
invoice = self.create_invoice(
self.supplier_extraEU_EUR,
amounts=[100],
taxes=self.tax_22ae,
currency=self.env.ref("base.EUR"),
)

self_invoice = invoice.rc_self_invoice_id
self_payment = self_invoice.rc_payment_move_id
# check self payment creation
self.assertTrue(self_payment)
# check self payment amount total
self.assertEqual(self_payment.amount_total, 144.0)
# check self payment amount total in currency
self.assertEqual(self_payment.amount_total_signed, 130.91)
# check self payment lines amount currency setting
self.assertTrue(all(self_payment.line_ids.mapped("amount_currency")))

# check self invoice amount
invoices_amounts_sum = (
invoice.amount_untaxed_signed + self_invoice.amount_untaxed_signed
)
self.assertEqual(invoices_amounts_sum, 0.0)

# check amount conversion
invoice_amount_untaxed_usd = invoice.currency_id._convert(
invoice.amount_untaxed,
invoice.company_id.currency_id,
invoice.company_id,
invoice.invoice_date,
)
self_invoice_test_line = self_invoice.line_ids.filtered(
lambda x: x.name == "test line"
)
self.assertEqual(
invoice_amount_untaxed_usd, abs(self_invoice_test_line.balance)
)

# check amount_currency setting
self.assertEqual(
invoice.amount_untaxed, abs(self_invoice_test_line.amount_currency)
)

def test_extra_EU_draft_and_reconfirm(self):
"""Check that an invoice with RC Self Purchase Invoice
can be reset to draft and confirmed again."""
Expand Down

0 comments on commit 87c54e2

Please sign in to comment.