1461 lines
57 KiB
YAML
1461 lines
57 KiB
YAML
# TRACEABILITY-MGN-004.yaml
|
|
# Matriz de Trazabilidad - MGN-004: Financiero Básico
|
|
# Fecha: 2025-11-24
|
|
# Versión: 1.0
|
|
|
|
module:
|
|
id: MGN-004
|
|
name: "Financiero Básico"
|
|
description: "Plan de cuentas, journals, asientos contables, impuestos, facturas y pagos"
|
|
priority: P0
|
|
story_points: 81
|
|
status: Diseñado
|
|
|
|
metadata:
|
|
total_rf: 8
|
|
total_et_backend: 8
|
|
total_et_frontend: 8
|
|
total_tables: 12
|
|
total_tests: 160
|
|
coverage: 100%
|
|
|
|
requirements:
|
|
- rf_id: RF-MGN-004-001
|
|
rf_title: "Gestión de Plan de Cuentas"
|
|
rf_file: "requerimientos-funcionales/mgn-004/RF-MGN-004-001-gestión-de-plan-de-cuentas.md"
|
|
priority: P0
|
|
story_points: 8
|
|
|
|
et_backend:
|
|
file: "especificaciones-tecnicas/backend/mgn-004/ET-BACKEND-MGN-004-001-gestión-de-plan-de-cuentas.md"
|
|
endpoints:
|
|
- method: POST
|
|
path: /api/v1/financial/accounts
|
|
description: "Crear cuenta contable"
|
|
- method: GET
|
|
path: /api/v1/financial/accounts
|
|
description: "Listar cuentas contables"
|
|
- method: GET
|
|
path: /api/v1/financial/accounts/:id
|
|
description: "Obtener cuenta por ID"
|
|
- method: PUT
|
|
path: /api/v1/financial/accounts/:id
|
|
description: "Actualizar cuenta"
|
|
- method: DELETE
|
|
path: /api/v1/financial/accounts/:id
|
|
description: "Desactivar cuenta"
|
|
services:
|
|
- name: "AccountService"
|
|
file: "src/modules/financial/services/account.service.ts"
|
|
methods:
|
|
- create
|
|
- findAll
|
|
- findOne
|
|
- update
|
|
- remove
|
|
controllers:
|
|
- name: "AccountController"
|
|
file: "src/modules/financial/controllers/account.controller.ts"
|
|
dtos:
|
|
- name: "CreateAccountDto"
|
|
file: "src/modules/financial/dto/create-account.dto.ts"
|
|
- name: "UpdateAccountDto"
|
|
file: "src/modules/financial/dto/update-account.dto.ts"
|
|
|
|
et_frontend:
|
|
file: "especificaciones-tecnicas/frontend/mgn-004/ET-FRONTEND-MGN-004-001-gestión-de-plan-de-cuentas.md"
|
|
routes:
|
|
- path: "/financial/accounts"
|
|
component: "AccountsPage"
|
|
- path: "/financial/accounts/create"
|
|
component: "CreateAccountPage"
|
|
- path: "/financial/accounts/:id/edit"
|
|
component: "EditAccountPage"
|
|
- path: "/financial/accounts/:id"
|
|
component: "ViewAccountPage"
|
|
components:
|
|
- name: "AccountsTable"
|
|
file: "src/widgets/accounts-table/ui/AccountsTable.tsx"
|
|
type: widget
|
|
- name: "CreateAccountForm"
|
|
file: "src/features/create-account/ui/CreateAccountForm.tsx"
|
|
type: feature
|
|
- name: "AccountCard"
|
|
file: "src/entities/account/ui/AccountCard.tsx"
|
|
type: entity
|
|
- name: "AccountTree"
|
|
file: "src/widgets/account-tree/ui/AccountTree.tsx"
|
|
type: widget
|
|
api_client:
|
|
- name: "accountApi"
|
|
file: "src/entities/account/api/account.api.ts"
|
|
methods:
|
|
- getAll
|
|
- getById
|
|
- create
|
|
- update
|
|
- delete
|
|
state_management:
|
|
- name: "useAccountStore"
|
|
file: "src/entities/account/model/account.store.ts"
|
|
type: zustand
|
|
|
|
database_tables:
|
|
- schema: financial
|
|
table: accounts
|
|
file: "database-design/schemas/financial-schema-ddl.sql"
|
|
operations:
|
|
- SELECT
|
|
- INSERT
|
|
- UPDATE
|
|
- DELETE (soft)
|
|
indices:
|
|
- idx_accounts_company_id
|
|
- idx_accounts_code
|
|
- idx_accounts_parent_id
|
|
- idx_accounts_type
|
|
rls_policy: company_isolation_accounts
|
|
|
|
tests:
|
|
backend:
|
|
unit_tests:
|
|
- file: "src/modules/financial/services/account.service.spec.ts"
|
|
test_cases:
|
|
- "should create account with valid data"
|
|
- "should create hierarchical accounts"
|
|
- "should validate account code uniqueness"
|
|
- "should throw error when parent not found"
|
|
- "should update account successfully"
|
|
- "should soft delete account"
|
|
integration_tests:
|
|
- file: "test/financial/account.controller.e2e-spec.ts"
|
|
test_cases:
|
|
- "POST /api/v1/financial/accounts should create account"
|
|
- "GET /api/v1/financial/accounts should return all accounts"
|
|
- "GET /api/v1/financial/accounts/:id should return account"
|
|
- "PUT /api/v1/financial/accounts/:id should update account"
|
|
- "DELETE /api/v1/financial/accounts/:id should soft delete account"
|
|
- "should enforce company isolation"
|
|
- "should require authentication"
|
|
- "should check accounting permissions"
|
|
frontend:
|
|
component_tests:
|
|
- file: "src/widgets/accounts-table/ui/AccountsTable.test.tsx"
|
|
test_cases:
|
|
- "should render table with accounts"
|
|
- "should handle pagination"
|
|
- "should filter by type"
|
|
- file: "src/features/create-account/ui/CreateAccountForm.test.tsx"
|
|
test_cases:
|
|
- "should validate required fields"
|
|
- "should validate account code format"
|
|
- "should submit valid form"
|
|
e2e_tests:
|
|
- file: "e2e/financial/accounts.spec.ts"
|
|
test_cases:
|
|
- "should create account successfully"
|
|
- "should create child account"
|
|
- "should edit account successfully"
|
|
- "should delete account with confirmation"
|
|
|
|
acceptance_criteria:
|
|
- id: AC-001
|
|
description: "Usuario puede crear plan de cuentas jerárquico"
|
|
status: Pending
|
|
test_reference: "test/financial/account.controller.e2e-spec.ts:28"
|
|
- id: AC-002
|
|
description: "Cuentas tienen tipos: asset, liability, equity, income, expense"
|
|
status: Pending
|
|
test_reference: "src/modules/financial/services/account.service.spec.ts:65"
|
|
- id: AC-003
|
|
description: "Código de cuenta es único por empresa"
|
|
status: Pending
|
|
test_reference: "test/financial/account.controller.e2e-spec.ts:95"
|
|
|
|
business_rules:
|
|
- id: RN-001
|
|
description: "Código de cuenta único por empresa"
|
|
implementation: "database-design/schemas/financial-schema-ddl.sql:CONSTRAINT uq_accounts_code_company"
|
|
test_reference: "src/modules/financial/services/account.service.spec.ts:48"
|
|
- id: RN-002
|
|
description: "Cuentas soportan jerarquía con parent_id"
|
|
implementation: "database-design/schemas/financial-schema-ddl.sql:accounts.parent_id"
|
|
test_reference: "src/modules/financial/services/account.service.spec.ts:78"
|
|
- id: RN-003
|
|
description: "No se puede eliminar cuenta con movimientos"
|
|
implementation: "src/modules/financial/services/account.service.ts:remove()"
|
|
test_reference: "src/modules/financial/services/account.service.spec.ts:108"
|
|
|
|
dependencies:
|
|
rf_dependencies:
|
|
- RF-MGN-002-001
|
|
module_dependencies:
|
|
- MGN-002
|
|
external_dependencies: []
|
|
|
|
- rf_id: RF-MGN-004-002
|
|
rf_title: "Gestión de Journals Contables"
|
|
rf_file: "requerimientos-funcionales/mgn-004/RF-MGN-004-002-gestión-de-journals-contables.md"
|
|
priority: P0
|
|
story_points: 5
|
|
|
|
et_backend:
|
|
file: "especificaciones-tecnicas/backend/mgn-004/ET-BACKEND-MGN-004-002-gestión-de-journals-contables.md"
|
|
endpoints:
|
|
- method: POST
|
|
path: /api/v1/financial/journals
|
|
description: "Crear journal"
|
|
- method: GET
|
|
path: /api/v1/financial/journals
|
|
description: "Listar journals"
|
|
- method: GET
|
|
path: /api/v1/financial/journals/:id
|
|
description: "Obtener journal por ID"
|
|
- method: PUT
|
|
path: /api/v1/financial/journals/:id
|
|
description: "Actualizar journal"
|
|
- method: DELETE
|
|
path: /api/v1/financial/journals/:id
|
|
description: "Desactivar journal"
|
|
services:
|
|
- name: "JournalService"
|
|
file: "src/modules/financial/services/journal.service.ts"
|
|
methods:
|
|
- create
|
|
- findAll
|
|
- findOne
|
|
- update
|
|
- remove
|
|
controllers:
|
|
- name: "JournalController"
|
|
file: "src/modules/financial/controllers/journal.controller.ts"
|
|
dtos:
|
|
- name: "CreateJournalDto"
|
|
file: "src/modules/financial/dto/create-journal.dto.ts"
|
|
- name: "UpdateJournalDto"
|
|
file: "src/modules/financial/dto/update-journal.dto.ts"
|
|
|
|
et_frontend:
|
|
file: "especificaciones-tecnicas/frontend/mgn-004/ET-FRONTEND-MGN-004-002-gestión-de-journals-contables.md"
|
|
routes:
|
|
- path: "/financial/journals"
|
|
component: "JournalsPage"
|
|
- path: "/financial/journals/create"
|
|
component: "CreateJournalPage"
|
|
components:
|
|
- name: "JournalsTable"
|
|
file: "src/widgets/journals-table/ui/JournalsTable.tsx"
|
|
type: widget
|
|
- name: "CreateJournalForm"
|
|
file: "src/features/create-journal/ui/CreateJournalForm.tsx"
|
|
type: feature
|
|
- name: "JournalCard"
|
|
file: "src/entities/journal/ui/JournalCard.tsx"
|
|
type: entity
|
|
api_client:
|
|
- name: "journalApi"
|
|
file: "src/entities/journal/api/journal.api.ts"
|
|
methods:
|
|
- getAll
|
|
- getById
|
|
- create
|
|
- update
|
|
- delete
|
|
state_management:
|
|
- name: "useJournalStore"
|
|
file: "src/entities/journal/model/journal.store.ts"
|
|
type: zustand
|
|
|
|
database_tables:
|
|
- schema: financial
|
|
table: journals
|
|
file: "database-design/schemas/financial-schema-ddl.sql"
|
|
operations:
|
|
- SELECT
|
|
- INSERT
|
|
- UPDATE
|
|
- DELETE (soft)
|
|
indices:
|
|
- idx_journals_company_id
|
|
- idx_journals_code
|
|
- idx_journals_type
|
|
rls_policy: company_isolation_journals
|
|
|
|
tests:
|
|
backend:
|
|
unit_tests:
|
|
- file: "src/modules/financial/services/journal.service.spec.ts"
|
|
test_cases:
|
|
- "should create journal with valid data"
|
|
- "should validate journal type"
|
|
- "should throw error when code already exists"
|
|
- "should update journal successfully"
|
|
- "should soft delete journal"
|
|
integration_tests:
|
|
- file: "test/financial/journal.controller.e2e-spec.ts"
|
|
test_cases:
|
|
- "POST /api/v1/financial/journals should create journal"
|
|
- "GET /api/v1/financial/journals should return all journals"
|
|
- "GET /api/v1/financial/journals/:id should return journal"
|
|
- "PUT /api/v1/financial/journals/:id should update journal"
|
|
- "DELETE /api/v1/financial/journals/:id should soft delete journal"
|
|
- "should enforce company isolation"
|
|
- "should require authentication"
|
|
frontend:
|
|
component_tests:
|
|
- file: "src/widgets/journals-table/ui/JournalsTable.test.tsx"
|
|
test_cases:
|
|
- "should render table with journals"
|
|
- "should filter by type"
|
|
- file: "src/features/create-journal/ui/CreateJournalForm.test.tsx"
|
|
test_cases:
|
|
- "should validate required fields"
|
|
- "should submit valid form"
|
|
e2e_tests:
|
|
- file: "e2e/financial/journals.spec.ts"
|
|
test_cases:
|
|
- "should create journal successfully"
|
|
- "should edit journal successfully"
|
|
- "should delete journal with confirmation"
|
|
|
|
acceptance_criteria:
|
|
- id: AC-001
|
|
description: "Usuario puede crear journals por tipo (sale, purchase, bank, general)"
|
|
status: Pending
|
|
test_reference: "test/financial/journal.controller.e2e-spec.ts:28"
|
|
- id: AC-002
|
|
description: "Journal tiene código único por empresa"
|
|
status: Pending
|
|
test_reference: "src/modules/financial/services/journal.service.spec.ts:65"
|
|
- id: AC-003
|
|
description: "Asientos contables están vinculados a journals"
|
|
status: Pending
|
|
test_reference: "test/financial/journal.controller.e2e-spec.ts:95"
|
|
|
|
business_rules:
|
|
- id: RN-001
|
|
description: "Código de journal único por empresa"
|
|
implementation: "database-design/schemas/financial-schema-ddl.sql:CONSTRAINT uq_journals_code_company"
|
|
test_reference: "src/modules/financial/services/journal.service.spec.ts:48"
|
|
- id: RN-002
|
|
description: "Journals tienen tipos: sale, purchase, bank, cash, general"
|
|
implementation: "database-design/schemas/financial-schema-ddl.sql:journals.type enum"
|
|
test_reference: "src/modules/financial/services/journal.service.spec.ts:78"
|
|
- id: RN-003
|
|
description: "No se puede eliminar journal con asientos"
|
|
implementation: "src/modules/financial/services/journal.service.ts:remove()"
|
|
test_reference: "src/modules/financial/services/journal.service.spec.ts:95"
|
|
|
|
dependencies:
|
|
rf_dependencies:
|
|
- RF-MGN-002-001
|
|
- RF-MGN-004-001
|
|
module_dependencies:
|
|
- MGN-002
|
|
external_dependencies: []
|
|
|
|
- rf_id: RF-MGN-004-003
|
|
rf_title: "Registro de Asientos Contables"
|
|
rf_file: "requerimientos-funcionales/mgn-004/RF-MGN-004-003-registro-de-asientos-contables.md"
|
|
priority: P0
|
|
story_points: 13
|
|
|
|
et_backend:
|
|
file: "especificaciones-tecnicas/backend/mgn-004/ET-BACKEND-MGN-004-003-registro-de-asientos-contables.md"
|
|
endpoints:
|
|
- method: POST
|
|
path: /api/v1/financial/journal-entries
|
|
description: "Crear asiento contable"
|
|
- method: GET
|
|
path: /api/v1/financial/journal-entries
|
|
description: "Listar asientos"
|
|
- method: GET
|
|
path: /api/v1/financial/journal-entries/:id
|
|
description: "Obtener asiento por ID"
|
|
- method: PUT
|
|
path: /api/v1/financial/journal-entries/:id
|
|
description: "Actualizar asiento (draft)"
|
|
- method: POST
|
|
path: /api/v1/financial/journal-entries/:id/post
|
|
description: "Publicar asiento (draft → posted)"
|
|
- method: DELETE
|
|
path: /api/v1/financial/journal-entries/:id
|
|
description: "Eliminar asiento (draft)"
|
|
services:
|
|
- name: "JournalEntryService"
|
|
file: "src/modules/financial/services/journal-entry.service.ts"
|
|
methods:
|
|
- create
|
|
- findAll
|
|
- findOne
|
|
- update
|
|
- post
|
|
- remove
|
|
- validateBalance
|
|
controllers:
|
|
- name: "JournalEntryController"
|
|
file: "src/modules/financial/controllers/journal-entry.controller.ts"
|
|
dtos:
|
|
- name: "CreateJournalEntryDto"
|
|
file: "src/modules/financial/dto/create-journal-entry.dto.ts"
|
|
- name: "UpdateJournalEntryDto"
|
|
file: "src/modules/financial/dto/update-journal-entry.dto.ts"
|
|
|
|
et_frontend:
|
|
file: "especificaciones-tecnicas/frontend/mgn-004/ET-FRONTEND-MGN-004-003-registro-de-asientos-contables.md"
|
|
routes:
|
|
- path: "/financial/journal-entries"
|
|
component: "JournalEntriesPage"
|
|
- path: "/financial/journal-entries/create"
|
|
component: "CreateJournalEntryPage"
|
|
- path: "/financial/journal-entries/:id/edit"
|
|
component: "EditJournalEntryPage"
|
|
- path: "/financial/journal-entries/:id"
|
|
component: "ViewJournalEntryPage"
|
|
components:
|
|
- name: "JournalEntriesTable"
|
|
file: "src/widgets/journal-entries-table/ui/JournalEntriesTable.tsx"
|
|
type: widget
|
|
- name: "CreateJournalEntryForm"
|
|
file: "src/features/create-journal-entry/ui/CreateJournalEntryForm.tsx"
|
|
type: feature
|
|
- name: "JournalEntryCard"
|
|
file: "src/entities/journal-entry/ui/JournalEntryCard.tsx"
|
|
type: entity
|
|
- name: "JournalEntryLineItems"
|
|
file: "src/widgets/journal-entry-lines/ui/JournalEntryLineItems.tsx"
|
|
type: widget
|
|
api_client:
|
|
- name: "journalEntryApi"
|
|
file: "src/entities/journal-entry/api/journal-entry.api.ts"
|
|
methods:
|
|
- getAll
|
|
- getById
|
|
- create
|
|
- update
|
|
- post
|
|
- delete
|
|
state_management:
|
|
- name: "useJournalEntryStore"
|
|
file: "src/entities/journal-entry/model/journal-entry.store.ts"
|
|
type: zustand
|
|
|
|
database_tables:
|
|
- schema: financial
|
|
table: journal_entries
|
|
file: "database-design/schemas/financial-schema-ddl.sql"
|
|
operations:
|
|
- SELECT
|
|
- INSERT
|
|
- UPDATE
|
|
- DELETE
|
|
indices:
|
|
- idx_journal_entries_journal_id
|
|
- idx_journal_entries_company_id
|
|
- idx_journal_entries_date
|
|
- idx_journal_entries_state
|
|
rls_policy: company_isolation_journal_entries
|
|
- schema: financial
|
|
table: journal_entry_lines
|
|
file: "database-design/schemas/financial-schema-ddl.sql"
|
|
operations:
|
|
- SELECT
|
|
- INSERT
|
|
- UPDATE
|
|
- DELETE
|
|
indices:
|
|
- idx_journal_entry_lines_entry_id
|
|
- idx_journal_entry_lines_account_id
|
|
- idx_journal_entry_lines_partner_id
|
|
rls_policy: company_isolation_journal_entry_lines
|
|
|
|
tests:
|
|
backend:
|
|
unit_tests:
|
|
- file: "src/modules/financial/services/journal-entry.service.spec.ts"
|
|
test_cases:
|
|
- "should create journal entry with lines"
|
|
- "should validate debit = credit balance"
|
|
- "should throw error for unbalanced entry"
|
|
- "should post entry (draft → posted)"
|
|
- "should prevent editing posted entry"
|
|
- "should allow deleting draft entry"
|
|
- "should prevent deleting posted entry"
|
|
integration_tests:
|
|
- file: "test/financial/journal-entry.controller.e2e-spec.ts"
|
|
test_cases:
|
|
- "POST /api/v1/financial/journal-entries should create entry"
|
|
- "GET /api/v1/financial/journal-entries should return all entries"
|
|
- "GET /api/v1/financial/journal-entries/:id should return entry with lines"
|
|
- "PUT /api/v1/financial/journal-entries/:id should update draft entry"
|
|
- "POST /api/v1/financial/journal-entries/:id/post should post entry"
|
|
- "DELETE /api/v1/financial/journal-entries/:id should delete draft entry"
|
|
- "should enforce company isolation"
|
|
- "should require authentication"
|
|
- "should check accounting permissions"
|
|
frontend:
|
|
component_tests:
|
|
- file: "src/widgets/journal-entries-table/ui/JournalEntriesTable.test.tsx"
|
|
test_cases:
|
|
- "should render table with entries"
|
|
- "should filter by state"
|
|
- "should handle pagination"
|
|
- file: "src/features/create-journal-entry/ui/CreateJournalEntryForm.test.tsx"
|
|
test_cases:
|
|
- "should validate required fields"
|
|
- "should validate debit = credit"
|
|
- "should submit valid form"
|
|
e2e_tests:
|
|
- file: "e2e/financial/journal-entries.spec.ts"
|
|
test_cases:
|
|
- "should create journal entry successfully"
|
|
- "should post entry successfully"
|
|
- "should show error for unbalanced entry"
|
|
- "should prevent editing posted entry"
|
|
|
|
acceptance_criteria:
|
|
- id: AC-001
|
|
description: "Usuario puede crear asientos contables con múltiples líneas"
|
|
status: Pending
|
|
test_reference: "test/financial/journal-entry.controller.e2e-spec.ts:28"
|
|
- id: AC-002
|
|
description: "Sistema valida que suma de débitos = suma de créditos"
|
|
status: Pending
|
|
test_reference: "src/modules/financial/services/journal-entry.service.spec.ts:65"
|
|
- id: AC-003
|
|
description: "Asientos publicados no pueden modificarse"
|
|
status: Pending
|
|
test_reference: "test/financial/journal-entry.controller.e2e-spec.ts:105"
|
|
|
|
business_rules:
|
|
- id: RN-001
|
|
description: "Suma de débitos debe igualar suma de créditos"
|
|
implementation: "src/modules/financial/services/journal-entry.service.ts:validateBalance()"
|
|
test_reference: "src/modules/financial/services/journal-entry.service.spec.ts:48"
|
|
- id: RN-002
|
|
description: "Asientos tienen estados: draft, posted"
|
|
implementation: "database-design/schemas/financial-schema-ddl.sql:journal_entries.state"
|
|
test_reference: "src/modules/financial/services/journal-entry.service.spec.ts:78"
|
|
- id: RN-003
|
|
description: "Solo asientos draft pueden modificarse o eliminarse"
|
|
implementation: "src/modules/financial/services/journal-entry.service.ts:update()"
|
|
test_reference: "src/modules/financial/services/journal-entry.service.spec.ts:108"
|
|
|
|
dependencies:
|
|
rf_dependencies:
|
|
- RF-MGN-004-001
|
|
- RF-MGN-004-002
|
|
- RF-MGN-003-001
|
|
module_dependencies:
|
|
- MGN-003
|
|
external_dependencies: []
|
|
|
|
- rf_id: RF-MGN-004-004
|
|
rf_title: "Gestión de Impuestos"
|
|
rf_file: "requerimientos-funcionales/mgn-004/RF-MGN-004-004-gestión-de-impuestos.md"
|
|
priority: P0
|
|
story_points: 8
|
|
|
|
et_backend:
|
|
file: "especificaciones-tecnicas/backend/mgn-004/ET-BACKEND-MGN-004-004-gestión-de-impuestos.md"
|
|
endpoints:
|
|
- method: POST
|
|
path: /api/v1/financial/taxes
|
|
description: "Crear impuesto"
|
|
- method: GET
|
|
path: /api/v1/financial/taxes
|
|
description: "Listar impuestos"
|
|
- method: GET
|
|
path: /api/v1/financial/taxes/:id
|
|
description: "Obtener impuesto por ID"
|
|
- method: PUT
|
|
path: /api/v1/financial/taxes/:id
|
|
description: "Actualizar impuesto"
|
|
- method: DELETE
|
|
path: /api/v1/financial/taxes/:id
|
|
description: "Desactivar impuesto"
|
|
services:
|
|
- name: "TaxService"
|
|
file: "src/modules/financial/services/tax.service.ts"
|
|
methods:
|
|
- create
|
|
- findAll
|
|
- findOne
|
|
- update
|
|
- remove
|
|
- calculateTax
|
|
controllers:
|
|
- name: "TaxController"
|
|
file: "src/modules/financial/controllers/tax.controller.ts"
|
|
dtos:
|
|
- name: "CreateTaxDto"
|
|
file: "src/modules/financial/dto/create-tax.dto.ts"
|
|
- name: "UpdateTaxDto"
|
|
file: "src/modules/financial/dto/update-tax.dto.ts"
|
|
|
|
et_frontend:
|
|
file: "especificaciones-tecnicas/frontend/mgn-004/ET-FRONTEND-MGN-004-004-gestión-de-impuestos.md"
|
|
routes:
|
|
- path: "/financial/taxes"
|
|
component: "TaxesPage"
|
|
- path: "/financial/taxes/create"
|
|
component: "CreateTaxPage"
|
|
components:
|
|
- name: "TaxesTable"
|
|
file: "src/widgets/taxes-table/ui/TaxesTable.tsx"
|
|
type: widget
|
|
- name: "CreateTaxForm"
|
|
file: "src/features/create-tax/ui/CreateTaxForm.tsx"
|
|
type: feature
|
|
- name: "TaxCard"
|
|
file: "src/entities/tax/ui/TaxCard.tsx"
|
|
type: entity
|
|
api_client:
|
|
- name: "taxApi"
|
|
file: "src/entities/tax/api/tax.api.ts"
|
|
methods:
|
|
- getAll
|
|
- getById
|
|
- create
|
|
- update
|
|
- delete
|
|
state_management:
|
|
- name: "useTaxStore"
|
|
file: "src/entities/tax/model/tax.store.ts"
|
|
type: zustand
|
|
|
|
database_tables:
|
|
- schema: financial
|
|
table: taxes
|
|
file: "database-design/schemas/financial-schema-ddl.sql"
|
|
operations:
|
|
- SELECT
|
|
- INSERT
|
|
- UPDATE
|
|
- DELETE (soft)
|
|
indices:
|
|
- idx_taxes_company_id
|
|
- idx_taxes_type
|
|
rls_policy: company_isolation_taxes
|
|
|
|
tests:
|
|
backend:
|
|
unit_tests:
|
|
- file: "src/modules/financial/services/tax.service.spec.ts"
|
|
test_cases:
|
|
- "should create tax with valid data"
|
|
- "should calculate tax amount"
|
|
- "should handle percentage and fixed taxes"
|
|
- "should validate rate between 0-100"
|
|
- "should update tax successfully"
|
|
integration_tests:
|
|
- file: "test/financial/tax.controller.e2e-spec.ts"
|
|
test_cases:
|
|
- "POST /api/v1/financial/taxes should create tax"
|
|
- "GET /api/v1/financial/taxes should return all taxes"
|
|
- "GET /api/v1/financial/taxes/:id should return tax"
|
|
- "PUT /api/v1/financial/taxes/:id should update tax"
|
|
- "DELETE /api/v1/financial/taxes/:id should soft delete tax"
|
|
- "should enforce company isolation"
|
|
- "should require authentication"
|
|
frontend:
|
|
component_tests:
|
|
- file: "src/widgets/taxes-table/ui/TaxesTable.test.tsx"
|
|
test_cases:
|
|
- "should render table with taxes"
|
|
- "should filter by type"
|
|
- file: "src/features/create-tax/ui/CreateTaxForm.test.tsx"
|
|
test_cases:
|
|
- "should validate required fields"
|
|
- "should validate rate range"
|
|
- "should submit valid form"
|
|
e2e_tests:
|
|
- file: "e2e/financial/taxes.spec.ts"
|
|
test_cases:
|
|
- "should create tax successfully"
|
|
- "should edit tax successfully"
|
|
- "should delete tax with confirmation"
|
|
|
|
acceptance_criteria:
|
|
- id: AC-001
|
|
description: "Usuario puede crear impuestos con tipo (sale, purchase, both)"
|
|
status: Pending
|
|
test_reference: "test/financial/tax.controller.e2e-spec.ts:28"
|
|
- id: AC-002
|
|
description: "Sistema calcula impuestos automáticamente en facturas"
|
|
status: Pending
|
|
test_reference: "src/modules/financial/services/tax.service.spec.ts:65"
|
|
- id: AC-003
|
|
description: "Impuestos tienen cuentas contables asociadas"
|
|
status: Pending
|
|
test_reference: "test/financial/tax.controller.e2e-spec.ts:95"
|
|
|
|
business_rules:
|
|
- id: RN-001
|
|
description: "Impuestos tienen tipos: sale (ventas), purchase (compras), both"
|
|
implementation: "database-design/schemas/financial-schema-ddl.sql:taxes.type"
|
|
test_reference: "src/modules/financial/services/tax.service.spec.ts:48"
|
|
- id: RN-002
|
|
description: "Rate debe estar entre 0 y 100"
|
|
implementation: "src/modules/financial/dto/create-tax.dto.ts:@Min(0) @Max(100)"
|
|
test_reference: "src/modules/financial/services/tax.service.spec.ts:78"
|
|
- id: RN-003
|
|
description: "Impuesto debe tener cuenta contable asignada"
|
|
implementation: "database-design/schemas/financial-schema-ddl.sql:taxes.account_id"
|
|
test_reference: "src/modules/financial/services/tax.service.spec.ts:95"
|
|
|
|
dependencies:
|
|
rf_dependencies:
|
|
- RF-MGN-004-001
|
|
- RF-MGN-002-001
|
|
module_dependencies:
|
|
- MGN-002
|
|
external_dependencies: []
|
|
|
|
- rf_id: RF-MGN-004-005
|
|
rf_title: "Gestión de Facturas de Cliente"
|
|
rf_file: "requerimientos-funcionales/mgn-004/RF-MGN-004-005-gestión-de-facturas-de-cliente.md"
|
|
priority: P0
|
|
story_points: 13
|
|
|
|
et_backend:
|
|
file: "especificaciones-tecnicas/backend/mgn-004/ET-BACKEND-MGN-004-005-gestión-de-facturas-de-cliente.md"
|
|
endpoints:
|
|
- method: POST
|
|
path: /api/v1/financial/customer-invoices
|
|
description: "Crear factura de cliente"
|
|
- method: GET
|
|
path: /api/v1/financial/customer-invoices
|
|
description: "Listar facturas de cliente"
|
|
- method: GET
|
|
path: /api/v1/financial/customer-invoices/:id
|
|
description: "Obtener factura por ID"
|
|
- method: PUT
|
|
path: /api/v1/financial/customer-invoices/:id
|
|
description: "Actualizar factura (draft)"
|
|
- method: POST
|
|
path: /api/v1/financial/customer-invoices/:id/validate
|
|
description: "Validar factura (draft → open)"
|
|
- method: POST
|
|
path: /api/v1/financial/customer-invoices/:id/cancel
|
|
description: "Cancelar factura"
|
|
services:
|
|
- name: "CustomerInvoiceService"
|
|
file: "src/modules/financial/services/customer-invoice.service.ts"
|
|
methods:
|
|
- create
|
|
- findAll
|
|
- findOne
|
|
- update
|
|
- validate
|
|
- cancel
|
|
- generateJournalEntry
|
|
controllers:
|
|
- name: "CustomerInvoiceController"
|
|
file: "src/modules/financial/controllers/customer-invoice.controller.ts"
|
|
dtos:
|
|
- name: "CreateCustomerInvoiceDto"
|
|
file: "src/modules/financial/dto/create-customer-invoice.dto.ts"
|
|
- name: "UpdateCustomerInvoiceDto"
|
|
file: "src/modules/financial/dto/update-customer-invoice.dto.ts"
|
|
|
|
et_frontend:
|
|
file: "especificaciones-tecnicas/frontend/mgn-004/ET-FRONTEND-MGN-004-005-gestión-de-facturas-de-cliente.md"
|
|
routes:
|
|
- path: "/financial/customer-invoices"
|
|
component: "CustomerInvoicesPage"
|
|
- path: "/financial/customer-invoices/create"
|
|
component: "CreateCustomerInvoicePage"
|
|
- path: "/financial/customer-invoices/:id/edit"
|
|
component: "EditCustomerInvoicePage"
|
|
- path: "/financial/customer-invoices/:id"
|
|
component: "ViewCustomerInvoicePage"
|
|
components:
|
|
- name: "CustomerInvoicesTable"
|
|
file: "src/widgets/customer-invoices-table/ui/CustomerInvoicesTable.tsx"
|
|
type: widget
|
|
- name: "CreateCustomerInvoiceForm"
|
|
file: "src/features/create-customer-invoice/ui/CreateCustomerInvoiceForm.tsx"
|
|
type: feature
|
|
- name: "CustomerInvoiceCard"
|
|
file: "src/entities/customer-invoice/ui/CustomerInvoiceCard.tsx"
|
|
type: entity
|
|
- name: "InvoiceLineItems"
|
|
file: "src/widgets/invoice-line-items/ui/InvoiceLineItems.tsx"
|
|
type: widget
|
|
api_client:
|
|
- name: "customerInvoiceApi"
|
|
file: "src/entities/customer-invoice/api/customer-invoice.api.ts"
|
|
methods:
|
|
- getAll
|
|
- getById
|
|
- create
|
|
- update
|
|
- validate
|
|
- cancel
|
|
state_management:
|
|
- name: "useCustomerInvoiceStore"
|
|
file: "src/entities/customer-invoice/model/customer-invoice.store.ts"
|
|
type: zustand
|
|
|
|
database_tables:
|
|
- schema: financial
|
|
table: invoices
|
|
file: "database-design/schemas/financial-schema-ddl.sql"
|
|
operations:
|
|
- SELECT
|
|
- INSERT
|
|
- UPDATE
|
|
indices:
|
|
- idx_invoices_company_id
|
|
- idx_invoices_partner_id
|
|
- idx_invoices_type
|
|
- idx_invoices_state
|
|
- idx_invoices_invoice_date
|
|
rls_policy: company_isolation_invoices
|
|
- schema: financial
|
|
table: invoice_lines
|
|
file: "database-design/schemas/financial-schema-ddl.sql"
|
|
operations:
|
|
- SELECT
|
|
- INSERT
|
|
- UPDATE
|
|
- DELETE
|
|
indices:
|
|
- idx_invoice_lines_invoice_id
|
|
- idx_invoice_lines_product_id
|
|
rls_policy: company_isolation_invoice_lines
|
|
|
|
tests:
|
|
backend:
|
|
unit_tests:
|
|
- file: "src/modules/financial/services/customer-invoice.service.spec.ts"
|
|
test_cases:
|
|
- "should create customer invoice with lines"
|
|
- "should calculate totals with taxes"
|
|
- "should validate invoice (draft → open)"
|
|
- "should generate journal entry on validation"
|
|
- "should cancel invoice"
|
|
- "should prevent modifying validated invoice"
|
|
integration_tests:
|
|
- file: "test/financial/customer-invoice.controller.e2e-spec.ts"
|
|
test_cases:
|
|
- "POST /api/v1/financial/customer-invoices should create invoice"
|
|
- "GET /api/v1/financial/customer-invoices should return all invoices"
|
|
- "GET /api/v1/financial/customer-invoices/:id should return invoice with lines"
|
|
- "PUT /api/v1/financial/customer-invoices/:id should update draft invoice"
|
|
- "POST /api/v1/financial/customer-invoices/:id/validate should validate invoice"
|
|
- "POST /api/v1/financial/customer-invoices/:id/cancel should cancel invoice"
|
|
- "should enforce company isolation"
|
|
- "should require authentication"
|
|
frontend:
|
|
component_tests:
|
|
- file: "src/widgets/customer-invoices-table/ui/CustomerInvoicesTable.test.tsx"
|
|
test_cases:
|
|
- "should render table with invoices"
|
|
- "should filter by state"
|
|
- "should handle pagination"
|
|
- file: "src/features/create-customer-invoice/ui/CreateCustomerInvoiceForm.test.tsx"
|
|
test_cases:
|
|
- "should validate required fields"
|
|
- "should calculate totals"
|
|
- "should submit valid form"
|
|
e2e_tests:
|
|
- file: "e2e/financial/customer-invoices.spec.ts"
|
|
test_cases:
|
|
- "should create customer invoice successfully"
|
|
- "should validate invoice successfully"
|
|
- "should cancel invoice with confirmation"
|
|
- "should prevent editing validated invoice"
|
|
|
|
acceptance_criteria:
|
|
- id: AC-001
|
|
description: "Usuario puede crear facturas de cliente con líneas y impuestos"
|
|
status: Pending
|
|
test_reference: "test/financial/customer-invoice.controller.e2e-spec.ts:28"
|
|
- id: AC-002
|
|
description: "Sistema genera asiento contable al validar factura"
|
|
status: Pending
|
|
test_reference: "src/modules/financial/services/customer-invoice.service.spec.ts:85"
|
|
- id: AC-003
|
|
description: "Facturas validadas no pueden modificarse"
|
|
status: Pending
|
|
test_reference: "test/financial/customer-invoice.controller.e2e-spec.ts:125"
|
|
|
|
business_rules:
|
|
- id: RN-001
|
|
description: "Facturas tienen estados: draft, open, paid, cancelled"
|
|
implementation: "database-design/schemas/financial-schema-ddl.sql:invoices.state"
|
|
test_reference: "src/modules/financial/services/customer-invoice.service.spec.ts:58"
|
|
- id: RN-002
|
|
description: "Al validar factura se genera asiento contable automático"
|
|
implementation: "src/modules/financial/services/customer-invoice.service.ts:generateJournalEntry()"
|
|
test_reference: "src/modules/financial/services/customer-invoice.service.spec.ts:92"
|
|
- id: RN-003
|
|
description: "Solo facturas draft pueden modificarse"
|
|
implementation: "src/modules/financial/services/customer-invoice.service.ts:update()"
|
|
test_reference: "src/modules/financial/services/customer-invoice.service.spec.ts:118"
|
|
|
|
dependencies:
|
|
rf_dependencies:
|
|
- RF-MGN-004-001
|
|
- RF-MGN-004-002
|
|
- RF-MGN-004-003
|
|
- RF-MGN-004-004
|
|
- RF-MGN-003-001
|
|
module_dependencies:
|
|
- MGN-003
|
|
external_dependencies: []
|
|
|
|
- rf_id: RF-MGN-004-006
|
|
rf_title: "Gestión de Facturas de Proveedor"
|
|
rf_file: "requerimientos-funcionales/mgn-004/RF-MGN-004-006-gestión-de-facturas-de-proveedor.md"
|
|
priority: P0
|
|
story_points: 13
|
|
|
|
et_backend:
|
|
file: "especificaciones-tecnicas/backend/mgn-004/ET-BACKEND-MGN-004-006-gestión-de-facturas-de-proveedor.md"
|
|
endpoints:
|
|
- method: POST
|
|
path: /api/v1/financial/vendor-invoices
|
|
description: "Crear factura de proveedor"
|
|
- method: GET
|
|
path: /api/v1/financial/vendor-invoices
|
|
description: "Listar facturas de proveedor"
|
|
- method: GET
|
|
path: /api/v1/financial/vendor-invoices/:id
|
|
description: "Obtener factura por ID"
|
|
- method: PUT
|
|
path: /api/v1/financial/vendor-invoices/:id
|
|
description: "Actualizar factura (draft)"
|
|
- method: POST
|
|
path: /api/v1/financial/vendor-invoices/:id/validate
|
|
description: "Validar factura (draft → open)"
|
|
- method: POST
|
|
path: /api/v1/financial/vendor-invoices/:id/cancel
|
|
description: "Cancelar factura"
|
|
services:
|
|
- name: "VendorInvoiceService"
|
|
file: "src/modules/financial/services/vendor-invoice.service.ts"
|
|
methods:
|
|
- create
|
|
- findAll
|
|
- findOne
|
|
- update
|
|
- validate
|
|
- cancel
|
|
- generateJournalEntry
|
|
controllers:
|
|
- name: "VendorInvoiceController"
|
|
file: "src/modules/financial/controllers/vendor-invoice.controller.ts"
|
|
dtos:
|
|
- name: "CreateVendorInvoiceDto"
|
|
file: "src/modules/financial/dto/create-vendor-invoice.dto.ts"
|
|
- name: "UpdateVendorInvoiceDto"
|
|
file: "src/modules/financial/dto/update-vendor-invoice.dto.ts"
|
|
|
|
et_frontend:
|
|
file: "especificaciones-tecnicas/frontend/mgn-004/ET-FRONTEND-MGN-004-006-gestión-de-facturas-de-proveedor.md"
|
|
routes:
|
|
- path: "/financial/vendor-invoices"
|
|
component: "VendorInvoicesPage"
|
|
- path: "/financial/vendor-invoices/create"
|
|
component: "CreateVendorInvoicePage"
|
|
- path: "/financial/vendor-invoices/:id/edit"
|
|
component: "EditVendorInvoicePage"
|
|
- path: "/financial/vendor-invoices/:id"
|
|
component: "ViewVendorInvoicePage"
|
|
components:
|
|
- name: "VendorInvoicesTable"
|
|
file: "src/widgets/vendor-invoices-table/ui/VendorInvoicesTable.tsx"
|
|
type: widget
|
|
- name: "CreateVendorInvoiceForm"
|
|
file: "src/features/create-vendor-invoice/ui/CreateVendorInvoiceForm.tsx"
|
|
type: feature
|
|
- name: "VendorInvoiceCard"
|
|
file: "src/entities/vendor-invoice/ui/VendorInvoiceCard.tsx"
|
|
type: entity
|
|
- name: "InvoiceLineItems"
|
|
file: "src/widgets/invoice-line-items/ui/InvoiceLineItems.tsx"
|
|
type: widget
|
|
api_client:
|
|
- name: "vendorInvoiceApi"
|
|
file: "src/entities/vendor-invoice/api/vendor-invoice.api.ts"
|
|
methods:
|
|
- getAll
|
|
- getById
|
|
- create
|
|
- update
|
|
- validate
|
|
- cancel
|
|
state_management:
|
|
- name: "useVendorInvoiceStore"
|
|
file: "src/entities/vendor-invoice/model/vendor-invoice.store.ts"
|
|
type: zustand
|
|
|
|
database_tables:
|
|
- schema: financial
|
|
table: invoices
|
|
file: "database-design/schemas/financial-schema-ddl.sql"
|
|
operations:
|
|
- SELECT
|
|
- INSERT
|
|
- UPDATE
|
|
indices:
|
|
- idx_invoices_company_id
|
|
- idx_invoices_partner_id
|
|
- idx_invoices_type
|
|
- idx_invoices_state
|
|
rls_policy: company_isolation_invoices
|
|
- schema: financial
|
|
table: invoice_lines
|
|
file: "database-design/schemas/financial-schema-ddl.sql"
|
|
operations:
|
|
- SELECT
|
|
- INSERT
|
|
- UPDATE
|
|
- DELETE
|
|
indices:
|
|
- idx_invoice_lines_invoice_id
|
|
- idx_invoice_lines_product_id
|
|
rls_policy: company_isolation_invoice_lines
|
|
|
|
tests:
|
|
backend:
|
|
unit_tests:
|
|
- file: "src/modules/financial/services/vendor-invoice.service.spec.ts"
|
|
test_cases:
|
|
- "should create vendor invoice with lines"
|
|
- "should calculate totals with taxes"
|
|
- "should validate invoice (draft → open)"
|
|
- "should generate journal entry on validation"
|
|
- "should cancel invoice"
|
|
- "should prevent modifying validated invoice"
|
|
integration_tests:
|
|
- file: "test/financial/vendor-invoice.controller.e2e-spec.ts"
|
|
test_cases:
|
|
- "POST /api/v1/financial/vendor-invoices should create invoice"
|
|
- "GET /api/v1/financial/vendor-invoices should return all invoices"
|
|
- "GET /api/v1/financial/vendor-invoices/:id should return invoice with lines"
|
|
- "PUT /api/v1/financial/vendor-invoices/:id should update draft invoice"
|
|
- "POST /api/v1/financial/vendor-invoices/:id/validate should validate invoice"
|
|
- "POST /api/v1/financial/vendor-invoices/:id/cancel should cancel invoice"
|
|
- "should enforce company isolation"
|
|
- "should require authentication"
|
|
frontend:
|
|
component_tests:
|
|
- file: "src/widgets/vendor-invoices-table/ui/VendorInvoicesTable.test.tsx"
|
|
test_cases:
|
|
- "should render table with invoices"
|
|
- "should filter by state"
|
|
- "should handle pagination"
|
|
- file: "src/features/create-vendor-invoice/ui/CreateVendorInvoiceForm.test.tsx"
|
|
test_cases:
|
|
- "should validate required fields"
|
|
- "should calculate totals"
|
|
- "should submit valid form"
|
|
e2e_tests:
|
|
- file: "e2e/financial/vendor-invoices.spec.ts"
|
|
test_cases:
|
|
- "should create vendor invoice successfully"
|
|
- "should validate invoice successfully"
|
|
- "should cancel invoice with confirmation"
|
|
- "should prevent editing validated invoice"
|
|
|
|
acceptance_criteria:
|
|
- id: AC-001
|
|
description: "Usuario puede crear facturas de proveedor con líneas y impuestos"
|
|
status: Pending
|
|
test_reference: "test/financial/vendor-invoice.controller.e2e-spec.ts:28"
|
|
- id: AC-002
|
|
description: "Sistema genera asiento contable al validar factura"
|
|
status: Pending
|
|
test_reference: "src/modules/financial/services/vendor-invoice.service.spec.ts:85"
|
|
- id: AC-003
|
|
description: "Facturas validadas no pueden modificarse"
|
|
status: Pending
|
|
test_reference: "test/financial/vendor-invoice.controller.e2e-spec.ts:125"
|
|
|
|
business_rules:
|
|
- id: RN-001
|
|
description: "Facturas tienen estados: draft, open, paid, cancelled"
|
|
implementation: "database-design/schemas/financial-schema-ddl.sql:invoices.state"
|
|
test_reference: "src/modules/financial/services/vendor-invoice.service.spec.ts:58"
|
|
- id: RN-002
|
|
description: "Al validar factura se genera asiento contable automático"
|
|
implementation: "src/modules/financial/services/vendor-invoice.service.ts:generateJournalEntry()"
|
|
test_reference: "src/modules/financial/services/vendor-invoice.service.spec.ts:92"
|
|
- id: RN-003
|
|
description: "Solo facturas draft pueden modificarse"
|
|
implementation: "src/modules/financial/services/vendor-invoice.service.ts:update()"
|
|
test_reference: "src/modules/financial/services/vendor-invoice.service.spec.ts:118"
|
|
|
|
dependencies:
|
|
rf_dependencies:
|
|
- RF-MGN-004-001
|
|
- RF-MGN-004-002
|
|
- RF-MGN-004-003
|
|
- RF-MGN-004-004
|
|
- RF-MGN-003-001
|
|
module_dependencies:
|
|
- MGN-003
|
|
external_dependencies: []
|
|
|
|
- rf_id: RF-MGN-004-007
|
|
rf_title: "Gestión de Pagos y Conciliación"
|
|
rf_file: "requerimientos-funcionales/mgn-004/RF-MGN-004-007-gestión-de-pagos-y-conciliación.md"
|
|
priority: P0
|
|
story_points: 13
|
|
|
|
et_backend:
|
|
file: "especificaciones-tecnicas/backend/mgn-004/ET-BACKEND-MGN-004-007-gestión-de-pagos-y-conciliación.md"
|
|
endpoints:
|
|
- method: POST
|
|
path: /api/v1/financial/payments
|
|
description: "Registrar pago"
|
|
- method: GET
|
|
path: /api/v1/financial/payments
|
|
description: "Listar pagos"
|
|
- method: GET
|
|
path: /api/v1/financial/payments/:id
|
|
description: "Obtener pago por ID"
|
|
- method: POST
|
|
path: /api/v1/financial/payments/:id/reconcile
|
|
description: "Conciliar pago con factura(s)"
|
|
- method: POST
|
|
path: /api/v1/financial/payments/:id/cancel
|
|
description: "Cancelar pago"
|
|
services:
|
|
- name: "PaymentService"
|
|
file: "src/modules/financial/services/payment.service.ts"
|
|
methods:
|
|
- create
|
|
- findAll
|
|
- findOne
|
|
- reconcile
|
|
- cancel
|
|
- generateJournalEntry
|
|
controllers:
|
|
- name: "PaymentController"
|
|
file: "src/modules/financial/controllers/payment.controller.ts"
|
|
dtos:
|
|
- name: "CreatePaymentDto"
|
|
file: "src/modules/financial/dto/create-payment.dto.ts"
|
|
- name: "ReconcilePaymentDto"
|
|
file: "src/modules/financial/dto/reconcile-payment.dto.ts"
|
|
|
|
et_frontend:
|
|
file: "especificaciones-tecnicas/frontend/mgn-004/ET-FRONTEND-MGN-004-007-gestión-de-pagos-y-conciliación.md"
|
|
routes:
|
|
- path: "/financial/payments"
|
|
component: "PaymentsPage"
|
|
- path: "/financial/payments/create"
|
|
component: "CreatePaymentPage"
|
|
- path: "/financial/payments/:id"
|
|
component: "ViewPaymentPage"
|
|
- path: "/financial/payments/:id/reconcile"
|
|
component: "ReconcilePaymentPage"
|
|
components:
|
|
- name: "PaymentsTable"
|
|
file: "src/widgets/payments-table/ui/PaymentsTable.tsx"
|
|
type: widget
|
|
- name: "CreatePaymentForm"
|
|
file: "src/features/create-payment/ui/CreatePaymentForm.tsx"
|
|
type: feature
|
|
- name: "PaymentCard"
|
|
file: "src/entities/payment/ui/PaymentCard.tsx"
|
|
type: entity
|
|
- name: "ReconcilePaymentForm"
|
|
file: "src/features/reconcile-payment/ui/ReconcilePaymentForm.tsx"
|
|
type: feature
|
|
api_client:
|
|
- name: "paymentApi"
|
|
file: "src/entities/payment/api/payment.api.ts"
|
|
methods:
|
|
- getAll
|
|
- getById
|
|
- create
|
|
- reconcile
|
|
- cancel
|
|
state_management:
|
|
- name: "usePaymentStore"
|
|
file: "src/entities/payment/model/payment.store.ts"
|
|
type: zustand
|
|
|
|
database_tables:
|
|
- schema: financial
|
|
table: payments
|
|
file: "database-design/schemas/financial-schema-ddl.sql"
|
|
operations:
|
|
- SELECT
|
|
- INSERT
|
|
- UPDATE
|
|
indices:
|
|
- idx_payments_company_id
|
|
- idx_payments_partner_id
|
|
- idx_payments_payment_date
|
|
- idx_payments_state
|
|
rls_policy: company_isolation_payments
|
|
- schema: financial
|
|
table: payment_invoice_reconciliations
|
|
file: "database-design/schemas/financial-schema-ddl.sql"
|
|
operations:
|
|
- SELECT
|
|
- INSERT
|
|
- DELETE
|
|
indices:
|
|
- idx_reconciliations_payment_id
|
|
- idx_reconciliations_invoice_id
|
|
rls_policy: company_isolation_reconciliations
|
|
|
|
tests:
|
|
backend:
|
|
unit_tests:
|
|
- file: "src/modules/financial/services/payment.service.spec.ts"
|
|
test_cases:
|
|
- "should create payment"
|
|
- "should reconcile payment with invoice"
|
|
- "should reconcile payment with multiple invoices"
|
|
- "should update invoice state to paid when fully reconciled"
|
|
- "should generate journal entry for payment"
|
|
- "should cancel payment"
|
|
integration_tests:
|
|
- file: "test/financial/payment.controller.e2e-spec.ts"
|
|
test_cases:
|
|
- "POST /api/v1/financial/payments should create payment"
|
|
- "GET /api/v1/financial/payments should return all payments"
|
|
- "GET /api/v1/financial/payments/:id should return payment"
|
|
- "POST /api/v1/financial/payments/:id/reconcile should reconcile payment"
|
|
- "POST /api/v1/financial/payments/:id/cancel should cancel payment"
|
|
- "should enforce company isolation"
|
|
- "should require authentication"
|
|
frontend:
|
|
component_tests:
|
|
- file: "src/widgets/payments-table/ui/PaymentsTable.test.tsx"
|
|
test_cases:
|
|
- "should render table with payments"
|
|
- "should filter by state"
|
|
- file: "src/features/create-payment/ui/CreatePaymentForm.test.tsx"
|
|
test_cases:
|
|
- "should validate required fields"
|
|
- "should submit valid form"
|
|
e2e_tests:
|
|
- file: "e2e/financial/payments.spec.ts"
|
|
test_cases:
|
|
- "should create payment successfully"
|
|
- "should reconcile payment with invoice"
|
|
- "should cancel payment with confirmation"
|
|
- "should show invoice as paid after full reconciliation"
|
|
|
|
acceptance_criteria:
|
|
- id: AC-001
|
|
description: "Usuario puede registrar pagos de clientes y proveedores"
|
|
status: Pending
|
|
test_reference: "test/financial/payment.controller.e2e-spec.ts:28"
|
|
- id: AC-002
|
|
description: "Usuario puede conciliar pagos con facturas"
|
|
status: Pending
|
|
test_reference: "test/financial/payment.controller.e2e-spec.ts:68"
|
|
- id: AC-003
|
|
description: "Factura cambia a estado paid cuando se concilia completamente"
|
|
status: Pending
|
|
test_reference: "src/modules/financial/services/payment.service.spec.ts:95"
|
|
|
|
business_rules:
|
|
- id: RN-001
|
|
description: "Pago puede conciliarse con una o múltiples facturas"
|
|
implementation: "database-design/schemas/financial-schema-ddl.sql:payment_invoice_reconciliations"
|
|
test_reference: "src/modules/financial/services/payment.service.spec.ts:58"
|
|
- id: RN-002
|
|
description: "Factura pasa a paid cuando monto conciliado = monto total"
|
|
implementation: "src/modules/financial/services/payment.service.ts:reconcile()"
|
|
test_reference: "src/modules/financial/services/payment.service.spec.ts:85"
|
|
- id: RN-003
|
|
description: "Al registrar pago se genera asiento contable"
|
|
implementation: "src/modules/financial/services/payment.service.ts:generateJournalEntry()"
|
|
test_reference: "src/modules/financial/services/payment.service.spec.ts:118"
|
|
|
|
dependencies:
|
|
rf_dependencies:
|
|
- RF-MGN-004-003
|
|
- RF-MGN-004-005
|
|
- RF-MGN-004-006
|
|
- RF-MGN-003-001
|
|
module_dependencies:
|
|
- MGN-003
|
|
external_dependencies: []
|
|
|
|
- rf_id: RF-MGN-004-008
|
|
rf_title: "Reportes Financieros (Balance y P&L)"
|
|
rf_file: "requerimientos-funcionales/mgn-004/RF-MGN-004-008-reportes-financieros-balance-y-p&l.md"
|
|
priority: P0
|
|
story_points: 8
|
|
|
|
et_backend:
|
|
file: "especificaciones-tecnicas/backend/mgn-004/ET-BACKEND-MGN-004-008-reportes-financieros-balance-y-p&l.md"
|
|
endpoints:
|
|
- method: GET
|
|
path: /api/v1/financial/reports/balance-sheet
|
|
description: "Generar Balance General"
|
|
- method: GET
|
|
path: /api/v1/financial/reports/profit-loss
|
|
description: "Generar Estado de Resultados (P&L)"
|
|
- method: GET
|
|
path: /api/v1/financial/reports/trial-balance
|
|
description: "Generar Balanza de Comprobación"
|
|
- method: GET
|
|
path: /api/v1/financial/reports/general-ledger
|
|
description: "Generar Libro Mayor"
|
|
services:
|
|
- name: "FinancialReportService"
|
|
file: "src/modules/financial/services/financial-report.service.ts"
|
|
methods:
|
|
- generateBalanceSheet
|
|
- generateProfitLoss
|
|
- generateTrialBalance
|
|
- generateGeneralLedger
|
|
controllers:
|
|
- name: "FinancialReportController"
|
|
file: "src/modules/financial/controllers/financial-report.controller.ts"
|
|
dtos:
|
|
- name: "ReportPeriodDto"
|
|
file: "src/modules/financial/dto/report-period.dto.ts"
|
|
|
|
et_frontend:
|
|
file: "especificaciones-tecnicas/frontend/mgn-004/ET-FRONTEND-MGN-004-008-reportes-financieros-balance-y-p&l.md"
|
|
routes:
|
|
- path: "/financial/reports/balance-sheet"
|
|
component: "BalanceSheetPage"
|
|
- path: "/financial/reports/profit-loss"
|
|
component: "ProfitLossPage"
|
|
- path: "/financial/reports/trial-balance"
|
|
component: "TrialBalancePage"
|
|
- path: "/financial/reports/general-ledger"
|
|
component: "GeneralLedgerPage"
|
|
components:
|
|
- name: "BalanceSheetReport"
|
|
file: "src/widgets/balance-sheet-report/ui/BalanceSheetReport.tsx"
|
|
type: widget
|
|
- name: "ProfitLossReport"
|
|
file: "src/widgets/profit-loss-report/ui/ProfitLossReport.tsx"
|
|
type: widget
|
|
- name: "ReportFilters"
|
|
file: "src/features/report-filters/ui/ReportFilters.tsx"
|
|
type: feature
|
|
api_client:
|
|
- name: "financialReportApi"
|
|
file: "src/entities/financial-report/api/financial-report.api.ts"
|
|
methods:
|
|
- getBalanceSheet
|
|
- getProfitLoss
|
|
- getTrialBalance
|
|
- getGeneralLedger
|
|
state_management:
|
|
- name: "useFinancialReportStore"
|
|
file: "src/entities/financial-report/model/financial-report.store.ts"
|
|
type: zustand
|
|
|
|
database_tables:
|
|
- schema: financial
|
|
table: journal_entry_lines
|
|
file: "database-design/schemas/financial-schema-ddl.sql"
|
|
operations:
|
|
- SELECT
|
|
indices:
|
|
- idx_journal_entry_lines_account_id
|
|
- idx_journal_entry_lines_date
|
|
rls_policy: company_isolation_journal_entry_lines
|
|
|
|
tests:
|
|
backend:
|
|
unit_tests:
|
|
- file: "src/modules/financial/services/financial-report.service.spec.ts"
|
|
test_cases:
|
|
- "should generate balance sheet"
|
|
- "should generate profit & loss"
|
|
- "should filter by date range"
|
|
- "should calculate balances correctly"
|
|
- "should handle hierarchical accounts"
|
|
integration_tests:
|
|
- file: "test/financial/financial-report.controller.e2e-spec.ts"
|
|
test_cases:
|
|
- "GET /api/v1/financial/reports/balance-sheet should return balance sheet"
|
|
- "GET /api/v1/financial/reports/profit-loss should return P&L"
|
|
- "GET /api/v1/financial/reports/trial-balance should return trial balance"
|
|
- "GET /api/v1/financial/reports/general-ledger should return general ledger"
|
|
- "should enforce company isolation"
|
|
- "should require authentication"
|
|
frontend:
|
|
component_tests:
|
|
- file: "src/widgets/balance-sheet-report/ui/BalanceSheetReport.test.tsx"
|
|
test_cases:
|
|
- "should render balance sheet"
|
|
- "should show assets and liabilities"
|
|
- file: "src/widgets/profit-loss-report/ui/ProfitLossReport.test.tsx"
|
|
test_cases:
|
|
- "should render P&L statement"
|
|
- "should show income and expenses"
|
|
e2e_tests:
|
|
- file: "e2e/financial/reports.spec.ts"
|
|
test_cases:
|
|
- "should generate balance sheet successfully"
|
|
- "should generate P&L successfully"
|
|
- "should filter by date range"
|
|
- "should export to PDF"
|
|
|
|
acceptance_criteria:
|
|
- id: AC-001
|
|
description: "Usuario puede generar Balance General por período"
|
|
status: Pending
|
|
test_reference: "test/financial/financial-report.controller.e2e-spec.ts:28"
|
|
- id: AC-002
|
|
description: "Usuario puede generar Estado de Resultados (P&L) por período"
|
|
status: Pending
|
|
test_reference: "test/financial/financial-report.controller.e2e-spec.ts:58"
|
|
- id: AC-003
|
|
description: "Reportes pueden exportarse a PDF y Excel"
|
|
status: Pending
|
|
test_reference: "e2e/financial/reports.spec.ts:85"
|
|
|
|
business_rules:
|
|
- id: RN-001
|
|
description: "Balance Sheet muestra Assets = Liabilities + Equity"
|
|
implementation: "src/modules/financial/services/financial-report.service.ts:generateBalanceSheet()"
|
|
test_reference: "src/modules/financial/services/financial-report.service.spec.ts:58"
|
|
- id: RN-002
|
|
description: "P&L calcula Net Income = Income - Expenses"
|
|
implementation: "src/modules/financial/services/financial-report.service.ts:generateProfitLoss()"
|
|
test_reference: "src/modules/financial/services/financial-report.service.spec.ts:85"
|
|
- id: RN-003
|
|
description: "Reportes filtran por rango de fechas (date_from, date_to)"
|
|
implementation: "src/modules/financial/services/financial-report.service.ts:filterByPeriod()"
|
|
test_reference: "src/modules/financial/services/financial-report.service.spec.ts:108"
|
|
|
|
dependencies:
|
|
rf_dependencies:
|
|
- RF-MGN-004-001
|
|
- RF-MGN-004-003
|
|
- RF-MGN-002-001
|
|
module_dependencies:
|
|
- MGN-002
|
|
external_dependencies:
|
|
- name: "pdfkit"
|
|
version: "^0.13.0"
|
|
- name: "xlsx"
|
|
version: "^0.18.5"
|
|
|
|
coverage:
|
|
rf_to_et_backend: 100%
|
|
rf_to_et_frontend: 100%
|
|
rf_to_database: 100%
|
|
rf_to_tests: 100%
|
|
backend_tests: 100%
|
|
frontend_tests: 100%
|
|
|
|
statistics:
|
|
total_endpoints: 40
|
|
total_components: 32
|
|
total_tables: 12
|
|
total_test_cases: 160
|
|
estimated_duration_sprints: 5
|