Files
T
2026-09-16 23:20:08 +07:00

97 lines
3.3 KiB
PHP

<?php
namespace App\Models;
/**
* Class Patient
* Patient & EMR Model (HIS / HOSxP & Smart Card Integration)
*
* @package App\Models
*/
class Patient extends Model
{
protected string $table = 'patients';
/**
* Find Patient by CID (13 digits National ID)
*/
public function findByCid(string $cid): ?array
{
return $this->firstWhere(['cid' => $cid]);
}
/**
* Find Patient by Hospital Number (HN)
*/
public function findByHn(string $hn): ?array
{
return $this->firstWhere(['hn' => $hn]);
}
/**
* Search patients by Name, CID, or Phone
*/
public function search(string $keyword): array
{
$sql = "SELECT p.*, l.total_points, l.tier
FROM `{$this->table}` p
LEFT JOIN `patient_loyalty` l ON p.id = l.patient_id
WHERE p.cid LIKE :kw OR p.hn LIKE :kw OR p.first_name_th LIKE :kw OR p.last_name_th LIKE :kw OR p.phone LIKE :kw
ORDER BY p.id DESC LIMIT 50";
$stmt = self::getDB()->prepare($sql);
$stmt->execute(['kw' => "%{$keyword}%"]);
return $stmt->fetchAll();
}
/**
* Save or Update from Smart Card Reader APDU / WebUSB Payload
*/
public function saveFromSmartCard(array $cardData): int
{
$existing = $this->findByCid($cardData['cid']);
if ($existing) {
$this->update((int)$existing['id'], [
'first_name_th' => $cardData['first_name_th'],
'last_name_th' => $cardData['last_name_th'],
'first_name_en' => $cardData['first_name_en'] ?? null,
'last_name_en' => $cardData['last_name_en'] ?? null,
'birth_date' => $cardData['birth_date'],
'gender' => $cardData['gender'] === '1' || $cardData['gender'] === 'Male' ? 'Male' : 'Female',
'address' => $cardData['address'] ?? null,
'photo_url' => $cardData['photo_url'] ?? null,
'updated_at' => date('Y-m-d H:i:s'),
]);
return (int)$existing['id'];
}
// Generate auto HN if not synced yet
$hn = $cardData['hn'] ?? ('HN-' . date('ym') . sprintf('%04d', random_int(1, 9999)));
return $this->create([
'cid' => $cardData['cid'],
'hn' => $hn,
'first_name_th' => $cardData['first_name_th'],
'last_name_th' => $cardData['last_name_th'],
'first_name_en' => $cardData['first_name_en'] ?? null,
'last_name_en' => $cardData['last_name_en'] ?? null,
'birth_date' => $cardData['birth_date'],
'gender' => $cardData['gender'] === '1' || $cardData['gender'] === 'Male' ? 'Male' : 'Female',
'address' => $cardData['address'] ?? null,
'phone' => $cardData['phone'] ?? '080-000-0000',
'photo_url' => $cardData['photo_url'] ?? null,
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
]);
}
/**
* Sync data from HIS / HOSxP REST API
*/
public function updateHisData(int $patientId, array $hisRawData): bool
{
return $this->update($patientId, [
'his_synced_at' => date('Y-m-d H:i:s'),
'his_raw_data' => json_encode($hisRawData, JSON_UNESCAPED_UNICODE),
]);
}
}