-- El numero de control lo asigna la imprenta y es un TEXTO (art. 30 de la
-- 000102). La cola lo guardaba como bigint, asi que con una imprenta que no
-- devuelve digitos puros la confirmacion reventaba y la Estacion resellaba la
-- misma venta cada 10 segundos sin cerrarla nunca.

-- 1. la columna guarda el numero de control tal como lo entrega la imprenta
alter table fiscal.cola_gustito
  alter column numero_control type text using numero_control::text;

-- 2. la puerta lo recibe como texto (DROP antes: cambiar el tipo de un
--    parametro crearia un overload y PostgREST responderia HTTP 300)
drop function if exists fiscal.confirmar_sellado(text, text, uuid, bigint, bigint, text);

create or replace function fiscal.confirmar_sellado(
  p_llave text, p_rif text, p_cola_id uuid,
  p_numero_documento bigint, p_numero_control text, p_token text
) returns jsonb
language plpgsql security definer set search_path to 'fiscal', 'public'
as $fn$
declare v_emisor uuid;
begin
  v_emisor := fiscal.autenticar(p_llave, p_rif, 'estacion: confirmar');

  update fiscal.cola_gustito
     set estado = 'sellado', sellado_en = now(), ultimo_error = null,
         numero_documento = p_numero_documento,
         numero_control = nullif(btrim(p_numero_control), ''),
         token = p_token
   where id = p_cola_id and emisor_id = v_emisor;

  if not found then raise exception 'Esa venta no es de este emisor'; end if;
  return jsonb_build_object('ok', true);
end;
$fn$;

-- 3. el despachador deja de exigir que sea un numero
CREATE OR REPLACE FUNCTION public.fn_estacion(p_accion text, p_llave text, p_rif text, p_datos jsonb DEFAULT '{}'::jsonb)
 RETURNS jsonb
 LANGUAGE plpgsql
 SECURITY DEFINER
 SET search_path TO 'public', 'fiscal'
AS $function$
begin
  case p_accion
    when 'pendientes' then
      return fiscal.ventas_pendientes(p_llave, p_rif, coalesce((p_datos->>'limite')::int, 50));
    when 'confirmar' then
      return fiscal.confirmar_sellado(p_llave, p_rif, (p_datos->>'cola_id')::uuid,
        nullif(p_datos->>'numero_documento','')::bigint,
        nullif(p_datos->>'numero_control',''),
        p_datos->>'token');
    when 'error' then
      return fiscal.reportar_error(p_llave, p_rif, (p_datos->>'cola_id')::uuid, p_datos->>'error');
    when 'anulaciones' then
      return fiscal.anulaciones_pendientes(p_llave, p_rif, coalesce((p_datos->>'limite')::int, 20));
    when 'anulacion_resultado' then
      return fiscal.anulacion_resultado(p_llave, p_rif, (p_datos->>'anulacion_id')::uuid,
        coalesce((p_datos->>'ok')::boolean, false),
        nullif(p_datos->>'numero_nota','')::bigint,
        p_datos->>'error');
    when 'latido' then
      return fiscal.latido(p_llave, p_rif, p_datos);
    when 'rescatar' then
      perform fiscal.autenticar(p_llave, p_rif, 'estacion: rescate');
      return jsonb_build_object('rescatadas', fiscal.rescatar_sin_encolar(coalesce((p_datos->>'horas')::int, 72)));
    when 'respaldo_hasta' then
      return fiscal.respaldo_hasta(p_llave, p_rif);
    when 'respaldo_guardar' then
      return fiscal.guardar_respaldo(p_llave, p_rif, coalesce(p_datos->'lineas', '[]'::jsonb));
    when 'respaldo_bajar' then
      return fiscal.bajar_respaldo(p_llave, p_rif, (p_datos->>'desde')::int, (p_datos->>'limite')::int);
    else
      raise exception 'Accion desconocida';
  end case;
end;
$function$
;
