Handle failed ABDM consent reset and add status help

This commit is contained in:
DevSoftTech Server 2026-07-28 01:05:25 +05:30
parent 646347534d
commit a15f5a0785
3 changed files with 179 additions and 16 deletions

View File

@ -3035,11 +3035,11 @@ class Patient extends BaseController
$phase = 'DENIED';
$priority = 300;
} elseif ($status === 'FAILED' && $httpCode === 404 && stripos($errorText, 'consent record not found') !== false) {
$phase = 'REQUESTED';
$priority = 80;
$phase = 'FAILED';
$priority = 280;
} elseif ($status === 'FAILED') {
$phase = 'PENDING';
$priority = 100;
$phase = 'FAILED';
$priority = 260;
} elseif (in_array($state, ['REQUESTED', 'PENDING', 'STATUS_CHECKED'], true)) {
$phase = 'REQUESTED';
$priority = 180;
@ -3053,7 +3053,9 @@ class Patient extends BaseController
} elseif ($phase === 'DENIED') {
$message = 'Consent was denied/revoked/expired in previous attempt.';
} elseif ($status === 'FAILED' && $httpCode === 404) {
$message = 'Consent status was not found on bridge in previous check. Retry after a short delay.';
$message = 'Last consent request was not found on bridge. Start a new consent request.';
} elseif ($phase === 'FAILED') {
$message = 'Last consent request failed. Start a new consent request.';
}
if ($best === null || $priority > $bestPriority) {
@ -3105,9 +3107,10 @@ class Patient extends BaseController
$snapshot['operation'] = (string) ($best['operation'] ?? '');
$snapshot['status'] = (string) ($best['status'] ?? '');
$snapshot['restart_required'] = (bool) (
($snapshot['phase'] === 'REQUESTED')
&& ($snapshot['status'] === 'failed')
&& stripos((string) ($snapshot['message'] ?? ''), 'not found on bridge') !== false
($snapshot['phase'] === 'FAILED')
|| (($snapshot['phase'] === 'REQUESTED')
&& ($snapshot['status'] === 'failed')
&& stripos((string) ($snapshot['message'] ?? ''), 'not found on bridge') !== false)
);
return $snapshot;

View File

@ -309,11 +309,23 @@ if ($patientPhotoPath === '') {
<?php } else { ?>
<span class="badge bg-warning-subtle text-warning border border-warning-subtle"><?= $abhaVerifiedStatus !== '' ? esc($abhaVerifiedStatus) : 'UNVERIFIED' ?></span>
<?php } ?>
&nbsp;|&nbsp;
Last Consent: <span class="badge bg-secondary" id="abdmLastConsentBadge">Unknown</span>
<span
class="ms-1 text-muted"
role="button"
tabindex="0"
data-bs-toggle="tooltip"
data-bs-placement="top"
title="Completed: data fetched. Granted: approved. Pending: waiting patient action. Failed: previous request failed. Failed - New Required: click New Consent Request."
aria-label="Consent status help"
>?</span>
</div>
</div>
<div class="d-flex gap-2 flex-wrap">
<button type="button" class="btn btn-outline-primary btn-sm" id="btnLoadAbdmDocs">Refresh Fetched Data</button>
<button type="button" class="btn btn-primary btn-sm" id="btnAutoAbdmFlow" <?= ($abhaIsVerified && $patientAbhaAddress !== '') ? '' : 'disabled' ?>>Start ABDM Sync</button>
<button type="button" class="btn btn-outline-danger btn-sm" id="btnNewAbdmConsent" <?= ($abhaIsVerified && $patientAbhaAddress !== '') ? '' : 'disabled' ?> style="display:none;">New Consent Request</button>
</div>
</div>
@ -410,6 +422,43 @@ $(function() {
var autoFlowMaxAttempts = 15;
var autoFlowNeedsFreshRequest = false;
function updateConsentBadge(phase, needsFresh) {
var text = (phase || '').toString().toUpperCase();
var $badge = $('#abdmLastConsentBadge');
if (!$badge.length) {
return;
}
$badge.removeClass('bg-secondary bg-success bg-info bg-warning bg-danger');
if (needsFresh) {
$badge.addClass('bg-danger').text('Failed - New Required');
return;
}
if (text === 'COMPLETED') {
$badge.addClass('bg-success').text('Completed');
} else if (text === 'GRANTED') {
$badge.addClass('bg-info').text('Granted');
} else if (text === 'REQUESTED' || text === 'PENDING') {
$badge.addClass('bg-warning').text('Pending');
} else if (text === 'FAILED' || text === 'DENIED') {
$badge.addClass('bg-danger').text('Failed');
} else {
$badge.addClass('bg-secondary').text('Unknown');
}
}
function applyConsentButtonState() {
var $newBtn = $('#btnNewAbdmConsent');
var canUse = autoFlowNeedsFreshRequest;
$newBtn.toggle(canUse);
if (canUse) {
$('#btnAutoAbdmFlow').text('Retry Sync');
} else {
$('#btnAutoAbdmFlow').text('Start ABDM Sync');
}
}
var zoom = 1;
var minZoom = 0.5;
var maxZoom = 3;
@ -621,8 +670,12 @@ $(function() {
setFlowProgress(2);
} else if (lastPhase === 'REQUESTED' || lastPhase === 'PENDING') {
setFlowProgress(1);
} else if (lastPhase === 'FAILED' || lastPhase === 'DENIED') {
setFlowProgress(0);
}
updateConsentBadge(lastPhase, autoFlowNeedsFreshRequest);
var baseMsg = 'Loaded ' + currentAbdmRows.length + ' fetched ABDM record(s).';
if (lastSync && (lastSync.message || '').toString().trim() !== '') {
baseMsg = (lastSync.message || '').toString();
@ -635,6 +688,7 @@ $(function() {
}
$('#abdmStatusBox').removeClass('text-danger').addClass('text-muted').text(baseMsg);
applyConsentButtonState();
})
.catch(function(err) {
$('#abdmStatusBox').removeClass('text-muted').addClass('text-danger').text('ABDM load failed: ' + (err.message || err));
@ -706,17 +760,21 @@ $(function() {
} else if (phase === 'REQUESTED' || phase === 'PENDING') {
setFlowProgress(1);
}
updateConsentBadge(phase, autoFlowNeedsFreshRequest);
$('#abdmStatusBox').removeClass('text-danger').addClass('text-muted').text(info + (autoFlowRequestId ? (' | Request ID: ' + autoFlowRequestId) : ''));
if (resetRequestId) {
autoFlowNeedsFreshRequest = true;
autoFlowRequestId = '';
if (autoFlowAttempts < autoFlowMaxAttempts) {
autoFlowAttempts += 1;
autoFlowTimer = setTimeout(runAutoFlowStep, 1200);
return;
}
stopAutoFlowLoop();
$('#btnAutoAbdmFlow').prop('disabled', false);
updateConsentBadge('FAILED', true);
applyConsentButtonState();
$('#abdmStatusBox').removeClass('text-danger').addClass('text-muted').text(
'Previous consent request is stale/failed. Click "New Consent Request" to start a fresh request.'
);
return;
}
var shouldPoll = Number(data.poll_again || 0) === 1;
@ -727,13 +785,15 @@ $(function() {
}
$('#btnAutoAbdmFlow').prop('disabled', false).text('One-Click Sync');
applyConsentButtonState();
if (phase === 'COMPLETED') {
loadAbdmDocs();
}
})
.catch(function(err) {
stopAutoFlowLoop();
$('#btnAutoAbdmFlow').prop('disabled', false).text('One-Click Sync');
$('#btnAutoAbdmFlow').prop('disabled', false);
applyConsentButtonState();
$('#abdmStatusBox').removeClass('text-muted').addClass('text-danger').text('Auto flow failed: ' + (err.message || err));
});
}
@ -794,10 +854,25 @@ $(function() {
runAutoFlowStep();
});
$(document).off('click.abdmOpd', '#btnNewAbdmConsent').on('click.abdmOpd', '#btnNewAbdmConsent', function() {
autoFlowNeedsFreshRequest = false;
autoFlowRequestId = '';
autoFlowAttempts = 0;
stopAutoFlowLoop();
updateConsentBadge('IDLE', false);
applyConsentButtonState();
$('#abdmStatusBox').removeClass('text-danger').addClass('text-muted').text('Fresh consent request context prepared. Click "Start ABDM Sync".');
});
$(document).off('shown.bs.tab.abdmOpd', '[data-bs-target="#opd-abdm-tab"]').on('shown.bs.tab.abdmOpd', '[data-bs-target="#opd-abdm-tab"]', function() {
if (!currentAbdmRows.length) {
loadAbdmDocs();
}
});
$('[data-bs-toggle="tooltip"]').tooltip();
applyConsentButtonState();
updateConsentBadge('IDLE', false);
});
</script>

View File

@ -48,11 +48,22 @@ $canUseM3 = $patientId > 0 && $abhaAddress !== '' && $abhaLooksVerified;
ABHA Number: <strong><?= $abhaNumber !== '' ? esc($abhaNumber) : 'Not available' ?></strong>
&nbsp;|&nbsp; ABHA Address: <strong><?= $abhaAddress !== '' ? esc($abhaAddress) : 'Not available' ?></strong>
&nbsp;|&nbsp; Status: <?= $abhaLooksVerified ? '<span class="badge bg-success">Verified</span>' : '<span class="badge bg-secondary">Not verified in HMS</span>' ?>
&nbsp;|&nbsp; Last Consent: <span class="badge bg-secondary" id="ayushmanLastConsentBadge">Unknown</span>
<span
class="ms-1 text-muted"
role="button"
tabindex="0"
data-bs-toggle="tooltip"
data-bs-placement="top"
title="Completed: data fetched. Granted: approved. Pending: waiting patient action. Failed: previous request failed. Failed - New Required: click New Consent Request."
aria-label="Consent status help"
>?</span>
</div>
</div>
<div class="d-flex gap-2 flex-wrap">
<button type="button" class="btn btn-sm btn-outline-primary" id="btnAyushmanLoadAbdmDocs" <?= $patientId > 0 ? '' : 'disabled' ?>>Load Fetched Data</button>
<button type="button" class="btn btn-sm btn-success" id="btnAyushmanFetchAbdmM3" <?= $canUseM3 ? '' : 'disabled' ?>>Fetch From ABDM M3</button>
<button type="button" class="btn btn-sm btn-outline-danger" id="btnAyushmanNewConsent" <?= $canUseM3 ? '' : 'disabled' ?> style="display:none;">New Consent Request</button>
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="load_form('<?= site_url('AbdmHiu') ?>','ABDM HIU M3')">Open M3 Console</button>
</div>
</div>
@ -145,6 +156,38 @@ $canUseM3 = $patientId > 0 && $abhaAddress !== '' && $abhaLooksVerified;
var pollTimer = null;
var pollAttempts = 0;
var maxPollAttempts = 15;
var needsFreshRequest = false;
function updateConsentBadge(phase, needsFresh) {
var text = (phase || '').toString().toUpperCase();
var $badge = $('#ayushmanLastConsentBadge');
if (!$badge.length) {
return;
}
$badge.removeClass('bg-secondary bg-success bg-info bg-warning bg-danger');
if (needsFresh) {
$badge.addClass('bg-danger').text('Failed - New Required');
return;
}
if (text === 'COMPLETED') {
$badge.addClass('bg-success').text('Completed');
} else if (text === 'GRANTED') {
$badge.addClass('bg-info').text('Granted');
} else if (text === 'REQUESTED' || text === 'PENDING') {
$badge.addClass('bg-warning').text('Pending');
} else if (text === 'FAILED' || text === 'DENIED') {
$badge.addClass('bg-danger').text('Failed');
} else {
$badge.addClass('bg-secondary').text('Unknown');
}
}
function applyConsentButtons() {
$('#btnAyushmanNewConsent').toggle(needsFreshRequest);
$('#btnAyushmanFetchAbdmM3').text(needsFreshRequest ? 'Retry ABDM M3 Sync' : 'Fetch From ABDM M3');
}
function esc(value) {
return $('<div>').text(value == null ? '' : String(value)).html();
@ -238,6 +281,18 @@ $canUseM3 = $patientId > 0 && $abhaAddress !== '' && $abhaLooksVerified;
}
var rows = Array.isArray(data.items) ? data.items : [];
renderRows(rows);
var lastSync = data.last_sync || null;
if (lastSync) {
var lastPhase = (lastSync.phase || '').toString().toUpperCase();
needsFreshRequest = !!lastSync.restart_required;
if (!needsFreshRequest && (lastSync.request_id || '').toString().trim() !== '') {
currentRequestId = (lastSync.request_id || '').toString().trim();
}
updateConsentBadge(lastPhase, needsFreshRequest);
applyConsentButtons();
}
setStatus('Loaded ' + rows.length + ' fetched ABDM record(s).', false);
})
.catch(function (error) {
@ -286,7 +341,20 @@ $canUseM3 = $patientId > 0 && $abhaAddress !== '' && $abhaLooksVerified;
currentRequestId = (data.request_id || currentRequestId || '').toString();
var phase = (data.phase || '').toString();
var message = (data.message || ('Phase: ' + (phase || 'UNKNOWN'))).toString();
var resetRequestId = parseInt(data.reset_request_id || 0, 10) === 1;
setStatus(message + (currentRequestId ? (' | Request ID: ' + currentRequestId) : ''), false);
updateConsentBadge(phase, needsFreshRequest);
if (resetRequestId) {
needsFreshRequest = true;
currentRequestId = '';
stopPolling();
$('#btnAyushmanFetchAbdmM3').prop('disabled', false);
updateConsentBadge('FAILED', true);
applyConsentButtons();
setStatus('Previous consent request is stale/failed. Click "New Consent Request" and run sync again.', false);
return;
}
if (parseInt(data.poll_again || 0, 10) === 1 && pollAttempts < maxPollAttempts) {
pollAttempts += 1;
@ -294,14 +362,16 @@ $canUseM3 = $patientId > 0 && $abhaAddress !== '' && $abhaLooksVerified;
return;
}
$('#btnAyushmanFetchAbdmM3').prop('disabled', false).text('Fetch From ABDM M3');
$('#btnAyushmanFetchAbdmM3').prop('disabled', false);
applyConsentButtons();
if (phase === 'COMPLETED') {
loadDocs();
}
})
.catch(function (error) {
stopPolling();
$('#btnAyushmanFetchAbdmM3').prop('disabled', false).text('Fetch From ABDM M3');
$('#btnAyushmanFetchAbdmM3').prop('disabled', false);
applyConsentButtons();
setStatus('M3 fetch failed: ' + (error.message || error), true);
});
}
@ -331,6 +401,21 @@ $canUseM3 = $patientId > 0 && $abhaAddress !== '' && $abhaLooksVerified;
setStatus('Starting ABDM M3 consent and data fetch flow...', false);
runM3AutoFlow();
});
$(document).off('click.ayushmanAbdm', '#btnAyushmanNewConsent').on('click.ayushmanAbdm', '#btnAyushmanNewConsent', function () {
needsFreshRequest = false;
currentRequestId = '';
pollAttempts = 0;
stopPolling();
updateConsentBadge('IDLE', false);
applyConsentButtons();
setStatus('Fresh consent request context prepared. Click "Fetch From ABDM M3" to create a new request.', false);
});
$('[data-bs-toggle="tooltip"]').tooltip();
applyConsentButtons();
updateConsentBadge('IDLE', false);
})();
</script>
<?php endif; ?>