diff --git a/app/Config/Routes.php b/app/Config/Routes.php
index 54f3e96..9558ec9 100644
--- a/app/Config/Routes.php
+++ b/app/Config/Routes.php
@@ -1289,6 +1289,9 @@ $routes->group('setting', static function($routes) {
$routes->post('admin/abdm-gateway/test', 'Setting\\AbdmGatewaySettings::testConnection', ['filter' => $settingsAdminFilter]);
$routes->get('admin/abdm-report-doctors', 'Setting\\AbdmReportDoctorSettings::index', ['filter' => $settingsAdminFilter]);
$routes->post('admin/abdm-report-doctors/save', 'Setting\\AbdmReportDoctorSettings::save', ['filter' => $settingsAdminFilter]);
+ $routes->get('admin/ipd-examination-fields', 'Setting\IpdExaminationFields::index', ['filter' => 'permission:ipd_discharge.master.manage']);
+ $routes->post('admin/ipd-examination-fields/save', 'Setting\IpdExaminationFields::save', ['filter' => ['permission:ipd_discharge.master.manage', 'csrf']]);
+ $routes->post('admin/ipd-examination-fields/toggle/(:num)', 'Setting\IpdExaminationFields::toggle/$1', ['filter' => ['permission:ipd_discharge.master.manage', 'csrf']]);
$routes->get('admin/hospital-profile', 'Setting\\HospitalProfile::index');
$routes->get('admin/system-ops', 'SystemOps::index', ['filter' => $settingsAdminFilter]);
$routes->get('admin/system-ops/panel', 'SystemOps::panel', ['filter' => $settingsAdminFilter]);
diff --git a/app/Controllers/Ipd_discharge.php b/app/Controllers/Ipd_discharge.php
index 496032b..d73c252 100644
--- a/app/Controllers/Ipd_discharge.php
+++ b/app/Controllers/Ipd_discharge.php
@@ -4169,11 +4169,18 @@ class Ipd_discharge extends BaseController
if ($this->tableHasColumns('ipd_discharge_general_exam_col', ['id', 'col_description'])) {
$generalBuilder = $this->db->table('ipd_discharge_general_exam_col')
->select('id,col_description,col_name,col_pre_value,cat_group')
+ ->orderBy($this->db->fieldExists('display_order', 'ipd_discharge_general_exam_col') ? 'display_order' : 'id', 'ASC')
->orderBy('id', 'ASC');
if ($this->db->fieldExists('col_unit', 'ipd_discharge_general_exam_col')) {
$generalBuilder->select('col_unit');
}
+ if ($this->db->fieldExists('col_type', 'ipd_discharge_general_exam_col')) {
+ $generalBuilder->select('col_type');
+ }
+ if ($this->db->fieldExists('is_active', 'ipd_discharge_general_exam_col')) {
+ $generalBuilder->where('is_active', 1);
+ }
$generalCols = $generalBuilder->get()->getResultArray();
@@ -4199,6 +4206,8 @@ class Ipd_discharge extends BaseController
'label' => (string) ($row['col_description'] ?? $row['col_name'] ?? ('Exam ' . $colId)),
'value' => (string) ($rdataMap[$colId] ?? (string) ($row['col_pre_value'] ?? '')),
'unit' => trim((string) ($row['col_unit'] ?? '')),
+ 'type' => (int) ($row['col_type'] ?? 0),
+ 'options' => (string) ($row['col_pre_value'] ?? ''),
];
$generalAll[] = $item;
@@ -6676,11 +6685,13 @@ class Ipd_discharge extends BaseController
// Examination on Admission (General Examination values).
if ($this->tableHasColumns('ipd_discharge_general_exam_col', ['id', 'col_name'])
&& $this->tableHasColumns('ipd_discharge_1_b', ['ipd_d_id', 'col_id', 'short_head', 'rdata'])) {
- $generalCols = $this->db->table('ipd_discharge_general_exam_col')
+ $generalBuilder = $this->db->table('ipd_discharge_general_exam_col')
->select('id,col_name')
- ->orderBy('id', 'ASC')
- ->get()
- ->getResultArray();
+ ->orderBy('id', 'ASC');
+ if ($this->db->fieldExists('is_active', 'ipd_discharge_general_exam_col')) {
+ $generalBuilder->where('is_active', 1);
+ }
+ $generalCols = $generalBuilder->get()->getResultArray();
foreach ($generalCols as $col) {
$colId = (int) ($col['id'] ?? 0);
diff --git a/app/Controllers/Setting/IpdExaminationFields.php b/app/Controllers/Setting/IpdExaminationFields.php
new file mode 100644
index 0000000..b16ef53
--- /dev/null
+++ b/app/Controllers/Setting/IpdExaminationFields.php
@@ -0,0 +1,81 @@
+ensureColumns();
+ return view('Setting/Admin/ipd_examination_fields', [
+ 'rows' => $this->db->table('ipd_discharge_general_exam_col')->orderBy('cat_group')->orderBy('display_order')->orderBy('id')->get()->getResultArray(),
+ ]);
+ }
+
+ public function save()
+ {
+ $this->ensureColumns();
+ $id = (int) ($this->request->getPost('id') ?? 0);
+ $code = strtoupper(trim((string) ($this->request->getPost('col_code') ?? '')));
+ $name = trim((string) ($this->request->getPost('col_name') ?? ''));
+ $label = trim((string) ($this->request->getPost('col_description') ?? ''));
+ if ($code === '' || ! preg_match('/^[A-Z][A-Z0-9_]{1,49}$/', $code) || $name === '' || $label === '') {
+ return $this->reply(false, 'Code, field name, and label are required. Use letters, numbers, and underscore in code.');
+ }
+
+ $duplicate = $this->db->table('ipd_discharge_general_exam_col')->where('col_code', $code);
+ if ($id > 0) {
+ $duplicate->where('id !=', $id);
+ }
+ if ($duplicate->countAllResults() > 0) {
+ return $this->reply(false, 'Field code already exists.');
+ }
+
+ $data = [
+ 'col_code' => $code,
+ 'col_name' => $name,
+ 'col_description' => $label,
+ 'col_unit' => trim((string) ($this->request->getPost('col_unit') ?? '')),
+ 'col_type' => max(0, min(4, (int) ($this->request->getPost('col_type') ?? 0))),
+ 'col_pre_value' => trim((string) ($this->request->getPost('col_pre_value') ?? '')),
+ 'cat_group' => (int) ($this->request->getPost('cat_group') ?? 1) === 2 ? 2 : 1,
+ 'is_active' => (int) ($this->request->getPost('is_active') ?? 0) === 1 ? 1 : 0,
+ 'display_order' => max(0, (int) ($this->request->getPost('display_order') ?? 0)),
+ ];
+ $saved = $id > 0
+ ? (bool) $this->db->table('ipd_discharge_general_exam_col')->where('id', $id)->update($data)
+ : (bool) $this->db->table('ipd_discharge_general_exam_col')->insert($data);
+
+ return $this->reply($saved, $saved ? 'Examination field saved.' : 'Unable to save examination field.');
+ }
+
+ public function toggle(int $id)
+ {
+ $this->ensureColumns();
+ $row = $this->db->table('ipd_discharge_general_exam_col')->select('id,is_active')->where('id', $id)->get()->getRowArray();
+ if ($row === null) {
+ return $this->reply(false, 'Examination field not found.');
+ }
+ $active = (int) ($row['is_active'] ?? 0) === 1 ? 0 : 1;
+ $saved = (bool) $this->db->table('ipd_discharge_general_exam_col')->where('id', $id)->update(['is_active' => $active]);
+ return $this->reply($saved, $saved ? ($active ? 'Field enabled.' : 'Field disabled.') : 'Unable to update field status.');
+ }
+
+ private function ensureColumns(): void
+ {
+ if (! $this->db->fieldExists('is_active', 'ipd_discharge_general_exam_col')) {
+ $this->db->query('ALTER TABLE ipd_discharge_general_exam_col ADD COLUMN is_active TINYINT(1) NOT NULL DEFAULT 1 AFTER cat_group');
+ }
+ if (! $this->db->fieldExists('display_order', 'ipd_discharge_general_exam_col')) {
+ $this->db->query('ALTER TABLE ipd_discharge_general_exam_col ADD COLUMN display_order INT NOT NULL DEFAULT 0 AFTER is_active');
+ $this->db->query('UPDATE ipd_discharge_general_exam_col SET display_order = id WHERE display_order = 0');
+ }
+ }
+
+ private function reply(bool $ok, string $message)
+ {
+ return $this->response->setJSON(['ok' => $ok ? 1 : 0, 'message' => $message, 'csrfName' => csrf_token(), 'csrfHash' => csrf_hash()]);
+ }
+}
\ No newline at end of file
diff --git a/app/Database/Migrations/2026-08-24-000003_AddIpdGeneralExamFieldControls.php b/app/Database/Migrations/2026-08-24-000003_AddIpdGeneralExamFieldControls.php
new file mode 100644
index 0000000..0e8095d
--- /dev/null
+++ b/app/Database/Migrations/2026-08-24-000003_AddIpdGeneralExamFieldControls.php
@@ -0,0 +1,42 @@
+tableExists('ipd_discharge_general_exam_col')) {
+ return;
+ }
+ if (! $this->fieldExists('is_active', 'ipd_discharge_general_exam_col')) {
+ $this->db->query('ALTER TABLE ipd_discharge_general_exam_col ADD COLUMN is_active TINYINT(1) NOT NULL DEFAULT 1 AFTER cat_group');
+ }
+ if (! $this->fieldExists('display_order', 'ipd_discharge_general_exam_col')) {
+ $this->db->query('ALTER TABLE ipd_discharge_general_exam_col ADD COLUMN display_order INT NOT NULL DEFAULT 0 AFTER is_active');
+ $this->db->query('UPDATE ipd_discharge_general_exam_col SET display_order = id WHERE display_order = 0');
+ }
+ }
+
+ public function down()
+ {
+ if ($this->tableExists('ipd_discharge_general_exam_col') && $this->fieldExists('display_order', 'ipd_discharge_general_exam_col')) {
+ $this->db->query('ALTER TABLE ipd_discharge_general_exam_col DROP COLUMN display_order');
+ }
+ if ($this->tableExists('ipd_discharge_general_exam_col') && $this->fieldExists('is_active', 'ipd_discharge_general_exam_col')) {
+ $this->db->query('ALTER TABLE ipd_discharge_general_exam_col DROP COLUMN is_active');
+ }
+ }
+
+ private function tableExists(string $table): bool
+ {
+ return $this->db->query('SHOW TABLES LIKE ' . $this->db->escape($table))->getRowArray() !== null;
+ }
+
+ private function fieldExists(string $field, string $table): bool
+ {
+ return $this->db->query('SHOW COLUMNS FROM `' . $table . '` LIKE ' . $this->db->escape($field))->getRowArray() !== null;
+ }
+}
\ No newline at end of file
diff --git a/app/Views/Setting/Admin/index.php b/app/Views/Setting/Admin/index.php
index 33689eb..a4cf7af 100644
--- a/app/Views/Setting/Admin/index.php
+++ b/app/Views/Setting/Admin/index.php
@@ -122,6 +122,12 @@
Bed Management
+
diff --git a/app/Views/Setting/Admin/ipd_examination_fields.php b/app/Views/Setting/Admin/ipd_examination_fields.php
new file mode 100644
index 0000000..187a1f7
--- /dev/null
+++ b/app/Views/Setting/Admin/ipd_examination_fields.php
@@ -0,0 +1,29 @@
+
+
+
+ | Order | Code | Label | Type | Group | Unit | Status | |
|---|
'>| = (int) ($row['display_order'] ?? 0) ?> | = esc($row['col_code'] ?? '') ?> | = esc($row['col_description'] ?? '') ?> | = ['Text', 'Long text', 'Number', 'Auto', 'Select'][(int) ($row['col_type'] ?? 0)] ?? 'Text' ?> | = (int) ($row['cat_group'] ?? 1) === 2 ? 'Other' : 'General' ?> | = esc($row['col_unit'] ?? '') ?> | = (int) ($row['is_active'] ?? 1) === 1 ? 'Enabled' : 'Disabled' ?> | |
+
+
\ No newline at end of file
diff --git a/app/Views/billing/ipd/discharge_create.php b/app/Views/billing/ipd/discharge_create.php
index 59171d2..5a20e95 100644
--- a/app/Views/billing/ipd/discharge_create.php
+++ b/app/Views/billing/ipd/discharge_create.php
@@ -819,7 +819,7 @@ $historyFields = [
-
+
@@ -833,7 +833,7 @@ $historyFields = [
-
+