From 70b46dbd729b482969c38b51f9242ef452646b2f Mon Sep 17 00:00:00 2001 From: mikael-zakaria Date: Thu, 16 Oct 2025 10:50:09 +0700 Subject: [PATCH] Update Refactoring Patient v2 --- app/Models/Patient/PatientModel.php | 173 ++++++++++------------------ 1 file changed, 59 insertions(+), 114 deletions(-) diff --git a/app/Models/Patient/PatientModel.php b/app/Models/Patient/PatientModel.php index 8f7dd73..57bd4f8 100644 --- a/app/Models/Patient/PatientModel.php +++ b/app/Models/Patient/PatientModel.php @@ -2,6 +2,13 @@ namespace App\Models\Patient; 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 { protected $table = 'patient'; @@ -16,6 +23,12 @@ class PatientModel extends BaseModel { protected $useSoftDeletes = true; protected $deletedField = 'DelDate'; + protected $beforeInsert = ['normalizeDatesToUTC']; + protected $beforeUpdate = ['normalizeDatesToUTC']; + protected $afterFind = ['convertDatesToUTCISO']; + protected $afterInsert = ['convertDatesToUTCISO']; + protected $afterUpdate = ['convertDatesToUTCISO']; + public function getPatients($filters = []) { $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"); if (!empty($filters['Name'])) { - $builder->like($qname, $filters['Name'], 'both'); + $rawSql = new RawSql($qname); + $builder->like($rawSql, $filters['Name'], 'both'); } if (!empty($filters['InternalPID'])) { @@ -113,45 +127,43 @@ class PatientModel extends BaseModel { public function createPatient($input) { $db = \Config\Database::connect(); - $patidt = $input['PatIdt'] ?? []; - $patatt = $input['PatAtt'] ?? []; - $patcom['Comment'] = $input['PatCom'] ?? null; + $this->modelPatAtt = new PatAttModel(); + $this->modelPatCom = new PatComModel(); + $this->modelPatIdt = new PatIdtModel(); + $input['LinkTo'] = empty($input['LinkTo']) ? null : $input['LinkTo']; $input['Birthdate'] = $this->isValidDateTime($input['Birthdate']); $input['DeathDateTime'] = $this->isValidDateTime($input['DeathDateTime']); + $db->transBegin(); try { - + + // Insert Data ke Tabel Patient, get ID dan cek apa ada error $this->insert($input); $newInternalPID = $this->getInsertID(); $this->checkDbError($db, 'Insert patient'); - if (!empty($patidt)) { - $patidt['InternalPID'] = $newInternalPID; - $db->table('patidt')->insert($patidt); - $this->checkDbError($db, 'Insert patidt'); + // Insert Data ke Tabel PatIdt + if (!empty($input['PatIdt'])) { + $this->modelPatIdt->createPatIdt($input['PatIdt'], $newInternalPID); + $this->checkDbError($db, 'Insert PatIdt'); } - if (!empty($patcom)) { - $patcom['InternalPID'] = $newInternalPID; - $db->table('patcom')->insert($patcom); - $this->checkDbError($db, 'Insert patcom'); + // Insert Data ke Tabel PatCom + if (!empty($input['PatCom'])) { + $this->modelPatCom->createPatCom($input['PatCom'], $newInternalPID); + $this->checkDbError($db, 'Insert PatCom'); } - - if (!empty($patatt)) { - foreach ($patatt as &$row) { - $row['InternalPID'] = $newInternalPID; - } - $db->table('patatt')->upsertBatch($patatt); - $this->checkDbError($db, 'Insert patatt'); + + // Insert Data ke Tabel PatAtt + if (!empty($input['PatAtt'])) { + $this->modelPatAtt->createPatAtt($input['PatAtt'], $newInternalPID); + $this->checkDbError($db, 'Insert PatAtt'); } $db->transCommit(); - // $db->transComplete(); - // if ($db->transStatus() === false) { - // throw new \Exception("Failed to sync patient relations"); - // } + return $newInternalPID; } catch (\Exception $e) { @@ -162,9 +174,10 @@ class PatientModel extends BaseModel { public function updatePatient($input) { $db = \Config\Database::connect(); - $patidt = $input['PatIdt'] ?? []; - $patatt = $input['PatAtt'] ?? []; - $patcom['Comment'] = $input['PatCom'] ?? null; + $this->modelPatIdt = new PatIdtModel(); + $this->modelPatCom = new PatComModel(); + $this->modelPatAtt = new PatAttModel(); + $input['LinkTo'] = empty($input['LinkTo']) ? null : $input['LinkTo']; $input['Birthdate'] = $this->isValidDateTime($input['Birthdate']); $input['DeathDateTime'] = $this->isValidDateTime($input['DeathDateTime']); @@ -172,109 +185,41 @@ class PatientModel extends BaseModel { $db->transBegin(); try { + + // Update Patient $InternalPID = $input['InternalPID']; $this->where('InternalPID',$InternalPID)->set($input)->update(); $this->checkDbError($db, 'Update patient'); - $now = date('Y-m-d H:i:s'); - - if (!empty($patidt)) { - $exists = $db->table('patidt')->where('InternalPID', $InternalPID)->get()->getRowArray(); - if ($exists) { - $db->table('patidt')->where('InternalPID', $InternalPID)->update($patidt); - } else { - $patidt['InternalPID'] = $InternalPID; - $db->table('patidt')->insert($patidt); - $this->checkDbError($db, 'Update patidt'); - } + // Update Patidt + if (!empty($input['PatIdt'])) { + $this->modelPatIdt->updatePatIdt($input['PatIdt'], $InternalPID); + $this->checkDbError($db, 'Update patIdt'); } else { - $db->table('patidt')->where('InternalPID', $InternalPID)->delete(); + $this->modelPatIdt->deletePatIdt($InternalPID); $this->checkDbError($db, 'Update patidt'); } - if (!empty($patcom)) { - $exists = $db->table('patcom')->where('InternalPID', $InternalPID)->get()->getRowArray(); - if ($exists) { - $db->table('patcom')->where('InternalPID', $InternalPID)->update($patcom); - $this->checkDbError($db, 'Update patcom'); - } else { - $patcom['InternalPID'] = $InternalPID; - $db->table('patcom')->insert($patcom); - $this->checkDbError($db, 'Update patcom'); - } + // Update Patcom + if (!empty($input['PatCom'])) { + $this->modelPatCom->updatePatCom($input['PatCom'], $InternalPID); + $this->checkDbError($db, 'Update PatCom'); } else { - $db->table('patcom')->where('InternalPID', $InternalPID)->delete(); + $this->modelPatCom->deletePatCom($InternalPID); $this->checkDbError($db, 'Update patcom'); } - if (!empty($patatt)) { - // Ambil daftar address aktif (DelDate IS NULL) di DB - $oldActive = $db->table('patatt') - ->select('Address') - ->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'); - } - } - + // Update Patatt + if (!empty($input['PatAtt'])) { + $this->modelPatAtt->updatePatAtt($input['PatAtt'], $InternalPID); + $this->checkDbError($db, 'Update PatAtt'); } else { - // Input kosong → semua yang masih aktif di-soft delete - $db->table('patatt')->where('InternalPID', $InternalPID)->where('DelDate', null)->set('DelDate', $now)->update(); - $this->checkDbError($db, 'Update/Delete patatt'); + $this->modelPatAtt->deletePatAtt($InternalPID); + $this->checkDbError($db, 'Update/Delete patatt'); } $db->transCommit(); - // if ($db->transStatus() === false) { - // throw new \Exception('Failed to sync patient relations'); - // } + return $InternalPID; } catch (\Exception $e) {