fix(abdm): auto-link ABHA address on discovery/confirm, resolve FHIR by patient_id on-demand, and display in profile
This commit is contained in:
parent
2f6b346e25
commit
24089f36a6
|
|
@ -148,12 +148,35 @@ class AbdmGateway extends BaseController
|
|||
if ($match !== null) {
|
||||
$patient = $match['patient'];
|
||||
$patientId = (int) $patient['id'];
|
||||
$patientRef = (string) ($patient['p_code'] ?: ('P-' . $patientId));
|
||||
$patientDisplay = trim((string) ($patient['p_fname'] ?? ''));
|
||||
if ($patientDisplay === '') {
|
||||
$patientDisplay = 'Patient ' . $patientRef;
|
||||
}
|
||||
$matchedBy = $match['matchedBy'];
|
||||
|
||||
// Save discovered ABHA address/ID to patient_master if not already present
|
||||
$discoveredAbha = trim((string) (
|
||||
$payload['patient']['id']
|
||||
?? $payload['patient']['abhaAddress']
|
||||
?? $payload['patient']['abha_address']
|
||||
?? $payload['abha_address']
|
||||
?? $payload['abhaAddress']
|
||||
?? $payload['abha_id']
|
||||
?? ''
|
||||
));
|
||||
if ($discoveredAbha !== '' && $this->db->tableExists('patient_master')) {
|
||||
$pmUpdate = [];
|
||||
if (str_contains($discoveredAbha, '@') && empty($patient['abha_address'])) {
|
||||
$pmUpdate['abha_address'] = $discoveredAbha;
|
||||
} elseif (strlen(preg_replace('/\D/', '', $discoveredAbha)) === 14 && empty($patient['abha_id'])) {
|
||||
$pmUpdate['abha_id'] = $discoveredAbha;
|
||||
}
|
||||
if (! empty($pmUpdate)) {
|
||||
$this->db->table('patient_master')->where('id', $patientId)->update($pmUpdate);
|
||||
}
|
||||
}
|
||||
|
||||
[$careContextsV3, $careContextsFull] = $this->findCareContextsForPatient($patientId, $patientRef, $patientDisplay);
|
||||
|
||||
$this->getAuditService()->log([
|
||||
|
|
@ -412,6 +435,63 @@ class AbdmGateway extends BaseController
|
|||
$resolvedRefs[$ccRef] = true;
|
||||
}
|
||||
|
||||
// On-Demand Resolution: Connect FHIR records by patient_id & session_id
|
||||
if (! empty($requestedRefs)) {
|
||||
foreach ($requestedRefs as $ref) {
|
||||
if (isset($resolvedRefs[$ref])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$targetPatientId = 0;
|
||||
$targetSessionId = 0;
|
||||
if (preg_match('/(?:OPD|PRESCRIPTION)-(\d+)(?:-S(\d+))?/i', $ref, $m)) {
|
||||
$targetPatientId = (int) $m[1];
|
||||
$targetSessionId = (int) ($m[2] ?? 0);
|
||||
}
|
||||
|
||||
$bundleData = null;
|
||||
if ($this->db->tableExists('opd_fhir_documents')) {
|
||||
$docBuilder = $this->db->table('opd_fhir_documents');
|
||||
if ($targetSessionId > 0) {
|
||||
$docBuilder->where('opd_session_id', $targetSessionId);
|
||||
} elseif ($targetPatientId > 0) {
|
||||
$docBuilder->where('opd_id', $targetPatientId);
|
||||
}
|
||||
$docRow = $docBuilder->orderBy('id', 'DESC')->get(1)->getRowArray();
|
||||
if (! empty($docRow['bundle_json'])) {
|
||||
$bundleData = json_decode((string) $docRow['bundle_json'], true);
|
||||
}
|
||||
}
|
||||
|
||||
if (! is_array($bundleData)) {
|
||||
$bundleData = $this->assembleFhirBundleForCareContext($ref);
|
||||
}
|
||||
|
||||
if (is_array($bundleData)) {
|
||||
$resolvedRefs[$ref] = true;
|
||||
$entries[] = [
|
||||
'careContextReference' => $ref,
|
||||
'media' => 'application/fhir+json',
|
||||
'fhir' => $bundleData,
|
||||
];
|
||||
|
||||
if ($this->db->tableExists('health_records')) {
|
||||
$this->storeHealthRecord([
|
||||
'patient_id' => $targetPatientId > 0 ? $targetPatientId : null,
|
||||
'abha_id' => $abhaLookup,
|
||||
'hi_type' => 'OPConsultRecord',
|
||||
'entity_type' => 'opd',
|
||||
'entity_id' => (string) ($targetSessionId > 0 ? $targetSessionId : $targetPatientId),
|
||||
'fhir_bundle' => json_encode($bundleData, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
|
||||
'care_context_reference' => $ref,
|
||||
'push_status' => 'linked',
|
||||
'reuse_existing' => true,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->confirmFetchedHealthRecordsLinked($deliveredHealthRows, $abhaLookup, $requestId, $payload);
|
||||
|
||||
$this->getAuditService()->log([
|
||||
|
|
@ -4634,6 +4714,28 @@ class AbdmGateway extends BaseController
|
|||
}
|
||||
$matchedBy = $match['matchedBy'];
|
||||
|
||||
// Save discovered ABHA address/ID to patient_master if not already present
|
||||
$discoveredAbha = trim((string) (
|
||||
$payload['patient']['id']
|
||||
?? $payload['patient']['abhaAddress']
|
||||
?? $payload['patient']['abha_address']
|
||||
?? $payload['abha_address']
|
||||
?? $payload['abhaAddress']
|
||||
?? $payload['abha_id']
|
||||
?? ''
|
||||
));
|
||||
if ($discoveredAbha !== '' && $this->db->tableExists('patient_master')) {
|
||||
$pmUpdate = [];
|
||||
if (str_contains($discoveredAbha, '@') && empty($patient['abha_address'])) {
|
||||
$pmUpdate['abha_address'] = $discoveredAbha;
|
||||
} elseif (strlen(preg_replace('/\D/', '', $discoveredAbha)) === 14 && empty($patient['abha_id'])) {
|
||||
$pmUpdate['abha_id'] = $discoveredAbha;
|
||||
}
|
||||
if (! empty($pmUpdate)) {
|
||||
$this->db->table('patient_master')->where('id', $patientId)->update($pmUpdate);
|
||||
}
|
||||
}
|
||||
|
||||
[$careContextsV3, $careContextsFull] = $this->findCareContextsForPatient($patientId, $patientRef, $patientDisplay);
|
||||
|
||||
$this->getAuditService()->log([
|
||||
|
|
@ -4809,6 +4911,35 @@ class AbdmGateway extends BaseController
|
|||
}
|
||||
}
|
||||
|
||||
// Strategy A.2: Check if opd_fhir_documents has stored FHIR bundle
|
||||
if ($db->tableExists('opd_fhir_documents')) {
|
||||
$targetPatientId = 0;
|
||||
$targetSessionId = 0;
|
||||
if (preg_match('/(?:OPD|PRESCRIPTION)-(\d+)(?:-S(\d+))?/i', $ref, $m)) {
|
||||
$targetPatientId = (int) $m[1];
|
||||
$targetSessionId = (int) ($m[2] ?? 0);
|
||||
}
|
||||
$docBuilder = $db->table('opd_fhir_documents');
|
||||
if ($targetSessionId > 0) {
|
||||
$docBuilder->where('opd_session_id', $targetSessionId);
|
||||
} elseif ($targetPatientId > 0) {
|
||||
$docBuilder->where('opd_id', $targetPatientId);
|
||||
}
|
||||
$docRow = $docBuilder->orderBy('id', 'DESC')->get(1)->getRowArray();
|
||||
if (! empty($docRow['bundle_json'])) {
|
||||
$bundleData = json_decode((string) $docRow['bundle_json'], true);
|
||||
if (is_array($bundleData)) {
|
||||
$records[] = [
|
||||
'careContextReference' => $ref,
|
||||
'hiType' => 'PrescriptionRecord',
|
||||
'display' => 'Prescription - ' . date('d M Y', strtotime($docRow['generated_at'] ?? 'now')),
|
||||
'bundle' => $bundleData,
|
||||
];
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Strategy B: Build compliant FHIR Document Bundle from patient_master & OPD
|
||||
$bundle = $this->assembleFhirBundleForCareContext($ref);
|
||||
if ($bundle !== null) {
|
||||
|
|
@ -5054,6 +5185,34 @@ class AbdmGateway extends BaseController
|
|||
}
|
||||
|
||||
$patientId = (int) $patient['id'];
|
||||
if ($abhaAddress === '') {
|
||||
$abhaAddress = trim((string) (
|
||||
$patient['abha_address']
|
||||
?? $patient['abha_id']
|
||||
?? $patient['abha']
|
||||
?? ''
|
||||
));
|
||||
}
|
||||
if ($abhaAddress === '' && ! empty($payload['patient']['unverifiedIdentifiers']) && is_array($payload['patient']['unverifiedIdentifiers'])) {
|
||||
foreach ($payload['patient']['unverifiedIdentifiers'] as $ui) {
|
||||
$type = strtoupper(trim((string) ($ui['type'] ?? '')));
|
||||
$val = trim((string) ($ui['value'] ?? ''));
|
||||
if (in_array($type, ['HEALTH_ID', 'ABHA_ADDRESS', 'ABHA_NUMBER', 'ABHA'], true) && $val !== '') {
|
||||
$abhaAddress = $val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($abhaAddress === '' && ! empty($payload['patient']['verifiedIdentifiers']) && is_array($payload['patient']['verifiedIdentifiers'])) {
|
||||
foreach ($payload['patient']['verifiedIdentifiers'] as $vi) {
|
||||
$type = strtoupper(trim((string) ($vi['type'] ?? '')));
|
||||
$val = trim((string) ($vi['value'] ?? ''));
|
||||
if (in_array($type, ['HEALTH_ID', 'ABHA_ADDRESS', 'ABHA_NUMBER', 'ABHA'], true) && $val !== '') {
|
||||
$abhaAddress = $val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$rawPhone = trim((string) ($patient['mphone1'] ?? $patient['mphone2'] ?? ''));
|
||||
$cleanPhone = substr(preg_replace('/\D/', '', $rawPhone), -10);
|
||||
if (strlen($cleanPhone) !== 10) {
|
||||
|
|
@ -5228,6 +5387,10 @@ class AbdmGateway extends BaseController
|
|||
|
||||
$patientId = (int) $txn['patient_id'];
|
||||
$abhaAddress = trim((string) ($txn['abha_address'] ?? ''));
|
||||
if ($abhaAddress === '') {
|
||||
$patientRow = $this->loadPatientRow($patientId);
|
||||
$abhaAddress = trim((string) ($patientRow['abha_address'] ?? $patientRow['abha_id'] ?? ''));
|
||||
}
|
||||
$now = date('Y-m-d H:i:s');
|
||||
|
||||
$this->db->transStart();
|
||||
|
|
@ -5238,7 +5401,16 @@ class AbdmGateway extends BaseController
|
|||
'abdm_linked_at' => $now,
|
||||
];
|
||||
if ($abhaAddress !== '') {
|
||||
$pmUpdate['abha_address'] = $abhaAddress;
|
||||
if (str_contains($abhaAddress, '@')) {
|
||||
$pmUpdate['abha_address'] = $abhaAddress;
|
||||
} else {
|
||||
$digits = preg_replace('/\D/', '', $abhaAddress);
|
||||
if (strlen($digits) === 14) {
|
||||
$pmUpdate['abha_id'] = $abhaAddress;
|
||||
} else {
|
||||
$pmUpdate['abha_address'] = $abhaAddress;
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->db->table('patient_master')->where('id', $patientId)->update($pmUpdate);
|
||||
}
|
||||
|
|
@ -5280,6 +5452,9 @@ class AbdmGateway extends BaseController
|
|||
}
|
||||
}
|
||||
|
||||
// Auto-sync any existing FHIR documents for this patient to health_records
|
||||
$this->syncPatientFhirToHealthRecords($patientId, $abhaAddress, $selectedRefs);
|
||||
|
||||
$this->db->table('abdm_link_transactions')
|
||||
->where('id', (int) $txn['id'])
|
||||
->update([
|
||||
|
|
@ -5356,6 +5531,74 @@ class AbdmGateway extends BaseController
|
|||
return $this->m2LinkConfirm();
|
||||
}
|
||||
|
||||
private function syncPatientFhirToHealthRecords(int $patientId, string $abhaAddress, array $careContextRefs): void
|
||||
{
|
||||
if ($patientId <= 0 || ! $this->db->tableExists('health_records')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$now = Time::now('Asia/Kolkata')->toDateTimeString();
|
||||
|
||||
foreach ($careContextRefs as $ref) {
|
||||
$ref = trim((string) $ref);
|
||||
if ($ref === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sessionId = 0;
|
||||
if (preg_match('/(?:OPD|PRESCRIPTION)-\d+-S(\d+)/i', $ref, $m)) {
|
||||
$sessionId = (int) $m[1];
|
||||
}
|
||||
|
||||
$docRow = null;
|
||||
if ($this->db->tableExists('opd_fhir_documents')) {
|
||||
$b = $this->db->table('opd_fhir_documents');
|
||||
if ($sessionId > 0) {
|
||||
$b->where('opd_session_id', $sessionId);
|
||||
} else {
|
||||
$b->where('opd_id', $patientId);
|
||||
}
|
||||
$docRow = $b->orderBy('id', 'DESC')->get(1)->getRowArray();
|
||||
}
|
||||
|
||||
$bundleJson = $docRow['bundle_json'] ?? null;
|
||||
if ($bundleJson === null) {
|
||||
$bundle = $this->assembleFhirBundleForCareContext($ref);
|
||||
if ($bundle !== null) {
|
||||
$bundleJson = json_encode($bundle, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
}
|
||||
}
|
||||
|
||||
if ($bundleJson !== null) {
|
||||
$existing = $this->db->table('health_records')
|
||||
->select('id')
|
||||
->where('care_context_reference', $ref)
|
||||
->get(1)
|
||||
->getRowArray();
|
||||
|
||||
$hrData = [
|
||||
'patient_id' => $patientId,
|
||||
'abha_id' => $abhaAddress !== '' ? $abhaAddress : null,
|
||||
'hi_type' => 'OPConsultRecord',
|
||||
'entity_type' => 'opd',
|
||||
'entity_id' => (string) ($sessionId > 0 ? $sessionId : $patientId),
|
||||
'record_data' => $bundleJson,
|
||||
'care_context_reference' => $ref,
|
||||
'push_status' => 'linked',
|
||||
'linked_at' => $now,
|
||||
'updated_at' => $now,
|
||||
];
|
||||
|
||||
if (! empty($existing)) {
|
||||
$this->db->table('health_records')->where('id', (int) $existing['id'])->update($hrData);
|
||||
} else {
|
||||
$hrData['created_at'] = $now;
|
||||
$this->db->table('health_records')->insert($hrData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// M2 Discovery & Linking Helpers
|
||||
// =========================================================================
|
||||
|
|
|
|||
|
|
@ -11763,13 +11763,41 @@ class Opd_prescription extends BaseController
|
|||
return false;
|
||||
}
|
||||
|
||||
// NOTE: Do NOT also enqueue an 'opd.fhir.generated' bridge_sync_queue event here.
|
||||
// That event type has no 'abdm.'/'snomed.'/'nhcx.' prefix, so BridgeSyncService
|
||||
// routes it to the generic CSNOtk terminology bridge (BRIDGE_SYNC_URL), which has
|
||||
// no handler for it and always returns HTTP 404 -- it has no consumer anywhere in
|
||||
// this codebase. The bundle is already persisted to opd_fhir_documents above; actual
|
||||
// ABDM sharing is triggered separately via DreamsoftConnector::sharePrescriptionBundle()
|
||||
// (event 'abdm.fhir.share.requested'), which correctly routes to ABDM_BRIDGE_URL.
|
||||
if ($this->db->tableExists('health_records')) {
|
||||
try {
|
||||
$patientId = (int) ($patientRow['id'] ?? ($opdRow['p_id'] ?? 0));
|
||||
$visitDateRaw = trim((string) ($opdRow['date_opd_visit'] ?? $opdRow['apointment_date'] ?? ''));
|
||||
$visitDate = $visitDateRaw !== '' ? date('Y-m-d', strtotime($visitDateRaw)) : date('Y-m-d');
|
||||
$careContextRef = 'OPD-' . $patientId . '-S' . $sessionId . '-' . str_replace('-', '', $visitDate);
|
||||
|
||||
$existingHr = $this->db->table('health_records')
|
||||
->select('id')
|
||||
->where('care_context_reference', $careContextRef)
|
||||
->get(1)
|
||||
->getRowArray();
|
||||
|
||||
$hrPayload = [
|
||||
'patient_id' => $patientId > 0 ? $patientId : null,
|
||||
'abha_id' => $abhaAddress !== '' ? $abhaAddress : null,
|
||||
'hi_type' => 'OPConsultRecord',
|
||||
'entity_type' => 'opd',
|
||||
'entity_id' => (string) $sessionId,
|
||||
'record_data' => $bundleJson,
|
||||
'care_context_reference' => $careContextRef,
|
||||
'push_status' => 'local_discovery_ready',
|
||||
'updated_at' => Time::now('Asia/Kolkata')->toDateTimeString(),
|
||||
];
|
||||
|
||||
if (! empty($existingHr)) {
|
||||
$this->db->table('health_records')->where('id', (int) $existingHr['id'])->update($hrPayload);
|
||||
} else {
|
||||
$hrPayload['created_at'] = Time::now('Asia/Kolkata')->toDateTimeString();
|
||||
$this->db->table('health_records')->insert($hrPayload);
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
log_message('warning', '[storePrescriptionFhirBundle] auto health_records insert error: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -967,6 +967,43 @@ class Patient extends BaseController
|
|||
return $this->response->setStatusCode(404)->setBody('Patient not found');
|
||||
}
|
||||
|
||||
if (! empty($data['data'][0])) {
|
||||
$curAbha = trim((string) ($data['data'][0]->abha_address ?? ''));
|
||||
if ($curAbha === '') {
|
||||
$foundAbha = '';
|
||||
if ($this->db->tableExists('abdm_link_transactions')) {
|
||||
$alt = $this->db->table('abdm_link_transactions')
|
||||
->select('abha_address')
|
||||
->where('patient_id', $pno)
|
||||
->where('abha_address !=', '')
|
||||
->orderBy('id', 'DESC')
|
||||
->get(1)->getRowArray();
|
||||
if (! empty($alt['abha_address'])) {
|
||||
$foundAbha = trim((string) $alt['abha_address']);
|
||||
}
|
||||
}
|
||||
if ($foundAbha === '' && $this->db->tableExists('record_links')) {
|
||||
$rl = $this->db->table('record_links')
|
||||
->select('abha_id')
|
||||
->where('care_context_reference LIKE', 'OPD-' . $pno . '-%')
|
||||
->where('abha_id !=', '')
|
||||
->orderBy('id', 'DESC')
|
||||
->get(1)->getRowArray();
|
||||
if (! empty($rl['abha_id'])) {
|
||||
$foundAbha = trim((string) $rl['abha_id']);
|
||||
}
|
||||
}
|
||||
if ($foundAbha !== '') {
|
||||
$data['data'][0]->abha_address = $foundAbha;
|
||||
if (str_contains($foundAbha, '@')) {
|
||||
$this->db->table('patient_master')->where('id', $pno)->update(['abha_address' => $foundAbha]);
|
||||
} else {
|
||||
$this->db->table('patient_master')->where('id', $pno)->update(['abha_id' => $foundAbha]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$required_age = $data['data'][0]->age;
|
||||
$required_age_in_month = $data['data'][0]->age_in_month;
|
||||
$required_dob = $data['data'][0]->dob;
|
||||
|
|
|
|||
|
|
@ -26,13 +26,41 @@
|
|||
if ($abhaAddress === '' && preg_match('/abha_address\s*:\s*([A-Za-z0-9._-]+@[A-Za-z0-9.-]+)/i', (string) ($data[0]->log ?? ''), $abhaLogMatch) === 1) {
|
||||
$abhaAddress = trim((string) ($abhaLogMatch[1] ?? ''));
|
||||
}
|
||||
if ($abhaAddress === '') {
|
||||
$db = \Config\Database::connect();
|
||||
if ($db->tableExists('abdm_link_transactions')) {
|
||||
$alt = $db->table('abdm_link_transactions')
|
||||
->select('abha_address')
|
||||
->where('patient_id', (int) ($data[0]->id ?? 0))
|
||||
->where('abha_address !=', '')
|
||||
->orderBy('id', 'DESC')
|
||||
->get(1)->getRowArray();
|
||||
if (! empty($alt['abha_address'])) {
|
||||
$abhaAddress = trim((string) $alt['abha_address']);
|
||||
}
|
||||
}
|
||||
if ($abhaAddress === '' && $db->tableExists('record_links')) {
|
||||
$rl = $db->table('record_links')
|
||||
->select('abha_id')
|
||||
->where('care_context_reference LIKE', 'OPD-' . (int) ($data[0]->id ?? 0) . '-%')
|
||||
->where('abha_id !=', '')
|
||||
->orderBy('id', 'DESC')
|
||||
->get(1)->getRowArray();
|
||||
if (! empty($rl['abha_id'])) {
|
||||
$abhaAddress = trim((string) $rl['abha_id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($patientAbhaId === '' && $abhaAddress !== '') {
|
||||
$patientAbhaId = $abhaAddress;
|
||||
}
|
||||
$abhaVerifiedStatus = trim((string) ($data[0]->abha_verified_status ?? ''));
|
||||
$abhaVerificationType = trim((string) ($data[0]->abha_verification_type ?? ''));
|
||||
$abhaKycVerified = (int) ($data[0]->abha_kyc_verified ?? 0) === 1;
|
||||
$abhaMobileVerified = (int) ($data[0]->abha_mobile_verified ?? 0) === 1;
|
||||
$abhaLinkedAt = trim((string) ($data[0]->abdm_linked_at ?? ''));
|
||||
$abhaPhotoAvailable = trim((string) ($data[0]->abha_profile_photo_base64 ?? '')) !== '';
|
||||
$isAbhaLinkedAndVerified = $patientAbhaId !== '' && strtoupper($abhaVerifiedStatus) === 'VERIFIED';
|
||||
$isAbhaLinkedAndVerified = $patientAbhaId !== '' && in_array(strtoupper($abhaVerifiedStatus), ['VERIFIED', 'LINKED'], true);
|
||||
?>
|
||||
<?php
|
||||
$user = auth()->user();
|
||||
|
|
|
|||
|
|
@ -558,7 +558,21 @@
|
|||
if ($relationLabel !== '') {
|
||||
$patientNameWithRelation .= ' (' . $relationLabel . ')';
|
||||
}
|
||||
$patientAbhaAddress = trim((string) ($patient_master[0]->abha_address ?? $patient_master[0]->abha ?? ''));
|
||||
$patientAbhaAddress = trim((string) ($patient_master[0]->abha_address ?? $patient_master[0]->abha_id ?? $patient_master[0]->abha ?? ''));
|
||||
if ($patientAbhaAddress === '') {
|
||||
$db = \Config\Database::connect();
|
||||
if ($db->tableExists('record_links')) {
|
||||
$rl = $db->table('record_links')
|
||||
->select('abha_id')
|
||||
->where('care_context_reference LIKE', 'OPD-' . (int) ($patient_master[0]->id ?? 0) . '-%')
|
||||
->where('abha_id !=', '')
|
||||
->orderBy('id', 'DESC')
|
||||
->get(1)->getRowArray();
|
||||
if (! empty($rl['abha_id'])) {
|
||||
$patientAbhaAddress = trim((string) $rl['abha_id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<a href="javascript:load_form('<?= esc($historyUrl, 'js') ?>','Consult History');"
|
||||
class="btn btn-info btn-sm"
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user