diff --git a/app/Controllers/AbdmGateway.php b/app/Controllers/AbdmGateway.php index da43343..a8f615a 100644 --- a/app/Controllers/AbdmGateway.php +++ b/app/Controllers/AbdmGateway.php @@ -3586,6 +3586,70 @@ class AbdmGateway extends BaseController ]; } + // Dietary Advice from food_ids + $foodIds = is_array($instructionMeta['food_ids'] ?? null) ? ($instructionMeta['food_ids'] ?? []) : []; + if (empty($foodIds) && $this->db && $this->db->tableExists('ipd_discharge_drug_food_interaction')) { + try { + $legacyFoodRow = $this->db->table('ipd_discharge_drug_food_interaction')->where('ipd_id', $ipdId)->get(1)->getRowArray(); + if (! empty($legacyFoodRow['food_id_list'])) { + $foodIds = array_filter(array_map('intval', explode(',', (string) $legacyFoodRow['food_id_list']))); + } + } catch (\Throwable $e) { + } + } + if (! empty($foodIds) && $this->db && $this->db->tableExists('ipd_discharge_master_food')) { + try { + $foodRows = $this->db->table('ipd_discharge_master_food') + ->select('id,food_short,food_desc,food_desc_lang') + ->whereIn('id', array_map('intval', $foodIds)) + ->get() + ->getResultArray(); + $dietParts = []; + foreach ($foodRows as $fRow) { + $heading = trim((string) ($fRow['food_short'] ?? '')); + $line = trim((string) ($fRow['food_desc_lang'] ?? '')); + if ($line === '') { + $line = trim((string) ($fRow['food_desc'] ?? '')); + } + if ($heading !== '' && $line !== '') { + $dietParts[] = $heading . ': ' . $line; + } elseif ($line !== '') { + $dietParts[] = $line; + } elseif ($heading !== '') { + $dietParts[] = $heading; + } + } + if (! empty($dietParts)) { + $carePlans[] = [ + 'title' => 'Dietary Advice', + 'description' => implode("\n", $dietParts), + 'created_at' => $this->toIsoDateTimeOrNow($dischargeRaw), + ]; + } + } catch (\Throwable $e) { + } + } + + // Other Advice + $otherText = trim((string) ($instructionMeta['other_text'] ?? '')); + if ($otherText !== '') { + $carePlans[] = [ + 'title' => 'Other Advice', + 'description' => strip_tags($otherText), + 'created_at' => $this->toIsoDateTimeOrNow($dischargeRaw), + ]; + } + + // Discharge Instructions / Remarks + $compRemark = trim((string) ($instructionRow['comp_remark'] ?? '')); + if ($compRemark !== '') { + $carePlans[] = [ + 'title' => 'Discharge Instructions', + 'description' => strip_tags($compRemark), + 'created_at' => $this->toIsoDateTimeOrNow($dischargeRaw), + ]; + } + $reviewAfter = trim((string) ($instructionRow['review_after'] ?? '')); if ($reviewAfter !== '') { $reviewDate = ''; @@ -3695,9 +3759,19 @@ class AbdmGateway extends BaseController 'room' => (string) ($locationInfo['room'] ?? ''), 'bed' => (string) ($locationInfo['bed'] ?? ''), ], + 'ui_complaints' => $chiefComplaints, + 'ui_complaint_narrative' => $chiefComplaintNarrative, + 'ui_final_diagnosis' => $diagnoses, + 'ui_clinical_history' => $diagnosisNarrative, + 'ui_physical_exam' => $observations, + 'ui_investigations' => $investigations, + 'ui_surgeries' => $procedures, + 'ui_discharge_medicine' => $medications, + 'ui_discharge_summary' => $carePlans, 'chief_complaints' => $chiefComplaints, 'chief_complaint_narrative' => $chiefComplaintNarrative, 'diagnoses' => $diagnoses, + 'conditions' => $diagnoses, 'diagnosis_narrative' => $diagnosisNarrative, 'procedures' => $procedures, 'medications' => $medications, @@ -3846,13 +3920,14 @@ class AbdmGateway extends BaseController $abdmTemplate = $this->resolveAbdmDischargeTemplate(); $abdmTemplateId = (int) ($abdmTemplate['id'] ?? 0); + $generatedBinary = null; try { $dischargeCtrl = new \App\Controllers\Ipd_discharge(); $request = \Config\Services::request(); $response = \Config\Services::response(); $logger = \Config\Services::logger(); $dischargeCtrl->initController($request, $response, $logger); - $dischargeCtrl->generateDischargeSummaryPdfBinary($ipdId, true, $abdmTemplateId > 0 ? $abdmTemplateId : null); + $generatedBinary = $dischargeCtrl->generateDischargeSummaryPdfBinary($ipdId, true, $abdmTemplateId > 0 ? $abdmTemplateId : null); } catch (\Throwable $e) { log_message('error', 'Auto-generating IPD Discharge Summary PDF failed for IPD {ipd}: {msg}', [ 'ipd' => $ipdId, @@ -3873,10 +3948,9 @@ class AbdmGateway extends BaseController foreach ($definitions as $definition) { $path = $directory . DIRECTORY_SEPARATOR . $definition['file']; - if (! is_file($path) || filesize($path) === 0) { - continue; - } - $binary = file_get_contents($path); + $binary = ($definition['file'] === 'discharge-summary.pdf' && is_string($generatedBinary) && str_starts_with($generatedBinary, '%PDF-')) + ? $generatedBinary + : (is_file($path) ? file_get_contents($path) : null); if (! is_string($binary) || ! str_starts_with($binary, '%PDF-')) { continue; } diff --git a/app/Controllers/Ipd_discharge.php b/app/Controllers/Ipd_discharge.php index 0393f80..a909a42 100644 --- a/app/Controllers/Ipd_discharge.php +++ b/app/Controllers/Ipd_discharge.php @@ -9019,8 +9019,9 @@ class Ipd_discharge extends BaseController $abdmTemplate = $this->resolveAbdmDischargeTemplate(); $abdmTemplateId = (int) ($abdmTemplate['id'] ?? 0); + $generatedBinary = null; try { - $this->generateDischargeSummaryPdfBinary($ipdId, true, $abdmTemplateId > 0 ? $abdmTemplateId : null); + $generatedBinary = $this->generateDischargeSummaryPdfBinary($ipdId, true, $abdmTemplateId > 0 ? $abdmTemplateId : null); } catch (\Throwable $e) { log_message('error', 'Auto-generating IPD Discharge Summary PDF failed for IPD {ipd}: {msg}', [ 'ipd' => $ipdId, @@ -9041,10 +9042,9 @@ class Ipd_discharge extends BaseController foreach ($definitions as $definition) { $path = $directory . DIRECTORY_SEPARATOR . $definition['file']; - if (! is_file($path) || filesize($path) === 0) { - continue; - } - $binary = file_get_contents($path); + $binary = ($definition['file'] === 'discharge-summary.pdf' && is_string($generatedBinary) && str_starts_with($generatedBinary, '%PDF-')) + ? $generatedBinary + : (is_file($path) ? file_get_contents($path) : null); if (! is_string($binary) || ! str_starts_with($binary, '%PDF-')) { continue; } @@ -9597,6 +9597,62 @@ class Ipd_discharge extends BaseController ]; } + // Dietary Advice from food_ids + $foodIds = is_array($instructionMeta['food_ids'] ?? null) ? ($instructionMeta['food_ids'] ?? []) : []; + if (empty($foodIds) && $this->tableHasColumns('ipd_discharge_drug_food_interaction', ['ipd_id', 'food_id_list'])) { + $legacyFoodRow = $this->firstRowByIpd('ipd_discharge_drug_food_interaction', $ipdId); + $foodIds = $this->parseFoodIdCsv((string) ($legacyFoodRow['food_id_list'] ?? '')); + } + if (! empty($foodIds) && $this->tableHasColumns('ipd_discharge_master_food', ['id', 'food_short', 'food_desc'])) { + $foodRows = $this->db->table('ipd_discharge_master_food') + ->select('id,food_short,food_desc,food_desc_lang') + ->whereIn('id', array_map('intval', $foodIds)) + ->get() + ->getResultArray(); + $dietParts = []; + foreach ($foodRows as $fRow) { + $heading = trim((string) ($fRow['food_short'] ?? '')); + $line = trim((string) ($fRow['food_desc_lang'] ?? '')); + if ($line === '') { + $line = trim((string) ($fRow['food_desc'] ?? '')); + } + if ($heading !== '' && $line !== '') { + $dietParts[] = $heading . ': ' . $line; + } elseif ($line !== '') { + $dietParts[] = $line; + } elseif ($heading !== '') { + $dietParts[] = $heading; + } + } + if (! empty($dietParts)) { + $carePlanRows[] = [ + 'title' => 'Dietary Advice', + 'description' => implode("\n", $dietParts), + 'created_at' => $dischargeIso, + ]; + } + } + + // Other Advice + $otherText = trim((string) ($instructionMeta['other_text'] ?? '')); + if ($otherText !== '') { + $carePlanRows[] = [ + 'title' => 'Other Advice', + 'description' => strip_tags($otherText), + 'created_at' => $dischargeIso, + ]; + } + + // Discharge Instructions / Remarks + $compRemark = trim((string) ($instructionRow['comp_remark'] ?? '')); + if ($compRemark !== '') { + $carePlanRows[] = [ + 'title' => 'Discharge Instructions', + 'description' => strip_tags($compRemark), + 'created_at' => $dischargeIso, + ]; + } + $reviewAfter = trim((string) ($instructionRow['review_after'] ?? '')); if ($reviewAfter !== '') { $reviewDate = ''; @@ -9773,7 +9829,17 @@ class Ipd_discharge extends BaseController 'ui_course_treatment' => $courseRows, 'ui_course_treatment_narrative' => $courseRemark, 'ui_discharge_medicine' => $medicationRows, + 'ui_discharge_summary' => $carePlanRows, + 'chief_complaints' => $chiefComplaintsList, + 'chief_complaint_narrative' => $complaintRemarkText, + 'diagnoses' => $conditionRows, + 'conditions' => $conditionRows, + 'diagnosis_narrative' => $uiClinicalHistoryText, + 'procedures' => $procedureRows, + 'medications' => $medicationRows, + 'observations' => $observationRows, 'allergies' => $allergyRows, + 'care_plans' => $carePlanRows, 'documents' => $documentsList, 'template' => $this->resolveAbdmDischargeTemplate(), ]; diff --git a/app/Libraries/Abdm/Fhir/Generators/DischargeFhirGenerator.php b/app/Libraries/Abdm/Fhir/Generators/DischargeFhirGenerator.php index 5408fb4..529d37a 100644 --- a/app/Libraries/Abdm/Fhir/Generators/DischargeFhirGenerator.php +++ b/app/Libraries/Abdm/Fhir/Generators/DischargeFhirGenerator.php @@ -230,12 +230,16 @@ class DischargeFhirGenerator extends \App\Libraries\Abdm\Fhir\Generators\Abstrac // ── Discharge Medications ─────────────────────────────────────────────── - foreach ((array) ($source['ui_discharge_medicine'] ?? $source['medications'] ?? []) as $idx => $med) { - $name = trim((string) ($med['name'] ?? '')); - if (! $this->isMeaningfulValue($name)) { - continue; + $rawMeds = ! empty($source['medications']) ? (array) $source['medications'] : (array) ($source['ui_discharge_medicine'] ?? []); + $validMeds = []; + foreach ($rawMeds as $med) { + if (is_array($med) && $this->isMeaningfulValue((string) ($med['name'] ?? ''))) { + $validMeds[] = $med; } + } + foreach ($validMeds as $idx => $med) { + $name = trim((string) ($med['name'] ?? '')); $medCode = trim((string) ($med['code'] ?? '')); $medCoding = []; if ($medCode !== '' && $this->isMeaningfulValue($medCode)) { @@ -442,7 +446,11 @@ class DischargeFhirGenerator extends \App\Libraries\Abdm\Fhir\Generators\Abstrac // ── Care Plans / Discharge Advice & Hospital Course ──────────────────── - $carePlansList = (array) ($source['ui_discharge_summary'] ?? $source['care_plans'] ?? []); + $rawCarePlans = array_merge( + (array) ($source['care_plans'] ?? []), + (array) ($source['ui_discharge_summary'] ?? []), + (array) ($source['ui_care_plans'] ?? []) + ); // Include hospital course / course of treatment if provided $courseItems = (array) ($source['ui_course_treatment'] ?? $source['course_treatment'] ?? []); @@ -458,18 +466,37 @@ class DischargeFhirGenerator extends \App\Libraries\Abdm\Fhir\Generators\Abstrac $courseParts[] = $courseNarrative; } if (! empty($courseParts)) { - $carePlansList[] = [ + $rawCarePlans[] = [ 'title' => 'Course of Treatment in Hospital', 'description' => implode("\n", array_unique($courseParts)), ]; } - foreach ($carePlansList as $idx => $cp) { + $validCarePlans = []; + $seenCp = []; + foreach ($rawCarePlans as $cp) { + if (! is_array($cp)) { + continue; + } $title = $this->cleanPlainText((string) ($cp['title'] ?? 'Discharge Advice')); $description = $this->cleanPlainText((string) ($cp['description'] ?? '')); if (! $this->isMeaningfulValue($description)) { continue; } + $key = $title . '|' . $description; + if (isset($seenCp[$key])) { + continue; + } + $seenCp[$key] = true; + $validCarePlans[] = [ + 'title' => $title !== '' ? $title : 'Discharge Advice', + 'description' => $description, + ]; + } + + foreach ($validCarePlans as $idx => $cp) { + $title = $cp['title']; + $description = $cp['description']; $carePlanResource = [ 'resourceType' => 'CarePlan', @@ -477,11 +504,11 @@ class DischargeFhirGenerator extends \App\Libraries\Abdm\Fhir\Generators\Abstrac 'meta' => ['profile' => ['https://nrces.in/ndhm/fhir/r4/StructureDefinition/CarePlan']], 'text' => [ 'status' => 'generated', - 'div' => '
' . htmlspecialchars($title !== '' ? $title : 'Discharge Advice') . ': ' . htmlspecialchars($description) . '
' . htmlspecialchars($title) . ': ' . htmlspecialchars($description) . '