feat: agregar control de visibilidad del total tarifado
This commit is contained in:
@@ -0,0 +1,248 @@
|
||||
-- =========================================================
|
||||
-- TABLERO CDC - Visibilidad del Total Tarifado
|
||||
-- Ejecutar en Supabase SQL Editor antes de desplegar esta versión.
|
||||
--
|
||||
-- Objetivo:
|
||||
-- - Por defecto, el Total Tarifado solo lo ven:
|
||||
-- * gmarrero@gomezleemarketing.com
|
||||
-- * jgomez@gomezleemarketing.com
|
||||
-- * iaracena@gomezleemarketing.com
|
||||
-- - Ellos pueden activar/desactivar un botón para mostrarlo temporalmente a todos.
|
||||
-- - No expone montos internos por proyecto; solo habilita/oculta el resumen global/filtrado.
|
||||
-- =========================================================
|
||||
|
||||
create table if not exists public.tablero_cdc_app_settings (
|
||||
key text primary key,
|
||||
value jsonb not null default '{}'::jsonb,
|
||||
updated_by uuid references auth.users(id),
|
||||
updated_at timestamptz not null default now()
|
||||
);
|
||||
|
||||
insert into public.tablero_cdc_app_settings (key, value)
|
||||
values ('pricing_summary_public', jsonb_build_object('enabled', false))
|
||||
on conflict (key) do nothing;
|
||||
|
||||
alter table public.tablero_cdc_app_settings enable row level security;
|
||||
|
||||
drop policy if exists "tablero_cdc_app_settings_select_authenticated" on public.tablero_cdc_app_settings;
|
||||
drop policy if exists "tablero_cdc_app_settings_insert_summary_controllers" on public.tablero_cdc_app_settings;
|
||||
drop policy if exists "tablero_cdc_app_settings_update_summary_controllers" on public.tablero_cdc_app_settings;
|
||||
drop policy if exists "tablero_cdc_app_settings_delete_none" on public.tablero_cdc_app_settings;
|
||||
|
||||
create policy "tablero_cdc_app_settings_select_authenticated"
|
||||
on public.tablero_cdc_app_settings
|
||||
for select
|
||||
to authenticated
|
||||
using (true);
|
||||
|
||||
create policy "tablero_cdc_app_settings_insert_summary_controllers"
|
||||
on public.tablero_cdc_app_settings
|
||||
for insert
|
||||
to authenticated
|
||||
with check (
|
||||
key = 'pricing_summary_public'
|
||||
and lower(coalesce(auth.jwt() ->> 'email', '')) in (
|
||||
'gmarrero@gomezleemarketing.com',
|
||||
'jgomez@gomezleemarketing.com',
|
||||
'iaracena@gomezleemarketing.com'
|
||||
)
|
||||
);
|
||||
|
||||
create policy "tablero_cdc_app_settings_update_summary_controllers"
|
||||
on public.tablero_cdc_app_settings
|
||||
for update
|
||||
to authenticated
|
||||
using (
|
||||
key = 'pricing_summary_public'
|
||||
and lower(coalesce(auth.jwt() ->> 'email', '')) in (
|
||||
'gmarrero@gomezleemarketing.com',
|
||||
'jgomez@gomezleemarketing.com',
|
||||
'iaracena@gomezleemarketing.com'
|
||||
)
|
||||
)
|
||||
with check (
|
||||
key = 'pricing_summary_public'
|
||||
and lower(coalesce(auth.jwt() ->> 'email', '')) in (
|
||||
'gmarrero@gomezleemarketing.com',
|
||||
'jgomez@gomezleemarketing.com',
|
||||
'iaracena@gomezleemarketing.com'
|
||||
)
|
||||
);
|
||||
|
||||
create policy "tablero_cdc_app_settings_delete_none"
|
||||
on public.tablero_cdc_app_settings
|
||||
for delete
|
||||
to authenticated
|
||||
using (false);
|
||||
|
||||
create or replace function public.set_tablero_cdc_app_settings_updated_at()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
as $$
|
||||
begin
|
||||
new.updated_at = now();
|
||||
new.updated_by = auth.uid();
|
||||
return new;
|
||||
end;
|
||||
$$;
|
||||
|
||||
drop trigger if exists trg_tablero_cdc_app_settings_updated_at on public.tablero_cdc_app_settings;
|
||||
|
||||
create trigger trg_tablero_cdc_app_settings_updated_at
|
||||
before insert or update on public.tablero_cdc_app_settings
|
||||
for each row
|
||||
execute function public.set_tablero_cdc_app_settings_updated_at();
|
||||
|
||||
create or replace function public.tablero_cdc_set_pricing_summary_public(p_enabled boolean)
|
||||
returns jsonb
|
||||
language plpgsql
|
||||
security definer
|
||||
set search_path = public
|
||||
as $$
|
||||
declare
|
||||
v_email text := lower(coalesce(auth.jwt() ->> 'email', ''));
|
||||
v_enabled boolean := coalesce(p_enabled, false);
|
||||
begin
|
||||
if v_email not in (
|
||||
'gmarrero@gomezleemarketing.com',
|
||||
'jgomez@gomezleemarketing.com',
|
||||
'iaracena@gomezleemarketing.com'
|
||||
) then
|
||||
raise exception 'No tienes permiso para cambiar la visibilidad del total tarifado.';
|
||||
end if;
|
||||
|
||||
insert into public.tablero_cdc_app_settings (key, value, updated_by, updated_at)
|
||||
values (
|
||||
'pricing_summary_public',
|
||||
jsonb_build_object('enabled', v_enabled),
|
||||
auth.uid(),
|
||||
now()
|
||||
)
|
||||
on conflict (key)
|
||||
do update set
|
||||
value = excluded.value,
|
||||
updated_by = auth.uid(),
|
||||
updated_at = now();
|
||||
|
||||
return jsonb_build_object('enabled', v_enabled);
|
||||
end;
|
||||
$$;
|
||||
|
||||
grant select on public.tablero_cdc_app_settings to authenticated;
|
||||
grant execute on function public.tablero_cdc_set_pricing_summary_public(boolean) to authenticated;
|
||||
|
||||
-- Reemplaza la RPC de resumen para respetar visibilidad pública temporal.
|
||||
create or replace function public.tablero_cdc_get_pricing_summary(
|
||||
p_tab text default 'todos',
|
||||
p_search text default '',
|
||||
p_country text default '',
|
||||
p_brand text default '',
|
||||
p_client text default '',
|
||||
p_cm text default ''
|
||||
)
|
||||
returns jsonb
|
||||
language sql
|
||||
stable
|
||||
security invoker
|
||||
set search_path = public
|
||||
as $$
|
||||
with visibility as (
|
||||
select coalesce((value ->> 'enabled')::boolean, false) as is_public
|
||||
from public.tablero_cdc_app_settings
|
||||
where key = 'pricing_summary_public'
|
||||
),
|
||||
allowed as (
|
||||
select
|
||||
lower(coalesce(auth.jwt() ->> 'email', '')) in (
|
||||
'gmarrero@gomezleemarketing.com',
|
||||
'jgomez@gomezleemarketing.com',
|
||||
'iaracena@gomezleemarketing.com'
|
||||
)
|
||||
or coalesce((select is_public from visibility), false) as can_view_pricing
|
||||
),
|
||||
params as (
|
||||
select
|
||||
lower(coalesce(nullif(trim(p_tab), ''), 'todos')) as tab,
|
||||
trim(coalesce(p_search, '')) as search_text,
|
||||
trim(coalesce(p_country, '')) as country_filter,
|
||||
trim(coalesce(p_brand, '')) as brand_filter,
|
||||
trim(coalesce(p_client, '')) as client_filter,
|
||||
trim(coalesce(p_cm, '')) as cm_filter
|
||||
),
|
||||
base_filtered as (
|
||||
select p.*
|
||||
from public.tablero_cdc_projects p
|
||||
cross join params prm
|
||||
where
|
||||
case
|
||||
when prm.tab in ('abiertos', 'activos', 'active', 'open') then
|
||||
coalesce(nullif(trim(p.status), ''), 'Activo') = 'Activo'
|
||||
when prm.tab in ('cerrados', 'closed') then
|
||||
coalesce(nullif(trim(p.status), ''), 'Activo') <> 'Activo'
|
||||
else
|
||||
true
|
||||
end
|
||||
and (
|
||||
prm.search_text = ''
|
||||
or coalesce(p.title, '') ilike '%' || prm.search_text || '%'
|
||||
or coalesce(p.client, '') ilike '%' || prm.search_text || '%'
|
||||
or coalesce(p.brand, '') ilike '%' || prm.search_text || '%'
|
||||
or coalesce(p.country, '') ilike '%' || prm.search_text || '%'
|
||||
or coalesce(p.requested_by, '') ilike '%' || prm.search_text || '%'
|
||||
or coalesce(p.country_manager, '') ilike '%' || prm.search_text || '%'
|
||||
or coalesce(p.description, '') ilike '%' || prm.search_text || '%'
|
||||
)
|
||||
),
|
||||
filtered as (
|
||||
select bf.*
|
||||
from base_filtered bf
|
||||
cross join params prm
|
||||
where
|
||||
(prm.country_filter = '' or coalesce(bf.country, '') ilike '%' || prm.country_filter || '%')
|
||||
and (prm.brand_filter = '' or coalesce(bf.brand, '') ilike '%' || prm.brand_filter || '%')
|
||||
and (prm.client_filter = '' or coalesce(bf.client, '') ilike '%' || prm.client_filter || '%')
|
||||
and (prm.cm_filter = '' or coalesce(bf.country_manager, '') ilike '%' || prm.cm_filter || '%')
|
||||
),
|
||||
totals as (
|
||||
select
|
||||
count(*)::integer as project_count,
|
||||
coalesce(
|
||||
sum(
|
||||
greatest(
|
||||
coalesce(nullif(trim(internal_amount::text), '')::numeric, 0),
|
||||
0
|
||||
)
|
||||
),
|
||||
0
|
||||
)::numeric as total_amount
|
||||
from filtered
|
||||
)
|
||||
select case
|
||||
when (select can_view_pricing from allowed) then
|
||||
jsonb_build_object(
|
||||
'total_amount', (select total_amount from totals),
|
||||
'project_count', (select project_count from totals)
|
||||
)
|
||||
else
|
||||
jsonb_build_object(
|
||||
'total_amount', 0,
|
||||
'project_count', 0
|
||||
)
|
||||
end;
|
||||
$$;
|
||||
|
||||
grant execute on function public.tablero_cdc_get_pricing_summary(text, text, text, text, text, text) to authenticated;
|
||||
|
||||
-- Intenta habilitar realtime para que el cambio de visible/oculto se refleje sin recargar.
|
||||
-- Si la publicación ya existe o la tabla ya está agregada, no hace nada.
|
||||
do $$
|
||||
begin
|
||||
alter publication supabase_realtime add table public.tablero_cdc_app_settings;
|
||||
exception
|
||||
when duplicate_object then null;
|
||||
when undefined_object then null;
|
||||
end $$;
|
||||
|
||||
select
|
||||
'Visibilidad del Total Tarifado lista' as status,
|
||||
(select value from public.tablero_cdc_app_settings where key = 'pricing_summary_public') as pricing_summary_public;
|
||||
Reference in New Issue
Block a user