erp-core/docs/04-modelado/domain-models/financial-domain.md

9.2 KiB

MODELO DE DOMINIO: Financiero

Módulos: MGN-004 (Financiero Básico) Fecha: 2025-11-24 Referencia Odoo: account Referencia Gamilit: financial_management schema


Diagrama de Entidades (Texto UML)

[Account]
  - id: UUID (PK)
  - tenant_id: UUID (FK)
  - company_id: UUID (FK)
  - code: String
  - name: String
  - account_type: ENUM (asset, liability, equity, income, expense)
  - parent_id: UUID (FK self)
  - currency_id: UUID (FK)

  1 <----> * [JournalEntry]

[Journal]
  - id: UUID (PK)
  - tenant_id: UUID (FK)
  - company_id: UUID (FK)
  - name: String
  - code: String
  - type: ENUM (sales, purchase, bank, cash, general)

  1 <----> * [JournalEntry]

[JournalEntry]
  - id: UUID (PK)
  - tenant_id: UUID (FK)
  - company_id: UUID (FK)
  - journal_id: UUID (FK)
  - name: String
  - date: Date
  - status: ENUM (draft, posted, cancelled)

  1 <----> * [JournalLine]

[JournalLine]
  - id: UUID (PK)
  - entry_id: UUID (FK)
  - account_id: UUID (FK)
  - partner_id: UUID (FK)
  - debit: Decimal
  - credit: Decimal
  - analytic_account_id: UUID (FK)
  - description: String

[Invoice]
  - id: UUID (PK)
  - tenant_id: UUID (FK)
  - company_id: UUID (FK)
  - partner_id: UUID (FK)
  - invoice_type: ENUM (customer, vendor)
  - number: String
  - date: Date
  - due_date: Date
  - status: ENUM (draft, open, paid, cancelled)
  - amount_total: Decimal
  - amount_paid: Decimal
  - journal_entry_id: UUID (FK)

  1 <----> * [InvoiceLine]
  * <----> * [Payment] (through PaymentInvoice)

[InvoiceLine]
  - id: UUID (PK)
  - invoice_id: UUID (FK)
  - product_id: UUID (FK)
  - description: String
  - quantity: Decimal
  - price_unit: Decimal
  - tax_ids: UUID[] (FK array)
  - subtotal: Decimal
  - total: Decimal
  - analytic_account_id: UUID (FK)

[Payment]
  - id: UUID (PK)
  - tenant_id: UUID (FK)
  - company_id: UUID (FK)
  - partner_id: UUID (FK)
  - payment_type: ENUM (inbound, outbound)
  - amount: Decimal
  - date: Date
  - payment_method: ENUM (cash, bank_transfer, check, card)
  - journal_entry_id: UUID (FK)

  * <----> * [Invoice] (through PaymentInvoice)

[PaymentInvoice] (many-to-many)
  - payment_id: UUID (FK)
  - invoice_id: UUID (FK)
  - amount: Decimal

[Tax]
  - id: UUID (PK)
  - tenant_id: UUID (FK)
  - company_id: UUID (FK)
  - name: String
  - code: String
  - rate: Decimal
  - type: ENUM (sales, purchase, all)
  - account_id: UUID (FK)

Entidades Principales

1. Account (Cuenta Contable)

Descripción: Cuenta del plan de cuentas contables.

Atributos:

  • id: UUID
  • code: Código de cuenta (ej: "110.01.001")
  • name: Nombre (ej: "Bancos - BBVA")
  • account_type: Tipo (asset, liability, equity, income, expense)
  • parent_id: Cuenta padre (jerarquía)
  • currency_id: Moneda

Relaciones:

  • 1 Account → N Journal Lines
  • N Accounts → 1 Company

Patrón Odoo: account.account Validaciones:

  • code único por company
  • Cuentas tipo 'view' no pueden tener movimientos

2. Journal (Diario Contable)

Descripción: Diario para agrupar asientos contables por tipo.

Atributos:

  • id: UUID
  • name: Nombre del diario
  • code: Código (ej: "SALES", "BANK")
  • type: Tipo (sales, purchase, bank, cash, general)

Relaciones:

  • 1 Journal → N Journal Entries

Patrón Odoo: account.journal Diarios estándar:

  • Sales Journal (facturas de cliente)
  • Purchase Journal (facturas de proveedor)
  • Bank Journal (movimientos bancarios)
  • Cash Journal (efectivo)
  • Miscellaneous Journal (asientos manuales)

3. JournalEntry (Asiento Contable)

Descripción: Asiento contable con múltiples líneas (débito/crédito).

Atributos:

  • id: UUID
  • journal_id: Diario asociado
  • name: Número de asiento
  • date: Fecha del asiento
  • status: draft, posted, cancelled

Relaciones:

  • 1 JournalEntry → N JournalLines
  • N JournalEntries → 1 Journal

Patrón Odoo: account.move Regla fundamental: SUM(debit) = SUM(credit)

4. JournalLine (Línea de Asiento)

Descripción: Línea individual de un asiento (débito o crédito).

Atributos:

  • id: UUID
  • entry_id: Asiento propietario
  • account_id: Cuenta contable
  • partner_id: Partner (cliente/proveedor)
  • debit: Monto débito
  • credit: Monto crédito
  • analytic_account_id: Cuenta analítica (opcional)

Relaciones:

  • N JournalLines → 1 JournalEntry
  • N JournalLines → 1 Account

Patrón Odoo: account.move.line Validación: En cada línea, debit XOR credit (no ambos)

5. Invoice (Factura)

Descripción: Factura de cliente o proveedor.

Atributos:

  • id: UUID
  • partner_id: Cliente/Proveedor
  • invoice_type: customer, vendor
  • number: Número de factura
  • date: Fecha de emisión
  • due_date: Fecha de vencimiento
  • status: draft, open, paid, cancelled
  • amount_total: Monto total
  • amount_paid: Monto pagado

Relaciones:

  • 1 Invoice → N InvoiceLines
  • 1 Invoice → 1 JournalEntry (al validar)
  • N Invoices ←→ N Payments

Patrón Odoo: account.move (type=invoice) Estados:

  • draft: Borrador (editable)
  • open: Validada (genera asiento)
  • paid: Pagada completamente
  • cancelled: Cancelada

6. InvoiceLine (Línea de Factura)

Descripción: Línea de producto/servicio en factura.

Atributos:

  • id: UUID
  • invoice_id: Factura propietaria
  • product_id: Producto/servicio
  • description: Descripción
  • quantity: Cantidad
  • price_unit: Precio unitario
  • tax_ids: Impuestos aplicados
  • subtotal: Subtotal sin impuestos
  • total: Total con impuestos

Relaciones:

  • N InvoiceLines → 1 Invoice

Patrón Odoo: account.move.line (con invoice_line_id) Cálculo: total = (quantity * price_unit) + taxes

7. Payment (Pago)

Descripción: Registro de pago de cliente o a proveedor.

Atributos:

  • id: UUID
  • partner_id: Cliente/Proveedor
  • payment_type: inbound (cliente), outbound (proveedor)
  • amount: Monto del pago
  • date: Fecha del pago
  • payment_method: cash, bank_transfer, check, card
  • journal_entry_id: Asiento generado

Relaciones:

  • N Payments ←→ N Invoices (reconciliación)
  • 1 Payment → 1 JournalEntry

Patrón Odoo: account.payment Flujo:

  1. Crear payment
  2. Validar payment → genera journal entry
  3. Reconciliar payment con invoice(s)

8. Tax (Impuesto)

Descripción: Configuración de impuestos (IVA, retenciones).

Atributos:

  • id: UUID
  • name: Nombre (ej: "IVA 16%")
  • code: Código (ej: "IVA16")
  • rate: Tasa (0.16 para 16%)
  • type: sales, purchase, all
  • account_id: Cuenta contable para impuesto

Relaciones:

  • N Taxes → N InvoiceLines

Patrón Odoo: account.tax Impuestos comunes México:

  • IVA 16% (ventas y compras)
  • IVA 8% (zona frontera)
  • Retención IVA 10.67%
  • Retención ISR 10%

Reglas de Negocio

RN-FIN-001: Balance de Asientos

  • TODO asiento debe cumplir: SUM(debit) = SUM(credit)
  • Validación obligatoria antes de posted

RN-FIN-002: Asientos Inmutables

  • Asientos con status=posted NO pueden editarse
  • Para corregir: crear asiento de reversa

RN-FIN-003: Generación Automática de Asientos

  • Validar factura → genera journal entry automáticamente
  • Validar pago → genera journal entry automáticamente

RN-FIN-004: Multi-Moneda

  • Transacciones en moneda extranjera se convierten a moneda de company
  • Usar tasa de cambio del día de la transacción
  • Gain/Loss se registra en cuenta especial

RN-FIN-005: Conciliación de Pagos

  • Payment puede aplicarse a múltiples invoices (parcial)
  • Invoice puede recibir múltiples payments
  • amount_paid se actualiza automáticamente

Casos de Uso Principales

  1. UC-FIN-001: Contador crea asiento contable manual
  2. UC-FIN-002: Usuario crea factura de cliente
  3. UC-FIN-003: Sistema genera asiento al validar factura
  4. UC-FIN-004: Usuario registra pago de cliente
  5. UC-FIN-005: Usuario concilia pago con facturas
  6. UC-FIN-006: Contador genera Balance General
  7. UC-FIN-007: Contador genera Estado de Resultados
  8. UC-FIN-008: Usuario crea factura en USD (empresa en MXN)

Validaciones y Constraints

-- Asiento balanceado
CHECK (SUM(debit) = SUM(credit) per entry_id)

-- Debit XOR Credit (no ambos)
CHECK ((debit > 0 AND credit = 0) OR (credit > 0 AND debit = 0))

-- Invoice number único por company y tipo
UNIQUE (tenant_id, company_id, invoice_type, number)

-- Status transitions válidos
-- (implementar con state machine)

Índices Requeridos

CREATE INDEX idx_accounts_company_id ON financial.accounts(company_id);
CREATE INDEX idx_accounts_code ON financial.accounts(code);
CREATE INDEX idx_journal_entries_company_id ON financial.journal_entries(company_id);
CREATE INDEX idx_journal_entries_date ON financial.journal_entries(date);
CREATE INDEX idx_journal_lines_account_id ON financial.journal_lines(account_id);
CREATE INDEX idx_invoices_partner_id ON financial.invoices(partner_id);
CREATE INDEX idx_invoices_status ON financial.invoices(status);
CREATE INDEX idx_payments_partner_id ON financial.payments(partner_id);

Referencias