fix(abdm): resolve JSON parse error on fetch and auto-reconcile revoked consents
This commit is contained in:
parent
cb0a1967a4
commit
9cb4ccd701
|
|
@ -83,6 +83,12 @@ class Filters extends BaseFilters
|
|||
'except' => [
|
||||
'Opd/*',
|
||||
'Opd_prescription/*',
|
||||
'billing/patient/abdm_*',
|
||||
'billing/patient/abdm_*/*',
|
||||
'AbdmHiu',
|
||||
'AbdmHiu/*',
|
||||
'AbdmGateway/*',
|
||||
'api/*',
|
||||
],
|
||||
],
|
||||
// 'honeypot',
|
||||
|
|
|
|||
|
|
@ -2853,7 +2853,10 @@ class Patient extends BaseController
|
|||
'message' => 'Records fetched successfully using existing granted consent.',
|
||||
'documents_persisted' => $reqDocumentsPersisted,
|
||||
'documents_updated' => $reqDocumentsUpdated,
|
||||
'data' => ['data_fetch' => $fetchResult, 'data_fetch_by_request_id' => $requestIdFetchResult],
|
||||
'data' => [
|
||||
'data_fetch' => $this->sanitizeFetchResultForResponse($fetchResult),
|
||||
'data_fetch_by_request_id' => $this->sanitizeFetchResultForResponse($requestIdFetchResult),
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -2887,7 +2890,10 @@ class Patient extends BaseController
|
|||
'message' => 'Records fetched successfully from historical ABDM records for this ABHA address.',
|
||||
'documents_persisted' => $abhaDocumentsPersisted,
|
||||
'documents_updated' => $abhaDocumentsUpdated,
|
||||
'data' => ['data_fetch' => $fetchResult, 'data_fetch_by_abha_address' => $abhaFetchResult],
|
||||
'data' => [
|
||||
'data_fetch' => $this->sanitizeFetchResultForResponse($fetchResult),
|
||||
'data_fetch_by_abha_address' => $this->sanitizeFetchResultForResponse($abhaFetchResult),
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -2900,7 +2906,7 @@ class Patient extends BaseController
|
|||
'message' => 'Consent is granted, but the health information provider has not sent any records yet. Please try again in a few minutes.',
|
||||
'documents_persisted' => 0,
|
||||
'documents_updated' => 0,
|
||||
'data' => ['data_fetch' => $fetchResult],
|
||||
'data' => ['data_fetch' => $this->sanitizeFetchResultForResponse($fetchResult)],
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -2910,10 +2916,23 @@ class Patient extends BaseController
|
|||
'message' => 'Records fetched successfully using existing granted consent.',
|
||||
'documents_persisted' => $documentsPersisted,
|
||||
'documents_updated' => $documentsUpdated,
|
||||
'data' => ['data_fetch' => $fetchResult],
|
||||
'data' => ['data_fetch' => $this->sanitizeFetchResultForResponse($fetchResult)],
|
||||
]);
|
||||
}
|
||||
|
||||
private function sanitizeFetchResultForResponse(array $result): array
|
||||
{
|
||||
$clean = $result;
|
||||
if (isset($clean['sessions']) && is_array($clean['sessions'])) {
|
||||
$clean['sessions_count'] = count($clean['sessions']);
|
||||
unset($clean['sessions']);
|
||||
}
|
||||
if (isset($clean['data']) && is_array($clean['data']) && isset($clean['data']['sessions'])) {
|
||||
unset($clean['data']['sessions']);
|
||||
}
|
||||
return $clean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consent detail breakdown for the "View Consent" modal — shows the requested vs
|
||||
* granted Health Information Types for the current consent artifact, plus the
|
||||
|
|
@ -3037,9 +3056,11 @@ class Patient extends BaseController
|
|||
continue;
|
||||
}
|
||||
$sessionRequestId = trim((string) ($consent['request_id'] ?? ''));
|
||||
$sessionGatewayRequestId = trim((string) ($consent['gateway_request_id'] ?? ''));
|
||||
$sessionConsentRequestId = trim((string) ($consent['consent_request_id'] ?? ''));
|
||||
$sessionConsentId = trim((string) ($consent['consent_id'] ?? ''));
|
||||
if ($sessionRequestId === '' && $sessionConsentRequestId === '' && $sessionConsentId === '') {
|
||||
$rawConsentId = trim((string) ($consent['consent_id'] ?? ''));
|
||||
$sessionConsentId = $rawConsentId !== '' ? trim((string) explode(':', $rawConsentId)[0]) : '';
|
||||
if ($sessionRequestId === '' && $sessionGatewayRequestId === '' && $sessionConsentRequestId === '' && $sessionConsentId === '') {
|
||||
continue;
|
||||
}
|
||||
$reconcileJobs[] = [
|
||||
|
|
@ -3047,6 +3068,7 @@ class Patient extends BaseController
|
|||
'payload' => [
|
||||
'abha_address' => $abhaAddress,
|
||||
'request_id' => $sessionRequestId,
|
||||
'gateway_request_id' => $sessionGatewayRequestId,
|
||||
'abdm_consent_request_id' => $sessionConsentRequestId,
|
||||
'abdm_consent_artifact_id' => $sessionConsentId,
|
||||
'consent_id' => $sessionConsentId,
|
||||
|
|
@ -3058,7 +3080,8 @@ class Patient extends BaseController
|
|||
$snapshot = $this->getLatestAbdmSyncSnapshot($abhaAddress);
|
||||
$requestId = trim((string) ($snapshot['request_id'] ?? ''));
|
||||
$consentRequestId = trim((string) ($snapshot['consent_request_id'] ?? ''));
|
||||
$consentId = trim((string) ($snapshot['consent_id'] ?? ''));
|
||||
$rawConsentId = trim((string) ($snapshot['consent_id'] ?? ''));
|
||||
$consentId = $rawConsentId !== '' ? trim((string) explode(':', $rawConsentId)[0]) : '';
|
||||
if ($requestId === '' && $consentRequestId === '' && $consentId === '') {
|
||||
return $this->response->setStatusCode(422)->setJSON([
|
||||
'ok' => 0,
|
||||
|
|
@ -5211,6 +5234,7 @@ class Patient extends BaseController
|
|||
$rowRequestId = trim((string) ($row['request_id'] ?? ''));
|
||||
$rowAbdmConsentRequestId = trim((string) ($row['abdm_consent_request_id'] ?? ''));
|
||||
$rowConsentId = trim((string) ($row['consent_id'] ?? ''));
|
||||
$rowGatewayRequestId = trim((string) ($row['gateway_request_id'] ?? ''));
|
||||
|
||||
if ($operation === 'CONSENT_REQUEST') {
|
||||
$anchorKey = 'anchor_' . count($order);
|
||||
|
|
@ -5219,6 +5243,9 @@ class Patient extends BaseController
|
|||
if ($rowRequestId !== '') {
|
||||
$requestIdToAnchor[$rowRequestId] = $anchorKey;
|
||||
}
|
||||
if ($rowGatewayRequestId !== '') {
|
||||
$requestIdToAnchor[$rowGatewayRequestId] = $anchorKey;
|
||||
}
|
||||
// Reconcile/status rows usually carry only the ABDM ids, so the
|
||||
// anchor must publish its own ids too or those rows cannot match.
|
||||
if ($rowAbdmConsentRequestId !== '') {
|
||||
|
|
@ -5229,6 +5256,9 @@ class Patient extends BaseController
|
|||
if ($rowConsentId !== '') {
|
||||
$abdmIdToAnchor[$rowConsentId] = $anchorKey;
|
||||
$requestIdToAnchor[$rowConsentId] = $anchorKey;
|
||||
$cleanConsentId = trim((string) explode(':', $rowConsentId)[0]);
|
||||
$abdmIdToAnchor[$cleanConsentId] = $anchorKey;
|
||||
$requestIdToAnchor[$cleanConsentId] = $anchorKey;
|
||||
}
|
||||
$openAnchor = $anchorKey;
|
||||
continue;
|
||||
|
|
@ -5239,8 +5269,12 @@ class Patient extends BaseController
|
|||
$anchorKey = $abdmIdToAnchor[$rowAbdmConsentRequestId];
|
||||
} elseif ($rowRequestId !== '' && isset($requestIdToAnchor[$rowRequestId])) {
|
||||
$anchorKey = $requestIdToAnchor[$rowRequestId];
|
||||
} elseif ($rowGatewayRequestId !== '' && isset($requestIdToAnchor[$rowGatewayRequestId])) {
|
||||
$anchorKey = $requestIdToAnchor[$rowGatewayRequestId];
|
||||
} elseif ($rowConsentId !== '' && isset($requestIdToAnchor[$rowConsentId])) {
|
||||
$anchorKey = $requestIdToAnchor[$rowConsentId];
|
||||
} elseif ($rowConsentId !== '' && isset($requestIdToAnchor[trim((string) explode(':', $rowConsentId)[0])])) {
|
||||
$anchorKey = $requestIdToAnchor[trim((string) explode(':', $rowConsentId)[0])];
|
||||
} elseif ($openAnchor !== null && ($rowAbdmConsentRequestId === '' || empty($anchorHasAbdmId[$openAnchor]))) {
|
||||
// Covers the first reconcile that discovers the ABDM id. A row
|
||||
// naming a consent request that belongs elsewhere must not be
|
||||
|
|
@ -5268,8 +5302,14 @@ class Patient extends BaseController
|
|||
if ($rowRequestId !== '') {
|
||||
$requestIdToAnchor[$rowRequestId] = $anchorKey;
|
||||
}
|
||||
if ($rowGatewayRequestId !== '') {
|
||||
$requestIdToAnchor[$rowGatewayRequestId] = $anchorKey;
|
||||
}
|
||||
if ($rowConsentId !== '') {
|
||||
$requestIdToAnchor[$rowConsentId] = $anchorKey;
|
||||
$cleanConsentId = trim((string) explode(':', $rowConsentId)[0]);
|
||||
$abdmIdToAnchor[$cleanConsentId] = $anchorKey;
|
||||
$requestIdToAnchor[$cleanConsentId] = $anchorKey;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5704,7 +5744,9 @@ class Patient extends BaseController
|
|||
'consent' => [
|
||||
'id' => $displayId,
|
||||
'request_id' => trim((string) (is_array($consentRequestRow) ? ($consentRequestRow['request_id'] ?? '') : ($best['request_id'] ?? ''))),
|
||||
'consent_id' => $consentId,
|
||||
'gateway_request_id' => trim((string) (is_array($consentRequestRow) ? ($consentRequestRow['gateway_request_id'] ?? '') : ($best['gateway_request_id'] ?? ''))),
|
||||
'consent_id' => $consentId !== '' ? trim((string) explode(':', $consentId)[0]) : '',
|
||||
'consent_id_raw' => $consentId,
|
||||
'consent_request_id' => $consentRequestId,
|
||||
'abha_address' => $abhaAddress,
|
||||
'status' => $phase,
|
||||
|
|
|
|||
|
|
@ -70,6 +70,12 @@ class M3HiuGatewayClient
|
|||
|
||||
public function reconcileConsentStatus(array $payload): array
|
||||
{
|
||||
if (isset($payload['consent_id']) && is_string($payload['consent_id']) && str_contains($payload['consent_id'], ':')) {
|
||||
$payload['consent_id'] = trim((string) explode(':', $payload['consent_id'])[0]);
|
||||
}
|
||||
if (isset($payload['consentId']) && is_string($payload['consentId']) && str_contains($payload['consentId'], ':')) {
|
||||
$payload['consentId'] = trim((string) explode(':', $payload['consentId'])[0]);
|
||||
}
|
||||
return $this->callGet('/v1/hiu/consent/status', $payload, 'consent.status.reconcile');
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ class M3HiuWorkflowService
|
|||
|
||||
$fields = $this->db->getFieldNames('abdm_hiu_workflows') ?? [];
|
||||
$selectCols = ['id', 'request_id', 'transaction_id', 'consent_id', 'abha_address', 'hfr_id', 'workflow_state', 'status', 'created_at', 'updated_at'];
|
||||
foreach (['abdm_consent_request_id', 'abdm_consent_artifact_id', 'completed_at', 'expired_at', 'revoked_at'] as $col) {
|
||||
foreach (['gateway_request_id', 'abdm_consent_request_id', 'abdm_consent_artifact_id', 'completed_at', 'expired_at', 'revoked_at'] as $col) {
|
||||
if (in_array($col, $fields, true)) {
|
||||
$selectCols[] = $col;
|
||||
}
|
||||
|
|
@ -212,11 +212,8 @@ class M3HiuWorkflowService
|
|||
->select(implode(', ', $selectCols))
|
||||
->where('operation', 'consent_request')
|
||||
->where('status', 'success')
|
||||
->whereNotIn('workflow_state', ['COMPLETED', 'EXPIRED', 'REVOKED', 'DENIED']);
|
||||
->whereNotIn('workflow_state', ['EXPIRED', 'REVOKED', 'DENIED']);
|
||||
|
||||
if (in_array('completed_at', $fields, true)) {
|
||||
$builder->where('completed_at IS NULL');
|
||||
}
|
||||
if (in_array('expired_at', $fields, true)) {
|
||||
$builder->where('expired_at IS NULL');
|
||||
}
|
||||
|
|
@ -263,6 +260,7 @@ class M3HiuWorkflowService
|
|||
|
||||
$payload = [
|
||||
'request_id' => $requestId,
|
||||
'gateway_request_id' => trim((string) ($row['gateway_request_id'] ?? '')),
|
||||
'transaction_id' => trim((string) ($row['transaction_id'] ?? '')),
|
||||
'consent_id' => trim((string) ($row['consent_id'] ?? '')),
|
||||
'abdm_consent_request_id' => trim((string) ($row['abdm_consent_request_id'] ?? '')),
|
||||
|
|
@ -1083,8 +1081,20 @@ class M3HiuWorkflowService
|
|||
if ($requestIdGenerated) {
|
||||
$requestIdRef = '';
|
||||
}
|
||||
$gatewayRequestId = trim((string) ($clean['gateway_request_id'] ?? ''));
|
||||
if ($gatewayRequestId !== '' && preg_match('/^REQ-/i', $gatewayRequestId) === 1 && stripos($gatewayRequestId, 'REQ-HIU-') !== 0) {
|
||||
$requestIdRef = $gatewayRequestId;
|
||||
} elseif (stripos($requestIdRef, 'REQ-HIU-') === 0 && $gatewayRequestId === '') {
|
||||
$requestIdRef = '';
|
||||
}
|
||||
|
||||
$consentRequestId = trim((string) ($clean['abdm_consent_request_id'] ?? $clean['consentRequestId'] ?? ''));
|
||||
$consentId = trim((string) ($clean['abdm_consent_artifact_id'] ?? $clean['consentId'] ?? $clean['consent_id'] ?? ''));
|
||||
$rawConsentId = trim((string) ($clean['abdm_consent_artifact_id'] ?? $clean['consentId'] ?? $clean['consent_id'] ?? ''));
|
||||
$consentId = $rawConsentId !== '' ? trim((string) explode(':', $rawConsentId)[0]) : '';
|
||||
|
||||
if ($requestIdRef === '' && $consentRequestId === '' && $consentId === '') {
|
||||
$requestIdRef = trim((string) ($clean['request_id'] ?? $clean['requestId'] ?? ''));
|
||||
}
|
||||
|
||||
if ($requestIdRef === '' && $consentRequestId === '' && $consentId === '') {
|
||||
return [
|
||||
|
|
|
|||
|
|
@ -1769,7 +1769,16 @@ $(function() {
|
|||
} else if (data.granted) {
|
||||
setAbdmStatus('Live status: GRANTED. Fetched data for ' + (data.artifacts_fetched || 0) + ' facility artifact(s)' + (data.data_fetch_failed ? (', ' + data.data_fetch_failed + ' failed') : '') + '.');
|
||||
} else {
|
||||
setAbdmStatus('Live status refreshed from ABDM bridge.');
|
||||
var latestStatus = ((currentAbdmRequests[0] && currentAbdmRequests[0].status) || '').toString().toUpperCase();
|
||||
if (latestStatus === 'REVOKED') {
|
||||
setAbdmStatus('Live status: REVOKED (consent was revoked in patient ABHA app).');
|
||||
} else if (latestStatus === 'DENIED') {
|
||||
setAbdmStatus('Live status: DENIED (consent was denied by patient).');
|
||||
} else if (latestStatus === 'EXPIRED') {
|
||||
setAbdmStatus('Live status: EXPIRED.');
|
||||
} else {
|
||||
setAbdmStatus('Live status refreshed from ABDM bridge.');
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(function(err) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user