A production-oriented, multi-tenant finance backend for Zelani. It centralizes invoicing, collections, expenses, payroll, statutory obligations, banking, FX, accounting, and audit trails in one Django REST API.
- 1. Business Context
- 2. Core Capabilities
- 3. Technology Stack
- 4. System Architecture
- 5. Domain Modules
- 6. Request Lifecycle
- 7. Getting Started
- 8. Configuration
- 9. API Surface
- 10. Data and Accounting Flow
- 11. Testing and Quality
- 12. Project Layout
- 13. Operations Notes
- 14. Contribution Guide
- 15. License
Insurance and claims operations usually split financial processes across disconnected tools. This module keeps everything in one place and links transactions to tenants and business events.
Typical outcomes:
- Faster fee note generation and insurer follow-up.
- Better visibility into receivables, payroll costs, and liabilities.
- Cleaner month-end close through structured journals and reports.
- Lower audit risk via immutable action history.
- Multi-tenant data model using tenant-aware entities.
- Double-entry accounting structures via accounts and journal entities.
- Fee note lifecycle for invoice issuance and reminders.
- Payment capture with withholding tax credit tracking.
- Expense and reimbursement workflows.
- Payroll computation and payroll line breakdowns.
- Statutory obligation tracking (due dates, statuses, amounts).
- Bank and petty cash records with reconciliation support.
- FX rates and multi-currency support.
- Reporting endpoints for income statement, receivables, and payroll summaries.
- Immutable audit records for key actions.
- Python 3.11 and 3.12
- Django 4.2
- Django REST Framework
- PostgreSQL (primary runtime database)
- Celery + Redis (asynchronous jobs and scheduling)
- drf-spectacular (OpenAPI schema + Swagger/ReDoc)
- Docker + Docker Compose (local and CI-friendly packaging)
Client Apps / Admin UI
|
v
Django REST API (zelani.urls)
|
+--> tenants app (tenant registry and configuration)
+--> finance domain apps
| - accounts
| - invoicing
| - payments
| - expenses
| - payroll
| - statutory
| - banking
| - fx
| - audit
| - reports
|
+--> PostgreSQL (persistent data)
+--> Redis (broker/backend)
|
v
Celery worker/beat
The project follows modular Django app boundaries. Every finance area has models, serializers, views, and URLs, with business logic consolidated in service modules where workflows are non-trivial.
- App: tenants
- Key models:
- Tenant
- TenantSetting
- Responsibility: tenant registry and tenant-level settings used across all finance apps.
- App: finance.accounts
- Key models:
- Account
- JournalEntry
- JournalLine
- Responsibility: chart-of-accounts structures and general journal lines posted by financial events.
- App: finance.invoicing
- Key models:
- FeeNote
- FeeNoteReminder
- Service: FeeNoteService
- Responsibility: issue fee notes, track status and reminders.
- App: finance.payments
- Key models:
- FeeNotePayment
- WHTCredit
- Service: PaymentService
- Responsibility: register incoming payments and withholding tax credits.
- App: finance.expenses
- Key models:
- Expense
- ReimbursementBatch
- ReimbursementRequest
- Responsibility: expense capture and reimbursement management.
- App: finance.payroll
- Key models:
- EmployeePayrollProfile
- EmployeeAllowance
- PayrollRun
- PayrollLine
- Service: PayrollService
- Responsibility: payroll run computation and employee-level line items.
- App: finance.statutory
- Key model:
- StatutoryObligation
- Responsibility: track statutory payable obligations and due dates.
- App: finance.banking
- Key models:
- BankAccount
- BankReconciliation
- PettyCashTransaction
- Cheque
- Responsibility: bank operations and reconciliation records.
- App: finance.fx
- Key model:
- ExchangeRate
- Responsibility: exchange rate storage and conversion support.
- App: finance.audit
- Key model:
- AuditLog
- Responsibility: append-only operational traceability.
- App: finance.reports
- Endpoints expose:
- Income statement data
- Outstanding invoices/receivables
- Payroll summary metrics
- Client authenticates and calls API endpoint.
- DRF view validates input with serializer.
- Business service executes workflow where applicable.
- Domain models are saved in PostgreSQL.
- Related financial or audit records are generated.
- API returns normalized response payload.
- Python 3.11 or 3.12
- PostgreSQL 14+
- Redis 7+
- Docker Desktop or Docker Engine (optional, recommended)
git clone https://github.com/zelanitech/Zelani-Finance-Module.git
cd Zelani-Finance-Module
cp .env.example .env
docker compose up --buildCreate an admin account:
docker compose exec web python manage.py createsuperusergit clone https://github.com/zelanitech/Zelani-Finance-Module.git
cd Zelani-Finance-Module
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
cp .env.example .env
python manage.py migrate
python manage.py createsuperuser
python manage.py runserverStart worker processes in separate terminals:
celery -A zelani worker -l info
celery -A zelani beat -l infomake help
make install
make migrate
make run
make test
make lint
make docker-upCreate .env from .env.example and set the following values:
| Variable | Required | Example | Purpose |
|---|---|---|---|
| SECRET_KEY | Yes | change-me | Django secret |
| DEBUG | No | True | Django debug mode |
| ALLOWED_HOSTS | No | localhost,127.0.0.1 | Allowed hosts list |
| DB_NAME | Yes | zelani_db | PostgreSQL database |
| DB_USER | Yes | postgres | PostgreSQL user |
| DB_PASSWORD | Yes | password | PostgreSQL password |
| DB_HOST | Yes | localhost | PostgreSQL host |
| DB_PORT | No | 5432 | PostgreSQL port |
| CELERY_BROKER_URL | Yes | redis://localhost:6379/0 | Celery broker |
| CELERY_RESULT_BACKEND | Yes | redis://localhost:6379/0 | Celery result backend |
| CORS_ALLOWED_ORIGINS | No | http://localhost:3000 | Comma-separated origins |
- GET /api/schema/
- GET /api/docs/
- GET /api/redoc/
- /api/tenants/
- /api/finance/accounts/
- /api/finance/invoicing/
- /api/finance/payments/
- /api/finance/expenses/
- /api/finance/payroll/
- /api/finance/statutory/
- /api/finance/banking/
- /api/finance/fx/
- /api/finance/audit/
- /api/finance/reports/
All endpoints are authenticated by default through DRF settings.
Examples of end-to-end flow:
-
Invoice flow:
- Fee note created.
- Receivable impact recorded in accounting layer.
- Reminder records may be generated.
-
Collection flow:
- Payment posted against fee note.
- Outstanding balance is reduced.
- WHT credits are tracked when supplied.
-
Payroll flow:
- Payroll run created.
- Payroll lines generated per employee.
- Statutory obligations and expense implications become reportable.
python manage.py check --settings=zelani.test_settings
python manage.py test tests/ --settings=zelani.test_settings --verbosity=2flake8 .
isort --check-only --diff .The CI workflow runs tests on Python 3.11 and 3.12 and executes lint checks in a dedicated job.
.
|-- manage.py
|-- requirements.txt
|-- requirements-dev.txt
|-- Dockerfile
|-- docker-compose.yml
|-- Makefile
|-- finance/
| |-- accounts/
| |-- invoicing/
| |-- payments/
| |-- expenses/
| |-- payroll/
| |-- statutory/
| |-- banking/
| |-- fx/
| |-- audit/
| `-- reports/
|-- tenants/
|-- tests/
`-- zelani/
- Use PostgreSQL in runtime environments. The test settings use SQLite for fast CI test execution.
- Keep tenant boundaries strict in all future model additions.
- Avoid committing generated runtime artifacts such as pycache and .pyc files.
- For production hardening: set DEBUG=False, rotate secrets, and configure ALLOWED_HOSTS/CORS explicitly.
Please read CONTRIBUTING.md before opening issues or pull requests.
MIT License. See LICENSE for details.