fix(discharge-ui): simplify preview and remove ABDM sandbox panel

This commit is contained in:
DevSoftTech Server 2026-06-05 09:40:30 +05:30
parent 3666875782
commit 55e56176aa
2 changed files with 60 additions and 281 deletions

View File

@ -627,41 +627,6 @@ $allergyStatusNoKnown = in_array($allergyStatusNormalized, ['no known drug aller
<div class="discharge-side-actions">
<button type="button" class="btn btn-primary btn-sm" id="btn_preview_side" onclick="openDischargePreview('<?= site_url('Ipd_discharge/preview_discharge_report/' . $ipdId . '?regen=1') ?>', 'Discharge Preview');">Preview</button>
</div>
<div class="card mt-2 border-primary-subtle" id="ipd_abdm_panel">
<div class="card-header py-1"><strong>ABDM Sandbox Actions</strong></div>
<div class="card-body p-2">
<div class="mb-2">
<label class="form-label mb-1 small">ABHA Address/ID</label>
<input type="text" class="form-control form-control-sm" id="ipd_abha_address" value="<?= esc($patientAbha) ?>" maxlength="32" placeholder="Enter ABHA Address">
</div>
<div class="mb-2">
<label class="form-label mb-1 small">QR Payload (Scan &amp; Share)</label>
<input type="text" class="form-control form-control-sm" id="ipd_abdm_qr_payload" placeholder="Paste scanned QR payload">
</div>
<div class="d-flex flex-wrap gap-1 mb-2">
<button type="button" class="btn btn-outline-primary btn-sm" id="btn_ipd_abdm_scan_lookup">Scan Lookup</button>
<button type="button" class="btn btn-outline-secondary btn-sm" id="btn_ipd_abdm_validate_abha">Validate ABHA</button>
</div>
<div class="row g-1 mb-2">
<div class="col-6">
<input type="text" class="form-control form-control-sm" id="ipd_abdm_purpose_code" placeholder="Purpose (CAREMGT)">
</div>
<div class="col-6">
<input type="datetime-local" class="form-control form-control-sm" id="ipd_abdm_consent_expires_at">
</div>
</div>
<div class="d-flex flex-wrap gap-1 mb-2">
<button type="button" class="btn btn-outline-success btn-sm" id="btn_ipd_abdm_consent_request">Request Consent</button>
<button type="button" class="btn btn-outline-warning btn-sm" id="btn_ipd_abdm_share_discharge">Share Discharge</button>
</div>
<div class="mb-2">
<label class="form-label mb-1 small">Consent Handle</label>
<input type="text" class="form-control form-control-sm" id="ipd_abdm_consent_handle" placeholder="Auto-filled after consent request">
</div>
<div class="small text-muted" id="ipd_abdm_action_status">Ready</div>
</div>
</div>
</div>
</div>
@ -3906,212 +3871,6 @@ $allergyStatusNoKnown = in_array($allergyStatusNormalized, ['no known drug aller
}, { passive: true, capture: true });
syncNavOnScroll();
// ─── ABDM Sandbox Actions (IPD Discharge) ─────────────────────────────
(function initIpdAbdmActions() {
var csrfName = '<?= csrf_token() ?>';
var csrfHash = '<?= csrf_hash() ?>';
var ipdId = <?= (int) $ipdId ?>;
var patientId = <?= (int) $patientId ?>;
function setStatus(msg, isError) {
var el = document.getElementById('ipd_abdm_action_status');
if (!el) { return; }
el.textContent = msg;
el.style.color = isError ? '#dc3545' : '#6c757d';
}
function abdmPost(url, payload, onSuccess) {
setStatus('Sending…');
var data = Object.assign({}, payload);
data[csrfName] = csrfHash;
$.ajax({
url: url,
type: 'POST',
data: data,
dataType: 'json'
}).done(function(resp) {
// refresh CSRF token if returned
if (resp && resp.csrf_hash) { csrfHash = resp.csrf_hash; }
if (resp && resp.csrf_token) { csrfName = resp.csrf_token; }
onSuccess(resp);
}).fail(function(xhr) {
setStatus('Request failed: ' + xhr.status + ' ' + xhr.statusText, true);
});
}
function pollScanLookupStatus(queueId, onTick, onDone) {
if (!queueId || queueId <= 0) {
if (typeof onDone === 'function') {
onDone({ ok: 0, status: 'unknown', error_text: 'Missing queue id' });
}
return;
}
var tries = 0;
var maxTries = 10;
var timer = setInterval(function() {
tries++;
$.getJSON('<?= base_url('AbdmGateway/scan_share_lookup_status') ?>/' + queueId, function(resp) {
if (typeof onTick === 'function') {
onTick(resp, tries, maxTries);
}
if (!resp || parseInt(resp.ok || 0, 10) !== 1) {
if (tries >= maxTries) {
clearInterval(timer);
if (typeof onDone === 'function') {
onDone(resp || { ok: 0, status: 'failed', error_text: 'Status lookup failed' });
}
}
return;
}
var status = (resp.status || '').toString().toLowerCase();
if (parseInt(resp.done || 0, 10) === 1 || status === 'sent' || status === 'failed') {
clearInterval(timer);
if (typeof onDone === 'function') {
onDone(resp);
}
return;
}
if (tries >= maxTries) {
clearInterval(timer);
if (typeof onDone === 'function') {
onDone(resp);
}
}
}).fail(function() {
if (tries >= maxTries) {
clearInterval(timer);
if (typeof onDone === 'function') {
onDone({ ok: 0, status: 'failed', error_text: 'Status polling failed' });
}
}
});
}, 3000);
}
// Scan & Share Lookup
var btnScan = document.getElementById('btn_ipd_abdm_scan_lookup');
if (btnScan) {
btnScan.addEventListener('click', function() {
var qrPayload = (document.getElementById('ipd_abdm_qr_payload') || {}).value || '';
if (!qrPayload.trim()) { setStatus('Enter QR payload first.', true); return; }
abdmPost('<?= base_url('AbdmGateway/scan_share_lookup') ?>', {
qr_payload: qrPayload,
patient_id: patientId
}, function(resp) {
if (resp && resp.abha_address) {
var addr = document.getElementById('ipd_abha_address');
if (addr) { addr.value = resp.abha_address; }
}
if (!resp || parseInt(resp.ok || 0, 10) !== 1) {
setStatus((resp && resp.error_text) ? resp.error_text : 'Scan lookup failed.', true);
return;
}
var queueId = parseInt(resp.queue_id || '0', 10);
setStatus((resp && resp.message ? resp.message : 'Lookup queued.') + ' Queue ID: ' + (queueId || '-') + '. Checking status...', false);
pollScanLookupStatus(queueId, function(scanResp, currentTry, maxTry) {
if (!scanResp || parseInt(scanResp.ok || 0, 10) !== 1) {
setStatus('Scan lookup status check (' + currentTry + '/' + maxTry + ')...', true);
return;
}
var st = (scanResp.status || 'pending').toString();
setStatus('Scan lookup status: ' + st.toUpperCase() + ' (' + currentTry + '/' + maxTry + ')', st === 'failed');
}, function(finalResp) {
if (!finalResp || parseInt(finalResp.ok || 0, 10) !== 1) {
setStatus((finalResp && finalResp.error_text) ? finalResp.error_text : 'Scan lookup status unresolved. Please check Bridge Log.', true);
return;
}
var fs = (finalResp.status || '').toString().toLowerCase();
if (fs === 'sent') {
setStatus('Scan lookup sent successfully. Queue ID: ' + queueId, false);
} else if (fs === 'failed') {
setStatus('Scan lookup failed: ' + (finalResp.last_error || 'Unknown bridge error'), true);
} else {
setStatus('Scan lookup is still ' + fs.toUpperCase() + '. Please check Bridge Log.', true);
}
});
});
});
}
// Validate ABHA
var btnVal = document.getElementById('btn_ipd_abdm_validate_abha');
if (btnVal) {
btnVal.addEventListener('click', function() {
var abhaAddr = (document.getElementById('ipd_abha_address') || {}).value || '';
if (!abhaAddr.trim()) { setStatus('Enter ABHA Address first.', true); return; }
abdmPost('<?= base_url('AbdmGateway/abha_validate') ?>', {
abha_address: abhaAddr,
patient_id: patientId
}, function(resp) {
setStatus(resp && resp.message ? resp.message : (resp && resp.ok ? 'ABHA valid.' : 'Validation failed.'), !(resp && resp.ok));
});
});
}
// Request Consent
var btnConsent = document.getElementById('btn_ipd_abdm_consent_request');
if (btnConsent) {
btnConsent.addEventListener('click', function() {
var abhaAddr = (document.getElementById('ipd_abha_address') || {}).value || '';
var purpose = (document.getElementById('ipd_abdm_purpose_code') || {}).value || 'CAREMGT';
var expiresAt = (document.getElementById('ipd_abdm_consent_expires_at') || {}).value || '';
if (!abhaAddr.trim()) { setStatus('Enter ABHA Address first.', true); return; }
abdmPost('<?= base_url('AbdmGateway/consent_request') ?>', {
abha_address: abhaAddr,
patient_id: patientId,
purpose_code: purpose,
expires_at: expiresAt
}, function(resp) {
if (resp && resp.consent_handle) {
var ch = document.getElementById('ipd_abdm_consent_handle');
if (ch) { ch.value = resp.consent_handle; }
}
setStatus(resp && resp.message ? resp.message : (resp && resp.ok ? 'Consent requested.' : 'Consent request failed.'), !(resp && resp.ok));
});
});
}
// Share Discharge FHIR Bundle
var btnShare = document.getElementById('btn_ipd_abdm_share_discharge');
if (btnShare) {
btnShare.addEventListener('click', function() {
var abhaAddr = (document.getElementById('ipd_abha_address') || {}).value || '';
var consentHandle = (document.getElementById('ipd_abdm_consent_handle') || {}).value || '';
if (!abhaAddr.trim()) { setStatus('Enter ABHA Address first.', true); return; }
abdmPost('<?= base_url('AbdmGateway/share_ipd_discharge_bundle') ?>', {
ipd_id: ipdId,
patient_id: patientId,
abha_id: abhaAddr,
consent_handle: consentHandle
}, function(resp) {
if (resp && resp.consent_handle) {
var ch = document.getElementById('ipd_abdm_consent_handle');
if (ch && !ch.value) { ch.value = resp.consent_handle; }
}
setStatus(resp && resp.status ? ('Queued: ' + resp.status) : (resp && resp.message ? resp.message : 'Share request sent.'), !(resp && (resp.ok || resp.queue_id)));
});
});
}
// Set default consent expiry to +30 days
(function setDefaultExpiry() {
var el = document.getElementById('ipd_abdm_consent_expires_at');
if (!el || el.value) { return; }
var d = new Date();
d.setDate(d.getDate() + 30);
var iso = d.toISOString().slice(0, 16);
el.value = iso;
})();
})();
// ─── end ABDM Sandbox Actions ──────────────────────────────────────────
})();
</script>
</section>

View File

@ -91,7 +91,7 @@ if ($person) {
<div class="col-md-3"><strong>Discharge Date:</strong> <?= esc($ipd->str_discharge_date ?? '') ?></div>
</div>
<form method="get" action="<?= site_url('Ipd_discharge/preview_discharge_report/' . $ipdId) ?>" class="row g-2 mb-3">
<form method="get" action="<?= site_url('Ipd_discharge/preview_discharge_report/' . $ipdId) ?>" class="row g-2 mb-3" id="discharge_template_apply_form">
<div class="col-md-6 col-lg-4">
<label class="form-label small mb-1"><strong>Discharge Template</strong></label>
<select class="form-select form-select-sm" name="tpl" id="tpl_selector">
@ -158,9 +158,44 @@ if ($person) {
<div class="d-flex flex-wrap gap-2 mt-3">
<a class="btn btn-primary" id="btn_create" href="<?= site_url('Ipd_discharge/ipd_select/' . $ipdId) ?>">Back to Create Discharge Summary</a>
<button type="button" class="btn btn-danger" id="btn_show">Make File and Print on Letter Head</button>
<button type="button" class="btn btn-danger" id="btn_show2">Make File and Print On Plain Paper</button>
<button type="button" class="btn btn-outline-danger" id="btn_show3">New Print</button>
<div class="btn-group" role="group">
<button type="button" class="btn btn-danger dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
Make File and Print on Letter Head
</button>
<ul class="dropdown-menu">
<?php foreach ($templateRows as $tpl): ?>
<?php $tplId = (int) ($tpl['id'] ?? 0); ?>
<li>
<button
type="button"
class="dropdown-item discharge-print-link"
data-print-url="<?= esc(site_url('Ipd_discharge/show_discharge/' . $ipdId . '/1') . '?tpl=' . $tplId) ?>"
>
<?= esc((string) ($tpl['template_name'] ?? ('Template #' . $tplId))) ?>
</button>
</li>
<?php endforeach; ?>
</ul>
</div>
<div class="btn-group" role="group">
<button type="button" class="btn btn-outline-danger dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
Make File and Print On Plain Paper
</button>
<ul class="dropdown-menu">
<?php foreach ($templateRows as $tpl): ?>
<?php $tplId = (int) ($tpl['id'] ?? 0); ?>
<li>
<button
type="button"
class="dropdown-item discharge-print-link"
data-print-url="<?= esc(site_url('Ipd_discharge/show_discharge/' . $ipdId . '/0') . '?tpl=' . $tplId) ?>"
>
<?= esc((string) ($tpl['template_name'] ?? ('Template #' . $tplId))) ?>
</button>
</li>
<?php endforeach; ?>
</ul>
</div>
</div>
</div>
</div>
@ -188,9 +223,9 @@ if ($person) {
var nabhCriticalMissingCount = <?= (int) $nabhCriticalMissingCount ?>;
var nabhCriticalMissingItems = <?= json_encode(array_values($nabhCriticalMissing), JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT) ?>;
var btnCreate = document.getElementById('btn_create');
var btnShow = document.getElementById('btn_show');
var btnShow2 = document.getElementById('btn_show2');
var btnShow3 = document.getElementById('btn_show3');
var printLinks = document.querySelectorAll('.discharge-print-link');
var applyTemplateForm = document.getElementById('discharge_template_apply_form');
var tplSelector = document.getElementById('tpl_selector');
function confirmNabhPrint() {
if (nabhCriticalMissingCount <= 0) {
@ -213,49 +248,34 @@ if ($person) {
});
}
if (btnShow) {
btnShow.addEventListener('click', function() {
if (!confirmNabhPrint()) {
if (applyTemplateForm) {
applyTemplateForm.addEventListener('submit', function(e) {
var action = applyTemplateForm.getAttribute('action') || '';
var tplId = tplSelector ? parseInt(tplSelector.value || '0', 10) : 0;
if (action === '') {
return;
}
var tpl = document.getElementById('tpl_selector');
var tplId = tpl ? parseInt(tpl.value || '0', 10) : 0;
var url = '<?= site_url('Ipd_discharge/show_discharge') ?>/' + ipdId + '/1';
if (tplId > 0) {
url += '?tpl=' + tplId;
if (typeof load_form === 'function' || typeof load_form_div === 'function') {
e.preventDefault();
if (tplId > 0) {
action += '?tpl=' + encodeURIComponent(String(tplId));
}
loadOrRedirect(action, 'Discharge Preview');
}
openUrl(url);
});
}
if (btnShow2) {
btnShow2.addEventListener('click', function() {
printLinks.forEach(function(btn) {
btn.addEventListener('click', function() {
if (!confirmNabhPrint()) {
return;
}
var tpl = document.getElementById('tpl_selector');
var tplId = tpl ? parseInt(tpl.value || '0', 10) : 0;
var url = '<?= site_url('Ipd_discharge/show_discharge') ?>/' + ipdId + '/0';
if (tplId > 0) {
url += '?tpl=' + tplId;
var url = btn.getAttribute('data-print-url') || '';
if (url !== '') {
openUrl(url);
}
openUrl(url);
});
}
if (btnShow3) {
btnShow3.addEventListener('click', function() {
if (!confirmNabhPrint()) {
return;
}
var tpl = document.getElementById('tpl_selector');
var tplId = tpl ? parseInt(tpl.value || '0', 10) : 0;
var url = '<?= site_url('Ipd_discharge/show_file3') ?>/' + ipdId;
if (tplId > 0) {
url += '?tpl=' + tplId;
}
openUrl(url);
});
}
});
})();
</script>