Files
rips_manager/app/routes/envios.py
T

117 lines
4.5 KiB
Python

import httpx
import traceback as tb
from fastapi import APIRouter, Request, Depends, Query
from fastapi.responses import JSONResponse
from app.auth import get_current_user
from app.database import get_connection
from app.services.scheduler import sync_recientes
from app.services.firebird_service import get_firebird_from_config
router = APIRouter(prefix="/envios", tags=["envios"])
@router.get("/tns")
async def envios_tns(request: Request, user: dict = Depends(get_current_user)):
return request.app.state.templates.TemplateResponse("envios_tns.html", {
"request": request, "user": user,
})
@router.get("/erp")
async def envios_erp(request: Request, user: dict = Depends(get_current_user)):
conn = get_connection()
configs = {row["key"]: row["value"] for row in conn.execute("SELECT * FROM config").fetchall()}
conn.close()
wa_url = configs.get("whatsapp_url", "")
wa_key = configs.get("whatsapp_api_key", "")
return request.app.state.templates.TemplateResponse("envios_erp.html", {
"request": request, "user": user,
"wa_configurado": bool(wa_url and wa_key),
"wa_url": wa_url,
})
@router.post("/erp/sync-now")
async def erp_sync_now(
ventana_min: int = Query(default=30, ge=1, le=1440),
user: dict = Depends(get_current_user),
):
try:
resultado = await sync_recientes(ventana_min=ventana_min)
return JSONResponse(resultado)
except Exception as e:
return JSONResponse({"ok": False, "error": str(e), "traceback": tb.format_exc()})
@router.post("/erp/sync-diagnosticos")
async def erp_sync_diagnosticos(
user: dict = Depends(get_current_user),
start_from: int = Query(default=0, ge=0, description="Índice desde el que reanudar"),
):
"""Migra los 12.422 diagnósticos CIE-10 de Firebird → WhatsApp en lotes de 200."""
try:
conn = get_connection()
configs = {row["key"]: row["value"] for row in conn.execute("SELECT * FROM config").fetchall()}
conn.close()
wa_url = configs.get("whatsapp_url", "").rstrip("/")
wa_key = configs.get("whatsapp_api_key", "")
if not wa_url or not wa_key:
return JSONResponse({"ok": False, "error": "whatsapp_url o whatsapp_api_key no configurados"})
fb, ok, msg = get_firebird_from_config(configs)
if not ok:
return JSONResponse({"ok": False, "error": f"Firebird: {msg}"})
ok_r, err_r, rows = fb.execute_query(
"SELECT TRIM(d.COD_DIAG) AS COD_DIAG, TRIM(d.CONCEPTO) AS CONCEPTO "
"FROM DIAGNOSTICO d ORDER BY d.COD_DIAG", None
)
fb.disconnect()
if not ok_r:
return JSONResponse({"ok": False, "error": f"Query Firebird: {err_r}"})
diagnosticos = [{"cod": r["COD_DIAG"], "concepto": r["CONCEPTO"]} for r in (rows or [])]
total = len(diagnosticos)
batch_size = 200
url = f"{wa_url}/api/lab/ingest_diagnosticos.php"
headers = {"Content-Type": "application/json", "X-Lab-Key": wa_key}
insertados = 0
errores = []
async with httpx.AsyncClient(timeout=60) as client:
for i in range(start_from, total, batch_size):
lote = diagnosticos[i:i + batch_size]
try:
resp = await client.post(url, json={"rows": lote}, headers=headers)
try:
data = resp.json()
except Exception:
raw = resp.text[:400].strip()
errores.append(f"Lote {i}-{i+len(lote)} HTTP {resp.status_code}: {raw!r}")
if i == 0:
break # Si el primer lote ya falla, no tiene sentido continuar
continue
if data.get("ok"):
insertados += data.get("insertados", len(lote))
else:
errores.append(f"Lote {i}-{i+len(lote)}: {data.get('error', '?')}")
if i == 0:
break
except Exception as ex:
errores.append(f"Lote {i}-{i+len(lote)}: {ex}")
if i == 0:
break
return JSONResponse({
"ok": len(errores) == 0,
"total": total,
"insertados": insertados,
"lotes": (total + batch_size - 1) // batch_size,
"errores": errores,
})
except Exception as e:
return JSONResponse({"ok": False, "error": str(e), "traceback": tb.format_exc()})