# Source-to-GL posting design Design only; no new posting behavior is enabled. Accounts, timing, tax and cost policy require approval in `accounting-policy-decisions.md`. | Event | Valid posting trigger | Conceptual debit / credit | Amount source | Stable key | Atomicity / timing | Reversal, subledger and proof | |---|---|---|---|---|---|---| | POS sale recognition | Approved goods-transfer event | Dr AR/tender receivable or mapped cash; approved discount contra-revenue; Cr revenue and output-tax payable if applicable | Immutable SO/invoice line snapshots, backend tax/discount calculation | SO ID + `sale_recognition` posting kind | Same transaction as recognition state or durable outbox | Linked reversal. Reconcile recognized invoices/tax; test state boundary and retry. | | Immediate POS collection | Successful recorded tender | Dr mapped cash/bank; Cr AR if already recognized, otherwise approved tender clearing | Payment row amount/method/reference | Payment ID + `collection` | Payment and journal one DB transaction | Linked refund/reversal. Test duplicate and partial balances. | | Invoice recognition | Invoice valid at approved fulfillment/invoice event | Dr AR; Cr revenue and output tax; discount per approved rule | Invoice and source SO lines | Invoice ID + `invoice_recognition` | Invoice state and journal atomic | Pre-payment cancellation only by approved linked correction. Test not double-posted with POS. | | Invoice partial payment | Payment committed against open invoice | Dr cash/bank/clearing; Cr AR | Payment amount/method/bank refs | Payment ID + `collection` | Lock invoice, mutate payment and journal together | Reverse by linked payment correction; test repeated partials and overpayment. | | Gateway capture | Verified gateway capture notification or provider status | Dr gateway clearing; Cr AR if sale recognized earlier. If not, policy must define sale/clearing recognition together. | Verified amount matched to invoice; operational payment amount remains auditable | Provider transaction ID + invoice/payment ID | Idempotent provider event, payment, invoice state and journal transaction | Duplicates return existing outcome; pending/failed/expired post nothing. Test webhook/poll race. | | Gateway bank settlement | Matched provider payout | Dr bank net; Dr fee expense if approved; Cr gateway clearing gross | Payout/fee statement | Provider settlement batch + payout-line ID | Batch detail and journal atomic, unique by source line | Correct through linked settlement reversal; clearing reconciliation. Payout lifecycle absent today. | | Sales return/refund | Approved immutable return | Dr contra-revenue/refund payable/tax correction as approved; Cr cash/bank/store-credit liability. Accepted goods: Dr inventory, Cr COGS at original cost. | Return lines + original invoice/payment + original cost snapshot | Return ID + posting kind | Return, refund, stock and GL effects atomic | Linked reversal. Test partial, over-return, damaged/restock and retry. | | Goods receipt | Confirmed accepted goods receipt | Dr inventory at selected receipt cost + recoverable tax if applicable; Cr GR/IR or AP | Accepted quantity × approved receipt cost | GR ID + `receipt_recognition` | Current GR commits before advisory draft; real posting needs same transaction or durable outbox | Linked source reversal; never recognize AP again at supplier invoice. Test partial receipt/idempotency. | | Supplier invoice | Approved invoice matched to PO/GR | Dr GR/IR/inventory/expense and input tax; Cr AP | Supplier invoice detail and matched receipt | Supplier invoice ID + `invoice_recognition` | Invoice/AP/journal atomic | Credit note or linked reversal. No complete supplier-invoice lifecycle verified. | | Supplier payment | Successful payment against approved AP | Dr AP; Cr selected bank/cash | Immutable supplier payment amount/account/reference | Supplier payment ID + payment kind | Current PO mutation and journal are separate transactions; use shared tx or durable outbox plus unique key | Linked payment reversal. Test retries and concurrent same payment. | | COGS recognition | Goods transfer to customer | Dr COGS; Cr inventory at assigned cost-layer value | Immutable cost ledger consumption | SO line ID + `cogs` posting kind | Cost layer, stock movement and journal atomic | Return uses original assigned cost. Test FIFO/WAC, backdates, negative-stock and rounding. | | Stock opname | Approved nonzero quantity/value variance | Shortage Dr approved shrinkage / Cr inventory; surplus Dr inventory / Cr approved gain | Valuation ledger difference | Opname ID + `adjustment` posting kind | Finalized opname, stock and journal atomic | Linked adjustment reversal; test source retry, actor/reason/account. | | Advance receipt | Confirmed customer deposit or supplier prepayment | Customer: Dr cash/clearing, Cr deposit liability. Supplier: Dr advance asset, Cr cash. | Advance receipt transaction | Advance transaction ID + `receipt` | Advance balance and journal atomic | Allocation/refund are separate entries. Test retry and multiple receipts. | | Advance allocation | Confirmed allocation transaction | Sales: Dr deposit liability / Cr AR. Supplier: Dr AP / Cr supplier advance. | Allocation transaction amount | Advance transaction ID + `allocation` | Transaction, advance balance and journal atomic | Linked correction; repeated partial allocation valid. | | Payroll | Approved payroll accrual or payment stage | Expense/payroll payable or payable/bank based on chosen lifecycle | Payroll run/lines | Payroll ID + stage (`accrual`, `payment`) | Payroll state and journal atomic | Reversal linked to exact stage. Test one per stage. | | Manual cash movement | Authorized manual cashflow with explicit accounts | Dr/Cr mapped cash and counterpart based on direction | Cashflow row amount and account IDs | Cashflow ID + posting kind | Cashflow and journal one DB transaction | Reverse with new linked cashflow; existing cashflow is not currently GL. | ## Posting and reversal invariants - Posted journal lines are immutable; correction appends a linked entry. - Gateway settlement never duplicates sale revenue already recognized at fulfillment/invoice. - Current `reversed` original and linked posted reversal remain in history. Period totals include both; they net only if the reversal mirrors the original. Close currently validates each entry’s line/header equality and debit-credit balance, but not reversal-link integrity or mirror equality. - Source uniqueness includes posting kind/stage for one-to-many source workflows. Do not add global `(source_type, source_id)` uniqueness without proven cardinality. - Period close blocks drafts and unbalanced posted/reversed entries; the database trigger and close transaction serialize on period row locks. ## Required before implementation Approve policy, account map, transaction boundary, stable source key, cost basis, retry handling and correction route for each event. Until then, keep these flows documented as design, not active GL postings.