Files
acmcc/supabase/migrations/20260607180000_backfill_imported_bill_approvers.sql
admin 6f68619b9c Bill approvals: backfill imported bills' approvers + auto-create on import
Approved/paid bills that never went through in-app approval (imports, bulk
loads) had no approver row, so the Approvers column was blank. Backfill a
synthetic approver: 'Imported' for system imports (created_by null), the
creator's name (fallback 'Direct entry') for in-app entries. Adds an AFTER
INSERT trigger so future imported-as-approved/paid bills get one too.
Applied to prod: +1,140 rows, 0 approved/paid bills now missing an approver.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 13:52:19 -04:00

63 lines
2.5 KiB
PL/PgSQL

-- Bills that arrive already 'approved'/'paid' (Buildium imports, bulk loads,
-- direct entry) never get routed through the in-app approval flow, so they have
-- no bill_approvals row and the Approvers column shows nothing. Per product
-- decision, give them a synthetic approver so the column is never blank.
--
-- Label: system imports (created_by null) -> 'Imported'; in-app entries ->
-- the creator's name, falling back to 'Direct entry'.
-- 1) Future imports: auto-create an approver row when a bill is inserted already
-- in an approved/paid state with no approver. Bills inserted as 'pending'
-- (the normal approval flow) are untouched.
create or replace function public.autocreate_imported_bill_approver()
returns trigger
language plpgsql
security definer
set search_path to 'public'
as $$
declare
v_name text;
begin
if NEW.status in ('approved','paid')
and not exists (select 1 from public.bill_approvals ba where ba.bill_id = NEW.id) then
if NEW.created_by is null then
v_name := 'Imported';
else
select coalesce(nullif(btrim(p.full_name), ''), 'Direct entry')
into v_name
from public.profiles p
where p.id = NEW.created_by;
v_name := coalesce(v_name, 'Direct entry');
end if;
insert into public.bill_approvals
(bill_id, association_id, approver_name, amount, status, approved_date, created_by)
values
(NEW.id, NEW.association_id, v_name, coalesce(NEW.amount, 0), 'approved',
coalesce(NEW.approved_date, NEW.paid_date, NEW.bill_date, current_date), NEW.created_by);
end if;
return NEW;
end;
$$;
drop trigger if exists trg_bills_autocreate_imported_approver on public.bills;
create trigger trg_bills_autocreate_imported_approver
after insert on public.bills
for each row execute function public.autocreate_imported_bill_approver();
-- 2) Backfill existing approved/paid bills that have no approver row.
insert into public.bill_approvals
(bill_id, association_id, approver_name, amount, status, approved_date, created_by)
select b.id,
b.association_id,
case when b.created_by is null then 'Imported'
else coalesce(nullif(btrim(p.full_name), ''), 'Direct entry') end,
coalesce(b.amount, 0),
'approved',
coalesce(b.approved_date, b.paid_date, b.bill_date, current_date),
b.created_by
from public.bills b
left join public.profiles p on p.id = b.created_by
where b.status in ('approved','paid')
and not exists (select 1 from public.bill_approvals ba where ba.bill_id = b.id);