Add new discharge template tokens: PATIENT_PHONE, INSURANCE_COMPANY, DOCTOR_NAMES

New placeholders added:

1. PATIENT_PHONE - Patient's phone number from patient_master.mphone1 or ipd_master.P_mobile1
   Example: 9876543210

2. INSURANCE_COMPANY - Insurance company name from ipd_master.ins_short_name or ins_company_name
   Example: Star Health Insurance
   Default: 'Direct' if no insurance

3. DOCTOR_NAMES / DOCTOR_NAME - Comma-separated list of treating doctors with specialties
   Example: Dr. Rajesh Kumar [General Medicine], Dr. Priya Sharma [Cardiology]
   Reads from ipd_master.doc_list field and joins with doctor_master and med_spec tables

Changes:
- Added getDischargeDoctorNames() helper function
- Updated buildDischargeSummaryTokenVars() to include three new tokens
- Updated DISCHARGE_TEMPLATE_GUIDE.md with new token documentation
- Added example template showing usage of new tokens
- Updated CI3 to CI4 migration mapping table

These tokens match the data shown in the auto-generated patient summary table
and allow templates to display this information in custom layouts.
This commit is contained in:
DevSoftTech Server 2026-06-06 12:21:37 +05:30
parent a8f09d007d
commit 3ad0025c24
2 changed files with 104 additions and 1 deletions

View File

@ -87,12 +87,26 @@ The CI4 discharge template system now **correctly matches** CI3 behavior where:
| `{{IPD_CODE}}` | IPD admission number | A26050000001 |
| `{{AGE_GENDER}}` | Age and gender | 26 Year / Female |
| `{{GUARDIAN}}` | Guardian relation and name | W/O of RAM SINGH |
| `{{GUARDIAN_RELATION}}` | Guardian relation only | W/O of |
| `{{GUARDIAN_NAME}}` | Guardian name only | RAM SINGH |
| `{{PATIENT_ADDRESS}}` | Full address | KASHIPUR, District, State |
| `{{PATIENT_PHONE}}` | Patient phone number | 9876543210 |
### IPD Information Tokens
| Token | Description | Example Output |
|-------|-------------|----------------|
| `{{DEPARTMENT}}` | Department name | General Medicine |
| `{{ADMIT_DATE}}` | Admission date | 23-05-2026 |
| `{{DISCHARGE_DATE}}` | Discharge date | 05-06-2026 |
| `{{ADMIT_DATE_ONLY}}` | Admission date (same as ADMIT_DATE) | 23-05-2026 |
| `{{DISCHARGE_DATE_ONLY}}` | Discharge date (same as DISCHARGE_DATE) | 05-06-2026 |
| `{{ADMISSION_TIME}}` | Admission time | 10:30 AM |
| `{{DISCHARGE_TIME}}` | Discharge time | 03:45 PM |
| `{{ADMIT_TIME}}` | Admission time (same as ADMISSION_TIME) | 10:30 AM |
| `{{INSURANCE_COMPANY}}` | Insurance company name | Star Health Insurance |
| `{{DOCTOR_NAMES}}` | Treating doctor(s) with specialties | Dr. Rajesh Kumar [General Medicine], Dr. Priya Sharma [Cardiology] |
| `{{DOCTOR_NAME}}` | Same as DOCTOR_NAMES | Dr. Rajesh Kumar [General Medicine] |
### Hospital Information Tokens
@ -197,6 +211,18 @@ The CI4 discharge template system now **correctly matches** CI3 behavior where:
<td><b>Discharge:</b></td>
<td>{{DISCHARGE_DATE}}</td>
</tr>
<tr>
<td><b>Phone:</b></td>
<td>{{PATIENT_PHONE}}</td>
<td><b>Insurance:</b></td>
<td>{{INSURANCE_COMPANY}}</td>
</tr>
<tr>
<td><b>Department:</b></td>
<td>{{DEPARTMENT}}</td>
<td><b>Doctor(s):</b></td>
<td>{{DOCTOR_NAMES}}</td>
</tr>
</table>
<hr>
@ -205,7 +231,7 @@ The CI4 discharge template system now **correctly matches** CI3 behavior where:
</div>
```
**Output:** Custom-styled discharge with full control over layout
**Output:** Custom-styled discharge with full control over layout, including phone, insurance, and doctor information
---
@ -318,6 +344,9 @@ The CI4 discharge template system now **correctly matches** CI3 behavior where:
| `$ipd_master[0]->p_code` | `{{UHID}}` |
| `$ipd_master[0]->ipd_code` | `{{IPD_CODE}}` |
| `$ipd_master[0]->str_age . ' / ' . $xgender` | `{{AGE_GENDER}}` |
| `$person->mphone1` | `{{PATIENT_PHONE}}` |
| `$ipd_master[0]->ins_company_name` | `{{INSURANCE_COMPANY}}` |
| `$doc_list_main_sign` (doctor names) | `{{DOCTOR_NAMES}}` |
| `$FinalDiagnosis` | `{{FINAL_DIAGNOSIS}}` |
| `$Surgery` | `{{SURGERY}}` |
| `$Procedure` | `{{PROCEDURE}}` |

View File

@ -444,17 +444,42 @@ class Ipd_discharge extends BaseController
$guardianCombined = $guardianName !== '' ? $guardianName : $guardianRelation;
}
// Patient phone number
$patientPhone = '';
if ($person) {
$patientPhone = trim((string) ($person->mphone1 ?? $person->phone ?? $person->contact_no ?? ''));
}
if ($patientPhone === '' && $ipd) {
$patientPhone = trim((string) ($ipd->P_mobile1 ?? $ipd->P_mobile2 ?? $ipd->contact_phone ?? ''));
}
// Insurance company name
$insuranceCompany = '';
if ($ipd) {
$insuranceCompany = trim((string) ($ipd->ins_short_name ?? $ipd->ins_company_name ?? ''));
if ($insuranceCompany === '') {
$insuranceCompany = 'Direct';
}
}
// Doctor names (from doc_list field in ipd_master)
$doctorNames = $this->getDischargeDoctorNames($ipd);
return [
'GUARDIAN_RELATION' => esc($guardianRelation !== '' ? $guardianRelation . ' of ' : ''),
'GUARDIAN_NAME' => esc($guardianName),
'GUARDIAN' => esc($guardianCombined),
'PATIENT_ADDRESS' => esc($address),
'PATIENT_PHONE' => esc($patientPhone),
'DEPARTMENT' => esc($this->getDischargeDepartmentName($ipd)),
'ADMIT_DATE_ONLY' => esc($this->safeDate((string) ($ipd->str_register_date ?? $ipd->register_date ?? ''))),
'DISCHARGE_DATE_ONLY' => esc($this->safeDate((string) ($ipd->str_discharge_date ?? $ipd->discharge_date ?? ''))),
'ADMISSION_TIME' => esc($this->safeTime((string) ($ipd->register_date ?? $ipd->register_time ?? $ipd->admission_time ?? $ipd->str_register_date ?? ''))),
'DISCHARGE_TIME' => esc($this->safeTime((string) ($ipd->discharge_date ?? $ipd->discharge_time ?? $ipd->str_discharge_date ?? ''))),
'ADMIT_TIME' => esc($this->safeTime((string) ($ipd->register_date ?? $ipd->register_time ?? $ipd->admission_time ?? $ipd->str_register_date ?? ''))),
'INSURANCE_COMPANY' => esc($insuranceCompany),
'DOCTOR_NAMES' => esc($doctorNames),
'DOCTOR_NAME' => esc($doctorNames),
];
}
@ -912,6 +937,55 @@ class Ipd_discharge extends BaseController
return 'user-' . (string) ($user->id ?? 0);
}
private function getDischargeDoctorNames($ipd): string
{
if (! $ipd) {
return '';
}
$docList = trim((string) ($ipd->doc_list ?? ''));
if ($docList === '' || $docList === '0') {
return '';
}
if (! $this->db->tableExists('doctor_master')) {
return '';
}
$docIds = array_filter(array_map('intval', explode(',', $docList)));
if (empty($docIds)) {
return '';
}
$doctors = $this->db->table('doctor_master d')
->select("d.id, d.p_fname, d.p_title, group_concat(distinct m.SpecName SEPARATOR ', ') as SpecName", false)
->join('doc_spec s', 'd.id = s.doc_id', 'left')
->join('med_spec m', 's.med_spec_id = m.id', 'left')
->whereIn('d.id', $docIds)
->groupBy('d.id')
->get()
->getResult();
if (empty($doctors)) {
return '';
}
$names = [];
foreach ($doctors as $doc) {
$title = trim((string) ($doc->p_title ?? ''));
$name = trim((string) ($doc->p_fname ?? ''));
$spec = trim((string) ($doc->SpecName ?? ''));
$fullName = ($title !== '' ? $title . ' ' : 'Dr. ') . $name;
if ($spec !== '') {
$fullName .= ' [' . $spec . ']';
}
$names[] = $fullName;
}
return implode(', ', $names);
}
private function saveDischargeContent(int $ipdId, string $content): bool
{
try {