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'] ?? '');
|
$remarks = (string) ($row['Prescriber_Remarks'] ?? '');
|
||||||
$nabh = $this->hydrateNabhPrescriptionFields($row, $remarks);
|
$nabh = $this->hydrateNabhPrescriptionFields($row, $remarks);
|
||||||
|
|
||||||
$complaintsText = trim((string) ($row['complaints'] ?? ''));
|
// Primary: use structured complaint_snomed_json (has SNOMED codes, severity, duration)
|
||||||
$complaints = [];
|
$complaints = [];
|
||||||
if ($complaintsText !== '') {
|
$snomedJson = trim((string) ($row['complaint_snomed_json'] ?? ''));
|
||||||
$parts = preg_split('/[,;\n\r]+/', $complaintsText) ?: [];
|
if ($snomedJson !== '' && $snomedJson !== '[]') {
|
||||||
$seen = [];
|
$items = json_decode($snomedJson, true);
|
||||||
foreach ($parts as $part) {
|
if (is_array($items)) {
|
||||||
$part = trim((string) $part);
|
$seen = [];
|
||||||
if ($part === '' || preg_match('/^Complaint\s*(Onset|Duration|Severity)\s*:/i', $part) === 1) {
|
foreach ($items as $item) {
|
||||||
continue;
|
$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[] = [
|
$complaintResource = [
|
||||||
'resource' => [
|
'resourceType' => 'Condition',
|
||||||
'resourceType' => 'Condition',
|
'id' => $complaintId,
|
||||||
'id' => $complaintId,
|
'clinicalStatus' => [
|
||||||
'clinicalStatus' => [
|
'coding' => [[
|
||||||
'coding' => [[
|
'system' => 'http://terminology.hl7.org/CodeSystem/condition-clinical',
|
||||||
'system' => 'http://terminology.hl7.org/CodeSystem/condition-clinical',
|
'code' => 'active',
|
||||||
'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',
|
|
||||||
]],
|
]],
|
||||||
'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) {
|
foreach ($observations as $index => $observation) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user