From 5c9daffb389fb23bb4e0d21a5735d6ad021b2693 Mon Sep 17 00:00:00 2001 From: "sas.fajri" Date: Sun, 31 May 2026 17:49:45 +0700 Subject: [PATCH] FHM31052601IBL - FPDF controllers: decrypt PII via Ibl_patient_decrypt library - Ibl_patient_decrypt: helper populate/delete patient_print_cache + decrypt_row - Inform_consent, Medical_checkup_report: decrypt langsung dari _enc (direct SQL) - Kartu_kontrol, Rpt_t_002, Rpt_t_002_eng: populate cache sebelum call SP, delete cache setelah SP selesai Co-Authored-By: Claude Sonnet 4.6 --- .../controllers/tools/Inform_consent.php | 36 ++++--- .../controllers/tools/Kartu_kontrol.php | 12 ++- .../tools/Medical_checkup_report.php | 37 ++++--- application/controllers/tools/Rpt_t_002.php | 5 + .../controllers/tools/Rpt_t_002_eng.php | 4 + application/libraries/Ibl_patient_decrypt.php | 100 ++++++++++++++++++ 6 files changed, 162 insertions(+), 32 deletions(-) create mode 100644 application/libraries/Ibl_patient_decrypt.php diff --git a/application/controllers/tools/Inform_consent.php b/application/controllers/tools/Inform_consent.php index 0fcfa4bd..55002cd4 100644 --- a/application/controllers/tools/Inform_consent.php +++ b/application/controllers/tools/Inform_consent.php @@ -10,6 +10,7 @@ class Inform_consent extends MY_Controller { parent::__construct(); $this->db_onedev = $this->load->database('onedev', true); + $this->load->library('ibl_patient_decrypt'); } public function index() @@ -68,16 +69,12 @@ class Inform_consent extends MY_Controller DATE_FORMAT(h.T_OrderHeaderDate, '%d-%m-%Y') as tanggal, DATE_FORMAT(h.T_OrderHeaderDate, '%H:%i') as jam, p.M_PatientID, - p.M_PatientNoReg, - CONCAT( - IF(TRIM(IFNULL(t.M_TitleName,''))='', '', CONCAT(TRIM(IFNULL(t.M_TitleName,'')), '. ')), - TRIM(IFNULL(p.M_PatientPrefix,'')), ' ', TRIM(IFNULL(p.M_PatientName,'')), ' ', TRIM(IFNULL(p.M_PatientSuffix,'')) - ) AS patient_name, + p.M_PatientNoReg, p.M_PatientPrefix, p.M_PatientSuffix, + t.M_TitleName, s.M_SexCode, - IFNULL(p.M_PatientPOB,'') as pob, - DATE_FORMAT(p.M_PatientDOB, '%d-%m-%Y') as dob, - IFNULL(pa.M_PatientAddressDescription,'') as alamat, - IFNULL(p.M_PatientHP,'') as phone, + p.M_PatientName_enc, p.M_PatientDOB_enc, p.M_PatientPOB_enc, + p.M_PatientDOB, p.M_PatientHP_enc, + pa.M_PatientAddressDescription_enc, IFNULL(c.M_CompanyName,'') as company_name, ( SELECT ps.Patient_SignatureUrl @@ -98,10 +95,23 @@ class Inform_consent extends MY_Controller WHERE h.T_OrderHeaderID = ? LIMIT 1"; $qry = $this->db_onedev->query($sql, [$orderHeaderId]); - if (!$qry) { - return false; - } - return $qry->row_array(); + if (!$qry) return false; + $row = $qry->row_array(); + if (!$row) return false; + + $row = $this->ibl_patient_decrypt->decrypt_row($row); + $title = trim($row['M_TitleName'] ?? ''); + $row['patient_name'] = trim( + ($title ? $title . '. ' : '') . + trim($row['M_PatientPrefix'] ?? '') . ' ' . + trim($row['M_PatientName'] ?? '') . ' ' . + trim($row['M_PatientSuffix'] ?? '') + ); + $row['dob'] = $row['M_PatientDOB']; + $row['pob'] = $row['M_PatientPOB'] ?? ''; + $row['phone'] = $row['M_PatientHP'] ?? ''; + $row['alamat'] = $row['M_PatientAddressDescription'] ?? ''; + return $row; } private function get_consent_content() diff --git a/application/controllers/tools/Kartu_kontrol.php b/application/controllers/tools/Kartu_kontrol.php index ec73a6ff..0fa8b12b 100644 --- a/application/controllers/tools/Kartu_kontrol.php +++ b/application/controllers/tools/Kartu_kontrol.php @@ -9,6 +9,7 @@ class Kartu_kontrol extends MY_Controller { parent::__construct(); $this->db_lab = $this->load->database('onedev', true); + $this->load->library('ibl_patient_decrypt'); } public function index() @@ -53,10 +54,15 @@ class Kartu_kontrol extends MY_Controller private function get_data($pid) { + // Populate decrypt cache sebelum call SP + $cache_id = $this->ibl_patient_decrypt->populate_cache_by_order($pid); + $qry = $this->db_lab->query("CALL sp_rpt_fo_001(?, 'fpdf')", [$pid]); - if (!$qry) { - return []; - } + + // Hapus cache setelah SP selesai + $this->ibl_patient_decrypt->delete_cache($cache_id); + + if (!$qry) return []; return $qry->result_array(); } diff --git a/application/controllers/tools/Medical_checkup_report.php b/application/controllers/tools/Medical_checkup_report.php index ac4fc0b2..092b7378 100644 --- a/application/controllers/tools/Medical_checkup_report.php +++ b/application/controllers/tools/Medical_checkup_report.php @@ -79,6 +79,7 @@ class Medical_checkup_report extends MY_Controller parent::__construct(); $this->db_onedev = $this->load->database('onedev', true); $this->load->library('Generateqrreport'); + $this->load->library('ibl_patient_decrypt'); } public function index() @@ -221,18 +222,10 @@ class Medical_checkup_report extends MY_Controller IFNULL(NULLIF(TRIM(IFNULL(p.M_PatientDivisi, '')), ''), '-') ) AS departemen_npk, IFNULL(s.M_SexName, '-') AS jenis_kelamin, - CONCAT( - IF(TRIM(IFNULL(t.M_TitleName, '')) = '', '', CONCAT(TRIM(t.M_TitleName), '. ')), - TRIM(IFNULL(p.M_PatientPrefix, '')), ' ', - TRIM(IFNULL(p.M_PatientName, '')), ' ', - TRIM(IFNULL(p.M_PatientSuffix, '')) - ) AS nama_pasien, - CONCAT( - IFNULL(DATE_FORMAT(p.M_PatientDOB, '%d-%m-%Y'), '-'), - ' / ', - IFNULL(NULLIF(TRIM(IFNULL(h.T_OrderHeaderM_PatientAge, '')), ''), '-') - ) AS tgl_lahir_usia, - IFNULL(pa.M_PatientAddressDescription, '-') AS alamat_pasien + p.M_PatientPrefix, p.M_PatientSuffix, t.M_TitleName, + p.M_PatientName_enc, p.M_PatientDOB_enc, + p.M_PatientDOB, h.T_OrderHeaderM_PatientAge, + pa.M_PatientAddressDescription_enc FROM t_orderheader h JOIN m_patient p ON p.M_PatientID = h.T_OrderHeaderM_PatientID LEFT JOIN m_title t ON t.M_TitleID = p.M_PatientM_TitleID @@ -244,10 +237,22 @@ class Medical_checkup_report extends MY_Controller WHERE h.T_OrderHeaderID = ? LIMIT 1"; $qry = $this->db_onedev->query($sql, [$orderHeaderId]); - if (!$qry) { - return false; - } - return $qry->row_array(); + if (!$qry) return false; + $row = $qry->row_array(); + if (!$row) return false; + + $row = $this->ibl_patient_decrypt->decrypt_row($row); + $title = trim($row['M_TitleName'] ?? ''); + $row['nama_pasien'] = trim( + ($title ? $title . '. ' : '') . + trim($row['M_PatientPrefix'] ?? '') . ' ' . + trim($row['M_PatientName'] ?? '') . ' ' . + trim($row['M_PatientSuffix'] ?? '') + ); + $row['tgl_lahir_usia'] = trim($row['M_PatientDOB'] ?? '-') . ' / ' . + trim($row['T_OrderHeaderM_PatientAge'] ?? '-'); + $row['alamat_pasien'] = $row['M_PatientAddressDescription'] ?? '-'; + return $row; } private function get_result_rows($orderHeaderId) diff --git a/application/controllers/tools/Rpt_t_002.php b/application/controllers/tools/Rpt_t_002.php index f394c0d6..6da228bc 100644 --- a/application/controllers/tools/Rpt_t_002.php +++ b/application/controllers/tools/Rpt_t_002.php @@ -4,6 +4,7 @@ class Rpt_t_002 extends MY_Controller public function __construct() { parent::__construct(); + $this->load->library('ibl_patient_decrypt'); } public function index() @@ -34,8 +35,10 @@ class Rpt_t_002 extends MY_Controller if ($an === null) { $an = ''; } + $cache_id = $this->ibl_patient_decrypt->populate_cache_by_order($orderHeaderId); $sql = 'CALL sp_rpt_t_002(?, ?, ?)'; $qry = $this->db->query($sql, [$orderHeaderId, $an, $username]); + $this->ibl_patient_decrypt->delete_cache($cache_id); $lastQry = $this->db->last_query(); if (!$qry) { @@ -75,8 +78,10 @@ class Rpt_t_002 extends MY_Controller if ($an === null) { $an = ''; } + $cache_id = $this->ibl_patient_decrypt->populate_cache_by_order($orderHeaderId); $sql = 'CALL sp_rpt_t_002(?, ?, ?)'; $qry = $this->db->query($sql, [$orderHeaderId, $an, $username]); + $this->ibl_patient_decrypt->delete_cache($cache_id); $lastQry = $this->db->last_query(); if (!$qry) { $this->sys_error_db([ diff --git a/application/controllers/tools/Rpt_t_002_eng.php b/application/controllers/tools/Rpt_t_002_eng.php index bfc1fefc..fe0ac32d 100644 --- a/application/controllers/tools/Rpt_t_002_eng.php +++ b/application/controllers/tools/Rpt_t_002_eng.php @@ -4,6 +4,7 @@ class Rpt_t_002_eng extends MY_Controller public function __construct() { parent::__construct(); + $this->load->library('ibl_patient_decrypt'); } public function index() @@ -35,8 +36,10 @@ class Rpt_t_002_eng extends MY_Controller $an = ''; } + $cache_id = $this->ibl_patient_decrypt->populate_cache_by_order($orderHeaderId); $sql = 'CALL sp_rpt_t_002_eng(?, ?, ?)'; $qry = $this->db->query($sql, [$orderHeaderId, $an, $username]); + $this->ibl_patient_decrypt->delete_cache($cache_id); $lastQry = $this->db->last_query(); if (!$qry) { @@ -77,6 +80,7 @@ class Rpt_t_002_eng extends MY_Controller $an = ''; } + $cache_id = $this->ibl_patient_decrypt->populate_cache_by_order($orderHeaderId); $sql = 'CALL sp_rpt_t_002_eng(?, ?, ?)'; $qry = $this->db->query($sql, [$orderHeaderId, $an, $username]); $lastQry = $this->db->last_query(); diff --git a/application/libraries/Ibl_patient_decrypt.php b/application/libraries/Ibl_patient_decrypt.php new file mode 100644 index 00000000..a74475e6 --- /dev/null +++ b/application/libraries/Ibl_patient_decrypt.php @@ -0,0 +1,100 @@ +db = $CI->load->database('onedev', true); + $CI->load->library('ibl_encryptor'); + $this->enc = $CI->ibl_encryptor; + } + + // Populate cache, return cache_id untuk cleanup + public function populate_cache_by_order($order_id) + { + $order_id = intval($order_id); + if (!$order_id) return null; + + $patient = $this->db->query( + "SELECT M_PatientID, M_PatientName_enc, M_PatientDOB_enc, + M_PatientHP_enc, M_PatientEmail_enc, M_PatientDOB + FROM t_orderheader + JOIN m_patient ON T_OrderHeaderM_PatientID = M_PatientID + WHERE T_OrderHeaderID = ? LIMIT 1", + [$order_id] + )->row_array(); + + if (!$patient) return null; + + $addr = $this->db->query( + "SELECT M_PatientAddressDescription_enc FROM m_patientaddress + WHERE M_PatientAddressM_PatientID = ? + AND M_PatientAddressIsActive = 'Y' + AND M_PatientAddressNote = 'Utama' + LIMIT 1", + [$patient['M_PatientID']] + )->row_array(); + + $enc = $this->enc; + $this->_insert_cache( + $order_id, + $patient['M_PatientID'], + $enc->decrypt($patient['M_PatientName_enc'] ?? '') ?? '', + $enc->decrypt($patient['M_PatientDOB_enc'] ?? '') ?? date('d-m-Y', strtotime($patient['M_PatientDOB'] ?? 'now')), + $enc->decrypt($patient['M_PatientHP_enc'] ?? '') ?? '', + $enc->decrypt($patient['M_PatientEmail_enc']?? '') ?? '', + $enc->decrypt($addr['M_PatientAddressDescription_enc'] ?? '') ?? '' + ); + + return $this->db->insert_id(); + } + + // Decrypt langsung dari query result (untuk controller dengan SQL sendiri) + public function decrypt_row(array $row): array + { + $enc = $this->enc; + if (!empty($row['M_PatientName_enc'])) $row['M_PatientName'] = $enc->decrypt($row['M_PatientName_enc']) ?? $row['M_PatientName'] ?? ''; + if (!empty($row['M_PatientDOB_enc'])) $row['M_PatientDOB'] = $enc->decrypt($row['M_PatientDOB_enc']) ?? $row['M_PatientDOB'] ?? ''; + if (!empty($row['M_PatientHP_enc'])) $row['M_PatientHP'] = $enc->decrypt($row['M_PatientHP_enc']) ?? ''; + if (!empty($row['M_PatientEmail_enc'])) $row['M_PatientEmail'] = $enc->decrypt($row['M_PatientEmail_enc']) ?? ''; + if (!empty($row['M_PatientPOB_enc'])) $row['M_PatientPOB'] = $enc->decrypt($row['M_PatientPOB_enc']) ?? ''; + if (!empty($row['M_PatientAddressDescription_enc'])) $row['M_PatientAddressDescription'] = $enc->decrypt($row['M_PatientAddressDescription_enc']) ?? ''; + if (!empty($row['phone_enc'])) $row['phone'] = $enc->decrypt($row['phone_enc']) ?? ''; + if (!empty($row['alamat_enc'])) $row['alamat'] = $enc->decrypt($row['alamat_enc']) ?? ''; + if (!empty($row['dob_enc'])) $row['dob'] = $enc->decrypt($row['dob_enc']) ?? ''; + foreach (array_keys($row) as $k) { if (substr($k, -4) === '_enc') unset($row[$k]); } + return $row; + } + + // Hapus cache by id + public function delete_cache($cache_id) + { + if ($cache_id) { + $this->db->query("DELETE FROM patient_print_cache WHERE ppc_id = ?", [$cache_id]); + } + // Cleanup expired juga + $this->db->query("DELETE FROM patient_print_cache WHERE ppc_created < NOW() - INTERVAL 5 MINUTE"); + } + + private function _insert_cache($order_id, $patient_id, $name, $dob, $hp, $email, $address) + { + $this->db->query( + "DELETE FROM patient_print_cache WHERE ppc_order_id = ? OR ppc_created < NOW() - INTERVAL 5 MINUTE", + [$order_id] + ); + $this->db->query( + "INSERT INTO patient_print_cache (ppc_order_id, ppc_patient_id, ppc_name, ppc_dob, ppc_hp, ppc_email, ppc_address, ppc_created) + VALUES (?, ?, ?, ?, ?, ?, ?, NOW())", + [$order_id, $patient_id, $name, $dob, $hp, $email, $address] + ); + } +}