feat: FHIR bundle — use complaint_snomed_json for coded complaints (SNOMED + severity + duration)
This commit is contained in:
parent
0dd6a18167
commit
cd18551ce2
|
|
@ -9587,22 +9587,59 @@ class Opd_prescription extends BaseController
|
|||
$remarks = (string) ($row['Prescriber_Remarks'] ?? '');
|
||||
$nabh = $this->hydrateNabhPrescriptionFields($row, $remarks);
|
||||
|
||||
$complaintsText = trim((string) ($row['complaints'] ?? ''));
|
||||
// Primary: use structured complaint_snomed_json (has SNOMED codes, severity, duration)
|
||||
$complaints = [];
|
||||
if ($complaintsText !== '') {
|
||||
$parts = preg_split('/[,;\n\r]+/', $complaintsText) ?: [];
|
||||
$seen = [];
|
||||
foreach ($parts as $part) {
|
||||
$part = trim((string) $part);
|
||||
if ($part === '' || preg_match('/^Complaint\s*(Onset|Duration|Severity)\s*:/i', $part) === 1) {
|
||||
continue;
|
||||
$snomedJson = trim((string) ($row['complaint_snomed_json'] ?? ''));
|
||||
if ($snomedJson !== '' && $snomedJson !== '[]') {
|
||||
$items = json_decode($snomedJson, true);
|
||||
if (is_array($items)) {
|
||||
$seen = [];
|
||||
foreach ($items as $item) {
|
||||
$text = trim((string) ($item['term'] ?? ''));
|
||||
if ($text === '') {
|
||||
continue;
|
||||
}
|
||||
$k = strtoupper($text);
|
||||
if (isset($seen[$k])) {
|
||||
continue;
|
||||
}
|
||||
$seen[$k] = true;
|
||||
$complaints[] = [
|
||||
'text' => $text,
|
||||
'snomed_code' => trim((string) ($item['concept_id'] ?? '')),
|
||||
'snomed_display' => $text,
|
||||
'severity' => trim((string) ($item['severity'] ?? '')),
|
||||
'duration' => trim((string) ($item['duration'] ?? '')),
|
||||
'frequency' => trim((string) ($item['frequency'] ?? '')),
|
||||
];
|
||||
}
|
||||
$k = strtoupper($part);
|
||||
if (isset($seen[$k])) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// Fallback: plain-text complaints field
|
||||
if (empty($complaints)) {
|
||||
$complaintsText = trim((string) ($row['complaints'] ?? ''));
|
||||
if ($complaintsText !== '') {
|
||||
$parts = preg_split('/[,;\n\r]+/', $complaintsText) ?: [];
|
||||
$seen = [];
|
||||
foreach ($parts as $part) {
|
||||
$part = trim((string) $part);
|
||||
if ($part === '' || preg_match('/^Complaint\s*(Onset|Duration|Severity)\s*:/i', $part) === 1) {
|
||||
continue;
|
||||
}
|
||||
$k = strtoupper($part);
|
||||
if (isset($seen[$k])) {
|
||||
continue;
|
||||
}
|
||||
$seen[$k] = true;
|
||||
$complaints[] = [
|
||||
'text' => $part,
|
||||
'snomed_code' => '',
|
||||
'snomed_display' => $part,
|
||||
'severity' => '',
|
||||
'duration' => '',
|
||||
'frequency' => '',
|
||||
];
|
||||
}
|
||||
$seen[$k] = true;
|
||||
$complaints[] = ['text' => $part];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -185,35 +185,66 @@ class FhirR4Builder
|
|||
]];
|
||||
}
|
||||
|
||||
$entries[] = [
|
||||
'resource' => [
|
||||
'resourceType' => 'Condition',
|
||||
'id' => $complaintId,
|
||||
'clinicalStatus' => [
|
||||
'coding' => [[
|
||||
'system' => 'http://terminology.hl7.org/CodeSystem/condition-clinical',
|
||||
'code' => 'active',
|
||||
]],
|
||||
],
|
||||
'verificationStatus' => [
|
||||
'coding' => [[
|
||||
'system' => 'http://terminology.hl7.org/CodeSystem/condition-ver-status',
|
||||
'code' => 'unconfirmed',
|
||||
]],
|
||||
],
|
||||
'category' => [[
|
||||
'coding' => [[
|
||||
'system' => 'http://terminology.hl7.org/CodeSystem/condition-category',
|
||||
'code' => 'problem-list-item',
|
||||
]],
|
||||
'text' => 'Chief Complaint',
|
||||
$complaintResource = [
|
||||
'resourceType' => 'Condition',
|
||||
'id' => $complaintId,
|
||||
'clinicalStatus' => [
|
||||
'coding' => [[
|
||||
'system' => 'http://terminology.hl7.org/CodeSystem/condition-clinical',
|
||||
'code' => 'active',
|
||||
]],
|
||||
'code' => $code,
|
||||
'subject' => ['reference' => $patientRef],
|
||||
'encounter' => ['reference' => $encounterRef],
|
||||
'recordedDate' => $issuedAt,
|
||||
],
|
||||
'verificationStatus' => [
|
||||
'coding' => [[
|
||||
'system' => 'http://terminology.hl7.org/CodeSystem/condition-ver-status',
|
||||
'code' => 'unconfirmed',
|
||||
]],
|
||||
],
|
||||
'category' => [[
|
||||
'coding' => [[
|
||||
'system' => 'http://terminology.hl7.org/CodeSystem/condition-category',
|
||||
'code' => 'problem-list-item',
|
||||
]],
|
||||
'text' => 'Chief Complaint',
|
||||
]],
|
||||
'code' => $code,
|
||||
'subject' => ['reference' => $patientRef],
|
||||
'encounter' => ['reference' => $encounterRef],
|
||||
'recordedDate' => $issuedAt,
|
||||
];
|
||||
|
||||
// Severity (High/Moderate/Low → SNOMED coded)
|
||||
$severityText = trim((string) ($complaint['severity'] ?? ''));
|
||||
if ($severityText !== '') {
|
||||
$severityMap = [
|
||||
'high' => ['24484000', 'Severe'],
|
||||
'severe' => ['24484000', 'Severe'],
|
||||
'moderate' => ['6736007', 'Moderate'],
|
||||
'mild' => ['255604002', 'Mild'],
|
||||
'low' => ['255604002', 'Mild'],
|
||||
];
|
||||
$severityKey = strtolower($severityText);
|
||||
[$sevCode, $sevDisplay] = $severityMap[$severityKey] ?? ['', $severityText];
|
||||
$severityCoding = ['text' => ucfirst($severityText)];
|
||||
if ($sevCode !== '') {
|
||||
$severityCoding['coding'] = [[
|
||||
'system' => 'http://snomed.info/sct',
|
||||
'code' => $sevCode,
|
||||
'display' => $sevDisplay,
|
||||
]];
|
||||
}
|
||||
$complaintResource['severity'] = $severityCoding;
|
||||
}
|
||||
|
||||
// Duration → note
|
||||
$durationText = trim((string) ($complaint['duration'] ?? ''));
|
||||
$frequencyText = trim((string) ($complaint['frequency'] ?? ''));
|
||||
$noteParts = array_filter([$durationText, $frequencyText]);
|
||||
if (! empty($noteParts)) {
|
||||
$complaintResource['note'] = [['text' => implode(' | ', $noteParts)]];
|
||||
}
|
||||
|
||||
$entries[] = ['resource' => $complaintResource];
|
||||
}
|
||||
|
||||
foreach ($observations as $index => $observation) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user