erp-core/docs/05-user-stories/mgn-004/US-MGN-004-004-001-crud-impuestos.md

6.2 KiB

US-MGN-004-004-001: CRUD de Impuestos

RF Asociado: RF-MGN-004-004 Módulo: MGN-004 - Financiero Básico Epic: Impuestos Prioridad: P0 (MVP) Story Points: 5 Sprint: Sprint 9 Estado: Ready for Development Fecha: 2025-11-24


User Story

Como contador, Quiero crear y gestionar impuestos (IVA, retenciones, etc.), Para calcular automáticamente los impuestos en facturas y generar reportes fiscales.


Descripción Detallada

Los impuestos son configuraciones que definen cómo calcular impuestos sobre transacciones. Cada impuesto tiene:

  • Código y nombre (ej: "IVA 21%")
  • Tipo: sale (ventas), purchase (compras), both (ambos)
  • Método de cálculo: percentage (porcentaje) o fixed (monto fijo)
  • Rate (tasa): 0-100 para percentage, monto para fixed
  • Cuentas contables asociadas (tax_collected_account, tax_paid_account)
  • Grupo de impuestos (opcional, para impuestos compuestos)

Criterios de Aceptación

Escenario 1: Crear impuesto porcentual exitosamente

Dado que soy contador con permisos accounting_manager, Cuando creo un impuesto con code="IVA21", name="IVA 21%", type="both", rate=21.0, method="percentage", Entonces el sistema crea el impuesto y retorna el registro con id y company_id.

Escenario 2: Validar rate entre 0 y 100

Dado que intento crear un impuesto con rate=150, Cuando envío el request, Entonces el sistema retorna error 400 "Rate debe estar entre 0 y 100".

Escenario 3: Listar impuestos con filtro por tipo

Dado que tengo impuestos de tipo sale y purchase, Cuando listo impuestos con filtro type="sale", Entonces el sistema retorna solo impuestos aplicables a ventas (type='sale' o type='both').

Escenario 4: Calcular monto de impuesto

Dado que tengo un impuesto con rate=21%, Cuando calculo el impuesto sobre base=1000, Entonces el sistema retorna tax_amount=210.

Escenario 5: Validar cuenta contable existe

Dado que intento crear un impuesto con tax_collected_account_id=999 (no existe), Cuando envío el request, Entonces el sistema retorna error 400 "Cuenta contable no encontrada".


Reglas de Negocio

  • RN-1: Code debe ser único por empresa.
  • RN-2: Tipos válidos: sale, purchase, both.
  • RN-3: Métodos válidos: percentage, fixed.
  • RN-4: Rate debe estar entre 0 y 100 para percentage.
  • RN-5: tax_collected_account_id es obligatorio para type='sale' o 'both'.
  • RN-6: tax_paid_account_id es obligatorio para type='purchase' o 'both'.
  • RN-7: Impuestos pueden estar activos o inactivos.
  • RN-8: RLS filtra por company_id.

Tareas Técnicas

Backend

  • Endpoint: POST /api/v1/financial/taxes
  • Endpoint: GET /api/v1/financial/taxes (filtros: type, active)
  • Endpoint: GET /api/v1/financial/taxes/:id
  • Endpoint: PUT /api/v1/financial/taxes/:id
  • Endpoint: DELETE /api/v1/financial/taxes/:id (soft delete)
  • Endpoint: POST /api/v1/financial/taxes/calculate (calcular impuesto)
  • Service: TaxService.create/findAll/findOne/update/remove/calculateTax
  • DTO: CreateTaxDto (validaciones @Min(0) @Max(100) para rate)
  • DTO: CalculateTaxDto (tax_id, base_amount)
  • Unit tests (10 test cases)
  • Integration tests (8 test cases)

Frontend

  • Página: TaxesPage.tsx (/financial/taxes)
  • Componente: TaxesTable.tsx
  • Componente: CreateTaxForm.tsx
  • API client: taxApi.ts
  • Store: useTaxStore.ts
  • Component tests (5 test cases)
  • E2E test: "should create tax successfully"

Database

  • Tabla: financial.taxes (ya existe)
  • Índices: idx_taxes_company_id, idx_taxes_type, idx_taxes_code
  • Constraint: uq_taxes_code_company
  • RLS policy: company_isolation_taxes

Mockups / Wireframes

Formulario Crear Impuesto:

┌───────────────────────────────────────┐
│ Código: [IVA21__] (required)         │
│ Nombre: [IVA 21%__] (required)       │
│ Tipo: [Ambos ▼] (Sale/Purchase/Both) │
│ Método: [Porcentaje ▼] (%)           │
│ Tasa: [21___] %                       │
│ Cuenta Impuesto Cobrado: [Select ▼]  │
│ Cuenta Impuesto Pagado: [Select ▼]   │
│ Activo: [✓]                           │
│ [Guardar] [Cancelar]                  │
└───────────────────────────────────────┘

Casos de Prueba

Funcionales

  1. TC-001: Crear impuesto percentage exitosamente
  2. TC-002: Crear impuesto fixed exitosamente
  3. TC-003: Error por rate > 100
  4. TC-004: Error por código duplicado
  5. TC-005: Listar impuestos con filtro type
  6. TC-006: Calcular impuesto 21% sobre 1000 = 210
  7. TC-007: Validar cuenta contable existe
  8. TC-008: RLS filtra por empresa

No Funcionales

  1. Performance: < 200ms
  2. Seguridad: JWT + accounting_manager

Dependencias

  • US bloqueantes:
    • US-MGN-004-001-001 (CRUD Cuentas) - Para tax_collected_account_id
    • US-MGN-002-001-001 (CRUD Empresas)
  • Módulos: MGN-002, MGN-004

Estimación Detallada

Tarea Estimación
Backend 3 horas
Frontend 3 horas
Testing 2 horas
Code Review 1 hora
TOTAL 9 horas = 5 SP

Definition of Done

  • Código implementado
  • Tests pasando (>80%)
  • Code review aprobado
  • Swagger docs actualizado
  • RLS aplicado
  • Merge a develop
  • QA validado
  • PO aprobado

Referencias