fix(abdm): eliminate dummy consultation bundles, fix Strategy 0 return bundle, add on-demand invoice FHIR, and ensure full multi-artifact HIU polling
This commit is contained in:
parent
1c41b4555b
commit
48d11b20df
|
|
@ -4942,8 +4942,13 @@ class AbdmGateway extends BaseController
|
|||
$targetOpdId = (int) ($pRow['opd_id'] ?? 0);
|
||||
}
|
||||
if ($targetOpdId <= 0 && $targetPatientId > 0 && $db->tableExists('opd_master')) {
|
||||
$opdRow = $db->table('opd_master')->select('opd_id')->where('p_id', $targetPatientId)->orderBy('opd_id', 'DESC')->get(1)->getRowArray();
|
||||
$targetOpdId = (int) ($opdRow['opd_id'] ?? 0);
|
||||
$opdRow = $db->table('opd_master')->select('opd_id')->where('opd_id', $targetPatientId)->get(1)->getRowArray();
|
||||
if ($opdRow) {
|
||||
$targetOpdId = (int) $opdRow['opd_id'];
|
||||
} else {
|
||||
$opdRow = $db->table('opd_master')->select('opd_id')->where('p_id', $targetPatientId)->orderBy('opd_id', 'DESC')->get(1)->getRowArray();
|
||||
$targetOpdId = (int) ($opdRow['opd_id'] ?? 0);
|
||||
}
|
||||
}
|
||||
|
||||
if ($targetOpdId > 0) {
|
||||
|
|
@ -4966,6 +4971,30 @@ class AbdmGateway extends BaseController
|
|||
}
|
||||
}
|
||||
|
||||
// Strategy 0b: Live On-Demand Fresh Generation for Invoice Record
|
||||
if (preg_match('/^INVOICE-(CHG|OPD|IPD)-(\d+)/i', $ref, $invM)) {
|
||||
$invSource = match(strtoupper($invM[1])) {
|
||||
'CHG' => 'charges_invoice',
|
||||
'OPD' => 'opd_invoice',
|
||||
'IPD' => 'ipd_invoice',
|
||||
};
|
||||
$invId = (int) $invM[2];
|
||||
try {
|
||||
$invPayload = $this->buildInvoiceSourceRecordPayload($invSource, $invId, 0, '');
|
||||
if ($invPayload !== null && !empty($invPayload['bundle'])) {
|
||||
$records[] = [
|
||||
'careContextReference' => $ref,
|
||||
'hiType' => 'InvoiceRecord',
|
||||
'display' => $invPayload['care_context_display'] ?? 'Invoice Record',
|
||||
'bundle' => $invPayload['bundle'],
|
||||
];
|
||||
continue;
|
||||
}
|
||||
} catch (\Throwable $ex) {
|
||||
log_message('warning', 'Live Invoice FHIR generation in recordsFetch failed: ' . $ex->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Strategy A: Check if health_records already has stored FHIR record_data
|
||||
$hrRow = null;
|
||||
if ($db->tableExists('health_records')) {
|
||||
|
|
@ -5017,14 +5046,18 @@ class AbdmGateway extends BaseController
|
|||
|
||||
|
||||
// Strategy B: Build compliant FHIR Document Bundle from patient_master & OPD
|
||||
$bundle = $this->assembleFhirBundleForCareContext($ref);
|
||||
if ($bundle !== null) {
|
||||
$records[] = [
|
||||
'careContextReference' => $ref,
|
||||
'hiType' => 'OPConsultRecord',
|
||||
'display' => 'OPConsultRecord - ' . date('d M Y'),
|
||||
'bundle' => $bundle,
|
||||
];
|
||||
// STRICTLY restricted to OPD/consultation care contexts.
|
||||
// NEVER synthesize dummy consultation records for invoices, discharge, labs, radiology, etc.
|
||||
if (preg_match('/^(?:OPD|PRESCRIPTION|CONSULT)/i', $ref)) {
|
||||
$bundle = $this->assembleFhirBundleForCareContext($ref);
|
||||
if ($bundle !== null) {
|
||||
$records[] = [
|
||||
'careContextReference' => $ref,
|
||||
'hiType' => 'OPConsultRecord',
|
||||
'display' => 'OPConsultRecord - ' . date('d M Y'),
|
||||
'bundle' => $bundle,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5049,10 +5082,25 @@ class AbdmGateway extends BaseController
|
|||
{
|
||||
$db = \Config\Database::connect();
|
||||
|
||||
// Extract patient ID from reference (e.g. "OPD-16-S1-20260909" -> patient_id 16)
|
||||
// Extract patient ID and doctor from reference (e.g. "OPD-16-S1-20260909" -> patient_id 16 or opd_id)
|
||||
$patientId = 0;
|
||||
$doctorName = 'Treating Doctor';
|
||||
if (preg_match('/OPD-(\d+)/i', $careContextRef, $matches)) {
|
||||
$patientId = (int) $matches[1];
|
||||
$extractedId = (int) $matches[1];
|
||||
if ($db->tableExists('opd_master')) {
|
||||
$opd = $db->table('opd_master')->where('opd_id', $extractedId)->get(1)->getRowArray();
|
||||
if (!empty($opd)) {
|
||||
if (!empty($opd['p_id'])) {
|
||||
$patientId = (int) $opd['p_id'];
|
||||
}
|
||||
if (!empty($opd['doc_name'])) {
|
||||
$doctorName = trim((string) $opd['doc_name']);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($patientId === 0) {
|
||||
$patientId = $extractedId;
|
||||
}
|
||||
} elseif (preg_match('/(?:HR|PAT|REG|P)-(\d+)/i', $careContextRef, $matches)) {
|
||||
$patientId = (int) $matches[1];
|
||||
}
|
||||
|
|
@ -5121,7 +5169,7 @@ class AbdmGateway extends BaseController
|
|||
],
|
||||
'date' => $nowIso,
|
||||
'author' => [
|
||||
['reference' => 'Practitioner/prac-1', 'display' => 'Treating Doctor'],
|
||||
['reference' => 'Practitioner/prac-1', 'display' => $doctorName],
|
||||
],
|
||||
'title' => 'Consultation Record',
|
||||
'section' => [
|
||||
|
|
@ -5155,7 +5203,7 @@ class AbdmGateway extends BaseController
|
|||
'resource' => [
|
||||
'resourceType' => 'Practitioner',
|
||||
'id' => 'prac-1',
|
||||
'name' => [['text' => 'Treating Doctor']],
|
||||
'name' => [['text' => $doctorName]],
|
||||
],
|
||||
],
|
||||
],
|
||||
|
|
|
|||
|
|
@ -4936,8 +4936,15 @@ class Opd_prescription extends BaseController
|
|||
$bundle = $this->fhirR4Builder->buildOpConsultBundle($patient, $encounter, $medications, $conditions, $clinicalContext);
|
||||
$bundleJson = (string) json_encode($bundle, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
|
||||
$user = function_exists('auth') ? auth()->user() : null;
|
||||
$generatedBy = (string) ($user->id ?? session('user_id') ?? 'system');
|
||||
$generatedBy = 'system';
|
||||
try {
|
||||
if (session_status() === PHP_SESSION_ACTIVE) {
|
||||
$user = function_exists('auth') ? auth()->user() : null;
|
||||
$generatedBy = (string) ($user->id ?? session('user_id') ?? 'system');
|
||||
}
|
||||
} catch (\Throwable) {
|
||||
$generatedBy = 'system';
|
||||
}
|
||||
$generatedAt = Time::now('Asia/Kolkata')->toDateTimeString();
|
||||
|
||||
// Overwrite the latest stored bundle for this opd_id / session
|
||||
|
|
@ -4975,6 +4982,7 @@ class Opd_prescription extends BaseController
|
|||
'ok' => 1,
|
||||
'message' => 'FHIR bundle regenerated successfully',
|
||||
'document_id' => $documentId,
|
||||
'bundle' => $bundle,
|
||||
'generated_at' => $generatedAt,
|
||||
'entry_count' => isset($bundle['entry']) ? count($bundle['entry']) : 0,
|
||||
];
|
||||
|
|
|
|||
|
|
@ -243,11 +243,11 @@ class M3HiuWorkflowService
|
|||
|
||||
$consentRowId = (int) ($row['id'] ?? 0);
|
||||
|
||||
// Fast-check: if a child reconcile/data_fetch workflow for this request_id has already reached terminal state
|
||||
// Fast-check: if a child reconcile/data_fetch workflow for this request_id has reached terminal state (EXPIRED, REVOKED, DENIED)
|
||||
$terminalCheck = $this->db->table('abdm_hiu_workflows')
|
||||
->select('id, workflow_state, operation')
|
||||
->where('request_id', $requestId)
|
||||
->whereIn('workflow_state', ['COMPLETED', 'EXPIRED', 'REVOKED', 'DENIED'])
|
||||
->whereIn('workflow_state', ['EXPIRED', 'REVOKED', 'DENIED'])
|
||||
->orderBy('id', 'DESC')
|
||||
->get(1)
|
||||
->getRowArray();
|
||||
|
|
@ -289,9 +289,27 @@ class M3HiuWorkflowService
|
|||
?? ''
|
||||
)));
|
||||
|
||||
$allArtifactsReceived = true;
|
||||
$resolvedConsentId = trim((string) (
|
||||
$consentResult['abdm_consent_request_id']
|
||||
?? $consentResult['consent_request_id']
|
||||
?? $consentResult['abdm_consent_artifact_id']
|
||||
?? $consentResult['consent_id']
|
||||
?? ''
|
||||
));
|
||||
if ($resolvedConsentId !== '' && $this->db->tableExists('abdm_hiu_consent_artifacts')) {
|
||||
$unreceived = $this->db->table('abdm_hiu_consent_artifacts')
|
||||
->where('consent_request_id', $resolvedConsentId)
|
||||
->whereNotIn('last_status', ['RECEIVED', 'DATA_RECEIVED', 'EXPIRED', 'REVOKED', 'DENIED', 'COMPLETED'])
|
||||
->countAllResults();
|
||||
if ($unreceived > 0) {
|
||||
$allArtifactsReceived = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (in_array($consentState, ['revoked', 'denied', 'expired'], true)) {
|
||||
$this->markConsentRequestTerminal($consentRowId, strtoupper($consentState));
|
||||
} elseif ($cascade['granted'] && $cascade['failed'] === 0 && $cascade['data_updates'] > 0) {
|
||||
} elseif ($cascade['granted'] && $cascade['failed'] === 0 && $cascade['data_updates'] > 0 && $allArtifactsReceived) {
|
||||
$this->markConsentRequestTerminal($consentRowId, 'COMPLETED');
|
||||
}
|
||||
} else {
|
||||
|
|
@ -432,7 +450,8 @@ class M3HiuWorkflowService
|
|||
$artifactResult = $this->runOperation('data_fetch', $artifactPayload);
|
||||
if ((int) ($artifactResult['ok'] ?? 0) === 1) {
|
||||
$result['data_updates']++;
|
||||
$this->markArtifactPolled($resolvedConsentId, $artifactId, (string) ($artifactResult['consent_status'] ?? ''));
|
||||
$status = (string) ($artifactResult['workflow_state'] ?? $artifactResult['status'] ?? $artifactResult['consent_status'] ?? '');
|
||||
$this->markArtifactPolled($resolvedConsentId, $artifactId, $status);
|
||||
} else {
|
||||
$result['failed']++;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user