416 lines
19 KiB
PL/PgSQL
416 lines
19 KiB
PL/PgSQL
-- ============================================================================
|
|
-- ESTIMATES Schema DDL - Estimaciones, Anticipos y Retenciones
|
|
-- Modulos: MAI-008 (Estimaciones y Facturación)
|
|
-- Version: 1.0.0
|
|
-- Fecha: 2025-12-08
|
|
-- ============================================================================
|
|
-- PREREQUISITOS:
|
|
-- 1. ERP-Core instalado (auth.tenants, auth.users)
|
|
-- 2. Schema construction instalado (fraccionamientos, contratos, conceptos, lotes, departamentos)
|
|
-- ============================================================================
|
|
|
|
-- Verificar prerequisitos
|
|
DO $$
|
|
BEGIN
|
|
IF NOT EXISTS (SELECT 1 FROM pg_namespace WHERE nspname = 'auth') THEN
|
|
RAISE EXCEPTION 'Schema auth no existe. Ejecutar primero ERP-Core DDL';
|
|
END IF;
|
|
IF NOT EXISTS (SELECT 1 FROM pg_namespace WHERE nspname = 'construction') THEN
|
|
RAISE EXCEPTION 'Schema construction no existe. Ejecutar primero construction DDL';
|
|
END IF;
|
|
END $$;
|
|
|
|
-- Crear schema
|
|
CREATE SCHEMA IF NOT EXISTS estimates;
|
|
|
|
-- ============================================================================
|
|
-- TYPES (ENUMs)
|
|
-- ============================================================================
|
|
|
|
DO $$ BEGIN
|
|
CREATE TYPE estimates.estimate_status AS ENUM (
|
|
'draft', 'submitted', 'reviewed', 'approved', 'invoiced', 'paid', 'rejected', 'cancelled'
|
|
);
|
|
EXCEPTION WHEN duplicate_object THEN NULL; END $$;
|
|
|
|
DO $$ BEGIN
|
|
CREATE TYPE estimates.advance_type AS ENUM (
|
|
'initial', 'progress', 'materials'
|
|
);
|
|
EXCEPTION WHEN duplicate_object THEN NULL; END $$;
|
|
|
|
DO $$ BEGIN
|
|
CREATE TYPE estimates.retention_type AS ENUM (
|
|
'guarantee', 'tax', 'penalty', 'other'
|
|
);
|
|
EXCEPTION WHEN duplicate_object THEN NULL; END $$;
|
|
|
|
DO $$ BEGIN
|
|
CREATE TYPE estimates.generator_status AS ENUM (
|
|
'draft', 'in_progress', 'completed', 'approved'
|
|
);
|
|
EXCEPTION WHEN duplicate_object THEN NULL; END $$;
|
|
|
|
-- ============================================================================
|
|
-- TABLES - ESTIMACIONES
|
|
-- ============================================================================
|
|
|
|
-- Tabla: estimaciones (estimaciones de obra)
|
|
CREATE TABLE IF NOT EXISTS 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,
|
|
status estimates.estimate_status NOT NULL DEFAULT 'draft',
|
|
subtotal DECIMAL(16,2) DEFAULT 0,
|
|
advance_amount DECIMAL(16,2) DEFAULT 0,
|
|
retention_amount DECIMAL(16,2) DEFAULT 0,
|
|
tax_amount DECIMAL(16,2) DEFAULT 0,
|
|
total_amount DECIMAL(16,2) DEFAULT 0,
|
|
submitted_at TIMESTAMPTZ,
|
|
submitted_by UUID REFERENCES auth.users(id),
|
|
reviewed_at TIMESTAMPTZ,
|
|
reviewed_by UUID REFERENCES auth.users(id),
|
|
approved_at TIMESTAMPTZ,
|
|
approved_by UUID REFERENCES auth.users(id),
|
|
invoice_id UUID,
|
|
invoiced_at TIMESTAMPTZ,
|
|
paid_at TIMESTAMPTZ,
|
|
notes TEXT,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
created_by UUID REFERENCES auth.users(id),
|
|
updated_at TIMESTAMPTZ,
|
|
updated_by UUID REFERENCES auth.users(id),
|
|
deleted_at TIMESTAMPTZ,
|
|
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 (líneas de estimación)
|
|
CREATE TABLE IF NOT EXISTS 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),
|
|
quantity_contract DECIMAL(12,4) DEFAULT 0,
|
|
quantity_previous DECIMAL(12,4) DEFAULT 0,
|
|
quantity_current DECIMAL(12,4) DEFAULT 0,
|
|
quantity_accumulated DECIMAL(12,4) GENERATED ALWAYS AS (quantity_previous + quantity_current) STORED,
|
|
unit_price DECIMAL(12,4) NOT NULL DEFAULT 0,
|
|
amount_current DECIMAL(14,2) GENERATED ALWAYS AS (quantity_current * unit_price) STORED,
|
|
notes TEXT,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
created_by UUID REFERENCES auth.users(id),
|
|
updated_at TIMESTAMPTZ,
|
|
updated_by UUID REFERENCES auth.users(id),
|
|
deleted_at TIMESTAMPTZ,
|
|
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 IF NOT EXISTS 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',
|
|
lote_id UUID REFERENCES construction.lotes(id),
|
|
departamento_id UUID REFERENCES construction.departamentos(id),
|
|
location_description VARCHAR(255),
|
|
quantity DECIMAL(12,4) NOT NULL DEFAULT 0,
|
|
formula TEXT,
|
|
photo_url VARCHAR(500),
|
|
sketch_url VARCHAR(500),
|
|
captured_by UUID NOT NULL REFERENCES auth.users(id),
|
|
captured_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
approved_by UUID REFERENCES auth.users(id),
|
|
approved_at TIMESTAMPTZ,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
created_by UUID REFERENCES auth.users(id),
|
|
updated_at TIMESTAMPTZ,
|
|
updated_by UUID REFERENCES auth.users(id),
|
|
deleted_at TIMESTAMPTZ,
|
|
deleted_by UUID REFERENCES auth.users(id)
|
|
);
|
|
|
|
-- ============================================================================
|
|
-- TABLES - ANTICIPOS
|
|
-- ============================================================================
|
|
|
|
-- Tabla: anticipos (anticipos otorgados)
|
|
CREATE TABLE IF NOT EXISTS 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,
|
|
gross_amount DECIMAL(16,2) NOT NULL,
|
|
tax_amount DECIMAL(16,2) DEFAULT 0,
|
|
net_amount DECIMAL(16,2) NOT NULL,
|
|
amortization_percentage DECIMAL(5,2) DEFAULT 0,
|
|
amortized_amount DECIMAL(16,2) DEFAULT 0,
|
|
pending_amount DECIMAL(16,2) GENERATED ALWAYS AS (net_amount - amortized_amount) STORED,
|
|
is_fully_amortized BOOLEAN DEFAULT FALSE,
|
|
approved_at TIMESTAMPTZ,
|
|
approved_by UUID REFERENCES auth.users(id),
|
|
paid_at TIMESTAMPTZ,
|
|
payment_reference VARCHAR(100),
|
|
notes TEXT,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
created_by UUID REFERENCES auth.users(id),
|
|
updated_at TIMESTAMPTZ,
|
|
updated_by UUID REFERENCES auth.users(id),
|
|
deleted_at TIMESTAMPTZ,
|
|
deleted_by UUID REFERENCES auth.users(id),
|
|
CONSTRAINT uq_anticipos_number_tenant UNIQUE (tenant_id, advance_number)
|
|
);
|
|
|
|
-- Tabla: amortizaciones (amortizaciones de anticipos)
|
|
CREATE TABLE IF NOT EXISTS 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,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
created_by UUID REFERENCES auth.users(id),
|
|
updated_at TIMESTAMPTZ,
|
|
updated_by UUID REFERENCES auth.users(id),
|
|
deleted_at TIMESTAMPTZ,
|
|
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 IF NOT EXISTS 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),
|
|
amount DECIMAL(16,2) NOT NULL,
|
|
release_date DATE,
|
|
released_at TIMESTAMPTZ,
|
|
released_amount DECIMAL(16,2),
|
|
notes TEXT,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
created_by UUID REFERENCES auth.users(id),
|
|
updated_at TIMESTAMPTZ,
|
|
updated_by UUID REFERENCES auth.users(id),
|
|
deleted_at TIMESTAMPTZ,
|
|
deleted_by UUID REFERENCES auth.users(id)
|
|
);
|
|
|
|
-- Tabla: fondo_garantia (acumulado de fondo de garantía)
|
|
CREATE TABLE IF NOT EXISTS 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,
|
|
released_amount DECIMAL(16,2) DEFAULT 0,
|
|
pending_amount DECIMAL(16,2) GENERATED ALWAYS AS (accumulated_amount - released_amount) STORED,
|
|
release_date DATE,
|
|
released_at TIMESTAMPTZ,
|
|
released_by UUID REFERENCES auth.users(id),
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
created_by UUID REFERENCES auth.users(id),
|
|
updated_at TIMESTAMPTZ,
|
|
updated_by UUID REFERENCES auth.users(id),
|
|
deleted_at TIMESTAMPTZ,
|
|
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 IF NOT EXISTS 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,
|
|
comments TEXT,
|
|
performed_by UUID NOT NULL REFERENCES auth.users(id),
|
|
performed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
created_by UUID REFERENCES auth.users(id)
|
|
);
|
|
|
|
-- ============================================================================
|
|
-- INDICES
|
|
-- ============================================================================
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_estimaciones_tenant_id ON estimates.estimaciones(tenant_id);
|
|
CREATE INDEX IF NOT EXISTS idx_estimaciones_contrato_id ON estimates.estimaciones(contrato_id);
|
|
CREATE INDEX IF NOT EXISTS idx_estimaciones_fraccionamiento_id ON estimates.estimaciones(fraccionamiento_id);
|
|
CREATE INDEX IF NOT EXISTS idx_estimaciones_status ON estimates.estimaciones(status);
|
|
CREATE INDEX IF NOT EXISTS idx_estimaciones_period ON estimates.estimaciones(period_start, period_end);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_est_conceptos_tenant_id ON estimates.estimacion_conceptos(tenant_id);
|
|
CREATE INDEX IF NOT EXISTS idx_est_conceptos_estimacion_id ON estimates.estimacion_conceptos(estimacion_id);
|
|
CREATE INDEX IF NOT EXISTS idx_est_conceptos_concepto_id ON estimates.estimacion_conceptos(concepto_id);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_generadores_tenant_id ON estimates.generadores(tenant_id);
|
|
CREATE INDEX IF NOT EXISTS idx_generadores_est_concepto_id ON estimates.generadores(estimacion_concepto_id);
|
|
CREATE INDEX IF NOT EXISTS idx_generadores_status ON estimates.generadores(status);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_anticipos_tenant_id ON estimates.anticipos(tenant_id);
|
|
CREATE INDEX IF NOT EXISTS idx_anticipos_contrato_id ON estimates.anticipos(contrato_id);
|
|
CREATE INDEX IF NOT EXISTS idx_anticipos_type ON estimates.anticipos(advance_type);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_amortizaciones_tenant_id ON estimates.amortizaciones(tenant_id);
|
|
CREATE INDEX IF NOT EXISTS idx_amortizaciones_anticipo_id ON estimates.amortizaciones(anticipo_id);
|
|
CREATE INDEX IF NOT EXISTS idx_amortizaciones_estimacion_id ON estimates.amortizaciones(estimacion_id);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_retenciones_tenant_id ON estimates.retenciones(tenant_id);
|
|
CREATE INDEX IF NOT EXISTS idx_retenciones_estimacion_id ON estimates.retenciones(estimacion_id);
|
|
CREATE INDEX IF NOT EXISTS idx_retenciones_type ON estimates.retenciones(retention_type);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_fondo_garantia_tenant_id ON estimates.fondo_garantia(tenant_id);
|
|
CREATE INDEX IF NOT EXISTS idx_fondo_garantia_contrato_id ON estimates.fondo_garantia(contrato_id);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_est_workflow_tenant_id ON estimates.estimacion_workflow(tenant_id);
|
|
CREATE INDEX IF NOT EXISTS idx_est_workflow_estimacion_id ON estimates.estimacion_workflow(estimacion_id);
|
|
|
|
-- ============================================================================
|
|
-- ROW LEVEL SECURITY (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;
|
|
|
|
DO $$ BEGIN
|
|
DROP POLICY IF EXISTS tenant_isolation_estimaciones ON estimates.estimaciones;
|
|
CREATE POLICY tenant_isolation_estimaciones ON estimates.estimaciones
|
|
FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
|
|
EXCEPTION WHEN undefined_object THEN NULL; END $$;
|
|
|
|
DO $$ BEGIN
|
|
DROP POLICY IF EXISTS tenant_isolation_est_conceptos ON estimates.estimacion_conceptos;
|
|
CREATE POLICY tenant_isolation_est_conceptos ON estimates.estimacion_conceptos
|
|
FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
|
|
EXCEPTION WHEN undefined_object THEN NULL; END $$;
|
|
|
|
DO $$ BEGIN
|
|
DROP POLICY IF EXISTS tenant_isolation_generadores ON estimates.generadores;
|
|
CREATE POLICY tenant_isolation_generadores ON estimates.generadores
|
|
FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
|
|
EXCEPTION WHEN undefined_object THEN NULL; END $$;
|
|
|
|
DO $$ BEGIN
|
|
DROP POLICY IF EXISTS tenant_isolation_anticipos ON estimates.anticipos;
|
|
CREATE POLICY tenant_isolation_anticipos ON estimates.anticipos
|
|
FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
|
|
EXCEPTION WHEN undefined_object THEN NULL; END $$;
|
|
|
|
DO $$ BEGIN
|
|
DROP POLICY IF EXISTS tenant_isolation_amortizaciones ON estimates.amortizaciones;
|
|
CREATE POLICY tenant_isolation_amortizaciones ON estimates.amortizaciones
|
|
FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
|
|
EXCEPTION WHEN undefined_object THEN NULL; END $$;
|
|
|
|
DO $$ BEGIN
|
|
DROP POLICY IF EXISTS tenant_isolation_retenciones ON estimates.retenciones;
|
|
CREATE POLICY tenant_isolation_retenciones ON estimates.retenciones
|
|
FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
|
|
EXCEPTION WHEN undefined_object THEN NULL; END $$;
|
|
|
|
DO $$ BEGIN
|
|
DROP POLICY IF EXISTS tenant_isolation_fondo_garantia ON estimates.fondo_garantia;
|
|
CREATE POLICY tenant_isolation_fondo_garantia ON estimates.fondo_garantia
|
|
FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
|
|
EXCEPTION WHEN undefined_object THEN NULL; END $$;
|
|
|
|
DO $$ BEGIN
|
|
DROP POLICY IF EXISTS tenant_isolation_est_workflow ON estimates.estimacion_workflow;
|
|
CREATE POLICY tenant_isolation_est_workflow ON estimates.estimacion_workflow
|
|
FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
|
|
EXCEPTION WHEN undefined_object THEN NULL; END $$;
|
|
|
|
-- ============================================================================
|
|
-- FUNCIONES
|
|
-- ============================================================================
|
|
|
|
-- Función: calcular totales de estimación
|
|
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;
|
|
v_tax DECIMAL(16,2);
|
|
v_total DECIMAL(16,2);
|
|
BEGIN
|
|
SELECT COALESCE(SUM(amount_current), 0) INTO v_subtotal
|
|
FROM estimates.estimacion_conceptos
|
|
WHERE estimacion_id = p_estimacion_id AND deleted_at IS NULL;
|
|
|
|
SELECT COALESCE(SUM(amount), 0) INTO v_advance
|
|
FROM estimates.amortizaciones
|
|
WHERE estimacion_id = p_estimacion_id AND deleted_at IS NULL;
|
|
|
|
SELECT COALESCE(SUM(amount), 0) INTO v_retention
|
|
FROM estimates.retenciones
|
|
WHERE estimacion_id = p_estimacion_id AND deleted_at IS NULL;
|
|
|
|
v_tax := v_subtotal * v_tax_rate;
|
|
v_total := v_subtotal + v_tax - v_advance - v_retention;
|
|
|
|
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 = NOW()
|
|
WHERE id = p_estimacion_id;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
-- ============================================================================
|
|
-- COMENTARIOS
|
|
-- ============================================================================
|
|
|
|
COMMENT ON SCHEMA estimates IS 'Schema de estimaciones, anticipos y retenciones de obra';
|
|
COMMENT ON TABLE estimates.estimaciones IS 'Estimaciones de obra periódicas';
|
|
COMMENT ON TABLE estimates.estimacion_conceptos IS 'Líneas de concepto por estimación';
|
|
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 estimación';
|
|
COMMENT ON TABLE estimates.retenciones IS 'Retenciones aplicadas a estimaciones';
|
|
COMMENT ON TABLE estimates.fondo_garantia IS 'Fondo de garantía acumulado por contrato';
|
|
COMMENT ON TABLE estimates.estimacion_workflow IS 'Historial de workflow de estimaciones';
|
|
|
|
-- ============================================================================
|
|
-- FIN DEL SCHEMA ESTIMATES
|
|
-- Total tablas: 8
|
|
-- ============================================================================
|