clqms-be/app/Controllers/Patient/PatientController.php
mahdahar e5ac1957fe ● refactor: update API responses to use {field}Label format
- Transform coded fields to lowercase with Label suffix for display text                                                                                                                                              - Controllers: OrderTestController, DemoOrderController, SpecimenController,
    SpecimenStatusController, SpecimenCollectionController, ContainerDefController,
    ContactController, TestMapController
  - Example: Priority: "R" → priority: "R", priorityLabel: "Routine"
  - Update api-docs.yaml with new OpenAPI schema definitions
  - Add API docs reminder to CLAUDE.md
2026-01-28 17:31:00 +07:00

237 lines
10 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Controllers\Patient;
use CodeIgniter\API\ResponseTrait;
use CodeIgniter\Controller;
use App\Models\Patient\PatientModel;
class PatientController extends Controller {
use ResponseTrait;
protected $db;
protected $model;
protected $rules;
use App\Libraries\ValueSet;
public function __construct() {
$this->db = \Config\Database::connect();
$this->model = new PatientModel();
$this->rules = [
'PatientID' => 'required|regex_match[/^[A-Za-z0-9]+$/]|max_length[30]',
'AlternatePID' => 'permit_empty|regex_match[/^[A-Za-z0-9]+$/]|max_length[30]',
'Prefix' => 'permit_empty|regex_match[/^[A-Za-z\'\. ]+$/]|max_length[10]',
'Sex' => 'required',
'NameFirst' => 'required|regex_match[/^[A-Za-z\'\. ]+$/]|min_length[1]|max_length[60]',
'NameMiddle' => 'permit_empty|regex_match[/^[A-Za-z\'\. ]+$/]|min_length[1]|max_length[60]',
'NameMaiden' => 'permit_empty|regex_match[/^[A-Za-z\'\. ]+$/]|min_length[1]|max_length[60]',
'NameLast' => 'permit_empty|regex_match[/^[A-Za-z\'\. ]+$/]|min_length[1]|max_length[60]',
'Suffix' => 'permit_empty|regex_match[/^[A-Za-z\'\. ]+$/]|max_length[10]',
'PlaceOfBirth' => 'permit_empty|regex_match[/^[A-Za-z\'\. ]+$/]|max_length[100]',
'Citizenship' => 'permit_empty|regex_match[/^[A-Za-z\'\. ]+$/]|max_length[100]',
'Street_1' => 'permit_empty|regex_match[/^[A-Za-z0-9\'.,\/\- ]+$/]|max_length[255]',
'Street_2' => 'permit_empty|regex_match[/^[A-Za-z0-9\'.,\/\- ]+$/]|max_length[255]',
'Street_3' => 'permit_empty|regex_match[/^[A-Za-z0-9\'.,\/\- ]+$/]|max_length[255]',
'EmailAddress1' => 'permit_empty|valid_email|max_length[100]',
'EmailAddress2' => 'permit_empty|valid_email|max_length[100]',
'Birthdate' => 'required',
'PatIdt.IdentifierType' => 'permit_empty',
'PatIdt.Identifier' => 'permit_empty|max_length[255]',
'ZIP' => 'permit_empty|is_natural|max_length[10]',
'Phone' => 'permit_empty|regex_match[/^\\+?[0-9]{8,15}$/]',
'MobilePhone' => 'permit_empty|regex_match[/^\\+?[0-9]{8,15}$/]'
];
}
public function index() {
$filters = [
'InternalPID' => $this->request->getVar('InternalPID'),
'PatientID' => $this->request->getVar('PatientID'),
'Name' => $this->request->getVar('Name'),
'Birthdate' => $this->request->getVar('Birthdate'),
];
try {
$rows = $this->model->getPatients($filters);
// Transform Sex to sex and sexLabel
foreach ($rows as &$row) {
if (isset($row['Sex'])) {
$row['sex'] = $row['Sex'];
$row['sexLabel'] = ValueSet::getLabel('sex', $row['Sex']) ?? '';
unset($row['Sex']);
}
}
return $this->respond([ 'status' => 'success', 'message'=> "data fetched successfully", 'data' => $rows ], 200);
} catch (\Exception $e) {
return $this->failServerError('Exception : '.$e->getMessage());
}
}
public function show($InternalPID = null) {
try {
$row = $this->model->getPatient($InternalPID);
if (empty($row)) { return $this->respond([ 'status' => 'success', 'message' => "data not found.", 'data' => null ], 200); }
// Transform Sex to sex and sexLabel
if (isset($row['Sex'])) {
$row['sex'] = $row['Sex'];
$row['sexLabel'] = ValueSet::getLabel('sex', $row['Sex']) ?? '';
unset($row['Sex']);
}
return $this->respond([ 'status' => 'success', 'message' => "data fetched successfully", 'data' => $row ], 200);
} catch (\Exception $e) {
return $this->failServerError('Something went wrong: ' . $e->getMessage());
}
}
public function create() {
$input = $this->request->getJSON(true);
// Khusus untuk Override PATIDT
$type = $input['PatIdt']['IdentifierType'] ?? null;
$identifierRulesMap = [
'KTP' => 'required|regex_match[/^[0-9]{16}$/]', // 16 pas digit numeric
'PASS' => 'required|regex_match[/^[A-Za-z0-9]{1,9}$/]', // alphanumeric max 9
'SSN' => 'required|regex_match[/^[0-9]{9}$/]', // numeric, pas 9 digit
'SIM' => 'required|regex_match[/^[0-9]{19,20}$/]', // numeric 1920 digit
'KTAS' => 'required|regex_match[/^[0-9]{11}$/]', // numeric, pas 11 digit
];
if ($type === null || $type === '' || !is_string($type)) {
$identifierRule = 'permit_empty|max_length[255]';
$this->rules['PatIdt.IdentifierType'] = 'permit_empty';
$this->rules['PatIdt.Identifier'] = $identifierRule;
} else {
$identifierRule = $identifierRulesMap[$type] ?? 'permit_empty|max_length[255]';
$this->rules['PatIdt.IdentifierType'] = 'required';
$this->rules['PatIdt.Identifier'] = $identifierRule;
}
if (!$this->validateData($input, $this->rules)) { return $this->failValidationErrors($this->validator->getErrors()); }
try {
$InternalPID = $this->model->createPatient($input);
return $this->respondCreated([ 'status' => 'success', 'message' => "data $InternalPID created successfully" ]);
} catch (\Exception $e) {
return $this->failServerError('Something went wrong: ' . $e->getMessage());
}
}
public function update() {
$input = $this->request->getJSON(true);
// Khusus untuk Override PATIDT
$type = $input['PatIdt']['IdentifierType'] ?? null;
$identifierRulesMap = [
'KTP' => 'required|regex_match[/^[0-9]{16}$/]',
'PASS' => 'required|regex_match[/^[A-Za-z0-9]{6,9}$/]',
'SSN' => 'required|regex_match[/^[0-9]{3}-[0-9]{2}-[0-9]{4}$/]',
'SIM' => 'required|regex_match[/^[A-Za-z0-9]{12,14}$/]',
'KTAS' => 'required|regex_match[/^[A-Za-z0-9]{12,15}$/]',
];
if ($type === null || $type === '' || !is_string($type)) {
$identifierRule = 'permit_empty|max_length[255]';
$this->rules['PatIdt.IdentifierType'] = 'permit_empty';
$this->rules['PatIdt.Identifier'] = $identifierRule;
} else {
$identifierRule = $identifierRulesMap[$type] ?? 'permit_empty|max_length[255]';
$this->rules['PatIdt.IdentifierType'] = 'required';
$this->rules['PatIdt.Identifier'] = $identifierRule;
}
if (!$this->validateData($input, $this->rules)) { return $this->failValidationErrors($this->validator->getErrors()); }
try {
$InternalPID = $this->model->updatePatient($input);
return $this->respondCreated([ 'status' => 'success', 'message' => "data $InternalPID update successfully" ]);
} catch (\Exception $e) {
return $this->failServerError('Something went wrong: ' . $e->getMessage());
}
}
public function delete() {
try {
$input = $this->request->getJSON(true);
$InternalPID = $input["InternalPID"];
// 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);
}
$patient = $this->db->table('patient')->where('InternalPID', $InternalPID)->get()->getRow();
if (!$patient) {
return $this->failNotFound("Patient ID with {$InternalPID} not found.");
}
$this->db->table('patient')->where('InternalPID', $InternalPID)->update(['DelDate' => date('Y-m-d H:i:s')]);
return $this->respondDeleted([
'status' => 'success',
'message' => "Patient ID with {$InternalPID} deleted successfully."
]);
} catch (\Exception $e) {
return $this->failServerError("Internal server error: " . $e->getMessage());
}
}
public function patientCheck() {
try {
$PatientID = $this->request->getVar('PatientID');
$EmailAddress1 = $this->request->getVar('EmailAddress1');
$tableName = '';
$searchName = '';
if (!empty($PatientID)){
$tableName = 'PatientID';
$searchName = $PatientID;
} elseif (!empty($EmailAddress1)){
$tableName = 'EmailAddress1';
$searchName = $EmailAddress1;
} else {
return $this->respond([
'status' => 'error',
'message' => 'PatientID or EmailAddress1 parameter is required.',
'data' => null
], 400);
}
$patient = $this->db->table('patient')
->where($tableName, $searchName)
->get()
->getRowArray();
if (!$patient) {
return $this->respond([
'status' => 'success',
'message' => "$tableName not found.",
'data' => true,
], 200);
}
return $this->respond([
'status' => 'success',
'message' => "$tableName already exists.",
'data' => false,
], 200);
} catch (\Exception $e) {
// Error Server Mengembalikan 500
return $this->failServerError('Something went wrong.'.$e->getMessage());
}
}
}