# 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 ```sql -- 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 ```sql 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 - [ALCANCE-POR-MODULO.md - MGN-004](../../01-definicion-modulos/ALCANCE-POR-MODULO.md#mgn-004) - [ADR-007: Database Design](../../adr/ADR-007-database-design.md) - [odoo-account-analysis.md](../../00-analisis-referencias/odoo/odoo-account-analysis.md)