# Plan: Reportería de Remisiones / Traslados — Recomendación

## Objetivo

Dar al usuario reportes **operativos** sobre los traslados de mercadería (notas de remisión):
quién trasladó qué, cuánto, hacia dónde, cuántos kilómetros, en qué estado, y qué salió del
depósito que **todavía no se facturó**.

Un cliente pidió puntualmente un **reporte por chofer**. En vez de construir un reporte aislado
que solo sirve a ese caso, la recomendación es hacer **un reporte genérico con dimensión de
agrupación configurable** — así el mismo reporte responde "por chofer", "por transportista",
"por vehículo", "por cliente", "por destino", etc., y le sirve a todas las empresas.

**Filosofía:** genérico > específico. Un reporte con `Agrupar por` cubre N pedidos puntuales.

---

## Datos disponibles (verificado en `nota_remision_cab` + detalle)

| Dato | Origen | Sirve para |
|---|---|---|
| Número, fecha emisión (`dfeemide`) | cabecera | identificar / filtrar por período |
| Cliente | `cliente_id` → `clientes` → `personas` (razón social, RUC) | agrupar/filtrar por cliente |
| Transportista | `transportista_id` → `personas` (razón social, RUC) | agrupar/filtrar por transportista |
| **Chofer** | `chofer_id` → `personas` (nombre, documento) + libreta/categoría/vencimiento licencia | **agrupar/filtrar por chofer (pedido del cliente)** |
| Vehículo | `vehiculo_id` (marca, modelo, matrícula/identificación, tipo) | flota, uso por vehículo |
| Agente de transporte | `agente_id` (opcional) | despachos con agente |
| **Kilómetros** | `dkmr` | km recorridos por chofer/vehículo/ruta |
| Motivo de emisión | `motivo_emision_id` (venta, consignación, devolución, interno…) | analizar por tipo de traslado |
| Tipo / modalidad transporte | `tipo_transporte_id`, `modalidad_transporte_id` | terrestre/fluvial, granel/refrigerado |
| Origen → Destino | ciudades salida/entrega → distrito → departamento | rutas, cobertura geográfica |
| Estado / Estado SIFEN | `estado`, `estado_sifen` | control de aprobadas/rechazadas/anuladas |
| Ítems | `nota_remision_det` (cantidad, precio, `cantidad_facturada`) | unidades, valor mercadería, facturado vs pendiente |

**Métricas derivadas por remisión:**
- **Valor de mercadería** = Σ(cantidad × precio_unitario) de los ítems.
- **Unidades trasladadas** = Σ cantidad.
- **Estado de facturación**: `sin facturar` / `parcial` / `facturada` (comparando `cantidad` vs `cantidad_facturada` por ítem).

---

## Ubicación en el menú (pantalla Reportes)

Se recomienda un **grupo nuevo "Logística / Traslados"** en `Reportes.jsx`, porque los traslados
son una dimensión operativa propia (transporte, flota, choferes) que hoy no tiene lugar natural
ni en Ventas ni en Inventario.

```
┌────────────────────────────────────────┐
│  🚚 Logística / Traslados               │
│  Controlá los traslados de mercadería   │
│   › Remisiones (Traslados)              │   ← reporte principal (agrupable)
│   › Remisiones pendientes de facturar   │   ← lista operativa
│   › Productividad de choferes  [opc.]   │   ← serie temporal (fase 2)
└────────────────────────────────────────┘
```

**Alternativa** (si no se quiere grupo nuevo): colgarlos de **Ventas** (junto a Resumen de Ventas).
Recomiendo el grupo propio por claridad operativa.

---

## Reporte A — Remisiones (Traslados)  ★ principal

El reporte núcleo. Una sola pantalla con **selector "Agrupar por"** que cubre todos los pedidos.

### Filtros
- **Rango de fechas** (por defecto mes en curso) — sobre `dfeemide`.
- **Estado** (Pendiente / Aprobado / Rechazado / Anulado / Todos).
- **Estado SIFEN** (Aprobado / Rechazado / Pendiente / Todos).
- **Cliente**, **Transportista**, **Chofer**, **Vehículo** (autocompletar).
- **Motivo de emisión**, **Tipo de transporte**.
- **Estado de facturación** (Sin facturar / Parcial / Facturada / Todos).
- **Destino** (departamento / ciudad de entrega).

### Dimensión "Agrupar por" (el corazón del reporte)
`Chofer` · `Transportista` · `Vehículo` · `Cliente` · `Destino` · `Motivo` · `Estado` · `Sin agrupar (detalle plano)`

### Vista AGRUPADA (ej. "Agrupar por Chofer")
Tabla resumen — una fila por chofer:

| Chofer | # Remisiones | Km total | Km prom. | Unidades | Valor mercadería | Facturadas | Pendientes | % del total |
|--------|-------------:|--------:|--------:|--------:|----------------:|-----------:|-----------:|-----------:|

Cada fila es expandible al detalle de sus remisiones (o botón "ver detalle" que filtra el detalle plano por ese chofer).

### Vista DETALLE (plano o al expandir un grupo)
Una fila por remisión:

| Número | Fecha | Cliente | Transportista | Chofer | Vehículo (matrícula) | Motivo | Origen → Destino | Km | Unidades | Valor | Estado | SIFEN | Facturación |
|--------|-------|---------|---------------|--------|----------------------|--------|------------------|---:|--------:|------:|--------|-------|-------------|

`Facturación` = chip **Sin facturar / Parcial (X/Y) / Facturada**.

### KPIs (tarjetas arriba)
- **Total remisiones** (del período, según filtros).
- **Km totales** trasladados.
- **Unidades trasladadas**.
- **Valor de mercadería movida**.
- **% facturadas** (aprovecha `cantidad_facturada`) — cuánto de lo que salió ya se facturó.
- **Anuladas** (conteo).

### Export
- **CSV** (patrón Libro IVA: `;` + BOM UTF-8) y/o **Excel `.xlsx`** (patrón Rentabilidad), respetando filtros y agrupación.
- Nombre: `remisiones_YYYY-MM-DD.csv`.

### Lectura típica
- **Por chofer**: carga de trabajo y km por conductor (pedido del cliente) — control de productividad y de viáticos/combustible.
- **Por transportista tercero**: cuánto se le despachó en el período (base para liquidarle flete).
- **Por vehículo**: uso de flota, km por unidad (mantenimiento preventivo).
- **Por destino**: cobertura geográfica y planificación de rutas.
- **% facturadas**: alerta de mercadería que salió y **aún no se facturó** (fuga de facturación).

---

## Reporte B — Remisiones pendientes de facturar  ★ operativo

Complementa el flujo **Remisión → Factura** que ya existe. Es una **lista de acción** (no analítica):
qué salió del depósito **sin factura** y todavía tiene saldo por facturar. Evita que quede mercadería
despachada sin facturar a fin de mes.

### Contenido
- Remisiones **Aprobadas**, **sin documento asociado**, con `cantidad > cantidad_facturada`.
- **Agrupable por cliente** (para ver "a este cliente le debo facturar N remisiones").

### Filtros
- Rango de fechas, cliente, antigüedad (ej. "más de 30 días sin facturar").

### Columnas
| Cliente | Número remisión | Fecha | Días sin facturar | Unidades pendientes | Valor pendiente | Chofer | Vehículo |
|---------|-----------------|-------|------------------:|--------------------:|----------------:|--------|----------|

### KPIs
- **Valor total pendiente de facturar**, **# remisiones pendientes**, **clientes con pendientes**, **antigüedad promedio**.

### Acción directa
- Link/CTA "Facturar" que lleva al **POS** con el cliente precargado (reusa "Facturar Remisiones").

> Técnicamente reutiliza la lógica de `findFacturables`, pero **a nivel empresa** (todas), no por un solo cliente.

---

## Reporte C — Productividad de choferes (opcional, fase 2)

Serie temporal, análogo a `reporte-cobrador/productividad`: remisiones y km **por día** en el rango,
filtrable por chofer/vehículo. Útil para gráfico de barras (carga diaria) y comparativa entre choferes.
No es imprescindible en v1 — la vista agrupada del Reporte A ya da el ranking.

---

## Diseño técnico propuesto

### Backend — nuevo módulo `reportes-remision`
Espeja el patrón de `reporte-cobrador` (resumen agregado + detalle paginado):

```
src/reportes-remision/
├── reportes-remision.module.ts
├── reportes-remision.controller.ts
└── reportes-remision.service.ts
```

Endpoints (v1):
```
GET /reportes-remision/resumen
    ?fecha_desde&fecha_hasta&agrupar_por=chofer|transportista|vehiculo|cliente|destino|motivo|estado
    &estado&estado_sifen&cliente_id&transportista_id&chofer_id&vehiculo_id&motivo_id&facturacion
    → { kpis: {...}, grupos: [{ clave, label, remisiones, km, km_prom, unidades, valor, facturadas, pendientes, pct }] }

GET /reportes-remision/detalle   (mismos filtros) &page&pageSize
    → { data: [ fila por remisión ], total, page, pageSize }

GET /reportes-remision/pendientes-facturar
    ?fecha_desde&fecha_hasta&cliente_id&dias_min
    → { kpis, clientes: [{ cliente, remisiones: [...] }] }
```

- **Multi-tenant**: filtrar por `empresa_id` del usuario en todos.
- **Permiso**: reutilizar `VEN_NR_NOTA_REMISION_VER` (o crear `VEN_NR_REPORTE` si se quiere gatear aparte).
- **Cálculo**: `valor` y `unidades` se agregan desde `nota_remision_det`; el join a `personas` da los
  nombres de chofer/transportista/cliente; ciudades → distrito → departamento para destino.
- **Rendimiento**: para `resumen` conviene `groupBy` de Prisma o SQL crudo con `SUM`/`COUNT` (evitar
  traer todas las remisiones a memoria). El `detalle` va paginado.

### Frontend
```
src/pages/ReporteRemisiones.jsx            ← reporte A (con selector Agrupar por + KPIs + tabla + export)
src/pages/ReporteRemisionesPendientes.jsx  ← reporte B
src/tanstack/ReportesStack.jsx             ← hooks nuevos (useReporteRemisionesResumen, ...detalle, ...pendientes)
src/pages/Reportes.jsx                     ← grupo nuevo "Logística / Traslados" con los links
+ rutas en el router
```
- Reutilizar componentes de reportes existentes (tarjetas KPI, tabla, filtros de fecha, botón export)
  para mantener el estándar visual.
- Estados con colores semánticos (igual que `RemisionesTab`): Pendiente `#f59e0b`, Aprobado `#22c55e`,
  Rechazado `#ef4444`, Anulado `#94a3b8`.

---

## Fases de implementación sugeridas

| Fase | Alcance | Valor | Estado |
|------|---------|-------|--------|
| **1** | Reporte A (Remisiones/Traslados) con `Agrupar por` + KPIs + detalle + export | Cubre el pedido "por chofer" y sirve a todos | ✅ **HECHO** |
| **2** | Reporte B (Pendientes de facturar) con CTA al POS | Cierra fuga de facturación; complementa Remisión→Factura | ✅ **HECHO** |
| **3** (opc.) | Reporte C (Productividad temporal) + gráfico | Análisis fino de carga por chofer/día | ⏳ |

### Fase 1 — implementado (2026-07-24)
- **Backend** módulo `reportes-remision`: `GET /api/v1/reportes-remision/resumen` (agrupable: chofer,
  transportista, vehiculo, cliente, destino, motivo, estado) + `GET .../detalle` (paginado). Permiso
  `VEN_NR_NOTA_REMISION_VER`, multi-tenant, registrado en `app.module.ts`.
- **Sin valor monetario (decisión multi-moneda, 2026-07-24)**: la **remisión no guarda moneda** (ni cabecera
  ni detalle) y `producto.precio` es un precio en moneda base sin código. Sumar un "valor" en Gs. mezclaría
  monedas y sería incorrecto. Decisión del usuario: **quitar el valor monetario** de los reportes. Quedan
  solo métricas **operativas y libres de moneda**: # remisiones, km (total/promedio), unidades trasladadas,
  estado de facturación (facturadas/parciales/sin facturar). `% del total` = participación por **unidades**.
  Si en el futuro se quiere valor real, requiere agregar `moneda_id` (+ tipo de cambio) a la remisión y que
  el form lo persista.
- **Frontend**: `pages/ReporteRemisiones.jsx` (filtros + selector Agrupar por + KPIs + tabla resumen +
  detalle paginado + export XLSX), `api/reportes-remision.service.js`, ruta
  `/reportes/traslados/remisiones`, grupo **"Logística / Traslados"** en `Reportes.jsx`.
- **Pendiente menor**: si se quiere que "Valor mercadería" refleje el precio real de la remisión (no el
  del producto), hay que hacer que `NuevaRemisionTemplate` persista `precio_unitario` en el detalle.
- **Export**: el Excel del Reporte A genera **2 hojas** (Resumen agrupado + Detalle completo de todas las
  remisiones del período/filtros, no solo la página visible).

### Fase 2 — implementado (2026-07-24)
- **Backend**: `GET /api/v1/reportes-remision/pendientes-facturar?dias_min&cliente_id&fecha_desde&fecha_hasta`
  — remisiones `estado='Aprobado'` + `tipo_documento_asociado IS NULL` con saldo (`dcantproser > cantidad_facturada`),
  agrupadas por cliente, con antigüedad (días) y **unidades pendientes** (sin monto, ver decisión multi-moneda).
  KPIs: unidades pendientes, # remisiones, # clientes, antigüedad promedio.
- **Frontend**: `pages/ReporteRemisionesPendientes.jsx` (KPIs + tarjetas por cliente expandibles + filtro
  de antigüedad + export XLSX + **CTA "Facturar" → `/pos-admin`**), ruta `/reportes/traslados/pendientes`,
  link activado en el grupo "Logística / Traslados".
- **CTA**: hoy navega a `/pos-admin` con un toast recordando seleccionar el cliente y usar "Facturar
  Remisiones". Mejora futura: precargar el cliente vía query param en POSAdmin.

Recomiendo arrancar por **Fase 1** — es el 80% del valor con un solo reporte.

---

## Por qué genérico y no "solo por chofer"

- El mismo esfuerzo de backend (una query con `GROUP BY` parametrizable) sirve para 7 dimensiones.
- Evita proliferación de pantallas casi idénticas ("por chofer", "por transportista", "por vehículo"…).
- El cliente que pidió "por chofer" lo obtiene eligiendo esa dimensión; otra empresa que quiera
  "por transportista tercero" o "por destino" lo tiene sin desarrollo adicional.
- Consistente con reportes existentes que ya agrupan por entidad (`reporte-cobrador`, `reportes-proveedor`).

---

## Documentos relacionados
- `plan-nota-remision.md` — módulo de remisión (modelo de datos, fases, stock).
- `guia-nota-remision.md` — guía funcional (incluye el flujo Remisión → Factura que alimenta el Reporte B).
- `guia-facturacion.md` — reportes de Ventas/Fiscal (patrón de columnas, KPIs y export a seguir).
