Data Model
Financial recalculation logic, table-level action matrix, and dependent entity handling for Order Split.
Strategy
Order Split uses a shift FK + selective clone model โ rows either travel with the moved tests or get copied independently onto the new bill.
Financial recalculation
All financial fields on the split bill are derived proportionally from the parent bill.
Proportion formula
split_base_amount = ฮฃ (testAmount - testConsc) for each non-profile BillingInfo in selection
original_base_total = parent.billTotalAmount - parent.billAdditionalAmount
+ parent.TDSAmount - parent.vat
split_proportion = split_base_amount / original_base_totalDerived split values
| Field | Formula |
|---|---|
vat | original_vat ร split_proportion |
TDSAmount | original_tds ร split_proportion |
billAdditionalAmount | original_additional ร split_proportion |
billTotalAmount | split_base_amount + split_additional - split_tds + split_vat |
vat_percent | (split_vat / (split_total - split_vat)) ร 100 |
co_pay_amount | ฮฃ co_pay_amount per selected non-profile row |
deductible_amount | ฮฃ deductible_amount per selected non-profile row |
patientPayableAmount | co_pay_amount + deductible_amount |
Parent bill values are reduced by exactly the split-side values (no rounding loss across both bills).
Non-insurance destination source
When new_source is not insurance, the split bill has insurance-specific fields reset to 0:
co_pay_amount = 0deductible_amount = 0patientPayableAmount = 0
The same reset is applied to the moved BillingInfo rows via shift_update_billing_info.
Order number
The split bill's orderNumber is derived from the parent:
parent.orderNumber = "ORD-1234" โ split.orderNumber = "ORD-1234~1"
parent.orderNumber = "ORD-1234~1" โ split.orderNumber = "ORD-1234~2"Table action matrix
| Model / Table | Action | Notes |
|---|---|---|
billing | Create + update parent | Split bill created; parent bill reduced |
billingInfo | Shift FK | Selected rows moved to split bill |
labReportRelation | Shift FK | Moved test report rows updated to split bill |
collectedSample | Conditional create + relink | New sample only when parent and split share one |
billing_icd | Shift + create | Test-level rows shifted; bill-level rows copied |
billing_modifier | Shift + create | Test-level rows shifted; bill-level rows copied |
org_test_count_ledger | Shift FK | Rows for moved tests reassigned to split bill |
payments | Create | Zero-amount CASH row bootstraps split bill |
symptoms_user_bill_relation | Create | Parent rows cloned for split bill |
UserBillInsurance | Create | Split bill gets insurance row when source is insurance |
organizationTransaction | Fusion webhook | Negative-amount ledger entry sent via Fusion; note_entry is true for PREPAID orgs only. Skipped when manageLedger is disabled. |
bill_approval_action | Create | Parent approval row cloned to split bill |
lab_missing_details | Create | Unresolved bill-level rows copied to split bill |
attachments | Copy + soft-delete | Smart reports soft-deleted on parent; eligible attachments copied |
QuestionValue (AOE) | Shift + create | Bill-level AOE cloned; test/profile-level AOE shifted for moved reports |
QuestionValue (consent) | Shift + create | Responses for moved reports shifted; bill/patient-level responses cloned |
LabFormLinkedProcesses | Shift + create | Patient/bill-level processes cloned; test/profile-level processes shifted |
reportValues / LRR doc stores | No change | Preserved via LRR identity continuity |
ReflexTestDetails | No change | Logging table |
Notification | No change | Logging table |
SmartReportGeneration | No change | Logging table |
invoice | No change | Invoiced bills are blocked from split |
formF | No impact | Stays on parent bill |
billTransaction | No impact | Split bill starts with a clean payment history |
onlinePayment | No impact | Deferred table; currently not in use |
LinkedBills | No impact | ABDM-linked bills are blocked before reaching this point |
inventoryTransaction | No impact | Consumption logged at parent billing stage |
DoctorReportRelation | No impact | Records are linked to reports |
LabForm | Create (clone) / Unhandled | Consent forms are cloned for the split bill (revoked forms excluded); AOE config form structures are not migrated (only their QuestionValue responses are moved) |
BillClassifierTags | Unhandled | Presence blocks split; not migrated |
TestClinicalInfo | Unhandled | Presence blocks split; not migrated |
ProcessedFile | Unhandled | Presence blocks split; not migrated |
homeCollection | Unhandled | Presence blocks split |
emrAppointments | Unhandled | Presence blocks split |
InsuranceClaim | Unhandled | Presence blocks split |
BillClaimRelation | Unhandled | Presence blocks split |
Kit | Unhandled | Presence blocks split |
ShippingDetails | Unhandled | Presence blocks split |
privilegeCardLedger | Unhandled | Not migrated; no guard |
prescriptions | Unhandled | Not migrated; no guard |
Dependent entity details
Sample handling
A new CollectedSample is created only when a sample is shared โ i.e. some tests staying on the parent and some moving to the split bill use the same sample row. If all tests on a sample move together, the existing sample row is simply relinked.
New samples reset positional fields: rackNo = 0, xPos = 0, yPos = 0, location = "". A new autoSampleID is generated.
Attachment handling
- Active attachments are fetched for both the bill and moved report IDs.
- Smart report attachments are soft-deleted on the parent (
is_deleted = True). - Remaining allowed attachments are copied: Storage Manager is tried first; S3 direct copy with manual ES indexing is the fallback.
- Copied attachments get new filenames (
{original_name}_{timestamp}.{ext}). - The split bill's
billingAttachmentfield is updated to the last copied URL.
ICD and modifier handling
- Bill-level rows (no
bill_info_id): new rows are created pointing to the split bill. - Test-level rows (have
bill_info_id): rows for movedBillingInfoIDs are shifted via FK update.
AOE and consent handling
LabForm records are split by type:
- Consent
LabFormโ IS migrated. A newLabFormrecord is cloned for the split bill (newlab_form_slugUUID). Only non-revoked forms are processed. - AOE config
LabFormโ NOT migrated. The form config stays on the parent. Only theQuestionValueresponses are moved.
QuestionValue records for moved reports are shifted; bill/patient-level records are cloned. AOE Promotion and Store process types are left on the parent bill.
See Transactions and Sync for the full migration sequence.