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, race.VDesc as Race, religion.VDesc as Religion, ethnic.VDesc as Ethnic, 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('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); } // Default nested structures $patient['Identity'] = null; $patient['Attachments'] = []; foreach ($rows as $row) { if ($row['IdentifierType'] && $row['Identifier'] && !$patient['Identity']) { $patient['Identity'] = [ 'IdentifierType' => $row['IdentifierType'], 'Identifier' => $row['Identifier'], ]; } if ($row['Address']) { $patient['Attachments'][] = ['Address' => $row['Address']]; } } if (empty($patient['Identity'])) { $patient['Identity'] = null; } if (empty($patient['Attachments'])) { $patient['Attachments'] = null; } return $patient; } public function createPatient($input) { $db = \Config\Database::connect(); $patidt = $input['patidt'] ?? []; $patatt = $input['patatt'] ?? []; $patcom = $input['patcom'] ?? []; try { $db->transStart(); $this->insert($input); $newInternalPID = $this->getInsertID(); if (!empty($patidt)) { $patidt['InternalPID'] = $newInternalPID; $db->table('patidt')->insert($patidt); } if (!empty($patatt)) { foreach ($patatt as &$row) { $row['InternalPID'] = $newInternalPID; } $db->table('patatt')->upsertBatch($patatt); } if (!empty($patcom['Comment'])) { $patcom['InternalPID'] = $newInternalPID; $db->table('patcom')->insert($patcom); } $db->transComplete(); if ($db->transStatus() === false) { $error = $db->error(); throw new \Exception('Transaction failed: ' . ($error['message'] ?? 'Unknown DB error')); } return $newInternalPID; } catch (\Exception $e) { $db->transRollback(); throw $e; // rethrow so controller can handle response } } private function transformPatientData(array $patient): array { $patient["Age"] = $this->calculateAgeFromBirthdate($patient["Birthdate"]); $patient["Birthdate"] = $this->formatedDate($patient["Birthdate"]); $patient["CreateDate"] = $this->formatedDate($patient["CreateDate"]); $patient["DelDate"] = $this->formatedDate($patient["DelDate"]); $patient["DeathDateTime"] = $this->formatedDate($patient["DeathDateTime"]); $patient["BirthdateConversion"] = $this->formatedDateForDisplay($patient["Birthdate"]); $patient["LinkTo"] = $this->getLinkedPatients($patient['LinkTo']); $patient["Custodian"] = $this->getCustodian($patient['Custodian']); 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) private function calculateAgeFromBirthdate($birthdate) { $dob = new \DateTime($birthdate); $today = new \DateTime(); $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 H:i private function formatedDate($dateString) { $date = \DateTime::createFromFormat('Y-m-d H:i', $dateString); if (!$date) { $timestamp = strtotime($dateString); if ($timestamp) { return date('Y-m-d H:i', $timestamp); } return null; } return $date->format('Y-m-d H:i'); } // Conversion Time to Format j M Y 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'); } }