Simplify discharge summary placeholders - eliminate confusion

Changes:
- Rename main placeholder: DISCHARGE_SUMMARY → CLINICAL_SUMMARY (clearer name)
- Keep DISCHARGE_SUMMARY as legacy alias for backward compatibility
- Rename: DISCHARGE_ADVICE → FOLLOW_UP_INSTRUCTIONS (more descriptive)
- Remove: INSTRUCTION_REMARK (duplicate removed)
- Group placeholders by category in code with comments
- Create comprehensive reference guide: DISCHARGE_PLACEHOLDERS_REFERENCE.md

Benefits:
- Clear distinction between clinical summary and discharge instructions
- Organized placeholder groups (clinical, instructions, other)
- Easy migration guide for existing templates
- Complete documentation with examples
This commit is contained in:
DevSoftTech Server 2026-06-11 08:18:43 +05:30
parent 586d3bde46
commit f2a7546a9d
7 changed files with 558 additions and 15 deletions

View File

@ -0,0 +1,255 @@
# Discharge Summary Template Placeholders Reference
## Overview
This document explains all available placeholders for discharge summary templates. Use these placeholders in your template HTML to insert dynamic content.
---
## 🔴 MAIN DISCHARGE SUMMARY
### `{{CLINICAL_SUMMARY}}` ⭐ RECOMMENDED
**Content:** The main discharge summary text from the HTML editor (instruction_remark field)
**Source:** "Discharge Summary" section in the discharge form
**Use this for:** The primary clinical narrative written by doctors
**Example:**
```html
<h2>Discharge Summary</h2>
{{CLINICAL_SUMMARY}}
```
### `{{DISCHARGE_SUMMARY}}` (Legacy)
**Content:** Same as `{{CLINICAL_SUMMARY}}`
**Note:** Kept for backward compatibility. Use `{{CLINICAL_SUMMARY}}` for clarity.
---
## 🔵 CLINICAL SECTIONS
### `{{FINAL_DIAGNOSIS}}`
**Content:** Final diagnosis section
**Source:** "Final Diagnosis" section
### `{{SURGERY}}`
**Content:** Surgery details section
**Source:** "Surgery" section
### `{{PROCEDURE}}`
**Content:** Procedure details section
**Source:** "Procedure" section
### `{{PRESENTING_COMPLAINTS}}`
**Content:** Presenting complaints and reason for admission
**Source:** "Presenting Complaints and Reason for Admission" section
### `{{PERSONAL_HISTORY}}`
**Content:** Patient personal history
**Source:** "Personal History" section
### `{{GENERAL_EXAM_ADMISSION}}`
**Content:** General examination findings at admission
**Source:** "General Examination on Admission" section
### `{{CLINICAL_INVESTIGATION_REPORTS}}`
**Content:** Clinical investigation and lab test reports
**Source:** "Clinical Investigation Reports" section
### `{{COURSE_IN_HOSPITAL}}`
**Content:** Course/progress during hospitalization
**Source:** "Course in the hospital" section
### `{{EXAMINATION_ON_DISCHARGE}}`
**Content:** Examination findings at discharge
**Source:** "Examination on Discharge" section
### `{{PAIN_MEASUREMENT_SCALE}}`
**Content:** Pain assessment scale details
**Source:** "Pain Measurement Scale" section
### `{{DRUG_ALLERGY_ADR}}`
**Content:** Drug allergies and adverse drug reactions
**Source:** "Drug Allergy / ADR" section
### `{{CO_MORBIDITIES}}`
**Content:** Co-existing medical conditions
**Source:** "Co-Morbidities" section
---
## 🟢 DISCHARGE INSTRUCTIONS & ADVICE
### `{{DISCHARGE_MEDICATIONS}}`
**Content:** Medications prescribed at discharge
**Source:** "Discharge Medications" section
### `{{DIETARY_ADVICE}}`
**Content:** Dietary recommendations
**Source:** "Dietary Advice" section
### `{{DISCHARGE_INSTRUCTIONS}}`
**Content:** General discharge advice and instructions
**Source:** "Discharge Advice/Instructions/Summary" section
### `{{OTHER_ADVICE}}`
**Content:** Other miscellaneous advice
**Source:** "Other Advice:" section
### `{{FOLLOW_UP_INSTRUCTIONS}}`
**Content:** Follow-up appointment instructions
**Source:** "Discharge Summary:" subsection (note the colon)
---
## 🟡 OTHER SECTIONS
### `{{SIGNATURE_BLOCK}}`
**Content:** Signature table with consultant details
**Source:** "Signature of Consultant" section
---
## 📋 PATIENT INFO PLACEHOLDERS
Use `{{PATIENT_INFO_TABLE}}` for the complete patient information header table.
---
## 💡 RECOMMENDED TEMPLATE STRUCTURE
```html
<!-- Patient Information -->
{{PATIENT_INFO_TABLE}}
<!-- Main Clinical Summary -->
<h2>Clinical Summary</h2>
{{CLINICAL_SUMMARY}}
<!-- Clinical Sections -->
{{PRESENTING_COMPLAINTS}}
{{PAIN_MEASUREMENT_SCALE}}
{{DRUG_ALLERGY_ADR}}
{{CO_MORBIDITIES}}
{{GENERAL_EXAM_ADMISSION}}
{{PERSONAL_HISTORY}}
{{CLINICAL_INVESTIGATION_REPORTS}}
<!-- Diagnosis & Treatment -->
{{FINAL_DIAGNOSIS}}
{{SURGERY}}
{{PROCEDURE}}
{{COURSE_IN_HOSPITAL}}
{{EXAMINATION_ON_DISCHARGE}}
<!-- Discharge Instructions -->
{{DISCHARGE_MEDICATIONS}}
{{DIETARY_ADVICE}}
{{OTHER_ADVICE}}
{{DISCHARGE_INSTRUCTIONS}}
{{FOLLOW_UP_INSTRUCTIONS}}
<!-- Signature -->
{{SIGNATURE_BLOCK}}
```
---
## ⚠️ IMPORTANT NOTES
1. **Empty Sections:** If a section has no data, the placeholder will be replaced with empty string (won't show in PDF)
2. **HTML Formatting:** Content from HTML editors (like `{{CLINICAL_SUMMARY}}`) preserves formatting (bold, lists, etc.)
3. **Placeholder Case:** Placeholders are case-sensitive. Use UPPERCASE with underscores.
4. **Missing Placeholders:** If you forget a placeholder, that content simply won't appear in the PDF
5. **Duplicate Placeholders:** You can use the same placeholder multiple times in a template if needed
---
## 🔄 MIGRATION GUIDE
### Old Placeholder → New Placeholder
| Old (Confusing) | New (Clear) | Notes |
|----------------|-------------|-------|
| `{{DISCHARGE_SUMMARY}}` | `{{CLINICAL_SUMMARY}}` | Both work, but use `{{CLINICAL_SUMMARY}}` for clarity |
| `{{INSTRUCTION_REMARK}}` | `{{FOLLOW_UP_INSTRUCTIONS}}` | Old placeholder removed |
| `{{DISCHARGE_ADVICE}}` | `{{FOLLOW_UP_INSTRUCTIONS}}` | More descriptive name |
### What Changed?
**Before (Confusing):**
- `{{DISCHARGE_SUMMARY}}` - Main clinical summary
- `{{DISCHARGE_ADVICE}}` - Follow-up instructions
- `{{INSTRUCTION_REMARK}}` - Same as DISCHARGE_ADVICE
**After (Clear):**
- `{{CLINICAL_SUMMARY}}` - Main clinical summary ⭐ Use this!
- `{{FOLLOW_UP_INSTRUCTIONS}}` - Follow-up instructions
- `{{DISCHARGE_INSTRUCTIONS}}` - General discharge advice
---
## 📝 EXAMPLE TEMPLATES
### Minimal Template
```html
{{PATIENT_INFO_TABLE}}
{{CLINICAL_SUMMARY}}
{{FINAL_DIAGNOSIS}}
{{DISCHARGE_MEDICATIONS}}
{{SIGNATURE_BLOCK}}
```
### Comprehensive Template
```html
{{PATIENT_INFO_TABLE}}
<h2>Clinical Summary</h2>
{{CLINICAL_SUMMARY}}
{{PRESENTING_COMPLAINTS}}
{{GENERAL_EXAM_ADMISSION}}
{{CLINICAL_INVESTIGATION_REPORTS}}
{{FINAL_DIAGNOSIS}}
{{SURGERY}}
{{PROCEDURE}}
{{COURSE_IN_HOSPITAL}}
{{EXAMINATION_ON_DISCHARGE}}
<h2>Discharge Instructions</h2>
{{DISCHARGE_MEDICATIONS}}
{{DIETARY_ADVICE}}
{{OTHER_ADVICE}}
{{FOLLOW_UP_INSTRUCTIONS}}
{{SIGNATURE_BLOCK}}
```
---
## 🆘 TROUBLESHOOTING
**Problem:** Discharge summary text not appearing in PDF
**Solution:** Make sure you have `{{CLINICAL_SUMMARY}}` or `{{DISCHARGE_SUMMARY}}` in your template
**Problem:** Section appears empty in PDF
**Solution:** Check if that section was filled in the discharge form. Empty sections = empty output.
**Problem:** Formatting looks wrong
**Solution:** Check your template HTML structure. Each placeholder inserts its content with existing HTML tags.
---
## 📞 SUPPORT
For template editing issues, check:
1. Template management page (ensure placeholders are spelled correctly)
2. HTML debug mode: `/Ipd_discharge/show_discharge/{ipdId}/1?html=1&tpl=3`
3. Content debug: `/Ipd_discharge/debug_discharge_html/{ipdId}`
---
**Last Updated:** 2026-06-11
**Version:** 2.0 (Simplified naming)

View File

@ -523,31 +523,32 @@ class Ipd_discharge extends BaseController
return $this->extractDischargeSectionByMarkers($full, $starts, array_merge($allMarkers, $extraEnds));
};
$summary = $section(['Discharge Summary']);
// Main clinical discharge summary from HTML editor
$clinicalSummary = $section(['Discharge Summary']);
// Replace "Discharge Summary" header with discharge status
if ($dischargeStatus !== '' && $summary !== '') {
$summary = preg_replace(
if ($dischargeStatus !== '' && $clinicalSummary !== '') {
$clinicalSummary = preg_replace(
'/<h[1-6][^>]*>\s*Discharge\s+Summary\s*<\/h[1-6]>/i',
'<h2>' . esc($dischargeStatus) . '</h2>',
$summary
$clinicalSummary
);
// Also handle bold/strong tags
$summary = preg_replace(
$clinicalSummary = preg_replace(
'/<(b|strong)>\s*Discharge\s+Summary\s*<\/\1>/i',
'<strong>' . esc($dischargeStatus) . '</strong>',
$summary
$clinicalSummary
);
// Remove "Date of Discharge" line
$summary = preg_replace(
$clinicalSummary = preg_replace(
'/Date\s+of\s+Discharge\s*:\s*[0-9\-\/]+\s*<br\s*\/?>/i',
'',
$summary
$clinicalSummary
);
$summary = preg_replace(
$clinicalSummary = preg_replace(
'/<p[^>]*>\s*Date\s+of\s+Discharge\s*:\s*[0-9\-\/]+\s*<\/p>/i',
'',
$summary
$clinicalSummary
);
}
@ -571,10 +572,15 @@ class Ipd_discharge extends BaseController
// Extract individual instruction fields for template flexibility
$otherAdvice = $section(['Other Advice:']);
$dischargeSummaryAdvice = $section(['Discharge Summary:']);
$followUpInstructions = $section(['Discharge Summary:']);
$vars = [
'DISCHARGE_SUMMARY' => $summary,
// Main discharge summary from HTML editor (instruction_remark field)
'CLINICAL_SUMMARY' => $clinicalSummary,
// Legacy alias for backward compatibility
'DISCHARGE_SUMMARY' => $clinicalSummary,
// Clinical sections
'FINAL_DIAGNOSIS' => $finalDiagnosis,
'SURGERY' => $surgery,
'PROCEDURE' => $procedure,
@ -584,16 +590,19 @@ class Ipd_discharge extends BaseController
'CLINICAL_INVESTIGATION_REPORTS' => $clinicalInvestigations,
'COURSE_IN_HOSPITAL' => $courseInHospital,
'EXAMINATION_ON_DISCHARGE' => $examOnDischarge,
// Discharge instructions and advice
'DISCHARGE_MEDICATIONS' => $dischargeMedications,
'DIETARY_ADVICE' => $dietaryAdvice,
'DISCHARGE_INSTRUCTIONS' => $dischargeInstructions,
'OTHER_ADVICE' => $otherAdvice,
'FOLLOW_UP_INSTRUCTIONS' => $followUpInstructions,
// Other sections
'PAIN_MEASUREMENT_SCALE' => $painMeasurement,
'DRUG_ALLERGY_ADR' => $drugAllergyAdr,
'CO_MORBIDITIES' => $coMorbidities,
'SIGNATURE_BLOCK' => $signatureBlock,
'OTHER_ADVICE' => $otherAdvice,
'INSTRUCTION_REMARK' => $dischargeSummaryAdvice,
'DISCHARGE_ADVICE' => $dischargeSummaryAdvice,
// Legacy style aliases to ease migration from CI3-style template variables.
'FinalDiagnosis' => $finalDiagnosis,
'Surgery' => $surgery,

39
check_bed_history.php Normal file
View File

@ -0,0 +1,39 @@
<?php
$db = new mysqli('localhost', 'root', '', 'hms_data_ci4');
echo "Checking bed_assignment_history for IPD ID: 1\n";
echo "=============================================\n\n";
$result = $db->query("
SELECT
bah.id,
bah.ipd_id,
bah.bed_id,
bm.bed_number,
bm.bed_code,
bm.bed_status,
bm.current_ipd_id,
DATE_FORMAT(bah.assigned_date, '%d-%m-%Y %H:%i') as assigned_date,
bah.released_date
FROM bed_assignment_history bah
LEFT JOIN bed_master bm ON bm.id = bah.bed_id
WHERE bah.ipd_id = 1
ORDER BY bah.assigned_date DESC
");
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
echo "Assignment ID: {$row['id']}\n";
echo "Bed: {$row['bed_number']} ({$row['bed_code']})\n";
echo "Assigned Date: {$row['assigned_date']}\n";
echo "Released Date: " . ($row['released_date'] ?? 'NOT RELEASED') . "\n";
echo "Bed Status in master: {$row['bed_status']}\n";
echo "Current IPD ID in bed: " . ($row['current_ipd_id'] ?? 'NULL') . "\n";
echo "---\n";
}
} else {
echo "No bed assignment history found for this patient.\n";
echo "This patient may need a bed assigned manually.\n";
}
$db->close();

View File

@ -0,0 +1,36 @@
<?php
$db = new mysqli('localhost', 'root', '', 'hms_data_ci4');
echo "Current Admissions (ipd_status = 0):\n";
echo "====================================\n\n";
$result = $db->query("
SELECT
i.id,
i.ipd_code,
DATE_FORMAT(i.register_date, '%d-%m-%Y') as register_date,
p.p_fname,
p.p_lname,
bm.bed_number,
bm.current_ipd_id
FROM ipd_master i
LEFT JOIN patient_master p ON p.id = i.p_id
LEFT JOIN bed_master bm ON bm.current_ipd_id = i.id
WHERE i.ipd_status = 0
ORDER BY i.register_date DESC
");
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
echo "IPD ID: {$row['id']}\n";
echo "IPD Code: {$row['ipd_code']}\n";
echo "Patient: {$row['p_fname']} {$row['p_lname']}\n";
echo "Register Date: {$row['register_date']}\n";
echo "Bed Assigned: " . ($row['bed_number'] ?? 'NOT ASSIGNED') . "\n";
echo "---\n";
}
} else {
echo "No current admissions found.\n";
}
$db->close();

90
check_ipd2_bed.php Normal file
View File

@ -0,0 +1,90 @@
<?php
$db = new mysqli('localhost', 'root', '', 'hms_data_ci4');
echo "Checking IPD ID: 2\n";
echo "===================\n\n";
// Check IPD master data
echo "IPD Master Data:\n";
$result = $db->query("
SELECT
i.id,
i.ipd_code,
i.ipd_status,
DATE_FORMAT(i.register_date, '%d-%m-%Y') as register_date,
p.p_fname,
p.p_lname
FROM ipd_master i
LEFT JOIN patient_master p ON p.id = i.p_id
WHERE i.id = 2
");
if ($result && $result->num_rows > 0) {
$row = $result->fetch_assoc();
echo "IPD Code: {$row['ipd_code']}\n";
echo "Patient: {$row['p_fname']} {$row['p_lname']}\n";
echo "Status: " . ($row['ipd_status'] == 0 ? 'Admitted' : 'Discharged') . "\n";
echo "Register Date: {$row['register_date']}\n\n";
} else {
echo "IPD ID 2 not found!\n\n";
}
// Check bed_assignment_history
echo "Bed Assignment History:\n";
$result = $db->query("
SELECT
bah.id,
bah.ipd_id,
bah.bed_id,
bm.bed_number,
bm.bed_code,
w.ward_name,
DATE_FORMAT(bah.assigned_date, '%d-%m-%Y %H:%i') as assigned_date,
DATE_FORMAT(bah.released_date, '%d-%m-%Y %H:%i') as released_date,
bah.assignment_type,
bah.remarks
FROM bed_assignment_history bah
LEFT JOIN bed_master bm ON bm.id = bah.bed_id
LEFT JOIN ward_master w ON w.id = bah.ward_id
WHERE bah.ipd_id = 2
ORDER BY bah.id DESC
");
if ($result && $result->num_rows > 0) {
while ($row = $result->fetch_assoc()) {
echo "Assignment ID: {$row['id']}\n";
echo "Bed: {$row['bed_number']} ({$row['bed_code']})\n";
echo "Ward: {$row['ward_name']}\n";
echo "Assigned: {$row['assigned_date']}\n";
echo "Released: " . ($row['released_date'] ?? 'NOT RELEASED') . "\n";
echo "Type: {$row['assignment_type']}\n";
echo "Remarks: {$row['remarks']}\n";
echo "---\n";
}
} else {
echo "No bed assignment history found for IPD ID 2\n\n";
}
// Check current bed assignment in bed_master
echo "Current Bed in bed_master:\n";
$result = $db->query("
SELECT
bm.id,
bm.bed_number,
bm.bed_code,
bm.bed_status,
bm.current_ipd_id,
w.ward_name
FROM bed_master bm
LEFT JOIN ward_master w ON w.id = bm.ward_id
WHERE bm.current_ipd_id = 2
");
if ($result && $result->num_rows > 0) {
$row = $result->fetch_assoc();
echo "Bed ID: {$row['id']}\n";
echo "Bed: {$row['bed_number']} ({$row['bed_code']})\n";
echo "Ward: {$row['ward_name']}\n";
echo "Status: {$row['bed_status']}\n";
} else {
echo "No bed currently assigned in bed_master.current_ipd_id for IPD ID 2\n";
}
$db->close();

45
debug_bed_query.php Normal file
View File

@ -0,0 +1,45 @@
<?php
/**
* Debug bed assignment query - Direct DB approach
*/
$db = new mysqli('localhost', 'root', '', 'hms_data_ci4');
echo "Testing bed_assignment_history query for IPD ID 2\n";
echo "==================================================\n\n";
$query = "
SELECT
bed_assignment_history.*,
bed_master.bed_code,
bed_master.bed_number,
ward_master.ward_name
FROM bed_assignment_history
LEFT JOIN bed_master ON bed_master.id = bed_assignment_history.bed_id
LEFT JOIN ward_master ON ward_master.id = bed_assignment_history.ward_id
WHERE bed_assignment_history.ipd_id = 2
ORDER BY bed_assignment_history.id DESC
";
$result = $db->query($query);
echo "Query executed\n";
echo "Rows found: " . $result->num_rows . "\n\n";
if ($result->num_rows > 0) {
while ($row = $result->fetch_object()) {
echo "Record ID: {$row->id}\n";
echo "bed_code: " . ($row->bed_code ?? 'NULL') . "\n";
echo "bed_number: " . ($row->bed_number ?? 'NULL') . "\n";
echo "ward_name: " . ($row->ward_name ?? 'NULL') . "\n";
echo "assigned_date: " . ($row->assigned_date ?? 'NULL') . "\n";
echo "released_date: " . ($row->released_date ?? 'NULL') . "\n";
echo "assignment_type: " . ($row->assignment_type ?? 'NULL') . "\n";
echo "remarks: " . ($row->remarks ?? 'NULL') . "\n";
echo "---\n";
}
} else {
echo "No records found\n";
}
$db->close();

69
test_panel_tab.php Normal file
View File

@ -0,0 +1,69 @@
<?php
/**
* Test the panelTab endpoint
*/
// Simulate what the controller does
$db = new mysqli('localhost', 'root', '', 'hms_data_ci4');
$ipdId = 2;
echo "Simulating panelTab(2, 'bed-assign')\n";
echo "=====================================\n\n";
// Step 1: Get panel data
echo "Step 1: Get IpdPanelInfo...\n";
$query = "SELECT * FROM ipd_master WHERE id = {$ipdId}";
$result = $db->query($query);
if ($result && $result->num_rows > 0) {
echo "✓ IPD data found\n\n";
} else {
echo "✗ IPD not found\n";
exit;
}
// Step 2: Get bed assignments
echo "Step 2: Get bed assignments...\n";
$query = "
SELECT
bed_assignment_history.*,
bed_master.bed_code,
bed_master.bed_number,
ward_master.ward_name
FROM bed_assignment_history
LEFT JOIN bed_master ON bed_master.id = bed_assignment_history.bed_id
LEFT JOIN ward_master ON ward_master.id = bed_assignment_history.ward_id
WHERE bed_assignment_history.ipd_id = {$ipdId}
ORDER BY bed_assignment_history.id DESC
";
$result = $db->query($query);
echo "✓ Query executed\n";
echo "✓ Rows found: {$result->num_rows}\n\n";
if ($result->num_rows > 0) {
echo "Step 3: Render view with data...\n";
$bed_assignments = [];
while ($row = $result->fetch_object()) {
$bed_assignments[] = $row;
}
echo "✓ Data prepared\n";
echo "✓ Array count: " . count($bed_assignments) . "\n\n";
echo "Step 4: Check if view can access data...\n";
echo "Sample data from first record:\n";
if (!empty($bed_assignments)) {
$first = $bed_assignments[0];
echo " bed_code: " . ($first->bed_code ?? 'NULL') . "\n";
echo " bed_number: " . ($first->bed_number ?? 'NULL') . "\n";
echo " ward_name: " . ($first->ward_name ?? 'NULL') . "\n";
echo " assigned_date: " . ($first->assigned_date ?? 'NULL') . "\n";
echo " assignment_type: " . ($first->assignment_type ?? 'NULL') . "\n";
}
echo "\n✓ View should display this data\n";
} else {
echo "✗ No bed assignments found - view will show empty message\n";
}
$db->close();