-- ============================================= -- Script SQL: Módulo de Colaboraciones Económicas -- Descripción: Crea las tablas para gestionar colaboraciones mensuales -- Autor: Sistema -- Fecha: 2026-02-01 -- ============================================= -- Tabla 1: Tipos de Colaboración (configurable) CREATE TABLE IF NOT EXISTS public.tipos_colaboracion ( id bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, nombre character varying(100) COLLATE pg_catalog."default" NOT NULL, descripcion text COLLATE pg_catalog."default", monto_sugerido decimal(10, 2) NOT NULL DEFAULT 0, activo boolean NOT NULL DEFAULT true, orden integer NOT NULL DEFAULT 0, creado_en timestamp with time zone NOT NULL DEFAULT now(), actualizado_en timestamp with time zone NOT NULL DEFAULT now(), CONSTRAINT pk_tipos_colaboracion PRIMARY KEY (id) ); COMMENT ON TABLE public.tipos_colaboracion IS 'Catálogo de tipos de colaboración (Transporte, Limpieza, etc.)'; COMMENT ON COLUMN public.tipos_colaboracion.nombre IS 'Nombre del tipo de colaboración'; COMMENT ON COLUMN public.tipos_colaboracion.monto_sugerido IS 'Cuota sugerida mensual'; COMMENT ON COLUMN public.tipos_colaboracion.orden IS 'Orden de presentación en UI'; -- Datos iniciales INSERT INTO public.tipos_colaboracion (nombre, descripcion, monto_sugerido, orden) VALUES ('Transporte', 'Colaboración mensual para transporte', 1.00, 1), ('Limpieza', 'Colaboración mensual para limpieza', 1.00, 2) ON CONFLICT DO NOTHING; -- ============================================= -- Tabla 2: Colaboraciones (cabecera de transacción) CREATE TABLE IF NOT EXISTS public.colaboraciones ( id bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, miembro_id bigint NOT NULL, fecha_registro timestamp with time zone NOT NULL DEFAULT now(), monto_total decimal(10, 2) NOT NULL, observaciones text COLLATE pg_catalog."default", registrado_por character varying(100) COLLATE pg_catalog."default", creado_en timestamp with time zone NOT NULL DEFAULT now(), actualizado_en timestamp with time zone NOT NULL DEFAULT now(), CONSTRAINT pk_colaboraciones PRIMARY KEY (id), CONSTRAINT fk_colaboraciones_miembro FOREIGN KEY (miembro_id) REFERENCES public.miembros (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE RESTRICT ); COMMENT ON TABLE public.colaboraciones IS 'Registro de transacciones de colaboración'; COMMENT ON COLUMN public.colaboraciones.miembro_id IS 'Miembro que realizó el pago'; COMMENT ON COLUMN public.colaboraciones.monto_total IS 'Monto total de la transacción'; COMMENT ON COLUMN public.colaboraciones.registrado_por IS 'Usuario que registró el pago'; -- Índices para optimizar búsquedas CREATE INDEX IF NOT EXISTS idx_colaboraciones_miembro ON public.colaboraciones(miembro_id); CREATE INDEX IF NOT EXISTS idx_colaboraciones_fecha ON public.colaboraciones(fecha_registro); -- ============================================= -- Tabla 3: Detalle de Colaboraciones (desglose mensual) CREATE TABLE IF NOT EXISTS public.detalle_colaboraciones ( id bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, colaboracion_id bigint NOT NULL, tipo_colaboracion_id bigint NOT NULL, mes integer NOT NULL, anio integer NOT NULL, monto decimal(10, 2) NOT NULL, creado_en timestamp with time zone NOT NULL DEFAULT now(), CONSTRAINT pk_detalle_colaboraciones PRIMARY KEY (id), CONSTRAINT fk_detalle_colaboracion FOREIGN KEY (colaboracion_id) REFERENCES public.colaboraciones (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE CASCADE, CONSTRAINT fk_detalle_tipo FOREIGN KEY (tipo_colaboracion_id) REFERENCES public.tipos_colaboracion (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE RESTRICT, CONSTRAINT chk_mes_valido CHECK (mes >= 1 AND mes <= 12), CONSTRAINT chk_anio_valido CHECK (anio >= 2000 AND anio <= 2100) ); COMMENT ON TABLE public.detalle_colaboraciones IS 'Desglose mensual de cada colaboración'; COMMENT ON COLUMN public.detalle_colaboraciones.mes IS 'Mes cubierto (1-12)'; COMMENT ON COLUMN public.detalle_colaboraciones.anio IS 'Año cubierto'; COMMENT ON COLUMN public.detalle_colaboraciones.monto IS 'Monto para este mes/tipo específico'; -- Índices para reportes y búsquedas CREATE INDEX IF NOT EXISTS idx_detalle_tipo ON public.detalle_colaboraciones(tipo_colaboracion_id); CREATE INDEX IF NOT EXISTS idx_detalle_periodo ON public.detalle_colaboraciones(anio, mes); -- Índice único para evitar duplicados (mismo mes/año/tipo en misma colaboración) CREATE UNIQUE INDEX IF NOT EXISTS idx_detalle_unico ON public.detalle_colaboraciones(colaboracion_id, tipo_colaboracion_id, mes, anio); -- ============================================= -- FIN DEL SCRIPT -- =============================================