diff --git a/app/Config/Routes.php b/app/Config/Routes.php index 2c0a847..074d89a 100644 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -529,6 +529,11 @@ $routes->get('Opd_prescription/fhir_bundle/(:num)/(:num)', 'Opd_prescription::fh $routes->get('Opd_prescription/fhir_bundle_history/(:num)', 'Opd_prescription::fhir_bundle_history/$1'); $routes->get('Opd_prescription/fhir_bundle_history/(:num)/(:num)', 'Opd_prescription::fhir_bundle_history/$1/$2'); $routes->get('Opd_prescription/complaints_search', 'Opd_prescription::complaints_search'); +$routes->get('Opd_prescription/provisional_diagnosis_search', 'Opd_prescription::provisional_diagnosis_search'); +$routes->get('Opd_prescription/finding_exam_search', 'Opd_prescription::finding_exam_search'); +$routes->get('Opd_prescription/get_complaints', 'Opd_prescription::get_complaints'); +$routes->get('Opd_prescription/get_disease', 'Opd_prescription::get_disease'); +$routes->get('Opd_prescription/get_finding_exam', 'Opd_prescription::get_finding_exam'); $routes->post('Opd_prescription/complaints_parse', 'Opd_prescription::complaints_parse'); $routes->post('Opd_prescription/complaints_ai_draft', 'Opd_prescription::complaints_ai_draft'); $routes->post('Opd_prescription/clinical_autotype', 'Opd_prescription::clinical_autotype'); diff --git a/app/Controllers/Opd_prescription.php b/app/Controllers/Opd_prescription.php index ad6a0e0..d385478 100644 --- a/app/Controllers/Opd_prescription.php +++ b/app/Controllers/Opd_prescription.php @@ -3883,6 +3883,151 @@ class Opd_prescription extends BaseController return $this->response->setJSON(['rows' => $rows]); } + public function provisional_diagnosis_search() + { + if (! $this->canAccessPrescription()) { + return $this->response->setStatusCode(403)->setJSON(['rows' => []]); + } + + $q = trim((string) $this->request->getGet('q')); + if ($q === '' || ! $this->db->tableExists('disease_master')) { + return $this->response->setJSON(['rows' => []]); + } + + $fields = $this->db->getFieldNames('disease_master') ?? []; + $nameField = in_array('Name', $fields, true) ? 'Name' : (in_array('name', $fields, true) ? 'name' : null); + if ($nameField === null) { + return $this->response->setJSON(['rows' => []]); + } + + $rows = $this->db->table('disease_master') + ->select($nameField . ' as name') + ->like($nameField, $q) + ->orderBy($nameField, 'ASC') + ->limit(20) + ->get() + ->getResultArray(); + + return $this->response->setJSON(['rows' => $rows]); + } + + public function finding_exam_search() + { + if (! $this->canAccessPrescription()) { + return $this->response->setStatusCode(403)->setJSON(['rows' => []]); + } + + $q = trim((string) $this->request->getGet('q')); + if ($q === '' || ! $this->db->tableExists('opd_prescription')) { + return $this->response->setJSON(['rows' => []]); + } + + $rows = $this->db->table('opd_prescription') + ->select('Finding_Examinations as finding_examinations') + ->where('Finding_Examinations IS NOT NULL', null, false) + ->where('Finding_Examinations <>', '') + ->like('Finding_Examinations', $q) + ->groupBy('Finding_Examinations') + ->orderBy('id', 'DESC') + ->limit(20) + ->get() + ->getResultArray(); + + return $this->response->setJSON(['rows' => $rows]); + } + + // Legacy-compatible wrappers used by older autocomplete clients. + public function get_complaints() + { + $q = trim((string) ($this->request->getGet('term') ?? '')); + if ($q === '' || ! $this->db->tableExists('complaints_master')) { + return $this->response->setJSON([]); + } + + $rows = $this->db->table('complaints_master') + ->select('Name as value') + ->where('is_active', 1) + ->like('Name', $q) + ->orderBy('Name', 'ASC') + ->limit(20) + ->get() + ->getResultArray(); + + $out = []; + foreach ($rows as $row) { + $value = trim((string) ($row['value'] ?? '')); + if ($value === '') { + continue; + } + $out[] = ['label' => $value, 'value' => $value]; + } + + return $this->response->setJSON($out); + } + + public function get_disease() + { + $q = trim((string) ($this->request->getGet('term') ?? '')); + if ($q === '' || ! $this->db->tableExists('disease_master')) { + return $this->response->setJSON([]); + } + + $fields = $this->db->getFieldNames('disease_master') ?? []; + $nameField = in_array('Name', $fields, true) ? 'Name' : (in_array('name', $fields, true) ? 'name' : null); + if ($nameField === null) { + return $this->response->setJSON([]); + } + + $rows = $this->db->table('disease_master') + ->select($nameField . ' as value') + ->like($nameField, $q) + ->orderBy($nameField, 'ASC') + ->limit(20) + ->get() + ->getResultArray(); + + $out = []; + foreach ($rows as $row) { + $value = trim((string) ($row['value'] ?? '')); + if ($value === '') { + continue; + } + $out[] = ['label' => $value, 'value' => $value]; + } + + return $this->response->setJSON($out); + } + + public function get_finding_exam() + { + $q = trim((string) ($this->request->getGet('term') ?? '')); + if ($q === '' || ! $this->db->tableExists('opd_prescription')) { + return $this->response->setJSON([]); + } + + $rows = $this->db->table('opd_prescription') + ->select('Finding_Examinations as value') + ->where('Finding_Examinations IS NOT NULL', null, false) + ->where('Finding_Examinations <>', '') + ->like('Finding_Examinations', $q) + ->groupBy('Finding_Examinations') + ->orderBy('id', 'DESC') + ->limit(20) + ->get() + ->getResultArray(); + + $out = []; + foreach ($rows as $row) { + $value = trim((string) ($row['value'] ?? '')); + if ($value === '') { + continue; + } + $out[] = ['label' => $value, 'value' => $value]; + } + + return $this->response->setJSON($out); + } + public function complaints_parse() { if (! $this->request->isAJAX()) { diff --git a/app/Views/billing/opd_prescription_basic.php b/app/Views/billing/opd_prescription_basic.php index 61babee..d393a28 100644 --- a/app/Views/billing/opd_prescription_basic.php +++ b/app/Views/billing/opd_prescription_basic.php @@ -1573,6 +1573,71 @@ }); } + function splitCommaTerms(val) { + return (val || '').toString().split(/,\s*/); + } + + function extractLastCommaTerm(term) { + return splitCommaTerms(term).pop() || ''; + } + + function bindLegacyCommaAutocomplete(selector, endpointUrl, extractValue) { + var $field = $(selector); + if (!$field.length || !($.ui && $.ui.autocomplete)) { + return; + } + + $field + .on('keydown', function(event) { + if (event.keyCode === $.ui.keyCode.TAB && $(this).autocomplete('instance') && $(this).autocomplete('instance').menu.active) { + event.preventDefault(); + } + }) + .autocomplete({ + minLength: 2, + source: function(request, response) { + var term = extractLastCommaTerm(request.term || '').trim(); + if (term.length < 2) { + response([]); + return; + } + + $.getJSON(endpointUrl, { q: term }, function(data) { + var rows = (data && data.rows) ? data.rows : []; + var out = []; + (rows || []).forEach(function(row) { + var value = ''; + if (typeof extractValue === 'function') { + value = (extractValue(row) || '').toString().trim(); + } else { + value = (row && (row.value || row.label || row.name || row.finding_examinations)) ? (row.value || row.label || row.name || row.finding_examinations).toString().trim() : ''; + } + if (value) { + out.push({ label: value, value: value }); + } + }); + response(out); + }).fail(function() { + response([]); + }); + }, + focus: function() { + return false; + }, + select: function(event, ui) { + var terms = splitCommaTerms(this.value); + terms.pop(); + terms.push((ui.item && ui.item.value) ? ui.item.value : ''); + terms.push(''); + this.value = terms.join(', '); + markDirty('Suggestion inserted'); + scheduleAutoSave(); + refreshCounters(); + return false; + } + }); + } + function getCsrfPair() { var input = document.querySelector('input[name=""]'); if (!input) { @@ -5764,6 +5829,16 @@ initConsultSectionDesigner(); + bindLegacyCommaAutocomplete('#complaints', '', function(row) { + return (row && row.name) ? row.name : ''; + }); + bindLegacyCommaAutocomplete('#provisional_diagnosis', '', function(row) { + return (row && row.name) ? row.name : ''; + }); + bindLegacyCommaAutocomplete('#finding_examinations', '', function(row) { + return (row && row.finding_examinations) ? row.finding_examinations : ''; + }); + if (localStorage.getItem(draftKey)) { setStatus('dirty', 'Draft available'); }