Update Refactoring Patient v2

This commit is contained in:
mikael-zakaria 2025-10-16 10:50:09 +07:00
parent 3290d24e05
commit 70b46dbd72

View File

@ -2,6 +2,13 @@
namespace App\Models\Patient; namespace App\Models\Patient;
use App\Models\BaseModel; use App\Models\BaseModel;
use App\Models\BaseUtcModel;
use App\Models\Patient\PatAttModel;
use App\Models\Patient\PatComModel;
use App\Models\Patient\PatIdtModel;
use CodeIgniter\Database\RawSql;
class PatientModel extends BaseModel { class PatientModel extends BaseModel {
protected $table = 'patient'; protected $table = 'patient';
@ -16,6 +23,12 @@ class PatientModel extends BaseModel {
protected $useSoftDeletes = true; protected $useSoftDeletes = true;
protected $deletedField = 'DelDate'; protected $deletedField = 'DelDate';
protected $beforeInsert = ['normalizeDatesToUTC'];
protected $beforeUpdate = ['normalizeDatesToUTC'];
protected $afterFind = ['convertDatesToUTCISO'];
protected $afterInsert = ['convertDatesToUTCISO'];
protected $afterUpdate = ['convertDatesToUTCISO'];
public function getPatients($filters = []) { public function getPatients($filters = []) {
$qname = "LOWER(CONCAT_WS(' ', IFNULL(Prefix,''), IFNULL(NameFirst,''), IFNULL(NameMiddle,''), IFNULL(NameLast,''), IFNULL(NameMaiden,''), IFNULL(Suffix,'')))"; $qname = "LOWER(CONCAT_WS(' ', IFNULL(Prefix,''), IFNULL(NameFirst,''), IFNULL(NameMiddle,''), IFNULL(NameLast,''), IFNULL(NameMaiden,''), IFNULL(Suffix,'')))";
@ -23,7 +36,8 @@ class PatientModel extends BaseModel {
$builder->select("InternalPID, PatientID, $qname as FullName, Gender, Birthdate, EmailAddress1 as Email, MobilePhone"); $builder->select("InternalPID, PatientID, $qname as FullName, Gender, Birthdate, EmailAddress1 as Email, MobilePhone");
if (!empty($filters['Name'])) { if (!empty($filters['Name'])) {
$builder->like($qname, $filters['Name'], 'both'); $rawSql = new RawSql($qname);
$builder->like($rawSql, $filters['Name'], 'both');
} }
if (!empty($filters['InternalPID'])) { if (!empty($filters['InternalPID'])) {
@ -113,45 +127,43 @@ class PatientModel extends BaseModel {
public function createPatient($input) { public function createPatient($input) {
$db = \Config\Database::connect(); $db = \Config\Database::connect();
$patidt = $input['PatIdt'] ?? []; $this->modelPatAtt = new PatAttModel();
$patatt = $input['PatAtt'] ?? []; $this->modelPatCom = new PatComModel();
$patcom['Comment'] = $input['PatCom'] ?? null; $this->modelPatIdt = new PatIdtModel();
$input['LinkTo'] = empty($input['LinkTo']) ? null : $input['LinkTo']; $input['LinkTo'] = empty($input['LinkTo']) ? null : $input['LinkTo'];
$input['Birthdate'] = $this->isValidDateTime($input['Birthdate']); $input['Birthdate'] = $this->isValidDateTime($input['Birthdate']);
$input['DeathDateTime'] = $this->isValidDateTime($input['DeathDateTime']); $input['DeathDateTime'] = $this->isValidDateTime($input['DeathDateTime']);
$db->transBegin(); $db->transBegin();
try { try {
// Insert Data ke Tabel Patient, get ID dan cek apa ada error
$this->insert($input); $this->insert($input);
$newInternalPID = $this->getInsertID(); $newInternalPID = $this->getInsertID();
$this->checkDbError($db, 'Insert patient'); $this->checkDbError($db, 'Insert patient');
if (!empty($patidt)) { // Insert Data ke Tabel PatIdt
$patidt['InternalPID'] = $newInternalPID; if (!empty($input['PatIdt'])) {
$db->table('patidt')->insert($patidt); $this->modelPatIdt->createPatIdt($input['PatIdt'], $newInternalPID);
$this->checkDbError($db, 'Insert patidt'); $this->checkDbError($db, 'Insert PatIdt');
} }
if (!empty($patcom)) { // Insert Data ke Tabel PatCom
$patcom['InternalPID'] = $newInternalPID; if (!empty($input['PatCom'])) {
$db->table('patcom')->insert($patcom); $this->modelPatCom->createPatCom($input['PatCom'], $newInternalPID);
$this->checkDbError($db, 'Insert patcom'); $this->checkDbError($db, 'Insert PatCom');
} }
if (!empty($patatt)) { // Insert Data ke Tabel PatAtt
foreach ($patatt as &$row) { if (!empty($input['PatAtt'])) {
$row['InternalPID'] = $newInternalPID; $this->modelPatAtt->createPatAtt($input['PatAtt'], $newInternalPID);
} $this->checkDbError($db, 'Insert PatAtt');
$db->table('patatt')->upsertBatch($patatt);
$this->checkDbError($db, 'Insert patatt');
} }
$db->transCommit(); $db->transCommit();
// $db->transComplete();
// if ($db->transStatus() === false) {
// throw new \Exception("Failed to sync patient relations");
// }
return $newInternalPID; return $newInternalPID;
} catch (\Exception $e) { } catch (\Exception $e) {
@ -162,9 +174,10 @@ class PatientModel extends BaseModel {
public function updatePatient($input) { public function updatePatient($input) {
$db = \Config\Database::connect(); $db = \Config\Database::connect();
$patidt = $input['PatIdt'] ?? []; $this->modelPatIdt = new PatIdtModel();
$patatt = $input['PatAtt'] ?? []; $this->modelPatCom = new PatComModel();
$patcom['Comment'] = $input['PatCom'] ?? null; $this->modelPatAtt = new PatAttModel();
$input['LinkTo'] = empty($input['LinkTo']) ? null : $input['LinkTo']; $input['LinkTo'] = empty($input['LinkTo']) ? null : $input['LinkTo'];
$input['Birthdate'] = $this->isValidDateTime($input['Birthdate']); $input['Birthdate'] = $this->isValidDateTime($input['Birthdate']);
$input['DeathDateTime'] = $this->isValidDateTime($input['DeathDateTime']); $input['DeathDateTime'] = $this->isValidDateTime($input['DeathDateTime']);
@ -172,109 +185,41 @@ class PatientModel extends BaseModel {
$db->transBegin(); $db->transBegin();
try { try {
// Update Patient
$InternalPID = $input['InternalPID']; $InternalPID = $input['InternalPID'];
$this->where('InternalPID',$InternalPID)->set($input)->update(); $this->where('InternalPID',$InternalPID)->set($input)->update();
$this->checkDbError($db, 'Update patient'); $this->checkDbError($db, 'Update patient');
$now = date('Y-m-d H:i:s'); // Update Patidt
if (!empty($input['PatIdt'])) {
if (!empty($patidt)) { $this->modelPatIdt->updatePatIdt($input['PatIdt'], $InternalPID);
$exists = $db->table('patidt')->where('InternalPID', $InternalPID)->get()->getRowArray(); $this->checkDbError($db, 'Update patIdt');
if ($exists) {
$db->table('patidt')->where('InternalPID', $InternalPID)->update($patidt);
} else {
$patidt['InternalPID'] = $InternalPID;
$db->table('patidt')->insert($patidt);
$this->checkDbError($db, 'Update patidt');
}
} else { } else {
$db->table('patidt')->where('InternalPID', $InternalPID)->delete(); $this->modelPatIdt->deletePatIdt($InternalPID);
$this->checkDbError($db, 'Update patidt'); $this->checkDbError($db, 'Update patidt');
} }
if (!empty($patcom)) { // Update Patcom
$exists = $db->table('patcom')->where('InternalPID', $InternalPID)->get()->getRowArray(); if (!empty($input['PatCom'])) {
if ($exists) { $this->modelPatCom->updatePatCom($input['PatCom'], $InternalPID);
$db->table('patcom')->where('InternalPID', $InternalPID)->update($patcom); $this->checkDbError($db, 'Update PatCom');
$this->checkDbError($db, 'Update patcom');
} else {
$patcom['InternalPID'] = $InternalPID;
$db->table('patcom')->insert($patcom);
$this->checkDbError($db, 'Update patcom');
}
} else { } else {
$db->table('patcom')->where('InternalPID', $InternalPID)->delete(); $this->modelPatCom->deletePatCom($InternalPID);
$this->checkDbError($db, 'Update patcom'); $this->checkDbError($db, 'Update patcom');
} }
if (!empty($patatt)) { // Update Patatt
// Ambil daftar address aktif (DelDate IS NULL) di DB if (!empty($input['PatAtt'])) {
$oldActive = $db->table('patatt') $this->modelPatAtt->updatePatAtt($input['PatAtt'], $InternalPID);
->select('Address') $this->checkDbError($db, 'Update PatAtt');
->where('InternalPID', $InternalPID)
->where('DelDate', null)
->get()->getResultArray();
$oldActive = array_column($oldActive, 'Address');
// Normalisasi & dedup input baru (berdasarkan Address)
$mapNew = [];
foreach ($patatt as $row) {
if (!isset($row['Address'])) continue;
$mapNew[$row['Address']] = $row; // overwrite duplikat di input
}
$newData = array_keys($mapNew);
// Hitung yang perlu ditambah & dihapus
$added = array_diff($newData, $oldActive); // baru (belum aktif)
$removed = array_diff($oldActive, $newData); // dulu aktif tapi hilang di input
// 1) Soft delete yang dihapus
if (!empty($removed)) {
$db->table('patatt')
->where('InternalPID', $InternalPID)
->whereIn('Address', $removed)
->set('DelDate', $now)
->update();
$this->checkDbError($db, 'Update/Delete patatt');
}
// 2) Tambahkan yang baru
foreach ($added as $addr) {
$data = $mapNew[$addr];
$data['InternalPID'] = $InternalPID;
// Coba REACTIVATE satu baris yang pernah di-soft delete (kalau ada)
$builder = $db->table('patatt');
$builder->set('DelDate', null);
// Kalau ada kolom lain yang mau di-update saat re-activate, set di sini juga
// mis: $builder->set('Note', $data['Note'] ?? null);
$builder->where('InternalPID', $InternalPID)
->where('Address', $addr)
->where('DelDate IS NOT NULL', null, false)
->orderBy('PatAttID', 'DESC')
->limit(1)
->update();
$this->checkDbError($db, 'Update/Insert patatt');
if ($db->affectedRows() === 0) {
// Tidak ada baris soft-deleted untuk alamat ini → INSERT baru
$db->table('patatt')->insert($data);
$this->checkDbError($db, 'Update/Insert patatt');
}
}
} else { } else {
// Input kosong → semua yang masih aktif di-soft delete $this->modelPatAtt->deletePatAtt($InternalPID);
$db->table('patatt')->where('InternalPID', $InternalPID)->where('DelDate', null)->set('DelDate', $now)->update(); $this->checkDbError($db, 'Update/Delete patatt');
$this->checkDbError($db, 'Update/Delete patatt');
} }
$db->transCommit(); $db->transCommit();
// if ($db->transStatus() === false) {
// throw new \Exception('Failed to sync patient relations');
// }
return $InternalPID; return $InternalPID;
} catch (\Exception $e) { } catch (\Exception $e) {