From aae6211f481b2f0eb0bf40bfc7f7c6dc0dea53a5 Mon Sep 17 00:00:00 2001 From: DevSoftTech Server Date: Tue, 14 Apr 2026 21:51:49 +0530 Subject: [PATCH] Add investigation shortcuts manager panel --- app/Config/Routes.php | 4 + app/Controllers/Opd_prescription.php | 152 ++++++- .../billing/opd_invest_shortcuts_manager.php | 419 ++++++++++++++++++ app/Views/billing/opd_prescription_basic.php | 185 ++++++++ 4 files changed, 744 insertions(+), 16 deletions(-) create mode 100644 app/Views/billing/opd_invest_shortcuts_manager.php diff --git a/app/Config/Routes.php b/app/Config/Routes.php index 10b7f0f..cf0ef59 100644 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -625,6 +625,7 @@ $routes->post('Opd_prescription/advice_remove/(:num)', 'Opd_prescription::advice $routes->get('Opd_prescription/investigation_search', 'Opd_prescription::investigation_search'); $routes->get('Opd_prescription/investigation_shortcuts', 'Opd_prescription::investigation_shortcuts'); +$routes->get('Opd_prescription/debug_investigation_fields', 'Opd_prescription::debug_investigation_fields'); $routes->get('Opd_prescription/investigation_list/(:num)', 'Opd_prescription::investigation_list/$1'); $routes->get('Opd_prescription/investigation_list/(:num)/(:num)', 'Opd_prescription::investigation_list/$1/$2'); $routes->post('Opd_prescription/investigation_add', 'Opd_prescription::investigation_add'); @@ -636,6 +637,9 @@ $routes->get('Opd_prescription/opd_invest_master_get/(:num)', 'Opd_prescription: $routes->post('Opd_prescription/opd_invest_master_save', 'Opd_prescription::opd_invest_master_save'); $routes->post('Opd_prescription/opd_invest_master_remove/(:num)', 'Opd_prescription::opd_invest_master_remove/$1'); $routes->post('Opd_prescription/opd_invest_master_toggle_fav/(:num)', 'Opd_prescription::opd_invest_master_toggle_fav/$1'); +$routes->get('Opd_prescription/opd_invest_shortcuts_manager', 'Opd_prescription::opd_invest_shortcuts_manager', ['filter' => 'permission:doctor_work.medicine.manage,doctor_work.access']); +$routes->get('Opd_prescription/opd_invest_shortcuts_all', 'Opd_prescription::opd_invest_shortcuts_all'); +$routes->post('Opd_prescription/opd_invest_shortcuts_save_item', 'Opd_prescription::opd_invest_shortcuts_save_item'); $routes->get('Opd_prescription/opd_invest_profile_master', 'Opd_prescription::opd_invest_profile_master', ['filter' => 'permission:doctor_work.medicine.manage,doctor_work.access']); $routes->get('Opd_prescription/opd_invest_profile_master_list', 'Opd_prescription::opd_invest_profile_master_list'); $routes->get('Opd_prescription/opd_invest_profile_master_data', 'Opd_prescription::opd_invest_profile_master_data'); diff --git a/app/Controllers/Opd_prescription.php b/app/Controllers/Opd_prescription.php index 2684007..a900709 100644 --- a/app/Controllers/Opd_prescription.php +++ b/app/Controllers/Opd_prescription.php @@ -3381,6 +3381,85 @@ class Opd_prescription extends BaseController ]); } + public function opd_invest_shortcuts_manager() + { + return view('billing/opd_invest_shortcuts_manager'); + } + + public function opd_invest_shortcuts_all() + { + if (! $this->db->tableExists('investigation')) { + return $this->response->setJSON(['rows' => []]); + } + $fields = $this->db->getFieldNames('investigation'); + $keyField = $this->resolveFirstField($fields, ['id', 'Code', 'code']); + $codeField = $this->resolveFirstField($fields, ['Code', 'code']); + $nameField = $this->resolveFirstField($fields, ['Name', 'name']); + if ($keyField === null || $codeField === null || $nameField === null) { + return $this->response->setJSON(['rows' => []]); + } + $selectCols = $keyField . ' as id, ' . $codeField . ' as code, ' . $nameField . ' as name'; + foreach (['short_name', 'sort_id'] as $f) { + if (in_array($f, $fields, true)) { + $selectCols .= ', ' . $f; + } + } + $rows = $this->db->table('investigation') + ->select($selectCols) + ->orderBy($nameField, 'ASC') + ->get()->getResultArray(); + $rows = array_map(static function (array $r): array { + return [ + 'id' => (int) ($r['id'] ?? 0), + 'code' => (string) ($r['code'] ?? ''), + 'name' => (string) ($r['name'] ?? ''), + 'short_name' => (string) ($r['short_name'] ?? ''), + 'sort_id' => (int) ($r['sort_id'] ?? 0), + ]; + }, $rows); + return $this->response->setJSON([ + 'rows' => $rows, + 'csrfName' => csrf_token(), + 'csrfHash' => csrf_hash(), + ]); + } + + public function opd_invest_shortcuts_save_item() + { + if (! $this->request->isAJAX()) { + return $this->response->setStatusCode(400)->setJSON(['update' => 0]); + } + if (! $this->db->tableExists('investigation')) { + return $this->response->setJSON(['update' => 0, 'error_text' => 'Investigation table not found']); + } + $id = (int) $this->request->getPost('id'); + if ($id <= 0) { + return $this->response->setJSON(['update' => 0, 'error_text' => 'Invalid id']); + } + $fields = $this->db->getFieldNames('investigation'); + $keyField = $this->resolveFirstField($fields, ['id', 'Code', 'code']); + if ($keyField === null) { + return $this->response->setJSON(['update' => 0, 'error_text' => 'Invalid table structure']); + } + $data = []; + if (in_array('short_name', $fields, true)) { + $data['short_name'] = trim((string) $this->request->getPost('short_name')); + } + if (in_array('sort_id', $fields, true)) { + $data['sort_id'] = max(0, (int) $this->request->getPost('sort_id')); + } + if (empty($data)) { + return $this->response->setJSON(['update' => 0, 'error_text' => 'Nothing to update']); + } + $this->db->table('investigation')->where($keyField, $id)->update($data); + return $this->response->setJSON([ + 'update' => 1, + 'error_text' => 'Saved', + 'csrfName' => csrf_token(), + 'csrfHash' => csrf_hash(), + ]); + } + public function opd_invest_profile_master() { return view('billing/opd_invest_profile_master_workspace'); @@ -4697,25 +4776,36 @@ class Opd_prescription extends BaseController if ($this->db->tableExists('investigation')) { $invFields = $this->db->getFieldNames('investigation'); - $codeField = $this->resolveFirstField($invFields, ['Code', 'code']); - $nameField = $this->resolveFirstField($invFields, ['Name', 'name']); - $shortField = $this->resolveFirstField($invFields, ['short_name', 'shortName', 'short']); - $sortField = $this->resolveFirstField($invFields, ['sort_id', 'sort_order', 'id']); - if ($codeField !== null && $nameField !== null && $shortField !== null) { - $builder = $this->db->table('investigation') - ->select($codeField . ' as code,' . $nameField . ' as name,' . $shortField . ' as short_name') + $pickField = static function (array $fields, array $candidates): ?string { + $map = []; + foreach ($fields as $field) { + $map[strtolower((string) $field)] = (string) $field; + } + foreach ($candidates as $candidate) { + $key = strtolower((string) $candidate); + if (isset($map[$key])) { + return $map[$key]; + } + } + return null; + }; + + $codeField = $pickField($invFields, ['Code', 'code']); + $nameField = $pickField($invFields, ['Name', 'name']); + $shortField = $pickField($invFields, ['short_name', 'shortName', 'short']); + $sortField = $pickField($invFields, ['sort_id', 'sort_order', 'id']); + + if ($codeField !== null && $nameField !== null && $shortField !== null && $sortField !== null) { + // Keep legacy CI3 behavior: show only mostly-used tests and group/order by short_name, sort_id. + $shortTests = $this->db->table('investigation') + ->select($codeField . ' as code,' . $nameField . ' as name,' . $shortField . ' as short_name,' . $sortField . ' as sort_id') ->where($shortField . ' !=', '') ->where($shortField . ' is not null', null, false) - ->limit(200); - - if ($sortField !== null) { - $builder->orderBy($shortField, 'ASC')->orderBy($sortField, 'ASC'); - } else { - $builder->orderBy($shortField, 'ASC')->orderBy($nameField, 'ASC'); - } - - $shortTests = $builder->get()->getResultArray(); + ->orderBy($shortField, 'ASC') + ->orderBy($sortField, 'ASC') + ->get() + ->getResultArray(); } } @@ -4796,6 +4886,36 @@ class Opd_prescription extends BaseController ]); } + // DEBUG ENDPOINT - Remove after verifying data + public function debug_investigation_fields() + { + if ($this->db->tableExists('investigation')) { + $fields = $this->db->getFieldNames('investigation'); + $total = $this->db->table('investigation')->countAll(); + $withShortName = $this->db->table('investigation') + ->where("short_name != ''", null, false) + ->where('short_name IS NOT NULL', null, false) + ->countAll(); + + $sample = $this->db->table('investigation') + ->where("short_name != ''", null, false) + ->where('short_name IS NOT NULL', null, false) + ->orderBy('short_name', 'ASC') + ->orderBy('sort_id', 'ASC') + ->limit(10) + ->get() + ->getResultArray(); + + return $this->response->setJSON([ + 'table_fields' => $fields, + 'total_investigations' => $total, + 'with_short_name' => $withShortName, + 'sample_data' => $sample, + ]); + } + return $this->response->setJSON(['error' => 'investigation table not found']); + } + public function investigation_list($opdId, $sessionId = 0) { $table = $this->findExistingTable(['opd_prescription_investigation']); diff --git a/app/Views/billing/opd_invest_shortcuts_manager.php b/app/Views/billing/opd_invest_shortcuts_manager.php new file mode 100644 index 0000000..69827c7 --- /dev/null +++ b/app/Views/billing/opd_invest_shortcuts_manager.php @@ -0,0 +1,419 @@ +
+
+
Investigation Shortcuts Manager
+ — +
+ +
+
+ + +
+
+ Panel Preview (how it will look on OPD form) +
+
+ Loading… +
+
+ +
+ +
+
+
+ Groups in Panel + 0 +
+
+
Loading…
+
+
+
+ + +
+
+
+ Not in Panel + 0 +
+
+ +
+
+
+
Loading…
+
+
+
+
+
+
+ + + + + + + + diff --git a/app/Views/billing/opd_prescription_basic.php b/app/Views/billing/opd_prescription_basic.php index 99ebda1..221538f 100644 --- a/app/Views/billing/opd_prescription_basic.php +++ b/app/Views/billing/opd_prescription_basic.php @@ -807,9 +807,17 @@ + + Manage Shortcuts + + +
+
Search and select multiple tests, then click Add Selected.
+
+ +
+ +