diff --git a/app/Controllers/Patient.php b/app/Controllers/Patient.php index 76eee82..1504756 100644 --- a/app/Controllers/Patient.php +++ b/app/Controllers/Patient.php @@ -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; diff --git a/app/Views/billing/Patient_Profile_Opd_V.php b/app/Views/billing/Patient_Profile_Opd_V.php index 7dbf779..8fb705e 100644 --- a/app/Views/billing/Patient_Profile_Opd_V.php +++ b/app/Views/billing/Patient_Profile_Opd_V.php @@ -309,11 +309,23 @@ if ($patientPhotoPath === '') { +  |  + Last Consent: Unknown + ?
+
@@ -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); }); diff --git a/app/Views/billing/ipd/ayushman_claim_sheet.php b/app/Views/billing/ipd/ayushman_claim_sheet.php index 37a4f41..ffe59e8 100644 --- a/app/Views/billing/ipd/ayushman_claim_sheet.php +++ b/app/Views/billing/ipd/ayushman_claim_sheet.php @@ -48,11 +48,22 @@ $canUseM3 = $patientId > 0 && $abhaAddress !== '' && $abhaLooksVerified; ABHA Number:  |  ABHA Address:  |  Status: Verified' : 'Not verified in HMS' ?> +  |  Last Consent: Unknown + ?
+
@@ -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 $('
').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); })();