fix(abdm): map admission/discharge encounter period, split vitals by admission/discharge, and attach size/hash to pdf document reference
This commit is contained in:
parent
c238fcfc40
commit
4e748dbaa8
|
|
@ -2718,11 +2718,24 @@ class AbdmGateway extends BaseController
|
|||
$abhaDigits = preg_replace('/\D/', '', $rawAbha);
|
||||
$abhaDigits = is_string($abhaDigits) ? $abhaDigits : '';
|
||||
|
||||
$admissionRaw = trim((string) ($ipdRow['register_date'] ?? ''));
|
||||
$dischargeRaw = trim((string) ($ipdRow['discharge_date'] ?? ''));
|
||||
$visitDate = $dischargeRaw !== ''
|
||||
? date('Y-m-d', strtotime($dischargeRaw))
|
||||
: ($admissionRaw !== '' ? date('Y-m-d', strtotime($admissionRaw)) : date('Y-m-d'));
|
||||
$admissionDate = trim((string) ($ipdRow['register_date'] ?? ''));
|
||||
$admissionTime = trim((string) ($ipdRow['reg_time'] ?? $ipdRow['reg_time_bak'] ?? ''));
|
||||
$admissionRaw = $admissionDate;
|
||||
if ($admissionTime !== '' && ! str_contains($admissionDate, ':')) {
|
||||
$admissionRaw = trim($admissionDate . ' ' . $admissionTime);
|
||||
}
|
||||
|
||||
$dischargeDate = trim((string) ($ipdRow['discharge_date'] ?? ''));
|
||||
$dischargeTime = trim((string) ($ipdRow['discharge_time'] ?? $ipdRow['discharge_time_bak'] ?? ''));
|
||||
$dischargeAmpm = trim((string) ($ipdRow['discharge_time_ampm'] ?? ''));
|
||||
$dischargeRaw = $dischargeDate;
|
||||
if ($dischargeTime !== '' && ! str_contains($dischargeDate, ':')) {
|
||||
$dischargeRaw = trim($dischargeDate . ' ' . $dischargeTime . ($dischargeAmpm !== '' ? ' ' . $dischargeAmpm : ''));
|
||||
}
|
||||
|
||||
$visitDate = $dischargeDate !== ''
|
||||
? date('Y-m-d', strtotime($dischargeDate))
|
||||
: ($admissionDate !== '' ? date('Y-m-d', strtotime($admissionDate)) : date('Y-m-d'));
|
||||
|
||||
$diagnoses = [];
|
||||
foreach ($this->ipdRows('ipd_discharge_diagnosis', ['comp_report'], $ipdId) as $row) {
|
||||
|
|
|
|||
|
|
@ -257,7 +257,7 @@ class DischargeFhirGenerator extends \App\Libraries\Abdm\Fhir\Generators\Abstrac
|
|||
$catText = trim((string) ($obs['category'] ?? $obs['category_text'] ?? $obs['stage'] ?? $obs['timing'] ?? ''));
|
||||
$isAdm = (stripos($catText, 'Admission') !== false || stripos($text, 'Admission') !== false);
|
||||
$isDis = (stripos($catText, 'Discharge') !== false || stripos($text, 'Discharge') !== false);
|
||||
$obsCategoryDisplay = $isAdm ? 'General Examination on Admission' : ($isDis ? 'Examination on Discharge' : 'Vital Signs');
|
||||
$obsCategoryDisplay = $isAdm ? 'Condition on Admission Time' : ($isDis ? 'Condition on Discharge Time' : 'Vital Signs');
|
||||
|
||||
$coding = [];
|
||||
$loincCode = trim((string) ($obs['loinc_code'] ?? ''));
|
||||
|
|
@ -484,7 +484,11 @@ class DischargeFhirGenerator extends \App\Libraries\Abdm\Fhir\Generators\Abstrac
|
|||
}
|
||||
}
|
||||
|
||||
$builder->addDocumentReference([
|
||||
$rawBytes = base64_decode($data);
|
||||
$fileSize = is_string($rawBytes) ? strlen($rawBytes) : 0;
|
||||
$sha1Hash = is_string($rawBytes) && $rawBytes !== '' ? base64_encode(sha1($rawBytes, true)) : '';
|
||||
|
||||
$docRef = [
|
||||
'resourceType' => 'DocumentReference',
|
||||
'id' => 'discharge-document-' . $recordId . '-' . $idx,
|
||||
'meta' => ['profile' => ['https://nrces.in/ndhm/fhir/r4/StructureDefinition/DocumentReference']],
|
||||
|
|
@ -509,11 +513,18 @@ class DischargeFhirGenerator extends \App\Libraries\Abdm\Fhir\Generators\Abstrac
|
|||
'contentType' => (string) ($document['content_type'] ?? 'application/pdf'),
|
||||
'language' => 'en-IN',
|
||||
'data' => $data,
|
||||
'size' => $fileSize,
|
||||
'title' => $docTitle,
|
||||
'creation' => (string) ($document['created_at'] ?? $timestamp),
|
||||
],
|
||||
]],
|
||||
]);
|
||||
];
|
||||
|
||||
if ($sha1Hash !== '') {
|
||||
$docRef['content'][0]['attachment']['hash'] = $sha1Hash;
|
||||
}
|
||||
|
||||
$builder->addDocumentReference($docRef);
|
||||
}
|
||||
|
||||
$rawObservations = (array) ($source['observations'] ?? []);
|
||||
|
|
@ -537,8 +548,24 @@ class DischargeFhirGenerator extends \App\Libraries\Abdm\Fhir\Generators\Abstrac
|
|||
];
|
||||
|
||||
if (! empty($admissionObsIndexed) && ! empty($dischargeObsIndexed)) {
|
||||
$sectionDefinitions[] = ['title' => 'General Examination on Admission', 'code' => '425044008', 'display' => 'Physical exam section', 'prefix' => 'discharge-observation-', 'items_indexed' => $admissionObsIndexed];
|
||||
$sectionDefinitions[] = ['title' => 'Examination on Discharge', 'code' => '425044008', 'display' => 'Physical exam section', 'prefix' => 'discharge-observation-', 'items_indexed' => $dischargeObsIndexed];
|
||||
$sectionDefinitions[] = ['title' => 'Condition on Admission Time', 'code' => '425044008', 'display' => 'Physical exam section', 'prefix' => 'discharge-observation-', 'items_indexed' => $admissionObsIndexed];
|
||||
$sectionDefinitions[] = ['title' => 'Condition on Discharge Time', 'code' => '425044008', 'display' => 'Physical exam section', 'prefix' => 'discharge-observation-', 'items_indexed' => $dischargeObsIndexed];
|
||||
} elseif (! empty($admissionObsIndexed)) {
|
||||
$sectionDefinitions[] = ['title' => 'Condition on Admission Time', 'code' => '425044008', 'display' => 'Physical exam section', 'prefix' => 'discharge-observation-', 'items_indexed' => $admissionObsIndexed];
|
||||
if (! empty($rawObservations)) {
|
||||
$otherObs = array_diff_key($rawObservations, $admissionObsIndexed);
|
||||
if (! empty($otherObs)) {
|
||||
$sectionDefinitions[] = ['title' => 'Physical examination', 'code' => '425044008', 'display' => 'Physical exam section', 'prefix' => 'discharge-observation-', 'items_indexed' => $otherObs];
|
||||
}
|
||||
}
|
||||
} elseif (! empty($dischargeObsIndexed)) {
|
||||
$sectionDefinitions[] = ['title' => 'Condition on Discharge Time', 'code' => '425044008', 'display' => 'Physical exam section', 'prefix' => 'discharge-observation-', 'items_indexed' => $dischargeObsIndexed];
|
||||
if (! empty($rawObservations)) {
|
||||
$otherObs = array_diff_key($rawObservations, $dischargeObsIndexed);
|
||||
if (! empty($otherObs)) {
|
||||
$sectionDefinitions[] = ['title' => 'Physical examination', 'code' => '425044008', 'display' => 'Physical exam section', 'prefix' => 'discharge-observation-', 'items_indexed' => $otherObs];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$sectionDefinitions[] = ['title' => 'Physical examination', 'code' => '425044008', 'display' => 'Physical exam section', 'prefix' => 'discharge-observation-', 'items' => $rawObservations];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2371,14 +2371,16 @@
|
|||
}
|
||||
|
||||
var admissionObservations = observations.filter(function(o) {
|
||||
return getObservationCategoryText(o).toLowerCase() === 'condition on admission time';
|
||||
var cat = getObservationCategoryText(o).toLowerCase();
|
||||
return cat.indexOf('admission') !== -1;
|
||||
});
|
||||
var dischargeObservations = observations.filter(function(o) {
|
||||
return getObservationCategoryText(o).toLowerCase() === 'condition on discharge time';
|
||||
var cat = getObservationCategoryText(o).toLowerCase();
|
||||
return cat.indexOf('discharge') !== -1;
|
||||
});
|
||||
var remainingObservations = observations.filter(function(o) {
|
||||
var cat = getObservationCategoryText(o).toLowerCase();
|
||||
return cat !== 'condition on admission time' && cat !== 'condition on discharge time';
|
||||
return cat.indexOf('admission') === -1 && cat.indexOf('discharge') === -1;
|
||||
});
|
||||
var vitalObservations = remainingObservations.filter(isVitalObservation);
|
||||
var labObservations = remainingObservations.filter(function(o) { return !isVitalObservation(o); });
|
||||
|
|
|
|||
|
|
@ -302,10 +302,10 @@ final class FhirGeneratorsTest extends CIUnitTestCase
|
|||
$bundle = $output['fhir_bundle'];
|
||||
$composition = $bundle['entry'][0]['resource'];
|
||||
|
||||
// Verify sections: should contain both General Examination on Admission and Examination on Discharge
|
||||
// Verify sections: should contain both Condition on Admission Time and Condition on Discharge Time
|
||||
$sectionTitles = array_column($composition['section'], 'title');
|
||||
$this->assertContains('General Examination on Admission', $sectionTitles);
|
||||
$this->assertContains('Examination on Discharge', $sectionTitles);
|
||||
$this->assertContains('Condition on Admission Time', $sectionTitles);
|
||||
$this->assertContains('Condition on Discharge Time', $sectionTitles);
|
||||
$this->assertContains('Care plan', $sectionTitles);
|
||||
$this->assertContains('Document reference', $sectionTitles);
|
||||
|
||||
|
|
@ -333,8 +333,8 @@ final class FhirGeneratorsTest extends CIUnitTestCase
|
|||
// Verify Observation Categories on Admission vs Discharge
|
||||
$observations = array_values(array_filter($bundle['entry'], static fn (array $e): bool => ($e['resource']['resourceType'] ?? '') === 'Observation' && isset($e['resource']['category'])));
|
||||
$this->assertGreaterThanOrEqual(14, count($observations));
|
||||
$this->assertSame('General Examination on Admission', $observations[0]['resource']['category'][0]['text']);
|
||||
$this->assertSame('Examination on Discharge', $observations[7]['resource']['category'][0]['text']);
|
||||
$this->assertSame('Condition on Admission Time', $observations[0]['resource']['category'][0]['text']);
|
||||
$this->assertSame('Condition on Discharge Time', $observations[7]['resource']['category'][0]['text']);
|
||||
|
||||
// Verify Encounter period & location
|
||||
$encounters = array_values(array_filter($bundle['entry'], static fn (array $e): bool => ($e['resource']['resourceType'] ?? '') === 'Encounter'));
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user