Fix colisión de numero de factura en TNS cuando varios IDRECEPCION comparten NUM_FACTURA
- 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 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
7e0c6039b8
commit
d9d3deef6c
+18
-1
@@ -266,9 +266,24 @@ async def test_enviar(request: Request, user: dict = Depends(get_current_user)):
|
|||||||
|
|
||||||
# Paso 2: enviar RDA
|
# Paso 2: enviar RDA
|
||||||
grupos = agrupar_por_recepcion(rows_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:
|
async with httpx.AsyncClient(timeout=30) as client:
|
||||||
for id_rec, grupo_rows in grupos.items():
|
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]
|
examenes = [r.get("COD_EXAMEN", "") for r in grupo_rows]
|
||||||
try:
|
try:
|
||||||
r = await client.post(endpoint_rda, json=rda_json, headers=headers)
|
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,
|
"respuesta_tns": raw_resp,
|
||||||
"json_enviado": rda_json,
|
"json_enviado": rda_json,
|
||||||
})
|
})
|
||||||
|
if ok_rda:
|
||||||
|
facturas_usadas_sesion.add(num_factura)
|
||||||
db_log = get_connection()
|
db_log = get_connection()
|
||||||
db_log.execute(
|
db_log.execute(
|
||||||
"INSERT OR REPLACE INTO rda_test_log (idrecepcion, factura, contrato, ok, mensaje) VALUES (?,?,?,?,?)",
|
"INSERT OR REPLACE INTO rda_test_log (idrecepcion, factura, contrato, ok, mensaje) VALUES (?,?,?,?,?)",
|
||||||
|
|||||||
@@ -227,15 +227,29 @@ async def send_transaccion(
|
|||||||
api_sucursal = cfg.get("api_sucursal", "") or "00"
|
api_sucursal = cfg.get("api_sucursal", "") or "00"
|
||||||
endpoint = f"{TNS_BASE}/v2/rda/RdaPaciente/Insertar?codigosucursal={api_sucursal}"
|
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 = []
|
resultados = []
|
||||||
async with httpx.AsyncClient(timeout=int(cfg.get("api_timeout", 30))) as client:
|
async with httpx.AsyncClient(timeout=int(cfg.get("api_timeout", 30))) as client:
|
||||||
for id_rec, grupo_rows in grupos.items():
|
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(
|
rda_json = generar_rda_paciente(
|
||||||
grupo_rows,
|
grupo_rows,
|
||||||
cfg.get("profesional_default", ""),
|
cfg.get("profesional_default", ""),
|
||||||
cfg.get("especialidad_default", ""),
|
cfg.get("especialidad_default", ""),
|
||||||
cfg.get("remisionante_default", "00"),
|
cfg.get("remisionante_default", "00"),
|
||||||
cfg.get("prefijo_tns_default", "00"),
|
cfg.get("prefijo_tns_default", "00"),
|
||||||
|
numero_override,
|
||||||
)
|
)
|
||||||
raw_resp = ""
|
raw_resp = ""
|
||||||
ok_rda = False
|
ok_rda = False
|
||||||
@@ -270,6 +284,8 @@ async def send_transaccion(
|
|||||||
raw_resp[:2000], msg_tns,
|
raw_resp[:2000], msg_tns,
|
||||||
datetime.now().isoformat(),
|
datetime.now().isoformat(),
|
||||||
))
|
))
|
||||||
|
if ok_rda:
|
||||||
|
facturas_ok_sesion.add(num_factura)
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
resultados.append({"idrecepcion": id_rec, "success": ok_rda, "msg": msg_tns})
|
resultados.append({"idrecepcion": id_rec, "success": ok_rda, "msg": msg_tns})
|
||||||
|
|||||||
@@ -97,7 +97,8 @@ def agrupar_por_recepcion(rows: list) -> dict:
|
|||||||
|
|
||||||
|
|
||||||
def generar_rda_paciente(rows: list, default_profesional: str = "", default_especialidad: str = "",
|
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:
|
if not rows:
|
||||||
return {}
|
return {}
|
||||||
h = rows[0]
|
h = rows[0]
|
||||||
@@ -159,7 +160,9 @@ def generar_rda_paciente(rows: list, default_profesional: str = "", default_espe
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
"codigoPrefijo": default_prefijo or str(h.get("PREFIJO") or "00").strip(),
|
"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,
|
"fecha": fecha,
|
||||||
"codTercero": str(h.get("COD_PACIENTE") or "").strip(),
|
"codTercero": str(h.get("COD_PACIENTE") or "").strip(),
|
||||||
"codVendedor": "00",
|
"codVendedor": "00",
|
||||||
|
|||||||
Reference in New Issue
Block a user