feat(abdm-m2): enable care context discovery and direct linking for invoice records
This commit is contained in:
parent
ccd5909fc6
commit
f7c30529a3
|
|
@ -6009,7 +6009,8 @@ class AbdmGateway extends BaseController
|
|||
string $patientName,
|
||||
string $taskType = '',
|
||||
string $entityId = '',
|
||||
int $taskId = 0
|
||||
int $taskId = 0,
|
||||
string $source = ''
|
||||
): array {
|
||||
$this->db = $this->db ?? \Config\Database::connect();
|
||||
$careContextsV3 = [];
|
||||
|
|
@ -6113,6 +6114,36 @@ class AbdmGateway extends BaseController
|
|||
'is_primary' => true,
|
||||
]);
|
||||
}
|
||||
} elseif (in_array($taskType, ['invoice_publish', 'invoice_record_publish'], true)) {
|
||||
$invoicePayload = null;
|
||||
$candidateSources = [];
|
||||
if ($source !== '' && in_array($source, ['opd_invoice', 'charges_invoice', 'ipd_invoice'], true)) {
|
||||
$candidateSources[] = $source;
|
||||
}
|
||||
$candidateSources = array_values(array_unique(array_merge($candidateSources, ['opd_invoice', 'charges_invoice', 'ipd_invoice'])));
|
||||
|
||||
foreach ($candidateSources as $candSource) {
|
||||
try {
|
||||
$invoicePayload = $this->buildInvoiceSourceRecordPayload($candSource, $taskEntityId, $patientId, '');
|
||||
if ($invoicePayload !== null) {
|
||||
break;
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
// ignore and try next candidate source
|
||||
}
|
||||
}
|
||||
|
||||
if ($invoicePayload !== null) {
|
||||
$addContext([
|
||||
'careContextId' => (string) $invoicePayload['care_context_reference'],
|
||||
'referenceNumber' => (string) $invoicePayload['care_context_reference'],
|
||||
'display' => (string) $invoicePayload['care_context_display'],
|
||||
'record_type' => 'InvoiceRecord',
|
||||
'patient_id' => $patientId,
|
||||
'is_fhir_ready' => true,
|
||||
'is_primary' => true,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6344,6 +6375,98 @@ class AbdmGateway extends BaseController
|
|||
}
|
||||
}
|
||||
|
||||
// 6b. Query recent invoices / billing records for this patient
|
||||
if ($this->db->tableExists('opd_master')) {
|
||||
$opdFields = $this->db->getFieldNames('opd_master') ?? [];
|
||||
if (in_array('opd_fee_amount', $opdFields, true)) {
|
||||
$codeCol = in_array('opd_code', $opdFields, true) ? 'opd_code' : 'opd_id';
|
||||
$opdInvoices = $this->db->table('opd_master')
|
||||
->select('opd_id, ' . $codeCol . ' as opd_code, p_id, apointment_date, opd_book_date, opd_fee_amount')
|
||||
->where('p_id', $patientId)
|
||||
->where('opd_fee_amount >', 0)
|
||||
->orderBy('opd_id', 'DESC')
|
||||
->limit(10)
|
||||
->get()
|
||||
->getResultArray();
|
||||
foreach ($opdInvoices as $oi) {
|
||||
$rawDate = ! empty($oi['apointment_date']) && $oi['apointment_date'] !== '0000-00-00 00:00:00'
|
||||
? $oi['apointment_date']
|
||||
: (! empty($oi['opd_book_date']) ? $oi['opd_book_date'] : date('Y-m-d'));
|
||||
$visitDate = date('Y-m-d', strtotime((string) $rawDate));
|
||||
$ccRef = 'INVOICE-OPD-' . $oi['opd_id'] . '-' . $visitDate;
|
||||
$display = 'Invoice ' . ((string) ($oi['opd_code'] ?: $oi['opd_id'])) . ' (OPD - Rs ' . number_format((float) $oi['opd_fee_amount'], 2) . ')';
|
||||
$addContext([
|
||||
'careContextId' => $ccRef,
|
||||
'referenceNumber' => $ccRef,
|
||||
'display' => $display,
|
||||
'record_type' => 'InvoiceRecord',
|
||||
'patient_id' => $patientId,
|
||||
'is_fhir_ready' => true,
|
||||
'is_primary' => false,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($this->db->tableExists('invoice_master')) {
|
||||
$chgFields = $this->db->getFieldNames('invoice_master') ?? [];
|
||||
if (in_array('net_amount', $chgFields, true) && in_array('attach_id', $chgFields, true)) {
|
||||
$invCodeCol = in_array('invoice_code', $chgFields, true) ? 'invoice_code' : 'id';
|
||||
$dateCol = in_array('inv_date', $chgFields, true) ? 'inv_date' : 'id';
|
||||
$attachTypeClause = in_array('attach_type', $chgFields, true);
|
||||
$builder = $this->db->table('invoice_master')
|
||||
->select('id, ' . $invCodeCol . ' as invoice_code, attach_id, ' . $dateCol . ' as inv_date, net_amount')
|
||||
->where('attach_id', $patientId);
|
||||
if ($attachTypeClause) {
|
||||
$builder->where('attach_type', 0);
|
||||
}
|
||||
$chgInvoices = $builder->orderBy('id', 'DESC')->limit(10)->get()->getResultArray();
|
||||
foreach ($chgInvoices as $ci) {
|
||||
$rawDate = ! empty($ci['inv_date']) ? $ci['inv_date'] : date('Y-m-d');
|
||||
$visitDate = date('Y-m-d', strtotime((string) $rawDate));
|
||||
$ccRef = 'INVOICE-CHG-' . $ci['id'] . '-' . $visitDate;
|
||||
$display = 'Invoice ' . ((string) ($ci['invoice_code'] ?: $ci['id'])) . ' (Charges - Rs ' . number_format((float) $ci['net_amount'], 2) . ')';
|
||||
$addContext([
|
||||
'careContextId' => $ccRef,
|
||||
'referenceNumber' => $ccRef,
|
||||
'display' => $display,
|
||||
'record_type' => 'InvoiceRecord',
|
||||
'patient_id' => $patientId,
|
||||
'is_fhir_ready' => true,
|
||||
'is_primary' => false,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($this->db->tableExists('ipd_master')) {
|
||||
$ipdFields = $this->db->getFieldNames('ipd_master') ?? [];
|
||||
if (in_array('net_amount', $ipdFields, true)) {
|
||||
$ipdCodeCol = in_array('ipd_code', $ipdFields, true) ? 'ipd_code' : 'id';
|
||||
$ipdInvoices = $this->db->table('ipd_master')
|
||||
->select('id, ' . $ipdCodeCol . ' as ipd_code, p_id, discharge_date, register_date, net_amount')
|
||||
->where('p_id', $patientId)
|
||||
->where('net_amount >', 0)
|
||||
->orderBy('id', 'DESC')
|
||||
->limit(5)
|
||||
->get()
|
||||
->getResultArray();
|
||||
foreach ($ipdInvoices as $ii) {
|
||||
$rawDate = ! empty($ii['discharge_date']) ? $ii['discharge_date'] : (! empty($ii['register_date']) ? $ii['register_date'] : date('Y-m-d'));
|
||||
$visitDate = date('Y-m-d', strtotime((string) $rawDate));
|
||||
$ccRef = 'INVOICE-IPD-' . $ii['id'] . '-' . $visitDate;
|
||||
$display = 'Invoice ' . ((string) ($ii['ipd_code'] ?: $ii['id'])) . ' (IPD - Rs ' . number_format((float) $ii['net_amount'], 2) . ')';
|
||||
$addContext([
|
||||
'careContextId' => $ccRef,
|
||||
'referenceNumber' => $ccRef,
|
||||
'display' => $display,
|
||||
'record_type' => 'InvoiceRecord',
|
||||
'patient_id' => $patientId,
|
||||
'is_fhir_ready' => true,
|
||||
'is_primary' => false,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 7. Fallback: default registration file care context
|
||||
if (empty($careContextsV3)) {
|
||||
$ccRef = 'REG-' . $patientRef;
|
||||
|
|
@ -10913,6 +11036,7 @@ class AbdmGateway extends BaseController
|
|||
$taskType = '';
|
||||
$entityId = '';
|
||||
$taskId = 0;
|
||||
$source = '';
|
||||
if (method_exists($this->request, 'getVar')) {
|
||||
$patientId = (int) ($this->request->getVar('patient_id') ?? 0);
|
||||
$abhaAddress = trim((string) ($this->request->getVar('abha_address') ?? ''));
|
||||
|
|
@ -10920,6 +11044,7 @@ class AbdmGateway extends BaseController
|
|||
$taskType = trim((string) ($this->request->getVar('task_type') ?? ''));
|
||||
$entityId = trim((string) ($this->request->getVar('entity_id') ?? ''));
|
||||
$taskId = (int) ($this->request->getVar('task_id') ?? 0);
|
||||
$source = trim((string) ($this->request->getVar('source') ?? ''));
|
||||
}
|
||||
if ($patientId <= 0 && ! empty($_REQUEST['patient_id'])) {
|
||||
$patientId = (int) $_REQUEST['patient_id'];
|
||||
|
|
@ -10939,6 +11064,9 @@ class AbdmGateway extends BaseController
|
|||
if ($taskId <= 0 && ! empty($_REQUEST['task_id'])) {
|
||||
$taskId = (int) $_REQUEST['task_id'];
|
||||
}
|
||||
if ($source === '' && ! empty($_REQUEST['source'])) {
|
||||
$source = trim((string) $_REQUEST['source']);
|
||||
}
|
||||
|
||||
if ($patientId <= 0 && $abhaAddress === '' && $pCode === '') {
|
||||
return $this->response->setJSON(['ok' => 0, 'error_text' => 'patient_id, abha_address, or p_code is required']);
|
||||
|
|
@ -11000,7 +11128,7 @@ class AbdmGateway extends BaseController
|
|||
$rawPhone = trim((string) ($patient['mphone1'] ?? $patient['mphone2'] ?? ''));
|
||||
$cleanPhone = substr(preg_replace('/\D/', '', $rawPhone), -10);
|
||||
|
||||
[$careContextsV3, $careContextsFull] = $this->findCareContextsForPatient($patientId, $patientRef, $patientName, $taskType, $entityId, $taskId);
|
||||
[$careContextsV3, $careContextsFull] = $this->findCareContextsForPatient($patientId, $patientRef, $patientName, $taskType, $entityId, $taskId, $source);
|
||||
|
||||
// Fetch already-linked care contexts from Bridge if ABHA address is present
|
||||
$linkedRefs = [];
|
||||
|
|
|
|||
|
|
@ -695,9 +695,13 @@ class AbdmTaskBoard extends BaseController
|
|||
$rows = [];
|
||||
|
||||
if ($this->db->tableExists('opd_master')) {
|
||||
foreach ($this->db->table('opd_master')
|
||||
->select('opd_id AS bill_id, opd_code AS bill_code, p_id AS patient_id, P_name AS patient_name, apointment_date AS bill_date, opd_fee_amount AS amount')
|
||||
->orderBy('opd_id', 'DESC')
|
||||
$builder = $this->db->table('opd_master o')
|
||||
->select("o.opd_id AS bill_id, o.opd_code AS bill_code, o.p_id AS patient_id, COALESCE(NULLIF(o.P_name, ''), p.p_fname, '') AS patient_name, o.apointment_date AS bill_date, o.opd_fee_amount AS amount, COALESCE(NULLIF(p.abha_address, ''), NULLIF(p.abha_id, ''), '') AS abha_id", false);
|
||||
if ($this->db->tableExists('patient_master')) {
|
||||
$builder->join('patient_master p', 'p.id = o.p_id', 'left');
|
||||
}
|
||||
foreach ($builder
|
||||
->orderBy('o.opd_id', 'DESC')
|
||||
->limit(100)
|
||||
->get()
|
||||
->getResultArray() as $row) {
|
||||
|
|
@ -706,9 +710,12 @@ class AbdmTaskBoard extends BaseController
|
|||
}
|
||||
|
||||
if ($this->db->tableExists('invoice_master')) {
|
||||
foreach ($this->db->table('invoice_master i')
|
||||
->select('i.id AS bill_id, i.invoice_code AS bill_code, i.attach_id AS patient_id, COALESCE(NULLIF(i.inv_name, ""), p.p_fname) AS patient_name, i.inv_date AS bill_date, i.net_amount AS amount')
|
||||
->join('patient_master p', 'p.id = i.attach_id AND i.attach_type = 0', 'left')
|
||||
$builder = $this->db->table('invoice_master i')
|
||||
->select("i.id AS bill_id, i.invoice_code AS bill_code, i.attach_id AS patient_id, COALESCE(NULLIF(i.inv_name, ''), p.p_fname, '') AS patient_name, i.inv_date AS bill_date, i.net_amount AS amount, COALESCE(NULLIF(p.abha_address, ''), NULLIF(p.abha_id, ''), '') AS abha_id", false);
|
||||
if ($this->db->tableExists('patient_master')) {
|
||||
$builder->join('patient_master p', 'p.id = i.attach_id AND i.attach_type = 0', 'left');
|
||||
}
|
||||
foreach ($builder
|
||||
->orderBy('i.id', 'DESC')
|
||||
->limit(100)
|
||||
->get()
|
||||
|
|
@ -718,9 +725,12 @@ class AbdmTaskBoard extends BaseController
|
|||
}
|
||||
|
||||
if ($this->db->tableExists('ipd_master')) {
|
||||
foreach ($this->db->table('ipd_master i')
|
||||
->select("i.id AS bill_id, i.ipd_code AS bill_code, i.p_id AS patient_id, COALESCE(NULLIF(NULLIF(TRIM(i.P_name), ''), '0'), NULLIF(TRIM(p.p_fname), '')) AS patient_name, COALESCE(i.discharge_date, i.register_date) AS bill_date, i.net_amount AS amount", false)
|
||||
->join('patient_master p', 'p.id = i.p_id', 'left')
|
||||
$builder = $this->db->table('ipd_master i')
|
||||
->select("i.id AS bill_id, i.ipd_code AS bill_code, i.p_id AS patient_id, COALESCE(NULLIF(NULLIF(TRIM(i.P_name), ''), '0'), NULLIF(TRIM(p.p_fname), ''), '') AS patient_name, COALESCE(i.discharge_date, i.register_date) AS bill_date, i.net_amount AS amount, COALESCE(NULLIF(p.abha_address, ''), NULLIF(p.abha_id, ''), '') AS abha_id", false);
|
||||
if ($this->db->tableExists('patient_master')) {
|
||||
$builder->join('patient_master p', 'p.id = i.p_id', 'left');
|
||||
}
|
||||
foreach ($builder
|
||||
->orderBy('i.id', 'DESC')
|
||||
->limit(100)
|
||||
->get()
|
||||
|
|
@ -819,13 +829,17 @@ class AbdmTaskBoard extends BaseController
|
|||
$statusTone = 'danger';
|
||||
}
|
||||
|
||||
$billDate = ! empty($row['bill_date']) ? date('Y-m-d', strtotime((string) $row['bill_date'])) : date('Y-m-d');
|
||||
$sourcePrefix = $row['source_key'] === 'opd_invoice' ? 'OPD' : ($row['source_key'] === 'ipd_invoice' ? 'IPD' : 'CHG');
|
||||
$defaultCareContext = 'INVOICE-' . $sourcePrefix . '-' . $billId . '-' . $billDate;
|
||||
|
||||
$row['record_status_label'] = $statusLabel;
|
||||
$row['record_status_tone'] = $statusTone;
|
||||
$row['push_status'] = $pushStatus;
|
||||
$row['link_status'] = $linkStatus;
|
||||
$row['queue_id'] = trim((string) ($hr['abdm_txn_id'] ?? ''));
|
||||
$row['bridge_record_id'] = (int) ($hr['bridge_record_id'] ?? 0);
|
||||
$row['care_context_reference'] = trim((string) ($hr['care_context_reference'] ?? ''));
|
||||
$row['care_context_reference'] = trim((string) ($hr['care_context_reference'] ?? '')) ?: $defaultCareContext;
|
||||
}
|
||||
unset($row);
|
||||
|
||||
|
|
|
|||
|
|
@ -474,6 +474,8 @@
|
|||
data-invoice-source="<?= esc((string) ($invoice['source_key'] ?? '')) ?>"
|
||||
data-bill-id="<?= (int) ($invoice['bill_id'] ?? 0) ?>"
|
||||
data-patient-id="<?= (int) ($invoice['patient_id'] ?? 0) ?>"
|
||||
data-abha-id="<?= esc((string) ($invoice['abha_id'] ?? '')) ?>"
|
||||
data-care-context="<?= esc((string) ($invoice['care_context_reference'] ?? '')) ?>"
|
||||
data-push-status="<?= esc($pushStatus) ?>"
|
||||
>
|
||||
<td><?= esc((string) ($invoice['source'] ?? '')) ?></td>
|
||||
|
|
@ -481,6 +483,9 @@
|
|||
<td>
|
||||
<div><?= esc((string) ($invoice['patient_name'] ?? '')) ?></div>
|
||||
<small class="text-muted">#<?= (int) ($invoice['patient_id'] ?? 0) ?></small>
|
||||
<?php if (! empty($invoice['abha_id'])): ?>
|
||||
<div><span class="text-primary small" title="ABHA"><i class="bi bi-person-check me-1"></i><?= esc((string) $invoice['abha_id']) ?></span></div>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?= esc(substr((string) ($invoice['bill_date'] ?? ''), 0, 16)) ?></td>
|
||||
<td class="text-end"><?= number_format((float) ($invoice['amount'] ?? 0), 2) ?></td>
|
||||
|
|
@ -497,7 +502,17 @@
|
|||
<?php if ($alreadySubmitted): ?>
|
||||
<span class="badge bg-success ms-1"><i class="bi bi-check-circle"></i> Linked</span>
|
||||
<?php else: ?>
|
||||
<button type="button" class="btn btn-sm btn-outline-success btn-invoice-care-link ms-1" data-patient-id="<?= (int) ($invoice['patient_id'] ?? 0) ?>" data-abha-id="<?= esc((string) ($invoice['abha_id'] ?? '')) ?>" data-patient-name="<?= esc((string) ($invoice['patient_name'] ?? '')) ?>" title="Link Care Context with patient ABHA"><i class="bi bi-link-45deg"></i> Link Context</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm btn-outline-success btn-invoice-care-link ms-1"
|
||||
data-bill-id="<?= (int) ($invoice['bill_id'] ?? 0) ?>"
|
||||
data-invoice-source="<?= esc((string) ($invoice['source_key'] ?? '')) ?>"
|
||||
data-patient-id="<?= (int) ($invoice['patient_id'] ?? 0) ?>"
|
||||
data-abha-id="<?= esc((string) ($invoice['abha_id'] ?? '')) ?>"
|
||||
data-patient-name="<?= esc((string) ($invoice['patient_name'] ?? '')) ?>"
|
||||
data-care-context="<?= esc((string) ($invoice['care_context_reference'] ?? '')) ?>"
|
||||
title="Link Care Context with patient ABHA"
|
||||
><i class="bi bi-link-45deg"></i> Link Context</button>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
@ -3512,19 +3527,82 @@
|
|||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll('.btn-opd-care-context-link, .btn-invoice-care-link').forEach(function (btn) {
|
||||
document.querySelectorAll('.btn-opd-care-context-link').forEach(function (btn) {
|
||||
btn.addEventListener('click', function () {
|
||||
var row = btn.closest('tr');
|
||||
var patientId = parseInt(btn.getAttribute('data-patient-id') || '0', 10);
|
||||
var abhaId = (btn.getAttribute('data-abha-id') || '').trim();
|
||||
var patientName = (btn.getAttribute('data-patient-name') || '').trim();
|
||||
var opdId = (btn.getAttribute('data-opd-id') || '').trim();
|
||||
var taskType = opdId ? 'opd_prescription_publish' : '';
|
||||
var entityId = opdId || '';
|
||||
if (typeof window.openAbdmHipLinkModal === 'function') {
|
||||
window.openAbdmHipLinkModal(patientId, abhaId, {
|
||||
patient_name: patientName,
|
||||
task_type: taskType,
|
||||
entity_id: entityId
|
||||
task_type: 'opd_prescription_publish',
|
||||
entity_id: opdId,
|
||||
onLinked: function (res) {
|
||||
if (!row) return;
|
||||
var actionCell = btn.parentNode;
|
||||
if (actionCell) {
|
||||
btn.outerHTML = '<span class="badge bg-success ms-1"><i class="bi bi-check-circle"></i> Linked</span>';
|
||||
}
|
||||
var statusBadge = row.querySelector('.opd-consult-status-badge');
|
||||
if (statusBadge) {
|
||||
statusBadge.className = 'badge bg-success opd-consult-status-badge';
|
||||
statusBadge.textContent = 'Linked';
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll('.btn-invoice-care-link').forEach(function (btn) {
|
||||
btn.addEventListener('click', function () {
|
||||
var row = btn.closest('tr');
|
||||
var patientId = parseInt(btn.getAttribute('data-patient-id') || (row ? row.getAttribute('data-patient-id') : '0') || '0', 10);
|
||||
var abhaId = (btn.getAttribute('data-abha-id') || (row ? row.getAttribute('data-abha-id') : '') || '').trim();
|
||||
var patientName = (btn.getAttribute('data-patient-name') || '').trim();
|
||||
var billId = (btn.getAttribute('data-bill-id') || (row ? row.getAttribute('data-bill-id') : '') || '').trim();
|
||||
var invoiceSource = (btn.getAttribute('data-invoice-source') || (row ? row.getAttribute('data-invoice-source') : '') || '').trim();
|
||||
var careContextRef = (btn.getAttribute('data-care-context') || (row ? row.getAttribute('data-care-context') : '') || '').trim();
|
||||
|
||||
if (typeof window.openAbdmHipLinkModal === 'function') {
|
||||
window.openAbdmHipLinkModal(patientId, abhaId, {
|
||||
patient_name: patientName,
|
||||
task_type: 'invoice_publish',
|
||||
entity_id: billId,
|
||||
source: invoiceSource,
|
||||
care_context: careContextRef,
|
||||
onLinked: function (res) {
|
||||
if (!row) return;
|
||||
// Update Link Status cell (cell 6)
|
||||
var linkStatusCell = row.children[6];
|
||||
if (linkStatusCell) {
|
||||
linkStatusCell.innerHTML = '<span class="badge bg-success">LINKED</span>';
|
||||
}
|
||||
// Update Status badge (cell 5)
|
||||
var pushStatusBadge = row.querySelector('.invoice-status-badge');
|
||||
if (pushStatusBadge) {
|
||||
pushStatusBadge.className = 'badge bg-success invoice-status-badge';
|
||||
pushStatusBadge.textContent = 'Linked';
|
||||
}
|
||||
// Update Gateway Reference cell (cell 7)
|
||||
var gatewayCell = row.querySelector('.invoice-details');
|
||||
if (gatewayCell && res && res.care_contexts && res.care_contexts.length > 0) {
|
||||
var firstCc = res.care_contexts[0].ref || '';
|
||||
if (firstCc) {
|
||||
gatewayCell.innerHTML = '<div class="text-truncate" title="' + firstCc + '"><strong>CC:</strong> ' + firstCc + '</div>';
|
||||
}
|
||||
}
|
||||
// Update Action button in Action cell (cell 8)
|
||||
var actionCell = row.children[8];
|
||||
if (actionCell) {
|
||||
var linkBtn = actionCell.querySelector('.btn-invoice-care-link');
|
||||
if (linkBtn) {
|
||||
linkBtn.outerHTML = '<span class="badge bg-success ms-1"><i class="bi bi-check-circle"></i> Linked</span>';
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -406,7 +406,7 @@
|
|||
/**
|
||||
* Load patient demographics and care contexts from server.
|
||||
*/
|
||||
window.loadPatientCareContexts = function(patientId, abhaAddress, taskType, entityId, taskId) {
|
||||
window.loadPatientCareContexts = function(patientId, abhaAddress, taskType, entityId, taskId, source) {
|
||||
var loading = document.getElementById('hipCareContextsLoading');
|
||||
var container = document.getElementById('hipCareContextsContainer');
|
||||
if (loading) loading.classList.remove('d-none');
|
||||
|
|
@ -415,6 +415,7 @@
|
|||
taskType = taskType || (window.currentHipTaskContext ? window.currentHipTaskContext.taskType : '');
|
||||
entityId = entityId || (window.currentHipTaskContext ? window.currentHipTaskContext.entityId : '');
|
||||
taskId = taskId || (window.currentHipTaskContext ? window.currentHipTaskContext.taskId : 0);
|
||||
source = source || (window.currentHipTaskContext ? window.currentHipTaskContext.source : '');
|
||||
|
||||
var csrf = getCsrfData();
|
||||
var url = '<?= base_url('AbdmGateway/hip_patient_care_contexts') ?>'
|
||||
|
|
@ -422,7 +423,8 @@
|
|||
+ '&abha_address=' + encodeURIComponent(abhaAddress || '')
|
||||
+ '&task_type=' + encodeURIComponent(taskType || '')
|
||||
+ '&entity_id=' + encodeURIComponent(entityId || '')
|
||||
+ '&task_id=' + encodeURIComponent(taskId || 0);
|
||||
+ '&task_id=' + encodeURIComponent(taskId || 0)
|
||||
+ '&source=' + encodeURIComponent(source || '');
|
||||
|
||||
fetch(url, {
|
||||
method: 'GET',
|
||||
|
|
@ -531,6 +533,8 @@
|
|||
taskId: prefill.task_id || 0,
|
||||
taskType: prefill.task_type || '',
|
||||
entityId: prefill.entity_id || '',
|
||||
source: prefill.source || '',
|
||||
careContext: prefill.care_context || '',
|
||||
onLinked: prefill.onLinked || null
|
||||
};
|
||||
|
||||
|
|
@ -567,7 +571,7 @@
|
|||
|
||||
// Load visits
|
||||
if (patientId > 0 || (abhaAddress && abhaAddress.length > 3)) {
|
||||
loadPatientCareContexts(patientId, abhaAddress, prefill.task_type, prefill.entity_id, prefill.task_id);
|
||||
loadPatientCareContexts(patientId, abhaAddress, prefill.task_type, prefill.entity_id, prefill.task_id, prefill.source);
|
||||
} else {
|
||||
var container = document.getElementById('hipCareContextsContainer');
|
||||
if (container) {
|
||||
|
|
@ -651,6 +655,29 @@
|
|||
alertBox.innerHTML += '<div class="mt-2 pt-2 border-top border-success-subtle text-dark small"><i class="bi bi-file-earmark-medical text-success me-1"></i><strong>FHIR Document Stored on Bridge:</strong> Consultation bundle is active on Bridge for Care Context <code>' + (pRes.care_context_reference || firstRef) + '</code>.<br><i class="bi bi-info-circle text-primary me-1"></i><strong>To view in PHR App:</strong> Open your PHR app (e.g. ABHA App) → tap <em>Linked Facilities</em> → tap <em>"Fetch Records" / "Pull Records"</em>.</div>';
|
||||
}
|
||||
}).catch(function() {});
|
||||
} else if (ctxTaskType === 'invoice_publish') {
|
||||
var pushData = new URLSearchParams();
|
||||
pushData.append('source', (window.currentHipTaskContext ? window.currentHipTaskContext.source : '') || '');
|
||||
pushData.append('bill_id', ctxEntityId);
|
||||
pushData.append('patient_id', ctxPatientId);
|
||||
pushData.append('abha_id', abhaAddress);
|
||||
if (firstRef) pushData.append('care_context_reference', firstRef);
|
||||
pushData.append(csrf.name || 'csrf_hms', csrf.hash);
|
||||
|
||||
fetch('<?= base_url('AbdmGateway/share_invoice_source_bundle') ?>', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
'Accept': 'application/json'
|
||||
},
|
||||
body: pushData.toString()
|
||||
}).then(function(r) { return r.json(); }).then(function(pRes) {
|
||||
updateCsrf(pRes);
|
||||
if (pRes && pRes.ok === 1 && alertBox) {
|
||||
alertBox.innerHTML += '<div class="mt-2 pt-2 border-top border-success-subtle text-dark small"><i class="bi bi-file-earmark-medical text-success me-1"></i><strong>FHIR Document Stored on Bridge:</strong> Invoice bundle is active on Bridge for Care Context <code>' + (pRes.care_context_reference || firstRef) + '</code>.<br><i class="bi bi-info-circle text-primary me-1"></i><strong>To view in PHR App:</strong> Open your PHR app (e.g. ABHA App) → tap <em>Linked Facilities</em> → tap <em>"Fetch Records" / "Pull Records"</em>.</div>';
|
||||
}
|
||||
}).catch(function() {});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -97,6 +97,17 @@ final class CareContextDiscoveryTest extends CIUnitTestCase
|
|||
abdm_care_context_reference TEXT
|
||||
)");
|
||||
|
||||
$db->query("CREATE TABLE IF NOT EXISTS " . $db->prefixTable('invoice_master') . " (
|
||||
id INTEGER PRIMARY KEY,
|
||||
invoice_code TEXT,
|
||||
attach_id INTEGER,
|
||||
attach_type INTEGER,
|
||||
inv_date TEXT,
|
||||
net_amount REAL
|
||||
)");
|
||||
|
||||
$db->resetDataCache();
|
||||
|
||||
$db->table('charge_master')->emptyTable();
|
||||
$db->table('lab_request')->emptyTable();
|
||||
$db->table('opd_prescription')->emptyTable();
|
||||
|
|
@ -105,6 +116,7 @@ final class CareContextDiscoveryTest extends CIUnitTestCase
|
|||
$db->table('patient_master')->emptyTable();
|
||||
$db->table('ipd_master')->emptyTable();
|
||||
$db->table('immunization_records')->emptyTable();
|
||||
$db->table('invoice_master')->emptyTable();
|
||||
|
||||
$db->table('patient_master')->insert([
|
||||
'id' => 12,
|
||||
|
|
@ -353,5 +365,49 @@ final class CareContextDiscoveryTest extends CIUnitTestCase
|
|||
$refs = array_column($v3, 'referenceNumber');
|
||||
$this->assertContains('OPD-12-S77-20260929', $refs);
|
||||
}
|
||||
|
||||
public function testDiscoversInvoiceCareContextWhenInvoiceTaskRequested(): void
|
||||
{
|
||||
$db = \Config\Database::connect();
|
||||
$db->table('invoice_master')->emptyTable();
|
||||
$db->table('invoice_master')->insert([
|
||||
'id' => 88,
|
||||
'invoice_code' => 'INV-88',
|
||||
'attach_id' => 12,
|
||||
'attach_type' => 0,
|
||||
'inv_date' => '2026-09-30',
|
||||
'net_amount' => 450.00,
|
||||
]);
|
||||
|
||||
$refGateway = new ReflectionClass($this->gateway);
|
||||
$method = $refGateway->getMethod('findCareContextsForPatient');
|
||||
$method->setAccessible(true);
|
||||
|
||||
[$v3, $full] = $method->invoke(
|
||||
$this->gateway,
|
||||
12,
|
||||
'P26071000012',
|
||||
'KESHAV SINGH',
|
||||
'invoice_publish',
|
||||
'88',
|
||||
0,
|
||||
'charges_invoice'
|
||||
);
|
||||
|
||||
$refs = array_column($v3, 'referenceNumber');
|
||||
$this->assertContains('INVOICE-CHG-88-2026-09-30', $refs);
|
||||
|
||||
$invoiceCtx = null;
|
||||
foreach ($full as $ctx) {
|
||||
if ($ctx['careContextId'] === 'INVOICE-CHG-88-2026-09-30') {
|
||||
$invoiceCtx = $ctx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->assertNotNull($invoiceCtx);
|
||||
$this->assertSame('InvoiceRecord', $invoiceCtx['record_type']);
|
||||
$this->assertTrue($invoiceCtx['is_primary']);
|
||||
$this->assertTrue($invoiceCtx['is_fhir_ready']);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user