-- ===================================================== -- SCHEMA: purchase (EXTENSION) -- PROPOSITO: Extensiones de compras para construccion -- MODULOS: MAI-004 (Compras e Inventarios) -- FECHA: 2025-11-24 -- TIPO: Extension del ERP Generico (MGN-006) -- ===================================================== -- NOTA: Este archivo contiene SOLO las extensiones especificas -- de construccion. Las tablas base estan en el ERP Generico. -- ===================================================== -- TABLES - EXTENSIONES CONSTRUCCION -- ===================================================== -- Tabla: purchase_order_construction (extension de ordenes de compra) -- Extiende: purchase.purchase_orders CREATE TABLE purchase.purchase_order_construction ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE, purchase_order_id UUID NOT NULL, -- FK a purchase.purchase_orders (ERP Generico) fraccionamiento_id UUID REFERENCES construction.fraccionamientos(id), requisicion_id UUID REFERENCES inventory.requisiciones_obra(id), -- Entregas delivery_location VARCHAR(255), -- Ubicacion de entrega en obra delivery_contact VARCHAR(100), -- Contacto para entrega delivery_phone VARCHAR(20), -- Validacion received_by UUID REFERENCES auth.users(id), received_at TIMESTAMP, quality_approved BOOLEAN, quality_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_po_construction_po_id UNIQUE (purchase_order_id) ); -- Tabla: supplier_construction (extension de proveedores) -- Extiende: purchase.suppliers CREATE TABLE purchase.supplier_construction ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE, supplier_id UUID NOT NULL, -- FK a purchase.suppliers (ERP Generico) -- Categorias de construccion is_materials_supplier BOOLEAN DEFAULT FALSE, is_services_supplier BOOLEAN DEFAULT FALSE, is_equipment_supplier BOOLEAN DEFAULT FALSE, specialties TEXT[], -- Array de especialidades: ['concreto', 'acero', 'electricidad'] -- Evaluacion quality_rating DECIMAL(3,2), -- Calificacion calidad 0-5 delivery_rating DECIMAL(3,2), -- Calificacion entregas 0-5 price_rating DECIMAL(3,2), -- Calificacion precios 0-5 overall_rating DECIMAL(3,2) GENERATED ALWAYS AS ( (COALESCE(quality_rating, 0) + COALESCE(delivery_rating, 0) + COALESCE(price_rating, 0)) / 3 ) STORED, last_evaluation_date DATE, -- Credito credit_limit DECIMAL(14,2), payment_days INTEGER DEFAULT 30, -- Documentos has_valid_documents BOOLEAN DEFAULT FALSE, documents_expiry_date DATE, -- 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_supplier_construction_supplier_id UNIQUE (supplier_id) ); -- Tabla: comparativo_cotizaciones (cuadro comparativo) CREATE TABLE purchase.comparativo_cotizaciones ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE, requisicion_id UUID REFERENCES inventory.requisiciones_obra(id), code VARCHAR(30) NOT NULL, name VARCHAR(255) NOT NULL, comparison_date DATE NOT NULL, status VARCHAR(20) NOT NULL DEFAULT 'draft', -- draft, in_progress, completed, approved winner_supplier_id UUID, -- FK a purchase.suppliers approved_by UUID REFERENCES auth.users(id), approved_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_comparativo_code_tenant UNIQUE (tenant_id, code) ); -- Tabla: comparativo_proveedores (proveedores en comparativo) CREATE TABLE purchase.comparativo_proveedores ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE, comparativo_id UUID NOT NULL REFERENCES purchase.comparativo_cotizaciones(id) ON DELETE CASCADE, supplier_id UUID NOT NULL, -- FK a purchase.suppliers quotation_number VARCHAR(50), quotation_date DATE, delivery_days INTEGER, payment_conditions VARCHAR(100), total_amount DECIMAL(16,2), is_selected BOOLEAN DEFAULT FALSE, evaluation_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) ); -- Tabla: comparativo_productos (productos en comparativo) CREATE TABLE purchase.comparativo_productos ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE, comparativo_proveedor_id UUID NOT NULL REFERENCES purchase.comparativo_proveedores(id) ON DELETE CASCADE, product_id UUID NOT NULL, -- FK a inventory.products quantity DECIMAL(12,4) NOT NULL, unit_price DECIMAL(12,4) NOT NULL, total_price DECIMAL(14,2) GENERATED ALWAYS AS (quantity * 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) ); -- ===================================================== -- INDICES -- ===================================================== -- Purchase Order Construction CREATE INDEX idx_po_construction_tenant_id ON purchase.purchase_order_construction(tenant_id); CREATE INDEX idx_po_construction_po_id ON purchase.purchase_order_construction(purchase_order_id); CREATE INDEX idx_po_construction_fraccionamiento_id ON purchase.purchase_order_construction(fraccionamiento_id); CREATE INDEX idx_po_construction_requisicion_id ON purchase.purchase_order_construction(requisicion_id); -- Supplier Construction CREATE INDEX idx_supplier_construction_tenant_id ON purchase.supplier_construction(tenant_id); CREATE INDEX idx_supplier_construction_supplier_id ON purchase.supplier_construction(supplier_id); CREATE INDEX idx_supplier_construction_rating ON purchase.supplier_construction(overall_rating); -- Comparativo Cotizaciones CREATE INDEX idx_comparativo_tenant_id ON purchase.comparativo_cotizaciones(tenant_id); CREATE INDEX idx_comparativo_requisicion_id ON purchase.comparativo_cotizaciones(requisicion_id); CREATE INDEX idx_comparativo_status ON purchase.comparativo_cotizaciones(status); -- Comparativo Proveedores CREATE INDEX idx_comparativo_prov_tenant_id ON purchase.comparativo_proveedores(tenant_id); CREATE INDEX idx_comparativo_prov_comparativo_id ON purchase.comparativo_proveedores(comparativo_id); CREATE INDEX idx_comparativo_prov_supplier_id ON purchase.comparativo_proveedores(supplier_id); -- ===================================================== -- ROW LEVEL SECURITY (RLS) -- ===================================================== ALTER TABLE purchase.purchase_order_construction ENABLE ROW LEVEL SECURITY; ALTER TABLE purchase.supplier_construction ENABLE ROW LEVEL SECURITY; ALTER TABLE purchase.comparativo_cotizaciones ENABLE ROW LEVEL SECURITY; ALTER TABLE purchase.comparativo_proveedores ENABLE ROW LEVEL SECURITY; ALTER TABLE purchase.comparativo_productos ENABLE ROW LEVEL SECURITY; CREATE POLICY tenant_isolation_po_construction ON purchase.purchase_order_construction USING (tenant_id = get_current_tenant_id()); CREATE POLICY tenant_isolation_supplier_construction ON purchase.supplier_construction USING (tenant_id = get_current_tenant_id()); CREATE POLICY tenant_isolation_comparativo ON purchase.comparativo_cotizaciones USING (tenant_id = get_current_tenant_id()); CREATE POLICY tenant_isolation_comparativo_prov ON purchase.comparativo_proveedores USING (tenant_id = get_current_tenant_id()); CREATE POLICY tenant_isolation_comparativo_prod ON purchase.comparativo_productos USING (tenant_id = get_current_tenant_id()); -- ===================================================== -- COMENTARIOS -- ===================================================== COMMENT ON TABLE purchase.purchase_order_construction IS 'Extension: datos adicionales de OC para construccion'; COMMENT ON TABLE purchase.supplier_construction IS 'Extension: datos adicionales de proveedores para construccion'; COMMENT ON TABLE purchase.comparativo_cotizaciones IS 'Extension: cuadro comparativo de cotizaciones'; COMMENT ON TABLE purchase.comparativo_proveedores IS 'Extension: proveedores participantes en comparativo'; COMMENT ON TABLE purchase.comparativo_productos IS 'Extension: productos cotizados por proveedor'; -- ===================================================== -- FIN DE EXTENSIONES PURCHASE -- =====================================================