Mejora Transacción y Historial: estado por fila, envío individual y filtros avanzados
- Transacción: tabla con estado Enviado/Pendiente/Error por IDRECEPCION, botón enviar fila a fila o masivo, modal con JSON + respuesta TNS por registro
- Historial: filtros por fecha, tipo, IDRECEPCION/contrato; paginación 50 por página; modal con 3 tabs (JSON enviado / Respuesta TNS / Mensaje)
- DB: migración automática para agregar columnas idrecepcion, contrato, mensaje_tns a tabla envios
- Logs route: nuevo endpoint /logs/detalle/{id} para cargar detalle completo vía JS
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
ef71a1db56
commit
7699303a53
+60
-12
@@ -1,9 +1,12 @@
|
||||
from fastapi import APIRouter, Request, Depends
|
||||
from fastapi.responses import JSONResponse
|
||||
from app.database import get_connection
|
||||
from app.auth import get_current_user
|
||||
|
||||
router = APIRouter(prefix="/logs", tags=["logs"])
|
||||
|
||||
PAGE_SIZE = 50
|
||||
|
||||
|
||||
@router.get("")
|
||||
async def logs_page(
|
||||
@@ -12,9 +15,12 @@ async def logs_page(
|
||||
tipo: str = "",
|
||||
status: str = "",
|
||||
factura: str = "",
|
||||
paciente: str = "",
|
||||
fecha_desde: str = "",
|
||||
fecha_hasta: str = "",
|
||||
offset: int = 0,
|
||||
):
|
||||
conn = get_connection()
|
||||
|
||||
where = ["1=1"]
|
||||
params = []
|
||||
|
||||
@@ -27,29 +33,71 @@ async def logs_page(
|
||||
if factura:
|
||||
where.append("e.factura LIKE ?")
|
||||
params.append(f"%{factura}%")
|
||||
if paciente:
|
||||
where.append("(CAST(e.idrecepcion AS TEXT) LIKE ? OR e.contrato LIKE ?)")
|
||||
params += [f"%{paciente}%", f"%{paciente}%"]
|
||||
if fecha_desde:
|
||||
where.append("DATE(e.created_at) >= ?")
|
||||
params.append(fecha_desde)
|
||||
if fecha_hasta:
|
||||
where.append("DATE(e.created_at) <= ?")
|
||||
params.append(fecha_hasta)
|
||||
|
||||
w = " AND ".join(where)
|
||||
|
||||
total = conn.execute(f"SELECT COUNT(*) FROM envios e WHERE {w}", params).fetchone()[0]
|
||||
|
||||
envios = conn.execute(f"""
|
||||
SELECT e.*, u.username FROM envios e
|
||||
LEFT JOIN users u ON e.user_id = u.id
|
||||
WHERE {' AND '.join(where)}
|
||||
ORDER BY e.created_at DESC LIMIT 100
|
||||
""", params).fetchall()
|
||||
WHERE {w}
|
||||
ORDER BY e.created_at DESC
|
||||
LIMIT ? OFFSET ?
|
||||
""", params + [PAGE_SIZE, offset]).fetchall()
|
||||
|
||||
stats = conn.execute("""
|
||||
SELECT
|
||||
tipo,
|
||||
status,
|
||||
COUNT(*) as total,
|
||||
SUM(CASE WHEN status = 'success' THEN 1 ELSE 0 END) as exitosos,
|
||||
SUM(CASE WHEN status = 'error' THEN 1 ELSE 0 END) as fallidos
|
||||
SELECT tipo, status, COUNT(*) as cnt
|
||||
FROM envios
|
||||
GROUP BY tipo, status
|
||||
ORDER BY tipo, status
|
||||
""").fetchall()
|
||||
|
||||
conn.close()
|
||||
|
||||
has_more = (offset + PAGE_SIZE) < total
|
||||
|
||||
return request.app.state.templates.TemplateResponse("logs.html", {
|
||||
"request": request, "user": user,
|
||||
"envios": envios, "stats": stats,
|
||||
"filtro_tipo": tipo, "filtro_status": status, "filtro_factura": factura,
|
||||
"envios": envios, "stats": stats, "total": total,
|
||||
"filtro_tipo": tipo, "filtro_status": status,
|
||||
"filtro_factura": factura, "filtro_paciente": paciente,
|
||||
"filtro_fecha_desde": fecha_desde, "filtro_fecha_hasta": fecha_hasta,
|
||||
"offset": offset, "page_size": PAGE_SIZE, "has_more": has_more,
|
||||
})
|
||||
|
||||
|
||||
@router.get("/detalle/{envio_id}")
|
||||
async def detalle_envio(envio_id: int, request: Request, user: dict = Depends(get_current_user)):
|
||||
conn = get_connection()
|
||||
row = conn.execute(
|
||||
"SELECT e.*, u.username FROM envios e LEFT JOIN users u ON e.user_id = u.id WHERE e.id = ?",
|
||||
(envio_id,)
|
||||
).fetchone()
|
||||
conn.close()
|
||||
if not row:
|
||||
return JSONResponse({"error": "No encontrado"}, status_code=404)
|
||||
return JSONResponse({
|
||||
"id": row["id"],
|
||||
"tipo": row["tipo"],
|
||||
"factura": row["factura"],
|
||||
"idrecepcion": row["idrecepcion"],
|
||||
"contrato": row["contrato"],
|
||||
"status": row["status"],
|
||||
"mensaje_tns": row["mensaje_tns"],
|
||||
"respuesta_api": row["respuesta_api"],
|
||||
"json_enviado": row["json_enviado"],
|
||||
"fecha_inicio": row["fecha_inicio"],
|
||||
"fecha_fin": row["fecha_fin"],
|
||||
"created_at": row["created_at"],
|
||||
"username": row["username"],
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user