Every entry needs a counterpart: a sale is revenue on one side and where the money went on the other. The user answers what they know: paid now or later? and how? The system turns that into the account. The admin configures it once in the chart. This ladder already exists in the code; for Uganda it needs mobile money and a few movement types that are neither income nor expense.
| What the user says | Debit | Credit | Decided by |
|---|---|---|---|
| Sold goods, cash | Cash | Sales | Step 2: payment method |
| Sold goods, pays next month | Receivables | Sales | Step 1: on credit |
| Paid rent by bank | Rent | Bank | Step 2 |
| Bought stock from a supplier, to pay later | Goods bought | Payables | Step 1 |
| Customer pays what they owed | Mobile money | Receivables | “Mark as paid” on the original sale |
| Monthly questionnaire: “March sales 3,000,000” | Cash (usual one) | Sales | Step 3, else asked once |
| Piece | Status |
|---|---|
| The five-step ladder | built resolveCounterpart, used by daily entry and the monthly questionnaire |
| Chart roles (receivables, payables, VAT, withholding…) | built One setting per chart; the default chart has them |
| Allowed pairs, suggested by AI and checked | built Admin import with blockers (self-pair, duplicate) and warnings (unusual type pair) |
| Mobile money as an account | add Not in the default chart. In Uganda it is how most small businesses get paid: add “Mobile money” under cash, and MTN / Airtel as payment methods |
| Movements that are not income or expense | missing Daily entry only knows income and expense. Needed for a real balance sheet: cash ↔ bank transfer, loan received or repaid, owner puts money in or takes it out, buying equipment |
| Monthly questionnaire default | decide For micro businesses pre-set “Cash” as the usual account, so the questionnaire never asks |
Read from Accounting-Next main @ 69b3aa41: src/lib/ledger/resolve-counterpart.ts, CounterpartPair, UserSettlementDefault, PaymentMethod, prisma/seed-data/default-chart.json.