From e68f24fe202e5314647487bd2e7b48886e29e660 Mon Sep 17 00:00:00 2001 From: acazares Date: Tue, 13 Jan 2026 08:21:57 -0600 Subject: [PATCH] feat(dashboard): add pedimentos metrics and chart data to dashboard service --- backend/api/v1/modules/core/dashboard/dto.py | 1 + .../api/v1/modules/core/dashboard/service.py | 70 ++++++++++++++++++- 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/backend/api/v1/modules/core/dashboard/dto.py b/backend/api/v1/modules/core/dashboard/dto.py index acc981c6..1228c98a 100644 --- a/backend/api/v1/modules/core/dashboard/dto.py +++ b/backend/api/v1/modules/core/dashboard/dto.py @@ -63,6 +63,7 @@ class DashboardStats(BaseModel): # Datos para gráficas invoices_by_month: List[ChartDataPoint] = Field(default_factory=list) + pedimentos_by_month: List[ChartDataPoint] = Field(default_factory=list) operations_by_type: List[ChartDataPoint] = Field(default_factory=list) top_clients: List[ChartDataPoint] = Field(default_factory=list) top_providers: List[ChartDataPoint] = Field(default_factory=list) diff --git a/backend/api/v1/modules/core/dashboard/service.py b/backend/api/v1/modules/core/dashboard/service.py index fdefad75..9c10d7a7 100644 --- a/backend/api/v1/modules/core/dashboard/service.py +++ b/backend/api/v1/modules/core/dashboard/service.py @@ -18,6 +18,7 @@ from api.v1.modules.a76.clients_and_providers.models import ( ClientOrProviderEnum, ) from api.v1.modules.a76.general_catalogs.company.models import Company +from api.v1.modules.a76.pedmientos.models.pedimentos import Pedimentos from .dto import ( DashboardStats, @@ -320,6 +321,70 @@ class DashboardService: return activities[:limit] + def get_pedimentos_metrics(self) -> tuple[KPIMetric, List[ChartDataPoint]]: + """Obtiene métricas de pedimentos""" + # Total de pedimentos actuales + current_total = ( + self.db.query(func.count(Pedimentos.id)) + .filter( + Pedimentos.tenant_id == self.tenant_id, + Pedimentos.company_id == self.company_id, + ) + .scalar() + or 0 + ) + + # Total del mes anterior para comparación + last_month = datetime.utcnow() - timedelta(days=30) + previous_total = ( + self.db.query(func.count(Pedimentos.id)) + .filter( + Pedimentos.tenant_id == self.tenant_id, + Pedimentos.company_id == self.company_id, + Pedimentos.created_at < last_month, + ) + .scalar() + or 0 + ) + + percentage, trend = self._calculate_trend(current_total, previous_total) + + kpi = KPIMetric( + label="Total Pedimentos", + value=current_total, + previous_value=previous_total, + percentage_change=percentage, + trend=trend, + ) + + # Pedimentos por mes (últimos 6 meses) + six_months_ago = datetime.utcnow() - timedelta(days=180) + + monthly_data = ( + self.db.query( + func.date_trunc("month", Pedimentos.created_at).label("month"), + func.count(Pedimentos.id).label("count"), + ) + .filter( + Pedimentos.tenant_id == self.tenant_id, + Pedimentos.company_id == self.company_id, + Pedimentos.created_at >= six_months_ago, + ) + .group_by("month") + .order_by("month") + .all() + ) + + chart_data = [ + ChartDataPoint( + label=row.month.strftime("%b %Y") if row.month else "Unknown", + value=float(row.count), + ) + for row in monthly_data + ] + + return kpi, chart_data + def get_complete_dashboard_stats(self) -> DashboardStats: """Genera estadísticas completas para el dashboard""" @@ -339,8 +404,8 @@ class DashboardService: operations_chart = self.get_operations_by_type() recent_activity = self.get_recent_activity() - # KPI de pedimentos (placeholder - implementar cuando exista el modelo) - pedimento_kpi = KPIMetric(label="Total Pedimentos", value=0, trend="stable") + # Obtener métricas de pedimentos + pedimento_kpi, pedimentos_chart = self.get_pedimentos_metrics() # KPI de aprobaciones pendientes pending_kpi = KPIMetric(label="Pendientes", value=0, trend="stable") @@ -353,6 +418,7 @@ class DashboardService: active_items=items_kpi, pending_approvals=pending_kpi, invoices_by_month=invoices_chart, + pedimentos_by_month=pedimentos_chart, operations_by_type=operations_chart, top_clients=top_clients, top_providers=top_providers,