-- Fix: vendor (money-out) bank transactions were re-debiting the expense account
-- when coded to one, double-counting expense (the bill already recognized it) and
-- never relieving Accounts Payable — so checks showed as P&L debits. Make vendor
-- payments relieve A/P; the coded account is only used for non-vendor/non-customer
-- transactions.
create or replace function accounting.post_transaction_gl(_txn_id uuid)
 returns void
 language plpgsql
 security definer
 set search_path to 'public', 'accounting'
as $function$
declare t accounting.transactions%rowtype; _counter uuid; _je uuid; _amt numeric;
begin
  select * into t from accounting.transactions where id=_txn_id;
  if not found then return; end if;
  perform accounting._gl_clear(t.company_id, 'acmacc_txn', t.id::text);
  if not accounting.gl_managed(t.company_id) then return; end if;
  if t.transfer_id is not null or t.deposit_id is not null then return; end if;
  if t.account_id is null then return; end if;
  _amt := coalesce(t.amount,0);
  if _amt = 0 then return; end if;
  _counter := case
    when t.customer_id is not null then accounting.coa_ar(t.company_id)
    when t.vendor_id is not null then accounting.coa_ap(t.company_id)
    when t.coa_account_id is not null then t.coa_account_id
    else null end;
  if _counter is null then return; end if;

  insert into accounting.journal_entries (company_id, date, description, reference, external_source, external_id)
  values (t.company_id, t.date, coalesce(nullif(t.description,''), 'Bank transaction'), t.reference, 'acmacc_txn', t.id::text)
  returning id into _je;
  if t.type = 'credit' then
    insert into accounting.journal_entry_lines (journal_entry_id, account_id, debit, credit, description) values
      (_je, t.account_id, _amt, 0, t.description),
      (_je, _counter,     0, _amt, t.description);
  else
    insert into accounting.journal_entry_lines (journal_entry_id, account_id, debit, credit, description) values
      (_je, _counter,     _amt, 0, t.description),
      (_je, t.account_id, 0, _amt, t.description);
  end if;
end$function$;
