# US-MGN-004-002-001: CRUD de Journals Contables **RF Asociado:** [RF-MGN-004-002](../../02-modelado/requerimientos-funcionales/mgn-004/RF-MGN-004-002-gestión-de-journals-contables.md) **Módulo:** MGN-004 - Financiero Básico **Epic:** Journals Contables **Prioridad:** P0 (MVP) **Story Points:** 5 **Sprint:** Sprint 7 **Estado:** Ready for Development **Fecha:** 2025-11-24 --- ## User Story **Como** contador de la empresa, **Quiero** crear y gestionar journals contables (diarios), **Para** clasificar los asientos contables según su origen (ventas, compras, banco, caja, misceláneos). --- ## Descripción Detallada Los journals (diarios contables) son libros donde se registran los asientos contables agrupados por tipo de operación. Cada journal tiene: - Código único por empresa (ej: "VEN", "COM", "BAN") - Nombre descriptivo - Tipo: sale (ventas), purchase (compras), bank (banco), cash (caja), general (misceláneos) - Secuencia para numerar asientos automáticamente - Cuenta bancaria asociada (opcional, para journals tipo bank) - Moneda por defecto Los journals permiten segregar y organizar los asientos contables, facilitando el análisis y auditoría. --- ## Criterios de Aceptación ### Escenario 1: Crear journal exitosamente **Dado que** soy contador con permisos accounting_manager, **Cuando** creo un journal con code="VEN", name="Ventas", type="sale", currency="USD", **Entonces** el sistema crea el journal y retorna el registro completo con id y company_id. ### Escenario 2: Validar código único por empresa **Dado que** ya existe un journal con code="VEN" en mi empresa, **Cuando** intento crear otro journal con el mismo código, **Entonces** el sistema retorna error 400 "El código de journal ya existe en esta empresa". ### Escenario 3: Listar journals con filtro por tipo **Dado que** tengo 10 journals en mi empresa, **Cuando** listo journals con filtro type="bank", **Entonces** el sistema retorna solo los journals de tipo bank. ### Escenario 4: Actualizar journal **Dado que** tengo un journal con id=5, **Cuando** actualizo el nombre a "Ventas Nacionales", **Entonces** el sistema actualiza el journal y retorna el registro modificado. ### Escenario 5: No se puede eliminar journal con asientos **Dado que** tengo un journal con asientos contables asociados, **Cuando** intento eliminar el journal, **Entonces** el sistema retorna error 409 "No se puede eliminar journal con asientos contables". ### Escenario 6: Tipos de journal válidos **Dado que** intento crear un journal con type="invalid", **Cuando** envío el request, **Entonces** el sistema retorna error 400 "Tipo de journal inválido. Valores permitidos: sale, purchase, bank, cash, general". --- ## Reglas de Negocio - **RN-1:** Código de journal debe ser único por empresa. - **RN-2:** Tipos válidos: sale, purchase, bank, cash, general. - **RN-3:** Journals tipo bank deben tener bank_account_id asociado (opcional para otros tipos). - **RN-4:** Cada journal tiene una secuencia para auto-numerar asientos (ej: VEN/2024/0001). - **RN-5:** No se puede eliminar un journal con asientos contables asociados. - **RN-6:** Journals pueden estar activos o inactivos (active field). - **RN-7:** RLS filtra journals por company_id. --- ## Tareas Técnicas ### Backend - [ ] Endpoint: `POST /api/v1/financial/journals` - [ ] Endpoint: `GET /api/v1/financial/journals` (con filtros: type, active) - [ ] Endpoint: `GET /api/v1/financial/journals/:id` - [ ] Endpoint: `PUT /api/v1/financial/journals/:id` - [ ] Endpoint: `DELETE /api/v1/financial/journals/:id` (soft delete) - [ ] Service: `JournalService.create/findAll/findOne/update/remove` - [ ] DTO: `CreateJournalDto` (validaciones @IsEnum para type) - [ ] DTO: `UpdateJournalDto` (partial) - [ ] Validar código único por empresa - [ ] Validar que bank_account_id existe (si journal type=bank) - [ ] Unit tests (8 test cases) - [ ] Integration tests (7 test cases) - [ ] Swagger docs ### Frontend - [ ] Componente: `JournalsTable.tsx` - [ ] Componente: `CreateJournalForm.tsx` - [ ] Componente: `EditJournalForm.tsx` - [ ] Página: `JournalsPage.tsx` (/financial/journals) - [ ] Página: `CreateJournalPage.tsx` - [ ] API client: `journalApi.ts` - [ ] Store: `useJournalStore.ts` - [ ] Component tests (5 test cases) - [ ] E2E test: "should create journal successfully" ### Database - [ ] Tabla: `financial.journals` (ya existe) - [ ] Índices: idx_journals_company_id, idx_journals_code, idx_journals_type - [ ] Constraint: uq_journals_code_company - [ ] RLS policy: company_isolation_journals --- ## Mockups / Wireframes **Lista de Journals:** - Tabla: Código | Nombre | Tipo | Moneda | Estado | Acciones - Botón: "Nuevo Journal" (primary) - Filtros: Tipo (dropdown), Estado (Activo/Inactivo) **Formulario Crear/Editar Journal:** - Campo: Código (input, required, max 10 chars, uppercase) - Campo: Nombre (input, required) - Campo: Tipo (select: Ventas, Compras, Banco, Caja, General) - Campo: Cuenta Bancaria (select, visible solo si type=bank) - Campo: Moneda (select, required) - Campo: Activo (checkbox) --- ## Casos de Prueba ### Funcionales 1. **TC-001:** Crear journal type=sale exitosamente 2. **TC-002:** Error por código duplicado 3. **TC-003:** Listar journals con filtro type=bank 4. **TC-004:** Actualizar nombre de journal 5. **TC-005:** Error al eliminar journal con asientos 6. **TC-006:** Error por type inválido 7. **TC-007:** RLS filtra por empresa ### No Funcionales 1. **Performance:** Response time < 200ms 2. **Seguridad:** JWT + permiso accounting_manager requerido --- ## Dependencias - **US bloqueantes:** - US-MGN-002-001-001 (CRUD Empresas) - US-MGN-003-003-001 (Gestión Monedas) - **Módulos:** MGN-002, MGN-003 --- ## 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 backend implementado - [ ] Código frontend implementado - [ ] Unit tests pasando (>80% cobertura) - [ ] Integration tests pasando - [ ] E2E tests pasando - [ ] Code review aprobado - [ ] Swagger docs actualizado - [ ] RLS aplicado - [ ] Merge a develop - [ ] QA validado - [ ] PO aprobado --- ## Referencias - [RF-MGN-004-002](../../02-modelado/requerimientos-funcionales/mgn-004/RF-MGN-004-002-gestión-de-journals-contables.md) - [ET-BACKEND-MGN-004-002](../../02-modelado/especificaciones-tecnicas/backend/mgn-004/ET-BACKEND-MGN-004-002-gestión-de-journals-contables.md) - [ET-FRONTEND-MGN-004-002](../../02-modelado/especificaciones-tecnicas/frontend/mgn-004/ET-FRONTEND-MGN-004-002-gestión-de-journals-contables.md) - [TRACEABILITY-MGN-004.yaml](../../02-modelado/trazabilidad/TRACEABILITY-MGN-004.yaml) - [Financial Schema DDL](../../02-modelado/database-design/schemas/financial-schema-ddl.sql)