97 lines
3.3 KiB
PHP
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),
|
|
]);
|
|
}
|
|
}
|