FINANCIAL CORE

From the first receipt to the final payment.

Cost tracking and invoicing are the same story told from two ends — what a project actually spent, and what the client actually gets billed and pays. Built as two connected apps so neither one drifts from the other.

PythonDjangoPostgreSQL
BCE / Financial Snapshot — Project ORA-25-014
Logged costsStructural → Rebar & Formwork · 14 entries
EGP 391,500
Invoice INV-2607-0032Status auto-tracked: Partial → Closed as payments land
68% collected
File versionInvoice re-uploaded → every payment & invoice reference re-points automatically
Auto-synced
BUDGET USED — REBAR & FORMWORK87% of EGP 450,000
0%80% warning95% critical
The Result

Every cost carries a verified, versioned paper trail, and every invoice is validated before it can go out wrong — with nothing ever hard-deleted.

The Breakdown

A Cost Without a Receipt

Spending nobody could verify

A Verified Paper Trail

Versioned, hashed, budget-tracked

Nothing Sent Wrong

Invoices validated before they go out

The Problem

Costs needed consistent categories across very different project types, with real supporting evidence that could survive an audit and budgets that warned before they were blown. On the billing side, invoices needed to stay searchable and filterable as volume grew, track partial payments without ever letting a client overpay, and keep every attached file pointed at its latest version — not a stale copy from three edits ago.

What I Built

A hierarchical cost-category tree with versioned, SHA-256-hashed cost files (13 document types) and threshold-based budget alerts, paired with an invoicing system that auto-populates the client from the project, validates every date and amount relationship, and won't let a payment exceed what's owed. Both apps share the same virtual-folder file storage — invoices and payments even get their own auto-created sub-folders — and a signal keeps every file reference in both apps pointed at the latest uploaded version automatically.

Process — Cost Side

Every cost, with a paper trail.

01

Categorize

A hierarchical CostCategory tree tags every cost by discipline — the same structure works whether the project is a bridge or an office fit-out.

02

Log and reconcile

A ProjectCost entry records amount, supplier, and tax detail. If quantity × unit price doesn't match the entered amount, the form either auto-corrects small rounding gaps or rejects it outright — it doesn't just trust whatever number was typed in.

03

Attach proof

Receipts, invoices, and POs attach as versioned, SHA-256-hashed files across 13 recognized document types, optionally requiring approval before they count as verified.

04

Track the budget

A ProjectCostBudget compares allocated against actual spend per category, firing configurable warning (80%) and critical (95%) threshold alerts.

Structural EGP 1,240,000 allocated
Rebar & Formwork 87% used
Steel Framing 42% used
Electrical EGP 380,000 allocated
Wiring & Panels 61% used
Architectural EGP 610,000 allocated
Mechanical EGP 290,000 allocated
Process — Invoice Side

Billing that can't quietly drift.

05

Bill from the project

An invoice auto-populates its client from the selected project, and validates that the due date isn't before the invoice date before it'll save.

06

Record payments safely

Partial payments are tracked individually — the form rejects any payment that would push the total received past the invoice amount, and requires a payment method whenever an initial payment is recorded.

07

Filter and search at scale

A dedicated filter service handles quick filters (draft, overdue, this month), date and amount ranges, and even boolean filters like "has files" or "has payments" — plus full-text search across the invoice number, project, client, and e-invoice reference in one pass.

08

Stay in sync automatically

When someone uploads a new version of an attached file, a signal walks every InvoiceFile and PaymentFile reference pointing at the old version and repoints it at the new one — nobody has to remember to update a link by hand.

Status — auto-computed on save, not set by hand

Draft
Issued
Partial
Closed
↳ Overdue fires automatically if due_date passes before status reaches Closed or Cancelled
Guardrails

Built so mistakes are recoverable, not just preventable.

01

Real-time validation

An AJAX endpoint mirrors the exact same rules as the form itself — required fields, date logic, amount checks — so a user finds out about a problem before they submit, not after.

02

Separated concerns

Export, permissions, validation, audit logging, and cross-app integration each live in their own dedicated mixin — no single view class tries to do all five jobs at once.

03

Nothing is ever truly deleted

Payments, invoice files, and payment files all soft-delete with a restore path — the payment cancel endpoint's own docstring calls it "cancel/archive instead of deleting." A mistake is reversible, not catastrophic.

Outcome
13
COST ATTACHMENT TYPES
RECEIPT TO TAX DOC
6
INVOICE FILTER TYPES
QUICK · DATE · AMOUNT · BOOL
Auto
FILE VERSION SYNC
ACROSS COST & INVOICE
0
HARD DELETES
EVERYTHING IS RESTORABLE
Why it matters

A cost without a receipt is a guess, and an invoice that doesn't match what was actually spent is a problem waiting to surface at the worst time. Keeping both sides validated, versioned, and connected to the same file system means the numbers a CEO sees on a Tuesday are the same numbers an auditor would find eighteen months later.