503 lines
19 KiB
PL/PgSQL
503 lines
19 KiB
PL/PgSQL
-- =====================================================
|
|
-- SCHEMA: estimates
|
|
-- PROPOSITO: Estimaciones, anticipos, retenciones, generadores
|
|
-- MODULOS: MAI-008 (Estimaciones y Facturacion)
|
|
-- FECHA: 2025-11-24
|
|
-- ESPECIFICO: 100% construccion
|
|
-- =====================================================
|
|
|
|
-- Crear schema
|
|
CREATE SCHEMA IF NOT EXISTS estimates;
|
|
|
|
-- =====================================================
|
|
-- TYPES (ENUMs)
|
|
-- =====================================================
|
|
|
|
CREATE TYPE estimates.estimate_status AS ENUM (
|
|
'draft', -- Borrador
|
|
'submitted', -- Enviada para revision
|
|
'reviewed', -- Revisada
|
|
'approved', -- Aprobada
|
|
'invoiced', -- Facturada
|
|
'paid', -- Pagada
|
|
'rejected', -- Rechazada
|
|
'cancelled' -- Cancelada
|
|
);
|
|
|
|
CREATE TYPE estimates.advance_type AS ENUM (
|
|
'initial', -- Anticipo inicial
|
|
'progress', -- Anticipo por avance
|
|
'materials' -- Anticipo para materiales
|
|
);
|
|
|
|
CREATE TYPE estimates.retention_type AS ENUM (
|
|
'guarantee', -- Retencion de garantia (fondo)
|
|
'tax', -- Retencion fiscal
|
|
'penalty', -- Penalizacion
|
|
'other' -- Otra retencion
|
|
);
|
|
|
|
CREATE TYPE estimates.generator_status AS ENUM (
|
|
'draft', -- Borrador
|
|
'in_progress', -- En captura
|
|
'completed', -- Completado
|
|
'approved' -- Aprobado
|
|
);
|
|
|
|
-- =====================================================
|
|
-- TABLES - ESTIMACIONES
|
|
-- =====================================================
|
|
|
|
-- Tabla: estimaciones (estimaciones de obra)
|
|
CREATE TABLE estimates.estimaciones (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
|
|
contrato_id UUID NOT NULL REFERENCES construction.contratos(id),
|
|
fraccionamiento_id UUID NOT NULL REFERENCES construction.fraccionamientos(id),
|
|
estimate_number VARCHAR(30) NOT NULL,
|
|
period_start DATE NOT NULL,
|
|
period_end DATE NOT NULL,
|
|
sequence_number INTEGER NOT NULL, -- Numero de estimacion (1, 2, 3...)
|
|
status estimates.estimate_status NOT NULL DEFAULT 'draft',
|
|
|
|
-- Montos
|
|
subtotal DECIMAL(16,2) DEFAULT 0,
|
|
advance_amount DECIMAL(16,2) DEFAULT 0, -- Amortizacion de anticipo
|
|
retention_amount DECIMAL(16,2) DEFAULT 0, -- Retencion
|
|
tax_amount DECIMAL(16,2) DEFAULT 0, -- IVA
|
|
total_amount DECIMAL(16,2) DEFAULT 0, -- Neto a pagar
|
|
|
|
-- Aprobaciones
|
|
submitted_at TIMESTAMP,
|
|
submitted_by UUID REFERENCES auth.users(id),
|
|
reviewed_at TIMESTAMP,
|
|
reviewed_by UUID REFERENCES auth.users(id),
|
|
approved_at TIMESTAMP,
|
|
approved_by UUID REFERENCES auth.users(id),
|
|
|
|
-- Facturacion
|
|
invoice_id UUID, -- FK a facturas (financial.invoices)
|
|
invoiced_at TIMESTAMP,
|
|
paid_at TIMESTAMP,
|
|
|
|
notes TEXT,
|
|
|
|
-- Auditoria
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
created_by UUID REFERENCES auth.users(id),
|
|
updated_at TIMESTAMP,
|
|
updated_by UUID REFERENCES auth.users(id),
|
|
deleted_at TIMESTAMP,
|
|
deleted_by UUID REFERENCES auth.users(id),
|
|
|
|
CONSTRAINT uq_estimaciones_number_tenant UNIQUE (tenant_id, estimate_number),
|
|
CONSTRAINT uq_estimaciones_sequence_contrato UNIQUE (contrato_id, sequence_number),
|
|
CONSTRAINT chk_estimaciones_period CHECK (period_end >= period_start)
|
|
);
|
|
|
|
-- Tabla: estimacion_conceptos (lineas de estimacion)
|
|
CREATE TABLE estimates.estimacion_conceptos (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
|
|
estimacion_id UUID NOT NULL REFERENCES estimates.estimaciones(id) ON DELETE CASCADE,
|
|
concepto_id UUID NOT NULL REFERENCES construction.conceptos(id),
|
|
contrato_partida_id UUID REFERENCES construction.contrato_partidas(id),
|
|
|
|
-- Cantidades
|
|
quantity_contract DECIMAL(12,4) DEFAULT 0, -- Cantidad contratada
|
|
quantity_previous DECIMAL(12,4) DEFAULT 0, -- Acumulado anterior
|
|
quantity_current DECIMAL(12,4) DEFAULT 0, -- Esta estimacion
|
|
quantity_accumulated DECIMAL(12,4) GENERATED ALWAYS AS (quantity_previous + quantity_current) STORED,
|
|
|
|
-- Precios
|
|
unit_price DECIMAL(12,4) NOT NULL DEFAULT 0,
|
|
amount_current DECIMAL(14,2) GENERATED ALWAYS AS (quantity_current * unit_price) STORED,
|
|
|
|
notes TEXT,
|
|
|
|
-- Auditoria
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
created_by UUID REFERENCES auth.users(id),
|
|
updated_at TIMESTAMP,
|
|
updated_by UUID REFERENCES auth.users(id),
|
|
deleted_at TIMESTAMP,
|
|
deleted_by UUID REFERENCES auth.users(id),
|
|
|
|
CONSTRAINT uq_est_conceptos_estimacion_concepto UNIQUE (estimacion_id, concepto_id)
|
|
);
|
|
|
|
-- Tabla: generadores (soporte de cantidades)
|
|
CREATE TABLE estimates.generadores (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
|
|
estimacion_concepto_id UUID NOT NULL REFERENCES estimates.estimacion_conceptos(id) ON DELETE CASCADE,
|
|
generator_number VARCHAR(30) NOT NULL,
|
|
description TEXT,
|
|
status estimates.generator_status NOT NULL DEFAULT 'draft',
|
|
|
|
-- Ubicacion
|
|
lote_id UUID REFERENCES construction.lotes(id),
|
|
departamento_id UUID REFERENCES construction.departamentos(id),
|
|
location_description VARCHAR(255), -- Descripcion libre de ubicacion
|
|
|
|
-- Calculo
|
|
quantity DECIMAL(12,4) NOT NULL DEFAULT 0,
|
|
formula TEXT, -- Formula de calculo (ej: "3.5 x 2.0 x 0.15")
|
|
|
|
-- Evidencia
|
|
photo_url VARCHAR(500),
|
|
sketch_url VARCHAR(500),
|
|
|
|
captured_by UUID NOT NULL REFERENCES auth.users(id),
|
|
captured_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
approved_by UUID REFERENCES auth.users(id),
|
|
approved_at TIMESTAMP,
|
|
|
|
-- Auditoria
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
created_by UUID REFERENCES auth.users(id),
|
|
updated_at TIMESTAMP,
|
|
updated_by UUID REFERENCES auth.users(id),
|
|
deleted_at TIMESTAMP,
|
|
deleted_by UUID REFERENCES auth.users(id)
|
|
);
|
|
|
|
-- =====================================================
|
|
-- TABLES - ANTICIPOS
|
|
-- =====================================================
|
|
|
|
-- Tabla: anticipos (anticipos otorgados)
|
|
CREATE TABLE estimates.anticipos (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
|
|
contrato_id UUID NOT NULL REFERENCES construction.contratos(id),
|
|
advance_type estimates.advance_type NOT NULL DEFAULT 'initial',
|
|
advance_number VARCHAR(30) NOT NULL,
|
|
advance_date DATE NOT NULL,
|
|
|
|
-- Montos
|
|
gross_amount DECIMAL(16,2) NOT NULL, -- Monto bruto
|
|
tax_amount DECIMAL(16,2) DEFAULT 0, -- IVA
|
|
net_amount DECIMAL(16,2) NOT NULL, -- Monto neto
|
|
|
|
-- Amortizacion
|
|
amortization_percentage DECIMAL(5,2) DEFAULT 0, -- % a amortizar por estimacion
|
|
amortized_amount DECIMAL(16,2) DEFAULT 0, -- Total amortizado
|
|
pending_amount DECIMAL(16,2) GENERATED ALWAYS AS (net_amount - amortized_amount) STORED,
|
|
is_fully_amortized BOOLEAN DEFAULT FALSE,
|
|
|
|
-- Aprobacion
|
|
approved_at TIMESTAMP,
|
|
approved_by UUID REFERENCES auth.users(id),
|
|
|
|
-- Pago
|
|
paid_at TIMESTAMP,
|
|
payment_reference VARCHAR(100),
|
|
|
|
notes TEXT,
|
|
|
|
-- Auditoria
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
created_by UUID REFERENCES auth.users(id),
|
|
updated_at TIMESTAMP,
|
|
updated_by UUID REFERENCES auth.users(id),
|
|
deleted_at TIMESTAMP,
|
|
deleted_by UUID REFERENCES auth.users(id),
|
|
|
|
CONSTRAINT uq_anticipos_number_tenant UNIQUE (tenant_id, advance_number)
|
|
);
|
|
|
|
-- Tabla: amortizaciones (amortizaciones de anticipos)
|
|
CREATE TABLE estimates.amortizaciones (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
|
|
anticipo_id UUID NOT NULL REFERENCES estimates.anticipos(id),
|
|
estimacion_id UUID NOT NULL REFERENCES estimates.estimaciones(id),
|
|
amount DECIMAL(16,2) NOT NULL,
|
|
amortization_date DATE NOT NULL,
|
|
notes TEXT,
|
|
|
|
-- Auditoria
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
created_by UUID REFERENCES auth.users(id),
|
|
updated_at TIMESTAMP,
|
|
updated_by UUID REFERENCES auth.users(id),
|
|
deleted_at TIMESTAMP,
|
|
deleted_by UUID REFERENCES auth.users(id),
|
|
|
|
CONSTRAINT uq_amortizaciones_anticipo_estimacion UNIQUE (anticipo_id, estimacion_id)
|
|
);
|
|
|
|
-- =====================================================
|
|
-- TABLES - RETENCIONES
|
|
-- =====================================================
|
|
|
|
-- Tabla: retenciones (retenciones aplicadas)
|
|
CREATE TABLE estimates.retenciones (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
|
|
estimacion_id UUID NOT NULL REFERENCES estimates.estimaciones(id),
|
|
retention_type estimates.retention_type NOT NULL,
|
|
description VARCHAR(255) NOT NULL,
|
|
percentage DECIMAL(5,2), -- Porcentaje de retencion
|
|
amount DECIMAL(16,2) NOT NULL, -- Monto retenido
|
|
release_date DATE, -- Fecha de liberacion programada
|
|
released_at TIMESTAMP, -- Fecha de liberacion real
|
|
released_amount DECIMAL(16,2), -- Monto liberado
|
|
notes TEXT,
|
|
|
|
-- Auditoria
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
created_by UUID REFERENCES auth.users(id),
|
|
updated_at TIMESTAMP,
|
|
updated_by UUID REFERENCES auth.users(id),
|
|
deleted_at TIMESTAMP,
|
|
deleted_by UUID REFERENCES auth.users(id)
|
|
);
|
|
|
|
-- Tabla: fondo_garantia (acumulado de fondo de garantia)
|
|
CREATE TABLE estimates.fondo_garantia (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
|
|
contrato_id UUID NOT NULL REFERENCES construction.contratos(id),
|
|
accumulated_amount DECIMAL(16,2) DEFAULT 0, -- Total acumulado
|
|
released_amount DECIMAL(16,2) DEFAULT 0, -- Total liberado
|
|
pending_amount DECIMAL(16,2) GENERATED ALWAYS AS (accumulated_amount - released_amount) STORED,
|
|
|
|
-- Liberacion
|
|
release_date DATE, -- Fecha programada de liberacion
|
|
released_at TIMESTAMP,
|
|
released_by UUID REFERENCES auth.users(id),
|
|
|
|
-- Auditoria
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
created_by UUID REFERENCES auth.users(id),
|
|
updated_at TIMESTAMP,
|
|
updated_by UUID REFERENCES auth.users(id),
|
|
deleted_at TIMESTAMP,
|
|
deleted_by UUID REFERENCES auth.users(id),
|
|
|
|
CONSTRAINT uq_fondo_garantia_contrato UNIQUE (contrato_id)
|
|
);
|
|
|
|
-- =====================================================
|
|
-- TABLES - WORKFLOW
|
|
-- =====================================================
|
|
|
|
-- Tabla: estimacion_workflow (historial de workflow)
|
|
CREATE TABLE estimates.estimacion_workflow (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
|
|
estimacion_id UUID NOT NULL REFERENCES estimates.estimaciones(id) ON DELETE CASCADE,
|
|
from_status estimates.estimate_status,
|
|
to_status estimates.estimate_status NOT NULL,
|
|
action VARCHAR(50) NOT NULL, -- submit, review, approve, reject, etc.
|
|
comments TEXT,
|
|
performed_by UUID NOT NULL REFERENCES auth.users(id),
|
|
performed_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
-- Auditoria
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
created_by UUID REFERENCES auth.users(id)
|
|
);
|
|
|
|
-- =====================================================
|
|
-- INDICES
|
|
-- =====================================================
|
|
|
|
-- Estimaciones
|
|
CREATE INDEX idx_estimaciones_tenant_id ON estimates.estimaciones(tenant_id);
|
|
CREATE INDEX idx_estimaciones_contrato_id ON estimates.estimaciones(contrato_id);
|
|
CREATE INDEX idx_estimaciones_fraccionamiento_id ON estimates.estimaciones(fraccionamiento_id);
|
|
CREATE INDEX idx_estimaciones_status ON estimates.estimaciones(status);
|
|
CREATE INDEX idx_estimaciones_period ON estimates.estimaciones(period_start, period_end);
|
|
CREATE INDEX idx_estimaciones_active ON estimates.estimaciones(tenant_id) WHERE deleted_at IS NULL;
|
|
|
|
-- Estimacion Conceptos
|
|
CREATE INDEX idx_est_conceptos_tenant_id ON estimates.estimacion_conceptos(tenant_id);
|
|
CREATE INDEX idx_est_conceptos_estimacion_id ON estimates.estimacion_conceptos(estimacion_id);
|
|
CREATE INDEX idx_est_conceptos_concepto_id ON estimates.estimacion_conceptos(concepto_id);
|
|
|
|
-- Generadores
|
|
CREATE INDEX idx_generadores_tenant_id ON estimates.generadores(tenant_id);
|
|
CREATE INDEX idx_generadores_est_concepto_id ON estimates.generadores(estimacion_concepto_id);
|
|
CREATE INDEX idx_generadores_lote_id ON estimates.generadores(lote_id);
|
|
CREATE INDEX idx_generadores_status ON estimates.generadores(status);
|
|
|
|
-- Anticipos
|
|
CREATE INDEX idx_anticipos_tenant_id ON estimates.anticipos(tenant_id);
|
|
CREATE INDEX idx_anticipos_contrato_id ON estimates.anticipos(contrato_id);
|
|
CREATE INDEX idx_anticipos_type ON estimates.anticipos(advance_type);
|
|
CREATE INDEX idx_anticipos_pending ON estimates.anticipos(tenant_id) WHERE is_fully_amortized = FALSE;
|
|
|
|
-- Amortizaciones
|
|
CREATE INDEX idx_amortizaciones_tenant_id ON estimates.amortizaciones(tenant_id);
|
|
CREATE INDEX idx_amortizaciones_anticipo_id ON estimates.amortizaciones(anticipo_id);
|
|
CREATE INDEX idx_amortizaciones_estimacion_id ON estimates.amortizaciones(estimacion_id);
|
|
|
|
-- Retenciones
|
|
CREATE INDEX idx_retenciones_tenant_id ON estimates.retenciones(tenant_id);
|
|
CREATE INDEX idx_retenciones_estimacion_id ON estimates.retenciones(estimacion_id);
|
|
CREATE INDEX idx_retenciones_type ON estimates.retenciones(retention_type);
|
|
CREATE INDEX idx_retenciones_pending ON estimates.retenciones(tenant_id) WHERE released_at IS NULL;
|
|
|
|
-- Fondo Garantia
|
|
CREATE INDEX idx_fondo_garantia_tenant_id ON estimates.fondo_garantia(tenant_id);
|
|
CREATE INDEX idx_fondo_garantia_contrato_id ON estimates.fondo_garantia(contrato_id);
|
|
|
|
-- Workflow
|
|
CREATE INDEX idx_est_workflow_tenant_id ON estimates.estimacion_workflow(tenant_id);
|
|
CREATE INDEX idx_est_workflow_estimacion_id ON estimates.estimacion_workflow(estimacion_id);
|
|
CREATE INDEX idx_est_workflow_performed_at ON estimates.estimacion_workflow(performed_at);
|
|
|
|
-- =====================================================
|
|
-- ROW LEVEL SECURITY (RLS)
|
|
-- =====================================================
|
|
|
|
-- Habilitar RLS
|
|
ALTER TABLE estimates.estimaciones ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE estimates.estimacion_conceptos ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE estimates.generadores ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE estimates.anticipos ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE estimates.amortizaciones ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE estimates.retenciones ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE estimates.fondo_garantia ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE estimates.estimacion_workflow ENABLE ROW LEVEL SECURITY;
|
|
|
|
-- Policies
|
|
CREATE POLICY tenant_isolation_estimaciones ON estimates.estimaciones
|
|
USING (tenant_id = get_current_tenant_id());
|
|
|
|
CREATE POLICY tenant_isolation_est_conceptos ON estimates.estimacion_conceptos
|
|
USING (tenant_id = get_current_tenant_id());
|
|
|
|
CREATE POLICY tenant_isolation_generadores ON estimates.generadores
|
|
USING (tenant_id = get_current_tenant_id());
|
|
|
|
CREATE POLICY tenant_isolation_anticipos ON estimates.anticipos
|
|
USING (tenant_id = get_current_tenant_id());
|
|
|
|
CREATE POLICY tenant_isolation_amortizaciones ON estimates.amortizaciones
|
|
USING (tenant_id = get_current_tenant_id());
|
|
|
|
CREATE POLICY tenant_isolation_retenciones ON estimates.retenciones
|
|
USING (tenant_id = get_current_tenant_id());
|
|
|
|
CREATE POLICY tenant_isolation_fondo_garantia ON estimates.fondo_garantia
|
|
USING (tenant_id = get_current_tenant_id());
|
|
|
|
CREATE POLICY tenant_isolation_est_workflow ON estimates.estimacion_workflow
|
|
USING (tenant_id = get_current_tenant_id());
|
|
|
|
-- =====================================================
|
|
-- FUNCTIONS
|
|
-- =====================================================
|
|
|
|
-- Funcion: calcular totales de estimacion
|
|
CREATE OR REPLACE FUNCTION estimates.calculate_estimate_totals(p_estimacion_id UUID)
|
|
RETURNS VOID AS $$
|
|
DECLARE
|
|
v_subtotal DECIMAL(16,2);
|
|
v_advance DECIMAL(16,2);
|
|
v_retention DECIMAL(16,2);
|
|
v_tax_rate DECIMAL(5,2) := 0.16; -- IVA Mexico
|
|
v_tax DECIMAL(16,2);
|
|
v_total DECIMAL(16,2);
|
|
BEGIN
|
|
-- Calcular subtotal
|
|
SELECT COALESCE(SUM(amount_current), 0) INTO v_subtotal
|
|
FROM estimates.estimacion_conceptos
|
|
WHERE estimacion_id = p_estimacion_id AND deleted_at IS NULL;
|
|
|
|
-- Calcular amortizacion de anticipos
|
|
SELECT COALESCE(SUM(amount), 0) INTO v_advance
|
|
FROM estimates.amortizaciones
|
|
WHERE estimacion_id = p_estimacion_id AND deleted_at IS NULL;
|
|
|
|
-- Calcular retenciones
|
|
SELECT COALESCE(SUM(amount), 0) INTO v_retention
|
|
FROM estimates.retenciones
|
|
WHERE estimacion_id = p_estimacion_id AND deleted_at IS NULL;
|
|
|
|
-- Calcular IVA sobre subtotal
|
|
v_tax := v_subtotal * v_tax_rate;
|
|
|
|
-- Calcular total neto
|
|
v_total := v_subtotal + v_tax - v_advance - v_retention;
|
|
|
|
-- Actualizar estimacion
|
|
UPDATE estimates.estimaciones
|
|
SET
|
|
subtotal = v_subtotal,
|
|
advance_amount = v_advance,
|
|
retention_amount = v_retention,
|
|
tax_amount = v_tax,
|
|
total_amount = v_total,
|
|
updated_at = CURRENT_TIMESTAMP
|
|
WHERE id = p_estimacion_id;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
COMMENT ON FUNCTION estimates.calculate_estimate_totals IS 'Recalcula los totales de una estimacion';
|
|
|
|
-- Funcion: actualizar amortizacion de anticipo
|
|
CREATE OR REPLACE FUNCTION estimates.update_advance_amortization()
|
|
RETURNS TRIGGER AS $$
|
|
BEGIN
|
|
IF TG_OP = 'INSERT' OR TG_OP = 'UPDATE' THEN
|
|
UPDATE estimates.anticipos
|
|
SET
|
|
amortized_amount = (
|
|
SELECT COALESCE(SUM(amount), 0)
|
|
FROM estimates.amortizaciones
|
|
WHERE anticipo_id = NEW.anticipo_id AND deleted_at IS NULL
|
|
),
|
|
is_fully_amortized = (
|
|
SELECT COALESCE(SUM(amount), 0) >= net_amount
|
|
FROM estimates.amortizaciones
|
|
WHERE anticipo_id = NEW.anticipo_id AND deleted_at IS NULL
|
|
),
|
|
updated_at = CURRENT_TIMESTAMP
|
|
WHERE id = NEW.anticipo_id;
|
|
END IF;
|
|
|
|
IF TG_OP = 'DELETE' THEN
|
|
UPDATE estimates.anticipos
|
|
SET
|
|
amortized_amount = (
|
|
SELECT COALESCE(SUM(amount), 0)
|
|
FROM estimates.amortizaciones
|
|
WHERE anticipo_id = OLD.anticipo_id AND deleted_at IS NULL
|
|
),
|
|
is_fully_amortized = FALSE,
|
|
updated_at = CURRENT_TIMESTAMP
|
|
WHERE id = OLD.anticipo_id;
|
|
END IF;
|
|
|
|
RETURN COALESCE(NEW, OLD);
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
CREATE TRIGGER trg_update_advance_amortization
|
|
AFTER INSERT OR UPDATE OR DELETE ON estimates.amortizaciones
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION estimates.update_advance_amortization();
|
|
|
|
-- =====================================================
|
|
-- COMENTARIOS
|
|
-- =====================================================
|
|
|
|
COMMENT ON SCHEMA estimates IS 'Schema de estimaciones, anticipos y retenciones de obra';
|
|
COMMENT ON TABLE estimates.estimaciones IS 'Estimaciones de obra periodicas';
|
|
COMMENT ON TABLE estimates.estimacion_conceptos IS 'Lineas de concepto por estimacion';
|
|
COMMENT ON TABLE estimates.generadores IS 'Generadores de cantidades para estimaciones';
|
|
COMMENT ON TABLE estimates.anticipos IS 'Anticipos otorgados a subcontratistas';
|
|
COMMENT ON TABLE estimates.amortizaciones IS 'Amortizaciones de anticipos por estimacion';
|
|
COMMENT ON TABLE estimates.retenciones IS 'Retenciones aplicadas a estimaciones';
|
|
COMMENT ON TABLE estimates.fondo_garantia IS 'Fondo de garantia acumulado por contrato';
|
|
COMMENT ON TABLE estimates.estimacion_workflow IS 'Historial de workflow de estimaciones';
|
|
|
|
-- =====================================================
|
|
-- FIN DEL SCHEMA ESTIMATES
|
|
-- =====================================================
|