Appearance
Journal Entry Controls
This page documents the complete control framework around journal entries in PinkApple ERP — from creation through posting, approval, and correction.
Journal Entry Lifecycle
DRAFT → PENDING_APPROVAL → APPROVED → POSTED
↓ ↓
REJECTED REVERSED / VOIDED| State | Description | Can Be Modified? |
|---|---|---|
| DRAFT | Entry created but not submitted | Yes — amounts, accounts, memo can change |
| PENDING_APPROVAL | Submitted for approval | No — locked for review |
| APPROVED | Passed approval chain | No — awaiting posting |
| POSTED | Written to the ledger | No — permanent record |
| REJECTED | Returned by approver with comments | Can be edited and resubmitted |
| REVERSED | Offset by a new correcting entry | No — both entries remain |
| VOIDED | Marked invalid before posting | No — remains as void record |
Who Can Do What
Creation Controls
| Control | Enforcement |
|---|---|
| Only authorised users can create entries | CREATE_GL_JOURNAL_ENTRY permission required |
| Entries must specify a valid fiscal period | System resolves from journal_date — rejects if period is closed |
| All COA accounts must be active and approved | Invalid COA IDs are rejected at creation |
| Entry must have at least 2 lines | Single-line entries are blocked |
| Debits must equal credits | Validated before save; unbalanced entries rejected |
| Business unit must be specified per line | Each line carries explicit BU assignment |
| Control accounts require sub-ledger | If a COA has sub-ledgers, sub_ledger_id is mandatory |
Approval Controls
| Control | Enforcement |
|---|---|
| Creator cannot approve own entry | System enforces different user_id for creation vs approval |
| Monetary thresholds trigger multi-step approval | Configurable per approval policy |
| Approval chains are sequential | Step 2 cannot approve until Step 1 completes |
| Rejected entries require comments | Approver must provide rejection reason |
| SLA tracking on approval steps | Escalation if step exceeds configured hours |
| Authority limits per user | Maximum amount a single approver can authorise |
Posting Controls
| Control | Enforcement |
|---|---|
| Only approved entries can be posted | approval_status = 'APPROVED' check |
| Posting date must be in an open period | HARD_CLOSED or LOCKED periods block posting |
| Soft-closed periods require elevated permission | allow_soft_closed_posting flag |
| Backdating beyond lag window blocked | Configurable GL_MAX_POSTING_LAG_DAYS |
| Future posting can be disabled | GL_ALLOW_FUTURE_POSTING configuration |
| Till-based posting requires open business day | Teller entries linked to active till session |
Posting Channels
Every entry is tagged with how it was created:
| Channel | Description | Approval Behaviour |
|---|---|---|
BACKOFFICE | Manual entry by accountant | Full approval chain applies |
TELLER | Posted through till/teller session | May have lower threshold |
SYSTEM | System-generated (EOD, accruals) | Typically auto-approved |
API | External integration | Depends on API configuration |
Batch Management
Journal entries are grouped into batches:
| Batch State | Description |
|---|---|
| OPEN | Batch accepting new entries |
| CLOSED | No more entries can be added |
| CANCELLED | Stale batch cancelled by cleanup process |
Stale Batch Cleanup
The system automatically cancels:
- DRAFT batches older than 30 days (configurable)
- OPEN batches older than 60 days with no posted entries
This prevents abandoned batches from cluttering the ledger.
Correction Procedures
Before Posting (DRAFT/PENDING)
- Entry can be edited directly (amounts, accounts, memo)
- Entry can be voided — sets
voided_flag = 1, excluded from all calculations - Both actions are logged in the activity trail
After Posting
- Entry cannot be edited or deleted
- Reversal is the only correction method:
- System creates a new entry with inverted amounts
- Original entry:
reversed_flag = 1,reversed_entry_id = new_entry_id - New entry: references original in
source_id - Both remain permanently visible
Auto-Reversal (Accruals)
Entries with auto_reverse_date set are automatically reversed on that date:
- Used for month-end accruals that should reverse on day 1 of next period
- System procedure
process_accrual_auto_reversalshandles this - Reversal is logged with source_type and links to original
Numeric Precision
| Aspect | Precision |
|---|---|
| Journal line amounts | DECIMAL(18,4) — 4 decimal places |
| Exchange rates | DECIMAL(18,6) — 6 decimal places |
| Balance tables | DECIMAL(18,2) — 2 decimal places |
| Balance check tolerance | 0.01 — entries within 1 cent are considered balanced |
Concurrent Access Controls
- Optimistic locking via
versioningtimestamp on all GL tables - Batch-level locking — only one user can post to a batch at a time
- Period-level protection — period state changes are atomic transactions
Regulatory Compliance Mapping
| Requirement | How PinkApple Meets It |
|---|---|
| SOX Section 302 (Management certification) | Complete audit trail with user attribution |
| SOX Section 404 (Internal controls) | Segregation of duties, approval chains, authority limits |
| IAS 8 (Accounting policy changes) | Adjustment periods (13-16) for prior-period corrections |
| ISA 240 (Fraud considerations) | Activity log, IP tracking, same-user approval prevention |
| IFRS 13 (Fair value) | Exchange rate sources tracked per entry |
| Local banking regulations | Period lock, daily balance capture, till reconciliation |
Control Summary for Auditors
The following controls operate automatically without user intervention:
- ✅ Every entry is balanced (debits = credits) — enforced at database level
- ✅ Every action is logged with user, IP, timestamp — cannot be disabled
- ✅ Posted entries cannot be modified — only reversed
- ✅ Period controls prevent back-posting — state machine enforced
- ✅ Control accounts require sub-ledger specification — prevents unallocated postings
- ✅ Sub-ledger totals checked against control at period close — blocks close if mismatched
- ✅ Stale drafts auto-cancelled — prevents orphaned entries
- ✅ Cash accounts checked for overdraft — prevents negative cash balances
- ✅ Approval enforces different user than creator — SOD compliance
- ✅ Daily balance capture at 10 hierarchy levels — full audit evidence
Next Steps
- Audit Trail & Controls — Activity log structure and immutability guarantees
- GL Posting Approval — Configuring approval chains and authority limits
- Month-End Close — Period close procedures
- Year-End Close — Fiscal year close and retained earnings
