diff --git a/route-planner/src/app/private/home/planning-kpis/planning-kpis.component.html b/route-planner/src/app/private/home/planning-kpis/planning-kpis.component.html
index 3459cd7..de01728 100644
--- a/route-planner/src/app/private/home/planning-kpis/planning-kpis.component.html
+++ b/route-planner/src/app/private/home/planning-kpis/planning-kpis.component.html
@@ -31,10 +31,6 @@
diff --git a/route-planner/src/app/private/home/planning-kpis/planning-kpis.component.ts b/route-planner/src/app/private/home/planning-kpis/planning-kpis.component.ts
index d370e3a..4e1b878 100644
--- a/route-planner/src/app/private/home/planning-kpis/planning-kpis.component.ts
+++ b/route-planner/src/app/private/home/planning-kpis/planning-kpis.component.ts
@@ -14,9 +14,7 @@ interface KpiSummary {
users: number;
days: number;
totalDistance: number;
- totalTravelHours: number;
averageDistance: number;
- averageTravelHours: number;
totalWorkHours: number;
averageRoutesPerUser: number;
averageUtilization: number;
@@ -95,7 +93,6 @@ export class PlanningKpisComponent implements OnInit, OnDestroy {
const totalPdvs = new Set([...assignedPdvIds, ...unassignedPdvIds]).size;
const dailyRoutes = summarizeDailyRoutes(assigned);
const totalDistance = dailyRoutes.reduce((sum, day) => sum + day.distanceKm, 0);
- const totalTravelHours = dailyRoutes.reduce((sum, day) => sum + day.travelHours, 0);
const totalWorkHours = dailyRoutes.reduce((sum, day) => sum + day.workHours, 0);
const users = new Set(assigned.map(route => String(route.json.usuario_id))).size;
const days = new Set(assigned.map(route => route.json.dia)).size;
@@ -146,9 +143,7 @@ export class PlanningKpisComponent implements OnInit, OnDestroy {
users,
days,
totalDistance,
- totalTravelHours,
averageDistance: assigned.length ? totalDistance / assigned.length : 0,
- averageTravelHours: assigned.length ? totalTravelHours / assigned.length : 0,
totalWorkHours,
averageRoutesPerUser: users ? assigned.length / users : 0,
averageUtilization,
@@ -186,9 +181,7 @@ export class PlanningKpisComponent implements OnInit, OnDestroy {
users: 0,
days: 0,
totalDistance: 0,
- totalTravelHours: 0,
averageDistance: 0,
- averageTravelHours: 0,
totalWorkHours: 0,
averageRoutesPerUser: 0,
averageUtilization: 0,
diff --git a/route-planner/src/app/private/home/route-overview-map/route-overview-map.component.css b/route-planner/src/app/private/home/route-overview-map/route-overview-map.component.css
index d2879f7..70a5a87 100644
--- a/route-planner/src/app/private/home/route-overview-map/route-overview-map.component.css
+++ b/route-planner/src/app/private/home/route-overview-map/route-overview-map.component.css
@@ -357,6 +357,13 @@
.daily-routes-card { padding: 12px; border: 1px solid var(--glm-gris-medio); border-top: 3px solid var(--glm-azul); border-radius: 4px; background: var(--glm-surface); }
.daily-routes-card h3 { margin: 0 0 8px; color: var(--glm-azul); font-size: 0.82rem; text-transform: uppercase; }
+.daily-route-group { border-bottom: 1px solid var(--glm-gris-claro); }
+.daily-route-group:last-child { border-bottom: 0; }
+.daily-route-toggle { display: flex; width: 100%; align-items: center; justify-content: space-between; gap: 8px; padding: 10px 0; border: 0; background: transparent; color: var(--glm-gris-oscuro); cursor: pointer; font: inherit; text-align: left; }
+.daily-route-toggle:hover { background: var(--glm-gris-claro); }
+.daily-route-toggle-title { color: var(--glm-azul); font-weight: 700; }
+.daily-route-toggle > span:last-child { color: var(--glm-acero); font-size: 0.78rem; }
+.daily-route-group-content { padding-left: 14px; }
.daily-route { display: grid; gap: 3px; padding: 8px 0; border-bottom: 1px solid var(--glm-gris-claro); color: var(--glm-gris-oscuro); font-size: 0.78rem; }
.daily-route:last-child { border-bottom: 0; }
.daily-route span, .daily-route small { color: var(--glm-acero); }
diff --git a/route-planner/src/app/private/home/route-overview-map/route-overview-map.component.html b/route-planner/src/app/private/home/route-overview-map/route-overview-map.component.html
index d08bc9f..fcb4feb 100644
--- a/route-planner/src/app/private/home/route-overview-map/route-overview-map.component.html
+++ b/route-planner/src/app/private/home/route-overview-map/route-overview-map.component.html
@@ -31,7 +31,7 @@
- {{ filteredRoutes.length }} PDVs
+ {{ uniqueFilteredRoutes.length }} PDVs
{{ totalDistancia }} km
{{ totalDuracionMin }} min
@@ -152,26 +152,19 @@
Rutas diarias
-
- {{ day.userName }} · {{ day.day }}
- {{ day.routes.length }} paradas · {{ day.distanceKm | number:'1.1-1' }} km · {{ (day.travelHours * 60) | number:'1.0-0' }} min
- {{ day.totalHours | number:'1.1-1' }} / {{ day.capacityHours | number:'1.1-1' }} h {{ day.exceedsCapacity ? '· Excede capacidad' : '· Capacidad disponible' }}
+
+
+
+
+ {{ route.userName }}
+ {{ route.routes.length }} paradas · {{ route.distanceKm | number:'1.1-1' }} km · {{ (route.travelHours * 60) | number:'1.0-0' }} min
+ {{ route.totalHours | number:'1.1-1' }} / {{ route.capacityHours | number:'1.1-1' }} h {{ route.exceedsCapacity ? '· Excede capacidad' : '· Capacidad disponible' }}
+
+
-
-
{{ selectedUsuarioId === 'Todos' ? 'PDVs de todos los usuarios' : 'PDVs del usuario' }} ({{ filteredRoutes.length }})
-
-
diff --git a/route-planner/src/app/private/home/route-overview-map/route-overview-map.component.ts b/route-planner/src/app/private/home/route-overview-map/route-overview-map.component.ts
index e5a20d1..566aa67 100644
--- a/route-planner/src/app/private/home/route-overview-map/route-overview-map.component.ts
+++ b/route-planner/src/app/private/home/route-overview-map/route-overview-map.component.ts
@@ -11,6 +11,14 @@ import { RouteAssignedResponse, RouteNoAssignedResponse } from '../../../core/mo
import { colorForUsuario } from '../../../shared/utils/palette.utils';
import { DailyRouteSummary, haversineKm, sequenceRoutes, summarizeDailyRoutes } from '../../../shared/utils/route-sequencing.utils';
+interface DailyRouteGroup {
+ day: string;
+ routes: DailyRouteSummary[];
+ totalStops: number;
+ totalDistance: number;
+ totalTravelHours: number;
+}
+
interface MapRoute {
data: RouteAssignedResponse;
color: string;
@@ -53,6 +61,7 @@ export class RouteOverviewMapComponent implements OnInit, OnDestroy, AfterViewIn
dias: string[] = [];
selectedUsuarioId: string = 'Todos';
selectedDia: string = 'Todos';
+ expandedDailyRouteDay: string | null = null;
selectedRouteDetail: RouteAssignedResponse | null = null;
filteredRoutes: RouteAssignedResponse[] = [];
@@ -81,16 +90,41 @@ export class RouteOverviewMapComponent implements OnInit, OnDestroy, AfterViewIn
reassignError: string | null = null;
// Summary stats
+ get uniqueFilteredRoutes(): RouteAssignedResponse[] {
+ const unique = new Map