feat(transaccion): envío RDA directo por prefijo + número de factura

Nuevo endpoint POST /transaccion/send-direct y panel "Enviar RDA directo"
en la UI: ingresa Tipo (prefijo) y Número, busca en Firebird y envía a TNS
sin necesidad de rango de fechas ni pasar por el flujo de preview.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-07-09 15:10:41 -05:00
co-authored by Claude Sonnet 4.6
parent d3a6ab7ab6
commit 3baa6e5f75
2 changed files with 194 additions and 0 deletions
+103
View File
@@ -308,3 +308,106 @@ async def send_transaccion(
"total_errores": err_count,
"resultados": resultados,
})
@router.post("/send-direct")
async def send_direct(
request: Request,
user: dict = Depends(get_current_user),
prefijo: str = Form(...),
numero: str = Form(...),
query_id: int = Form(...),
):
conn = get_connection()
q = conn.execute("SELECT * FROM queries WHERE id = ?", (query_id,)).fetchone()
cfg = {r["key"]: r["value"] for r in conn.execute("SELECT * FROM config").fetchall()}
conn.close()
if not q:
return JSONResponse({"success": False, "message": "Consulta no encontrada"})
prefijo = prefijo.strip().upper()
numero = numero.strip()
factura_str = f"{prefijo}{numero}"
rows, err, _ = _query_rows(cfg, q["query_text"], factura_str, "2000-01-01", "2099-12-31")
if rows is None:
return JSONResponse({"success": False, "message": err})
if not rows:
return JSONResponse({"success": False, "message": f"No se encontró factura {factura_str} en Firebird"})
grupos = agrupar_por_recepcion(rows)
if not grupos:
return JSONResponse({"success": False, "message": "Sin datos agrupables"})
token, token_err = await get_tns_token(
cfg.get("tns_empresa", ""), cfg.get("tns_usuario", ""), cfg.get("tns_password", "")
)
if not token:
return JSONResponse({"success": False, "message": f"Error login TNS: {token_err}"})
headers = {"Content-Type": "application/json", "Authorization": f"Bearer {token}"}
api_sucursal = cfg.get("api_sucursal", "") or "00"
endpoint = f"{TNS_BASE}/v2/rda/RdaPaciente/Insertar?codigosucursal={api_sucursal}"
contrato_map = load_contrato_map()
resultados = []
async with httpx.AsyncClient(timeout=int(cfg.get("api_timeout", 30))) as client:
for id_rec, grupo_rows in grupos.items():
num_fac = str(grupo_rows[0].get("NUM_FACTURA") or "").strip()
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"),
num_fac,
contrato_map=contrato_map,
)
raw_resp = ""
ok_rda = False
msg_tns = ""
try:
r = await client.post(endpoint, json=rda_json, headers=headers)
raw_resp = r.text
try:
data = r.json()
ok_rda = bool(data.get("status") or (data.get("data") or {}).get("success", False))
msg_tns = ((data.get("data") or {}).get("response") or data.get("message") or raw_resp[:300])
except Exception:
ok_rda = r.status_code < 300
msg_tns = raw_resp[:300]
except Exception as ex:
msg_tns = str(ex)
conn = get_connection()
conn.execute("""
INSERT INTO envios (user_id, tipo, factura, idrecepcion, contrato,
fecha_inicio, fecha_fin, pacientes_count, servicios_count,
status, json_enviado, respuesta_api, mensaje_tns, created_at)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)
""", (
user["user_id"], "transaccion", factura_str, id_rec,
str(grupo_rows[0].get("CODCONTRATO", "")),
"2000-01-01", "2099-12-31", 1, len(grupo_rows),
"success" if ok_rda else "error",
json_lib.dumps(rda_json, ensure_ascii=False)[:5000],
raw_resp[:2000], msg_tns, datetime.now().isoformat(),
))
conn.commit()
conn.close()
resultados.append({
"idrecepcion": id_rec,
"factura": factura_str,
"success": ok_rda,
"message": msg_tns,
"raw_tns": raw_resp[:1000],
"json": rda_json,
})
ok_count = sum(1 for r in resultados if r["success"])
return JSONResponse({
"success": ok_count > 0,
"total": len(resultados),
"resultados": resultados,
})