Overview
Backend architecture, split API behavior, transactional data movement, and system integrations for Order Split.
Architecture overview
The backend is split into two layers.
View layer (BillSplitView) handles HTTP concerns only: payload parsing, session validation, mode routing (is_validate, is_calculate, execute), and response serialization. It delegates all logic to the manager.
Manager layer (BillSplitManager) owns everything else: eligibility checks, financial calculations, the atomic transaction, and all post-commit side effects. The manager uses __getattribute__ to guard against calling business methods when validation failures exist, preventing partial operations on an invalid state.
Core responsibilities
| Layer | Responsibility |
|---|---|
BillSplitView | Parse request, route by mode flag, serialize response |
BillSplitManager.__init__ | Bill and test eligibility checks (runs for all modes) |
BillSplitManager.get_bill_calculations | Proportional financial computation in memory |
BillSplitManager.validate_split | Guard-table, advance, attachment, and residual-test checks |
BillSplitManager.do_split | Atomic transaction โ all DB writes |
BillSplitManager (post-commit) | ES sync, Redis invalidation, ledger webhook, activity logs |
Transactional data movement
All DB writes execute inside transaction.atomic(). If any step fails, the full transaction rolls back โ no partial split state is possible.
Execution order:
- Save split bill
- Save updated parent bill
- Create zero-amount CASH payment bootstrap
- Create new
CollectedSamplewhere parent and split would share a sample - Shift
LabReportRelationrows to split bill (and remap sample references) - Shift
BillingInforows to split bill - Clone
BillApprovalActionto split bill - Migrate AOE and patient consent records (
QuestionValue,LabForm,LabFormLinkedProcesses) - Clone unresolved
LabMissingDetailsrows - Shift/clone
BillingICDrows - Copy/shift/soft-delete
Attachments - Shift
OrgTestCountLedgerrows - Shift/clone
BillingModifierrows - Clone
SymptomsUserBillRelationrows
Post-transaction updates
Run after the transaction commits. A failure here does not roll back the split.
| Update | Detail |
|---|---|
| Elasticsearch | Bulk re-index moved LabReportRelation docs in patient_reports using labReportId as key |
| Pusher | Broadcast patient_reports and getLatestSamples events for live UI refresh |
| Redis | Delete finance graph, collection graph, and sample batch cache keys |
| Ledger | POST Fusion webhook to /manageLedgerBalance/ (only when org has manageLedger enabled) |
| Activity log | Write two ActivityLog entries โ one for the split bill, one for the parent bill |