- chart_of_accounts: Catalogo de cuentas contables con jerarquia - accounting_entries: Polizas contables - accounting_entry_lines: Lineas de poliza - accounts_payable: Cuentas por pagar - accounts_receivable: Cuentas por cobrar - bank_accounts: Cuentas bancarias - bank_movements: Movimientos bancarios - bank_reconciliations: Conciliacion bancaria - ap_payments: Pagos a proveedores - ar_payments: Cobros de clientes - cash_flow_projections: Flujo de efectivo Includes: RLS, indices, triggers, audit functions Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1236 lines
40 KiB
PL/PgSQL
1236 lines
40 KiB
PL/PgSQL
-- ============================================================================
|
|
-- 08-finance-schema-ddl.sql
|
|
-- Schema: finance
|
|
-- ERP Construccion - Modulo Finanzas y Controlling (MAE-014)
|
|
-- ============================================================================
|
|
-- Descripcion: Gestion financiera completa incluyendo:
|
|
-- - Catalogo de cuentas contables (Chart of Accounts)
|
|
-- - Polizas contables (Journal Entries)
|
|
-- - Cuentas por pagar (Accounts Payable)
|
|
-- - Cuentas por cobrar (Accounts Receivable)
|
|
-- - Cuentas bancarias y movimientos
|
|
-- - Conciliacion bancaria
|
|
-- - Proyecciones de flujo de efectivo
|
|
-- ============================================================================
|
|
-- Autor: Claude-Arquitecto-Orquestador
|
|
-- Fecha: 2026-01-25
|
|
-- Version: 1.0.0
|
|
-- ============================================================================
|
|
|
|
-- Crear schema si no existe
|
|
CREATE SCHEMA IF NOT EXISTS finance;
|
|
|
|
-- ============================================================================
|
|
-- ENUMS
|
|
-- ============================================================================
|
|
|
|
-- Tipo de cuenta contable
|
|
CREATE TYPE finance.account_type AS ENUM (
|
|
'asset', -- Activo
|
|
'liability', -- Pasivo
|
|
'equity', -- Capital
|
|
'income', -- Ingreso
|
|
'expense' -- Gasto
|
|
);
|
|
|
|
-- Naturaleza de cuenta (deudora/acreedora)
|
|
CREATE TYPE finance.account_nature AS ENUM (
|
|
'debit', -- Deudora
|
|
'credit' -- Acreedora
|
|
);
|
|
|
|
-- Estado de cuenta contable
|
|
CREATE TYPE finance.account_status AS ENUM (
|
|
'active', -- Activa
|
|
'inactive', -- Inactiva
|
|
'blocked' -- Bloqueada
|
|
);
|
|
|
|
-- Tipo de poliza contable
|
|
CREATE TYPE finance.entry_type AS ENUM (
|
|
'purchase', -- Compra
|
|
'sale', -- Venta
|
|
'payment', -- Pago
|
|
'collection', -- Cobro
|
|
'payroll', -- Nomina
|
|
'adjustment', -- Ajuste
|
|
'depreciation', -- Depreciacion
|
|
'transfer', -- Traspaso
|
|
'opening', -- Apertura
|
|
'closing' -- Cierre
|
|
);
|
|
|
|
-- Estado de poliza contable
|
|
CREATE TYPE finance.entry_status AS ENUM (
|
|
'draft', -- Borrador
|
|
'pending_approval', -- Pendiente de aprobacion
|
|
'approved', -- Aprobada
|
|
'posted', -- Contabilizada
|
|
'cancelled', -- Cancelada
|
|
'reversed' -- Reversada
|
|
);
|
|
|
|
-- Tipo de documento CxP
|
|
CREATE TYPE finance.ap_document_type AS ENUM (
|
|
'invoice', -- Factura
|
|
'credit_note', -- Nota de credito
|
|
'debit_note', -- Nota de debito
|
|
'advance', -- Anticipo
|
|
'retention' -- Retencion
|
|
);
|
|
|
|
-- Estado de CxP
|
|
CREATE TYPE finance.ap_status AS ENUM (
|
|
'pending', -- Pendiente
|
|
'partial', -- Parcialmente pagado
|
|
'paid', -- Pagado
|
|
'overdue', -- Vencido
|
|
'cancelled', -- Cancelado
|
|
'disputed' -- En disputa
|
|
);
|
|
|
|
-- Tipo de documento CxC
|
|
CREATE TYPE finance.ar_document_type AS ENUM (
|
|
'invoice', -- Factura
|
|
'credit_note', -- Nota de credito
|
|
'debit_note', -- Nota de debito
|
|
'advance', -- Anticipo
|
|
'estimation' -- Estimacion
|
|
);
|
|
|
|
-- Estado de CxC
|
|
CREATE TYPE finance.ar_status AS ENUM (
|
|
'pending', -- Pendiente
|
|
'partial', -- Parcialmente cobrado
|
|
'collected', -- Cobrado
|
|
'overdue', -- Vencido
|
|
'cancelled', -- Cancelado
|
|
'written_off' -- Incobrable
|
|
);
|
|
|
|
-- Tipo de cuenta bancaria
|
|
CREATE TYPE finance.bank_account_type AS ENUM (
|
|
'checking', -- Cuenta de cheques
|
|
'savings', -- Cuenta de ahorro
|
|
'investment', -- Inversion
|
|
'credit_line', -- Linea de credito
|
|
'other' -- Otro
|
|
);
|
|
|
|
-- Estado de cuenta bancaria
|
|
CREATE TYPE finance.bank_account_status AS ENUM (
|
|
'active', -- Activa
|
|
'inactive', -- Inactiva
|
|
'blocked', -- Bloqueada
|
|
'closed' -- Cerrada
|
|
);
|
|
|
|
-- Tipo de movimiento bancario
|
|
CREATE TYPE finance.bank_movement_type AS ENUM (
|
|
'debit', -- Cargo
|
|
'credit' -- Abono
|
|
);
|
|
|
|
-- Estado de movimiento bancario
|
|
CREATE TYPE finance.bank_movement_status AS ENUM (
|
|
'pending', -- Pendiente
|
|
'matched', -- Coincidente
|
|
'reconciled', -- Conciliado
|
|
'unreconciled', -- No conciliado
|
|
'ignored' -- Ignorado
|
|
);
|
|
|
|
-- Origen de movimiento bancario
|
|
CREATE TYPE finance.bank_movement_source AS ENUM (
|
|
'manual', -- Manual
|
|
'import_file', -- Importacion de archivo
|
|
'api', -- API bancaria
|
|
'system' -- Sistema
|
|
);
|
|
|
|
-- Metodo de pago
|
|
CREATE TYPE finance.payment_method AS ENUM (
|
|
'cash', -- Efectivo
|
|
'check', -- Cheque
|
|
'transfer', -- Transferencia
|
|
'card', -- Tarjeta
|
|
'compensation', -- Compensacion
|
|
'other' -- Otro
|
|
);
|
|
|
|
-- Estado de pago (CxP)
|
|
CREATE TYPE finance.payment_status AS ENUM (
|
|
'pending', -- Pendiente
|
|
'processed', -- Procesado
|
|
'reconciled', -- Conciliado
|
|
'cancelled', -- Cancelado
|
|
'returned' -- Devuelto
|
|
);
|
|
|
|
-- Metodo de cobro
|
|
CREATE TYPE finance.collection_method AS ENUM (
|
|
'cash', -- Efectivo
|
|
'check', -- Cheque
|
|
'transfer', -- Transferencia
|
|
'card', -- Tarjeta
|
|
'compensation', -- Compensacion
|
|
'other' -- Otro
|
|
);
|
|
|
|
-- Estado de cobro (CxC)
|
|
CREATE TYPE finance.collection_status AS ENUM (
|
|
'pending', -- Pendiente
|
|
'deposited', -- Depositado
|
|
'reconciled', -- Conciliado
|
|
'cancelled', -- Cancelado
|
|
'returned' -- Devuelto
|
|
);
|
|
|
|
-- Estado de conciliacion
|
|
CREATE TYPE finance.reconciliation_status AS ENUM (
|
|
'draft', -- Borrador
|
|
'in_progress', -- En proceso
|
|
'completed', -- Completada
|
|
'approved', -- Aprobada
|
|
'cancelled' -- Cancelada
|
|
);
|
|
|
|
-- Tipo de flujo de efectivo
|
|
CREATE TYPE finance.cash_flow_type AS ENUM (
|
|
'projected', -- Proyectado
|
|
'actual', -- Real
|
|
'comparison' -- Comparativo
|
|
);
|
|
|
|
-- Tipo de periodo de flujo
|
|
CREATE TYPE finance.cash_flow_period_type AS ENUM (
|
|
'daily', -- Diario
|
|
'weekly', -- Semanal
|
|
'monthly', -- Mensual
|
|
'quarterly' -- Trimestral
|
|
);
|
|
|
|
-- ============================================================================
|
|
-- TABLAS
|
|
-- ============================================================================
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
-- 1. Catalogo de Cuentas Contables (Chart of Accounts)
|
|
-- ----------------------------------------------------------------------------
|
|
CREATE TABLE finance.chart_of_accounts (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL,
|
|
|
|
-- Codigo jerarquico de cuenta
|
|
code VARCHAR(50) NOT NULL,
|
|
name VARCHAR(255) NOT NULL,
|
|
description TEXT,
|
|
|
|
-- Tipo y naturaleza
|
|
account_type finance.account_type NOT NULL,
|
|
nature finance.account_nature NOT NULL,
|
|
status finance.account_status NOT NULL DEFAULT 'active',
|
|
|
|
-- Jerarquia
|
|
level INTEGER NOT NULL DEFAULT 1,
|
|
parent_id UUID REFERENCES finance.chart_of_accounts(id),
|
|
|
|
-- Configuracion de imputacion
|
|
cost_center_required BOOLEAN NOT NULL DEFAULT FALSE,
|
|
project_required BOOLEAN NOT NULL DEFAULT FALSE,
|
|
allows_direct_posting BOOLEAN NOT NULL DEFAULT TRUE,
|
|
|
|
-- Codigos de integracion con ERPs externos
|
|
sap_code VARCHAR(50),
|
|
contpaqi_code VARCHAR(50),
|
|
aspel_code VARCHAR(50),
|
|
|
|
-- Saldos (actualizados periodicamente)
|
|
initial_balance DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
current_balance DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
balance_updated_at TIMESTAMPTZ,
|
|
|
|
-- Notas y metadatos
|
|
notes TEXT,
|
|
metadata JSONB,
|
|
|
|
-- Auditoria
|
|
created_by UUID,
|
|
updated_by UUID,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
deleted_at TIMESTAMPTZ,
|
|
|
|
-- Constraints
|
|
CONSTRAINT uq_chart_of_accounts_tenant_code UNIQUE (tenant_id, code)
|
|
);
|
|
|
|
-- Tabla de closure para jerarquia (TypeORM Tree closure-table)
|
|
CREATE TABLE finance.chart_of_accounts_closure (
|
|
id_ancestor UUID NOT NULL REFERENCES finance.chart_of_accounts(id) ON DELETE CASCADE,
|
|
id_descendant UUID NOT NULL REFERENCES finance.chart_of_accounts(id) ON DELETE CASCADE,
|
|
PRIMARY KEY (id_ancestor, id_descendant)
|
|
);
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
-- 2. Polizas Contables (Accounting Entries)
|
|
-- ----------------------------------------------------------------------------
|
|
CREATE TABLE finance.accounting_entries (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL,
|
|
|
|
-- Numero de poliza
|
|
entry_number VARCHAR(50) NOT NULL,
|
|
|
|
-- Tipo y fecha
|
|
entry_type finance.entry_type NOT NULL,
|
|
entry_date DATE NOT NULL,
|
|
status finance.entry_status NOT NULL DEFAULT 'draft',
|
|
|
|
-- Descripcion
|
|
description TEXT NOT NULL,
|
|
reference VARCHAR(255),
|
|
|
|
-- Origen (modulo que genero la poliza)
|
|
source_module VARCHAR(50),
|
|
source_id UUID,
|
|
|
|
-- Proyecto asociado
|
|
project_id UUID,
|
|
|
|
-- Periodo contable
|
|
fiscal_year INTEGER NOT NULL,
|
|
fiscal_period INTEGER NOT NULL,
|
|
|
|
-- Totales (calculados)
|
|
total_debit DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
total_credit DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
is_balanced BOOLEAN NOT NULL DEFAULT FALSE,
|
|
|
|
-- Moneda
|
|
currency VARCHAR(3) NOT NULL DEFAULT 'MXN',
|
|
exchange_rate DECIMAL(12,6) NOT NULL DEFAULT 1,
|
|
|
|
-- Aprobacion
|
|
approved_by_id UUID,
|
|
approved_at TIMESTAMPTZ,
|
|
|
|
-- Contabilizacion
|
|
posted_at TIMESTAMPTZ,
|
|
posted_by_id UUID,
|
|
|
|
-- Reversion
|
|
reversed_entry_id UUID REFERENCES finance.accounting_entries(id),
|
|
reversal_reason TEXT,
|
|
|
|
-- Notas y metadatos
|
|
notes TEXT,
|
|
metadata JSONB,
|
|
|
|
-- Auditoria
|
|
created_by UUID,
|
|
updated_by UUID,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
deleted_at TIMESTAMPTZ,
|
|
|
|
-- Constraints
|
|
CONSTRAINT uq_accounting_entries_tenant_number UNIQUE (tenant_id, entry_number)
|
|
);
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
-- 3. Lineas de Poliza Contable (Accounting Entry Lines)
|
|
-- ----------------------------------------------------------------------------
|
|
CREATE TABLE finance.accounting_entry_lines (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL,
|
|
|
|
-- Referencia a la poliza
|
|
entry_id UUID NOT NULL REFERENCES finance.accounting_entries(id) ON DELETE CASCADE,
|
|
|
|
-- Numero de linea
|
|
line_number INTEGER NOT NULL,
|
|
|
|
-- Cuenta contable
|
|
account_id UUID NOT NULL REFERENCES finance.chart_of_accounts(id),
|
|
account_code VARCHAR(50) NOT NULL,
|
|
|
|
-- Descripcion de la linea
|
|
description TEXT NOT NULL,
|
|
|
|
-- Montos
|
|
debit DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
credit DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
|
|
-- Centro de costo (opcional)
|
|
cost_center_id UUID,
|
|
cost_center_code VARCHAR(50),
|
|
|
|
-- Proyecto (opcional)
|
|
project_id UUID,
|
|
project_code VARCHAR(50),
|
|
|
|
-- Tercero (proveedor/cliente)
|
|
partner_id UUID,
|
|
partner_name VARCHAR(255),
|
|
|
|
-- Documento de referencia
|
|
document_type VARCHAR(50),
|
|
document_number VARCHAR(100),
|
|
|
|
-- Moneda original (si es diferente)
|
|
original_currency VARCHAR(3),
|
|
original_amount DECIMAL(18,2),
|
|
|
|
-- Metadatos
|
|
metadata JSONB,
|
|
|
|
-- Auditoria
|
|
created_by UUID,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
-- 4. Cuentas por Pagar (Accounts Payable)
|
|
-- ----------------------------------------------------------------------------
|
|
CREATE TABLE finance.accounts_payable (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL,
|
|
|
|
-- Numero de documento
|
|
document_number VARCHAR(100) NOT NULL,
|
|
document_type finance.ap_document_type NOT NULL DEFAULT 'invoice',
|
|
|
|
-- Proveedor
|
|
supplier_id UUID NOT NULL,
|
|
supplier_name VARCHAR(255) NOT NULL,
|
|
supplier_rfc VARCHAR(13),
|
|
|
|
-- Estado
|
|
status finance.ap_status NOT NULL DEFAULT 'pending',
|
|
|
|
-- Fechas
|
|
invoice_date DATE NOT NULL,
|
|
received_date DATE,
|
|
due_date DATE NOT NULL,
|
|
payment_date DATE,
|
|
|
|
-- Montos
|
|
subtotal DECIMAL(18,2) NOT NULL,
|
|
tax_amount DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
retention_amount DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
total_amount DECIMAL(18,2) NOT NULL,
|
|
paid_amount DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
balance DECIMAL(18,2) NOT NULL,
|
|
|
|
-- Moneda
|
|
currency VARCHAR(3) NOT NULL DEFAULT 'MXN',
|
|
exchange_rate DECIMAL(12,6) NOT NULL DEFAULT 1,
|
|
|
|
-- Origen (orden de compra, contrato)
|
|
source_module VARCHAR(50),
|
|
source_id UUID,
|
|
purchase_order_number VARCHAR(50),
|
|
|
|
-- Proyecto asociado
|
|
project_id UUID,
|
|
project_code VARCHAR(50),
|
|
|
|
-- Centro de costo
|
|
cost_center_id UUID,
|
|
|
|
-- Cuenta contable de contrapartida
|
|
expense_account_id UUID REFERENCES finance.chart_of_accounts(id),
|
|
|
|
-- Condiciones de pago
|
|
payment_terms VARCHAR(100),
|
|
payment_days INTEGER NOT NULL DEFAULT 30,
|
|
|
|
-- Dias de atraso (calculado)
|
|
days_overdue INTEGER NOT NULL DEFAULT 0,
|
|
|
|
-- CFDI (facturacion electronica Mexico)
|
|
cfdi_uuid VARCHAR(36),
|
|
cfdi_xml_path VARCHAR(500),
|
|
cfdi_pdf_path VARCHAR(500),
|
|
|
|
-- Aprobacion
|
|
approved_for_payment BOOLEAN NOT NULL DEFAULT FALSE,
|
|
approved_by_id UUID,
|
|
approved_at TIMESTAMPTZ,
|
|
|
|
-- Poliza contable generada
|
|
accounting_entry_id UUID REFERENCES finance.accounting_entries(id),
|
|
|
|
-- Notas y metadatos
|
|
notes TEXT,
|
|
metadata JSONB,
|
|
|
|
-- Auditoria
|
|
created_by UUID,
|
|
updated_by UUID,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
deleted_at TIMESTAMPTZ
|
|
);
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
-- 5. Cuentas por Cobrar (Accounts Receivable)
|
|
-- ----------------------------------------------------------------------------
|
|
CREATE TABLE finance.accounts_receivable (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL,
|
|
|
|
-- Numero de documento
|
|
document_number VARCHAR(100) NOT NULL,
|
|
document_type finance.ar_document_type NOT NULL DEFAULT 'invoice',
|
|
|
|
-- Cliente
|
|
customer_id UUID NOT NULL,
|
|
customer_name VARCHAR(255) NOT NULL,
|
|
customer_rfc VARCHAR(13),
|
|
|
|
-- Estado
|
|
status finance.ar_status NOT NULL DEFAULT 'pending',
|
|
|
|
-- Fechas
|
|
invoice_date DATE NOT NULL,
|
|
due_date DATE NOT NULL,
|
|
collection_date DATE,
|
|
|
|
-- Montos
|
|
subtotal DECIMAL(18,2) NOT NULL,
|
|
tax_amount DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
retention_amount DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
total_amount DECIMAL(18,2) NOT NULL,
|
|
collected_amount DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
balance DECIMAL(18,2) NOT NULL,
|
|
|
|
-- Moneda
|
|
currency VARCHAR(3) NOT NULL DEFAULT 'MXN',
|
|
exchange_rate DECIMAL(12,6) NOT NULL DEFAULT 1,
|
|
|
|
-- Origen (estimacion, venta)
|
|
source_module VARCHAR(50),
|
|
source_id UUID,
|
|
estimation_number VARCHAR(50),
|
|
|
|
-- Proyecto asociado
|
|
project_id UUID,
|
|
project_code VARCHAR(50),
|
|
|
|
-- Condiciones de cobro
|
|
payment_terms VARCHAR(100),
|
|
payment_days INTEGER NOT NULL DEFAULT 30,
|
|
|
|
-- Dias de atraso (calculado)
|
|
days_overdue INTEGER NOT NULL DEFAULT 0,
|
|
|
|
-- CFDI (facturacion electronica Mexico)
|
|
cfdi_uuid VARCHAR(36),
|
|
cfdi_xml_path VARCHAR(500),
|
|
cfdi_pdf_path VARCHAR(500),
|
|
|
|
-- Cuenta contable
|
|
income_account_id UUID REFERENCES finance.chart_of_accounts(id),
|
|
|
|
-- Poliza contable generada
|
|
accounting_entry_id UUID REFERENCES finance.accounting_entries(id),
|
|
|
|
-- Seguimiento de cobranza
|
|
last_collection_attempt DATE,
|
|
collection_attempts INTEGER NOT NULL DEFAULT 0,
|
|
collection_notes TEXT,
|
|
|
|
-- Notas y metadatos
|
|
notes TEXT,
|
|
metadata JSONB,
|
|
|
|
-- Auditoria
|
|
created_by UUID,
|
|
updated_by UUID,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
deleted_at TIMESTAMPTZ
|
|
);
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
-- 6. Cuentas Bancarias (Bank Accounts)
|
|
-- ----------------------------------------------------------------------------
|
|
CREATE TABLE finance.bank_accounts (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL,
|
|
|
|
-- Informacion de la cuenta
|
|
name VARCHAR(100) NOT NULL,
|
|
account_number VARCHAR(50) NOT NULL,
|
|
clabe VARCHAR(18),
|
|
account_type finance.bank_account_type NOT NULL DEFAULT 'checking',
|
|
status finance.bank_account_status NOT NULL DEFAULT 'active',
|
|
|
|
-- Banco
|
|
bank_name VARCHAR(100) NOT NULL,
|
|
bank_code VARCHAR(10),
|
|
branch_name VARCHAR(100),
|
|
branch_code VARCHAR(20),
|
|
|
|
-- Moneda
|
|
currency VARCHAR(3) NOT NULL DEFAULT 'MXN',
|
|
|
|
-- Saldos
|
|
initial_balance DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
current_balance DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
available_balance DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
balance_updated_at TIMESTAMPTZ,
|
|
|
|
-- Limites (para lineas de credito)
|
|
credit_limit DECIMAL(18,2),
|
|
minimum_balance DECIMAL(18,2),
|
|
|
|
-- Proyecto asociado (si es cuenta especifica de proyecto)
|
|
project_id UUID,
|
|
project_code VARCHAR(50),
|
|
|
|
-- Cuenta contable vinculada
|
|
ledger_account_id UUID REFERENCES finance.chart_of_accounts(id),
|
|
|
|
-- Contacto del banco
|
|
bank_contact_name VARCHAR(255),
|
|
bank_contact_phone VARCHAR(50),
|
|
bank_contact_email VARCHAR(255),
|
|
|
|
-- Conciliacion
|
|
last_reconciliation_date DATE,
|
|
last_reconciled_balance DECIMAL(18,2),
|
|
|
|
-- Acceso banca en linea
|
|
online_banking_user VARCHAR(100),
|
|
supports_api BOOLEAN NOT NULL DEFAULT FALSE,
|
|
|
|
-- Flags
|
|
is_default BOOLEAN NOT NULL DEFAULT FALSE,
|
|
allows_payments BOOLEAN NOT NULL DEFAULT TRUE,
|
|
allows_collections BOOLEAN NOT NULL DEFAULT TRUE,
|
|
|
|
-- Notas y metadatos
|
|
notes TEXT,
|
|
metadata JSONB,
|
|
|
|
-- Auditoria
|
|
created_by UUID,
|
|
updated_by UUID,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
deleted_at TIMESTAMPTZ,
|
|
|
|
-- Constraints
|
|
CONSTRAINT uq_bank_accounts_tenant_number UNIQUE (tenant_id, account_number)
|
|
);
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
-- 7. Movimientos Bancarios (Bank Movements)
|
|
-- ----------------------------------------------------------------------------
|
|
CREATE TABLE finance.bank_movements (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL,
|
|
|
|
-- Cuenta bancaria
|
|
bank_account_id UUID NOT NULL REFERENCES finance.bank_accounts(id),
|
|
|
|
-- Referencia del movimiento
|
|
movement_reference VARCHAR(100),
|
|
bank_reference VARCHAR(100),
|
|
|
|
-- Tipo y fecha
|
|
movement_type finance.bank_movement_type NOT NULL,
|
|
movement_date DATE NOT NULL,
|
|
value_date DATE,
|
|
|
|
-- Descripcion del banco
|
|
description TEXT NOT NULL,
|
|
bank_description TEXT,
|
|
|
|
-- Monto
|
|
amount DECIMAL(18,2) NOT NULL,
|
|
currency VARCHAR(3) NOT NULL DEFAULT 'MXN',
|
|
|
|
-- Saldo despues del movimiento
|
|
balance_after DECIMAL(18,2),
|
|
|
|
-- Estado de conciliacion
|
|
status finance.bank_movement_status NOT NULL DEFAULT 'pending',
|
|
|
|
-- Origen del movimiento
|
|
source finance.bank_movement_source NOT NULL DEFAULT 'manual',
|
|
import_batch_id UUID,
|
|
|
|
-- Coincidencia automatica
|
|
matched_payment_id UUID,
|
|
matched_collection_id UUID,
|
|
matched_entry_id UUID REFERENCES finance.accounting_entries(id),
|
|
match_confidence DECIMAL(5,2),
|
|
|
|
-- Conciliacion
|
|
reconciliation_id UUID,
|
|
reconciled_at TIMESTAMPTZ,
|
|
reconciled_by_id UUID,
|
|
|
|
-- Categorizacion
|
|
category VARCHAR(100),
|
|
subcategory VARCHAR(100),
|
|
|
|
-- Tercero identificado
|
|
partner_id UUID,
|
|
partner_name VARCHAR(255),
|
|
|
|
-- Flags
|
|
is_duplicate BOOLEAN NOT NULL DEFAULT FALSE,
|
|
requires_review BOOLEAN NOT NULL DEFAULT FALSE,
|
|
|
|
-- Notas y metadatos
|
|
notes TEXT,
|
|
metadata JSONB,
|
|
|
|
-- Datos originales del banco
|
|
raw_data JSONB,
|
|
|
|
-- Auditoria
|
|
created_by UUID,
|
|
updated_by UUID,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
-- 8. Conciliaciones Bancarias (Bank Reconciliations)
|
|
-- ----------------------------------------------------------------------------
|
|
CREATE TABLE finance.bank_reconciliations (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL,
|
|
|
|
-- Cuenta bancaria
|
|
bank_account_id UUID NOT NULL REFERENCES finance.bank_accounts(id),
|
|
|
|
-- Periodo de conciliacion
|
|
period_start DATE NOT NULL,
|
|
period_end DATE NOT NULL,
|
|
|
|
-- Estado
|
|
status finance.reconciliation_status NOT NULL DEFAULT 'draft',
|
|
|
|
-- Saldos segun banco
|
|
bank_opening_balance DECIMAL(18,2) NOT NULL,
|
|
bank_closing_balance DECIMAL(18,2) NOT NULL,
|
|
|
|
-- Saldos segun libros
|
|
book_opening_balance DECIMAL(18,2) NOT NULL,
|
|
book_closing_balance DECIMAL(18,2) NOT NULL,
|
|
|
|
-- Partidas de conciliacion
|
|
deposits_in_transit DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
checks_in_transit DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
bank_charges_not_recorded DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
interest_not_recorded DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
other_adjustments DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
|
|
-- Saldo conciliado
|
|
reconciled_balance DECIMAL(18,2) NOT NULL,
|
|
|
|
-- Diferencia (debe ser 0 si esta conciliado)
|
|
difference DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
is_balanced BOOLEAN NOT NULL DEFAULT FALSE,
|
|
|
|
-- Contadores
|
|
total_movements INTEGER NOT NULL DEFAULT 0,
|
|
reconciled_movements INTEGER NOT NULL DEFAULT 0,
|
|
pending_movements INTEGER NOT NULL DEFAULT 0,
|
|
|
|
-- Estado de cuenta bancario (archivo importado)
|
|
statement_file_path VARCHAR(500),
|
|
statement_import_date TIMESTAMPTZ,
|
|
|
|
-- Fechas de proceso
|
|
started_at TIMESTAMPTZ,
|
|
completed_at TIMESTAMPTZ,
|
|
|
|
-- Aprobacion
|
|
approved_by_id UUID,
|
|
approved_at TIMESTAMPTZ,
|
|
|
|
-- Poliza de ajuste generada
|
|
adjustment_entry_id UUID REFERENCES finance.accounting_entries(id),
|
|
|
|
-- Notas y metadatos
|
|
notes TEXT,
|
|
reconciliation_items JSONB,
|
|
metadata JSONB,
|
|
|
|
-- Auditoria
|
|
created_by UUID,
|
|
updated_by UUID,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
deleted_at TIMESTAMPTZ
|
|
);
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
-- 9. Pagos a Proveedores (AP Payments)
|
|
-- ----------------------------------------------------------------------------
|
|
CREATE TABLE finance.ap_payments (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL,
|
|
|
|
-- Numero de pago
|
|
payment_number VARCHAR(50) NOT NULL,
|
|
|
|
-- Cuenta por pagar asociada
|
|
account_payable_id UUID NOT NULL REFERENCES finance.accounts_payable(id),
|
|
|
|
-- Metodo de pago
|
|
payment_method finance.payment_method NOT NULL,
|
|
status finance.payment_status NOT NULL DEFAULT 'pending',
|
|
|
|
-- Fecha de pago
|
|
payment_date DATE NOT NULL,
|
|
|
|
-- Monto
|
|
amount DECIMAL(18,2) NOT NULL,
|
|
currency VARCHAR(3) NOT NULL DEFAULT 'MXN',
|
|
exchange_rate DECIMAL(12,6) NOT NULL DEFAULT 1,
|
|
|
|
-- Cuenta bancaria de origen
|
|
bank_account_id UUID REFERENCES finance.bank_accounts(id),
|
|
|
|
-- Detalles del instrumento de pago
|
|
check_number VARCHAR(50),
|
|
transfer_reference VARCHAR(100),
|
|
authorization_code VARCHAR(50),
|
|
|
|
-- Beneficiario
|
|
beneficiary_name VARCHAR(255),
|
|
beneficiary_bank VARCHAR(100),
|
|
beneficiary_account VARCHAR(50),
|
|
beneficiary_clabe VARCHAR(18),
|
|
|
|
-- Poliza contable generada
|
|
accounting_entry_id UUID REFERENCES finance.accounting_entries(id),
|
|
|
|
-- Conciliacion bancaria
|
|
bank_movement_id UUID REFERENCES finance.bank_movements(id),
|
|
reconciled_at TIMESTAMPTZ,
|
|
|
|
-- Notas y metadatos
|
|
notes TEXT,
|
|
metadata JSONB,
|
|
|
|
-- Auditoria
|
|
created_by UUID,
|
|
updated_by UUID,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
deleted_at TIMESTAMPTZ
|
|
);
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
-- 10. Cobros de Clientes (AR Payments)
|
|
-- ----------------------------------------------------------------------------
|
|
CREATE TABLE finance.ar_payments (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL,
|
|
|
|
-- Numero de cobro
|
|
collection_number VARCHAR(50) NOT NULL,
|
|
|
|
-- Cuenta por cobrar asociada
|
|
account_receivable_id UUID NOT NULL REFERENCES finance.accounts_receivable(id),
|
|
|
|
-- Metodo de cobro
|
|
collection_method finance.collection_method NOT NULL,
|
|
status finance.collection_status NOT NULL DEFAULT 'pending',
|
|
|
|
-- Fecha de cobro
|
|
collection_date DATE NOT NULL,
|
|
deposit_date DATE,
|
|
|
|
-- Monto
|
|
amount DECIMAL(18,2) NOT NULL,
|
|
currency VARCHAR(3) NOT NULL DEFAULT 'MXN',
|
|
exchange_rate DECIMAL(12,6) NOT NULL DEFAULT 1,
|
|
|
|
-- Cuenta bancaria de destino
|
|
bank_account_id UUID REFERENCES finance.bank_accounts(id),
|
|
|
|
-- Detalles del instrumento de cobro
|
|
check_number VARCHAR(50),
|
|
check_bank VARCHAR(100),
|
|
transfer_reference VARCHAR(100),
|
|
|
|
-- Pagador (si es diferente al cliente)
|
|
payer_name VARCHAR(255),
|
|
payer_bank VARCHAR(100),
|
|
payer_account VARCHAR(50),
|
|
|
|
-- Poliza contable generada
|
|
accounting_entry_id UUID REFERENCES finance.accounting_entries(id),
|
|
|
|
-- Conciliacion bancaria
|
|
bank_movement_id UUID REFERENCES finance.bank_movements(id),
|
|
reconciled_at TIMESTAMPTZ,
|
|
|
|
-- Notas y metadatos
|
|
notes TEXT,
|
|
metadata JSONB,
|
|
|
|
-- Auditoria
|
|
created_by UUID,
|
|
updated_by UUID,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
deleted_at TIMESTAMPTZ
|
|
);
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
-- 11. Proyecciones de Flujo de Efectivo (Cash Flow Projections)
|
|
-- ----------------------------------------------------------------------------
|
|
CREATE TABLE finance.cash_flow_projections (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL,
|
|
|
|
-- Tipo de flujo
|
|
flow_type finance.cash_flow_type NOT NULL,
|
|
period_type finance.cash_flow_period_type NOT NULL DEFAULT 'weekly',
|
|
|
|
-- Periodo
|
|
period_start DATE NOT NULL,
|
|
period_end DATE NOT NULL,
|
|
fiscal_year INTEGER NOT NULL,
|
|
fiscal_period INTEGER NOT NULL,
|
|
|
|
-- Proyecto (opcional, si es por proyecto)
|
|
project_id UUID,
|
|
project_code VARCHAR(50),
|
|
|
|
-- Saldo inicial
|
|
opening_balance DECIMAL(18,2) NOT NULL,
|
|
|
|
-- INGRESOS OPERATIVOS
|
|
income_estimations DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
income_sales DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
income_advances DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
income_other DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
total_income DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
|
|
-- EGRESOS OPERATIVOS
|
|
expense_suppliers DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
expense_subcontractors DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
expense_payroll DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
expense_taxes DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
expense_operating DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
expense_other DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
total_expenses DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
|
|
-- FLUJO NETO OPERATIVO
|
|
net_operating_flow DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
|
|
-- INVERSION
|
|
investing_income DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
investing_expense DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
net_investing_flow DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
|
|
-- FINANCIAMIENTO
|
|
financing_income DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
financing_expense DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
net_financing_flow DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
|
|
-- TOTALES
|
|
net_cash_flow DECIMAL(18,2) NOT NULL DEFAULT 0,
|
|
closing_balance DECIMAL(18,2) NOT NULL,
|
|
|
|
-- Varianza (para comparaciones)
|
|
projected_amount DECIMAL(18,2),
|
|
actual_amount DECIMAL(18,2),
|
|
variance_amount DECIMAL(18,2),
|
|
variance_percentage DECIMAL(8,2),
|
|
|
|
-- Desglose detallado (JSON)
|
|
income_breakdown JSONB,
|
|
expense_breakdown JSONB,
|
|
|
|
-- Estado
|
|
is_locked BOOLEAN NOT NULL DEFAULT FALSE,
|
|
locked_at TIMESTAMPTZ,
|
|
|
|
-- Notas y metadatos
|
|
notes TEXT,
|
|
variance_notes TEXT,
|
|
metadata JSONB,
|
|
|
|
-- Auditoria
|
|
created_by UUID,
|
|
updated_by UUID,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
deleted_at TIMESTAMPTZ
|
|
);
|
|
|
|
-- ============================================================================
|
|
-- INDICES
|
|
-- ============================================================================
|
|
|
|
-- Chart of Accounts
|
|
CREATE INDEX idx_chart_of_accounts_tenant ON finance.chart_of_accounts(tenant_id);
|
|
CREATE INDEX idx_chart_of_accounts_tenant_type ON finance.chart_of_accounts(tenant_id, account_type);
|
|
CREATE INDEX idx_chart_of_accounts_parent ON finance.chart_of_accounts(parent_id);
|
|
|
|
-- Accounting Entries
|
|
CREATE INDEX idx_accounting_entries_tenant ON finance.accounting_entries(tenant_id);
|
|
CREATE INDEX idx_accounting_entries_tenant_date ON finance.accounting_entries(tenant_id, entry_date);
|
|
CREATE INDEX idx_accounting_entries_tenant_status ON finance.accounting_entries(tenant_id, status);
|
|
CREATE INDEX idx_accounting_entries_source ON finance.accounting_entries(tenant_id, source_module, source_id);
|
|
|
|
-- Accounting Entry Lines
|
|
CREATE INDEX idx_accounting_entry_lines_tenant ON finance.accounting_entry_lines(tenant_id);
|
|
CREATE INDEX idx_accounting_entry_lines_entry ON finance.accounting_entry_lines(tenant_id, entry_id);
|
|
CREATE INDEX idx_accounting_entry_lines_account ON finance.accounting_entry_lines(tenant_id, account_id);
|
|
|
|
-- Accounts Payable
|
|
CREATE INDEX idx_accounts_payable_tenant ON finance.accounts_payable(tenant_id);
|
|
CREATE INDEX idx_accounts_payable_supplier ON finance.accounts_payable(tenant_id, supplier_id);
|
|
CREATE INDEX idx_accounts_payable_status ON finance.accounts_payable(tenant_id, status);
|
|
CREATE INDEX idx_accounts_payable_due_date ON finance.accounts_payable(tenant_id, due_date);
|
|
CREATE INDEX idx_accounts_payable_project ON finance.accounts_payable(tenant_id, project_id);
|
|
|
|
-- Accounts Receivable
|
|
CREATE INDEX idx_accounts_receivable_tenant ON finance.accounts_receivable(tenant_id);
|
|
CREATE INDEX idx_accounts_receivable_customer ON finance.accounts_receivable(tenant_id, customer_id);
|
|
CREATE INDEX idx_accounts_receivable_status ON finance.accounts_receivable(tenant_id, status);
|
|
CREATE INDEX idx_accounts_receivable_due_date ON finance.accounts_receivable(tenant_id, due_date);
|
|
CREATE INDEX idx_accounts_receivable_project ON finance.accounts_receivable(tenant_id, project_id);
|
|
|
|
-- Bank Accounts
|
|
CREATE INDEX idx_bank_accounts_tenant ON finance.bank_accounts(tenant_id);
|
|
CREATE INDEX idx_bank_accounts_status ON finance.bank_accounts(tenant_id, status);
|
|
|
|
-- Bank Movements
|
|
CREATE INDEX idx_bank_movements_tenant ON finance.bank_movements(tenant_id);
|
|
CREATE INDEX idx_bank_movements_account ON finance.bank_movements(tenant_id, bank_account_id);
|
|
CREATE INDEX idx_bank_movements_date ON finance.bank_movements(tenant_id, movement_date);
|
|
CREATE INDEX idx_bank_movements_status ON finance.bank_movements(tenant_id, status);
|
|
|
|
-- Bank Reconciliations
|
|
CREATE INDEX idx_bank_reconciliations_tenant ON finance.bank_reconciliations(tenant_id);
|
|
CREATE INDEX idx_bank_reconciliations_account ON finance.bank_reconciliations(tenant_id, bank_account_id);
|
|
CREATE INDEX idx_bank_reconciliations_period ON finance.bank_reconciliations(tenant_id, period_end);
|
|
CREATE INDEX idx_bank_reconciliations_status ON finance.bank_reconciliations(tenant_id, status);
|
|
|
|
-- AP Payments
|
|
CREATE INDEX idx_ap_payments_tenant ON finance.ap_payments(tenant_id);
|
|
CREATE INDEX idx_ap_payments_ap ON finance.ap_payments(tenant_id, account_payable_id);
|
|
CREATE INDEX idx_ap_payments_date ON finance.ap_payments(tenant_id, payment_date);
|
|
CREATE INDEX idx_ap_payments_bank ON finance.ap_payments(tenant_id, bank_account_id);
|
|
|
|
-- AR Payments
|
|
CREATE INDEX idx_ar_payments_tenant ON finance.ar_payments(tenant_id);
|
|
CREATE INDEX idx_ar_payments_ar ON finance.ar_payments(tenant_id, account_receivable_id);
|
|
CREATE INDEX idx_ar_payments_date ON finance.ar_payments(tenant_id, collection_date);
|
|
CREATE INDEX idx_ar_payments_bank ON finance.ar_payments(tenant_id, bank_account_id);
|
|
|
|
-- Cash Flow Projections
|
|
CREATE INDEX idx_cash_flow_tenant ON finance.cash_flow_projections(tenant_id);
|
|
CREATE INDEX idx_cash_flow_project ON finance.cash_flow_projections(tenant_id, project_id);
|
|
CREATE INDEX idx_cash_flow_period ON finance.cash_flow_projections(tenant_id, period_start, period_end);
|
|
CREATE INDEX idx_cash_flow_type ON finance.cash_flow_projections(tenant_id, flow_type);
|
|
|
|
-- ============================================================================
|
|
-- ROW LEVEL SECURITY (RLS)
|
|
-- ============================================================================
|
|
|
|
-- Habilitar RLS en todas las tablas
|
|
ALTER TABLE finance.chart_of_accounts ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE finance.accounting_entries ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE finance.accounting_entry_lines ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE finance.accounts_payable ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE finance.accounts_receivable ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE finance.bank_accounts ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE finance.bank_movements ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE finance.bank_reconciliations ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE finance.ap_payments ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE finance.ar_payments ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE finance.cash_flow_projections ENABLE ROW LEVEL SECURITY;
|
|
|
|
-- Crear politicas de tenant isolation (asumiendo funcion current_tenant_id() existe)
|
|
-- Estas politicas deben crearse despues de que exista la funcion en el schema auth
|
|
|
|
-- ============================================================================
|
|
-- TRIGGERS DE AUDITORIA
|
|
-- ============================================================================
|
|
|
|
-- Trigger para updated_at
|
|
CREATE OR REPLACE FUNCTION finance.set_updated_at()
|
|
RETURNS TRIGGER AS $$
|
|
BEGIN
|
|
NEW.updated_at = NOW();
|
|
RETURN NEW;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
-- Aplicar trigger a todas las tablas con updated_at
|
|
CREATE TRIGGER trg_chart_of_accounts_updated_at
|
|
BEFORE UPDATE ON finance.chart_of_accounts
|
|
FOR EACH ROW EXECUTE FUNCTION finance.set_updated_at();
|
|
|
|
CREATE TRIGGER trg_accounting_entries_updated_at
|
|
BEFORE UPDATE ON finance.accounting_entries
|
|
FOR EACH ROW EXECUTE FUNCTION finance.set_updated_at();
|
|
|
|
CREATE TRIGGER trg_accounting_entry_lines_updated_at
|
|
BEFORE UPDATE ON finance.accounting_entry_lines
|
|
FOR EACH ROW EXECUTE FUNCTION finance.set_updated_at();
|
|
|
|
CREATE TRIGGER trg_accounts_payable_updated_at
|
|
BEFORE UPDATE ON finance.accounts_payable
|
|
FOR EACH ROW EXECUTE FUNCTION finance.set_updated_at();
|
|
|
|
CREATE TRIGGER trg_accounts_receivable_updated_at
|
|
BEFORE UPDATE ON finance.accounts_receivable
|
|
FOR EACH ROW EXECUTE FUNCTION finance.set_updated_at();
|
|
|
|
CREATE TRIGGER trg_bank_accounts_updated_at
|
|
BEFORE UPDATE ON finance.bank_accounts
|
|
FOR EACH ROW EXECUTE FUNCTION finance.set_updated_at();
|
|
|
|
CREATE TRIGGER trg_bank_movements_updated_at
|
|
BEFORE UPDATE ON finance.bank_movements
|
|
FOR EACH ROW EXECUTE FUNCTION finance.set_updated_at();
|
|
|
|
CREATE TRIGGER trg_bank_reconciliations_updated_at
|
|
BEFORE UPDATE ON finance.bank_reconciliations
|
|
FOR EACH ROW EXECUTE FUNCTION finance.set_updated_at();
|
|
|
|
CREATE TRIGGER trg_ap_payments_updated_at
|
|
BEFORE UPDATE ON finance.ap_payments
|
|
FOR EACH ROW EXECUTE FUNCTION finance.set_updated_at();
|
|
|
|
CREATE TRIGGER trg_ar_payments_updated_at
|
|
BEFORE UPDATE ON finance.ar_payments
|
|
FOR EACH ROW EXECUTE FUNCTION finance.set_updated_at();
|
|
|
|
CREATE TRIGGER trg_cash_flow_projections_updated_at
|
|
BEFORE UPDATE ON finance.cash_flow_projections
|
|
FOR EACH ROW EXECUTE FUNCTION finance.set_updated_at();
|
|
|
|
-- ============================================================================
|
|
-- FUNCIONES AUXILIARES
|
|
-- ============================================================================
|
|
|
|
-- Funcion para validar balance de poliza
|
|
CREATE OR REPLACE FUNCTION finance.validate_entry_balance()
|
|
RETURNS TRIGGER AS $$
|
|
DECLARE
|
|
v_total_debit DECIMAL(18,2);
|
|
v_total_credit DECIMAL(18,2);
|
|
BEGIN
|
|
SELECT COALESCE(SUM(debit), 0), COALESCE(SUM(credit), 0)
|
|
INTO v_total_debit, v_total_credit
|
|
FROM finance.accounting_entry_lines
|
|
WHERE entry_id = NEW.entry_id;
|
|
|
|
UPDATE finance.accounting_entries
|
|
SET total_debit = v_total_debit,
|
|
total_credit = v_total_credit,
|
|
is_balanced = (v_total_debit = v_total_credit)
|
|
WHERE id = NEW.entry_id;
|
|
|
|
RETURN NEW;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
CREATE TRIGGER trg_validate_entry_balance
|
|
AFTER INSERT OR UPDATE OR DELETE ON finance.accounting_entry_lines
|
|
FOR EACH ROW EXECUTE FUNCTION finance.validate_entry_balance();
|
|
|
|
-- Funcion para actualizar saldo de CxP
|
|
CREATE OR REPLACE FUNCTION finance.update_ap_balance()
|
|
RETURNS TRIGGER AS $$
|
|
DECLARE
|
|
v_paid_amount DECIMAL(18,2);
|
|
BEGIN
|
|
SELECT COALESCE(SUM(amount), 0)
|
|
INTO v_paid_amount
|
|
FROM finance.ap_payments
|
|
WHERE account_payable_id = COALESCE(NEW.account_payable_id, OLD.account_payable_id)
|
|
AND status NOT IN ('cancelled', 'returned')
|
|
AND deleted_at IS NULL;
|
|
|
|
UPDATE finance.accounts_payable
|
|
SET paid_amount = v_paid_amount,
|
|
balance = total_amount - v_paid_amount,
|
|
status = CASE
|
|
WHEN v_paid_amount >= total_amount THEN 'paid'::finance.ap_status
|
|
WHEN v_paid_amount > 0 THEN 'partial'::finance.ap_status
|
|
ELSE status
|
|
END
|
|
WHERE id = COALESCE(NEW.account_payable_id, OLD.account_payable_id);
|
|
|
|
RETURN COALESCE(NEW, OLD);
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
CREATE TRIGGER trg_update_ap_balance
|
|
AFTER INSERT OR UPDATE OR DELETE ON finance.ap_payments
|
|
FOR EACH ROW EXECUTE FUNCTION finance.update_ap_balance();
|
|
|
|
-- Funcion para actualizar saldo de CxC
|
|
CREATE OR REPLACE FUNCTION finance.update_ar_balance()
|
|
RETURNS TRIGGER AS $$
|
|
DECLARE
|
|
v_collected_amount DECIMAL(18,2);
|
|
BEGIN
|
|
SELECT COALESCE(SUM(amount), 0)
|
|
INTO v_collected_amount
|
|
FROM finance.ar_payments
|
|
WHERE account_receivable_id = COALESCE(NEW.account_receivable_id, OLD.account_receivable_id)
|
|
AND status NOT IN ('cancelled', 'returned')
|
|
AND deleted_at IS NULL;
|
|
|
|
UPDATE finance.accounts_receivable
|
|
SET collected_amount = v_collected_amount,
|
|
balance = total_amount - v_collected_amount,
|
|
status = CASE
|
|
WHEN v_collected_amount >= total_amount THEN 'collected'::finance.ar_status
|
|
WHEN v_collected_amount > 0 THEN 'partial'::finance.ar_status
|
|
ELSE status
|
|
END
|
|
WHERE id = COALESCE(NEW.account_receivable_id, OLD.account_receivable_id);
|
|
|
|
RETURN COALESCE(NEW, OLD);
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
CREATE TRIGGER trg_update_ar_balance
|
|
AFTER INSERT OR UPDATE OR DELETE ON finance.ar_payments
|
|
FOR EACH ROW EXECUTE FUNCTION finance.update_ar_balance();
|
|
|
|
-- ============================================================================
|
|
-- COMENTARIOS DE DOCUMENTACION
|
|
-- ============================================================================
|
|
|
|
COMMENT ON SCHEMA finance IS 'Modulo de Finanzas y Controlling (MAE-014) - ERP Construccion';
|
|
|
|
COMMENT ON TABLE finance.chart_of_accounts IS 'Catalogo de cuentas contables con jerarquia';
|
|
COMMENT ON TABLE finance.accounting_entries IS 'Polizas contables (asientos contables)';
|
|
COMMENT ON TABLE finance.accounting_entry_lines IS 'Lineas de detalle de polizas contables';
|
|
COMMENT ON TABLE finance.accounts_payable IS 'Cuentas por pagar a proveedores';
|
|
COMMENT ON TABLE finance.accounts_receivable IS 'Cuentas por cobrar de clientes';
|
|
COMMENT ON TABLE finance.bank_accounts IS 'Cuentas bancarias de la empresa';
|
|
COMMENT ON TABLE finance.bank_movements IS 'Movimientos bancarios importados';
|
|
COMMENT ON TABLE finance.bank_reconciliations IS 'Procesos de conciliacion bancaria';
|
|
COMMENT ON TABLE finance.ap_payments IS 'Pagos realizados a proveedores';
|
|
COMMENT ON TABLE finance.ar_payments IS 'Cobros recibidos de clientes';
|
|
COMMENT ON TABLE finance.cash_flow_projections IS 'Proyecciones de flujo de efectivo';
|
|
|
|
-- ============================================================================
|
|
-- FIN DEL SCRIPT
|
|
-- ============================================================================
|