fix(abdm): unify consult visit into single OPConsultRecord bundle and auto-sync on print
This commit is contained in:
parent
d46f222fa3
commit
f367603962
|
|
@ -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,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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_');
|
||||
|
|
|
|||
|
|
@ -11799,12 +11799,27 @@ class Opd_prescription extends BaseController
|
|||
* @param array<string, mixed> $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());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 [
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user