Files
ATLAS/backend/app/api/v1/reportes.py
ATLAS Admin e59aa2a742 feat: Complete ATLAS system installation and API fixes
## Backend Changes
- Add new API endpoints: combustible, pois, mantenimiento, video, configuracion
- Fix vehiculos endpoint to return paginated response with items array
- Add /vehiculos/all endpoint for non-paginated list
- Add /geocercas/all endpoint
- Add /alertas/configuracion GET/PUT endpoints
- Add /viajes/activos and /viajes/iniciar endpoints
- Add /reportes/stats, /reportes/templates, /reportes/preview endpoints
- Add /conductores/all and /conductores/disponibles endpoints
- Update router.py to include all new modules

## Frontend Changes
- Fix authentication token handling (snake_case vs camelCase)
- Update vehiculosApi.listAll to use /vehiculos/all
- Fix FuelGauge component usage in Combustible page
- Fix chart component exports (named + default exports)
- Update API client for proper token refresh

## Infrastructure
- Rename services from ADAN to ATLAS
- Configure Cloudflare tunnel for atlas.consultoria-as.com
- Update systemd service files
- Configure PostgreSQL with TimescaleDB
- Configure Redis, Mosquitto, Traccar, MediaMTX

## Documentation
- Update installation guides
- Update API reference
- Rename all ADAN references to ATLAS

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 03:04:23 +00:00

304 lines
8.3 KiB
Python

"""
Endpoints para reportes y dashboard.
"""
from datetime import datetime
from typing import Optional
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from app.core.database import get_db
from app.core.security import get_current_user
from app.models.usuario import Usuario
from app.schemas.reporte import (
DashboardResumen,
DashboardGrafico,
ReporteRequest,
ReporteResponse,
)
from app.services.reporte_service import ReporteService
router = APIRouter(prefix="/reportes", tags=["Reportes"])
@router.get("/stats")
async def obtener_estadisticas_reportes(
db: AsyncSession = Depends(get_db),
current_user: Usuario = Depends(get_current_user),
):
"""Obtiene estadísticas de reportes generados."""
return {
"total_generados": 0,
"ultimo_mes": 0,
"por_tipo": {
"viajes": 0,
"alertas": 0,
"combustible": 0,
"mantenimiento": 0,
}
}
@router.get("/templates")
async def listar_plantillas_reportes(
db: AsyncSession = Depends(get_db),
current_user: Usuario = Depends(get_current_user),
):
"""Lista las plantillas de reportes disponibles."""
return [
{"id": "viajes", "nombre": "Reporte de Viajes", "descripcion": "Detalle de viajes realizados"},
{"id": "alertas", "nombre": "Reporte de Alertas", "descripcion": "Resumen de alertas generadas"},
{"id": "combustible", "nombre": "Reporte de Combustible", "descripcion": "Consumo y cargas de combustible"},
{"id": "mantenimiento", "nombre": "Reporte de Mantenimiento", "descripcion": "Estado de mantenimientos"},
{"id": "resumen", "nombre": "Reporte Resumen", "descripcion": "Resumen general de la flota"},
]
@router.post("/preview")
async def previsualizar_reporte(
request: ReporteRequest,
db: AsyncSession = Depends(get_db),
current_user: Usuario = Depends(get_current_user),
):
"""Previsualiza un reporte sin generarlo completamente."""
reporte_service = ReporteService(db)
datos = await reporte_service._recopilar_datos_reporte(request)
return {
"preview": True,
"tipo": request.tipo,
"registros": len(datos.get("datos", [])) if isinstance(datos, dict) else 0,
"datos_muestra": datos[:10] if isinstance(datos, list) else datos,
}
@router.get("/programados")
async def listar_reportes_programados(
db: AsyncSession = Depends(get_db),
current_user: Usuario = Depends(get_current_user),
):
"""Lista los reportes programados."""
# Por ahora retorna lista vacía, la funcionalidad completa requiere tabla de reportes programados
return {"items": [], "total": 0}
@router.post("/programar")
async def programar_reporte(
data: dict,
db: AsyncSession = Depends(get_db),
current_user: Usuario = Depends(get_current_user),
):
"""Programa un nuevo reporte."""
# Por ahora solo retorna confirmación, la funcionalidad completa requiere tabla de reportes programados
return {
"message": "Reporte programado",
"tipo": data.get("tipo"),
"frecuencia": data.get("frecuencia"),
"email_destino": data.get("email_destino"),
}
@router.get("/dashboard", response_model=DashboardResumen)
async def obtener_dashboard(
db: AsyncSession = Depends(get_db),
current_user: Usuario = Depends(get_current_user),
):
"""
Obtiene datos del dashboard principal.
Returns:
Resumen del dashboard.
"""
reporte_service = ReporteService(db)
return await reporte_service.obtener_dashboard_resumen()
@router.get("/dashboard/graficos", response_model=DashboardGrafico)
async def obtener_graficos_dashboard(
db: AsyncSession = Depends(get_db),
current_user: Usuario = Depends(get_current_user),
):
"""
Obtiene datos para gráficos del dashboard.
Returns:
Datos para gráficos.
"""
reporte_service = ReporteService(db)
return await reporte_service.obtener_dashboard_graficos()
@router.post("/generar", response_model=ReporteResponse)
async def generar_reporte(
request: ReporteRequest,
db: AsyncSession = Depends(get_db),
current_user: Usuario = Depends(get_current_user),
):
"""
Genera un reporte según los parámetros.
Args:
request: Parámetros del reporte.
Returns:
Información del reporte generado.
"""
reporte_service = ReporteService(db)
return await reporte_service.generar_reporte(request)
@router.get("/viajes")
async def reporte_viajes(
desde: datetime,
hasta: datetime,
vehiculo_id: Optional[int] = None,
formato: str = "json",
db: AsyncSession = Depends(get_db),
current_user: Usuario = Depends(get_current_user),
):
"""
Genera reporte de viajes.
Args:
desde: Fecha inicio.
hasta: Fecha fin.
vehiculo_id: Filtrar por vehículo.
formato: Formato de salida.
Returns:
Datos del reporte.
"""
reporte_service = ReporteService(db)
request = ReporteRequest(
tipo="viajes",
formato=formato if formato != "json" else "pdf",
fecha_inicio=desde,
fecha_fin=hasta,
vehiculos_ids=[vehiculo_id] if vehiculo_id else None,
)
datos = await reporte_service._recopilar_datos_reporte(request)
if formato == "json":
return datos
resultado = await reporte_service.generar_reporte(request)
return resultado
@router.get("/alertas")
async def reporte_alertas(
desde: datetime,
hasta: datetime,
vehiculo_id: Optional[int] = None,
formato: str = "json",
db: AsyncSession = Depends(get_db),
current_user: Usuario = Depends(get_current_user),
):
"""
Genera reporte de alertas.
Args:
desde: Fecha inicio.
hasta: Fecha fin.
vehiculo_id: Filtrar por vehículo.
formato: Formato de salida.
Returns:
Datos del reporte.
"""
reporte_service = ReporteService(db)
request = ReporteRequest(
tipo="alertas",
formato=formato if formato != "json" else "pdf",
fecha_inicio=desde,
fecha_fin=hasta,
vehiculos_ids=[vehiculo_id] if vehiculo_id else None,
)
datos = await reporte_service._recopilar_datos_reporte(request)
if formato == "json":
return datos
resultado = await reporte_service.generar_reporte(request)
return resultado
@router.get("/combustible")
async def reporte_combustible(
desde: datetime,
hasta: datetime,
vehiculo_id: Optional[int] = None,
formato: str = "json",
db: AsyncSession = Depends(get_db),
current_user: Usuario = Depends(get_current_user),
):
"""
Genera reporte de combustible.
Args:
desde: Fecha inicio.
hasta: Fecha fin.
vehiculo_id: Filtrar por vehículo.
formato: Formato de salida.
Returns:
Datos del reporte.
"""
reporte_service = ReporteService(db)
request = ReporteRequest(
tipo="combustible",
formato=formato if formato != "json" else "pdf",
fecha_inicio=desde,
fecha_fin=hasta,
vehiculos_ids=[vehiculo_id] if vehiculo_id else None,
)
datos = await reporte_service._recopilar_datos_reporte(request)
if formato == "json":
return datos
resultado = await reporte_service.generar_reporte(request)
return resultado
@router.get("/mantenimiento")
async def reporte_mantenimiento(
desde: datetime,
hasta: datetime,
vehiculo_id: Optional[int] = None,
formato: str = "json",
db: AsyncSession = Depends(get_db),
current_user: Usuario = Depends(get_current_user),
):
"""
Genera reporte de mantenimiento.
Args:
desde: Fecha inicio.
hasta: Fecha fin.
vehiculo_id: Filtrar por vehículo.
formato: Formato de salida.
Returns:
Datos del reporte.
"""
reporte_service = ReporteService(db)
request = ReporteRequest(
tipo="mantenimiento",
formato=formato if formato != "json" else "pdf",
fecha_inicio=desde,
fecha_fin=hasta,
vehiculos_ids=[vehiculo_id] if vehiculo_id else None,
)
datos = await reporte_service._recopilar_datos_reporte(request)
if formato == "json":
return datos
resultado = await reporte_service.generar_reporte(request)
return resultado