Fix candidatos: uppercase column keys, filter by TNS-configured articles, show last 10

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-06-26 19:15:26 -05:00
co-authored by Claude Sonnet 4.6
parent c2977011ee
commit c1cbe54105
2 changed files with 25 additions and 13 deletions
+19 -8
View File
@@ -72,7 +72,7 @@ async def test_page(request: Request, user: dict = Depends(get_current_user)):
@router.get("/candidatos") @router.get("/candidatos")
async def get_candidatos(request: Request, user: dict = Depends(get_current_user), async def get_candidatos(request: Request, user: dict = Depends(get_current_user),
contrato: str = "", factura: str = ""): contrato: str = "", factura: str = "", articulos: str = ""):
db = get_connection() db = get_connection()
cfg = {r[0]: r[1] for r in db.execute("SELECT key, value FROM config").fetchall()} cfg = {r[0]: r[1] for r in db.execute("SELECT key, value FROM config").fetchall()}
db.close() db.close()
@@ -81,9 +81,19 @@ async def get_candidatos(request: Request, user: dict = Depends(get_current_user
if not fb_ok: if not fb_ok:
return JSONResponse({"error": f"Error Firebird: {fb_msg}"}) return JSONResponse({"error": f"Error Firebird: {fb_msg}"})
sql = _SQL_CANDIDATOS # Artículos configurados con especialidad en TNS
arts_default = "CH4,CREA,TGP,VSG,PCR,AU,FER,TPO,TSH,TGO,GLI,BUN,COL,TRI,HDL,LDL,HBA1,VB12,VITD,PO,FER,K,NA,MG,URO,PRL,TSH,T4L,T3,T4,T3L,HIV,VDRL,PSA,AFP,CEA,CA125,CA199,FV,TP,TPT"
arts_str = articulos.strip() if articulos.strip() else arts_default
arts_list = [a.strip().upper() for a in arts_str.split(",") if a.strip()]
arts_in = ", ".join(f"'{a}'" for a in arts_list)
filtros = [
"r.NUM_FACTURA > 0",
"e.CODCONTRATO IS NOT NULL",
"TRIM(e.CODCONTRATO) <> ''",
f"rel.COD_EXAMEN IN ({arts_in})",
]
params = {} params = {}
filtros = ["r.NUM_FACTURA > 0", "e.CODCONTRATO IS NOT NULL", "TRIM(e.CODCONTRATO) <> ''"]
if contrato: if contrato:
filtros.append("e.CODCONTRATO = :contrato") filtros.append("e.CODCONTRATO = :contrato")
params["contrato"] = contrato params["contrato"] = contrato
@@ -92,10 +102,11 @@ async def get_candidatos(request: Request, user: dict = Depends(get_current_user
params["factura"] = int(factura) params["factura"] = int(factura)
sql_final = """ sql_final = """
SELECT FIRST 100 SELECT FIRST 10
r.IDRECEPCION, r.NUM_FACTURA, r.FECHA_RECEPCION, r.COD_PACIENTE, r.NIT_EMPRESA, r.IDRECEPCION, r.NUM_FACTURA, r.FECHA_RECEPCION, r.COD_PACIENTE, r.NIT_EMPRESA,
e.CODCONTRATO, LIST(DISTINCT rel.COD_EXAMEN, ', ') AS examenes, e.CODCONTRATO,
COUNT(DISTINCT rel.COD_EXAMEN) AS total_examenes LIST(DISTINCT rel.COD_EXAMEN, ', ') AS EXAMENES,
COUNT(DISTINCT rel.COD_EXAMEN) AS TOTAL_EXAMENES
FROM RECEPCION r FROM RECEPCION r
JOIN RELACION rel ON rel.IDRECEPCION = r.IDRECEPCION JOIN RELACION rel ON rel.IDRECEPCION = r.IDRECEPCION
LEFT JOIN EMPRESA e ON e.NIT = r.NIT_EMPRESA LEFT JOIN EMPRESA e ON e.NIT = r.NIT_EMPRESA
@@ -119,8 +130,8 @@ async def get_candidatos(request: Request, user: dict = Depends(get_current_user
"paciente": row.get("COD_PACIENTE", ""), "paciente": row.get("COD_PACIENTE", ""),
"empresa": row.get("NIT_EMPRESA", ""), "empresa": row.get("NIT_EMPRESA", ""),
"contrato": row.get("CODCONTRATO", ""), "contrato": row.get("CODCONTRATO", ""),
"examenes": row.get("examenes", ""), "examenes": row.get("EXAMENES", ""),
"total": row.get("total_examenes", 0), "total": row.get("TOTAL_EXAMENES", 0),
}) })
return JSONResponse({"candidatos": candidatos}) return JSONResponse({"candidatos": candidatos})
+6 -5
View File
@@ -8,11 +8,12 @@
<div class="bg-white rounded-xl shadow-sm border border-gray-200"> <div class="bg-white rounded-xl shadow-sm border border-gray-200">
<div class="px-6 py-4 border-b border-gray-200 flex items-center justify-between"> <div class="px-6 py-4 border-b border-gray-200 flex items-center justify-between">
<h3 class="font-semibold text-gray-800"><i class="fas fa-list mr-2 text-blue-500"></i>Candidatos disponibles</h3> <h3 class="font-semibold text-gray-800"><i class="fas fa-list mr-2 text-blue-500"></i>Candidatos disponibles</h3>
<div class="flex gap-2 items-center"> <div class="flex gap-2 items-center flex-wrap">
<input id="filtro-contrato" type="text" placeholder="Contrato (ej: 011)" <input id="filtro-contrato" type="text" placeholder="Contrato (ej: 011)"
class="px-3 py-1.5 border border-gray-300 rounded-lg text-sm w-32"> class="px-3 py-1.5 border border-gray-300 rounded-lg text-sm w-32">
<input id="filtro-factura" type="text" placeholder="Factura (ej: 3990)" <input id="filtro-articulos" type="text" placeholder="Artículos (ej: CH4,TSH,GLI)"
class="px-3 py-1.5 border border-gray-300 rounded-lg text-sm w-36"> class="px-3 py-1.5 border border-gray-300 rounded-lg text-sm w-56"
title="Filtrar por artículos configurados en TNS. Vacío = lista predeterminada.">
<button onclick="cargarCandidatos()" <button onclick="cargarCandidatos()"
class="px-4 py-1.5 bg-blue-600 text-white rounded-lg text-sm hover:bg-blue-700"> class="px-4 py-1.5 bg-blue-600 text-white rounded-lg text-sm hover:bg-blue-700">
<i class="fas fa-search mr-1"></i> Buscar <i class="fas fa-search mr-1"></i> Buscar
@@ -85,14 +86,14 @@
<script> <script>
async function cargarCandidatos() { async function cargarCandidatos() {
const contrato = document.getElementById('filtro-contrato').value.trim(); const contrato = document.getElementById('filtro-contrato').value.trim();
const factura = document.getElementById('filtro-factura').value.trim(); const articulos = document.getElementById('filtro-articulos').value.trim();
document.getElementById('cargando-candidatos').classList.remove('hidden'); document.getElementById('cargando-candidatos').classList.remove('hidden');
document.getElementById('tabla-candidatos').classList.add('hidden'); document.getElementById('tabla-candidatos').classList.add('hidden');
document.getElementById('sin-candidatos').classList.add('hidden'); document.getElementById('sin-candidatos').classList.add('hidden');
const params = new URLSearchParams(); const params = new URLSearchParams();
if (contrato) params.append('contrato', contrato); if (contrato) params.append('contrato', contrato);
if (factura) params.append('factura', factura); if (articulos) params.append('articulos', articulos);
const resp = await fetch('/test-rda/candidatos?' + params.toString()); const resp = await fetch('/test-rda/candidatos?' + params.toString());
const data = await resp.json(); const data = await resp.json();