-- EL CANDADO TIENE QUE DEJAR PASAR AL PROVEEDOR (2026-07-29)
--
-- Lo cazo la prueba del interruptor: el trigger que impide que el negocio se
-- cambie los datos fiscales tambien estaba frenando a fiscal.vincular_negocio,
-- que es justamente quien SI tiene derecho a ponerlos (copia el encabezado del
-- emisor al negocio al darlo de alta).
--
-- Se arregla diciendo la regla completa, no aflojando el candado: el cambio
-- pasa solo cuando viene marcado por el proveedor, y esa marca solo la puede
-- poner una funcion del esquema fiscal (que el negocio no puede ejecutar).
-- La marca es local a la transaccion: se borra sola al terminar.
begin;

create or replace function public.fn_proteger_datos_fiscales()
returns trigger
language plpgsql
security definer
set search_path to 'public', 'fiscal'
as $fn$
begin
  if new.rif is distinct from old.rif
     or new.razon_social is distinct from old.razon_social
     or new.domicilio_fiscal is distinct from old.domicilio_fiscal then
    -- El proveedor autorizado se identifica con esta marca de transaccion.
    if coalesce(current_setting('fiscal.cambio_autorizado', true), '') = '1' then
      return new;
    end if;
    if exists (select 1 from fiscal.negocios n
                join fiscal.emisores e on e.id = n.emisor_id
               where n.restaurante_id = old.id and e.activo) then
      raise exception 'Los datos fiscales de este negocio los administra el proveedor autorizado. Comunicate con el para cualquier cambio.';
    end if;
  end if;
  return new;
end;
$fn$;

create or replace function fiscal.vincular_negocio(
  p_restaurante_id uuid,
  p_rif text,
  p_serie text default null,
  p_quien text default null,
  p_nota text default null
)
returns jsonb
language plpgsql
security definer
set search_path to 'fiscal', 'public'
as $fn$
declare
  v_emisor record;
  v_rest   record;
begin
  select * into v_emisor from fiscal.emisores where rif = public.fn_rif_normalizado(p_rif);
  if not found then
    raise exception 'Ese RIF no esta dado de alta como cliente de la imprenta';
  end if;

  select id, nombre into v_rest from public.restaurantes where id = p_restaurante_id;
  if not found then
    raise exception 'No existe ese negocio en Gustito';
  end if;

  insert into fiscal.negocios (restaurante_id, emisor_id, serie, vinculado_por, nota)
    values (p_restaurante_id, v_emisor.id,
            upper(coalesce(nullif(trim(p_serie), ''), v_emisor.serie_asignada, 'A')),
            p_quien, p_nota)
    on conflict (restaurante_id) do update set
      emisor_id = excluded.emisor_id,
      serie = excluded.serie,
      vinculado_en = now(),
      vinculado_por = excluded.vinculado_por,
      nota = excluded.nota;

  -- El encabezado del documento sale de los datos del emisor, no de lo que el
  -- negocio haya escrito por su cuenta. Se copian una vez y quedan bajo llave.
  perform set_config('fiscal.cambio_autorizado', '1', true);
  update public.restaurantes
     set rif = v_emisor.rif,
         razon_social = v_emisor.razon_social,
         domicilio_fiscal = v_emisor.domicilio_fiscal
   where id = p_restaurante_id;
  perform set_config('fiscal.cambio_autorizado', '0', true);

  return jsonb_build_object('negocio', v_rest.nombre, 'rif', v_emisor.rif);
end;
$fn$;

commit;
