Skip to content

Commit 8cc2d48

Browse files
committed
[16.0][FIX]l10n_es_aeat_sii_oca: arreglar error del sii en un cornercase de céntimos que sucede en algunas facturas con impuestos incluídos
Para reproducir el caso, se reproduce tanto en una factura de venta o compra como en un pos_order. Lo que sucede es que se envía en el desglose de impuestos una base con un céntimo positivo y una cuota con un céntimo negativo, o viceversa. Por lo que el sii devuelve el error 1231: 'El campo CuotaRepercutida y BaseImponible deben tener el mismo signo.',
1 parent d83d9fa commit 8cc2d48

4 files changed

Lines changed: 102 additions & 2 deletions

File tree

l10n_es_aeat_sii_oca/models/account_move.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ def _get_sii_tax_dict(self, tax_line, tax_lines):
212212
if req_tax:
213213
tax_dict["TipoRecargoEquivalencia"] = req_tax.amount
214214
tax_dict["CuotaRecargoEquivalencia"] = tax_lines[req_tax]["amount"]
215+
tax_dict = self._clean_sii_tax_dict(tax, self.move_type, tax_dict)
215216
return tax_dict
216217

217218
def _get_document_amount_total(self):

l10n_es_aeat_sii_oca/models/sii_mixin.py

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from odoo import _, api, exceptions, fields, models
1111
from odoo.exceptions import UserError, ValidationError
1212
from odoo.modules.registry import Registry
13-
from odoo.tools.float_utils import float_compare
13+
from odoo.tools.float_utils import float_compare, float_is_zero
1414

1515
from odoo.addons.l10n_es_aeat.models.aeat_mixin import round_by_keys
1616

@@ -422,7 +422,8 @@ def _get_sii_tax_dict(self, tax_line, tax_lines):
422422
else:
423423
tax_type = abs(tax.amount)
424424
tax_dict = {"TipoImpositivo": str(tax_type), "BaseImponible": tax_base_amount}
425-
if self._get_mapping_key() in ["out_invoice", "out_refund"]:
425+
mapping_key = self._get_mapping_key()
426+
if mapping_key in ["out_invoice", "out_refund"]:
426427
key = "CuotaRepercutida"
427428
else:
428429
key = "CuotaSoportada"
@@ -432,6 +433,7 @@ def _get_sii_tax_dict(self, tax_line, tax_lines):
432433
if req_tax:
433434
tax_dict["TipoRecargoEquivalencia"] = req_tax.amount
434435
tax_dict["CuotaRecargoEquivalencia"] = tax_lines[req_tax]["amount"]
436+
tax_dict = self._clean_sii_tax_dict(tax, mapping_key, tax_dict)
435437
return tax_dict
436438

437439
def _get_no_taxable_cause(self):
@@ -741,6 +743,36 @@ def _get_aeat_invoice_dict(self):
741743
)
742744
return inv_dict
743745

746+
def _clean_sii_tax_dict(self, tax, move_type, tax_dict):
747+
"""
748+
Clean tax dict rounding issues for price included taxes
749+
corner cases.
750+
:param tax: tax record
751+
:param move_type: invoice move type
752+
:param tax_dict: tax dict to clean
753+
:return: cleaned tax dict
754+
"""
755+
if tax.price_include:
756+
base_amount = round(tax_dict.get("BaseImponible", 0.0), 2)
757+
key = (
758+
"CuotaRepercutida"
759+
if move_type in ["out_invoice", "out_refund"]
760+
else "CuotaSoportada"
761+
)
762+
tax_amount = round(tax_dict.get(key, 0.0), 2)
763+
if (
764+
float_is_zero(base_amount, precision_digits=1)
765+
and float_is_zero(tax_amount, precision_digits=1)
766+
and not float_is_zero(base_amount, precision_digits=2)
767+
and not float_is_zero(tax_amount, precision_digits=2)
768+
and float_is_zero(
769+
abs(base_amount) - abs(tax_amount), precision_digits=2
770+
)
771+
):
772+
tax_dict[key] = 0.0
773+
tax_dict["BaseImponible"] = 0.0
774+
return tax_dict
775+
744776
def _get_account_registration_date(self):
745777
"""Hook method to allow the setting of the account registration date
746778
of each supplier invoice. The SII recommends to set the send date as
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"IDFactura": {
3+
"IDEmisorFactura": {"NIF": "U2687761C"},
4+
"NumSerieFacturaEmisor": "TEST001",
5+
"FechaExpedicionFacturaEmisor": "01-01-2020"
6+
},
7+
"PeriodoLiquidacion": {"Ejercicio": 2020, "Periodo": "01"},
8+
"FacturaExpedida": {
9+
"TipoFactura": "F1",
10+
"ClaveRegimenEspecialOTrascendencia": "01",
11+
"DescripcionOperacion": "/",
12+
"TipoDesglose": {
13+
"DesgloseTipoOperacion": {
14+
"PrestacionServicios": {
15+
"Sujeta": {
16+
"NoExenta": {
17+
"TipoNoExenta": "S1",
18+
"DesgloseIVA": {
19+
"DetalleIVA": [
20+
{
21+
"TipoImpositivo": "21.0",
22+
"BaseImponible": 0.0,
23+
"CuotaRepercutida": 0.0
24+
}
25+
]
26+
}
27+
}
28+
}
29+
}
30+
}
31+
},
32+
"ImporteTotal": 0.0,
33+
"Contraparte": {"NombreRazon": "Test partner", "NIF": "F35999705"}
34+
}
35+
}

l10n_es_aeat_sii_oca/tests/test_l10n_es_aeat_sii.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,3 +545,35 @@ def test_start_date(self):
545545
self.company.sii_start_date = False
546546
self.assertTrue(invoice2.sii_enabled)
547547
self.assertTrue(invoice2.filtered_domain([("sii_enabled", "=", True)]))
548+
549+
def test_get_invoice_data_tax_price_include_cents_corner_case(self):
550+
xml_id = "l10n_es.{}_account_tax_template_{}".format(
551+
self.company.id, "s_iva21s"
552+
)
553+
tax = self.env.ref(xml_id)
554+
tax.price_include = True
555+
mapping = [
556+
(
557+
"out_invoice",
558+
[
559+
(-45, ["s_iva21s"]),
560+
(15, ["s_iva21s"]),
561+
(15, ["s_iva21s"]),
562+
(15, ["s_iva21s"]),
563+
],
564+
{},
565+
),
566+
(
567+
"out_invoice",
568+
[
569+
(45, ["s_iva21s"]),
570+
(-15, ["s_iva21s"]),
571+
(-15, ["s_iva21s"]),
572+
(-15, ["s_iva21s"]),
573+
],
574+
{},
575+
),
576+
]
577+
for inv_type, lines, extra_vals in mapping:
578+
self._create_and_test_invoice_sii_dict(inv_type, lines, extra_vals)
579+
return

0 commit comments

Comments
 (0)