# US-MGN-007-006-002: Análisis de Ventas por Producto/Cliente/Período

**RF Asociado:** [RF-MGN-007-006](../../02-modelado/requerimientos-funcionales/mgn-007/RF-MGN-007-006-reportes-de-ventas.md)
**Módulo:** MGN-007 - Ventas Básico
**Epic:** Reportes de Ventas
**Prioridad:** P2
**Story Points:** 3
**Sprint:** Sprint 17
**Estado:** Ready for Development
**Fecha:** 2025-11-24

---

## User Story

**Como** gerente de ventas,
**Quiero** generar reportes de ventas con agrupaciones dinámicas (producto, cliente, período),
**Para** analizar tendencias y patrones de ventas en detalle.

---

## Descripción Detallada

Reporte de análisis de ventas permite:
- **Agrupaciones:**
  - Por producto (product_id)
  - Por cliente (customer_id)
  - Por período (día, semana, mes, trimestre, año)
  - Por vendedor (user_id)
  - Combinaciones (ej: producto × mes)

- **Métricas:**
  - Total vendido (revenue)
  - Cantidad vendida (qty)
  - # órdenes
  - Ticket promedio
  - Margen (si hay costo configurado)

- **Comparaciones:**
  - Período actual vs período anterior
  - Crecimiento % (growth_rate)

- **Exportar:** Excel, PDF, CSV

---

## Criterios de Aceptación

### Escenario 1: Reporte por producto (Camino Feliz)
**Dado que** hay ventas de 3 productos en enero,
**Cuando** genero reporte agrupado por producto, período=enero,
**Entonces** veo tabla: Producto A ($10K), Producto B ($8K), Producto C ($5K).

### Escenario 2: Reporte por cliente y mes
**Dado que** selecciono agrupación "Cliente × Mes",
**Cuando** genero reporte,
**Entonces** veo matriz con clientes en filas, meses en columnas, revenue en celdas.

### Escenario 3: Comparar períodos
**Dado que** selecciono "Enero 2024 vs Enero 2023",
**Cuando** genero reporte,
**Entonces** veo columnas: Ene-2024, Ene-2023, Diferencia, Growth%.

### Escenario 4: Filtrar por múltiples criterios
**Dado que** aplico filtros: producto=Laptop, cliente=ABC Corp, período=Q1-2024,
**Cuando** genero reporte,
**Entonces** solo veo ventas que cumplen todos los filtros.

### Escenario 5: Exportar a Excel
**Dado que** tengo reporte generado,
**Cuando** hago clic en "Export to Excel",
**Entonces** descarga archivo .xlsx con los datos del reporte.

### Escenario 6: Ordenar por columna
**Dado que** veo reporte con 10 productos,
**Cuando** hago clic en header "Revenue",
**Entonces** tabla se ordena descendente por revenue.

---

## Reglas de Negocio

- **RN-1:** Reportes filtran por empresa (RLS).
- **RN-2:** sales_user solo ve sus ventas, sales_manager ve todas.
- **RN-3:** Agrupaciones son excluyentes: producto OR cliente OR período (no múltiples simultáneas).
- **RN-4:** Comparaciones solo para mismo tipo de período (mes vs mes, año vs año).
- **RN-5:** Exportación incluye filtros aplicados en metadata.
- **RN-6:** Máximo 10,000 registros por exportación.

---

## Tareas Técnicas

### Backend
- [ ] Endpoint: `GET /api/v1/sales/reports/sales-analysis?group_by&date_from&date_to&product_id&customer_id&user_id`
- [ ] Endpoint: `GET /api/v1/sales/reports/sales-analysis/export?format=excel|pdf|csv`
- [ ] Service: `SalesReportService.generateAnalysis(filters, groupBy)`
- [ ] Query: Agrupación dinámica con GROUP BY
- [ ] Query: Cálculo de métricas (SUM, COUNT, AVG)
- [ ] Query: Comparación de períodos (self-join o subquery)
- [ ] Service: `ExportService.toExcel(data)` usando exceljs
- [ ] Service: `ExportService.toPDF(data)` usando puppeteer
- [ ] Aplicar RLS y permisos
- [ ] Unit tests (>80%)
- [ ] Integration tests
- [ ] Swagger docs

### Frontend
- [ ] Página: `SalesAnalysisReportPage.tsx` (/sales/reports/analysis)
- [ ] Componente: `ReportFiltersPanel.tsx` (filtros múltiples)
- [ ] Componente: `GroupBySelector.tsx` (radio: producto/cliente/período)
- [ ] Componente: `SalesAnalysisTable.tsx` (tabla con sort)
- [ ] Componente: `ComparisonChart.tsx` (gráfico comparativo)
- [ ] Botón: "Export to Excel/PDF/CSV"
- [ ] API client: `reportsApi.getSalesAnalysis(filters)`
- [ ] API client: `reportsApi.exportSalesAnalysis(format)`
- [ ] State management: `useSalesReportStore`
- [ ] Component tests
- [ ] E2E test: "should generate sales analysis report"

### Database
- [ ] View (opcional): `sales_analysis_report` para optimizar queries
- [ ] Índices: Optimizar para GROUP BY (product_id, customer_id, date)

---

## Mockups / Wireframes

**Página de Análisis de Ventas:**
```
┌──────────────────────────────────────────────────────┐
│ Análisis de Ventas                                   │
├──────────────────────────────────────────────────────┤
│ Filtros:                                             │
│ [Rango: Q1 2024] [Producto: Todos ▼] [Cliente: Todos]│
│                                                      │
│ Agrupar por: ⦿ Producto ○ Cliente ○ Mes ○ Vendedor  │
│                                                      │
│ [Generar Reporte] [Export ▼]                         │
├──────────────────────────────────────────────────────┤
│ Resultados:                                          │
│ ┌────────────────┬─────────┬──────┬────────┬───────┐│
│ │ Producto       │ Revenue │ Qty  │ Órdenes│ Avg   ││
│ ├────────────────┼─────────┼──────┼────────┼───────┤│
│ │ Laptop HP      │ $50,000 │ 100  │   25   │$2,000 ││
│ │ Mouse Logitech │ $30,000 │ 500  │   50   │ $600  ││
│ │ ...            │         │      │        │       ││
│ └────────────────┴─────────┴──────┴────────┴───────┘│
│                                                      │
│ Total: $80,000 | 600 unidades | 75 órdenes          │
└──────────────────────────────────────────────────────┘
```

---

## Casos de Prueba

### Funcionales
1. **TC-001:** Reporte por producto generado correctamente
2. **TC-002:** Reporte por cliente generado correctamente
3. **TC-003:** Reporte por mes generado correctamente
4. **TC-004:** Filtros aplicados correctamente
5. **TC-005:** Ordenar columnas funciona
6. **TC-006:** Exportar a Excel funciona
7. **TC-007:** Exportar a PDF funciona
8. **TC-008:** Comparación de períodos correcta
9. **TC-009:** RLS filtra por empresa
10. **TC-010:** Permisos aplicados correctamente

### No Funcionales
1. **Performance:** < 3s para generar reporte con 1,000 registros
2. **Seguridad:** JWT + permiso sales_user

---

## Dependencias

- **US bloqueantes:**
  - US-MGN-007-002-001 (Crear SO)
- **Módulos requeridos:** MGN-003 (Partners), MGN-005 (Productos)

---

## Notas de Implementación

- Query optimizada con índices compuestos
- Exportación: Streaming para archivos grandes (evitar OOM)
- Frontend: Pagination para reportes con muchos registros
- Considerar cache de 10 minutos para reportes pesados

---

## Estimación Detallada

| Tarea | Horas |
|-------|-------|
| Backend | 2 |
| Frontend | 2 |
| Export | 1 |
| Testing | 1 |
| Code Review | 0.5 |
| **TOTAL** | **6.5 horas = 3 SP** |

---

## Definition of Done

- [ ] Código implementado según ET
- [ ] Tests pasando (>80%)
- [ ] Code review aprobado
- [ ] Reportes generados correctamente
- [ ] Agrupaciones funcionan
- [ ] Filtros aplicados
- [ ] Exportación funciona (Excel, PDF, CSV)
- [ ] RLS y permisos aplicados
- [ ] Swagger docs actualizado
- [ ] QA validado
- [ ] PO aprobado

---

## Referencias

- [RF-MGN-007-006](../../02-modelado/requerimientos-funcionales/mgn-007/RF-MGN-007-006-reportes-de-ventas.md)
- [ET Backend](../../02-modelado/especificaciones-tecnicas/backend/mgn-007/ET-BACKEND-MGN-007-006-reportes.md)
- [ET Frontend](../../02-modelado/especificaciones-tecnicas/frontend/mgn-007/ET-FRONTEND-MGN-007-006-reportes.md)
- [Traceability](../../02-modelado/trazabilidad/TRACEABILITY-MGN-007.yaml)
