Product EngineeringFeaturesOrder SplitBackend

Transactions and Sync

Atomic split sequence, Elasticsearch synchronization, Redis status, and post-transaction audit behavior.

šŸ‘¤ Sachin SharmašŸ“… Updated: May 2, 2026šŸ·ļø featurešŸ·ļø backendšŸ·ļø transactionšŸ·ļø elasticsearchšŸ·ļø redisšŸ·ļø activity-log

Transaction behavior

All DB writes for the split run inside transaction.atomic(). If any step fails, the full transaction rolls back and no partial split state remains.


A) Pre-transaction calculations

Before entering the transaction, the backend prepares in-memory objects:

  • Compute split-side financials (get_bill_calculations()).
  • Update parent bill values by subtracting split values (update_original_bill(...)).
  • Prepare split bill object (get_split_bill(new_source, calculations)):
    • generate new labBillId
    • set default and computed billing attributes
    • apply insurance-field reset when destination source is non-insurance
    • set orderNumber by appending ~{step} to the parent bill's order number

B) In-transaction operations (execution order)

  1. Persist split bill (split_bill.save()).
  2. Persist updated parent bill (original_bill.save()).
  3. Create zero-amount payment bootstrap (create_payment(split_bill)).
  4. Create conditional sample clones (create_collected_sample()).
  5. Shift report relations and sample mapping (shift_lab_reports(...)).
  6. Shift selected billing lines (shift_update_billing_info(...)).
  7. Copy bill approval row if present (create_bill_approval(...)).
  8. Migrate AOE responses and patient consents (create_shift_consents(...)).
  9. Copy unresolved missing-details rows if present (create_missing_details(...)).
  10. Shift and copy ICD rows (shift_create_billing_icd(...)).
  11. Process attachments (create_shift_attachments(...)).
  12. Shift org test count ledger rows (shift_org_test_count_ledger(...)).
  13. Shift and copy billing modifiers (shift_create_billing_modifiers(...)).
  14. Clone symptoms relation rows (create_symptoms_user_bill_relation(...)).

create_shift_consents handles two form types: AOE and patient consent.

AOE (create_shift_aoe)

  • Bill-level AOE — cloned to the split bill. A new QuestionValue row is created with the split bill as the owner.
  • Test/Profile-level AOE — shifted to the split bill. The existing QuestionValue row is updated to reference the split bill if the linked labReportId is in the set of moved reports.
  • Promotion/Store-level AOE — not handled; left on the parent bill.
  • A new LabForm record is created for the split bill (cloned from the parent, with a new lab_form_slug UUID). Revoked forms are excluded.
  • Patient/Bill-level LabFormLinkedProcesses — cloned and linked to the new LabForm.
  • Test/Profile-level LabFormLinkedProcesses — shifted to the new LabForm when the linked process_id maps to one of the moved tests.
  • QuestionValue responses for moved reports — shifted (FK update) to reference the split bill.
  • QuestionValue responses for non-moved (patient/bill-level) — cloned to the split bill.

Post-transaction updates

These run after a successful commit. A failure here does not roll back the split.

Elasticsearch synchronization

  • Re-index moved LabReportRelation documents in patient_reports.
  • Bulk update uses labReportId as the document key, preserving report identity while updating bill context.
  • After ES sync, each report broadcasts a patient_reports event via Pusher.
  • A getLatestSamples Pusher event is sent per moved sample for live UI refresh.

Redis cache invalidation

Billing-level keys (always):

  • FINANCE_GRAPH_{lab_id}
  • bill_companies_{lab_id}
  • billing_services_{lab_id}
  • COLLECTION_GRAPH_{lab_id}
  • FINANCE_EXCEPTIONS_{lab_id}

Batch/sample-level keys (when new samples were created):

  • centreBatch_{batch_id}
  • centreBatch_{batch_id}_Pending

Organization ledger update

A Fusion webhook is sent to /manageLedgerBalance/ with a negative-amount entry for the split bill:

  • amount = -split_bill.billTotalAmount
  • note_entry = true for PREPAID organisations; false for POSTPAID
  • Payload includes lab, org, bill, amount, actor context, and a comment identifying the originating parent bill
  • Only executed when organization.manageLedger is enabled

Activity and audit logging

  • Write ActivityLog with log_context = BILL_SPLIT and billing category for the split bill (category id 3).
  • Write a second ActivityLog for the parent bill (category id 17) recording the update caused by the split.
  • Log payload includes bill-level diff data, original and split bill IDs and labBillIds, and moved BillingInfo IDs.

On this page