From 3f1e89d4be5a9db142b2dd78804b62560dea622b Mon Sep 17 00:00:00 2001 From: DevSoftTech Server Date: Wed, 23 Sep 2026 10:12:42 +0530 Subject: [PATCH] Fix IPD patient admit search error, add admission type filters to IPD patient list, remove redundant sidebar links, and add OPD Day Care template support --- app/Config/Routes.php | 6 + app/Controllers/Billing/Ipd.php | 10 +- app/Controllers/IpdPatient.php | 18 +- app/Controllers/Opd.php | 16 ++ app/Controllers/Setting/Doctor.php | 33 ++++ ...01_AddOpdDayCareTemplateToDoctorMaster.php | 35 ++++ app/Database/master_schema.json | 11 ++ app/Views/Setting/Doctor/Doctor_V.php | 14 +- app/Views/Setting/Doctor/Doctor_profile_V.php | 14 +- app/Views/billing/opd_template_builder.php | 2 +- .../opd_templates/day_care_format.html | 127 ++++++++++++++ app/Views/ipd_nursing/patient_list.php | 157 ++++++++++++++++-- app/Views/partials/sidebar.php | 20 +-- 13 files changed, 423 insertions(+), 40 deletions(-) create mode 100644 app/Database/Migrations/2026-09-23-000001_AddOpdDayCareTemplateToDoctorMaster.php create mode 100644 app/Views/billing/opd_templates/day_care_format.html diff --git a/app/Config/Routes.php b/app/Config/Routes.php index 4197f3a..31cf58f 100644 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -705,6 +705,12 @@ $routes->get('opd_print/invoice_print_pdf/(:num)', 'Opd::invoice_print_pdf/$1'); $routes->get('opd_print/opd_PDF_print/(:num)', 'Opd::opd_pdf_print/$1'); $routes->get('opd_print/opd_Cont_print/(:num)', 'Opd::opd_cont_print/$1'); $routes->get('opd_print/opd_blank_print/(:num)', 'Opd::opd_blank_print/$1'); +$routes->get('opd_print/opd_day_care/(:num)/(:num)', 'Opd::opd_day_care/$1/$2'); +$routes->get('opd_print/opd_day_care/(:num)', 'Opd::opd_day_care/$1'); +$routes->get('Opd_print/opd_day_care/(:num)/(:num)', 'Opd::opd_day_care/$1/$2'); +$routes->get('Opd_print/opd_day_care/(:num)', 'Opd::opd_day_care/$1'); +$routes->get('Opd/opd_day_care/(:num)/(:num)', 'Opd::opd_day_care/$1/$2'); +$routes->get('Opd/opd_day_care/(:num)', 'Opd::opd_day_care/$1'); $routes->get('Opd_prescription/Prescription/(:num)', 'Opd_prescription::Prescription/$1'); $routes->match(['GET', 'POST'], 'Opd_prescription/create_opd_queue/(:num)', 'Opd_prescription::create_opd_queue/$1'); diff --git a/app/Controllers/Billing/Ipd.php b/app/Controllers/Billing/Ipd.php index f72114d..7b43109 100644 --- a/app/Controllers/Billing/Ipd.php +++ b/app/Controllers/Billing/Ipd.php @@ -229,9 +229,10 @@ class Ipd extends BaseController } $builder = $this->db->table('patient_master p'); - $builder->select('p.id, p.p_code, p.p_fname as patient_name, p.gender, p.age, p.dob, p.mphone1, p.mphone2'); + $builder->select('p.id, p.p_code, p.p_fname, p.p_rname, p.gender, p.age, p.dob, p.mphone1, p.mphone2'); $builder->groupStart() ->like('p.p_fname', $termClean) + ->orLike('p.p_rname', $termClean) ->orLike('p.p_code', $termClean) ->orLike('p.mphone1', $termClean) ->orLike('p.mphone2', $termClean) @@ -243,12 +244,15 @@ class Ipd extends BaseController $activeIpds = []; if (! empty($patientIds)) { $rows = $this->db->table('ipd_master') - ->select('id, p_id, coalesce(ipd_code, pid) as ipd_code, admission_type, ipd_status') + ->select('id, p_id, ipd_code, admission_type, ipd_status') ->whereIn('p_id', $patientIds) ->where('ipd_status', 0) ->get() ->getResultArray(); foreach ($rows as $r) { + if (empty($r['ipd_code'])) { + $r['ipd_code'] = '#' . $r['id']; + } $activeIpds[(int) $r['p_id']] = $r; } } @@ -256,6 +260,8 @@ class Ipd extends BaseController foreach ($results as &$pt) { $genderVal = (int) ($pt['gender'] ?? 0); $pt['gender_text'] = ($genderVal === 1) ? 'Male' : (($genderVal === 2) ? 'Female' : 'Other'); + $fullName = trim(($pt['p_fname'] ?? '') . ' ' . ($pt['p_rname'] ?? '')); + $pt['patient_name'] = $fullName !== '' ? $fullName : 'Unnamed'; $pt['active_ipd'] = $activeIpds[(int) $pt['id']] ?? null; } unset($pt); diff --git a/app/Controllers/IpdPatient.php b/app/Controllers/IpdPatient.php index c41d9c8..7b3549d 100644 --- a/app/Controllers/IpdPatient.php +++ b/app/Controllers/IpdPatient.php @@ -55,7 +55,22 @@ class IpdPatient extends BaseController 'cleaning' => 0, 'total_admitted' => count($records), 'nursing_stations' => 0, + 'count_ipd' => 0, + 'count_daycare' => 0, + 'count_emergency' => 0, ]; + + foreach ($records as $rec) { + $admType = strtolower(trim((string) ($rec->admission_type ?? 'ipd'))); + if ($admType === 'emergency') { + $stats['count_emergency']++; + } elseif ($admType === 'daycare') { + $stats['count_daycare']++; + } else { + $stats['count_ipd']++; + } + } + $floors = []; $wards = []; @@ -83,7 +98,7 @@ class IpdPatient extends BaseController if ($this->db->tableExists('ipd_master')) { $builder - ->select('i.id as ipd_id, i.ipd_code, i.register_date, i.r_doc_name') + ->select('i.id as ipd_id, i.ipd_code, i.register_date, i.r_doc_name, i.admission_type') ->join('ipd_master i', 'i.id = b.current_ipd_id AND i.ipd_status = 0', 'left', false); if ($this->db->tableExists('patient_master')) { @@ -145,6 +160,7 @@ class IpdPatient extends BaseController 'doctor_name' => trim((string) ($row->r_doc_name ?? '')), 'ipd_code' => (string) ($row->ipd_code ?? ''), 'ipd_id' => (int) ($row->ipd_id ?? 0), + 'admission_type' => strtolower(trim((string) ($row->admission_type ?? 'ipd'))), 'admit_date' => (string) ($row->register_date ?? ''), 'days_admitted' => $daysAdmitted, 'has_oxygen' => (bool) ($row->has_oxygen ?? false), diff --git a/app/Controllers/Opd.php b/app/Controllers/Opd.php index 80a8724..22950e5 100644 --- a/app/Controllers/Opd.php +++ b/app/Controllers/Opd.php @@ -2535,6 +2535,18 @@ class Opd extends BaseController return redirect()->to($url); } + public function opd_day_care(int $opdId, int $mode = 0) + { + $printConfig = $this->resolveDoctorPrintConfigByField($opdId, 'opd_day_care_template', 'day_care_format'); + $url = base_url('Opd/opd_lettre_pdf/' . (int) $opdId); + if ($printConfig['template'] !== '') { + $url .= '?template=' . urlencode($printConfig['template']); + } else { + $url .= '?template=day_care_format'; + } + return redirect()->to($url); + } + /** * @return array{layout:string,template:string} */ @@ -2547,6 +2559,10 @@ class Opd extends BaseController $fallbackLayout = 'full'; } + if (! $this->db->tableExists('doctor_master') || ! $this->db->fieldExists($fieldName, 'doctor_master')) { + return ['layout' => $fallbackLayout, 'template' => '']; + } + $query = $this->db->query( 'SELECT d.' . $fieldName . ' AS layout_field FROM opd_master o diff --git a/app/Controllers/Setting/Doctor.php b/app/Controllers/Setting/Doctor.php index 5e6f4b8..25c2508 100644 --- a/app/Controllers/Setting/Doctor.php +++ b/app/Controllers/Setting/Doctor.php @@ -106,6 +106,7 @@ class Doctor extends BaseController 'opd_print_format' => 'tmpl_opd_print_format', 'opd_blank_print' => 'tmpl_opd_blank_print', 'opd_cont_paper_print' => 'tmpl_opd_cont_paper_print', + 'opd_day_care_template' => 'tmpl_opd_day_care_template', 'rx_pre_print_letter_head_format' => 'tmpl_rx_pre_print_letter_head_format', 'rx_blank_letter_head' => 'tmpl_rx_blank_letter_head', 'rx_plain_paper' => 'tmpl_rx_plain_paper', @@ -229,6 +230,7 @@ class Doctor extends BaseController 'opd_print_format' => 'tmpl_opd_print_format', 'opd_blank_print' => 'tmpl_opd_blank_print', 'opd_cont_paper_print' => 'tmpl_opd_cont_paper_print', + 'opd_day_care_template' => 'tmpl_opd_day_care_template', 'rx_pre_print_letter_head_format' => 'tmpl_rx_pre_print_letter_head_format', 'rx_blank_letter_head' => 'tmpl_rx_blank_letter_head', 'rx_plain_paper' => 'tmpl_rx_plain_paper', @@ -671,6 +673,7 @@ class Doctor extends BaseController 'opd_print_format', 'opd_blank_print', 'opd_cont_paper_print', + 'opd_day_care_template', 'rx_pre_print_letter_head_format', 'rx_blank_letter_head', 'rx_plain_paper', @@ -681,6 +684,23 @@ class Doctor extends BaseController } $doctorFields = $this->db->getFieldNames('doctor_master') ?? []; + if (! in_array('opd_day_care_template', $doctorFields, true)) { + try { + $forge = \Config\Database::forge(); + $forge->addColumn('doctor_master', [ + 'opd_day_care_template' => [ + 'type' => 'VARCHAR', + 'constraint' => 100, + 'null' => true, + 'default' => null, + 'after' => 'opd_cont_paper_print', + ], + ]); + $doctorFields[] = 'opd_day_care_template'; + } catch (\Throwable $e) { + // Ignore if unable to add dynamically + } + } $availableFields = array_values(array_intersect($allTemplateFields, $doctorFields)); $options = $this->collectStoredTemplateOptions(); @@ -737,6 +757,19 @@ class Doctor extends BaseController } } + $fsDir = APPPATH . 'Views/billing/opd_templates/'; + if (is_dir($fsDir)) { + $files = glob($fsDir . '*.html'); + if ($files) { + foreach ($files as $file) { + $templateId = $this->normalizeTemplateId(basename($file, '.html')); + if ($templateId !== '') { + $options[] = $templateId; + } + } + } + } + return $options; } diff --git a/app/Database/Migrations/2026-09-23-000001_AddOpdDayCareTemplateToDoctorMaster.php b/app/Database/Migrations/2026-09-23-000001_AddOpdDayCareTemplateToDoctorMaster.php new file mode 100644 index 0000000..a283d4b --- /dev/null +++ b/app/Database/Migrations/2026-09-23-000001_AddOpdDayCareTemplateToDoctorMaster.php @@ -0,0 +1,35 @@ +db->tableExists('doctor_master')) { + $fields = []; + if (! $this->db->fieldExists('opd_day_care_template', 'doctor_master')) { + $fields['opd_day_care_template'] = [ + 'type' => 'VARCHAR', + 'constraint' => 100, + 'null' => true, + 'default' => null, + 'after' => 'opd_cont_paper_print', + ]; + } + + if (! empty($fields)) { + $this->forge->addColumn('doctor_master', $fields); + } + } + } + + public function down() + { + if ($this->db->tableExists('doctor_master') && $this->db->fieldExists('opd_day_care_template', 'doctor_master')) { + $this->forge->dropColumn('doctor_master', 'opd_day_care_template'); + } + } +} diff --git a/app/Database/master_schema.json b/app/Database/master_schema.json index 57d3f2a..170de2c 100644 --- a/app/Database/master_schema.json +++ b/app/Database/master_schema.json @@ -4919,6 +4919,17 @@ "Privileges": "select,insert,update,references", "Comment": "" }, + "opd_day_care_template": { + "Field": "opd_day_care_template", + "Type": "varchar(100)", + "Collation": "utf8mb3_unicode_ci", + "Null": "YES", + "Key": "", + "Default": null, + "Extra": "", + "Privileges": "select,insert,update,references", + "Comment": "" + }, "opd_valid_no_days": { "Field": "opd_valid_no_days", "Type": "int", diff --git a/app/Views/Setting/Doctor/Doctor_V.php b/app/Views/Setting/Doctor/Doctor_V.php index 33bb347..a4960fa 100644 --- a/app/Views/Setting/Doctor/Doctor_V.php +++ b/app/Views/Setting/Doctor/Doctor_V.php @@ -134,6 +134,18 @@ + +
+ + +
+ +
@@ -147,7 +159,7 @@ -
+
+ + + + + +
+ +
@@ -188,7 +200,7 @@ if (!empty($data) && !empty($data[0]) && !empty($data[0]->dob)) { -
+
+
-
+
+ +
+
-
+
-
+
@@ -89,6 +102,25 @@
+ + +
+ Quick Filter by Type: +
+ + + + +
+
@@ -173,10 +205,13 @@ $statusLabel = ucfirst($bed['bed_status']); } - $searchText = strtolower($bed['bed_number'] . ' ' . $bed['bed_code'] . ' ' . $bed['patient_name'] . ' ' . $bed['doctor_name'] . ' ' . $bed['ipd_code'] . ' ' . $wardInfo['ward_name'] . ' ' . $bed['station_name']); + $admType = strtolower(trim((string)($bed['admission_type'] ?? 'ipd'))); + $admTypeLabel = ($admType === 'emergency') ? 'emergency casualty' : (($admType === 'daycare') ? 'daycare day care' : 'ipd inpatient regular'); + $searchText = strtolower($bed['bed_number'] . ' ' . $bed['bed_code'] . ' ' . $bed['patient_name'] . ' ' . $bed['doctor_name'] . ' ' . $bed['ipd_code'] . ' ' . $wardInfo['ward_name'] . ' ' . $bed['station_name'] . ' ' . $admTypeLabel); ?>
@@ -196,11 +231,26 @@
- - - days - - +
+ + + d + + + + + Casualty + + + + Day Care + + + + IPD + + +
@@ -252,6 +302,7 @@ IPD Code UHID Patient Name + Type Bed & Ward Location Doctor Admit Date @@ -262,17 +313,27 @@ - + No current IPD admissions found. $row) : ?> - + admission_type ?? 'ipd'))); ?> + ipd_code ?? '') ?> p_code ?? '') ?> p_fname ?? '') . ' ' . ($row->p_rname ?? '')))) ?> + + + Casualty + + Day Care + + Regular IPD + + Bed_Desc ?? '') ?> @@ -298,6 +359,7 @@ diff --git a/app/Views/partials/sidebar.php b/app/Views/partials/sidebar.php index a78db22..27df873 100644 --- a/app/Views/partials/sidebar.php +++ b/app/Views/partials/sidebar.php @@ -238,18 +238,7 @@ if (! $canChargesSettings && $user && method_exists($user, 'inGroup')) { IPD Billing - - + +