erp-clinicas-database-v2/schemas/07-purchase-ext-fase8-schema-ddl.sql
rckrdmrd cf07a84e26 Migración desde erp-clinicas/database - Estándar multi-repo v2
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 08:12:00 -06:00

149 lines
5.8 KiB
PL/PgSQL

-- ============================================================================
-- 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
-- ============================================================================