Store ABHA card and improve patient comparison
This commit is contained in:
parent
6a670d4c48
commit
73ad7ef11f
|
|
@ -474,6 +474,7 @@ class Abha extends BaseController
|
|||
'abha_qr_url' => $abhaQrUrl,
|
||||
'patient_mobile' => $mobileNo,
|
||||
'mobile_verified' => $mobileVerified,
|
||||
'stored_abha_card' => trim((string) ($patient['abha_card_base64'] ?? '')),
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -803,6 +804,7 @@ class Abha extends BaseController
|
|||
$abhaMeta = [
|
||||
'abha_address' => (string) ($this->request->getPost('abha_address') ?? ''),
|
||||
'profile_photo' => (string) ($this->request->getPost('photo') ?? ''),
|
||||
'card_base64' => (string) ($this->request->getPost('card_base64') ?? ''),
|
||||
'verified_status' => (string) ($this->request->getPost('verified_status') ?? ''),
|
||||
'verification_type' => (string) ($this->request->getPost('verification_type') ?? ''),
|
||||
'kyc_verified' => $this->request->getPost('kyc_verified'),
|
||||
|
|
@ -1025,7 +1027,7 @@ class Abha extends BaseController
|
|||
}
|
||||
|
||||
$selectFields = array_values(array_intersect(
|
||||
['id', 'p_code', 'p_fname', 'p_lname', 'gender', 'dob', 'age', 'mphone1', 'udai', 'add1', 'district', 'state', 'zip'],
|
||||
['id', 'p_code', 'p_fname', 'p_lname', 'gender', 'dob', 'age', 'mphone1', 'udai', 'add1', 'district', 'state', 'zip', 'profile_file_id', 'profile_picture', 'abha_profile_photo_base64'],
|
||||
$fields
|
||||
));
|
||||
$select = implode(',', $selectFields);
|
||||
|
|
@ -1109,6 +1111,7 @@ class Abha extends BaseController
|
|||
'dob' => $rowDob,
|
||||
'age' => $rowAgeYears,
|
||||
'mobile' => (string) ($row['mphone1'] ?? ''),
|
||||
'photo_url' => $this->resolvePatientPhotoUrl($row),
|
||||
'address' => trim(implode(', ', array_filter([
|
||||
(string) ($row['add1'] ?? ''),
|
||||
(string) ($row['district'] ?? ''),
|
||||
|
|
@ -1391,6 +1394,11 @@ class Abha extends BaseController
|
|||
if ($profilePhoto !== '' && in_array('abha_profile_photo_base64', $fields, true)) {
|
||||
$target['abha_profile_photo_base64'] = $profilePhoto;
|
||||
}
|
||||
|
||||
$cardBase64 = trim((string) ($abhaMeta['card_base64'] ?? ''));
|
||||
if ($cardBase64 !== '' && in_array('abha_card_base64', $fields, true)) {
|
||||
$target['abha_card_base64'] = $cardBase64;
|
||||
}
|
||||
}
|
||||
|
||||
private function toDbBool($value): int
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use CodeIgniter\Database\Migration;
|
||||
|
||||
class AddAbhaCardToPatientMaster extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
if (! $this->tableExists('patient_master')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$fields = $this->getColumns('patient_master');
|
||||
if (! in_array('abha_card_base64', $fields, true)) {
|
||||
$this->forge->addColumn('patient_master', [
|
||||
'abha_card_base64' => [
|
||||
'type' => 'LONGTEXT',
|
||||
'null' => true,
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
if ($this->tableExists('patient_master') && in_array('abha_card_base64', $this->getColumns('patient_master'), true)) {
|
||||
$this->forge->dropColumn('patient_master', 'abha_card_base64');
|
||||
}
|
||||
}
|
||||
|
||||
private function getColumns(string $table): array
|
||||
{
|
||||
$result = $this->db->query('SHOW COLUMNS FROM `' . $table . '`')->getResultArray();
|
||||
return array_map(static fn (array $row): string => (string) ($row['Field'] ?? ''), $result);
|
||||
}
|
||||
|
||||
private function tableExists(string $table): bool
|
||||
{
|
||||
return ! empty($this->db->query("SHOW TABLES LIKE '" . $table . "'")->getRowArray());
|
||||
}
|
||||
}
|
||||
|
|
@ -168,6 +168,8 @@
|
|||
background: #fff;
|
||||
}
|
||||
.qr-value { margin-top: 5px; font-size: 10px; color: #3b5474; word-break: break-word; }
|
||||
.official-card-wrap { margin-top: 14px; text-align: center; }
|
||||
.official-card { display: block; width: 100%; max-height: 480px; object-fit: contain; border: 1px solid #d8e6fb; border-radius: 8px; background: #fff; }
|
||||
.abha-number-wrap {
|
||||
margin-top: 12px;
|
||||
border: 1px solid #d3e3f9;
|
||||
|
|
@ -241,6 +243,10 @@ $abhaQrUrl = esc($abha_qr_url ?? '');
|
|||
$barcodeImage = esc($hms_barcode_image ?? '');
|
||||
$patientMobile = esc($patient_mobile ?? '');
|
||||
$mobileVerified = (bool) ($mobile_verified ?? false);
|
||||
$storedAbhaCard = trim((string) ($stored_abha_card ?? ''));
|
||||
$storedAbhaCardSrc = $storedAbhaCard !== ''
|
||||
? (str_starts_with($storedAbhaCard, 'data:') ? $storedAbhaCard : 'data:image/png;base64,' . $storedAbhaCard)
|
||||
: '';
|
||||
?>
|
||||
|
||||
<div class="abha-shell">
|
||||
|
|
@ -263,6 +269,13 @@ $mobileVerified = (bool) ($mobile_verified ?? false);
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ($storedAbhaCardSrc !== ''): ?>
|
||||
<div class="official-card-wrap">
|
||||
<div class="meta">Stored official ABHA card</div>
|
||||
<img class="official-card" src="<?= esc($storedAbhaCardSrc) ?>" alt="Stored official ABHA card">
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($barcodeImage !== '' && $hmsId !== ''): ?>
|
||||
<div class="hospital-strip">
|
||||
<div class="patient-id-strip">
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@
|
|||
<span class="badge bg-secondary" id="abhaMatch_count">0 found</span>
|
||||
</div>
|
||||
<div id="abhaMatch_candidates" style="max-height:360px;overflow-y:auto"></div>
|
||||
<div id="abhaMatch_update_preview" class="alert alert-info py-2 small d-none"></div>
|
||||
<div id="abhaMatch_empty" class="alert alert-warning py-2 small d-none">
|
||||
No matching patient found in HMS by name, age or gender. You can create a new patient record.
|
||||
</div>
|
||||
|
|
@ -118,6 +119,27 @@ window.AbhaPatientMatchModal = (function () {
|
|||
function alertHtml(type, msg) {
|
||||
return '<div class="alert alert-' + type + ' py-2">' + msg + '</div>';
|
||||
}
|
||||
function profileValue(value) { return String(value == null ? '' : value).trim().toUpperCase(); }
|
||||
function normalizedGender(value) {
|
||||
var gender = profileValue(value);
|
||||
if (gender === '1' || gender === 'M' || gender === 'MALE') return 'M';
|
||||
if (gender === '2' || gender === 'F' || gender === 'FEMALE') return 'F';
|
||||
if (gender === '3' || gender === 'O' || gender === 'OTHER') return 'O';
|
||||
return gender;
|
||||
}
|
||||
function renderUpdatePreview(c) {
|
||||
var fields = [];
|
||||
var p = _profile || {};
|
||||
if (profileValue(p.name) !== profileValue(c.name)) fields.push('Name');
|
||||
if (normalizedGender(p.gender) !== normalizedGender(c.gender_label)) fields.push('Gender');
|
||||
if (String(p.dob || '').slice(0, 4) !== String(c.dob || '').slice(0, 4)) fields.push('Birth year');
|
||||
if (String(p.mobile || '').replace(/\D/g, '') !== String(c.mobile || '').replace(/\D/g, '')) fields.push('Mobile');
|
||||
var abhaAddress = [p.address, p.district, p.state, p.zip].filter(Boolean).join(', ');
|
||||
if (profileValue(abhaAddress) !== profileValue(c.address)) fields.push('Address');
|
||||
$('#abhaMatch_update_preview').toggleClass('d-none', !fields.length).html(
|
||||
fields.length ? '<strong>Update Details will change:</strong> ' + fields.map(esc).join(', ') : '<strong>No HMS demographic changes detected.</strong>'
|
||||
);
|
||||
}
|
||||
|
||||
function renderProfile(p) {
|
||||
var abhaNum = p.abha_number || '';
|
||||
|
|
@ -157,7 +179,8 @@ window.AbhaPatientMatchModal = (function () {
|
|||
+ ' <div class="card-body py-2">'
|
||||
+ ' <div class="d-flex justify-content-between align-items-start">'
|
||||
+ ' <div>'
|
||||
+ ' <div class="fw-semibold">' + esc(c.name || '—') + ' <small class="text-muted">(' + esc(c.p_code || '') + ')</small></div>'
|
||||
+ (c.photo_url ? ' <img src="' + esc(c.photo_url) + '" alt="Patient photo" class="rounded-circle me-2" style="width:38px;height:38px;object-fit:cover;vertical-align:middle">' : '')
|
||||
+ ' <div class="fw-semibold d-inline-block">' + esc(c.name || '—') + ' <small class="text-muted">(' + esc(c.p_code || '') + ')</small></div>'
|
||||
+ ' <div class="mt-1">'
|
||||
+ badge(m.name, 'Name')
|
||||
+ badge(m.age, 'Age ' + (c.age != null ? c.age : '?'))
|
||||
|
|
@ -185,6 +208,8 @@ window.AbhaPatientMatchModal = (function () {
|
|||
$('.abhaMatch-candidate[data-id="' + id + '"]').addClass('border-success bg-success-subtle');
|
||||
$('.abhaMatch-radio[value="' + id + '"]').prop('checked', true);
|
||||
$('#abhaMatch_keep_existing_btn,#abhaMatch_update_existing_btn').prop('disabled', !id);
|
||||
var selected = (_profile && window._abhaMatchCandidates || []).find(function (candidate) { return Number(candidate.id) === Number(id); });
|
||||
if (selected) renderUpdatePreview(selected);
|
||||
}
|
||||
|
||||
function submitConfirm(action, patientId, updateMode, $btn) {
|
||||
|
|
@ -205,6 +230,7 @@ window.AbhaPatientMatchModal = (function () {
|
|||
dob: _profile.dob || '',
|
||||
abha_address: _profile.abha_address || '',
|
||||
photo: _profile.photo || '',
|
||||
card_base64: _profile.card_base64 || '',
|
||||
verified_status: _profile.verified_status || '',
|
||||
verification_type: _profile.verification_type || '',
|
||||
kyc_verified: _profile.kyc_verified,
|
||||
|
|
@ -264,12 +290,14 @@ window.AbhaPatientMatchModal = (function () {
|
|||
return {
|
||||
open: function (profile, candidates, onResolved) {
|
||||
_profile = profile || {};
|
||||
window._abhaMatchCandidates = candidates || [];
|
||||
_selectedId = 0;
|
||||
_onResolved = onResolved;
|
||||
$('#abhaMatch_alert').empty();
|
||||
$('#abhaMatch_keep_existing_btn,#abhaMatch_update_existing_btn').prop('disabled', true);
|
||||
renderProfile(_profile);
|
||||
renderCandidates(candidates || []);
|
||||
$('#abhaMatch_update_preview').addClass('d-none').empty();
|
||||
if (_bsModal) { _bsModal.show(); } else { $modalEl.modal('show'); }
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user