From ed4e7c1fe4b28648295caf9cf3bc2fbd6a1dcbd7 Mon Sep 17 00:00:00 2001 From: DevSoftTech Server Date: Wed, 20 May 2026 00:29:00 +0530 Subject: [PATCH] =?UTF-8?q?feat:=20ABDM=20task=20board=20=E2=80=94=20remov?= =?UTF-8?q?e=20All,=20rename=20ABHA=20Update,=20add=20OPD=20Book=20+=20OPD?= =?UTF-8?q?=20Consult=20Publish=20sections?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Controllers/AbdmTaskBoard.php | 67 ++++++++++- app/Views/abdm/task_board.php | 183 +++++++++++++++++++++++++++--- 2 files changed, 233 insertions(+), 17 deletions(-) diff --git a/app/Controllers/AbdmTaskBoard.php b/app/Controllers/AbdmTaskBoard.php index e69dd94..747af2f 100644 --- a/app/Controllers/AbdmTaskBoard.php +++ b/app/Controllers/AbdmTaskBoard.php @@ -21,8 +21,10 @@ class AbdmTaskBoard extends BaseController $tasks = $this->taskService->getOpenTasks(300); return view('abdm/task_board', [ - 'tasks' => $tasks, - 'today_credit_opd_rows' => $this->getTodayCreditOpdConsultRows(), + 'tasks' => $tasks, + 'today_credit_opd_rows' => $this->getTodayCreditOpdConsultRows(), + 'opd_book_rows' => $this->getOpdBookRows(), + 'opd_consult_rows' => $this->getOpdConsultPublishRows(), ]); } @@ -435,4 +437,65 @@ class AbdmTaskBoard extends BaseController return null; } + + /** + * OPD Book rows: HMS OPD appointments (last 7 days) where patient has ABHA. + * + * @return array> + */ + private function getOpdBookRows(): array + { + if (! $this->db->tableExists('opd_master') || ! $this->db->tableExists('patient_master')) { + return []; + } + + $patientFields = $this->db->getFieldNames('patient_master') ?? []; + $abhaCol = $this->resolveExistingColumn($patientFields, ['abha_id', 'abha_no', 'abha_address', 'abha']); + if ($abhaCol === null) { + return []; + } + + $rows = $this->db->table('opd_master o') + ->select('o.opd_id, o.p_id, o.P_name, o.apointment_date, o.opd_status, o.doc_name, p.' . $abhaCol . ' as abha_id', false) + ->join('patient_master p', 'p.id = o.p_id', 'left') + ->where('DATE(o.apointment_date) >=', date('Y-m-d', strtotime('-7 days')), false) + ->where('p.' . $abhaCol . ' !=', '') + ->orderBy('o.opd_id', 'DESC') + ->limit(200) + ->get() + ->getResultArray(); + + return array_values(array_filter($rows, static fn ($r) => preg_match('/^\d{14}$/', trim((string) ($r['abha_id'] ?? ''))) === 1)); + } + + /** + * OPD Consult Publish rows: done OPD (opd_status=2) with ABHA, last 30 days. + * + * @return array> + */ + private function getOpdConsultPublishRows(): array + { + if (! $this->db->tableExists('opd_master') || ! $this->db->tableExists('patient_master')) { + return []; + } + + $patientFields = $this->db->getFieldNames('patient_master') ?? []; + $abhaCol = $this->resolveExistingColumn($patientFields, ['abha_id', 'abha_no', 'abha_address', 'abha']); + if ($abhaCol === null) { + return []; + } + + $rows = $this->db->table('opd_master o') + ->select('o.opd_id, o.p_id, o.P_name, o.apointment_date, o.opd_status, o.doc_name, p.' . $abhaCol . ' as abha_id', false) + ->join('patient_master p', 'p.id = o.p_id', 'left') + ->where('o.opd_status', 2) + ->where('DATE(o.apointment_date) >=', date('Y-m-d', strtotime('-30 days')), false) + ->where('p.' . $abhaCol . ' !=', '') + ->orderBy('o.opd_id', 'DESC') + ->limit(300) + ->get() + ->getResultArray(); + + return array_values(array_filter($rows, static fn ($r) => preg_match('/^\d{14}$/', trim((string) ($r['abha_id'] ?? ''))) === 1)); + } } diff --git a/app/Views/abdm/task_board.php b/app/Views/abdm/task_board.php index 14163c6..6f1076c 100644 --- a/app/Views/abdm/task_board.php +++ b/app/Views/abdm/task_board.php @@ -23,10 +23,9 @@
- - - - + + + @@ -126,7 +125,7 @@
-
+
@@ -266,6 +265,99 @@ + +
+
+
+ OPD Book — ABDM Patients + +
+
+ + +
+
+
+
+ ABDM Gateway Queue + - + Click "Fetch ABDM Queue" to load +
+
+
+ + + + +
TokenABHANameStatusTimeHMS Patient
Not loaded yet.
+
+
+ HMS Direct OPD with ABHA + + Last 7 days · patient has 14-digit ABHA +
+
+ + + + + + + + + + + + + + + + + + + + +
OPD IDPatientABHADateDoctorStatus
#= 2 ? 'Done' : 'Pending' ?>
No OPD with ABHA found in last 7 days.
+
+
+
+ + +
+
+ OPD Consult Publish — Done Appointments with ABHA + + Last 30 days · opd_status=Done · ABHA linked +
+
+
+ + + + + + + + + + + + + + + + + + + + +
OPD IDPatientABHAConsult DateDoctorAction
# + +
No done OPD with ABHA found in last 30 days.
+
+
+
+
Ready
@@ -340,17 +432,29 @@ el.textContent = text; } - function applyFilter(filter) { - var appliedFilter = filter; - if ((filter || '').toLowerCase() === 'opd_consult_publish') { - appliedFilter = 'opd_prescription_publish'; - } + var opdBookCard = document.getElementById('opdBookCard'); + var opdConsultCard = document.getElementById('opdConsultCard'); + var taskTableCard = document.getElementById('taskTableCard'); - var rows = document.querySelectorAll('#taskTable tbody tr'); - rows.forEach(function (row) { - var type = (row.getAttribute('data-task-type') || '').toLowerCase(); - row.style.display = (appliedFilter === 'all' || type === appliedFilter.toLowerCase()) ? '' : 'none'; - }); + function applyFilter(filter) { + // Hide dedicated section cards + if (opdBookCard) opdBookCard.classList.add('d-none'); + if (opdConsultCard) opdConsultCard.classList.add('d-none'); + + if (filter === 'opd_book') { + if (taskTableCard) taskTableCard.classList.add('d-none'); + if (opdBookCard) opdBookCard.classList.remove('d-none'); + } else if (filter === 'opd_consult_publish') { + if (taskTableCard) taskTableCard.classList.add('d-none'); + if (opdConsultCard) opdConsultCard.classList.remove('d-none'); + } else { + if (taskTableCard) taskTableCard.classList.remove('d-none'); + var rows = document.querySelectorAll('#taskTable tbody tr'); + rows.forEach(function (row) { + var type = (row.getAttribute('data-task-type') || '').toLowerCase(); + row.style.display = (type === filter.toLowerCase()) ? '' : 'none'; + }); + } document.querySelectorAll('.filter-btn').forEach(function (btn) { btn.classList.remove('btn-primary'); @@ -852,6 +956,55 @@ }); }); + // ABDM Gateway Queue fetch for OPD Book + document.getElementById('btnFetchAbdmQueue').addEventListener('click', function () { + var date = (document.getElementById('opdBookDate').value || '').trim() || ''; + var statusEl = document.getElementById('abdmQueueStatus'); + var badge = document.getElementById('abdmQueueBadge'); + var tbody = document.getElementById('abdmQueueTbody'); + if (statusEl) statusEl.textContent = 'Fetching...'; + fetch('?date=' + encodeURIComponent(date) + '&status=PENDING', { + method: 'GET', + headers: { 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'application/json' } + }).then(function (r) { return r.json(); }).then(function (data) { + var tokens = data.data || data.tokens || []; + if (badge) badge.textContent = tokens.length; + if (statusEl) statusEl.textContent = 'Loaded ' + tokens.length + ' token(s)'; + if (! tbody) return; + if (! tokens.length) { + tbody.innerHTML = 'No PENDING tokens for ' + date + '.'; + return; + } + tbody.innerHTML = tokens.map(function (t) { + var abha = (t.abha_id || t.abha_number || t.abhaId || '').toString().trim(); + var name = (t.patient_name || t.name || t.patientName || '').toString(); + var stat = (t.status || t.queue_status || '').toString(); + var token = (t.token_number || t.tokenNumber || t.gateway_token_id || t.id || '').toString(); + var time = (t.created_at || t.token_time || t.arrival_time || '').toString(); + var hms = t.patient_id ? ('#' + t.patient_id + (t.p_fname ? ' ' + t.p_fname : '')) : '—'; + return '' + + '' + (token || '—') + '' + + '' + (abha || '—') + '' + + '' + (name || '—') + '' + + '' + (stat || '—') + '' + + '' + (time ? time.substring(0, 16) : '—') + '' + + '' + hms + '' + + ''; + }).join(''); + }).catch(function (e) { + if (statusEl) statusEl.textContent = 'Fetch failed: ' + e.message; + }); + }); + + // OPD Consult Publish — FHIR preview buttons + document.querySelectorAll('.btn-opd-consult-fhir').forEach(function (btn) { + btn.addEventListener('click', function () { + var opdId = parseInt(btn.getAttribute('data-opd-id') || '0', 10); + if (opdId <= 0) return; + showInlineFhirPreview('/' + opdId, 'OPD Consult FHIR ' + opdId); + }); + }); + document.getElementById('btnRefresh').addEventListener('click', function () { if (typeof window.load_form === 'function') { window.load_form(refreshUrl, 'ABDM Task Board');