From f3676039627d2e3a5f2dd03e7d4a2eea95ef0d28 Mon Sep 17 00:00:00 2001 From: DevSoftTech Server Date: Tue, 6 Oct 2026 16:40:30 +0530 Subject: [PATCH] fix(abdm): unify consult visit into single OPConsultRecord bundle and auto-sync on print --- app/Controllers/AbdmGateway.php | 122 +++++++-------- app/Controllers/Opd.php | 22 +++ app/Controllers/Opd_prescription.php | 144 ++++-------------- .../Abdm/Sync/AbdmTaskBoardSyncService.php | 112 +------------- 4 files changed, 108 insertions(+), 292 deletions(-) diff --git a/app/Controllers/AbdmGateway.php b/app/Controllers/AbdmGateway.php index 8128d54..d12f709 100644 --- a/app/Controllers/AbdmGateway.php +++ b/app/Controllers/AbdmGateway.php @@ -6459,7 +6459,16 @@ class AbdmGateway extends BaseController if ($ccRef === '') { $ccRef = 'HR-' . (int) ($row['id'] ?? 0); } + // Skip redundant/legacy separate PRESC- and WELLNESS- contexts (now unified under OPD-) + if (str_starts_with($ccRef, 'PRESC-') || str_starts_with($ccRef, 'WELLNESS-')) { + continue; + } $hiType = trim((string) ($row['hi_type'] ?? 'HealthDocumentRecord')); + if (str_starts_with($ccRef, 'INVOICE-') || stripos($hiType, 'invoice') !== false) { + $hiType = 'InvoiceRecord'; + } elseif (str_starts_with($ccRef, 'OPD-')) { + $hiType = 'OPConsultRecord'; + } $dateStr = date('d M Y', strtotime((string) ($row['created_at'] ?? $row['updated_at'] ?? 'now'))); $display = $hiType . ' - ' . $dateStr; @@ -6570,7 +6579,6 @@ class AbdmGateway extends BaseController $aliasRef = 'OPD-' . $patientId . '-S' . $opdId . '-' . $cleanDate; $docName = trim((string) ($om['doc_name'] ?? '')); - $display = 'OPConsultRecord - ' . ($docName !== '' ? 'Dr. ' . $docName . ' - ' : '') . $dateStr; // Determine FHIR readiness: check stored doc, health_records, status, or clinical findings $hasStoredDoc = false; @@ -6622,8 +6630,35 @@ class AbdmGateway extends BaseController } } - $isReady = $hasStoredDoc || $hasHr || $isVisitDone || $hasFindings || $hasMeds; + // Check vitals / wellness + $hasVitals = ! empty($pr) && (! empty($pr['bp']) || ! empty($pr['pulse']) || ! empty($pr['temp']) || ! empty($pr['spo2']) || ! empty($pr['weight']) || ! empty($pr['height'])); + // Check scanned or uploaded documents + $hasDocs = false; + if ($this->db->tableExists('file_upload_data')) { + $hasDocs = ($this->db->table('file_upload_data')->where('opd_id', $opdId)->countAllResults() > 0); + } + + // Build unified clinical components label + $components = ['OPD Consult']; + if ($hasVitals) { + $components[] = 'Wellness'; + } + if ($hasMeds) { + $components[] = 'Prescription'; + } + if ($hasDocs) { + $components[] = 'HealthDocument'; + } + $compStr = implode(', ', $components); + $display = $compStr . ' - ' . ($docName !== '' ? 'Dr. ' . $docName . ' - ' : '') . $dateStr; + if (strlen($display) > 85) { + $display = $compStr . ' - ' . $dateStr; + } + + $isReady = $hasStoredDoc || $hasHr || $isVisitDone || $hasFindings || $hasMeds || $hasVitals; + + // Single unified care context covering consult note, wellness, prescription, and documents $addContext([ 'careContextId' => $ccRef, 'referenceNumber' => $ccRef, @@ -6635,37 +6670,6 @@ class AbdmGateway extends BaseController 'is_primary' => false, ]); $seenRefs[$aliasRef] = true; - - // 4b. Prescription Record (if prescribed medicines exist) - if ($hasMeds) { - $prescCcRef = 'PRESC-' . $patientId . '-S' . $sessionId . '-' . $cleanDate; - $prescDisplay = 'Prescription - ' . ($docName !== '' ? 'Dr. ' . $docName . ' - ' : '') . $dateStr; - $addContext([ - 'careContextId' => $prescCcRef, - 'referenceNumber' => $prescCcRef, - 'display' => $prescDisplay, - 'record_type' => 'PrescriptionRecord', - 'patient_id' => $patientId, - 'is_fhir_ready' => true, - 'is_primary' => false, - ]); - } - - // 4c. Wellness Record (if vitals exist) - $hasVitals = ! empty($pr) && (! empty($pr['bp']) || ! empty($pr['pulse']) || ! empty($pr['temp']) || ! empty($pr['spo2']) || ! empty($pr['weight']) || ! empty($pr['height'])); - if ($hasVitals) { - $wellCcRef = 'WELLNESS-' . $sessionId . '-' . $cleanDate; - $wellDisplay = 'Wellness Record - ' . $dateStr; - $addContext([ - 'careContextId' => $wellCcRef, - 'referenceNumber' => $wellCcRef, - 'display' => $wellDisplay, - 'record_type' => 'WellnessRecord', - 'patient_id' => $patientId, - 'is_fhir_ready' => true, - 'is_primary' => false, - ]); - } } } @@ -6688,16 +6692,6 @@ class AbdmGateway extends BaseController || trim((string) ($pr['diagnosis'] ?? '')) !== '' || trim((string) ($pr['Provisional_diagnosis'] ?? '')) !== ''; $ccRef = 'OPD-' . $patientId . '-S' . $sessionId . '-' . $cleanDate; - $display = 'OPConsultRecord - ' . $dateStr; - $addContext([ - 'careContextId' => $ccRef, - 'referenceNumber' => $ccRef, - 'display' => $display, - 'record_type' => 'OPConsultRecord', - 'patient_id' => $patientId, - 'is_fhir_ready' => $hasFindings, - 'is_primary' => false, - ]); // Also check if prescribed medicines exist for orphan $hasMeds = false; @@ -6710,35 +6704,29 @@ class AbdmGateway extends BaseController $hasMeds = ($this->db->table($tblPresc)->where($col, (int) $pr['id'])->countAllResults() > 0); } } - if ($hasMeds) { - $prescCcRef = 'PRESC-' . $patientId . '-S' . $sessionId . '-' . $cleanDate; - $prescDisplay = 'Prescription - ' . $dateStr; - $addContext([ - 'careContextId' => $prescCcRef, - 'referenceNumber' => $prescCcRef, - 'display' => $prescDisplay, - 'record_type' => 'PrescriptionRecord', - 'patient_id' => $patientId, - 'is_fhir_ready' => true, - 'is_primary' => false, - ]); - } // Also check if vitals exist for orphan $hasVitals = ! empty($pr['bp']) || ! empty($pr['pulse']) || ! empty($pr['temp']) || ! empty($pr['spo2']) || ! empty($pr['weight']) || ! empty($pr['height']); + + $components = ['OPD Consult']; if ($hasVitals) { - $wellCcRef = 'WELLNESS-' . $sessionId . '-' . $cleanDate; - $wellDisplay = 'Wellness Record - ' . $dateStr; - $addContext([ - 'careContextId' => $wellCcRef, - 'referenceNumber' => $wellCcRef, - 'display' => $wellDisplay, - 'record_type' => 'WellnessRecord', - 'patient_id' => $patientId, - 'is_fhir_ready' => true, - 'is_primary' => false, - ]); + $components[] = 'Wellness'; } + if ($hasMeds) { + $components[] = 'Prescription'; + } + $compStr = implode(', ', $components); + $display = $compStr . ' - ' . $dateStr; + + $addContext([ + 'careContextId' => $ccRef, + 'referenceNumber' => $ccRef, + 'display' => $display, + 'record_type' => 'OPConsultRecord', + 'patient_id' => $patientId, + 'is_fhir_ready' => $hasFindings || $hasMeds || $hasVitals, + 'is_primary' => false, + ]); } } diff --git a/app/Controllers/Opd.php b/app/Controllers/Opd.php index a50caeb..db34ec3 100644 --- a/app/Controllers/Opd.php +++ b/app/Controllers/Opd.php @@ -2130,6 +2130,17 @@ class Opd extends BaseController return $this->response->setStatusCode(404)->setBody('OPD not found'); } + // Auto create/update FHIR bundle when printing consult form + try { + $resolvedSessionId = $sessionId > 0 ? $sessionId : (int) ($data['opd_prescription']->id ?? 0); + $prescCtrl = new \App\Controllers\Opd_prescription(); + $patientRowArr = ! empty($data['patient_master'][0]) ? (array) $data['patient_master'][0] : null; + $opdRowArr = ! empty($data['opd_master'][0]) ? (array) $data['opd_master'][0] : null; + $prescCtrl->storePrescriptionFhirBundle($opdId, $resolvedSessionId, $patientRowArr, $opdRowArr); + } catch (\Throwable $fhirEx) { + log_message('warning', '[opd_lettre_print] FHIR bundle sync on print warning: ' . $fhirEx->getMessage()); + } + $data['print_layout_mode'] = $layoutMode; return view('billing/opd_letter_head', $data); @@ -2165,6 +2176,17 @@ class Opd extends BaseController return $this->response->setStatusCode(404)->setBody('OPD not found'); } + // Auto create/update FHIR bundle when generating consult form PDF + try { + $resolvedSessionId = $sessionId > 0 ? $sessionId : (int) ($data['opd_prescription']->id ?? 0); + $prescCtrl = new \App\Controllers\Opd_prescription(); + $patientRowArr = ! empty($data['patient_master'][0]) ? (array) $data['patient_master'][0] : null; + $opdRowArr = ! empty($data['opd_master'][0]) ? (array) $data['opd_master'][0] : null; + $prescCtrl->storePrescriptionFhirBundle($opdId, $resolvedSessionId, $patientRowArr, $opdRowArr); + } catch (\Throwable $fhirEx) { + log_message('warning', '[opd_lettre_pdf] FHIR bundle sync on PDF print warning: ' . $fhirEx->getMessage()); + } + $data['print_layout_mode'] = $layoutMode; $isComposedTemplate = $templateKey !== '' && str_starts_with($templateKey, 'compose_'); diff --git a/app/Controllers/Opd_prescription.php b/app/Controllers/Opd_prescription.php index 7172af3..525bb25 100644 --- a/app/Controllers/Opd_prescription.php +++ b/app/Controllers/Opd_prescription.php @@ -11799,12 +11799,27 @@ class Opd_prescription extends BaseController * @param array $opdRow * @param int $sessionId */ - private function storePrescriptionFhirBundle(int $opdId, int $sessionId, array $patientRow, array $opdRow): bool + public function storePrescriptionFhirBundle(int $opdId, int $sessionId = 0, ?array $patientRow = null, ?array $opdRow = null): bool { + if ($this->db === null) { + $this->db = \Config\Database::connect(); + } if (! $this->db->tableExists('opd_fhir_documents')) { return false; } + if (empty($opdRow) && $this->db->tableExists('opd_master')) { + $opdRow = $this->db->table('opd_master')->where('opd_id', $opdId)->get(1)->getRowArray() ?? []; + } + + if (empty($patientRow) && ! empty($opdRow['p_id']) && $this->db->tableExists('patient_master')) { + $patientRow = $this->db->table('patient_master')->where('id', (int) $opdRow['p_id'])->get(1)->getRowArray() ?? []; + } + + if (empty($opdRow) || empty($patientRow)) { + return false; + } + if ($sessionId <= 0 && $this->db->tableExists('opd_prescription')) { $presRow = $this->db->table('opd_prescription')->select('id')->where('opd_id', $opdId)->orderBy('id', 'DESC')->get(1)->getRowArray(); if (! empty($presRow['id'])) { @@ -11853,13 +11868,6 @@ class Opd_prescription extends BaseController 'period_end' => Time::now('Asia/Kolkata')->toDateTimeString(), ]; - if ($sessionId <= 0 && $this->db->tableExists('opd_prescription')) { - $presRow = $this->db->table('opd_prescription')->select('id')->where('opd_id', $opdId)->orderBy('id', 'DESC')->get(1)->getRowArray(); - if (! empty($presRow['id'])) { - $sessionId = (int) $presRow['id']; - } - } - $medications = $this->getPrescriptionMedicines($sessionId); $conditions = $this->getPrescriptionConditions($sessionId); $clinicalContext = $this->getPrescriptionClinicalContext($sessionId, $opdRow); @@ -11869,7 +11877,9 @@ class Opd_prescription extends BaseController if ($prescriptionPdf !== null) { $clinicalContext['attachments'][] = $prescriptionPdf; } - $bundle = $this->fhirR4Builder->buildOpConsultBundle($patient, $encounter, $medications, $conditions, $clinicalContext); + + $builder = $this->fhirR4Builder ?? new \App\Libraries\FhirR4Builder(); + $bundle = $builder->buildOpConsultBundle($patient, $encounter, $medications, $conditions, $clinicalContext); $bundleJson = (string) json_encode($bundle, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); $userId = null; @@ -11913,45 +11923,6 @@ class Opd_prescription extends BaseController ]); } - // Also generate and store PrescriptionRecord FHIR bundle if medicines were prescribed - $prescBundleJson = null; - if (! empty($medications)) { - $prescContext = $clinicalContext; - $prescContext['bundle_type'] = 'PrescriptionRecord'; - $prescBundle = $this->fhirR4Builder->buildOpConsultBundle($patient, $encounter, $medications, $conditions, $prescContext); - $prescBundleJson = (string) json_encode($prescBundle, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); - - $existingPrescDoc = $this->db->table('opd_fhir_documents') - ->where('opd_id', $opdId) - ->where('opd_session_id', $sessionId) - ->where('bundle_type', 'PrescriptionRecord') - ->orderBy('id', 'DESC') - ->get(1) - ->getRowArray(); - - if (! empty($existingPrescDoc['id'])) { - $this->db->table('opd_fhir_documents') - ->where('id', (int) $existingPrescDoc['id']) - ->update([ - 'bundle_json' => $prescBundleJson, - 'generated_by' => $generatedBy, - 'generated_at' => $now, - 'updated_at' => $now, - ]); - } else { - $this->db->table('opd_fhir_documents')->insert([ - 'opd_id' => $opdId, - 'opd_session_id' => $sessionId, - 'bundle_type' => 'PrescriptionRecord', - 'bundle_json' => $prescBundleJson, - 'generated_by' => $generatedBy, - 'generated_at' => $now, - 'created_at' => $now, - 'updated_at' => $now, - ]); - } - } - if (! $inserted) { return false; } @@ -11964,7 +11935,7 @@ class Opd_prescription extends BaseController $cleanDate = str_replace('-', '', $visitDate); $careContextRef = 'OPD-' . $patientId . '-S' . $sessionId . '-' . $cleanDate; - // 1. Upsert OPConsultRecord + // 1. Upsert single unified OPConsultRecord (covers Consult, Rx, Vitals, and Attachments) $existingHr = $this->db->table('health_records') ->select('id') ->where('care_context_reference', $careContextRef) @@ -11990,73 +11961,14 @@ class Opd_prescription extends BaseController $this->db->table('health_records')->insert($hrPayload); } - // 2. Upsert PrescriptionRecord (if medications exist) - if (! empty($medications) && ! empty($prescBundleJson)) { - $prescCcRef = 'PRESC-' . $patientId . '-S' . $sessionId . '-' . $cleanDate; - $existingPrescHr = $this->db->table('health_records') - ->select('id') - ->where('care_context_reference', $prescCcRef) - ->get(1) - ->getRowArray(); - $prescHrPayload = [ - 'patient_id' => $patientId > 0 ? $patientId : null, - 'abha_id' => $abhaAddress !== '' ? $abhaAddress : null, - 'hi_type' => 'PrescriptionRecord', - 'entity_type' => 'opd_prescription', - 'entity_id' => (string) $sessionId, - 'record_data' => $prescBundleJson, - 'care_context_reference' => $prescCcRef, - 'push_status' => 'local_discovery_ready', - 'updated_at' => Time::now('Asia/Kolkata')->toDateTimeString(), - ]; - if (! empty($existingPrescHr)) { - $this->db->table('health_records')->where('id', (int) $existingPrescHr['id'])->update($prescHrPayload); - } else { - $prescHrPayload['created_at'] = Time::now('Asia/Kolkata')->toDateTimeString(); - $this->db->table('health_records')->insert($prescHrPayload); - } - } - - // 3. Upsert WellnessRecord (if vitals exist) - $hasVitals = ! empty($clinicalContext['observations']); - if ($hasVitals && class_exists('\App\Controllers\DoctorDocument')) { - try { - $docCtrl = new \App\Controllers\DoctorDocument(); - $wSource = $docCtrl->buildWellnessRecordSource($patientId, $sessionId); - if (! empty($wSource) && ! empty($wSource['vitals'])) { - $wFactory = new \App\Libraries\Abdm\Fhir\FhirGeneratorFactory(); - $wGen = $wFactory->wellness()->generate($wSource); - if (! empty($wGen['bundle'])) { - $wellBundleJson = json_encode($wGen['bundle'], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); - $wellCcRef = 'WELLNESS-' . $sessionId . '-' . $cleanDate; - $existingWellHr = $this->db->table('health_records') - ->select('id') - ->where('care_context_reference', $wellCcRef) - ->get(1) - ->getRowArray(); - $wellHrPayload = [ - 'patient_id' => $patientId > 0 ? $patientId : null, - 'abha_id' => $abhaAddress !== '' ? $abhaAddress : null, - 'hi_type' => 'WellnessRecord', - 'entity_type' => 'opd_vitals', - 'entity_id' => (string) $sessionId, - 'record_data' => $wellBundleJson, - 'care_context_reference' => $wellCcRef, - 'push_status' => 'local_discovery_ready', - 'updated_at' => Time::now('Asia/Kolkata')->toDateTimeString(), - ]; - if (! empty($existingWellHr)) { - $this->db->table('health_records')->where('id', (int) $existingWellHr['id'])->update($wellHrPayload); - } else { - $wellHrPayload['created_at'] = Time::now('Asia/Kolkata')->toDateTimeString(); - $this->db->table('health_records')->insert($wellHrPayload); - } - } - } - } catch (\Throwable $we) { - log_message('warning', '[storePrescriptionFhirBundle] auto wellness error: ' . $we->getMessage()); - } - } + // Delete redundant standalone PRESC / WELLNESS records so only the single unified bundle is kept + $redundantRefs = [ + 'PRESC-' . $patientId . '-S' . $sessionId . '-' . $cleanDate, + 'WELLNESS-' . $sessionId . '-' . $cleanDate, + ]; + $this->db->table('health_records') + ->whereIn('care_context_reference', $redundantRefs) + ->delete(); } catch (\Throwable $e) { log_message('warning', '[storePrescriptionFhirBundle] auto health_records insert error: ' . $e->getMessage()); } diff --git a/app/Libraries/Abdm/Sync/AbdmTaskBoardSyncService.php b/app/Libraries/Abdm/Sync/AbdmTaskBoardSyncService.php index 568b1ad..2c02542 100644 --- a/app/Libraries/Abdm/Sync/AbdmTaskBoardSyncService.php +++ b/app/Libraries/Abdm/Sync/AbdmTaskBoardSyncService.php @@ -568,115 +568,9 @@ class AbdmTaskBoardSyncService } } - // 5b. If medications exist and we linked OPConsultRecord, also link PrescriptionRecord care context to bridge - $sessionId = (int) ($docRow['opd_session_id'] ?? 0); - if ($isSuccess && $sessionId > 0) { - $hasMeds = false; - $tblPresc = $this->db->tableExists('opd_prescrption_prescribed') ? 'opd_prescrption_prescribed' : ($this->db->tableExists('opd_prescription_prescribed') ? 'opd_prescription_prescribed' : null); - if ($tblPresc !== null) { - $col = $this->db->fieldExists('opd_pre_id', $tblPresc) ? 'opd_pre_id' : ($this->db->fieldExists('prescription_id', $tblPresc) ? 'prescription_id' : null); - if ($col !== null) { - $hasMeds = ($this->db->table($tblPresc)->where($col, $sessionId)->countAllResults() > 0); - } - } - if ($hasMeds) { - $cleanDate = str_replace('-', '', $visitDate); - $prescCcRef = 'PRESC-' . $patientId . '-S' . $sessionId . '-' . $cleanDate; - $prescDisplay = 'Prescription - ' . $visitDate; - try { - $opdCtrl = new \App\Controllers\Opd_prescription(); - $opdCtrl->initController(\Config\Services::request(), \Config\Services::response(), service('logger')); - $prescRegen = $opdCtrl->regenerateFhirBundleInternal($opdId, $sessionId, 'PrescriptionRecord'); - $prescBundleJson = ! empty($prescRegen['bundle']) ? json_encode($prescRegen['bundle'], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) : null; - - $prescPushData = [ - 'patient_id' => (string) $patientId, - 'patient_name' => $patientName !== '' ? $patientName : ('PATIENT-' . $patientId), - 'abha_id' => $abhaNumber, - 'abha_address' => $abhaAddress, - 'year_of_birth' => $yearOfBirth, - 'gender' => $gender, - 'hi_type' => 'PrescriptionRecord', - 'record_type' => 'PrescriptionRecord', - 'visit_date' => $visitDate, - 'care_context_reference' => $prescCcRef, - 'care_context_display' => $prescDisplay, - 'notes' => $prescDisplay, - 'queue_id' => $prescCcRef, - ]; - if (! empty($prescRegen['bundle'])) { - $prescPushData['bundle'] = $prescRegen['bundle']; - $prescPushData['fhir_bundle'] = $prescRegen['bundle']; - } - $prescRes = $this->connector->pushRecord($prescPushData); - $this->recordLinkedState( - $patientId, - $effectiveAbha, - 'PrescriptionRecord', - 'opd_prescription', - (string) $sessionId, - $prescCcRef, - (string) ($prescRes['queue_id'] ?? $prescCcRef), - (int) ($prescRes['record_id'] ?? 0), - $prescBundleJson - ); - } catch (\Throwable $pe) { - log_message('warning', '[linkAndPushOpdRecord] Prescription care context push error: ' . $pe->getMessage()); - } - } - - // 5c. If vitals exist, also link WellnessRecord care context to bridge - try { - $pRow = $this->db->table('opd_prescription')->where('id', $sessionId)->get(1)->getRowArray(); - $hasVitals = ! empty($pRow['bp']) || ! empty($pRow['pulse']) || ! empty($pRow['temp']) || ! empty($pRow['spo2']) || ! empty($pRow['weight']); - if ($hasVitals && class_exists('\App\Controllers\DoctorDocument')) { - $cleanDate = str_replace('-', '', $visitDate); - $wellCcRef = 'WELLNESS-' . $sessionId . '-' . $cleanDate; - $docCtrl = new \App\Controllers\DoctorDocument(); - $wSource = $docCtrl->buildWellnessRecordSource($patientId, $sessionId); - if (! empty($wSource) && ! empty($wSource['vitals'])) { - $wFactory = new \App\Libraries\Abdm\Fhir\FhirGeneratorFactory(); - $wGen = $wFactory->wellness()->generate($wSource); - $wellBundleJson = ! empty($wGen['bundle']) ? json_encode($wGen['bundle'], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) : null; - $wellDisplay = 'Wellness Record - ' . $visitDate; - - $wellPushData = [ - 'patient_id' => (string) $patientId, - 'patient_name' => $patientName !== '' ? $patientName : ('PATIENT-' . $patientId), - 'abha_id' => $abhaNumber, - 'abha_address' => $abhaAddress, - 'year_of_birth' => $yearOfBirth, - 'gender' => $gender, - 'hi_type' => 'WellnessRecord', - 'record_type' => 'WellnessRecord', - 'visit_date' => $visitDate, - 'care_context_reference' => $wellCcRef, - 'care_context_display' => $wellDisplay, - 'notes' => $wellDisplay, - 'queue_id' => $wellCcRef, - ]; - if (! empty($wGen['bundle'])) { - $wellPushData['bundle'] = $wGen['bundle']; - $wellPushData['fhir_bundle'] = $wGen['bundle']; - } - $wellRes = $this->connector->pushRecord($wellPushData); - $this->recordLinkedState( - $patientId, - $effectiveAbha, - 'WellnessRecord', - 'opd_vitals', - (string) $sessionId, - $wellCcRef, - (string) ($wellRes['queue_id'] ?? $wellCcRef), - (int) ($wellRes['record_id'] ?? 0), - $wellBundleJson - ); - } - } - } catch (\Throwable $we) { - log_message('warning', '[linkAndPushOpdRecord] Wellness care context push error: ' . $we->getMessage()); - } - } + // In ABDM standard, OPConsultRecord is a single unified bundle that already includes + // consultation note, physical examination (wellness/vitals), prescriptions (medications), + // and attached health documents. We intentionally do NOT create duplicate care contexts. if ($isSuccess) { return [