Fix param validation errors and add TNS config section

- terceros/transaccion: return clear error when required params (doc_num, num_factura) are missing instead of passing empty dict to Firebird causing Column unknown error
- transaccion: remove prefijo from 'por factura' query; parse num_factura as int when digit
- automation: add /preview endpoint to show patient/reception counts before sending; update UI with preview step and disabled run button until preview loads
- config: add TNS credentials section (tns_empresa, tns_usuario, tns_password, api_sucursal) with test-connection button
- config: add POST /config/test-tns endpoint

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-06-25 19:29:32 -05:00
co-authored by Claude Sonnet 4.6
parent 3755a51562
commit b4a7271d8d
7 changed files with 246 additions and 47 deletions
+51
View File
@@ -76,6 +76,57 @@ async def automation_page(request: Request, user: dict = Depends(get_current_use
})
@router.post("/preview")
async def preview_automation(
request: Request,
user: dict = Depends(get_current_user),
fecha: str = Form(...),
):
conn = get_connection()
configs = {row["key"]: row["value"] for row in conn.execute("SELECT * FROM config").fetchall()}
conn.close()
fb, fb_ok, fb_msg = get_firebird_from_config(configs)
if not fb_ok:
return JSONResponse({"success": False, "message": f"Error Firebird: {fb_msg}"})
fecha_ini = f"{fecha} 00:00:00"
fecha_fin = f"{fecha} 23:59:59"
params = {"fecha_ini": fecha_ini, "fecha_fin": fecha_fin}
ok1, err1, rows_pac = fb.execute_query(_SQL_PACIENTES, params)
if not ok1:
fb.disconnect()
return JSONResponse({"success": False, "message": f"Error BD pacientes: {err1}"})
ok2, err2, rows_rda = fb.execute_query(_SQL_RDA, params)
fb.disconnect()
if not ok2:
return JSONResponse({"success": False, "message": f"Error BD RDA: {err2}"})
grupos = agrupar_por_recepcion(rows_rda)
total_examenes = sum(len(v) for v in grupos.values())
pacientes_preview = [
{
"doc": str(p.get("DOCIDENT", "")),
"nombre": f"{p.get('NOMBRES', '')} {p.get('APELLIDOS', '')}".strip(),
"tipo": str(p.get("TIPOIDENT", "")),
}
for p in rows_pac[:10]
]
return JSONResponse({
"success": True,
"fecha": fecha,
"pacientes": len(rows_pac),
"recepciones": len(grupos),
"examenes": total_examenes,
"pacientes_preview": pacientes_preview,
"hay_mas": len(rows_pac) > 10,
})
@router.post("/run")
async def run_automation(
request: Request,
+16 -1
View File
@@ -1,7 +1,8 @@
from fastapi import APIRouter, Request, Form, Depends
from fastapi.responses import RedirectResponse
from fastapi.responses import JSONResponse, RedirectResponse
from app.database import get_connection
from app.auth import get_current_user
from app.services.api_client import get_tns_token
router = APIRouter(prefix="/config", tags=["config"])
@@ -45,6 +46,20 @@ async def config_page(request: Request, user: dict = Depends(get_current_user)):
})
@router.post("/test-tns")
async def test_tns(
request: Request,
user: dict = Depends(get_current_user),
empresa: str = Form(""),
usuario: str = Form(""),
password: str = Form(""),
):
token, err = await get_tns_token(empresa, usuario, password)
if token:
return JSONResponse({"success": True, "message": "Login TNS exitoso"})
return JSONResponse({"success": False, "message": err or "Error desconocido"})
@router.post("/save")
async def config_save(request: Request, user: dict = Depends(get_current_user)):
form = await request.form()
+10 -2
View File
@@ -79,8 +79,12 @@ async def preview_query(
if not ok:
return JSONResponse({"success": False, "message": f"Error Firebird: {msg}"})
if ":doc_num" in q["query_text"] and not doc_num:
fb.disconnect()
return JSONResponse({"success": False, "message": "Ingresa el número de documento para buscar el paciente"})
params = {}
if ":doc_num" in q["query_text"] and doc_num:
if ":doc_num" in q["query_text"]:
params["doc_num"] = doc_num
if ":fecha_ini" in q["query_text"]:
params["fecha_ini"] = "1900-01-01"
@@ -124,9 +128,13 @@ async def send_terceros(
if not ok:
return JSONResponse({"success": False, "message": f"Error Firebird: {msg}"})
if ":doc_num" in q["query_text"] and not doc_num:
fb.disconnect()
return JSONResponse({"success": False, "message": "Ingresa el número de documento"})
params = {}
if ":doc_num" in q["query_text"]:
params["doc_num"] = doc_num or configs.get("doc_num_default", "")
params["doc_num"] = doc_num
success, error, rows = fb.execute_query(q["query_text"], params if params else None)
fb.disconnect()
+12 -10
View File
@@ -53,12 +53,13 @@ async def preview_transaccion(
if not ok:
return JSONResponse({"success": False, "message": f"Error Firebird: {msg}"})
if ":num_factura" in q["query_text"] and not factura:
fb.disconnect()
return JSONResponse({"success": False, "message": "Ingresa el número de factura"})
params = {"fecha_ini": fecha_inicio, "fecha_fin": fecha_fin}
if ":num_factura" in q["query_text"] and factura:
params["num_factura"] = factura
prefijo = configs.get("api_prefijo", "")
if prefijo:
params["prefijo"] = prefijo
if ":num_factura" in q["query_text"]:
params["num_factura"] = int(factura) if factura.isdigit() else factura
success, error, rows = fb.execute_query(q["query_text"], params)
fb.disconnect()
@@ -101,12 +102,13 @@ async def send_transaccion(
if not ok:
return JSONResponse({"success": False, "message": f"Error Firebird: {msg}"})
if ":num_factura" in q["query_text"] and not factura:
fb.disconnect()
return JSONResponse({"success": False, "message": "Ingresa el número de factura"})
params = {"fecha_ini": fecha_inicio, "fecha_fin": fecha_fin}
if ":num_factura" in q["query_text"] and factura:
params["num_factura"] = factura
prefijo = configs.get("api_prefijo", "")
if prefijo:
params["prefijo"] = prefijo
if ":num_factura" in q["query_text"]:
params["num_factura"] = int(factura) if factura.isdigit() else factura
success, error, rows = fb.execute_query(q["query_text"], params)
fb.disconnect()