From 7addc20b557e0524ec8f2976359503726baaf6da Mon Sep 17 00:00:00 2001 From: mikael-zakaria Date: Thu, 16 Oct 2025 10:46:29 +0700 Subject: [PATCH] Update Refactoring Patient --- app/Models/PatientModel.php | 350 ------------------------------------ 1 file changed, 350 deletions(-) delete mode 100644 app/Models/PatientModel.php diff --git a/app/Models/PatientModel.php b/app/Models/PatientModel.php deleted file mode 100644 index 57bd4f8..0000000 --- a/app/Models/PatientModel.php +++ /dev/null @@ -1,350 +0,0 @@ -db->table($this->table); - $builder->select("InternalPID, PatientID, $qname as FullName, Gender, Birthdate, EmailAddress1 as Email, MobilePhone"); - - if (!empty($filters['Name'])) { - $rawSql = new RawSql($qname); - $builder->like($rawSql, $filters['Name'], 'both'); - } - - if (!empty($filters['InternalPID'])) { - $builder->where('InternalPID', $filters['InternalPID']); - } - - if (!empty($filters['PatientID'])) { - $builder->like('PatientID', $filters['PatientID'], 'both'); - } - - if (!empty($filters['Birthdate'])) { - $builder->where('Birthdate', $filters['Birthdate']); - } - - return $builder->get()->getResultArray(); - } - - public function getPatient($InternalPID) { - $rows = $this->db->table('patient p') - ->select(" - p.*, - country.VDesc as Country, - country.VID as CountryVID, - race.VDesc as Race, - race.VID as RaceVID, - religion.VDesc as Religion, - religion.VID as ReligionVID, - ethnic.VDesc as Ethnic, - ethnic.VID as EthnicVID, - gender.VDesc as Gender, - gender.VID as GenderVID, - deathindicator.VDesc as DeathIndicator, - deathindicator.VID as DeathIndicatorVID, - maritalstatus.VDesc as MaritalStatus, - maritalstatus.VID as MaritalStatusVID, - patcom.Comment as Comment, - patidt.IdentifierType, - patidt.Identifier, - patatt.Address - ") - ->join('valueset country', 'country.VID = p.Country', 'left') - ->join('valueset race', 'race.VID = p.Race', 'left') - ->join('valueset religion', 'religion.VID = p.Religion', 'left') - ->join('valueset ethnic', 'ethnic.VID = p.Ethnic', 'left') - ->join('valueset gender', 'gender.VID = p.Gender', 'left') - ->join('valueset deathindicator', 'deathindicator.VID = p.DeathIndicator', 'left') - ->join('valueset maritalstatus', 'maritalstatus.VID = p.MaritalStatus', 'left') - ->join('patcom', 'patcom.InternalPID = p.InternalPID', 'left') - ->join('patidt', 'patidt.InternalPID = p.InternalPID', 'left') - ->join('patatt', 'patatt.InternalPID = p.InternalPID and patatt.DelDate is null', 'left') - ->where('p.InternalPID', (int) $InternalPID) - ->get() - ->getResultArray(); - - if (empty($rows)) { return null; } - - $patient = $rows[0]; - - if (method_exists($this, 'transformPatientData')) { $patient = $this->transformPatientData($patient); } - unset($patient['Address']); - unset($patient['IdentifierType']); - unset($patient['Identifier']); - unset($patient['Comment']); - - // Default nested structures - $patient['PatIdt'] = null; - $patient['PatAtt'] = []; - - foreach ($rows as $row) { - if ($row['IdentifierType'] && $row['Identifier'] && !$patient['PatIdt']) { - $patient['PatIdt'] = [ - 'IdentifierType' => $row['IdentifierType'], - 'Identifier' => $row['Identifier'], - ]; - } - - if ($row['Address']) { - $patient['PatAtt'][] = ['Address' => $row['Address']]; - } - } - - if (empty($patient['PatIdt'])) { $patient['PatIdt'] = null; } - if (empty($patient['PatAtt'])) { $patient['PatAtt'] = null; } - - return $patient; - } - - public function createPatient($input) { - $db = \Config\Database::connect(); - $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'); - - // Insert Data ke Tabel PatIdt - if (!empty($input['PatIdt'])) { - $this->modelPatIdt->createPatIdt($input['PatIdt'], $newInternalPID); - $this->checkDbError($db, 'Insert PatIdt'); - } - - // Insert Data ke Tabel PatCom - if (!empty($input['PatCom'])) { - $this->modelPatCom->createPatCom($input['PatCom'], $newInternalPID); - $this->checkDbError($db, 'Insert PatCom'); - } - - // Insert Data ke Tabel PatAtt - if (!empty($input['PatAtt'])) { - $this->modelPatAtt->createPatAtt($input['PatAtt'], $newInternalPID); - $this->checkDbError($db, 'Insert PatAtt'); - } - - $db->transCommit(); - - return $newInternalPID; - - } catch (\Exception $e) { - $db->transRollback(); - throw $e; - } - } - - public function updatePatient($input) { - $db = \Config\Database::connect(); - $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']); - - $db->transBegin(); - - try { - - // Update Patient - $InternalPID = $input['InternalPID']; - $this->where('InternalPID',$InternalPID)->set($input)->update(); - $this->checkDbError($db, 'Update patient'); - - // Update Patidt - if (!empty($input['PatIdt'])) { - $this->modelPatIdt->updatePatIdt($input['PatIdt'], $InternalPID); - $this->checkDbError($db, 'Update patIdt'); - } else { - $this->modelPatIdt->deletePatIdt($InternalPID); - $this->checkDbError($db, 'Update patidt'); - } - - // Update Patcom - if (!empty($input['PatCom'])) { - $this->modelPatCom->updatePatCom($input['PatCom'], $InternalPID); - $this->checkDbError($db, 'Update PatCom'); - } else { - $this->modelPatCom->deletePatCom($InternalPID); - $this->checkDbError($db, 'Update patcom'); - } - - // Update Patatt - if (!empty($input['PatAtt'])) { - $this->modelPatAtt->updatePatAtt($input['PatAtt'], $InternalPID); - $this->checkDbError($db, 'Update PatAtt'); - } else { - $this->modelPatAtt->deletePatAtt($InternalPID); - $this->checkDbError($db, 'Update/Delete patatt'); - } - - $db->transCommit(); - - return $InternalPID; - - } catch (\Exception $e) { - $db->transRollback(); - throw $e; - } - } - - private function transformPatientData(array $patient): array { - $patient["Age"] = $this->calculateAgeFromBirthdate($patient["Birthdate"], $patient["DeathDateTime"]); - $patient["DeathDateTime"] = $this->formattedDate($patient["DeathDateTime"]); - $patient["CreateDate"] = $this->formattedDate($patient["CreateDate"]); - $patient["BirthdateConversion"] = $this->formatedDateForDisplay($patient["Birthdate"]); - $patient["LinkTo"] = $this->getLinkedPatients($patient['LinkTo']); - $patient["Custodian"] = $this->getCustodian($patient['Custodian']); - $patient['PatCom'] = $patient['Comment']; - - return $patient; - } - - private function getLinkedPatients(?string $linkTo): ?array { - if (empty($linkTo)) { return null; } - - $ids = array_filter(explode(',', $linkTo)); - - return $this->db->table('patient') - ->select('InternalPID, PatientID') - ->whereIn('InternalPID', $ids) - ->get() - ->getResultArray() ?: null; - } - - private function getCustodian($custodianId): ?array { - if (empty($custodianId)) { - return null; - } - - return $this->db->table('patient') - ->select('InternalPID, PatientID') - ->where('InternalPID', (int) $custodianId) - ->get() - ->getRowArray() ?: null; - } - - // Conversion to (Years Months Days) - For Age - private function calculateAgeFromBirthdate($birthdate, $deathdatetime) { - $dob = new \DateTime($birthdate); - - // Cek DeathTime - if ($deathdatetime == null) { - $today = new \DateTime(); - } else { - $deathdatetime = new \DateTime($deathdatetime); - $today = $deathdatetime; - } - - $diff = $today->diff($dob); - $formattedAge = ""; - if ($diff->y > 0){ - $formattedAge .= "{$diff->y} Years "; - } - if ($diff->m > 0){ - $formattedAge .= "{$diff->m} Months "; - } - if ($diff->d > 0){ - $formattedAge .= "{$diff->d} Days"; - } - - return $formattedAge; - } - - // Conversion Time to Format Y-m-d\TH:i:s\Z - private function formattedDate(?string $dateString): ?string { - try { - if (empty($dateString)) {return null;} - - $dt = new \DateTime($dateString, new \DateTimeZone("UTC")); - return $dt->format('Y-m-d\TH:i:s\Z'); // ISO 8601 UTC - } catch (\Exception $e) { - return null; - } - } - - // Conversion Time to Format j M Y - For BirthdateConversion - private function formatedDateForDisplay($dateString) { - $date = \DateTime::createFromFormat('Y-m-d H:i', $dateString); - - if (!$date) { - $timestamp = strtotime($dateString); - if ($timestamp) { - return date('j M Y', $timestamp); - } - return null; - } - - return $date->format('j M Y'); - } - - // Check Error and Send Spesific Messages - private function checkDbError($db, string $context) { - $error = $db->error(); - if (!empty($error['code'])) { - throw new \Exception( - "{$context} failed: {$error['code']} - {$error['message']}" - ); - } - } - - // Preventif 0000-00-00 - private function isValidDateTime($datetime) { - if (empty($datetime) || $datetime=="") {return null; } - try { - // Kalau input hanya Y-m-d (tanpa jam) - if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $datetime)) { - $dt = \DateTime::createFromFormat('Y-m-d', $datetime); - return $dt ? $dt->format('Y-m-d') : null; // hanya tanggal - } - - // Selain itu (ISO 8601 atau datetime lain), format ke Y-m-d H:i:s - $dt = new \DateTime($datetime); - return $dt->format('Y-m-d H:i:s'); - - } catch (\Exception $e) { - return null; - } - } - -}