LedgerFlow
An offline digital ledger for small businesses: track credit and debit per customer and share PDF statements, with no sign-up.
A mobile app designed and built by Hassan Ur Rahman.
Overview
LedgerFlow ("LedgerFlow: Debt & Credit Book" on Google Play) is a Flutter app for shopkeepers, freelancers, and small business owners. You record money given and received for each customer, and the app keeps a running balance so you always know who owes what.
It replaces paper notebooks and slow phone spreadsheets. There is no account or login, and ledger data stays on the device in SQLite, so the core ledger works offline. The network is only used for sharing, ads, and update checks.
Key features
Multiple businesses
Keep separate businesses, each with its own customers, in one app.
Customer ledger
Credit and debit entries with notes and up to three receipt photos each, a full history per customer, and a running balance.
PDF account statements
Multi-page statements for any date range, grouped by month with subtotals and a closing balance, shared through the system share sheet.
WhatsApp sharing
Send a customer their statement or open a chat with them on WhatsApp in one tap.
Due-date reminders
Set due dates on balances and get local notifications when payments are due.
Reports dashboard
Charts for activity trends, balance distribution, top customers, period comparison, and outstanding balances over any date range.
App lock
PIN, fingerprint, or face lock that re-locks whenever the app goes to the background.
Backup, export, and dark mode
Compressed backups you can save anywhere and restore later, CSV export of customers and transactions, and a dark theme.
How it's built
- Flutter and Dart with Provider for state management, and a repository layer for report queries.
- Local SQLite through sqflite at schema version 10, with step-by-step migrations and indexes for customer and date lookups.
- Backups are gzipped JSON, and receipt photos are resized and re-encoded before they are embedded. Restore detects compressed files by their magic bytes, so older plain-JSON backups still restore.
- PDF statements are generated on the device with the pdf and printing packages, using bundled fonts and a multi-page layout that repeats table headers.
- An app-lifecycle observer drives the auto-lock (local_auth plus PIN) and a usage-based in-app review prompt. Ads are AdMob native ads placed inside the lists.
Challenges & solutions
- Restores failing on duplicate records
- Restore runs inside a single transaction, matches incoming businesses and customers against existing ones, and remaps their IDs, so restoring into a non-empty app skips duplicates instead of failing.
- Multi-page PDF layout bugs
- Fixed a duplicated table header on the second page and a clipped closing-balance label by restructuring how the final table section renders and letting long labels wrap.
- Backups bloated by receipt photos
- Backups are gzip-compressed and photos are resized and re-encoded as JPEG before being embedded, with a plain-JSON fallback if compression fails.
Tech stack
- Flutter
- Dart
- SQLite
- Provider
- fl_chart
- PDF Generation
- Biometrics
- Google Mobile Ads
- Android