Commit 608fd005 authored by agb80's avatar agb80 Committed by Noe Fernando Izquierdo Hernandez

fix(account.invoice): corrige la diferencia en montos cuando el cliente no es sujeto de IEPS

Por la forma en la que se estaban procesando los impuestos cuando el cliente no era sujeto de IEPS
se forzaba realizar nuevamente el cálculo y esto ocasionaba que el precio unitario de las líneas de
factura acumulara una pequeña diferencia en decimales. El problema era que al acumular esa
diferencia en grandes cantidades acababa surgiendo una diferencia significativa en los montos de las
líneas y en el monto final de la factura. Para evitar estas diferencias se cambió la forma en como
se procesan los impuestos para evitar esas diferencias.
parent 16cf073c
Pipeline #22065 failed with stage
in 1 minute and 43 seconds
......@@ -579,9 +579,6 @@ class AccountInvoiceLine(models.Model):
"""
tax_record = self.env["account.tax"].browse(tax["id"])
tax_group = tax_record.tax_category_id
# IEPS tax only must be included when partner is IEPS subjected
if tax_group.name == "IEPS" and not partner.ieps_subjected:
return
# TODO: Delete on version 3.0.0
if "base" not in tax:
tax["base"] = currency.cfdi_round(tax["price_unit"] * self.quantity)
......@@ -597,16 +594,7 @@ class AccountInvoiceLine(models.Model):
total_discount *= 1 - self.invoice_id.global_discount / 100
price = float_round(self.price_unit * total_discount, precision)
partner = self.invoice_id.partner_id
# Check if IEPS is on taxes, this will be used later to know if need price
# to be recalculated because IEPS must be price included as partner is not
# IEPS subjected and product include IEPS taxes
ieps_group = self.env.ref("l10n_mx.tax_category_ieps")
is_ieps_tax_subjected = any(
tax.tax_category_id == ieps_group for tax in self.invoice_line_tax_id
)
is_price_included = any(
tax.price_include for tax in self.invoice_line_tax_id
)
# Compute taxes using original compute_all function from
# account.invoice.tax to get same result for CFDI display
res = self.invoice_line_tax_id.compute_all(
......@@ -616,36 +604,19 @@ class AccountInvoiceLine(models.Model):
partner=partner,
currency=self.invoice_id.currency_id,
)
# pylint: disable=C1801
if len(res["taxes"]) == 0:
if not len(res["taxes"]):
raise ValidationError(
_("Product {p} must have at least one tax selected.").format(
p=self.product_id.name
)
)
taxes = []
taxes_list = iter(res["taxes"])
tax = next(taxes_list)
# Iterate taxes and append to the new tax list as needed
while True:
tax = process_tax(tax)
if tax:
taxes.append(tax)
try:
tax = next(taxes_list)
except StopIteration:
if tax is None:
raise ValidationError(
_(
"Incorrect tax sequence configuration, check "
"this data in Account >> Tax >> Sequence"
)
)
break
is_price_included = any(
tax.price_include for tax in self.invoice_line_tax_id
)
res["price_unit"] = self.price_unit
# Recompute price_unit is needed when any tax is setup to price included or
# when product is IEPS subjected but not partner
if is_price_included or (not partner.ieps_subjected and is_ieps_tax_subjected):
# Recompute price_unit is needed when any tax is setup to price included
if is_price_included:
# Send round=False in context to avoid rounding to wrong value when working
# with high Product Price precision (6 digits)
res["price_unit"] = self.invoice_line_tax_id.with_context(
......@@ -661,6 +632,25 @@ class AccountInvoiceLine(models.Model):
self.env["decimal.precision"].precision_get("Product Price"),
)
taxes = []
taxes_list = iter(res["taxes"])
tax = next(taxes_list)
# Iterate taxes and append to the new tax list as needed
while True:
tax = process_tax(tax)
# IEPS tax only must be included when partner is IEPS subjected
if tax["group"] == "IEPS" and not partner.ieps_subjected:
res["price_unit"] = float_round(
res["price_unit"] + (tax["amount"] / self.quantity),
self.env["decimal.precision"].precision_get("Product Price"),
)
else:
taxes.append(tax)
try:
tax = next(taxes_list)
except StopIteration:
break
res["importe"] = currency.round(res["price_unit"] * self.quantity)
res["descuento"] = currency.round(res["importe"] * (1 - total_discount))
# Overrides original taxes with the list computed by us
......
......@@ -31,3 +31,15 @@ Característica: Cancelar facturas con CFDIS no timbrados.
Cuando se cancele la Factura
Entonces la factura cambia a Cancelada
Y el CFDI cambia a Cancelado
Característica: Validación de XML y PDF en el total de factura, importe y precio unitario del producto
Esquema del escenario:
Dado una factura con la siguiente información
El cliente no está sujeto a IEPS
| Concepto | Precio Unitario | Cantidad | Impuesto |
| ProductoA | 308.3554| 5.0 | IEPS 30% |
| | | | IVA 16% |
Cuando: Valido la factura.
Entonces: la factura cambia a Abierta
Y el total de la factura, el importe y precio unitario del producto es correcto en el XML
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment