versión 1.2.1: la diferencia de importes con SAP se redondea a 2 decimales

La comparación abs(a - b) < 0.01 no era fiable por la coma flotante: el mismo
céntimo se aceptaba o rechazaba según el importe (431.41 contra 431.40 se
rechazaba y 624.39 contra 624.38 se aceptaba). pipeline_utils.importes_coinciden
redondea la diferencia a 2 decimales, lo que muestra un comprobante, y admite
hasta 1 céntimo. Se usa en la validación de precios y en la comparación del
valor referencial. Con datos reales de SAP (49 líneas) ningún resultado cambió.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
GeorgeandClaude Sonnet 5.5 committed 2026-10-22 13:07:28 -05:00
1 parent cdcecc2b56
commit 3b5400018c
11 files changed
+95 -17

No files matched your search

+18 -5
View File
@@ -79,11 +79,24 @@ def test_varias_guias_de_una_linea_se_suman(sap):
assert len(resultados[0]["guias_lt"]) == 2
def test_tolerancia_de_un_centimo(sap):
factura = {"lineas": [{"cantidad": 1, "total_linea": 100.005, "guias_remision": [_guia()]}]}
assert draft_sap.validate_prices(factura)[0] is True
factura["lineas"][0]["total_linea"] = 100.02
assert draft_sap.validate_prices(factura)[0] is False
@pytest.mark.parametrize("total_xml, total_sap, coincide", [
# un céntimo de diferencia: antes se aceptaba o se rechazaba según el ruido de la coma flotante
(624.38, 624.39, True), (624.39, 624.38, True),
(431.40, 431.41, True), (170.29, 170.30, True), # estos dos la regla vieja los rechazaba
(828.73, 828.74, True), (828.74, 828.73, True),
(100.00, 100.01, True), (0.50, 0.51, True), (1.00, 1.01, True), (10.01, 10.00, True),
# menos de un céntimo, o igual
(100.00, 100.00, True), (100.005, 100.00, True), (1203.94, 1203.9399, True),
# dos céntimos o más: no coincide
(100.00, 100.02, False), (100.02, 100.00, False), (624.38, 624.40, False), (624.38, 674.38, False),
])
def test_tolerancia_de_un_centimo_es_determinista(sap, total_xml, total_sap, coincide):
sap["dn"] = _delivery_note(line_total=total_sap)
factura = {"lineas": [{"cantidad": 1, "total_linea": total_xml, "guias_remision": [_guia()]}]}
todas_coinciden, resultados = draft_sap.validate_prices(factura)
assert todas_coinciden is coincide and resultados[0]["ok"] is coincide
def test_cantidad_cero_no_se_valida(sap):
+7
View File
@@ -44,3 +44,10 @@ def test_valor_referencial_no_coincide():
factura = {"lineas": [{"valor_referencial": 10.0}]}
html = n.build_valor_referencial_html(factura, [{"serie": "T001", "numero": "1", "valor_sap": 9.0}])
assert "❌ No coincide" in html
def test_valor_referencial_con_un_centimo_de_diferencia_coincide():
factura = {"lineas": [{"valor_referencial": 624.38}]}
html = n.build_valor_referencial_html(factura, [{"serie": "T001", "numero": "1", "valor_sap": 624.39}])
assert "✅ Coincide" in html
+31
View File
@@ -0,0 +1,31 @@
import pytest
from pipeline_utils import TOLERANCIA_IMPORTE, importes_coinciden
def test_el_ruido_de_la_coma_flotante_era_el_problema():
"""Documenta por qué no se compara ``abs(a - b) < 0.01``: el mismo céntimo daba resultados distintos."""
assert abs(431.41 - 431.40) >= 0.01 # 0.01000000000004775: la regla vieja lo rechazaba
assert abs(170.30 - 170.29) >= 0.01 # 0.01000000000001933: también
assert abs(624.39 - 624.38) < 0.01 # 0.00999999999999091: la regla vieja lo aceptaba
assert abs(828.74 - 828.73) < 0.01 # igual: el mismo céntimo, otro resultado
for a, b in [(431.41, 431.40), (170.30, 170.29), (624.39, 624.38), (828.74, 828.73)]:
assert importes_coinciden(a, b)
@pytest.mark.parametrize("a, b, esperado", [
(100.00, 100.00, True), (100.00, 100.01, True), (100.01, 100.00, True), (100.004, 100.00, True),
(100.00, 100.02, False), (100.02, 100.00, False), (0.00, 0.02, False), (1500.00, 1499.98, False),
(0.0, 0.0, True), (-5.00, -5.01, True),
])
def test_importes_coinciden(a, b, esperado):
assert importes_coinciden(a, b) is esperado
def test_la_comparacion_es_simetrica():
for a, b in [(624.38, 624.39), (1.0, 1.02), (850.5, 850.49)]:
assert importes_coinciden(a, b) == importes_coinciden(b, a)
def test_la_tolerancia_es_un_centimo():
assert TOLERANCIA_IMPORTE == 0.01