ABDM task board: show OPD record lifecycle status
This commit is contained in:
parent
c7c18adae2
commit
db7ba044b1
|
|
@ -496,6 +496,174 @@ class AbdmTaskBoard extends BaseController
|
|||
->get()
|
||||
->getResultArray();
|
||||
|
||||
return array_values(array_filter($rows, static fn ($r) => preg_match('/^\d{14}$/', trim((string) ($r['abha_id'] ?? ''))) === 1));
|
||||
$rows = array_values(array_filter($rows, static fn ($r) => preg_match('/^\d{14}$/', trim((string) ($r['abha_id'] ?? ''))) === 1));
|
||||
if (empty($rows)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$opdIds = array_values(array_unique(array_map(static fn ($r) => (int) ($r['opd_id'] ?? 0), $rows)));
|
||||
|
||||
$latestDocByOpd = [];
|
||||
if (! empty($opdIds) && $this->db->tableExists('opd_fhir_documents')) {
|
||||
$docRows = $this->db->table('opd_fhir_documents')
|
||||
->select('id, opd_id, opd_session_id, generated_at, created_at')
|
||||
->whereIn('opd_id', $opdIds)
|
||||
->whereIn('bundle_type', ['OPConsultRecord', 'MedicationRequestBundle'])
|
||||
->orderBy('id', 'DESC')
|
||||
->get()
|
||||
->getResultArray();
|
||||
|
||||
foreach ($docRows as $doc) {
|
||||
$k = (int) ($doc['opd_id'] ?? 0);
|
||||
if ($k <= 0 || isset($latestDocByOpd[$k])) {
|
||||
continue;
|
||||
}
|
||||
$latestDocByOpd[$k] = $doc;
|
||||
}
|
||||
}
|
||||
|
||||
$latestHrByOpd = [];
|
||||
if (! empty($opdIds) && $this->db->tableExists('health_records')) {
|
||||
$hrFields = $this->db->getFieldNames('health_records') ?? [];
|
||||
$hrSelect = ['id', 'entity_id', 'push_status', 'abdm_txn_id', 'care_context_reference', 'push_at', 'linked_at', 'updated_at'];
|
||||
if (in_array('bridge_record_id', $hrFields, true)) {
|
||||
$hrSelect[] = 'bridge_record_id';
|
||||
}
|
||||
|
||||
$opdIdStrings = array_map(static fn ($v) => (string) $v, $opdIds);
|
||||
$hrRows = $this->db->table('health_records')
|
||||
->select(implode(',', $hrSelect))
|
||||
->where('entity_type', 'opd')
|
||||
->whereIn('entity_id', $opdIdStrings)
|
||||
->orderBy('id', 'DESC')
|
||||
->get()
|
||||
->getResultArray();
|
||||
|
||||
foreach ($hrRows as $hr) {
|
||||
$k = (int) ($hr['entity_id'] ?? 0);
|
||||
if ($k <= 0 || isset($latestHrByOpd[$k])) {
|
||||
continue;
|
||||
}
|
||||
$latestHrByOpd[$k] = $hr;
|
||||
}
|
||||
}
|
||||
|
||||
$recordLinksByContext = [];
|
||||
if ($this->db->tableExists('record_links')) {
|
||||
$contexts = [];
|
||||
foreach ($latestHrByOpd as $hr) {
|
||||
$cc = trim((string) ($hr['care_context_reference'] ?? ''));
|
||||
if ($cc !== '') {
|
||||
$contexts[] = $cc;
|
||||
}
|
||||
}
|
||||
$contexts = array_values(array_unique($contexts));
|
||||
|
||||
if (! empty($contexts)) {
|
||||
$rlRows = $this->db->table('record_links')
|
||||
->select('id, care_context_reference, link_status, linked_at, updated_at')
|
||||
->whereIn('care_context_reference', $contexts)
|
||||
->orderBy('id', 'DESC')
|
||||
->get()
|
||||
->getResultArray();
|
||||
|
||||
foreach ($rlRows as $rl) {
|
||||
$cc = trim((string) ($rl['care_context_reference'] ?? ''));
|
||||
if ($cc === '' || isset($recordLinksByContext[$cc])) {
|
||||
continue;
|
||||
}
|
||||
$recordLinksByContext[$cc] = $rl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$out = [];
|
||||
foreach ($rows as $row) {
|
||||
$opdId = (int) ($row['opd_id'] ?? 0);
|
||||
if ($opdId <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$doc = $latestDocByOpd[$opdId] ?? null;
|
||||
$hr = $latestHrByOpd[$opdId] ?? null;
|
||||
$sessionId = (int) ($doc['opd_session_id'] ?? 0);
|
||||
|
||||
$consultDate = (string) ($row['apointment_date'] ?? '');
|
||||
$visitDate = $consultDate !== '' ? date('Y-m-d', strtotime($consultDate)) : date('Y-m-d');
|
||||
$derivedCareContext = 'OPD-' . $opdId . '-S' . ($sessionId > 0 ? $sessionId : 0) . '-' . $visitDate;
|
||||
|
||||
$careContextRef = trim((string) ($hr['care_context_reference'] ?? ''));
|
||||
if ($careContextRef === '') {
|
||||
$careContextRef = $derivedCareContext;
|
||||
}
|
||||
|
||||
$rl = $recordLinksByContext[$careContextRef] ?? null;
|
||||
$pushStatus = strtolower(trim((string) ($hr['push_status'] ?? '')));
|
||||
$linkStatus = strtolower(trim((string) ($rl['link_status'] ?? '')));
|
||||
|
||||
$statusLabel = 'Not Registered';
|
||||
$statusTone = 'secondary';
|
||||
$statusNote = 'FHIR not registered in health_records yet.';
|
||||
|
||||
if ($doc !== null) {
|
||||
$statusLabel = 'FHIR Generated';
|
||||
$statusTone = 'info';
|
||||
$statusNote = 'FHIR bundle generated; awaiting registration.';
|
||||
}
|
||||
|
||||
if ($pushStatus !== '') {
|
||||
if ($pushStatus === 'local_discovery_ready') {
|
||||
$statusLabel = 'Discovery Ready';
|
||||
$statusTone = 'primary';
|
||||
$statusNote = 'Registered in HMS for M2 discovery/fetch callbacks.';
|
||||
} elseif ($pushStatus === 'local_only') {
|
||||
$statusLabel = 'Local Only';
|
||||
$statusTone = 'secondary';
|
||||
$statusNote = 'Stored locally only (ABHA/consent not ready).';
|
||||
} elseif ($pushStatus === 'queued') {
|
||||
$statusLabel = 'Gateway Queued';
|
||||
$statusTone = 'warning';
|
||||
$statusNote = 'Submitted to gateway and waiting for link workflow.';
|
||||
} elseif ($pushStatus === 'linked') {
|
||||
$statusLabel = 'Linked';
|
||||
$statusTone = 'success';
|
||||
$statusNote = 'Care context linked successfully.';
|
||||
} elseif ($pushStatus === 'failed') {
|
||||
$statusLabel = 'Failed';
|
||||
$statusTone = 'danger';
|
||||
$statusNote = 'Last registration/share attempt failed.';
|
||||
}
|
||||
}
|
||||
|
||||
if ($linkStatus === 'linked') {
|
||||
$statusLabel = 'Linked';
|
||||
$statusTone = 'success';
|
||||
$statusNote = 'Care context link confirmed by callback.';
|
||||
} elseif ($linkStatus === 'pending_discovery' && $statusLabel === 'Discovery Ready') {
|
||||
$statusNote = 'Waiting for ABDM discovery and consent fetch callbacks.';
|
||||
} elseif ($linkStatus === 'failed') {
|
||||
$statusLabel = 'Link Failed';
|
||||
$statusTone = 'danger';
|
||||
$statusNote = 'Link callback reported failure.';
|
||||
}
|
||||
|
||||
$queueId = trim((string) ($hr['abdm_txn_id'] ?? ''));
|
||||
$bridgeRecordId = (int) ($hr['bridge_record_id'] ?? 0);
|
||||
|
||||
$out[] = array_merge($row, [
|
||||
'opd_session_id' => $sessionId,
|
||||
'care_context_reference' => $careContextRef,
|
||||
'record_status_label' => $statusLabel,
|
||||
'record_status_tone' => $statusTone,
|
||||
'record_status_note' => $statusNote,
|
||||
'push_status' => $pushStatus,
|
||||
'link_status' => $linkStatus,
|
||||
'queue_id' => $queueId,
|
||||
'bridge_record_id' => $bridgeRecordId > 0 ? $bridgeRecordId : null,
|
||||
'has_fhir' => $doc !== null ? 1 : 0,
|
||||
]);
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -266,24 +266,63 @@
|
|||
<div class="table-responsive">
|
||||
<table class="table table-sm mb-0">
|
||||
<thead class="table-light">
|
||||
<tr><th>OPD ID</th><th>Patient</th><th>ABHA</th><th>Consult Date</th><th>Doctor</th><th>Action</th></tr>
|
||||
<tr><th>OPD ID</th><th>Patient</th><th>ABHA</th><th>Consult Date</th><th>Doctor</th><th>Record Status</th><th>Details</th><th>Action</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (! empty($opd_consult_rows ?? [])): ?>
|
||||
<?php foreach (($opd_consult_rows ?? []) as $r): ?>
|
||||
<?php
|
||||
$statusTone = trim((string) ($r['record_status_tone'] ?? 'secondary'));
|
||||
$allowedTones = ['secondary', 'primary', 'info', 'success', 'warning', 'danger', 'dark'];
|
||||
if (! in_array($statusTone, $allowedTones, true)) {
|
||||
$statusTone = 'secondary';
|
||||
}
|
||||
$statusLabel = trim((string) ($r['record_status_label'] ?? 'Not Registered'));
|
||||
$statusNote = trim((string) ($r['record_status_note'] ?? ''));
|
||||
$queueId = trim((string) ($r['queue_id'] ?? ''));
|
||||
$careContext = trim((string) ($r['care_context_reference'] ?? ''));
|
||||
$linkStatus = trim((string) ($r['link_status'] ?? ''));
|
||||
$bridgeRecordId = trim((string) ($r['bridge_record_id'] ?? ''));
|
||||
$hasFhir = (int) ($r['has_fhir'] ?? 0) === 1;
|
||||
$statusBadgeClass = 'badge bg-' . $statusTone;
|
||||
if ($statusTone === 'warning') {
|
||||
$statusBadgeClass .= ' text-dark';
|
||||
}
|
||||
?>
|
||||
<tr>
|
||||
<td>#<?= (int) ($r['opd_id'] ?? 0) ?></td>
|
||||
<td><?= esc((string) ($r['P_name'] ?? '')) ?></td>
|
||||
<td><span class="text-primary small"><?= esc((string) ($r['abha_id'] ?? '')) ?></span></td>
|
||||
<td><?= esc(substr((string) ($r['apointment_date'] ?? ''), 0, 16)) ?></td>
|
||||
<td><?= esc((string) ($r['doc_name'] ?? '')) ?></td>
|
||||
<td><span class="<?= esc($statusBadgeClass) ?>"><?= esc($statusLabel) ?></span></td>
|
||||
<td class="small text-muted" style="min-width:260px;max-width:340px;">
|
||||
<?php if ($statusNote !== ''): ?>
|
||||
<div><?= esc($statusNote) ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if ($queueId !== ''): ?>
|
||||
<div><strong>Queue:</strong> <?= esc($queueId) ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if ($bridgeRecordId !== ''): ?>
|
||||
<div><strong>Bridge:</strong> #<?= esc($bridgeRecordId) ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if ($linkStatus !== ''): ?>
|
||||
<div><strong>Link:</strong> <?= esc(strtoupper($linkStatus)) ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if ($careContext !== ''): ?>
|
||||
<div class="text-truncate" title="<?= esc($careContext) ?>"><strong>CC:</strong> <?= esc($careContext) ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if (! $hasFhir): ?>
|
||||
<div class="text-danger">FHIR bundle not generated yet.</div>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-sm btn-outline-primary btn-opd-consult-fhir" data-opd-id="<?= (int) ($r['opd_id'] ?? 0) ?>">Preview FHIR</button>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<tr><td colspan="6" class="text-muted px-2 py-2">No done OPD with ABHA found in last 30 days.</td></tr>
|
||||
<tr><td colspan="8" class="text-muted px-2 py-2">No done OPD with ABHA found in last 30 days.</td></tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user