Files
cruce-cuentas-glm-centralizado/SUPABASE_Honduras_READY.sql
T

113 lines
10 KiB
PL/PgSQL

-- ============================================================
-- CRUCE DE CUENTAS GLM · HABILITAR HONDURAS (HN)
-- GT + TT + PA + SV + HN
-- ============================================================
-- Ejecutar en el SQL Editor del Supabase empresarial.
-- Conserva datos existentes y puede ejecutarse nuevamente de forma segura.
begin;
-- 1) Constraints de país: aliases, correcciones, históricos y accesos.
do $$
declare r record;
begin
if to_regclass('public.cruce_cuentas_bamboo_aliases') is null then raise exception 'No existe public.cruce_cuentas_bamboo_aliases.'; end if;
if to_regclass('public.cruce_cuentas_bamboo_correcciones') is null then raise exception 'No existe public.cruce_cuentas_bamboo_correcciones.'; end if;
if to_regclass('public.cruces_cuentas_gt_reportes') is null then raise exception 'No existe public.cruces_cuentas_gt_reportes.'; end if;
if to_regclass('public.cruce_cuentas_usuarios_autorizados') is null then raise exception 'No existe public.cruce_cuentas_usuarios_autorizados.'; end if;
for r in select conname from pg_constraint where conrelid='public.cruce_cuentas_bamboo_aliases'::regclass and contype='c' and pg_get_constraintdef(oid) ilike '%pais%' and pg_get_constraintdef(oid) ilike '%GT%' and pg_get_constraintdef(oid) not ilike '%HN%' loop
execute format('alter table public.cruce_cuentas_bamboo_aliases drop constraint %I',r.conname);
end loop;
alter table public.cruce_cuentas_bamboo_aliases drop constraint if exists ck_cruce_cuentas_bamboo_aliases_pais;
alter table public.cruce_cuentas_bamboo_aliases add constraint ck_cruce_cuentas_bamboo_aliases_pais check (upper(trim(pais)) in ('GT','TT','PA','SV','HN'));
for r in select conname from pg_constraint where conrelid='public.cruce_cuentas_bamboo_correcciones'::regclass and contype='c' and pg_get_constraintdef(oid) ilike '%pais%' and pg_get_constraintdef(oid) ilike '%GT%' and pg_get_constraintdef(oid) not ilike '%HN%' loop
execute format('alter table public.cruce_cuentas_bamboo_correcciones drop constraint %I',r.conname);
end loop;
alter table public.cruce_cuentas_bamboo_correcciones drop constraint if exists ck_cruce_cuentas_bamboo_correcciones_pais;
alter table public.cruce_cuentas_bamboo_correcciones add constraint ck_cruce_cuentas_bamboo_correcciones_pais check (upper(trim(pais)) in ('GT','TT','PA','SV','HN'));
for r in select conname from pg_constraint where conrelid='public.cruces_cuentas_gt_reportes'::regclass and contype='c' and pg_get_constraintdef(oid) ilike '%country%' and pg_get_constraintdef(oid) ilike '%GT%' and pg_get_constraintdef(oid) not ilike '%HN%' loop
execute format('alter table public.cruces_cuentas_gt_reportes drop constraint %I',r.conname);
end loop;
alter table public.cruces_cuentas_gt_reportes drop constraint if exists ck_cruces_cuentas_reportes_country;
alter table public.cruces_cuentas_gt_reportes add constraint ck_cruces_cuentas_reportes_country check (country is null or upper(trim(country)) in ('GT','TT','PA','SV','HN'));
-- La tabla de acceso usa text[] en paises.
alter table public.cruce_cuentas_usuarios_autorizados drop constraint if exists cruce_cuentas_paises_validos_check;
alter table public.cruce_cuentas_usuarios_autorizados add constraint cruce_cuentas_paises_validos_check check (paises is null or paises <@ array['GT','TT','PA','SV','HN']::text[]);
end;
$$;
-- 2) Dar HN a TODOS los usuarios autorizados actuales, preservando permisos.
update public.cruce_cuentas_usuarios_autorizados
set paises = case
when paises is null then array['GT','TT','PA','SV','HN']::text[]
when not ('HN'=any(paises)) then array_append(paises,'HN')
else paises
end,
updated_at=now();
-- 3) Alias BambooHR activos: cinco países.
create or replace function public.cruce_cuentas_bamboo_aliases_activos(p_pais text)
returns jsonb language sql stable security definer set search_path=public as $$
select jsonb_build_object('ok',true,'pais',upper(trim(coalesce(p_pais,''))),'aliases',coalesce(jsonb_agg(jsonb_build_object('id',a.id,'pais',a.pais,'nombre_origen',a.nombre_origen,'nombre_origen_normalizado',a.nombre_origen_normalizado,'cuenta_bancaria',a.cuenta_bancaria,'bamboo_employee_number',a.bamboo_employee_number,'bamboo_employee_id',a.bamboo_employee_id,'bamboo_nombre',a.bamboo_nombre,'motivo',a.motivo,'activo',a.activo) order by a.updated_at desc) filter (where a.id is not null),'[]'::jsonb))
from public.cruce_cuentas_bamboo_aliases a where a.activo=true and a.pais=upper(trim(coalesce(p_pais,''))) and upper(trim(coalesce(p_pais,''))) in ('GT','TT','PA','SV','HN');
$$;
revoke all on function public.cruce_cuentas_bamboo_aliases_activos(text) from public,anon,authenticated;
grant execute on function public.cruce_cuentas_bamboo_aliases_activos(text) to service_role;
-- 4) Históricos paginados: cinco países.
create index if not exists idx_cruces_cuentas_reportes_country_created on public.cruces_cuentas_gt_reportes(country,created_at desc);
create index if not exists idx_cruces_cuentas_reportes_country_status_created on public.cruces_cuentas_gt_reportes(country,estado,created_at desc);
create or replace function public.cruce_cuentas_get_historicos(p_country text,p_page integer default 1,p_page_size integer default 10,p_search text default null,p_status text default null)
returns jsonb language plpgsql security definer set search_path=public as $$
declare
v_country text := upper(trim(coalesce(p_country,'')));
v_page integer := greatest(coalesce(p_page,1),1);
v_page_size integer := least(greatest(coalesce(p_page_size,10),1),100);
v_offset integer;
v_search text := nullif(trim(coalesce(p_search,'')),'');
v_status text := nullif(trim(coalesce(p_status,'')),'');
v_total bigint; v_filtered_total bigint; v_reports jsonb;
begin
if v_country not in ('GT','TT','PA','SV','HN') then raise exception 'País no permitido: %',v_country; end if;
v_offset := (v_page-1)*v_page_size;
select count(*) into v_total from public.cruces_cuentas_gt_reportes r where upper(coalesce(r.country,'GT'))=v_country;
select count(*) into v_filtered_total from public.cruces_cuentas_gt_reportes r where upper(coalesce(r.country,'GT'))=v_country and (v_status is null or r.estado=v_status) and (v_search is null or coalesce(r.period_label,'') ilike '%'||v_search||'%' or coalesce(r.payroll_file_name,'') ilike '%'||v_search||'%' or coalesce(r.ejecutado_por_nombre,'') ilike '%'||v_search||'%' or coalesce(r.resuelto_por_nombre,'') ilike '%'||v_search||'%' or r.id::text ilike '%'||v_search||'%');
select coalesce(jsonb_agg((to_jsonb(q)-'detalle_banco_sin_bamboo') order by q.created_at desc),'[]'::jsonb) into v_reports from (select r.* from public.cruces_cuentas_gt_reportes r where upper(coalesce(r.country,'GT'))=v_country and (v_status is null or r.estado=v_status) and (v_search is null or coalesce(r.period_label,'') ilike '%'||v_search||'%' or coalesce(r.payroll_file_name,'') ilike '%'||v_search||'%' or coalesce(r.ejecutado_por_nombre,'') ilike '%'||v_search||'%' or coalesce(r.resuelto_por_nombre,'') ilike '%'||v_search||'%' or r.id::text ilike '%'||v_search||'%') order by r.created_at desc limit v_page_size offset v_offset) q;
return jsonb_build_object('ok',true,'country',v_country,'page',v_page,'page_size',v_page_size,'total',v_total,'filtered_total',v_filtered_total,'total_pages',greatest(ceil(v_filtered_total::numeric/v_page_size)::integer,1),'reports',v_reports);
end;
$$;
revoke all on function public.cruce_cuentas_get_historicos(text,integer,integer,text,text) from public,anon;
grant execute on function public.cruce_cuentas_get_historicos(text,integer,integer,text,text) to authenticated;
-- 5) Detalle Banco sin Bamboo de históricos.
create or replace function public.cruce_cuentas_get_banco_sin_bamboo_reporte(p_report_id text,p_country text)
returns jsonb language plpgsql stable security definer set search_path=public as $$
declare
v_country text := upper(trim(coalesce(p_country,'')));
v_report public.cruces_cuentas_gt_reportes%rowtype;
v_corrections jsonb := '[]'::jsonb;
begin
if auth.uid() is null then raise exception 'No autenticado.'; end if;
if v_country not in ('GT','TT','PA','SV','HN') then raise exception 'País no permitido: %',v_country; end if;
select r.* into v_report from public.cruces_cuentas_gt_reportes r where r.id::text=trim(coalesce(p_report_id,'')) and upper(coalesce(r.country,'GT'))=v_country limit 1;
if not found then return jsonb_build_object('ok',false,'message','No se encontró el reporte solicitado.'); end if;
select coalesce(jsonb_agg(jsonb_build_object('id',c.id,'pais',c.pais,'nombre_origen_principal',c.nombre_origen_principal,'nombres_origen',c.nombres_origen,'cuenta_bancaria',c.cuenta_bancaria,'bamboo_employee_number',c.bamboo_employee_number,'bamboo_nombre',c.bamboo_nombre,'estado',c.estado,'correo_enviado',c.correo_enviado,'correo_enviado_at',c.correo_enviado_at,'created_at',c.created_at) order by c.created_at desc),'[]'::jsonb) into v_corrections from public.cruce_cuentas_bamboo_correcciones c where c.pais=v_country and (c.execution_id=v_report.id::text or (nullif(trim(coalesce(c.execution_id,'')),'') is null and nullif(trim(coalesce(c.report_url,'')),'') is not null and c.report_url=v_report.report_url));
return jsonb_build_object('ok',true,'report',jsonb_build_object('id',v_report.id,'country',v_report.country,'period_label',v_report.period_label,'period_start',v_report.period_start,'period_end',v_report.period_end,'report_url',v_report.report_url,'banco_sin_bamboo',v_report.banco_sin_bamboo),'cases',coalesce(v_report.detalle_banco_sin_bamboo,'[]'::jsonb),'corrections',v_corrections);
end;
$$;
revoke all on function public.cruce_cuentas_get_banco_sin_bamboo_reporte(text,text) from public,anon;
grant execute on function public.cruce_cuentas_get_banco_sin_bamboo_reporte(text,text) to authenticated;
commit;
-- VALIDACIÓN (solo lectura)
select email,nombre,paises from public.cruce_cuentas_usuarios_autorizados order by email;
select public.cruce_cuentas_bamboo_aliases_activos('HN');
select public.cruce_cuentas_get_historicos('HN',1,10,null,null);
select conrelid::regclass as tabla,conname,pg_get_constraintdef(oid) as definicion from pg_constraint where conrelid in ('public.cruce_cuentas_bamboo_aliases'::regclass,'public.cruce_cuentas_bamboo_correcciones'::regclass,'public.cruces_cuentas_gt_reportes'::regclass,'public.cruce_cuentas_usuarios_autorizados'::regclass) and contype='c' order by 1,2;