ekmungai/laravel-ifrs
Laravel IFRS brings double-entry accounting and IFRS-compliant financial reporting to Laravel apps. Manage chart of accounts, journal entries, ledgers, and trial balances, then generate balance sheets, income statements, and other audit-ready financial reports from clean data.
This release targets Laravel 11–13 on PHP 8.2+, so confirm your app is on a supported runtime before anything else:
php -v # must be >= 8.2
composer require vendor/package:^6.0
php artisan vendor:publish --tag=package-migrations
php artisan migrate
If you published migrations in a previous major, re-check remove_vat_id_column — v6 changes the drop order (foreign key before column). On SQLite with Laravel 11+ the old ordering fails during the table rebuild, so either republish the migration or add a follow-up migration that drops the FK explicitly first.
Look first at the config file (chart of accounts / default currency / VAT settings) and the migrations, since the data model is the actual API surface here. The first meaningful use case is a single end-to-end posting:
LineItem records referencing those accounts.If that round-trip works, the rest of the package is variations on it.
Chart of accounts as data, not code. Seed accounts in a seeder and reference them by a stable code/slug in your app rather than by ID, so re-seeding in test or staging environments doesn't break posting logic.
Wrap posting in a transaction with a service class. Line items, VAT rows and totals should be written atomically. A thin LedgerService::post() around the package models keeps controllers and jobs clean, and gives you one place to add validation (balanced entries, non-zero amounts, valid account types).
VAT as a first-class concern. Let the package's Vat models own the rate and computed amounts rather than calculating tax in your own code — otherwise your stored totals and the package's reports will drift. When a rate changes, create a new rate record instead of mutating an existing one, so historical entries keep their original rate.
Report generation as an explicit, cacheable step. Trial Balance, aging via AccountSchedule, and similar reports are read-side operations. Run them in a queued job or a scheduled command and persist the output if they're expensive, rather than calling them inside a request that also writes data.
Aging buckets around Carbon 3. Carbon 3's diffInDays() returns a signed float. Any bucket logic you write on top of AccountSchedule should normalise with (int) abs(...) or pass the absolute flag, otherwise an account due in the future can land in the "overdue 90+" bucket.
Testing against the package. Pin orchestra/testbench to the version matching your Laravel target (^9, ^10, ^11), and seed Faker in your own setUp/bootstrap if you assert on generated monetary values — a process-wide PRNG means amounts shift depending on test order. Better still, avoid asserting on factory-generated amounts at all; assert on amounts you set explicitly.
LineItem and Vat factories generating zero amount/quantity/rate. If you copied factories into your app, do the same — zero-value lines produce zero-balance accounts that reports legitimately omit, and assertions on "account exists in report" then fail intermittently.diffInDays() and comparing to an int needs review after the upgrade — floats and signs both changed. diffInDays($other, true) for absolute whole days.collision, phpunit and laravel-ignition pins will block the upgrade in CI even if your app code is fine.phpunit.xml, the <source> element replaces <coverage> filters and several attributes were removed. Silent misconfiguration here means coverage or test-suite filters quietly stop applying.How can I help you explore Laravel packages today?