fix(abdm): sanitize care context display, fix discharge care_context_reference and bundle generation, fix taskboard sync patientId
This commit is contained in:
parent
f7761218d0
commit
5130c6b18a
|
|
@ -2218,7 +2218,8 @@ class AbdmGateway extends BaseController
|
|||
$dateClean = str_replace('-', '', $visitDate);
|
||||
$ccRef = $prefix . '-' . $labReqId . '-' . $dateClean;
|
||||
}
|
||||
$careContextDisplay = ($isImaging ? 'Radiology Report - ' : 'Diagnostic Report - ') . ($testTitle !== '' ? $testTitle : ($isImaging ? 'Radiology Report' : 'Lab Report')) . ' (' . date('d M Y', strtotime($visitDate)) . ')';
|
||||
$cleanTestTitle = self::sanitizeCareContextDisplay($testTitle !== '' ? $testTitle : ($isImaging ? 'Radiology Report' : 'Lab Report'));
|
||||
$careContextDisplay = self::sanitizeCareContextDisplay(($isImaging ? 'Radiology Report - ' : 'Diagnostic Report - ') . $cleanTestTitle . ' ' . date('d M Y', strtotime($visitDate)));
|
||||
|
||||
$healthRecordId = $this->storeHealthRecord([
|
||||
'patient_id' => $patientId,
|
||||
|
|
@ -3190,6 +3191,12 @@ class AbdmGateway extends BaseController
|
|||
$diagnoses[] = ['text' => $problem, 'code' => ''];
|
||||
}
|
||||
}
|
||||
if (empty($diagnoses) && ! empty($chiefComplaints)) {
|
||||
$diagnoses = $chiefComplaints;
|
||||
}
|
||||
if (empty($diagnoses) && empty($procedures)) {
|
||||
$diagnoses[] = ['text' => 'Medical care and evaluation', 'code' => ''];
|
||||
}
|
||||
$chiefComplaintNarrative = trim((string) (($this->ipdRows('ipd_discharge_complaint_remark', ['comp_remark'], $ipdId)[0]['comp_remark'] ?? '')));
|
||||
$diagnosisNarrative = trim((string) (($this->ipdRows('ipd_discharge_diagnosis_remark', ['comp_remark'], $ipdId)[0]['comp_remark'] ?? '')));
|
||||
|
||||
|
|
@ -3368,9 +3375,13 @@ class AbdmGateway extends BaseController
|
|||
|
||||
$uniqueSuffix = $isNewRecord ? ('-v' . time()) : '';
|
||||
|
||||
$ccRef = 'DISCHARGE-' . $ipdId . '-' . str_replace('-', '', (string) $visitDate) . $uniqueSuffix;
|
||||
$ccDisplay = 'DischargeSummaryRecord - ' . date('d M Y', strtotime((string) $visitDate));
|
||||
|
||||
$source = [
|
||||
'record_id' => (string) $ipdId,
|
||||
'care_context_reference' => 'DISCHARGE-' . $ipdId . '-S' . $ipdId . '-' . $visitDate . $uniqueSuffix,
|
||||
'care_context_reference' => $ccRef,
|
||||
'care_context_display' => $ccDisplay,
|
||||
'bundle_identifier' => 'discharge-' . (trim((string) ($ipdRow['ipd_code'] ?? '')) ?: (string) $ipdId) . $uniqueSuffix,
|
||||
'session_id' => (string) $ipdId,
|
||||
'visit_date' => $visitDate,
|
||||
|
|
@ -3379,6 +3390,9 @@ class AbdmGateway extends BaseController
|
|||
'doctor_name' => $doctorName,
|
||||
'discharge_status' => $dischargeStatus,
|
||||
'problem' => trim((string) ($ipdRow['problem'] ?? '')),
|
||||
'diagnoses' => $diagnoses,
|
||||
'conditions' => $diagnoses,
|
||||
'chief_complaints' => $chiefComplaints,
|
||||
'doctor' => [
|
||||
'id' => $doctorId > 0 ? (string) $doctorId : '',
|
||||
'name' => $doctorName,
|
||||
|
|
@ -6398,7 +6412,8 @@ class AbdmGateway extends BaseController
|
|||
$visitDate = date('Y-m-d', strtotime((string) $reportedDate));
|
||||
$dateStr = date('d M Y', strtotime($visitDate));
|
||||
$ccRef = $prefix . '-' . $taskEntityId . '-' . str_replace('-', '', $visitDate);
|
||||
$display = ($isImaging ? 'Radiology Report - ' : 'Diagnostic Report - ') . $title . ' (' . $dateStr . ')';
|
||||
$cleanTitle = self::sanitizeCareContextDisplay($title);
|
||||
$display = self::sanitizeCareContextDisplay(($isImaging ? 'Radiology Report - ' : 'Diagnostic Report - ') . $cleanTitle . ' ' . $dateStr);
|
||||
|
||||
$hasFindings = trim((string) ($labReq['Report_Data'] ?? '')) !== '' || trim((string) ($labReq['report_data_Impression'] ?? '')) !== '';
|
||||
$statusVal = (int) ($labReq['status'] ?? 0);
|
||||
|
|
@ -6711,7 +6726,8 @@ class AbdmGateway extends BaseController
|
|||
$visitDate = date('Y-m-d', strtotime((string) $reportedDate));
|
||||
$dateStr = date('d M Y', strtotime($visitDate));
|
||||
$ccRef = $prefix . '-' . $lr['id'] . '-' . str_replace('-', '', $visitDate);
|
||||
$display = ($isImaging ? 'Radiology Report - ' : 'Diagnostic Report - ') . $title . ' (' . $dateStr . ')';
|
||||
$cleanTitle = self::sanitizeCareContextDisplay($title);
|
||||
$display = self::sanitizeCareContextDisplay(($isImaging ? 'Radiology Report - ' : 'Diagnostic Report - ') . $cleanTitle . ' ' . $dateStr);
|
||||
|
||||
$hasFindings = trim((string) ($lr['Report_Data'] ?? '')) !== '' || trim((string) ($lr['report_data_Impression'] ?? '')) !== '';
|
||||
$statusVal = (int) ($lr['status'] ?? 0);
|
||||
|
|
@ -11939,6 +11955,17 @@ class AbdmGateway extends BaseController
|
|||
// Body: { abha_address, link_token_id, patient_ref, display, hi_type, care_contexts[] }
|
||||
// =========================================================================
|
||||
|
||||
public static function sanitizeCareContextDisplay(string $display): string
|
||||
{
|
||||
$display = str_replace('&', 'and', $display);
|
||||
$display = preg_replace('/[^a-zA-Z0-9 \-_.]/', ' ', $display);
|
||||
$display = trim(preg_replace('/\s+/', ' ', (string) $display));
|
||||
if (mb_strlen($display) > 100) {
|
||||
$display = mb_substr($display, 0, 100);
|
||||
}
|
||||
return $display;
|
||||
}
|
||||
|
||||
public function hipLinkCareContext()
|
||||
{
|
||||
if (ENVIRONMENT !== 'testing' && ! $this->request->isAJAX()) {
|
||||
|
|
@ -12015,6 +12042,46 @@ class AbdmGateway extends BaseController
|
|||
}
|
||||
}
|
||||
|
||||
if (! empty($body['display'])) {
|
||||
$body['display'] = self::sanitizeCareContextDisplay((string) $body['display']);
|
||||
}
|
||||
if (! empty($body['care_contexts']) && is_array($body['care_contexts'])) {
|
||||
foreach ($body['care_contexts'] as &$cc) {
|
||||
if (isset($cc['display'])) {
|
||||
$cc['display'] = self::sanitizeCareContextDisplay((string) $cc['display']);
|
||||
}
|
||||
}
|
||||
unset($cc);
|
||||
}
|
||||
|
||||
// Auto-ensure health record bundle is pushed to bridge for linked discharge care contexts
|
||||
if (! empty($body['care_contexts']) && is_array($body['care_contexts'])) {
|
||||
foreach ($body['care_contexts'] as $ccItem) {
|
||||
$refNo = (string) ($ccItem['referenceNumber'] ?? $ccItem['reference_number'] ?? $ccItem['ref'] ?? $ccItem['careContextId'] ?? '');
|
||||
if (str_starts_with($refNo, 'DISCHARGE-')) {
|
||||
if (preg_match('/^DISCHARGE-(\d+)/', $refNo, $mIpd)) {
|
||||
$targetIpdId = (int) $mIpd[1];
|
||||
if ($targetIpdId > 0 && class_exists('\App\Controllers\Ipd_discharge')) {
|
||||
try {
|
||||
$ipdCtrl = new \App\Controllers\Ipd_discharge();
|
||||
$ipdCtrl->initController($this->request, $this->response, $this->logger);
|
||||
$refIpd = new \ReflectionClass($ipdCtrl);
|
||||
if ($refIpd->hasMethod('enqueueIpdDischargeFhirSync')) {
|
||||
$mSync = $refIpd->getMethod('enqueueIpdDischargeFhirSync');
|
||||
$mSync->setAccessible(true);
|
||||
$ipdRow = $this->db->table('ipd_master')->where('id', $targetIpdId)->get(1)->getRowArray() ?? [];
|
||||
$pRow = $this->db->table('patient_master')->where('id', $patientId)->get(1)->getRowArray() ?? [];
|
||||
$mSync->invoke($ipdCtrl, $targetIpdId, $patientId, $ipdRow, $pRow);
|
||||
}
|
||||
} catch (\Throwable $eIpd) {
|
||||
log_message('warning', 'hipLinkCareContext IPD sync error: ' . $eIpd->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$result = $this->connector->hipLinkCareContext($body);
|
||||
return $this->response->setJSON($result);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9420,6 +9420,13 @@ class Ipd_discharge extends BaseController
|
|||
$chiefComplaintsList[] = ['text' => $complaintRemarkText, 'code' => ''];
|
||||
}
|
||||
|
||||
if (empty($conditionRows) && ! empty($chiefComplaintsList)) {
|
||||
$conditionRows = $chiefComplaintsList;
|
||||
}
|
||||
if (empty($conditionRows)) {
|
||||
$conditionRows[] = ['text' => 'Medical care and evaluation', 'code' => ''];
|
||||
}
|
||||
|
||||
$procedureRows = [];
|
||||
foreach ($this->byIpdRows('ipd_discharge_surgery', ['surgery_name', 'surgery_date'], 'id ASC', $ipdId) as $row) {
|
||||
$text = trim((string) ($row['surgery_name'] ?? ''));
|
||||
|
|
@ -9686,8 +9693,13 @@ class Ipd_discharge extends BaseController
|
|||
$patientPin = trim((string) ($patientRow['p_pin'] ?? $patientRow['pincode'] ?? ''));
|
||||
$dischargeStatus = trim((string) ($ipdRow['discarge_patient_status'] ?? ''));
|
||||
|
||||
$ccRef = 'DISCHARGE-' . $ipdId . '-' . str_replace('-', '', (string) $visitDate);
|
||||
$ccDisplay = 'DischargeSummaryRecord - ' . date('d M Y', strtotime((string) $visitDate));
|
||||
|
||||
$source = [
|
||||
'record_id' => (string) $ipdId,
|
||||
'care_context_reference' => $ccRef,
|
||||
'care_context_display' => $ccDisplay,
|
||||
'bundle_identifier' => 'discharge-' . $ipdNo,
|
||||
'session_id' => (string) $ipdId,
|
||||
'visit_date' => $visitDate,
|
||||
|
|
@ -9696,6 +9708,9 @@ class Ipd_discharge extends BaseController
|
|||
'doctor_name' => trim((string) ($ipdRow['r_doc_name'] ?? '')),
|
||||
'discharge_status' => $dischargeStatus,
|
||||
'problem' => trim((string) ($ipdRow['problem'] ?? '')),
|
||||
'diagnoses' => $conditionRows,
|
||||
'conditions' => $conditionRows,
|
||||
'chief_complaints' => $chiefComplaintsList,
|
||||
'organization' => [
|
||||
'id' => $hfrId,
|
||||
'name' => $hospitalName,
|
||||
|
|
@ -9773,6 +9788,30 @@ class Ipd_discharge extends BaseController
|
|||
|
||||
$outbox = new AbdmSyncOutboxService();
|
||||
$outbox->enqueueRecordSync($syncPayload);
|
||||
|
||||
// Also push synchronously to E-Atria bridge so the bundle is immediately accessible to PHR apps
|
||||
try {
|
||||
$connector = new \App\Libraries\Abdm\EAtriaBridgeConnector();
|
||||
$pushData = [
|
||||
'patient_id' => (string) $patientId,
|
||||
'patient_name' => (string) ($gatewayPayload['patient_name'] ?? $patientName),
|
||||
'abha_id' => (string) ($gatewayPayload['abha_id'] ?? $abhaDigits),
|
||||
'abha_address' => (string) ($gatewayPayload['abha_address'] ?? $abhaAddress),
|
||||
'hi_type' => 'DischargeSummaryRecord',
|
||||
'record_type' => 'DischargeSummaryRecord',
|
||||
'visit_date' => (string) ($gatewayPayload['visit_date'] ?? $visitDate),
|
||||
'care_context_reference' => $ccRef,
|
||||
'care_context_display' => $ccDisplay,
|
||||
'notes' => $ccDisplay,
|
||||
'queue_id' => $ccRef,
|
||||
'bundle' => (array) ($gatewayPayload['fhir_bundle'] ?? []),
|
||||
'fhir_bundle' => (array) ($gatewayPayload['fhir_bundle'] ?? []),
|
||||
'record_data' => (array) ($gatewayPayload['fhir_bundle'] ?? []),
|
||||
];
|
||||
$connector->pushRecord($pushData);
|
||||
} catch (\Throwable $pe) {
|
||||
log_message('warning', '[enqueueIpdDischargeFhirSync] Direct bridge push error: ' . $pe->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private function normalizeFhirGender(string $gender): string
|
||||
|
|
|
|||
|
|
@ -94,8 +94,17 @@ class DischargeFhirGenerator extends \App\Libraries\Abdm\Fhir\Generators\Abstrac
|
|||
$patientRef = 'urn:uuid:patient-' . $patientId;
|
||||
$encounterRef = is_array($encounter) ? 'urn:uuid:' . (string) ($encounter['id'] ?? '') : null;
|
||||
|
||||
$diagnosesList = (array) ($source['diagnoses'] ?? $source['conditions'] ?? []);
|
||||
$chiefComplaintsList = (array) ($source['chief_complaints'] ?? []);
|
||||
$diagnosesList = (array) ($source['diagnoses'] ?? $source['conditions'] ?? $source['ui_final_diagnosis'] ?? []);
|
||||
$chiefComplaintsList = (array) ($source['chief_complaints'] ?? $source['ui_complaints'] ?? []);
|
||||
|
||||
if (empty($diagnosesList) && empty($chiefComplaintsList)) {
|
||||
$problem = trim((string) ($source['problem'] ?? ''));
|
||||
if ($problem !== '') {
|
||||
$diagnosesList = [['text' => $problem, 'code' => '']];
|
||||
} else {
|
||||
$diagnosesList = [['text' => 'Medical care and evaluation', 'code' => '']];
|
||||
}
|
||||
}
|
||||
|
||||
$conditionGroups = [
|
||||
[
|
||||
|
|
|
|||
|
|
@ -168,7 +168,8 @@ class AbdmTaskBoardSyncService
|
|||
}
|
||||
|
||||
$opdId = (int) ($row['opd_id'] ?? 0);
|
||||
if ($opdId <= 0) {
|
||||
$patientId = (int) ($row['p_id'] ?? 0);
|
||||
if ($opdId <= 0 || $patientId <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -895,6 +896,23 @@ class AbdmTaskBoardSyncService
|
|||
log_message('warning', '[processIndividualWorkTask] Wellness bundle generation error: ' . $we->getMessage());
|
||||
}
|
||||
}
|
||||
} elseif ($taskType === 'ipd_discharge_publish') {
|
||||
if ($this->db->tableExists('abdm_sync_record')) {
|
||||
$syncRec = $this->db->table('abdm_sync_record')
|
||||
->where('local_record_id', 'ipd-discharge-' . $entityId)
|
||||
->orWhere('care_context_reference', $careContextRef)
|
||||
->get(1)
|
||||
->getRowArray();
|
||||
if (! empty($syncRec['fhir_bundle_json'])) {
|
||||
$decodedBundle = json_decode((string) $syncRec['fhir_bundle_json'], true);
|
||||
if (is_array($decodedBundle) && ! empty($decodedBundle)) {
|
||||
$pushData['bundle'] = $decodedBundle;
|
||||
$pushData['fhir_bundle'] = $decodedBundle;
|
||||
$pushData['record_data'] = $decodedBundle;
|
||||
$bundleJson = (string) $syncRec['fhir_bundle_json'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user