============================================================
The VeriPath Accounting App is a customised ERPNext v15 installation providing bookkeeping and accounting for healthcare organisations — clinics, dental surgeries, and private practices. The same installation procedure is used for every practice (GP, dental, etc.); the only per-sector difference is the Chart of Accounts content.
healthcare_accounting — invoicing, payments, claims, role mapping, SSOerpnext_web, erpnext_worker, erpnext_scheduler) — shared by all practice sites{practice}.accounts.{sector}.veripath.co.uk, e.g.
test-client.accounts.gp.veripath.co.uktest-client.accounts.dental.veripath.co.ukaccounts.veripath.co.uk — VeriPath's own general accounting site (on-demand project invoicing, not client-VPS related) → VeriPath — Own Accounting FacilityEach site is a full ERPNext install (~700 tables, ~42 MB DB). Non-accounting modules are hidden in the UI afterwards; no tables are dropped. Do not create schema-level "accounts-only" installs — keeping the full schema keeps upgrades and migrations safe.
The accounting app integrates with the Django booking apps (GP Booking App, Dental Booking App) via the healthcare_accounting REST API:
| Feature | Description |
|---|---|
| Invoicing | Appointment invoices auto-created in ERPNext |
| Payments | Stripe/cash payments sync to Payment Entries |
| Claims | Dual-invoice flow (insurer + patient shortfall) |
| SSO | Single sign-on via Keycloak — no separate login |
→ GP integration plan
→ Dental integration plan
Shared Keycloak identity provider:
auth.veripath.co.uk (realm veripath)erpnextrole attribute maps to ERPNext permissions| App Role | ERPNext Role | Accounting Access |
|---|---|---|
ACCOUNTANT |
Accounts Manager | Full (invoices, payments, journals, reports, settings) |
ACCOUNTS_USER |
Accounts User | Limited (invoices, payments, basic reports) |
RECEPTIONIST |
Accounts User | Basic invoicing access |
REGISTERED_MANAGER |
Accounts Manager | Full accounting access |
Both GP and dental use the UK Healthcare Clinic COA template (gb_uk_healthcare_clinic.json, built into the image). Sector-specific accounts are added through the healthcare_accounting patches (add_healthcare_coa) — this is the only part that may differ per sector/practice.
Create the site (run detached — takes ~15–20 min; DB is remote over the tunnel):
bench new-site {practice}.accounts.{sector}.veripath.co.uk \
--db-type postgres --db-name erpnext_{practice} \
--db-host 172.18.0.1 --db-port {tunnel_port} \
--db-root-username postgres --db-root-password '{client_db_superuser_pw}' \
--admin-password '{generated}' \
--install-app erpnext --install-app healthcare_accounting
Watch progress with a detached poller (site dir + SELECT count(*) FROM information_schema.tables on the client DB). A slow install is normal, not a failure.
Known pitfalls (both fixed in the image):
healthcare_accounting must be listed in the bench sites/apps.txt or --install-app fails with "App not in apps.txt".patches.txt must contain a [post_model_sync] section (the [pre_model_sync]-only version crashed bench install-app).site_config.json: after new-site, append keycloak_realm: veripath, keycloak_client_secret (from the Keycloak erpnext client), encryption_key (generated), setup_complete: 1. Restart the web container to load healthcare_accounting patches.
Keycloak: add the explicit per-host redirect URI https://{practice}.accounts.{sector}.veripath.co.uk/* to the erpnext client's redirectUris. *.accounts.…/* wildcards do not match subdomains — the explicit entry is what works.
Bootstrap the Company (UK Healthcare Clinic COA). When created via get_doc rather than the setup wizard, you must also seed: setup fixtures (install_fixtures('United Kingdom')), Fiscal Years, Price Lists (install_defaults), and set the Global Defaults currency to the company currency (a fresh site defaults to INR, which breaks invoicing). Set the company's default income/receivable/cash/bank/payable/expense accounts + cost centers.
API access: generate an API key/secret (Administrator user) for the Django ERPNextConfig; create the Keycloak Social Login Key on the site.
Hide non-accounting modules (optional, cosmetic): block modules globally via the Administrator user's block_modules.
Verify: curl https://{site}/api/method/frappe.ping → 200; smoke-test healthcare_accounting.api.* (create customer → create+submit Sales Invoice → Payment Entry → invoice Paid).
ERPNext's MySQL-first SQL is adapted for PostgreSQL by gunicorn_app.py (/opt/erpnext/gunicorn_app.py, repo patches/gunicorn_app.py). It rewrites:
GROUP BY with bare non-aggregated columns → wrapped in MAX(col) AS col (preserves MySQL grouping semantics)HAVING output-alias refs on ungrouped queries → resolved + converted to WHEREIF(numeric, …) → boolean CASE/WHEN"literal" strings → PostgreSQL 'literal' (backtick-quoted queries only)These patches are required for Sales Invoice submission and Payment Entry flows on PostgreSQL. Full details: → Deployment & Implementation
============================================================