erp-core/docs/05-user-stories/mgn-004/US-MGN-004-008-001-reportes-financieros-balance-pl.md

10 KiB

US-MGN-004-008-001: Reportes Financieros (Balance General y P&L)

RF Asociado: RF-MGN-004-008 Módulo: MGN-004 - Financiero Básico Epic: Reportes Financieros Prioridad: P0 (MVP) Story Points: 8 Sprint: Sprint 13 Estado: Ready for Development Fecha: 2025-11-24


User Story

Como contador o gerente, Quiero generar reportes de Balance General y Estado de Resultados (P&L), Para analizar la situación financiera de mi empresa en un período determinado.


Descripción Detallada

Reportes financieros básicos:

Balance General (Balance Sheet):

  • Activos = Pasivos + Patrimonio
  • Muestra saldos de cuentas al cierre del período
  • Agrupa por tipo: Activos Corrientes, No Corrientes, Pasivos, Patrimonio
  • Filtros: fecha_corte, comparar_con_periodo_anterior

Estado de Resultados (Profit & Loss / P&L):

  • Ingresos - Gastos = Utilidad Neta
  • Muestra movimientos del período (no saldos acumulados)
  • Agrupa por tipo: Ingresos, Costo de Ventas, Gastos Operacionales, Otros Gastos
  • Filtros: date_from, date_to

Criterios de Aceptación

Escenario 1: Generar Balance General

Dado que soy contador, Cuando solicito GET /financial/reports/balance-sheet?as_of_date=2024-12-31, Entonces recibo reporte con:

  • Activos Corrientes (suma de cuentas tipo asset)
  • Pasivos Corrientes (suma de cuentas tipo liability)
  • Patrimonio (suma de cuentas tipo equity)
  • Validación: Total Activos = Total Pasivos + Patrimonio

Escenario 2: Generar Estado de Resultados (P&L)

Dado que solicito GET /financial/reports/profit-loss?date_from=2024-01-01&date_to=2024-12-31, Entonces recibo reporte con:

  • Total Ingresos (suma de créditos en cuentas income)
  • Total Gastos (suma de débitos en cuentas expense)
  • Utilidad Neta = Ingresos - Gastos

Escenario 3: Filtrar por jerarquía de cuentas

Dado que cuentas tienen jerarquía (parent_id), Cuando genero reporte, Entonces totales se agrupan por cuenta padre (ej: 1.1 Activos Corrientes = suma de 1.1.01 + 1.1.02 + ...).

Escenario 4: Exportar a PDF

Dado que visualizo Balance General, Cuando hago clic en "Exportar PDF", Entonces descargo PDF con logo empresa, período, y datos tabulados.

Escenario 5: Comparar con período anterior

Dado que solicito balance con compare=true, Cuando genero reporte, Entonces columnas: Período Actual | Período Anterior | Variación %.


Reglas de Negocio

  • RN-1: Balance General usa saldos acumulados (balance_debit, balance_credit).
  • RN-2: P&L usa movimientos del período (sum de journal_entry_lines filtradas por fecha).
  • RN-3: Balance: Assets = Liabilities + Equity.
  • RN-4: P&L: Net Income = Income - Expenses.
  • RN-5: Solo considerar journal entries con state='posted'.
  • RN-6: Jerarquía de cuentas: calcular totales recursivamente.
  • RN-7: Montos en moneda base de la empresa.
  • RN-8: RLS filtra por company_id.

Tareas Técnicas

Backend

  • GET /api/v1/financial/reports/balance-sheet
  • GET /api/v1/financial/reports/profit-loss
  • GET /api/v1/financial/reports/trial-balance (balanza)
  • GET /api/v1/financial/reports/general-ledger (libro mayor)
  • DTO: ReportPeriodDto (date_from, date_to, as_of_date, compare)
  • Service: FinancialReportService.generateBalanceSheet()
  • Service: FinancialReportService.generateProfitLoss()
  • Lógica: Calcular saldos por tipo de cuenta
  • Lógica: Agrupar por jerarquía de cuentas (CTE recursivo)
  • Lógica: Comparación con período anterior
  • Exportación: PDF usando pdfkit
  • Exportación: Excel usando xlsx
  • Unit tests (10 test cases)
  • Integration tests (8 test cases)

Frontend

  • Página: BalanceSheetPage.tsx (/financial/reports/balance-sheet)
  • Página: ProfitLossPage.tsx (/financial/reports/profit-loss)
  • Componente: BalanceSheetReport.tsx (tabla balance)
  • Componente: ProfitLossReport.tsx (tabla P&L)
  • Componente: ReportFilters.tsx (date pickers, compare checkbox)
  • Botones: [Exportar PDF] [Exportar Excel]
  • Tabla jerárquica: indentación por niveles
  • API client: financialReportApi.getBalanceSheet(), getProfitLoss()
  • Component tests (5 test cases)
  • E2E test: "should generate balance sheet and P&L"

Database

  • Query: Calcular saldos por tipo cuenta
  • Query: CTE recursivo para jerarquía
  • Índices: Optimizar queries de reportes (idx_journal_entry_lines_account_id, idx_journal_entry_lines_date)

Mockups / Wireframes

Balance General:

┌──────────────────────────────────────────┐
│ Balance General al 31/12/2024            │
│ [Exportar PDF] [Exportar Excel]          │
├──────────────────────────────────────────┤
│ ACTIVOS                                  │
│   Activos Corrientes:        50,000.00   │
│     1.1.01 Caja                5,000.00  │
│     1.1.02 Bancos             35,000.00  │
│     1.1.03 Cuentas por Cobrar 10,000.00  │
│   Activos No Corrientes:     100,000.00  │
│   ────────────────────────────────────   │
│   TOTAL ACTIVOS:             150,000.00  │
│                                          │
│ PASIVOS                                  │
│   Pasivos Corrientes:         30,000.00  │
│     2.1.01 Cuentas por Pagar  30,000.00  │
│   ────────────────────────────────────   │
│   TOTAL PASIVOS:              30,000.00  │
│                                          │
│ PATRIMONIO                               │
│   3.1.01 Capital             100,000.00  │
│   3.2.01 Utilidades Acum.     20,000.00  │
│   ────────────────────────────────────   │
│   TOTAL PATRIMONIO:          120,000.00  │
│                                          │
│ TOTAL PASIVOS + PATRIMONIO:  150,000.00 ✓│
└──────────────────────────────────────────┘

Estado de Resultados:

┌──────────────────────────────────────────┐
│ Estado de Resultados 01/01 - 31/12/2024  │
├──────────────────────────────────────────┤
│ INGRESOS                                 │
│   4.1 Ventas de Productos:    80,000.00  │
│   4.2 Servicios:              20,000.00  │
│   ────────────────────────────────────   │
│   TOTAL INGRESOS:            100,000.00  │
│                                          │
│ GASTOS                                   │
│   5.1 Costo de Ventas:        40,000.00  │
│   5.2 Gastos Operacionales:   30,000.00  │
│   5.3 Gastos Financieros:      5,000.00  │
│   ────────────────────────────────────   │
│   TOTAL GASTOS:               75,000.00  │
│                                          │
│ ══════════════════════════════════════   │
│ UTILIDAD NETA:                25,000.00  │
└──────────────────────────────────────────┘

Casos de Prueba

  1. TC-001: Generar Balance General correctamente
  2. TC-002: Validar Assets = Liabilities + Equity
  3. TC-003: Generar P&L correctamente
  4. TC-004: Calcular Net Income = Income - Expenses
  5. TC-005: Agrupar por jerarquía de cuentas
  6. TC-006: Filtrar por rango de fechas
  7. TC-007: Comparar con período anterior
  8. TC-008: Exportar a PDF
  9. TC-009: Exportar a Excel
  10. TC-010: RLS filtra por empresa

Dependencias

  • US bloqueantes:
    • US-MGN-004-001-001 (CRUD Cuentas)
    • US-MGN-004-003-002 (Postear Asientos)
  • Módulos: MGN-004
  • Librerías: pdfkit (PDF), xlsx (Excel)

Notas de Implementación

  • Cálculo de saldos: Usar campos precalculados accounts.balance_debit y accounts.balance_credit para Balance General
  • P&L: Query directo a journal_entry_lines con filtro por fecha y tipo de cuenta
  • Jerarquía: CTE recursivo para sumar totales de cuentas hijas
  • Performance: Cachear resultados de reportes en Redis (TTL 5 minutos)
  • PDF: Logo de empresa, formato profesional, saltos de página
  • Excel: Múltiples hojas (Balance Sheet, P&L, Trial Balance)

Estimación Detallada

Tarea Estimación
Backend (queries + services) 4 horas
Frontend (reportes + gráficos) 3 horas
Exportación PDF/Excel 2 horas
Testing 2 horas
Code Review 1 hora
TOTAL 12 horas = 8 SP

Definition of Done

  • Balance General genera correctamente
  • P&L genera correctamente
  • Jerarquía de cuentas funciona
  • Exportación PDF funciona
  • Exportación Excel funciona
  • Comparación períodos funciona
  • Tests pasando (>80%)
  • Code review aprobado
  • Merge a develop
  • QA validado (verificar cálculos contables)
  • PO aprobado

Referencias