2025-07-02 16:10:37 +07:00
< ? php
namespace App\Controllers ;
use CodeIgniter\API\ResponseTrait ;
use CodeIgniter\Controller ;
2025-10-01 12:40:05 +07:00
use App\Models\PatientModel ;
2025-07-02 16:10:37 +07:00
class Patient extends Controller {
use ResponseTrait ;
2025-10-01 12:40:05 +07:00
protected $db ;
protected $modelPatient ;
protected $rulesPatient ;
protected $rulesPatIdt ;
2025-07-02 16:10:37 +07:00
public function __construct () {
$this -> db = \Config\Database :: connect ();
2025-10-01 12:40:05 +07:00
$this -> modelPatient = new PatientModel ();
2025-09-16 15:33:22 +07:00
$this -> rulesPatient = [
'PatientID' => 'required|is_unique[patient.PatientID]|max_length[50]' ,
'AlternatePID' => 'permit_empty|max_length[50]' ,
'NameFirst' => 'required|min_length[1]|max_length[255]' ,
'EmailAddress1' => 'required|is_unique[patient.EmailAddress1]' ,
'Gender' => 'required'
];
$this -> rulesPatIdt = [ 'Identifier' => 'required|is_unique[patidt.Identifier]' ];
2025-07-02 16:10:37 +07:00
}
public function index () {
2025-10-01 12:40:05 +07:00
$filters = [
'InternalPID' => $this -> request -> getVar ( 'InternalPID' ),
'PatientID' => $this -> request -> getVar ( 'PatientID' ),
'Name' => $this -> request -> getVar ( 'Name' ),
'Birthdate' => $this -> request -> getVar ( 'Birthdate' ),
];
2025-07-23 11:03:46 +07:00
2025-10-01 12:40:05 +07:00
try {
$rows = $this -> modelPatient -> getPatients ( $filters );
return $this -> respond ([ 'status' => 'success' , 'message' => " data fetched successfully " , 'data' => $rows ], 200 );
2025-07-23 11:03:46 +07:00
} catch ( \Exception $e ) {
2025-10-01 12:40:05 +07:00
return $this -> failServerError ( 'Exception : ' . $e -> getMessage ());
2025-07-23 11:03:46 +07:00
}
2025-07-02 16:10:37 +07:00
}
2025-08-01 22:18:45 +07:00
public function show ( $InternalPID = null ) {
2025-07-23 11:03:46 +07:00
try {
2025-10-01 12:40:05 +07:00
$rows = $this -> modelPatient -> getPatient ( $InternalPID );
if ( empty ( $rows )) { return $this -> respond ([ 'status' => 'success' , 'message' => " data not found. " ], 200 ); }
return $this -> respond ([ 'status' => 'success' , 'message' => " data fetched successfully " , 'data' => $rows ], 200 );
2025-07-23 11:03:46 +07:00
} catch ( \Exception $e ) {
2025-09-08 15:56:38 +07:00
return $this -> failServerError ( 'Something went wrong: ' . $e -> getMessage ());
}
}
2025-07-23 11:03:46 +07:00
2025-07-02 16:10:37 +07:00
public function create () {
2025-10-01 12:40:05 +07:00
$input = $this -> request -> getJSON ( true );
if ( ! $this -> validateData ( $input , $this -> rulesPatient )) { return $this -> validationError ( 'patient' , $this -> validator -> getErrors ()); }
if ( ! $this -> validateData ( $input , $this -> rulesPatIdt )) { return $this -> validationError ( 'patidt' , $this -> validator -> getErrors ()); }
2025-07-23 11:03:46 +07:00
try {
2025-10-01 12:40:05 +07:00
$newInternalPID = $this -> modelPatient -> createPatient ( $input );
return $this -> respondCreated ([ 'status' => 'success' , 'message' => 'data created successfully' , 'data' => $newInternalPID ]);
2025-07-23 11:03:46 +07:00
} catch ( \Exception $e ) {
2025-08-08 13:49:18 +07:00
return $this -> failServerError ( 'Something went wrong: ' . $e -> getMessage ());
2025-07-23 11:03:46 +07:00
}
2025-07-02 16:10:37 +07:00
}
2025-09-25 14:01:33 +07:00
// Setting up data
2025-09-19 16:42:27 +07:00
private function preparePatientData ( array $input , string $mode = 'create' ) : array {
2025-09-08 15:56:38 +07:00
$LinkTo = null ;
if ( ! empty ( $input [ 'LinkTo' ])) {
$ids = array_column ( $input [ 'LinkTo' ], 'InternalPID' );
$LinkTo = implode ( ',' , $ids );
}
$data = [
" PatientID " => $input [ 'PatientID' ] ? ? null ,
" AlternatePID " => $input [ 'AlternatePID' ] ? ? null ,
" Prefix " => $input [ 'Prefix' ] ? ? null ,
" NameFirst " => $input [ 'NameFirst' ] ? ? null ,
" NameMiddle " => $input [ 'NameMiddle' ] ? ? null ,
" NameMaiden " => $input [ 'NameMaiden' ] ? ? null ,
" NameLast " => $input [ 'NameLast' ] ? ? null ,
" Suffix " => $input [ 'Suffix' ] ? ? null ,
" NameAlias " => $input [ 'NameAlias' ] ? ? null ,
" Gender " => ! empty ( $input [ 'Gender' ]) ? ( int ) $input [ 'Gender' ] : null ,
" PlaceOfBirth " => $input [ 'PlaceOfBirth' ] ? ? null ,
" Birthdate " => $input [ 'Birthdate' ] ? ? null ,
" Street_1 " => $input [ 'Street_1' ] ? ? null ,
" Street_2 " => $input [ 'Street_2' ] ? ? null ,
" Street_3 " => $input [ 'Street_3' ] ? ? null ,
" City " => $input [ 'City' ] ? ? null ,
" Province " => $input [ 'Province' ] ? ? null ,
" ZIP " => $input [ 'ZIP' ] ? ? null ,
" EmailAddress1 " => $input [ 'EmailAddress1' ] ? ? null ,
" EmailAddress2 " => $input [ 'EmailAddress2' ] ? ? null ,
" Phone " => $input [ 'Phone' ] ? ? null ,
" MobilePhone " => $input [ 'MobilePhone' ] ? ? null ,
" RaceID " => isset ( $input [ 'RaceID' ]) ? ( int ) $input [ 'RaceID' ] : null ,
" IntCountryID " => isset ( $input [ 'IntCountryID' ]) ? ( int ) $input [ 'IntCountryID' ] : null ,
" MaritalStatus " => $input [ 'MaritalStatus' ] ? ? null ,
" ReligionID " => isset ( $input [ 'ReligionID' ]) ? ( int ) $input [ 'ReligionID' ] : null ,
" EthnicID " => isset ( $input [ 'EthnicID' ]) ? ( int ) $input [ 'EthnicID' ] : null ,
" Citizenship " => $input [ 'Citizenship' ] ? ? null ,
" DeathIndicator " => isset ( $input [ 'DeathIndicator' ]) ? ( int ) $input [ 'DeathIndicator' ] : null ,
" DeathDateTime " => $input [ 'DeathDateTime' ] ? ? null ,
" Custodian " => isset ( $input [ 'Custodian' ]) ? ( int ) $input [ 'Custodian' ] : null ,
" DelDate " => null ,
" LinkTo " => $LinkTo
];
2025-09-16 15:33:22 +07:00
if ( ! empty ( $input [ 'InternalPID' ])) { $data [ " InternalPID " ] = $input [ " InternalPID " ]; }
2025-09-08 15:56:38 +07:00
return $data ;
}
2025-09-16 15:33:22 +07:00
private function preparePatidtData ( array $input ) : array {
2025-09-08 15:56:38 +07:00
$data = [
" IdentifierType " => $input [ 'Identity' ][ 'IdentifierType' ] ? ? null ,
" Identifier " => $input [ 'Identity' ][ 'Identifier' ] ? ? null ,
];
return $data ;
}
2025-09-16 15:33:22 +07:00
private function preparePatattData ( array $input ) : array {
2025-09-08 15:56:38 +07:00
if ( empty ( $input [ 'Attachments' ])) {
return [];
}
2025-09-16 15:33:22 +07:00
return array_map ( function ( $attachment ) {
2025-09-08 15:56:38 +07:00
$row = [
" Address " => $attachment [ 'Address' ] ? ? null ,
];
return $row ;
}, $input [ 'Attachments' ]);
}
2025-09-16 15:33:22 +07:00
private function preparePatcomData ( array $input ) : array {
2025-09-08 15:56:38 +07:00
$data = [
" Comment " => $input [ 'Comment' ] ? ? null ,
];
return $data ;
}
2025-09-16 15:33:22 +07:00
private function validationError ( string $context , array $errors ) {
2025-09-08 15:56:38 +07:00
return $this -> respond ([
'status' => 'error' ,
'message' => " Validation failed ( { $context } ) " ,
'errors' => $errors
], 400 );
}
2025-09-25 14:01:33 +07:00
// Unit Testing Pass : On Progress
2025-09-16 15:33:22 +07:00
public function update () {
2025-07-23 11:03:46 +07:00
try {
$input = $this -> request -> getJSON ( true );
2025-09-08 15:56:38 +07:00
if ( ! $input ) { return $this -> respond ([ 'status' => 'error' , 'message' => 'Invalid JSON input' ], 400 ); }
2025-09-16 15:33:22 +07:00
if ( ! $input [ " InternalPID " ] || ! is_numeric ( $input [ " InternalPID " ])) { return $this -> respond ([ 'status' => 'error' , 'message' => 'Invalid or missing InternalPID' ], 400 ); }
$InternalPID = $input [ " InternalPID " ];
2025-09-25 14:01:33 +07:00
$patient = $this -> db -> table ( 'patient' ) -> where ( 'InternalPID' , $InternalPID ) -> get () -> getRowArray ();
2025-09-08 15:56:38 +07:00
if ( ! $patient ) { return $this -> respond ([ 'status' => 'error' , 'message' => 'Patient not found' ], 404 ); }
2025-07-02 16:10:37 +07:00
2025-09-16 15:33:22 +07:00
$dataPatient = $this -> preparePatientData ( $input );
$dataPatIdt = $this -> preparePatidtData ( $input );
$dataPatCom = $this -> preparePatcomData ( $input );
$dataPatAtt = $this -> preparePatattData ( $input );
2025-08-12 09:19:10 +07:00
// Validasi
2025-09-16 15:33:22 +07:00
if ( ! $this -> validateData ( $dataPatient , $this -> rulesPatient )) {
2025-08-12 09:19:10 +07:00
return $this -> respond ([
'status' => 'error' ,
'message' => 'Validation failed (patient)' ,
'errors' => $this -> validator -> getErrors ()
], 400 );
2025-07-02 16:10:37 +07:00
}
2025-09-16 15:33:22 +07:00
if ( ! $this -> validateData ( $dataPatIdt , $this -> rulesPatIdt )) {
2025-08-12 09:19:10 +07:00
return $this -> respond ([
'status' => 'error' ,
'message' => 'Validation failed (patidt)' ,
'errors' => $this -> validator -> getErrors ()
], 400 );
2025-07-23 11:03:46 +07:00
}
2025-08-12 09:19:10 +07:00
$this -> db -> transStart ();
2025-07-23 11:03:46 +07:00
2025-08-12 09:19:10 +07:00
$this -> db -> table ( 'patient' ) -> where ( 'InternalPID' , $InternalPID ) -> update ( $dataPatient );
$dbError = $this -> db -> error ();
if ( ! empty ( $dbError [ 'message' ])) {
$this -> db -> transRollback ();
return $this -> failServerError ( 'Update patient failed: ' . $dbError [ 'message' ]);
2025-07-23 11:03:46 +07:00
}
2025-09-16 15:33:22 +07:00
$this -> db -> table ( 'patidt' ) -> where ( 'InternalPID' , $InternalPID ) -> update ( $dataPatIdt );
2025-08-12 09:19:10 +07:00
$dbError = $this -> db -> error ();
if ( ! empty ( $dbError [ 'message' ])) {
$this -> db -> transRollback ();
return $this -> failServerError ( 'Update patidt failed: ' . $dbError [ 'message' ]);
2025-07-23 11:03:46 +07:00
}
2025-09-16 15:33:22 +07:00
if ( ! empty ( $dataPatAtt )) {
foreach ( $dataPatAtt as & $row ) {
2025-09-08 15:56:38 +07:00
$row [ 'InternalPID' ] = $InternalPID ;
}
2025-09-16 15:33:22 +07:00
$this -> db -> table ( 'patatt' ) -> upsertBatch ( $dataPatAtt );
$addresses = array_column ( $dataPatAtt , 'Address' );
2025-09-08 16:53:49 +07:00
$this -> db -> table ( 'patatt' ) -> where ( 'InternalPID' , $InternalPID ) -> WhereNotIn ( 'Address' , $addresses ) -> update ([ 'DelDate' => date ( 'Y-m-d H:i:s' )]);
} else {
$this -> db -> table ( 'patatt' ) -> where ( 'InternalPID' , $InternalPID ) -> update ([ 'DelDate' => date ( 'Y-m-d H:i:s' )]);
2025-09-08 15:56:38 +07:00
}
if ( ! empty ( $dataPatcom [ 'Comment' ])) {
$dataPatcom [ 'InternalPID' ] = $InternalPID ;
2025-09-16 15:33:22 +07:00
$this -> db -> table ( 'patcom' ) -> upsert ( $dataPatCom );
2025-09-08 15:56:38 +07:00
}
2025-08-12 09:19:10 +07:00
$this -> db -> transComplete ();
2025-07-02 16:10:37 +07:00
2025-08-12 09:19:10 +07:00
if ( $this -> db -> transStatus () === false ) {
$dbError = $this -> db -> error ();
return $this -> failServerError ( 'Failed to update patient data (transaction rolled back): ' . ( $dbError [ 'message' ] ? ? 'Unknown error' ));
}
return $this -> respond ([
'status' => 'success' ,
2025-07-23 11:03:46 +07:00
'message' => 'Patient updated successfully' ,
2025-09-16 15:33:22 +07:00
'data' => $dataPatient
2025-08-12 09:19:10 +07:00
], 200 );
2025-07-02 16:10:37 +07:00
2025-07-23 11:03:46 +07:00
} catch ( \Exception $e ) {
2025-08-12 09:19:10 +07:00
$this -> db -> transRollback ();
return $this -> failServerError ( 'Something went wrong: ' . $e -> getMessage ());
}
2025-07-02 16:10:37 +07:00
}
2025-07-23 11:03:46 +07:00
2025-09-25 14:01:33 +07:00
// Unit Testing Pass : \clqms-be\tests\feature\Patients\PatientDeleteTest.php
2025-09-16 15:33:22 +07:00
public function delete () {
2025-07-23 11:03:46 +07:00
try {
2025-09-16 15:33:22 +07:00
$input = $this -> request -> getJSON ( true );
$InternalPID = $input [ " InternalPID " ];
2025-09-25 14:01:33 +07:00
// Mencegah Inputan 0, [], null, sql injection
if ( empty ( $InternalPID ) || ! ctype_digit (( string ) $InternalPID )) {
return $this -> respond ([
'status' => 'error' ,
'message' => " Patient ID must be a valid integer. "
], 400 );
2025-07-23 11:03:46 +07:00
}
2025-08-01 22:26:27 +07:00
$patient = $this -> db -> table ( 'patient' ) -> where ( 'InternalPID' , $InternalPID ) -> get () -> getRow ();
2025-07-23 11:03:46 +07:00
if ( ! $patient ) {
2025-08-01 22:18:45 +07:00
return $this -> failNotFound ( " Patient ID with { $InternalPID } not found. " );
2025-07-23 11:03:46 +07:00
}
2025-08-05 10:03:33 +07:00
$this -> db -> table ( 'patient' ) -> where ( 'InternalPID' , $InternalPID ) -> update ([ 'DelDate' => date ( 'Y-m-d H:i:s' )]);
2025-07-23 11:03:46 +07:00
return $this -> respondDeleted ([
'status' => 'success' ,
2025-08-01 22:18:45 +07:00
'message' => " Patient ID with { $InternalPID } deleted successfully. "
2025-07-23 11:03:46 +07:00
]);
} catch ( \Exception $e ) {
return $this -> failServerError ( " Internal server error: " . $e -> getMessage ());
}
}
2025-08-14 15:28:16 +07:00
public function patientCheck () {
2025-08-14 09:17:15 +07:00
try {
2025-08-14 15:28:16 +07:00
$PatientID = $this -> request -> getVar ( 'PatientID' );
$EmailAddress1 = $this -> request -> getVar ( 'EmailAddress1' );
if ( $PatientID != null ){
$tableName = 'PatientID' ;
$searchName = $PatientID ;
}
if ( $EmailAddress1 != null ){
$tableName = 'EmailAddress1' ;
$searchName = $EmailAddress1 ;
2025-08-14 09:17:15 +07:00
}
$patient = $this -> db -> table ( 'patient' )
2025-08-14 15:28:16 +07:00
-> where ( $tableName , $searchName )
2025-08-14 09:17:15 +07:00
-> get ()
2025-09-25 14:01:33 +07:00
-> getRowArray ();
2025-08-14 09:17:15 +07:00
if ( ! $patient ) {
return $this -> respond ([
'status' => 'success' ,
2025-08-14 15:28:16 +07:00
'message' => " $tableName not found. " ,
2025-08-14 09:17:15 +07:00
'data' => true ,
], 200 );
}
return $this -> respond ([
'status' => 'success' ,
2025-08-14 15:28:16 +07:00
'message' => " $tableName already exists. " ,
2025-08-14 09:17:15 +07:00
'data' => false ,
], 200 );
2025-08-14 15:28:16 +07:00
} catch ( \Exception $e ) {
// Error Server Mengembalikan 500
return $this -> failServerError ( 'Something went wrong.' . $e -> getMessage ());
2025-08-14 09:17:15 +07:00
}
}
2025-07-02 16:10:37 +07:00
}