-- ============================================================================ -- PURCHASE EXTENSIONS - FASE 8 ERP-Core -- ERP Clínicas (Base Genérica) -- ============================================================================ -- Fecha: 2026-01-04 -- Versión: 1.0 -- ============================================================================ -- Schema CREATE SCHEMA IF NOT EXISTS purchase; -- ============================================================================ -- TABLAS -- ============================================================================ -- Información de proveedores por producto CREATE TABLE IF NOT EXISTS purchase.product_supplierinfo ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), tenant_id UUID NOT NULL, partner_id UUID, product_id UUID, product_name VARCHAR(200), product_code VARCHAR(50), -- Precios y cantidades min_qty NUMERIC(10,2) DEFAULT 1, price NUMERIC(12,4) NOT NULL, currency_id UUID, -- Tiempos delay INTEGER DEFAULT 1, date_start DATE, date_end DATE, -- Extensiones clínica aplica_iva BOOLEAN DEFAULT true, requiere_receta BOOLEAN DEFAULT false, tiempo_entrega_dias INTEGER DEFAULT 1, -- Control sequence INTEGER DEFAULT 10, active BOOLEAN DEFAULT true, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); COMMENT ON TABLE purchase.product_supplierinfo IS 'Información de productos por proveedor - FASE 8'; COMMENT ON COLUMN purchase.product_supplierinfo.requiere_receta IS 'El producto requiere receta médica'; COMMENT ON COLUMN purchase.product_supplierinfo.tiempo_entrega_dias IS 'Días estimados de entrega'; -- ============================================================================ -- CAMPOS ADICIONALES A PURCHASE_ORDERS (si existe) -- ============================================================================ DO $$ BEGIN IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = 'purchase' AND table_name = 'purchase_orders') THEN -- origin IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = 'purchase' AND table_name = 'purchase_orders' AND column_name = 'origin') THEN ALTER TABLE purchase.purchase_orders ADD COLUMN origin VARCHAR(100); END IF; -- partner_ref IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = 'purchase' AND table_name = 'purchase_orders' AND column_name = 'partner_ref') THEN ALTER TABLE purchase.purchase_orders ADD COLUMN partner_ref VARCHAR(100); END IF; -- date_approve IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = 'purchase' AND table_name = 'purchase_orders' AND column_name = 'date_approve') THEN ALTER TABLE purchase.purchase_orders ADD COLUMN date_approve TIMESTAMPTZ; END IF; -- receipt_status IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = 'purchase' AND table_name = 'purchase_orders' AND column_name = 'receipt_status') THEN ALTER TABLE purchase.purchase_orders ADD COLUMN receipt_status VARCHAR(20); END IF; END IF; END $$; -- ============================================================================ -- FUNCIONES -- ============================================================================ -- Función para crear movimientos de stock CREATE OR REPLACE FUNCTION purchase.action_create_stock_moves(p_order_id UUID) RETURNS JSONB LANGUAGE plpgsql SECURITY DEFINER AS $$ DECLARE v_result JSONB := '{"moves_created": 0, "errors": []}'::JSONB; v_move_count INTEGER := 0; BEGIN -- Verificar que la orden existe IF NOT EXISTS ( SELECT 1 FROM purchase.purchase_orders WHERE id = p_order_id ) THEN v_result := jsonb_set(v_result, '{errors}', v_result->'errors' || '["Orden de compra no encontrada"]'::JSONB); RETURN v_result; END IF; -- Aquí se crearían los movimientos de stock -- La implementación depende de la estructura de inventory.stock_moves v_result := jsonb_set(v_result, '{moves_created}', to_jsonb(v_move_count)); v_result := jsonb_set(v_result, '{status}', '"success"'::JSONB); RETURN v_result; END; $$; COMMENT ON FUNCTION purchase.action_create_stock_moves IS 'Crea movimientos de stock desde orden de compra - FASE 8'; -- ============================================================================ -- ÍNDICES -- ============================================================================ CREATE INDEX IF NOT EXISTS idx_product_supplierinfo_tenant ON purchase.product_supplierinfo(tenant_id); CREATE INDEX IF NOT EXISTS idx_product_supplierinfo_partner ON purchase.product_supplierinfo(partner_id); CREATE INDEX IF NOT EXISTS idx_product_supplierinfo_product ON purchase.product_supplierinfo(product_id); CREATE INDEX IF NOT EXISTS idx_product_supplierinfo_dates ON purchase.product_supplierinfo(tenant_id, date_start, date_end); -- ============================================================================ -- RLS -- ============================================================================ ALTER TABLE purchase.product_supplierinfo ENABLE ROW LEVEL SECURITY; DROP POLICY IF EXISTS tenant_isolation_supplierinfo ON purchase.product_supplierinfo; CREATE POLICY tenant_isolation_supplierinfo ON purchase.product_supplierinfo USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID); -- ============================================================================ -- FIN PURCHASE EXTENSIONS -- ============================================================================