laravel-erp-accounting maintained by jeffersongoncalves

Laravel ERP Accounting
ERP accounting — chart of accounts, general ledger, journal/payment entries and invoices for the Laravel ERP ecosystem.
This package is the accounting / general-ledger module of an ERPNext-native rebuild. It sits at the base of the transactional dependency graph: it depends only on jeffersongoncalves/laravel-erp-core and never on selling, buying or stock packages. Those packages depend on it.
Features
- Chart of Accounts — Hierarchical accounts with
RootType/AccountTypeclassification, cost centers, and a configurable table tree - Double-Entry General Ledger — A single
GeneralLedgerServiceposts and reverses balanced ledger entries for every submittable voucher, enforcingdebit == credit - Transaction Documents — Journal entries, payment entries, sales invoices and purchase invoices, all built on the core
IsSubmittablelifecycle (Draft → Submitted → Cancelled) - Immutable Ledger —
gl_entriesrows can never have their monetary impact edited or be deleted; cancellation writes mirror rows so the net effect is zero - Masters — Payment terms, modes of payment, tax templates, banks, bank accounts and budgets
- Period Closing & Bank Reconciliation — Period closing vouchers that zero out income/expense into a closing account, plus a lightweight bank transaction model
- Customizable Models — Override any model via config (ModelResolver pattern);
AccountandGlEntryship swappable contracts - Translations — English and Brazilian Portuguese
Compatibility
| Package | PHP | Laravel |
|---|---|---|
^1.0 |
^8.2 |
^11.0 | ^12.0 | ^13.0 |
Installation
composer require jeffersongoncalves/laravel-erp-accounting
Publish and run the migrations (the core package migrations must be published too):
php artisan vendor:publish --tag="erp-core-migrations"
php artisan vendor:publish --tag="erp-accounting-migrations"
php artisan migrate
Publish the config (optional):
php artisan vendor:publish --tag="erp-accounting-config"
Dynamic Party & Item Links (Frappe-style)
To keep accounting at the base of the dependency graph, transaction documents reference external parties and items without hard foreign keys — the Customer, Supplier and Item models live in other packages that may not be installed.
- Party reference =
party_type(string, e.g.'Customer'/'Supplier') +party_id(nullable unsigned big integer) + a denormalizedparty_name/customer_name/supplier_name. There is no FK constraint to a Customer or Supplier table. - Item reference (on invoice lines) =
item_code(string) +item_name(string) + the chosen GL account (income_account_id/expense_account_id). There is no FK to an Item model.
This mirrors ERPNext/Frappe "Dynamic Link" fields: the ledger records what was transacted and against whom by value, while only the genuinely accounting-owned references (accounts, cost centers, companies) use real foreign keys.
The General Ledger
GeneralLedgerService is the heart of the module and is registered as a singleton.
use JeffersonGoncalves\Erp\Accounting\Services\GeneralLedgerService;
$gl = app(GeneralLedgerService::class);
// Post a balanced set of entries for a submittable voucher.
$gl->post($voucher, [
['account_id' => $ar->id, 'debit' => 110, 'credit' => 0],
['account_id' => $income->id, 'debit' => 0, 'credit' => 100],
['account_id' => $tax->id, 'debit' => 0, 'credit' => 10],
]);
// Unwind every entry of a voucher on cancellation (net zero).
$gl->reverse($voucher);
// Running balance (debit - credit), optionally up to a date.
$gl->accountBalance($account);
post() throws DomainException('Debit and credit not balanced') (compared on rounded 2-decimals) when the entries do not balance. Documents implementing PostsToLedger call these hooks automatically on submit() and cancel().
Posting logic
- Sales Invoice —
debitthe receivable (debit_to) for the grand total,crediteach line'sincome_accountfor its amount,crediteach tax account for its tax amount;outstanding_amountis set to the grand total. - Payment Entry — Receive:
debitpaid_to(bank) andcreditpaid_from(receivable) forpaid_amount; Pay is the inverse; Internal Transfer debitspaid_toand creditspaid_from. - Purchase Invoice — mirror of the sales invoice:
creditthe payable (credit_to) for the grand total,debiteach line'sexpense_accountand each tax account. - Journal Entry — posts one GL row per child account line exactly as entered, after validating that total debit equals total credit.
Database Tables
All tables use the configured prefix shared with the core package (default: erp_): accounts, cost_centers, payment_terms, modes_of_payment, tax_templates, tax_template_taxes, banks, bank_accounts, budgets, budget_accounts, gl_entries, journal_entries, journal_entry_accounts, payment_entries, sales_invoices, sales_invoice_items, sales_invoice_taxes, purchase_invoices, purchase_invoice_items, purchase_invoice_taxes, period_closing_vouchers, bank_transactions.
Testing
composer test
Changelog
Please see CHANGELOG for what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
The MIT License (MIT). Please see License File for more information.