-- post_deposit_gl: credit the chosen source account(s) instead of always Undeposited.
-- Debit the bank for the deposit total; credit each deposit_lines row's account for its
-- amount; if there are no lines, credit source_account_id; if neither is set, fall back
-- to Undeposited Funds (backward compatible with every existing deposit). The GL
-- contract (one journal entry per deposit, cleared by external ref acmacc_dep) is
-- otherwise unchanged.
create or replace function accounting.post_deposit_gl(_deposit_id uuid)
  returns void language plpgsql security definer set search_path to 'public', 'accounting' as $function$
declare
  d accounting.deposits%rowtype;
  _je uuid;
  _line_count int;
  _line_sum numeric;
  _remainder numeric;
begin
  select * into d from accounting.deposits where id = _deposit_id;
  if not found then return; end if;
  perform accounting._gl_clear(d.company_id, 'acmacc_dep', d.id::text);
  if not accounting.gl_managed(d.company_id) then return; end if;
  if coalesce(d.amount, 0) = 0 or d.bank_account_id is null then return; end if;

  insert into accounting.journal_entries (company_id, date, description, reference, external_source, external_id)
  values (d.company_id, d.date, coalesce(nullif(d.memo, ''), 'Deposit'), null, 'acmacc_dep', d.id::text)
  returning id into _je;

  -- Debit the bank for the full deposit total.
  insert into accounting.journal_entry_lines (journal_entry_id, account_id, debit, credit, description)
  values (_je, d.bank_account_id, d.amount, 0, 'Deposit');

  select count(*), coalesce(sum(amount), 0) into _line_count, _line_sum
  from accounting.deposit_lines where deposit_id = d.id;

  if _line_count > 0 then
    -- Credit each line's account for its amount.
    insert into accounting.journal_entry_lines (journal_entry_id, account_id, debit, credit, description)
    select _je, dl.account_id, 0, dl.amount, coalesce(nullif(dl.memo, ''), 'Deposit')
    from accounting.deposit_lines dl where dl.deposit_id = d.id;
    -- Safety net: if the lines don't cover the total, balance the remainder to
    -- Undeposited Funds so the entry never posts unbalanced (UI keeps them equal).
    _remainder := d.amount - _line_sum;
    if _remainder > 0.005 then
      insert into accounting.journal_entry_lines (journal_entry_id, account_id, debit, credit, description)
      values (_je, accounting.coa_undeposited(d.company_id), 0, _remainder, 'Deposit');
    end if;
  else
    -- No lines: single-source deposit. Credit source_account_id, else Undeposited Funds.
    insert into accounting.journal_entry_lines (journal_entry_id, account_id, debit, credit, description)
    values (_je, coalesce(d.source_account_id, accounting.coa_undeposited(d.company_id)), 0, d.amount, 'Deposit');
  end if;
end$function$;
