-- LETRERO DE MESA SIN COBRAR (2026-07-27, pedido de Gilberto)
-- La pantalla de Mesas solo decia "Ya se sirvio todo, falta cobrar", en chiquito,
-- sin monto y sin decir desde CUANDO. Y solo salia si TODOS los pedidos estaban
-- marcados 'entregado', cosa que con la cocina de papel casi nadie hace: por eso
-- una mesa con 3 horas y saldo se veia igualita a una de 8 minutos.
-- mis_cuentas_mesa gana servido_en (cuando se sirvio lo ultimo) para que el panel
-- pueda gritar "se sirvio hace 45 min y nadie ha cobrado".
-- Se dropea antes de crear porque cambia el RETURNS TABLE (CREATE OR REPLACE no
-- deja cambiar el tipo de retorno).
begin;

drop function if exists public.mis_cuentas_mesa(uuid);

CREATE OR REPLACE FUNCTION public.mis_cuentas_mesa(p_restaurante_id uuid)
 RETURNS TABLE(id uuid, mesa text, estado text, total_usd numeric, tasa_bs numeric, abierta_en timestamp with time zone, pago_solicitado_en timestamp with time zone, metodo_pago text, referencia text, comprobante_url text, n_pedidos integer, mesero_id uuid, mesero_nombre text, pagado_usd numeric, comensales integer, modo_cuenta text, por_revisar_usd numeric, abierta_por text, todo_entregado boolean, perdida_usd numeric, servido_en timestamp with time zone)
 LANGUAGE sql
 STABLE SECURITY DEFINER
 SET search_path TO 'public'
AS $function$
  select c.id, c.mesa, c.estado,
    coalesce((select sum(p.total_usd) from public.pedidos p where p.cuenta_id = c.id and p.estado <> 'cancelado'), 0),
    r.tasa_bs, c.abierta_en, c.pago_solicitado_en, c.metodo_pago, c.referencia, c.comprobante_url,
    (select count(*)::int from public.pedidos p where p.cuenta_id = c.id and p.estado <> 'cancelado'),
    c.mesero_id, c.mesero_nombre,
    coalesce((select sum(pm.monto_usd) from public.pagos_mesa pm where pm.cuenta_id = c.id and pm.verificado and pm.metodo <> 'perdida'), 0),
    c.comensales, c.modo_cuenta,
    coalesce((select sum(pm.monto_usd) from public.pagos_mesa pm where pm.cuenta_id = c.id and not pm.verificado), 0),
    coalesce(
      (select cm.nombre from public.comensales_mesa cm where cm.cuenta_id = c.id order by cm.orden limit 1),
      (select p.cliente_nombre from public.pedidos p where p.cuenta_id = c.id and p.estado <> 'cancelado' order by p.recibido_en limit 1)
    ),
    (
      exists (select 1 from public.pedidos p where p.cuenta_id = c.id and p.estado = 'entregado')
      and not exists (select 1 from public.pedidos p where p.cuenta_id = c.id and p.estado not in ('entregado', 'cancelado'))
    ),
    coalesce((select sum(pm.monto_usd) from public.pagos_mesa pm where pm.cuenta_id = c.id and pm.metodo = 'perdida'), 0),
    -- Cuando se sirvio lo ultimo: con eso el panel sabe hace CUANTO esta la
    -- mesa lista para cobrar, no solo que lo esta.
    (select max(p.entregado_en) from public.pedidos p where p.cuenta_id = c.id and p.estado = 'entregado')
  from public.cuentas_mesa c
  join public.restaurantes r on r.id = c.restaurante_id
  where c.restaurante_id = p_restaurante_id
    and c.estado <> 'cerrada'
    and public.fn_mesa_de_staff(c.mesero_id, c.restaurante_id)
  order by c.abierta_en;
$function$
;

grant execute on function public.mis_cuentas_mesa(uuid) to anon, authenticated, service_role;

commit;
