Settle bills
settle_billsSettle a batch of bills in one call — each pair links a bill / purchase order / GRN (cont-…) to its payment: either an existing expense (expense) or a bank transaction (transaction: a bank-feed transaction's own unallocated expense is re-pointed at the bill; an unlinked transaction gets a new expense linking the two). Money-out settle = an expense whose accountid is the bill's id. record_document_payment settles ONE bill at a time (minting the expense from payment fields); this tool instead LINKS an existing expense or bank transaction and settles a whole batch, which the chat loop can't do with N single settles. Each pair is applied INDEPENDENTLY: one failing (missing/locked/bad ref) never aborts the rest. Every id (bill, expense, transaction) is owner-scoped; an already-settled bill, or a transaction whose expense already pays that bill, is a safe no-op (not a failure), so re-running the same batch is harmless. A transaction allocated elsewhere (income, another bill or category, several expenses) fails with a reason naming the allocation. A bank transaction slightly ABOVE the bill (a bank fee, at most 3% of the outstanding, same currency) is not refused: it comes back status "proposed" with a proposal {type bank-charge, amount, accountid 201, accountname Bank Charges, outstanding, paid} and NOTHING is written. Show the user the fee; only once they confirm, re-send the same pair with bankcharge = proposal.amount to settle the bill and post the fee to Bank Charges in one transaction (re-sending again is an already-settled no-op). Above 3% the over-settle refusal stands. A bank transaction in a DIFFERENT currency from the bill, worth within 3% of the outstanding at its date's rate, comes back status "proposed" with a proposal {type fx-gain|fx-loss, amount, currency, accountid, accountname, outstanding, paid, paidcurrency, paidbase, exchangerate; for a bill in a foreign currency also billcurrency, carrying (the bill's base value), paidbill} and NOTHING is written. Show the user the FX line; only once they confirm, re-send the same pair with fxadjustment = proposal.amount to settle the bill and post the difference to the Foreign Exchange account (when the business has autofxadjustment on, it is booked without asking). A bill in a foreign currency paid from a bank line in that same currency settles at once and books the rate move since the bill date to Foreign Exchange (fxadjustment, autobooked); with no dated rate it settles with no FX line and fxunsized true. Any other currency mismatch (an expense pair, no dated rate, outside 3%, a partial payment in another currency) is refused with status "failed", code "cross-currency-needs-fx", billcurrency and paymentcurrency, and NOTHING is written. Returns {results [{bill, status "settled"|"already-settled"|"proposed"|"failed", expenseid, created, bankchargeid, fxadjustmentid, fxadjustment, proposal, reason}], settled, already-settled, proposed, failed} — expenseid is the undo handle and created=false means the expense pre-existed (undo by UNLINKING it, never deleting); bankchargeid is the minted fee expense (safe to delete); fxadjustmentid is removed automatically when its expenseid is unlinked from the bill or deleted, so do NOT delete it separately (restoring a deleted expense does not bring its FX line back). Max 100 pairs per call. Only run after the user has confirmed the proposed matches.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| pairs | Yes | The confirmed bill↔payment pairs to reconcile. Each is applied independently. |