devsofttech_hms_ci4/app/Database/Migrations/2026-05-15-000203_AddAbdmPushFieldsToOpdAndPatient.php
DevSoftTech Server 0628f8f813 feat: ABDM OPD Queue + ABHA Register flow + patient ABHA search fix
ABDM OPD Queue (today):
- New EAtriaBridgeConnector: opdQueueFetch/opdTokenCreate/opdTokenUpdateStatus + patch() helper
- New AbdmOpdQueue controller: index/list/fetchQueue/createToken/updateTokenStatus/processScannedToken
  - fetchQueue syncs gateway tokens into abdm_opd_tokens (local DB) and enriches with HMS patient data
  - processScannedToken auto-finds/creates patient_master record from ABHA scan data, marks token CALLED
- New migration: abdm_opd_tokens table (gateway_token_id, source, status, patient_id, opd_id, processed_at)
- New view: abdm/opd_queue.php - reception screen with auto-refresh 30s, HMS Patient column (green row when OPD registered)
- Sidebar: ABDM OPD Queue nav link added
- Routes: AbdmOpdQueue with abdmPermFilter

ABHA Register tab (earlier this session):
- New Abha controller: initiate/verifyOtp/communication/verifyCommOtp/validateAbha/card + autoCreateOrFindPatient
- New views: abha/card.php, partials/abha_create_panel.php, partials/abha_otp_modal.php
- Patient_V.php: ABHA Register tab with 4-method wizard (ABHA number, QR scan, facility QR, mobile OTP)

Patient ABHA search fix:
- Patient::search() now detects ABHA column (abha_id/abha_no/abha/abha_address) and searches by it

ABDM Bridge infrastructure:
- EAtriaBridgeConnector: new connector for e-atria.in ABDM bridge gateway
- AbdmConnectorFactory/Interface updated
- AbdmGatewaySettings controller + view
- SNOMED/CSNOTK terminology service skeleton
- Finance payout OPD consult views
- Migration: AddAbdmPushFieldsToOpdAndPatient, CreateSnomedCoreTables
- Docs: abdm/ API specs, architecture, gateway guides
2026-05-16 04:21:31 +05:30

106 lines
3.0 KiB
PHP

<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class AddAbdmPushFieldsToOpdAndPatient extends Migration
{
public function up(): void
{
$this->addOpdPrescriptionFields();
$this->addPatientMasterFields();
}
public function down(): void
{
if ($this->hasTable('opd_prescription')) {
$fields = $this->getTableFields('opd_prescription');
foreach (['abdm_push_status', 'abdm_push_at'] as $col) {
if (in_array($col, $fields, true)) {
$this->forge->dropColumn('opd_prescription', $col);
}
}
}
if ($this->hasTable('patient_master')) {
$fields = $this->getTableFields('patient_master');
if (in_array('abdm_linked_at', $fields, true)) {
$this->forge->dropColumn('patient_master', 'abdm_linked_at');
}
}
}
// -------------------------------------------------------------------------
private function addOpdPrescriptionFields(): void
{
if (! $this->hasTable('opd_prescription')) {
return;
}
$fields = $this->getTableFields('opd_prescription');
$toAdd = [];
if (! in_array('abdm_push_status', $fields, true)) {
$toAdd['abdm_push_status'] = [
'type' => 'TINYINT',
'constraint' => 1,
'default' => 0,
'null' => false,
// 0 = not pushed, 1 = pushed, 2 = failed
];
}
if (! in_array('abdm_push_at', $fields, true)) {
$toAdd['abdm_push_at'] = [
'type' => 'DATETIME',
'null' => true,
];
}
if (! empty($toAdd)) {
$this->forge->addColumn('opd_prescription', $toAdd);
}
}
private function addPatientMasterFields(): void
{
if (! $this->hasTable('patient_master')) {
return;
}
$fields = $this->getTableFields('patient_master');
if (! in_array('abdm_linked_at', $fields, true)) {
$this->forge->addColumn('patient_master', [
'abdm_linked_at' => [
'type' => 'DATETIME',
'null' => true,
],
]);
}
}
// -------------------------------------------------------------------------
private function hasTable(string $table): bool
{
if (! preg_match('/^[a-zA-Z0-9_]+$/', $table)) {
return false;
}
$row = $this->db->query("SHOW TABLES LIKE '" . $table . "'")->getRowArray();
return ! empty($row);
}
/** @return string[] */
private function getTableFields(string $table): array
{
if (! preg_match('/^[a-zA-Z0-9_]+$/', $table)) {
return [];
}
$result = $this->db->query('SHOW COLUMNS FROM `' . $table . '`')->getResultArray();
return array_map(static fn (array $r): string => (string) ($r['Field'] ?? ''), $result);
}
}