feat(transactions): expose the bank account (cash_account_id + ledger) on listings, filter by it (#1809)
* feat(transactions): expose the bank account (cash_account_id + ledger) on listings, filter by it Customer report: neither the MCP transaction listings nor v1 REST said which bank account a transaction belongs to, so per-account reconciliation could not be driven from outside and a difference on one account was hunted on another. - gnubok_list_uncategorized_transactions: cash_account_id + cash_account_ledger (BAS account of the bank account, one lookup per page) on every row, and an optional cash_account_id filter applied to both count and page. - transactions_without_documents RPC (new migration, same signature): rows carry cash_account_id + cash_account_ledger via LEFT JOIN cash_accounts; gnubok_list_transactions_without_documents declares them. - v1 transactions list/detail: cash_account_id column; list accepts ?cash_account_id=<uuid> (400 on non-UUID). - tools/list budget bumped 59.85K -> 59.9K with the usual log entry; no property descriptions added. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(transactions): import insertCashAccount in the pg test, regenerate banking.md, validate cash_account_id Skeptic/CI findings: the new pg-real test referenced insertCashAccount without importing it; the accounted-api agent skill (banking.md) was stale after cash_account_id joined the v1 projections (apiskill:check). Also reject a ledger number passed as cash_account_id on the MCP tool with a clear message instead of a raw uuid cast error, since the ledger now sits next to the id in every row. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
d4c42fd8db
commit
6e5694fd03
@@ -4,6 +4,7 @@ import { NEEDS_DOC_SOURCE_TYPES } from '@/lib/worklist/categories'
|
||||
import { getPool } from './setup'
|
||||
import {
|
||||
seedCompany,
|
||||
insertCashAccount,
|
||||
insertDraftJournalEntry,
|
||||
insertPostedJournalEntry,
|
||||
insertBalancedLines,
|
||||
@@ -697,3 +698,47 @@ describe('floating supplier-invoice document backfill (migration 20260727180000)
|
||||
expect(await anchorOf(doc)).toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
describe('transactions_without_documents: bank account on each row (A4)', () => {
|
||||
it('returns cash_account_id and the cash account ledger, null when unbackfilled', async () => {
|
||||
const s = await seedCompany()
|
||||
const cashAccountId = await insertCashAccount({ companyId: s.companyId, ledgerAccount: '1940' })
|
||||
const mkJe = (n: number) =>
|
||||
insertPostedJournalEntry({
|
||||
userId: s.userId,
|
||||
companyId: s.companyId,
|
||||
fiscalPeriodId: s.fiscalPeriodId,
|
||||
voucherNumber: n,
|
||||
entryDate: `2026-06-${String(n).padStart(2, '0')}`,
|
||||
description: `bank ${n}`,
|
||||
sourceType: 'bank_transaction',
|
||||
lines: [
|
||||
{ accountNumber: '1940', debitAmount: 100, creditAmount: 0 },
|
||||
{ accountNumber: '3001', debitAmount: 0, creditAmount: 100 },
|
||||
],
|
||||
})
|
||||
const jeWithAccount = await mkJe(1)
|
||||
const jeWithoutAccount = await mkJe(2)
|
||||
const txWith = await insertTransaction({
|
||||
companyId: s.companyId,
|
||||
userId: s.userId,
|
||||
journalEntryId: jeWithAccount,
|
||||
cashAccountId,
|
||||
date: '2026-06-01',
|
||||
})
|
||||
const txWithout = await insertTransaction({
|
||||
companyId: s.companyId,
|
||||
userId: s.userId,
|
||||
journalEntryId: jeWithoutAccount,
|
||||
cashAccountId: null,
|
||||
date: '2026-06-02',
|
||||
})
|
||||
|
||||
const { rows } = await getPool().query<{
|
||||
r: { ok: boolean; transactions: Array<{ id: string; cash_account_id: string | null; cash_account_ledger: string | null }> }
|
||||
}>(`SELECT public.transactions_without_documents($1, NULL, 100, 0) AS r`, [s.companyId])
|
||||
const byId = new Map(rows[0].r.transactions.map((t) => [t.id, t]))
|
||||
expect(byId.get(txWith)).toMatchObject({ cash_account_id: cashAccountId, cash_account_ledger: '1940' })
|
||||
expect(byId.get(txWithout)).toMatchObject({ cash_account_id: null, cash_account_ledger: null })
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user