Billing V2 - Advanced Django Billing System
A comprehensive, production-ready billing platform built with Django, Celery, and PostgreSQL. Handles recurring invoices, client management, reconciliation, and automated scheduling.
π Features
Core Billing
- β Recurring Invoicing β Automatic monthly billing based on custom policies
- β Invoice Management β Create, edit, send, and track invoices
- β Client Management β Multi-tenant support with client profiles
- β Payment Tracking β Record and reconcile payments
- β Quote Workflow β Create quotes and convert to invoices
- β Credit Notes β Handle refunds and adjustments
Advanced Features
- π€ AI Insights β Anomaly detection using Google GenAI
- π§ Email Integration β Automated invoice delivery via Brevo
- β±οΈ Timesheet Management β Log hours, track by category, generate invoices
- π Reconciliation β Data integrity checks and dual verification
- π Analytics Dashboard β Real-time financial metrics
- π Notifications β Client alerts and system notifications
- β° Flexible Scheduling β First working day, specific dates, or custom rules
- π·οΈ Invoice Type Filtering β Filter & sort invoices by Items vs Timesheet
- π¨ Automated Monitoring β Error detection with email alerts every 10 minutes
Technical
- π³ Docker & Docker Compose β Full containerization
- π Celery + Redis β Async task processing & scheduling
- π PostgreSQL β Robust relational database
- π Multi-tenancy β Isolated user data
- π§ͺ Comprehensive Tests β 10+ tests for recurring invoicing
- π‘οΈ Security β CSRF protection, SSL/TLS ready, audit logging
π Prerequisites
Option 1: Docker (Recommended)
- Docker 20.10+
- Docker Compose 2.0+
- 4GB RAM minimum
Option 2: Local Development
- Python 3.12+
- PostgreSQL 14+
- Redis 7+
- pip or poetry
π Quick Start with Docker
1. Clone Repository
git clone <repository-url> cd billing_v2
2. Setup Environment
cp .env.example .env
# Edit .env with your configuration
nano .envKey variables to update:
DJANGO_SECRET_KEY=your-secret-key-here DB_PASSWORD=strong-password REDIS_PASSWORD=strong-password BREVO_API_KEY=your-email-api-key GOOGLE_GENAI_API_KEY=your-ai-api-key
3. Run Setup Script
chmod +x docker-setup.sh ./docker-setup.sh
Or manually:
# Build images docker-compose build # Start services docker-compose up -d # Run migrations docker-compose exec web python manage.py migrate # Create superuser docker-compose exec web python manage.py createsuperuser
4. Access Application
- Web App: http://localhost:8000
- Admin Panel: http://localhost:8000/admin
- Monitoring: http://localhost:5555 (Celery Flower)
π οΈ Local Development Setup
Prerequisites
# Install Python 3.12 python3.12 --version # Install PostgreSQL brew install postgresql # macOS # or sudo apt-get install postgresql # Ubuntu # Install Redis brew install redis # macOS # or sudo apt-get install redis-server # Ubuntu
Setup
# Create virtual environment python3.12 -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate # Install dependencies pip install -r requirements.txt # Create .env cp .env.example .env # Configure database in .env # DATABASES should use your local PostgreSQL
Run Services
# Terminal 1: Django development server python manage.py runserver # Terminal 2: Celery worker celery -A core_project worker --loglevel=info # Terminal 3: Celery Beat (scheduler) celery -A core_project beat --loglevel=info # Terminal 4: Redis (if not already running) redis-server
π Documentation
| Document | Purpose |
|---|---|
| LOG_MONITORING_README.md | Automated error detection & alert system |
| DOCKER_DEPLOYMENT.md | Complete Docker guide, scaling, troubleshooting |
| RECONCILIATION_GUIDE.md | Data integrity & verification workflows |
| INVOICE_CANCELLATION_RULES.md | Cancellation policies & rules |
| MANAGER_METHODS_DOCUMENTATION.md | API & manager methods reference |
ποΈ Project Structure
billing_v2/
βββ billing_schedule/ # Recurring billing policies
βββ clients/ # Client management
βββ core/ # Core models & authentication
βββ invoices/ # Invoice & payment handling
βββ items/ # Line items & recurring templates
βββ timesheets/ # Timesheet integration
βββ notifications/ # Alert system
βββ templates/ # HTML templates
βββ static/ # CSS, JS, images
βββ core_project/ # Django settings & config
β βββ settings.py # Main configuration
β βββ celery.py # Celery setup
β βββ urls.py # URL routing
βββ docker-compose.yml # Service orchestration
βββ Dockerfile # Container image build
βββ requirements.txt # Python dependencies
βββ manage.py # Django management
π Billing Approaches
This system supports two primary billing workflows to fit your business needs:
Option 1: Recurring Invoicing (Set & Forget)
Perfect for: Fixed monthly services, subscriptions, retainers
How it works:
- Create recurring items once (e.g., "Monthly hosting", "Support retainer")
- Set a billing policy (e.g., "Bill on the 1st of each month")
- The system automatically invoices your clients every month β no further action needed
- Invoices are generated at the scheduled time and emailed to clients
Example:
March 1: Customer A invoiced $1,000 for hosting
April 1: Customer A automatically invoiced again $1,000
May 1: Customer A automatically invoiced again $1,000
... continues every month
Option 2: Accumulate & Invoice (Timesheets + Ad-Hoc Items)
Perfect for: Project work, hourly billing, variable services
How it works:
- All month long: Log timesheet entries OR add ad-hoc items as work is completed
- Log time spent on projects (e.g., 8 hours Dev work = $2,000)
- Add miscellaneous items (e.g., "Server upgrade" = $500)
- Items and timesheets for each client accumulate in the system
- End of month: Trigger bulk invoicing (automatically or manually)
- All accumulated timesheets and items are collated into correct invoices per client
- One invoice per client containing all their work for the month
- Invoices are emailed to clients automatically
Example:
March 5: Log 4 hours Dev work for Client A = $1,000
March 10: Log 2 hours QA work for Client A = $500
March 12: Add miscellaneous item to Client B = $800
March 15: Log meeting time for Client A = $300
March 20: Log 6 hours Dev work for Client B = $1,500
March 31 at 00:01 (or manual trigger):
β Client A invoice created: Dev (4h) + QA (2h) + Meeting (1h) = $1,800
β Client B invoice created: Dev (6h) + Misc item = $2,300
β Invoices emailed to both clients
π User Workflow Diagram
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β MANAGER ADMIN PORTAL β
β β’ Create new tenants/user accounts β
β β’ Manage access and permissions β
ββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββ
β USER LOGIN β
βββββββββ¬ββββββββ
β
ββββββββββΌβββββββββ
β DASHBOARD β
ββββββ¬βββββββββ¬ββββ
β β
ββββββββββββΌββββ ββββΌβββββββββββββββ
β RECURRING β β ACCUMULATE & β
β INVOICES β β INVOICE β
ββββββββββββββββ ββββββββββββββββββββ
β β
β βββΊ Log Timesheets (all month)
βββΊ Create Items β
β βββΊ Add Ad-Hoc Items
βββΊ Set Policy β
β (Run Day) βΌ
β ββββββββββββββββββββ
β β COLLATE BY CLIENTβ
β β (Smart grouping)β
β ββββββ¬ββββββββββββββ
β β
βββββββββββββββββββββββ€
β β
βΌ βΌ
ββββββββββββββββ ββββββββββββββββ
β INVOICES β β INVOICES β
β GENERATED β β GENERATED β
ββββββββ¬ββββββββ ββββββββ¬ββββββββ
β β
ββββββββ¬ββββββββββββ
β
βΌ
ββββββββββββββββββββ
βEMAIL TO CLIENTS β
β(via Brevo) β
ββββββββββ¬ββββββββββ
β
βΌ
ββββββββββββββββββββ
βPAYMENT TRACKING β
ββ’ Record payments β
ββ’ Reconcile β
ββ’ Track reports β
ββββββββββββββββββββ
See the full visual flowchart on our GitHub documentation for an interactive version.
π Billing Workflow
Recurring Invoices (Automatic)
1. Create Billing Policy
- Navigate to
/scheduler/policies/ - Define:
- Name: e.g., "Monthly Service"
- Run Day: Day of month (1-31) or "First Working Day"
- Status: Active/Inactive
2. Link Items to Policy
- Create recurring items in
/items/(e.g., "Hosting", "Support retainer") - Select billing policy
- Mark as recurring
- Set initial
last_billed_date
3. Automatic Daily Processing
- When: Daily at 00:01 (UTC+2) via Celery Beat
- Process:
billing_schedule.tasks.process_daily_billing_queue - Check: Which policies are due today
- Action: Creates invoices for all matching recurring items
- Safety: Prevents duplicates within same month
4. Email Delivery
- Invoices automatically emailed via Brevo API
- Status marked as "PENDING"
emailed_attimestamp recorded
5. Payment Tracking
- Record payments manually or via webhook
- System updates invoice status to "PAID"
- Reconciliation verifies amounts
Accumulate & Invoice (Timesheets + Items)
1. Throughout the Month
- Log Timesheets: Visit
/timesheets/log-time/and record work (hours, rate, category) - Add Items: Create ad-hoc items in
/items/for one-time charges - Accumulate: All entries accumulate in the system β nothing is invoiced yet
2. Smart Collation
When invoicing is triggered, the system automatically:
- Groups all timesheets and items by client
- Consolidates multiple entries into single invoices per client
- Prevents double-invoicing of the same work
3. Generate Invoices
- Option A (Automatic): At scheduled policy date, system generates invoices from all accumulated timesheets + items
- Option B (Manual): Visit
/invoices/and click "Generate from Timesheets" for specific entries - Result: One professional invoice per client with all their work itemized
4. Email & Payment Tracking
- Invoices emailed to clients via Brevo
- Status marked as "PENDING"
- Record payments as they arrive
- System marks invoice as "PAID"
β±οΈ Timesheet Management
Track billable hours all month, then automatically generate properly collated invoices for all clients.
Features
- Time Entry Logging β Log hours with date, category, and hourly rate as work is completed
- Custom Categories β Create work categories (Development, Meetings, Support, etc.)
- Metadata Tracking β Add custom fields to entries (Attendees, Location, etc.)
- Unbilled Hours Report β View all time entries waiting to be invoiced (sorted by client)
- Smart Bulk Invoicing β Convert multiple timesheet entries into correctly collated invoices per client
- Automatic Grouping β System intelligently groups and consolidates items for each client into single invoices
- Time Report PDF β Generate detailed timesheet reports with metadata
- Audit Trail β Track which timesheets are billed and linked to invoices
Workflow
1. Create Work Categories
- Navigate to
/timesheets/manage-categories/ - Define categories: Development, Meetings, Support, etc.
- Optionally add metadata fields (Attendees, Location, etc.)
2. Log Time Throughout the Month
- Visit
/timesheets/log-time/and start logging as you work - Select client and category
- Enter date, hours, and hourly rate
- Add optional metadata (attendees, notes, etc.)
- Submit β entries accumulate in the system, nothing invoiced yet
- Repeat all month β log different clients, projects, work types
3. View Accumulated Unbilled Hours
- Navigate to
/timesheets/β see all logged time organized by client - Filter by client or date range to review before invoicing
- See total monetary value of unbilled hours per client
- Preview exactly what each client will be invoiced for
4. Generate Invoice from Timesheets (Smart Collation)
- Click "Generate Invoice" for unbilled entries
- System automatically groups timesheets and items by client
- Smart collation: Multiple entries from the same client β single professional invoice
- Client A: Dev time + Meetings + Misc items = ONE invoice
- Client B: Support time + Dev time = ONE invoice
- Each work entry becomes a line item (description, hours, rate, subtotal)
- Invoice ready to send to client
5. Generate Time Report PDF
- From generated invoice:
/invoices/<id>/time-report/ - PDF includes:
- All timesheet entries with descriptions
- Formatted metadata (Attendees, Location, etc.)
- Hours worked, hourly rates, and totals
- Professional formatting for client delivery
- Can be emailed with invoice
API Endpoints
| Endpoint | Method | Purpose |
|---|---|---|
/timesheets/ |
GET | List all timesheet entries (current user) |
/timesheets/log-time/ |
POST | Create new timesheet entry |
/timesheets/<id>/edit/ |
POST | Update existing entry |
/timesheets/<id>/delete/ |
POST | Delete entry |
/timesheets/manage-categories/ |
GET/POST | Manage work categories |
/invoices/<id>/time-report/ |
GET | Generate PDF report |
/timesheets/invoice-bulk/ |
POST | Convert timesheets to invoice |
Database Models
TimesheetEntry
userβ Ownerclientβ Client to billcategoryβ Work typedateβ Date of workhoursβ Hours worked (decimal)hourly_rateβ Rate per houris_billedβ Whether converted to invoiceinvoiceβ Link to generated invoicemetadataβ Custom fields (JSON)
WorkCategory
userβ Ownernameβ Category namemetadata_schemaβ List of custom field names
Example: Track Development Work
Date: 2026-03-02
Client: Acme Corp
Category: Development
Hours: 4.5
Hourly Rate: $75
Metadata: {
"Task": "Build API endpoint",
"Ticket": "#1234"
}
Then later:
# Select this entry + others for same client # Click "Generate Invoice" # Creates invoice line: "2026-03-02: Development - Build API endpoint (4.5 hrs Γ $75)"
Example Reports
- Client Unbilled Hours: How many hours waiting to be billed?
- Timesheet Report: PDF with all hours, rates, and metadata for client
- Category Usage: How many hours in each category this month?
π§ͺ Testing
Run All Tests
# With Docker docker-compose exec web python manage.py test # Locally python manage.py test
Run Specific Tests
# Recurring invoicing tests python manage.py test items.tests.test_recurring_invoicing -v 2 # Invoice data integrity python manage.py test invoices.tests.test_new_data_integrity -v 2
Test Coverage
- 10+ tests for recurring billing
- Invoice creation, emailing, deduplication
- Monthly rollover safety
- Policy scheduling logic
π Key API Endpoints
Invoices
GET /invoices/β List invoicesPOST /invoices/create/β Create invoiceGET /invoices/<id>/β Invoice detailPOST /invoices/<id>/send/β Send invoice
Clients
GET /clients/β List clientsPOST /clients/create/β Create clientGET /clients/<id>/β Client detail
Items
GET /items/β List itemsPOST /items/create/β Create itemGET /items/<id>/β Item detail
Scheduler
GET /scheduler/policies/β List billing policiesPOST /scheduler/policies/create/β Create policy
Timesheets
GET /timesheets/β List timesheet entriesPOST /timesheets/log-time/β Create new entryPOST /timesheets/<id>/edit/β Update entryPOST /timesheets/<id>/delete/β Delete entryGET /timesheets/manage-categories/β Manage work categoriesGET /invoices/<id>/time-report/β Generate timesheet report PDFPOST /timesheets/invoice-bulk/β Convert timesheets to invoice
See MANAGER_METHODS_DOCUMENTATION.md for complete API reference.
βοΈ Configuration
Environment Variables
See .env.example for all available options.
Critical for production:
DEBUG=False SECRET_KEY=generate-new-secure-key ALLOWED_HOSTS=yourdomain.com,www.yourdomain.com DB_PASSWORD=strong-password REDIS_PASSWORD=strong-password BREVO_API_KEY=your-email-api-key GOOGLE_GENAI_API_KEY=your-ai-api-key
Database
- Default: PostgreSQL (recommended)
- Fallback: SQLite (development only)
- Run migrations:
python manage.py migrate
Celery
- Broker: Redis
- Result Backend: Redis
- Beat Scheduler: Celery Beat (with database store)
- Monitoring: Flower (http://localhost:5555)
π³ Docker Services
| Service | Container | Port | Purpose |
|---|---|---|---|
| Django Web | billing_web | 8000 | Main application |
| PostgreSQL | billing_db | 5432 | Database |
| Redis | billing_redis | 6379 | Cache/broker |
| Celery Worker | billing_celery_worker | - | Task processing |
| Celery Beat | billing_celery_beat | - | Scheduling |
| Flower | billing_flower | 5555 | Monitoring |
Common Docker Commands
# View all logs docker-compose logs -f # Restart services docker-compose restart # Stop and remove containers docker-compose down # Remove containers AND volumes (WARNING: deletes data) docker-compose down -v # Run Django command docker-compose exec web python manage.py shell # View database docker-compose exec db psql -U billing_user -d billing_v2_db
π Security
Production Checklist
- Generate new
SECRET_KEY - Set
DEBUG=False - Update
ALLOWED_HOSTS - Use strong
DB_PASSWORDandREDIS_PASSWORD - Set up SSL/TLS with reverse proxy (Nginx)
- Restrict admin panel access
- Enable audit logging
- Set up monitoring & backups
SSL/TLS Setup
See nginx.conf.example for reverse proxy configuration with Let's Encrypt.
π Monitoring
Celery Tasks
Access Flower Dashboard at http://localhost:5555
- Monitor active/completed tasks
- Check worker status
- View task history
Database
# Connect to PostgreSQL docker-compose exec db psql -U billing_user -d billing_v2_db # Check invoice count SELECT COUNT(*) FROM invoices_invoice WHERE status='SENT'; # View recent transactions SELECT * FROM invoices_invoice ORDER BY date_issued DESC LIMIT 10;
Logs
# All services docker-compose logs -f # Specific service docker-compose logs -f web docker-compose logs -f celery_worker docker-compose logs -f celery_beat
π Troubleshooting
Migrations fail
docker-compose exec web python manage.py migrate --noinput
docker-compose restart webCelery tasks not running
# Check if Redis is running docker-compose exec redis redis-cli ping # Check Celery worker logs docker-compose logs celery_worker # Check Celery Beat logs docker-compose logs celery_beat
Static files not loading
docker-compose exec web python manage.py collectstatic --noinput --clear
docker-compose restart webDatabase connection error
# Check PostgreSQL is running docker-compose exec db pg_isready # Verify credentials in .env docker-compose config | grep DB_
See DOCKER_DEPLOYMENT.md for more troubleshooting.
π Performance Optimization
Scaling Celery Workers
docker-compose up -d --scale celery_worker=3
Increasing Gunicorn Workers
Edit docker-compose.yml:
command: gunicorn --bind 0.0.0.0:8000 --workers 8 core_project.wsgi:application
Database Connection Pooling
Configure in settings for production:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'CONN_MAX_AGE': 600, # Connection pooling ... } }
π€ Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Run tests (
python manage.py test) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open a Pull Request
π License
This project is licensed under the MIT License.
π Support
For issues, questions, or suggestions:
- Check existing documentation in the repo
- Review DOCKER_DEPLOYMENT.md for deployment issues
- Check RECONCILIATION_GUIDE.md for data integrity questions
- Open an issue on GitHub
π Deployment
Production Checklist
- Update SECRET_KEY
- Set DEBUG=False
- Use PostgreSQL (not SQLite)
- Use external Redis (not container-based)
- Setup SSL/TLS with Nginx reverse proxy
- Configure email service (Brevo API key)
- Setup backup strategy
- Configure monitoring (Flower, Sentry)
- Load test with production data
- Document runbooks
See DOCKER_DEPLOYMENT.md for detailed production deployment steps.
Built with β€οΈ using Django, Celery, and PostgreSQL
Last Updated: March 2, 2026