-- REPORTE DE IVA DEL PERIODO (2026-07-28)
-- Lo que el negocio necesita para declarar: cuanto vendio, cuanto de eso es base
-- imponible y cuanto es impuesto, separado por alicuota. Sale del desglose que
-- quedo CONGELADO en cada venta, no de recalcular con la alicuota de hoy.
-- Solo el dueño (o admin): mismo candado que reporte_pagos.
begin;

drop function if exists public.reporte_iva(uuid, timestamptz, timestamptz);

create or replace function public.reporte_iva(
  p_restaurante_id uuid,
  p_desde timestamptz,
  p_hasta timestamptz default now()
)
returns table(
  alicuota numeric,
  pedidos integer,
  base_usd numeric,
  iva_usd numeric,
  total_usd numeric
)
language plpgsql
stable
security definer
set search_path to 'public'
as $fn$
begin
  if not (public.fn_es_dueno_de(p_restaurante_id) or public.fn_es_admin()) then
    raise exception 'Sin permiso';
  end if;

  return query
  with renglones as (
    -- Lo vendido, renglon por renglon
    select p.id as pedido_id,
           coalesce(pi.iva_alicuota, p.iva_alicuota, 16) as alic,
           coalesce(pi.base_usd, 0) as base,
           coalesce(pi.iva_usd, 0) as iva
      from public.pedidos p
      join public.pedido_items pi on pi.pedido_id = p.id
     where p.restaurante_id = p_restaurante_id
       and p.estado <> 'cancelado'
       and p.recibido_en >= p_desde
       and p.recibido_en < p_hasta
       and p.base_imponible_usd is not null
    union all
    -- El delivery cobrado: es la diferencia entre el total fiscal del pedido y
    -- la suma de sus renglones (asi no hace falta guardarlo aparte).
    select p.id,
           coalesce(p.iva_alicuota, 16),
           p.base_imponible_usd - coalesce((select sum(x.base_usd) from public.pedido_items x where x.pedido_id = p.id), 0),
           p.iva_usd - coalesce((select sum(x.iva_usd) from public.pedido_items x where x.pedido_id = p.id), 0)
      from public.pedidos p
     where p.restaurante_id = p_restaurante_id
       and p.estado <> 'cancelado'
       and p.recibido_en >= p_desde
       and p.recibido_en < p_hasta
       and p.base_imponible_usd is not null
       and coalesce(p.costo_delivery_usd, 0) > 0
  )
  select r.alic,
         count(distinct r.pedido_id)::int,
         round(sum(r.base), 2),
         round(sum(r.iva), 2),
         round(sum(r.base + r.iva), 2)
    from renglones r
   group by r.alic
   order by r.alic;
end;
$fn$;

revoke execute on function public.reporte_iva(uuid, timestamptz, timestamptz) from anon;
grant execute on function public.reporte_iva(uuid, timestamptz, timestamptz) to authenticated, service_role;

commit;
