From d9d3deef6cd17fcfb915fa069f0271689c053fa7 Mon Sep 17 00:00:00 2001 From: Lizandro Guarnizo <77708265+lizandrogd@users.noreply.github.com> Date: Fri, 26 Jun 2026 19:50:30 -0500 Subject: [PATCH] =?UTF-8?q?Fix=20colisi=C3=B3n=20de=20numero=20de=20factur?= =?UTF-8?q?a=20en=20TNS=20cuando=20varios=20IDRECEPCION=20comparten=20NUM?= =?UTF-8?q?=5FFACTURA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - json_generator: agrega parámetro numero_override para usar un número alternativo - test_rda: detecta si el NUM_FACTURA ya fue enviado exitosamente (sesión o rda_test_log) y usa "{factura}-{idrecepcion}" como numero único en TNS - transaccion: misma lógica en envío masivo, evita que el segundo IDRECEPCION de la misma factura falle con 409 Co-Authored-By: Claude Sonnet 4.6 --- app/routes/test_rda.py | 19 ++++++++++++++++++- app/routes/transaccion.py | 16 ++++++++++++++++ app/services/json_generator.py | 7 +++++-- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/app/routes/test_rda.py b/app/routes/test_rda.py index 0265d31..061caeb 100644 --- a/app/routes/test_rda.py +++ b/app/routes/test_rda.py @@ -266,9 +266,24 @@ async def test_enviar(request: Request, user: dict = Depends(get_current_user)): # Paso 2: enviar RDA grupos = agrupar_por_recepcion(rows_rda) + # Rastrear facturas usadas en esta sesión para evitar colisión en TNS + facturas_usadas_sesion: set = set() + # También verificar facturas ya exitosas en rda_test_log + db_check = get_connection() + facturas_previas = {r[0] for r in db_check.execute( + "SELECT factura FROM rda_test_log WHERE ok = 1" + ).fetchall()} + db_check.close() + async with httpx.AsyncClient(timeout=30) as client: for id_rec, grupo_rows in grupos.items(): - rda_json = generar_rda_paciente(grupo_rows, prof_def, esp_def, remis_def, prefijo_def) + num_factura = str(grupo_rows[0].get("NUM_FACTURA") or "").strip() + # Si este numero ya fue enviado exitosamente (en esta sesión o antes), usar id único + if num_factura and (num_factura in facturas_previas or num_factura in facturas_usadas_sesion): + numero_override = f"{num_factura}-{id_rec}" + else: + numero_override = "" + rda_json = generar_rda_paciente(grupo_rows, prof_def, esp_def, remis_def, prefijo_def, numero_override) examenes = [r.get("COD_EXAMEN", "") for r in grupo_rows] try: r = await client.post(endpoint_rda, json=rda_json, headers=headers) @@ -297,6 +312,8 @@ async def test_enviar(request: Request, user: dict = Depends(get_current_user)): "respuesta_tns": raw_resp, "json_enviado": rda_json, }) + if ok_rda: + facturas_usadas_sesion.add(num_factura) db_log = get_connection() db_log.execute( "INSERT OR REPLACE INTO rda_test_log (idrecepcion, factura, contrato, ok, mensaje) VALUES (?,?,?,?,?)", diff --git a/app/routes/transaccion.py b/app/routes/transaccion.py index d92cc72..a06df5f 100644 --- a/app/routes/transaccion.py +++ b/app/routes/transaccion.py @@ -227,15 +227,29 @@ async def send_transaccion( api_sucursal = cfg.get("api_sucursal", "") or "00" endpoint = f"{TNS_BASE}/v2/rda/RdaPaciente/Insertar?codigosucursal={api_sucursal}" + # Rastrear facturas ya enviadas exitosamente para evitar numero duplicado en TNS + conn_check = get_connection() + facturas_ok_prev = {r[0] for r in conn_check.execute( + "SELECT DISTINCT factura FROM envios WHERE tipo='transaccion' AND status='success'" + ).fetchall()} + conn_check.close() + facturas_ok_sesion: set = set() + resultados = [] async with httpx.AsyncClient(timeout=int(cfg.get("api_timeout", 30))) as client: for id_rec, grupo_rows in grupos.items(): + num_factura = str(grupo_rows[0].get("NUM_FACTURA") or "").strip() + if num_factura and (num_factura in facturas_ok_prev or num_factura in facturas_ok_sesion): + numero_override = f"{num_factura}-{id_rec}" + else: + numero_override = "" rda_json = generar_rda_paciente( grupo_rows, cfg.get("profesional_default", ""), cfg.get("especialidad_default", ""), cfg.get("remisionante_default", "00"), cfg.get("prefijo_tns_default", "00"), + numero_override, ) raw_resp = "" ok_rda = False @@ -270,6 +284,8 @@ async def send_transaccion( raw_resp[:2000], msg_tns, datetime.now().isoformat(), )) + if ok_rda: + facturas_ok_sesion.add(num_factura) conn.commit() conn.close() resultados.append({"idrecepcion": id_rec, "success": ok_rda, "msg": msg_tns}) diff --git a/app/services/json_generator.py b/app/services/json_generator.py index 12d1e14..a57e420 100644 --- a/app/services/json_generator.py +++ b/app/services/json_generator.py @@ -97,7 +97,8 @@ def agrupar_por_recepcion(rows: list) -> dict: def generar_rda_paciente(rows: list, default_profesional: str = "", default_especialidad: str = "", - default_remisionante: str = "00", default_prefijo: str = "00") -> dict: + default_remisionante: str = "00", default_prefijo: str = "00", + numero_override: str = "") -> dict: if not rows: return {} h = rows[0] @@ -159,7 +160,9 @@ def generar_rda_paciente(rows: list, default_profesional: str = "", default_espe return { "codigoPrefijo": default_prefijo or str(h.get("PREFIJO") or "00").strip(), - "numero": str(h.get("NUM_FACTURA") or "").strip() if (h.get("NUM_FACTURA") or 0) != 0 else "", + "numero": numero_override if numero_override else ( + str(h.get("NUM_FACTURA") or "").strip() if (h.get("NUM_FACTURA") or 0) != 0 else "" + ), "fecha": fecha, "codTercero": str(h.get("COD_PACIENTE") or "").strip(), "codVendedor": "00",