Posting model
Posting is the controlled conversion of an approved Finance event into balanced debit and credit evidence in the internal Makronexus General Ledger. It is not the same as saving an invoice, receiving money, issuing a receipt, exporting a ledger file, or matching a bank statement.
Audience: accountants, bursars, finance-control owners, implementers, auditors, and support analysts
Learning time: 40 minutes
Navigation: Finance → Accounting → Posting Controls, Finance → Accounting → General Ledger, and Finance → Accounting → Journals
Product boundary: the backend posting resolver is authoritative. The browser must not invent final accounts, sides, or functional amounts.
Learning outcomes
You will be able to:
- explain the difference between a source transaction, posting decision, journal document, journal line, and ledger export;
- identify the configuration and evidence required before posting;
- distinguish transaction currency from functional currency;
- use posting simulation without treating it as a committed journal;
- verify that a posting is balanced, idempotent, source-linked, and school-scoped;
- recognise when an exception blocks posting or period close;
- hand unresolved settlement and bank evidence to P6 without claiming reconciliation.
Exact definition and boundaries
A source record describes the operational event: an invoice was approved, a Payment was verified, a refund was processed, an expenditure was paid, or an authorised manual adjustment was requested. A posting rule and account mapping resolve that event to ledger accounts. A journal document records the accounting result. Its lines classify debit and credit amounts and can also carry cost centre, project, fund, department, revenue-stream, and other dimensions.
The internal General Ledger is the accounting source in Makronexus. Ledger Exports package posted information for downstream systems; they are not the primary ledger. A successful export does not prove that the source event was posted correctly, and a saved source transaction does not prove that a journal exists.
The current journal-document contract supports transaction currency, functional currency, exchange rate, an idempotency key, multiple lines, and totals for both transaction and functional debits and credits. The posting is acceptable only when the appropriate totals balance and every line points to an active posting account.
Prerequisites
| Requirement | Why it matters | Evidence |
|---|---|---|
| Correct tenant and school | account resolution and journals are scope-sensitive | school selector and journal school identity |
| Active Chart of Accounts | postings cannot use missing, inactive, or header accounts | account code, status, type, and school/default scope |
| Effective posting policy | defines blocking, approval, close, and manual-journal behaviour | active policy and effective dates |
| Effective account mappings | resolve posting type and source attributes to accounts | mapping type, key, side, priority, and status |
| Open eligible accounting period | posting date must be governed | fiscal year and period state |
| Currency design | transaction and functional amounts must be reproducible | currencies, rate, timestamp, source, and reference |
| Exact permission | UI visibility is not authority | session ability list |
| Source approval/verification | only eligible source states should post | source status and actor evidence |
| Idempotency identity | prevents a repeated request from creating a second economic effect | idempotency key and request fingerprint |
Roles and exact permissions
| Action | Typical role | Exact ability | Control |
|---|---|---|---|
| View active policy | accountant or auditor | finance_control:read | identify tenant default versus school override |
| View mappings and overrides | accountant | finance_control:list | do not infer missing mappings |
| View readiness | close owner | finance_control:readiness | failed checks must remain visible |
| Simulate posting | accountant or implementer | finance_control:simulate | simulation is non-posting evidence |
| List accounts | accountant | gl_account:list | choose active non-header accounts |
| View journals | accountant or auditor | gl_journal_entry:list | filter by source, status, account, and date |
| Read one journal | accountant or support analyst | gl_journal_entry:read | retain source and reversal lineage |
| View statements | accountant | gl:statements | use backend-computed totals |
| Resolve posting exception | authorised control owner | finance_posting_exception:resolve | record reason and evidence |
The posting-controls UI also uses finance_control:create, finance_control:update, finance_control:delete, finance_control:request_change, finance_control:approve, and finance_control:apply_change. Those configuration and maker-checker actions are taught in Posting review and approval.
Posting decision model
A simulation answers what the current resolver would do. It does not reserve an account, lock a rate, close a period, or create a journal. Re-run simulation after any policy, mapping, source, currency, date, or Chart of Accounts change.
Guided procedure
- Confirm scope. Select the intended school and record whether the effective controls come from a tenant default or a school override. Expected result: the scope badge and school identity agree.
- Open Posting Controls. Review readiness, active policy, mappings, overrides, and open exceptions. Expected result: no critical blocker is hidden by a failed secondary panel.
- Identify the source event. Record source type, source ID, business date, posting date, amount, transaction currency, functional currency, and current source status.
- Confirm the posting type. Examples supported by current contracts include invoice, payment, refund, expenditure, credit note, scholarship, payroll, platform billing, manual, and reversal sources. Do not assume identical rules for every source.
- Run simulation when available. Inspect resolved debit account, credit account, sides, dimensions, policy source, mapping precedence, and warnings.
- Resolve blockers. Correct missing mappings, inactive/header accounts, closed periods, missing rate evidence, unapproved controls, or unsupported source state. Never bypass a blocker by selecting an unrelated account.
- Post through the governed source action or journal workflow. Supply an idempotency key for journal-document posting. Do not retry with a new key merely because the browser timed out.
- Read the returned journal. Verify header ID, entry number, source type/ID, school, currencies, exchange rate, line count, debit totals, credit totals, poster, and timestamp.
- Trace the result. Open the account activity, trial balance, and source detail. A success toast is insufficient.
- Preserve the handoff. P5 proves accounting evidence. Bank/provider settlement matching remains P6.
Accounting impact
Accounting impact is configuration-derived. The following pattern is illustrative:
| Event | Debit | Credit | Amount basis | Date | Reversal |
|---|---|---|---|---|---|
| approved student invoice | receivable | configured revenue/deferred account | approved invoice lines | posting date | linked offsetting journal |
| verified Payment | cash/bank/clearing | receivable or student credit | verified and allocated amount policy | posting date | refund/reversal workflow |
| authorised refund | refund/receivable/student-credit account | cash/bank/clearing | approved return components | return date | compensating evidence |
| manual adjustment | selected active posting account | selected active posting account | approved document lines | journal date | linked reversal document |
Never copy an illustrative account name into production configuration without verifying the school’s Chart of Accounts and effective mapping.
Controls and audit evidence
Minimum evidence includes source identity, source state, posting type, effective policy, mapping or override used, account identities, line sides, transaction and functional amounts, exchange rate, idempotency key, actor, timestamps, journal header, legacy projection IDs where present, and any exception or approval record.
Posted history is not corrected by editing totals in place. Use a linked reversal or a governed compensating journal. Keep simulation output separate from committed journal evidence. If the same idempotency key returns an existing document, treat that as duplicate prevention, not as a new posting.
Worked scenario: Mupfure Learning Academy
Mupfure Learning Academy verifies a USD 600 bank Payment allocated to two invoices. The accountant confirms the school scope, active policy, payment.verified mapping, settlement account, receivable account, open period, and functional-currency rule. Simulation resolves the accounts without blockers. The posting returns one journal document with balanced transaction and functional totals and source linkage to the Payment.
The accountant does not mark the bank movement reconciled. The journal proves accounting recognition; P6 will prove the external statement match.
Failure modes
| Symptom | Likely cause | Evidence to inspect | Safe action | Escalate when |
|---|---|---|---|---|
| no journal after eligible source action | missing mapping, automation disabled, exception, or source ineligible | source status, posting readiness, exceptions, audit events | correct named blocker and retry idempotently | source is eligible and resolver reports ready but no journal exists |
| debit and credit totals differ | invalid document or normalization defect | journal totals and every line | do not rely on the entry; block close | backend accepted an unbalanced posted document |
| wrong school account used | scope omitted or override/default precedence misunderstood | school ID, account school scope, mapping source | reverse and repost through approved correction | cross-school account identity appears |
| duplicate-looking journals | retry used different key or two source events exist | idempotency keys, source IDs, timestamps, fingerprints | determine economic identity before reversal | duplicates cannot be linked to requests |
| simulation and posted result differ | controls, source, period, or rates changed | simulation timestamp and effective evidence | re-simulate and explain change | same immutable inputs resolve differently |
| export exists but journal is missing | export is not the source ledger | export lines and GL journals | investigate GL first | export contains unsupported fabricated accounting |
Verification checklist
- Tenant and school scope are explicit.
- Source type, source ID, state, amount, currency, and dates are recorded.
- Effective policy and mapping evidence is retained.
- Every account is active, non-header, and in the allowed scope.
- Transaction and functional debit/credit totals balance.
- Exchange-rate evidence is reproducible when currencies differ.
- Idempotency identity is retained.
- Journal source and reversal lineage are visible.
- Trial-balance or account-activity effect is reproducible.
- No bank/provider reconciliation claim is made from posting alone.
Practice and knowledge check
Guided practice: simulate and trace one approved source event in a test school. Record every input and compare the simulation with the committed journal.
Independent scenario: a Payment is verified, the receipt exists, and no journal appears. Build a safe investigation order without creating a manual journal first.
- Why is a source transaction not a journal?
- Why must the frontend not calculate final accounts?
- What does an idempotency key protect?
- Why is a ledger export not the General Ledger?
- Which totals must balance in a multi-currency journal document?
- What is the difference between simulation and posting?
- Which evidence belongs to P6 rather than P5?
Answer guide: operational and accounting records have different purposes; the backend resolver owns mappings and rules; idempotency prevents duplicate effects; exports package ledger data; transaction and functional debits/credits must balance; simulation is non-committing; external bank/provider matching belongs to reconciliation.
Next lesson
Continue to Journals and journal lines.