Skip to content

Book 4, Chapter 15 — General Ledger & Journals

Bizwiz Guide — module-by-module static-analysis of the Bizwiz ERP. This chapter covers the General Ledger, Banking, Utility, and Reports sub-menus under Finance. Fixed Assets are Chapter 16; Petty-Cash approvals are Chapter 17.


1. Purpose

(narrative — plain language)

The General Ledger (GL) is the ERP's financial "book of record." Everything that happens anywhere in Bizwiz that has a money value — a sale invoiced, stock received, a supplier paid, cash banked, VAT charged — eventually lands as a row in one table: wa_gl_trans. That table is the trial-balance spine: sum it up by account and you get the Trial Balance, the Profit & Loss, and the Balance Sheet. If it balances (debits = credits), the books are healthy; when it doesn't, the Utility sub-menu exists to hunt down why.

This chapter covers four things a finance clerk sees under the Finance → General Ledger menu:

  1. Chart of Accounts — the master list of account codes (e.g. 54008-000 Cash Control, 55001-007 Fraud). Every GL row points at one.
  2. General Journal / Journal Entries — manual "journal vouchers" (JVs): a human types "debit this account, credit that account" for things automation doesn't cover (accruals, corrections, opening balances). These go through an approval/posting lifecycle before hitting the ledger.
  3. Inquiry & viewing screens — Account Inquiry, GL Transactions, View Ledger, GL Journal Inquiry: read-only windows onto wa_gl_trans.
  4. Banking, Utility and Reports — the bank-account master and GL-side deposits/transfers; a large toolbox of clean-up/integrity utilities for when the ledger drifts; and the financial statements.

The key mental model: most GL rows are NOT typed by a human. They are posted automatically by other modules (Accounts Payable in Book 3, Sales/Debtors in Book 1, Inventory in Book 2). This chapter documents the GL as the destination those postings land in, plus the manual journal path and the tools to keep it clean.


Cross-reference: Book 1, Chapter 6 ("Banking & Receivables Reconciliation") owns the money-in / receivables side — how a customer receipt gets matched to a bank statement and only then posted to wa_gl_trans + wa_banktran. This chapter covers the GL-side banking (bank-account master, deposits, transfers) and the ledger table itself; it does not re-document receivables reconciliation. Book 3 (Accounts Payable) owns the money-out postings; this chapter documents where they land.


2. Users & roles

(narrative — plain language)

The GL menu is used by the finance/accounts team: accountants who post journals, a finance manager who approves them, and back-office "GL admin" users who run the integrity utilities and month-/day-end routines. Ordinary sales and warehouse staff never see this menu — their transactions post into the GL invisibly.

Access is gated at three levels: (a) the top-level Finance menu requires finance___view; (b) each screen has its own view permission; (c) super-admins (role_id == 1, a.k.a. config('app.allowed_role')) bypass every check.


Permission checks render two ways in this codebase. The sidebar uses isset($my_permissions['<module>___<action>']); controllers/blades use the can($action, $module) helper, which looks up "$module___$action" and returns true for super-admins (app/helpers.php:4182, getUserPermissions returns the literal string 'superadmin' when role_id == 1, app/helpers.php:4195-4207).

Permission strings gating each screen (from resources/views/admin/includes/sidebar_includes/general_ledger.blade.php):

Screen Route Permission string
Finance (parent) — finance___view (:1)
Chart Of Accounts chart-of-accounts.index chart-of-accounts___view (:160)
General Journal journal-entries.index journal-entries___view (:166)
Processed JV journal-entries.processed_index journal-entries___processed (:403)
Account Inquiry admin.account-inquiry.index account-inquiry___view (:172)
GL Transactions general-ledgers.gl-entries transfers___view (:179) — note: odd reuse of a transfers permission
View Ledger edit-ledger.index edit-ledger___processed (:186)
GL Journal Inquiry admin.journal-inquiry.index journal-inquiry___view (:202)
Banking (parent) — bank-accounts___view (:362)
Bank Accounts bank-accounts.index bank-accounts___view (:371)
Bank Deposit banking.deposite.list bank-accounts___bankdeposit (:376)
Transfer banking.transfer.list bank-accounts___banktransfer (:383)
Reconcile Daily Transactions banking.reconcile.daily.transactions bank-accounts___reconcile-daily-transaction (:391)
Utility (parent) — general-ledger-utility___view (:410)
Transaction Search gl-transaction-search.index wa-gl-trans___view (:424)
Manual GL Posting gl-reconciliation.manual-posting.create manual-gl-posting___view (:430)
Records Pending GL (parent) — can('view','existing-records-pending-gl-utility') (:434)
— Sales Payments gl-utility.existing-records-pending-gl.sales-payments existing-records-pending-gl-utility___sales-payments
— Bank Statements …bank-statements …___bank-statements
— Resolved Short Banking …resolved-short-banking …___resolved-short-banking
Assign Account View assign_account_view.index assign-account-view___view (:468)
Transaction Without Branch transactions-without-branches.index transaction-without-branch___view (:476)
GL Configurations general-ledger-configurations.index general-ledger-configurations___view (:485)
Add Customer to GL update-customer-to-gl.index update-customer-to-gl___view (:492)
GL Trans Duplicates gl-utility.gl-trans-duplicates gl-trans-duplicates-utility___view (:499)
GL Account Misposts gl-utility.gl-account-mispost gl-account-mispost-utility___view (:507)
Debtors - GL Mismatch gl-utility.debtors-gl-mismatch debtors-gl-mismatch-utility___view (:515)
Untraced in GL gl-utility.untraced-in-gl untraced-in-gl-utility___view (:522)
Unbalanced Transactions gl-utility.unbalanced-transactions unbalanced-gl-transactions___view (:529)
GL Clean up gl-utility.gl-cleanup gl-cleanup-utility___view (:535)
Trans Dates Cleanup gl-utility.trans-dates-cleanup gl-trans-dates-cleanup-utility___view (:541)
Subsidiary/Debtors/Creditors vs GL gl-utility.subsidiary-vs-gl subsidiary-vs-gl-utility / debtors-vs-gl-utility / creditors-vs-gl-utility ___view (:547)
Transfer GL Transactions gl-utility.gl-transfer-transactions gl-transfer-transactions-utility___view (:554)
Document Number Change gl-utility.document-number-change.index document-number-change-utility___view (:560)
GL EOD Routine gl-eod-routine.index gl-eod-routine-utility___view (:566)
Bank Recon gl-utility.bank-recon bank-gl-reconciliation___view (:572)
Reports general-ledger-reports.index general-ledger-reports___view (:736)

Disabled / inactive nav (rendered but non-clickable): Budgeting (budgeting___view, :582-592) and Cash Management (cash-management___view, :594-604) are rendered with class="disabled" … pointer-events:none; opacity:0.6 and onclick="return false;" — visible placeholders for up-and-coming modules, not yet functional.


3. Processes

(narrative — plain language)

There are five process families here: (1) maintaining the chart of accounts, (2) the manual journal-voucher lifecycle, (3) the automatic posting path by which any module's transaction becomes GL rows, (4) GL-side banking (deposits/transfers), and (5) the utility/clean-up toolbox plus reports. The heart of it all is a small, disciplined service — GlTransactionService — that every modern posting funnels through, and which refuses to write anything that doesn't balance to zero.


3.1 The GL posting engine (the universal path to wa_gl_trans)

Every modern posting is built with app/Services/GlTransactionService.php. You call make(transactionNo, module, context) (:44), stack up ->dr(account, amount) and ->cr(account, amount) legs, then ->post().

  • dr() pushes a positive signed amount (:67-74).
  • cr() pushes a negative signed amount (amount * -1, :79-84).
  • post() computes balance() (sum of signed amounts, :105-107); if abs(balance) > 0.01 it throws UnbalancedGlTransactionException (:130-139). An optional rounding account absorbs sub-1.00 imbalances (:120-127).
  • save() (:145-181) writes one WaGlTran row per leg inside a DB transaction, stamping period_number (current WaAccountingPeriod), transaction_no, trans_date, account, signed amount, narrative, tb_reporting_branch, and the relevant source FK from context.

Sign convention (CODE-PROVEN, the single most important fact): wa_gl_trans.amount is one signed column — debits positive, credits negative — and a valid transaction sums to zero. Reports reconstruct DR/CR with SUM(CASE WHEN amount>0 …) AS debit / SUM(CASE WHEN amount<=0 …) AS credit (see JournalEntryController processed lookup).

flowchart LR
    A[Any module event<br/>invoice / GRN / payment / journal] --> B["GlTransactionService::make()"]
    B --> C["->dr(acct, +amt)"]
    B --> D["->cr(acct, -amt)"]
    C --> E["->post()"]
    D --> E
    E --> F{balance == 0?}
    F -- no --> G[throw UnbalancedGlTransactionException]
    F -- yes --> H["save(): insert WaGlTran rows<br/>signed amount, period, source FK"]
    H --> I[(wa_gl_trans)]

Around this engine sits a large family of per-domain posting services in app/Services/*GlPostingService.php (40+: SupplierInvoiceGlPostingService, RouteSalesGlPostingService, GrnGlPostingService, CashSalePaymentsGlPostingService, CreditNoteGlPostingService, PayrollMonthGlPostingService, etc.). Each knows the DR/CR shape of its business event and which accounts to hit, then delegates to GlTransactionService.

3.2 Account resolution — which account does each event hit?

Two mechanisms coexist:

  1. Extensive mode (app/Services/ExtensiveGlPostingService.php): a feature flag isEnabled() reads administration_settings.slug = 'use-extensive-gl-posting' (:19-26). When on, per-category account codes resolve from WaCompanyPreference (per-branch via Restaurant.wa_company_preference_id, :34-43), TaxManager (VAT), and Restaurant columns — e.g. gitAccountCode() → goods_received_clearing_gl_account (:60-64), cogsAccountCode(), salesAccountCode(), debtorsAccountCode(), inputVatAccountCode()/outputVatAccountCode(), branchCashSalesAccountCode(). accountCode(id,label) resolves an id → wa_charts_of_accounts.account_code and throws GlPostingException if unconfigured (:46-57).
  2. gl_configurations table (§4.5) — the GL Configurations screen (general-ledger-configurations.index) edits name → wa_charts_of_accounts_id mappings. This appears to be a newer/parallel config surface; the per-category WaCompanyPreference columns are what the extensive posting services actually read (see Open Questions on which is authoritative).

3.3 Chart of Accounts maintenance

chart-of-accounts.index lists accounts from wa_charts_of_accounts. Users create/edit accounts (code, name, pl_or_bs classification, group, parent). Accounts are soft-deleted (deleted_at, added 2025-09) so historical GL rows keep resolving.

3.4 Manual journal-voucher (JV) lifecycle

Handled by app/Http/Controllers/Admin/JournalEntryController.php. A clerk opens General Journal (journal-entries.index), creates a wa_journal_entries header (status = 'pending') and line items in wa_journal_entrie_items (each line has separate debit/credit and a gl_account_id). A process() action validates DR total == CR total, then posts.

  • Posting (JV process): for each line it creates a WaGlTran row — credit lines as amount = '-' . $item->credit, debit lines as amount = $item->debit — stamping transaction_no = journal_entry_no, grn_type_number = 11 (JOURNAL_ENTRY series), and wa_journal_entrie_id = header id. Sub-ledger rows are also written when a line targets a Bank / Customer / Supplier account (wa_banktrans / wa_debtor_trans / wa_supp_tran).
  • State transition: header status: pending → processed after posting. Processed JVs surface under Processed JV (journal-entries.processed_index), which reconstructs debit/credit from the signed wa_gl_trans.amount.
stateDiagram-v2
    [*] --> Pending: clerk creates JV header + lines
    Pending --> Pending: add/edit lines (debit/credit per line)
    Pending --> Validated: process() checks DR total == CR total
    Validated --> Processed: insert WaGlTran rows (signed amount)<br/>+ sub-ledger rows if Bank/Cust/Supp
    Processed --> [*]: header status = 'processed', locked
    Validated --> Pending: unbalanced -> rejected

3.5 GL-side banking — deposits & transfers

Under the Banking submenu: Bank Accounts (bank-accounts.index) is the master (wa_bank_accounts, each row maps a bank to a GL code via bank_account_gl_code_id). Bank Deposit (banking.deposite.list) and Transfer (banking.transfer.list) move money between GL bank accounts and post the matching double entry to wa_gl_trans plus a wa_banktrans line. Reconcile Daily Transactions (banking.reconcile.daily.transactions) reconciles bank movements for the day.

flowchart LR
    A[Bank Deposit / Transfer form] --> B[pick source & dest bank accounts]
    B --> C[GlTransactionService: DR dest bank, CR source bank]
    C --> D[(wa_gl_trans: 2 signed rows)]
    C --> E[(wa_banktrans: bank-side line)]

Receivables reconciliation (customer receipt → bank statement match → GL post) is Book 1 Ch6, not repeated here.

3.6 Utilities & EOD

The Utility submenu is an integrity toolbox operating on wa_gl_trans: Transaction Search (gl-transaction-search.index), Manual GL Posting (gl-reconciliation.manual-posting.create → ManualGlPosting/ManualGlPostingItem models), Records Pending GL (source docs not yet posted: sales-payments / bank-statements / resolved-short-banking), and clean-up tools: GL Trans Duplicates, GL Account Misposts, Debtors-GL Mismatch, Untraced in GL, Unbalanced Transactions, GL Clean up, Trans Dates Cleanup, Subsidiary/Debtors/Creditors vs GL, Transfer GL Transactions, Document Number Change, Bank Recon.

GL EOD Routine (gl-eod-routine.index): the related console command app/Console/Commands/RunEndOfDayChecks.php iterates branches with activate_transfers = 1 and runs OperationShiftService::index() to close operational shifts. Note: EOD does not batch-post GL — GL rows are posted immediately at transaction time. (The screen's exact behaviour vs the console command is an Open Question.)


4. Tables touched & key data

(narrative — plain language)

Six tables carry the GL. wa_gl_trans is the ledger itself — one row per debit or credit, tagged with an account code and a signed amount. wa_charts_of_accounts is the account master. wa_journal_entries + wa_journal_entrie_items hold manual journal vouchers (header + lines). wa_banktrans shadows the cash/bank side, and wa_bank_accounts is the bank-account master.


4.1 wa_gl_trans — the ledger spine

Migration: database/migrations/2023_09_08_134414_create_wa_gl_trans_table.php:17-48. Key columns:

  • account (string, indexed) — the GL account code it hits (matches wa_charts_of_accounts.account_code).
  • amount (decimal(15), widened to decimal(20,2) in 2026_02_01_150000_increase_amount_column_sizes.php:16) — a single SIGNED amount. There is no separate debit/credit column on wa_gl_trans. Debits are positive, credits are negative (confirmed by the posting code — see §3 and Book 1 Ch6:177, which writes credit = -abs(amount), debit = +abs(amount)). A balanced transaction sums to zero across its rows.
  • transaction_no (string, indexed) — the group key tying together the DR/CR legs of one business event.
  • transaction_type, grn_type_number, reference, narrative (text) — descriptive/source fields.
  • trans_date (dateTime), period_number (string) — the accounting date and period bucket.
  • Source foreign keys — this is how GL rows trace back to their origin module: wa_purchase_order_id, wa_internal_requisition_id, stock_adjustment_id, wa_supp_tran_id, wa_debtor_tran_id, wa_sales_invoice_id, wa_credit_note_id, wa_journal_entrie_id (misspelled — see below), wa_pos_cash_sales_id. Exactly one is typically set per row, identifying which module posted it.
  • balancing_gl_account (string) — the "other side" account (contra) for the leg.
  • tb_reporting_branch (unsignedInteger, added 2024_04_08_093327_add_tb_reporting_branch_to_wa_gl_trans.php:14) — the branch/location the row rolls up to on the Trial Balance.
  • customer_id (added 2024_07_01_133937_add_customer_to_wa_gl_trans.php:15) — links a GL row to a debtor (feeds "Add Customer to GL" / Debtors-vs-GL utilities).
  • gl_reconcile_id, gl_recon_statement_id (added 2024_09_03_113324_add_column_to_wa_gl_trans.php:15-16) — bank-reconciliation linkage.
  • salesman_id, shift_id, restaurant_id, supplier_account_number, user_id, cheque_image, banking_expense_id, banking_expense_type.

⚠️ Misspelling flagged verbatim: the FK column is wa_journal_entrie_id (should be ..._entry_id), matching the equally-misspelled table wa_journal_entrie_items.

"Processed" vs unprocessed: wa_gl_trans itself has no status/posted flag — a row's existence in wa_gl_trans is the posting. "Processed" is a state of the source document (the journal, the payment), not of the GL row. Once a source doc is processed, its GL rows exist; there is no draft GL row. (See Open Questions.)

4.2 wa_charts_of_accounts — account master

Migration 2023_09_08_134414_create_wa_charts_of_accounts_table.php:17-25: - account_name, slug, account_code (the code wa_gl_trans.account joins to). - wa_account_group_id, wa_account_sub_section_id (added 2023_12_05_151030:15) — grouping for reports. - pl_or_bs — enum ('PROFIT AND LOSS', 'BALANCE SHEET'); drives whether the account lands on the P&L or the Balance Sheet. - parent_id, is_parent (added 2023_12_05_151030:16-17) — hierarchy (parent/roll-up accounts). - deleted_at — soft-deletes added 2025_09_23_155219_add_soft_deletes_to_chart_of_accounts.php:16.

4.3 Journal tables

wa_journal_entries (header, 2023_09_08_134414_create_wa_journal_entries_table.php:17-25): journal_entry_no, slug, date_to_process (date the JV should post), entry_type, status enum ('pending','processed') default 'pending', user_id.

wa_journal_entrie_items (lines, 2023_09_08_134414_create_wa_journal_entrie_items_table.php:17-28) — ⚠️ table name misspelled "entrie": - wa_journal_entry_id (FK to header — note this column is spelled "entry", unlike the table name and the wa_gl_trans.wa_journal_entrie_id FK — inconsistent), gl_account_id, - credit and debit (separate columns here, decimal(10) → decimal(20,2) in 2026_02_01_150000:21-22) — the journal captures DR/CR separately, then the posting service converts to the signed amount on wa_gl_trans. - entry_type, narrative, reference, restaurant_id.

4.4 Bank tables

wa_banktrans (2023_09_08_134414_create_wa_banktrans_table.php:17-33): type_number, document_no, bank_gl_account_code, reference, trans_date, wa_payment_method_id, amount (decimal(10)), wa_curreny_id (⚠️ misspelled "curreny"), balancing_gl_account (unique), cashier_id, plus enum flags amountCleared, exrate, functionalExrate.

⚠️ Naming caution: the table is wa_banktrans (migration name), but code and Book 1 Ch6 refer to it as wa_bank_trans / wa_banktran. Treat these as the same table; confirm the live table name against the schema.

wa_bank_accounts (2023_09_08_134414_create_wa_bank_accounts_table.php:17-26): account_name, account_code, account_number, bank_account_gl_code_id (the GL account this bank maps to), currency, bank_address, wa_payment_method_id (added 2025_02_17_165824:15).

4.5 GL configuration — event → account mapping

A gl_configurations table exists (2025_10_07_223238_create_gl_configurations_table.php:14-22): name (event key), code, description, wa_charts_of_accounts_id (the account that event posts to), active (bool). This is the "which account does each posting hit" config that the GL Configurations screen edits.

⚠️ The chapter brief anticipated a general_ledger_configurations table; the migration found is named gl_configurations (singular concept, created 2025-10). The route is general-ledger-configurations.index. Whether an older/other config table also exists is an Open Question — the posting services (§3) are the authoritative source of account resolution.


5. Interactions with other modules

(narrative — plain language)

The GL is the destination trial balance for the entire ERP. It has almost no "outbound" handoffs — it mostly receives. Every module that moves value posts inbound rows into wa_gl_trans, and the Reports screens read them back out. The only genuine two-way seams are the sub-ledgers (debtors, creditors, bank) which the GL keeps in step, and the Utility screens that reach into other modules' pending records to force a posting.


Inbound postings (other modules → wa_gl_trans): identified by which source FK the row carries and which *GlPostingService wrote it.

Source module Book Example services GL rows (typical)
Accounts Payable (supplier invoices, GRN, cash payments) Book 3 SupplierInvoiceGlPostingService, GrnGlPostingService, SupplierCashPaymentGlPostingService DR GIT/Purchases + VAT input, CR Creditors control / WHT-VAT-statutory liabilities / Bank; also wa_banktrans
Sales / Debtors (invoices, route sales, credit notes, receipts) Book 1 RouteSalesGlPostingService, RouteSalePaymentGlPostingService, CreditNoteGlPostingService, CashSalePaymentsGlPostingService DR Debtors control / Cash Control, CR Sales + Output VAT
Inventory (adjustments, movement, COGS) Book 2 ConsumableStockAdjustmentGlPostingService, extensive COGS legs (applySalesCogsPosting) DR/CR Stock movement, COGS, Purchase variance
Payroll / Petty cash Book 3/17 PayrollMonthGlPostingService, PettyCashDisbursementGlPostingService Salary/expense + statutory liabilities
Manual journals (this chapter) Book 4 JournalEntryController@process Any account pair the clerk keys

CRITICAL inbound seam (per brief): Book 3 Accounts Payable posts to wa_gl_trans + wa_banktrans; Book 1 (sales/debtors) and Book 2 (inventory) also feed here. Confirmed via the domain posting services all delegating to GlTransactionService and by Book 1 Ch6's own documentation of writing wa_gl_trans + wa_banktran on approval (01_sales_and_revenue/06_...:149,177).

Sub-ledger sync: when a GL leg targets a Bank / Customer / Supplier account, the writing code also inserts the matching sub-ledger row — wa_banktrans (bank), wa_debtor_trans (debtor control), wa_supp_tran (creditor control) — so subsidiary ledgers stay reconciled to the GL. The Subsidiary/Debtors/Creditors vs GL utilities (DebtorsVsGlController) exist to catch drift when this sync fails.

Outbound (GL → elsewhere): Reports (GeneralLedgerReportsController) read wa_gl_trans to build Trial Balance / P&L / Balance Sheet; the pl_or_bs flag on wa_charts_of_accounts routes each account to the right statement. Fixed Assets (Ch16) posts depreciation/capitalization into the GL — that posting lives in Ch16, but it lands here.


6. Alternatives & variants

(narrative — plain language)

Bizwiz posts to the GL two very different ways, and the choice is a per-tenant setting. There is also a "simple vs extensive" split in how granular the postings are, a manual override path, and two nav modules that are visible but switched off.


  • Automated vs manual posting. The overwhelming majority of GL rows are written automatically by *GlPostingService classes at transaction time. The manual path is (a) the Journal Voucher (JournalEntryController) for accruals/corrections, and (b) Manual GL Posting (ManualGLPostingController@create, manual-gl-posting___add) which writes ManualGlPosting/ManualGlPostingItem and then to wa_gl_trans — used mostly to force unmatched reconciliation records into the ledger.

  • Extensive vs default posting (per-tenant feature flag). ExtensiveGlPostingService::isEnabled() reads administration_settings.slug = 'use-extensive-gl-posting' (:19-26). When enabled, sales/purchase/inventory events post a rich, per-category set of legs (GIT, Uninvoiced GRN, Purchases, Stock Movement, COGS, Sales control, Debtors, Input/Output VAT, Purchase Variance), with account codes resolved per-branch from WaCompanyPreference (via Restaurant.wa_company_preference_id), TaxManager, and Restaurant columns. When disabled, the legacy simpler posting runs. This is the tenant/feature-flag difference the brief flagged: the same business event yields a different set of GL legs depending on the flag.

  • Branch-specific accounts. With extensive mode (and the SEPARATE_GL_ACCOUNTS_PER_BRANCH-style preferences noted in Book 1 Ch6:177), cash-control and other accounts resolve per branch; otherwise a company-wide default account (e.g. Cash Control 54008-000) is used.

  • Two account-mapping surfaces. gl_configurations (name → wa_charts_of_accounts_id, edited via GlConfigurationsController) vs the per-category columns on WaCompanyPreference/TaxManager that the extensive services actually read. Which is authoritative for a given posting is an Open Question.

  • Edge cases / integrity utilities. The Utility submenu is essentially a catalogue of known failure modes: duplicate GL rows, mispostings to wrong accounts, unbalanced transactions, orphaned/untraced rows, transactions without a branch, wrong trans-dates, and debtor/creditor-vs-GL drift. GlCleanupUtilityController bundles orphan removal and cash-debtor transfers.

  • Disabled modules. Budgeting and Cash Management render in the nav but are hard-disabled (pointer-events:none; opacity:0.6; onclick="return false;", sidebar :582-604) — placeholders for future functionality, no routes/controllers wired.


7. Open questions to confirm

CODE-PROVEN (stated as fact, with file:line)

  • wa_gl_trans is a single signed-amount ledger; debits positive, credits negative; a transaction must net to zero. GlTransactionService::dr/cr (app/Services/GlTransactionService.php:67-84), balance check throwing UnbalancedGlTransactionException (:130-139), and save() inserting WaGlTran (:145-181). Journal path mirrors it: credit = '-' . $item->credit, debit = $item->debit (JournalEntryController@process).
  • wa_gl_trans has no debit/credit columns and no posted/status flag — verified against migration 2023_09_08_134414_create_wa_gl_trans_table.php:17-48 (only signed amount).
  • Journal header status enum is ('pending','processed') — 2023_09_08_134414_create_wa_journal_entries_table.php:17-25.
  • Extensive posting is gated by administration_settings.slug = 'use-extensive-gl-posting' — ExtensiveGlPostingService.php:19-26.
  • Misspelled identifiers (verbatim): table wa_journal_entrie_items; FK wa_gl_trans.wa_journal_entrie_id; column wa_banktrans.wa_curreny_id. Migration files cited in §4.
  • Budgeting & Cash Management are disabled nav placeholders — general_ledger.blade.php:582-604.
  • Every domain posting funnels through GlTransactionService, with 40+ *GlPostingService classes in app/Services/.

INFERENCE / needs human validation

  • Which config surface is authoritative — gl_configurations vs WaCompanyPreference/TaxManager columns? The extensive services read the preference/tax columns; gl_configurations (created 2025-10) is edited by GlConfigurationsController but I did not statically confirm a posting path that reads it. Needs confirmation of which one drives live postings.
  • "Processed" semantics for GL rows. I assert GL rows have no status flag and "processed" is a source-document state. Confirm no other module treats a GL row as draft/unposted (e.g. via gl_reconcile_id).
  • GL EOD Routine screen behaviour. The console command RunEndOfDayChecks.php closes shifts and does not post GL; the GlEodRoutineController@index screen reportedly runs "unbalanced GL and subsidiary verification." Confirm the screen's exact actions (verification-only vs corrective) with a dev.
  • The general-ledgers.gl-entries permission transfers___view (sidebar :179) looks like a copy-paste reuse rather than an intentional dependency on a transfers module — flag for review (same pattern Book 1 Ch6 noted).
  • wa_banktrans vs wa_bank_trans/wa_banktran naming. Migration creates wa_banktrans; code/Ch6 use variants. Confirm the single live table name.
  • Account-code constants (Cash Control 54008-000, Fraud 55001-007) come from Book 1 Ch6; confirm these are the same defaults used by the extensive services when no branch override exists.
  • Whether journal-entries supports a distinct approval step beyond process(). The agent found store + process but no separate approve method; confirm approval is folded into process().

8. Source references

Nav / permissions - resources/views/admin/includes/sidebar_includes/general_ledger.blade.php — full GL/Banking/Utility/Reports menu; permission gates at lines cited in §2; disabled modules :582-604. - app/helpers.php:4182 (can()), :4195-4207 (getUserPermissions, role_id==1 → 'superadmin').

Schema (migrations) - database/migrations/2023_09_08_134414_create_wa_gl_trans_table.php:17-48; widen amount 2026_02_01_150000_increase_amount_column_sizes.php:16; adds 2024_04_08_093327_...:14 (tb_reporting_branch), 2024_07_01_133937_...:15 (customer_id), 2024_09_03_113324_...:15-16 (gl_reconcile_id, gl_recon_statement_id). - ..._create_wa_charts_of_accounts_table.php:17-25; 2023_12_05_151030_...:15-17; soft-deletes 2025_09_23_155219_...:16. - ..._create_wa_journal_entries_table.php:17-25; ..._create_wa_journal_entrie_items_table.php:17-28. - ..._create_wa_banktrans_table.php:17-33; ..._create_wa_bank_accounts_table.php:17-26 + 2025_02_17_165824_...:15. - 2025_10_07_223238_create_gl_configurations_table.php:14-22.

Services - app/Services/GlTransactionService.php — make():44, dr():67, cr():79, balance():105, post():113, save():145. - app/Services/ExtensiveGlPostingService.php — isEnabled():19, companyPreferenceForBranch():34, accountCode():46, gitAccountCode():60, plus per-category resolvers :74-161. - app/Services/*GlPostingService.php — 40+ domain posting services (list in §3.1). - app/Console/Commands/RunEndOfDayChecks.php — EOD shift close.

Controllers - app/Http/Controllers/Admin/ChartsOfAccountController.php:85 (chart index). - app/Http/Controllers/Admin/JournalEntryController.php — index:39, processed_index:58, store:328, process:428 (JV posting to wa_gl_trans, status → processed). - app/Http/Controllers/Admin/WaAccountInquiryController.php:54; GeneralLedgersController.php:25 (glEntries); EditLedgerController.php:35; Finance/WaGLJournalInquiryController.php:17. - Banking: BankAccountController.php:37; WaBankingController.php — transferList:36, depositeList:125, reconcile_daily_transactions:806. - Utility: GlTransactionSearchController.php:22; ManualGLPostingController.php:38; GlReconciliationController.php — pending-GL :1035/:1475/:2205, duplicates :1801, mispost :1948, debtors-mismatch :2075; AssignAccountUserController.php:25; TransactionsWithoutBranchesController.php:17; GlConfigurationsController.php:15; UpdateGLCustomerController.php:20; UntracedInGLController.php:21; UnbalancedGlTransactionsController.php:21; GlCleanupUtilityController.php:552; GlTransDatesCleanupController.php:36; DebtorsVsGlController.php:29; GlTransferTransactionsController.php:23; DocumentNumberChangeController.php:30; BankGlReconciliationController.php:34; GlEodRoutineController.php:24. - Reports: GeneralLedgerReportsController.php:23.

Cross-references - Book 1 Ch6: ai/bizwiz_guide/01_sales_and_revenue/06_banking_and_receivables_reconciliation.md — receivables reconciliation, GL handoff (:149,:177), Cash Control 54008-000 / Fraud 55001-007, wa_banktran naming. - Book 3 (Accounts Payable) — inbound creditors/GIT/VAT/bank postings. Book 2 (Inventory) — COGS/stock postings. Ch16 Fixed Assets — depreciation postings into GL.