414 lines
9.6 KiB
Markdown
414 lines
9.6 KiB
Markdown
# ANALISIS MODULO RT-008: REPORTES Y DASHBOARD
|
|
|
|
**Fecha:** 2025-12-18
|
|
**Fase:** 2 - Analisis por Modulo
|
|
**Modulo:** RT-008 Reportes
|
|
**Herencia:** 70%
|
|
**Story Points:** 30
|
|
**Prioridad:** P1
|
|
|
|
---
|
|
|
|
## 1. DESCRIPCION GENERAL
|
|
|
|
### 1.1 Proposito
|
|
Sistema de analytics con dashboards en tiempo real, reportes de ventas, inventario, clientes y metricas operativas.
|
|
|
|
### 1.2 Funcionalidades Principales
|
|
|
|
| Funcionalidad | Descripcion | Criticidad |
|
|
|---------------|-------------|------------|
|
|
| Dashboard principal | KPIs tiempo real | Alta |
|
|
| Reportes ventas | Por periodo/sucursal | Alta |
|
|
| Analisis productos | Top vendidos, ABC | Media |
|
|
| Reportes inventario | Stock, valoracion | Media |
|
|
| Exportacion | Excel, PDF | Media |
|
|
|
|
---
|
|
|
|
## 2. HERENCIA DEL CORE
|
|
|
|
### 2.1 Componentes Heredados (70%)
|
|
|
|
| Componente Core | % Uso | Accion |
|
|
|-----------------|-------|--------|
|
|
| MGN-009 Reports | 70% | EXTENDER |
|
|
| Analytics module | 100% | HEREDAR |
|
|
|
|
### 2.2 Servicios a Heredar
|
|
|
|
```typescript
|
|
import { ReportsService } from '@erp-core/reports';
|
|
import { AnalyticsService } from '@erp-core/analytics';
|
|
import { ExportService } from '@erp-core/reports';
|
|
```
|
|
|
|
---
|
|
|
|
## 3. COMPONENTES NUEVOS
|
|
|
|
### 3.1 Dashboard Principal
|
|
|
|
```typescript
|
|
interface RetailDashboard {
|
|
// Metricas del dia
|
|
today: {
|
|
totalSales: number;
|
|
totalTransactions: number;
|
|
avgTicket: number;
|
|
newCustomers: number;
|
|
returningCustomers: number;
|
|
pointsRedeemed: number;
|
|
refunds: number;
|
|
};
|
|
|
|
// Comparativo
|
|
comparison: {
|
|
vsYesterday: PercentChange;
|
|
vsLastWeek: PercentChange;
|
|
vsLastMonth: PercentChange;
|
|
};
|
|
|
|
// Graficos
|
|
charts: {
|
|
salesByHour: TimeSeriesData[];
|
|
salesByPaymentMethod: PieChartData[];
|
|
topProducts: BarChartData[];
|
|
topBranches: BarChartData[];
|
|
};
|
|
|
|
// Alertas
|
|
alerts: {
|
|
lowStock: number;
|
|
pendingTransfers: number;
|
|
unapprovedClosings: number;
|
|
};
|
|
}
|
|
```
|
|
|
|
### 3.2 Tipos de Reportes
|
|
|
|
```typescript
|
|
// 1. Reporte de Ventas
|
|
interface SalesReport {
|
|
period: DateRange;
|
|
groupBy: 'day' | 'week' | 'month' | 'branch' | 'cashier';
|
|
|
|
summary: {
|
|
totalSales: number;
|
|
totalTransactions: number;
|
|
avgTicket: number;
|
|
totalDiscounts: number;
|
|
totalRefunds: number;
|
|
netSales: number;
|
|
};
|
|
|
|
byPaymentMethod: {
|
|
cash: number;
|
|
card: number;
|
|
transfer: number;
|
|
credit: number;
|
|
mixed: number;
|
|
};
|
|
|
|
details: SalesReportLine[];
|
|
}
|
|
|
|
// 2. Reporte de Productos
|
|
interface ProductReport {
|
|
period: DateRange;
|
|
branchId?: string;
|
|
|
|
topSelling: ProductRanking[];
|
|
slowMoving: ProductRanking[];
|
|
noMovement: Product[];
|
|
abcAnalysis: {
|
|
A: Product[]; // 80% ventas
|
|
B: Product[]; // 15% ventas
|
|
C: Product[]; // 5% ventas
|
|
};
|
|
}
|
|
|
|
// 3. Reporte de Inventario
|
|
interface InventoryReport {
|
|
branchId?: string;
|
|
|
|
summary: {
|
|
totalProducts: number;
|
|
totalValue: number;
|
|
lowStockItems: number;
|
|
outOfStockItems: number;
|
|
};
|
|
|
|
byCategory: CategoryStock[];
|
|
lowStockAlerts: StockAlert[];
|
|
valuationMethod: 'FIFO' | 'LIFO' | 'AVCO';
|
|
}
|
|
|
|
// 4. Reporte de Clientes
|
|
interface CustomerReport {
|
|
period: DateRange;
|
|
|
|
summary: {
|
|
totalCustomers: number;
|
|
newCustomers: number;
|
|
activeCustomers: number;
|
|
avgPurchaseFrequency: number;
|
|
};
|
|
|
|
topCustomers: CustomerRanking[];
|
|
byMembershipLevel: MembershipBreakdown;
|
|
loyaltyMetrics: {
|
|
pointsIssued: number;
|
|
pointsRedeemed: number;
|
|
redemptionRate: number;
|
|
};
|
|
}
|
|
|
|
// 5. Reporte de Caja
|
|
interface CashReport {
|
|
period: DateRange;
|
|
branchId?: string;
|
|
|
|
closings: CashClosingSummary[];
|
|
differences: {
|
|
total: number;
|
|
count: number;
|
|
byReason: DifferenceBreakdown[];
|
|
};
|
|
movements: {
|
|
totalIn: number;
|
|
totalOut: number;
|
|
byReason: MovementBreakdown[];
|
|
};
|
|
}
|
|
```
|
|
|
|
### 3.3 Servicios Backend
|
|
|
|
| Servicio | Metodos Principales |
|
|
|----------|-------------------|
|
|
| DashboardService | getDashboard(), refresh() |
|
|
| SalesReportService | generate(), getByPeriod(), export() |
|
|
| ProductReportService | getTopSelling(), getABCAnalysis() |
|
|
| InventoryReportService | getStockReport(), getValuation() |
|
|
| CustomerReportService | getCustomerMetrics(), getLoyaltyStats() |
|
|
| CashReportService | getClosingsReport(), getDifferences() |
|
|
| ExportService | toExcel(), toPDF() |
|
|
|
|
### 3.4 Controladores
|
|
|
|
```typescript
|
|
@Controller('reports')
|
|
export class ReportsController {
|
|
// Dashboard
|
|
@Get('dashboard')
|
|
getDashboard(@Query('branchId') branchId?: string): Promise<RetailDashboard>;
|
|
|
|
// Ventas
|
|
@Get('sales')
|
|
getSalesReport(@Query() filters: SalesFilters): Promise<SalesReport>;
|
|
|
|
@Get('sales/by-hour')
|
|
getSalesByHour(@Query('date') date: string): Promise<HourlySales[]>;
|
|
|
|
@Get('sales/by-cashier')
|
|
getSalesByCashier(@Query() filters: DateFilters): Promise<CashierSales[]>;
|
|
|
|
// Productos
|
|
@Get('products/top-selling')
|
|
getTopSelling(@Query() filters: ProductFilters): Promise<ProductRanking[]>;
|
|
|
|
@Get('products/abc-analysis')
|
|
getABCAnalysis(@Query('branchId') branchId?: string): Promise<ABCAnalysis>;
|
|
|
|
@Get('products/slow-moving')
|
|
getSlowMoving(@Query() filters: ProductFilters): Promise<Product[]>;
|
|
|
|
// Inventario
|
|
@Get('inventory')
|
|
getInventoryReport(@Query('branchId') branchId?: string): Promise<InventoryReport>;
|
|
|
|
@Get('inventory/valuation')
|
|
getValuation(@Query('branchId') branchId?: string): Promise<ValuationReport>;
|
|
|
|
// Clientes
|
|
@Get('customers')
|
|
getCustomerReport(@Query() filters: CustomerFilters): Promise<CustomerReport>;
|
|
|
|
@Get('customers/loyalty')
|
|
getLoyaltyMetrics(@Query() filters: DateFilters): Promise<LoyaltyMetrics>;
|
|
|
|
// Caja
|
|
@Get('cash/closings')
|
|
getClosingsReport(@Query() filters: CashFilters): Promise<CashClosingSummary[]>;
|
|
|
|
@Get('cash/differences')
|
|
getDifferencesReport(@Query() filters: CashFilters): Promise<DifferenceReport>;
|
|
|
|
// Exportacion
|
|
@Get(':type/export/excel')
|
|
exportToExcel(@Param('type') type: string, @Query() filters: any): Promise<Buffer>;
|
|
|
|
@Get(':type/export/pdf')
|
|
exportToPDF(@Param('type') type: string, @Query() filters: any): Promise<Buffer>;
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 4. VISTAS MATERIALIZADAS
|
|
|
|
### 4.1 Para Performance
|
|
|
|
```sql
|
|
-- Vista materializada de ventas diarias
|
|
CREATE MATERIALIZED VIEW retail.mv_daily_sales AS
|
|
SELECT
|
|
DATE(po.order_date) as sale_date,
|
|
po.tenant_id,
|
|
ps.branch_id,
|
|
ps.user_id as cashier_id,
|
|
COUNT(*) as transaction_count,
|
|
SUM(po.total) as total_sales,
|
|
SUM(po.discount_amount) as total_discounts,
|
|
AVG(po.total) as avg_ticket,
|
|
SUM(CASE WHEN po.status = 'refunded' THEN po.total ELSE 0 END) as refunds
|
|
FROM retail.pos_orders po
|
|
JOIN retail.pos_sessions ps ON po.session_id = ps.id
|
|
WHERE po.status IN ('done', 'refunded')
|
|
GROUP BY DATE(po.order_date), po.tenant_id, ps.branch_id, ps.user_id;
|
|
|
|
CREATE UNIQUE INDEX idx_mv_daily_sales ON retail.mv_daily_sales(sale_date, tenant_id, branch_id, cashier_id);
|
|
|
|
-- Vista materializada de productos mas vendidos
|
|
CREATE MATERIALIZED VIEW retail.mv_product_sales AS
|
|
SELECT
|
|
pol.product_id,
|
|
pol.tenant_id,
|
|
ps.branch_id,
|
|
DATE_TRUNC('month', po.order_date) as sale_month,
|
|
SUM(pol.quantity) as qty_sold,
|
|
SUM(pol.total) as revenue,
|
|
COUNT(DISTINCT po.id) as order_count
|
|
FROM retail.pos_order_lines pol
|
|
JOIN retail.pos_orders po ON pol.order_id = po.id
|
|
JOIN retail.pos_sessions ps ON po.session_id = ps.id
|
|
WHERE po.status = 'done'
|
|
GROUP BY pol.product_id, pol.tenant_id, ps.branch_id, DATE_TRUNC('month', po.order_date);
|
|
|
|
-- Refresh cada hora
|
|
-- REFRESH MATERIALIZED VIEW CONCURRENTLY retail.mv_daily_sales;
|
|
```
|
|
|
|
---
|
|
|
|
## 5. GRAFICOS Y VISUALIZACIONES
|
|
|
|
### 5.1 Componentes Frontend
|
|
|
|
| Componente | Tipo | Datos |
|
|
|------------|------|-------|
|
|
| SalesChart | Line | Ventas por hora/dia |
|
|
| PaymentPieChart | Pie | Por metodo de pago |
|
|
| TopProductsChart | Bar | Top 10 productos |
|
|
| BranchComparison | Bar | Ventas por sucursal |
|
|
| TrendIndicator | KPI | Variacion % |
|
|
| AlertsBadge | Badge | Alertas pendientes |
|
|
|
|
### 5.2 Configuracion
|
|
|
|
```typescript
|
|
interface ChartConfig {
|
|
refreshInterval: number; // segundos
|
|
defaultPeriod: 'today' | 'week' | 'month';
|
|
colors: {
|
|
primary: string;
|
|
success: string;
|
|
warning: string;
|
|
danger: string;
|
|
};
|
|
}
|
|
|
|
const defaultConfig: ChartConfig = {
|
|
refreshInterval: 300, // 5 minutos
|
|
defaultPeriod: 'today',
|
|
colors: {
|
|
primary: '#3B82F6',
|
|
success: '#10B981',
|
|
warning: '#F59E0B',
|
|
danger: '#EF4444'
|
|
}
|
|
};
|
|
```
|
|
|
|
---
|
|
|
|
## 6. DEPENDENCIAS
|
|
|
|
### 6.1 Dependencias de Core
|
|
|
|
| Modulo | Estado | Requerido Para |
|
|
|--------|--------|---------------|
|
|
| MGN-009 Reports | 0% | Base de reportes |
|
|
|
|
### 6.2 Dependencias de Retail
|
|
|
|
| Modulo | Tipo |
|
|
|--------|------|
|
|
| RT-001 Fundamentos | Prerequisito |
|
|
| RT-002 POS | Datos de ventas |
|
|
| RT-003 Inventario | Datos de stock |
|
|
| RT-005 Clientes | Datos de lealtad |
|
|
| RT-007 Caja | Datos de cortes |
|
|
|
|
---
|
|
|
|
## 7. CRITERIOS DE ACEPTACION
|
|
|
|
### 7.1 Dashboard
|
|
|
|
- [ ] Cargar dashboard < 3s
|
|
- [ ] Auto-refresh cada 5 min
|
|
- [ ] Mostrar KPIs del dia
|
|
- [ ] Grafico de ventas por hora
|
|
- [ ] Top 5 productos
|
|
- [ ] Alertas visibles
|
|
|
|
### 7.2 Reportes
|
|
|
|
- [ ] Filtrar por sucursal
|
|
- [ ] Filtrar por periodo
|
|
- [ ] Comparar periodos
|
|
- [ ] Exportar a Excel
|
|
- [ ] Exportar a PDF
|
|
|
|
### 7.3 Performance
|
|
|
|
- [ ] Dashboard < 3s
|
|
- [ ] Reportes < 5s
|
|
- [ ] Vistas materializadas
|
|
|
|
---
|
|
|
|
## 8. ESTIMACION DETALLADA
|
|
|
|
| Componente | SP Backend | SP Frontend | Total |
|
|
|------------|-----------|-------------|-------|
|
|
| Dashboard Service | 3 | - | 3 |
|
|
| Sales Report Service | 3 | - | 3 |
|
|
| Product Report Service | 2 | - | 2 |
|
|
| Inventory Report Service | 2 | - | 2 |
|
|
| Customer Report Service | 2 | - | 2 |
|
|
| Cash Report Service | 2 | - | 2 |
|
|
| Export Service | 3 | - | 3 |
|
|
| Vistas Materializadas | 2 | - | 2 |
|
|
| Dashboard UI | - | 8 | 8 |
|
|
| Report Pages | - | 3 | 3 |
|
|
| **TOTAL** | **19** | **11** | **30** |
|
|
|
|
---
|
|
|
|
**Estado:** ANALISIS COMPLETO
|
|
**Bloqueado por:** RT-002, RT-003, RT-005, RT-007
|