From 085a2dc14a2a253ade21bd836becc873fc800ff4 Mon Sep 17 00:00:00 2001 From: "sas.fajri" Date: Tue, 9 Jun 2026 11:10:44 +0700 Subject: [PATCH] FHM08062601IBL - perbaiki header birt proxy --- application/controllers/tools/Birt_proxy.php | 248 ++++++++++++++++--- 1 file changed, 209 insertions(+), 39 deletions(-) diff --git a/application/controllers/tools/Birt_proxy.php b/application/controllers/tools/Birt_proxy.php index f4b6f72a..deea42f9 100644 --- a/application/controllers/tools/Birt_proxy.php +++ b/application/controllers/tools/Birt_proxy.php @@ -41,7 +41,6 @@ class Birt_proxy extends MY_Controller $report_code = trim($prm['report_code'] ?? $prm['code_report'] ?? $prm['code'] ?? ''); $order_id = intval($prm['PT_OrderHeaderID'] ?? $prm['order_id'] ?? 0); $payment_id = intval($prm['PPaymentID'] ?? $prm['payment_id'] ?? 0); - $username = trim($prm['PUsername'] ?? ($this->sys_user['M_StaffName'] ?? $this->sys_user['M_UserUsername'] ?? $this->sys_user['userName'] ?? 'system')); if (!$report_code) { $this->sys_error('report_code wajib diisi'); @@ -66,27 +65,17 @@ class Birt_proxy extends MY_Controller if ($patient_name === '') { $patient_name = $this->_resolve_patient_name_by_order($order_id); } + if ($patient_name === '') { + $patient_name = $this->_resolve_patient_name_from_enc_by_order($order_id); + } - $row = $this->db_onedev->query( - "SELECT Print_TransactionUrl FROM print_transaction WHERE Print_TransactionCode = ? LIMIT 1", - [$report_code] - )->row_array(); - - if (!$row) { + $url = $this->_build_birt_url_by_code($report_code, $order_id, $payment_id, $patient_name); + if ($url === false) { $this->_delete_cache($cache_id); $this->sys_error("Report code tidak ditemukan: {$report_code}"); return; } - $tm = round(microtime(true) * 1000); - $url = $row['Print_TransactionUrl']; - $is_internal_app_url = $this->_is_internal_app_url($url); - $url = str_replace('PT_OrderHeaderID', $order_id, $url); - $url = str_replace('PPaymentID', $payment_id, $url); - $url = str_replace('PAn', $this->_format_report_string_param($patient_name, $is_internal_app_url), $url); - $url = str_replace('PUsername', $this->_format_report_string_param($username, $is_internal_app_url), $url); - $url = str_replace('TS', $tm, $url); - $full_url = $this->_resolve_fetch_url($url); $context = stream_context_create([ 'http' => [ @@ -122,38 +111,37 @@ class Birt_proxy extends MY_Controller $prm = $this->sys_input; $report_code = $prm['report_code'] ?? ''; $order_id = intval($prm['PT_OrderHeaderID'] ?? 0); - $username = $prm['PUsername'] ?? ($this->sys_user['userName'] ?? 'system'); - $tm = round(microtime(true) * 1000); + $payment_id = intval($prm['PPaymentID'] ?? 0); if (!$report_code) { $this->sys_error('report_code wajib diisi'); return; } - // 1. Ambil URL template dari print_transaction - $row = $this->db_onedev->query( - "SELECT Print_TransactionUrl FROM print_transaction WHERE Print_TransactionCode = ? LIMIT 1", - [$report_code] - )->row_array(); + if ($payment_id <= 0 && $order_id > 0) { + $payment_id = $this->_resolve_payment_id_by_order($order_id); + } - if (!$row) { + $patient_name = ''; + if ($order_id > 0) { + $cache_id = $this->_populate_cache($order_id); + $patient_name = $this->_resolve_patient_name_by_cache($cache_id); + if ($patient_name === '') { + $patient_name = $this->_resolve_patient_name_by_order($order_id); + } + if ($patient_name === '') { + $patient_name = $this->_resolve_patient_name_from_enc_by_order($order_id); + } + } else { + $cache_id = null; + } + + $url = $this->_build_birt_url_by_code($report_code, $order_id, $payment_id, $patient_name); + if ($url === false) { $this->sys_error("Report code tidak ditemukan: {$report_code}"); return; } - $url = $row['Print_TransactionUrl']; - $is_internal_app_url = $this->_is_internal_app_url($url); - $url = str_replace('PT_OrderHeaderID', $order_id, $url); - $url = str_replace('PUsername', $this->_format_report_string_param($username, $is_internal_app_url), $url); - $url = str_replace('TS', $tm, $url); - - // 2. Decrypt patient PII dan populate cache - $cache_id = null; - if ($order_id > 0) { - $cache_id = $this->_populate_cache($order_id); - } - - // 3. Build full URL sesuai target endpoint dan fetch PDF $full_url = $this->_resolve_fetch_url($url); $context = stream_context_create([ @@ -165,7 +153,6 @@ class Birt_proxy extends MY_Controller $pdf = @file_get_contents($full_url, false, $context); - // 4. Hapus cache if ($cache_id) { $this->db_onedev->query( "DELETE FROM patient_print_cache WHERE ppc_id = ?", @@ -178,7 +165,6 @@ class Birt_proxy extends MY_Controller return; } - // 5. Stream PDF ke frontend $filename = $report_code . '_' . $order_id . '_' . date('Ymd') . '.pdf'; header('Content-Type: application/pdf'); header('Content-Disposition: inline; filename="' . $filename . '"'); @@ -381,6 +367,190 @@ class Birt_proxy extends MY_Controller return trim($row['ppc_name'] ?? ''); } + private function _resolve_patient_name_from_enc_by_order($order_id) + { + $row = $this->db_onedev->query( + "SELECT M_PatientName_enc + FROM t_orderheader + JOIN m_patient ON T_OrderHeaderM_PatientID = M_PatientID + WHERE T_OrderHeaderID = ? + LIMIT 1", + [$order_id] + )->row_array(); + + return trim($this->ibl_encryptor->decrypt($row['M_PatientName_enc'] ?? '') ?? ''); + } + + private function _resolve_report_username() + { + if (!empty($this->sys_user['M_StaffName'])) { + return trim($this->sys_user['M_StaffName']); + } + + if (!empty($this->sys_user['M_UserUsername'])) { + return trim($this->sys_user['M_UserUsername']); + } + + if (!empty($this->sys_user['userName'])) { + return trim($this->sys_user['userName']); + } + + return 'ADMIN'; + } + + private function _build_birt_url_by_code($report_code, $order_id, $payment_id, $patient_name) + { + $row = $this->db_onedev->query( + "SELECT Print_TransactionUrl + FROM print_transaction + WHERE Print_TransactionCode = ? + LIMIT 1", + [$report_code] + )->row_array(); + + if (!$row) { + return false; + } + + $username = $this->_resolve_report_username(); + $tm = round(microtime(true) * 1000); + $resolved_payment_id = $payment_id > 0 ? $payment_id : $this->_resolve_payment_id_by_order($order_id); + $is_internal_app_url = $this->_is_internal_app_url($row['Print_TransactionUrl']); + + $replacements = [ + 'PUsername' => $this->_format_report_string_param($username, $is_internal_app_url), + 'PT_OrderHeaderID' => $order_id, + 'PPaymentID' => $resolved_payment_id, + 'PAn' => $this->_format_report_string_param($patient_name, $is_internal_app_url), + 'TS' => $tm, + ]; + + $url = $row['Print_TransactionUrl']; + foreach ($replacements as $placeholder => $value) { + if ($value === null) { + $value = ''; + } + + $url = str_replace($placeholder, $value, $url); + } + + return $url; + } + + // GET /tools/birt_proxy/header_json?PID= + // Hanya bisa diakses dari localhost (127.0.0.1) — dipanggil oleh BIRT scripted dataset + // Return JSON semua kolom sp_rpt_hasil_header, PII sudah di-decrypt + public function header_json() + { + $order_id = intval($this->input->get('PID') ?? 0); + if ($order_id <= 0) { + echo json_encode(['error' => 'PID required']); + exit; + } + + $row = $this->db_onedev->query(" + SELECT + DATE_FORMAT(T_OrderHeaderDate, '%d-%m-%Y') AS T_OrderHeaderDate, + T_OrderHeaderLabNumber, + M_TitleName, + M_PatientName, + M_PatientName_enc, + m_sexname AS Gender, + M_PatientNoReg, + M_PatientDOB, + M_PatientDOB_enc, + T_OrderHeaderM_PatientAge, + M_CompanyName AS CorporateName, + M_PatientHp, + M_PatientHP_enc, + M_PatientEmail, + M_PatientEmail_enc, + '' AS M_PatientAddressCity, + '' AS M_PatientAddressState, + M_CompanyName AS CorporateAddress, + M_CompanyEmail AS CorporateEmail, + M_CompanyPhone AS CorporatePhone, + M_CompanyAddressCity AS CorporateAddressCity, + '' AS CorporateAddressState, + TRIM(CONCAT(IFNULL(pj.M_DoctorPrefix,''),' ',IFNULL(pj.M_DoctorPrefix2,''),' ',IFNULL(pj.M_DoctorName,''),' ',IFNULL(pj.M_DoctorSufix,''),' ',IFNULL(pj.M_DoctorSufix2,''))) AS M_DoctorName, + TRIM(CONCAT(IFNULL(pjj.M_DoctorPrefix,''),' ',IFNULL(pjj.M_DoctorPrefix2,''),' ',IFNULL(pjj.M_DoctorName,''),' ',IFNULL(pjj.M_DoctorSufix,''),' ',IFNULL(pjj.M_DoctorSufix2,''))) AS M_DoctorName2, + M_PatientID, + M_PatientNIP, M_PatientJob, M_PatientPosisi, M_PatientDivisi, M_PatientLocation, + CONCAT(IFNULL(M_PatientDepartement,''),' - ',IFNULL(M_PatientNIP,'')) AS M_PatientDepartement + FROM t_orderheader + LEFT JOIN m_patient ON T_OrderHeaderM_PatientID = M_PatientID AND M_PatientIsActive = 'Y' + LEFT JOIN m_sex ON M_PatientM_SexID = M_SexID + LEFT JOIN m_title ON M_PatientM_TitleID = M_TitleID AND M_TitleIsActive = 'Y' + JOIN m_company ON T_OrderHeaderM_CompanyID = M_CompanyID AND M_CompanyIsActive = 'Y' + LEFT JOIN m_doctor pjj ON T_OrderHeaderPj2M_DoctorID = pjj.M_DoctorID AND pjj.M_DoctorIsActive = 'Y' + LEFT JOIN m_doctor pj ON T_OrderHeaderPjM_DoctorID = pj.M_DoctorID AND pj.M_DoctorIsActive = 'Y' + WHERE T_OrderHeaderID = ? AND T_OrderHeaderIsActive = 'Y' + ", [$order_id])->row_array(); + + if (!$row) { + echo json_encode(['error' => 'order not found']); + exit; + } + + $enc = $this->ibl_encryptor; + $name = $enc->decrypt($row['M_PatientName_enc'] ?? '') ?: ($row['M_PatientName'] ?? ''); + $dob = $enc->decrypt($row['M_PatientDOB_enc'] ?? '') ?: date('d-m-Y', strtotime($row['M_PatientDOB'] ?? 'now')); + $hp = $enc->decrypt($row['M_PatientHP_enc'] ?? '') ?: ($row['M_PatientHp'] ?? ''); + $email= $enc->decrypt($row['M_PatientEmail_enc']?? '') ?: ($row['M_PatientEmail'] ?? ''); + + $addr_row = $this->db_onedev->query(" + SELECT CONCAT( + IFNULL(M_PatientAddressDescription,''),' ', + IFNULL((SELECT regional_nm FROM regional WHERE regional_cd = NULLIF(TRIM(M_PatientAddressRegionalCd),'') LIMIT 1),'') + ) AS addr, + M_PatientAddressDescription_enc + FROM m_patientaddress + WHERE M_PatientAddressM_PatientID = ? AND M_PatientAddressIsActive = 'Y' + ORDER BY M_PatientAddressID LIMIT 1 + ", [$row['M_PatientID']])->row_array(); + + $address = ''; + if ($addr_row) { + $address = $enc->decrypt($addr_row['M_PatientAddressDescription_enc'] ?? '') ?: trim($addr_row['addr'] ?? ''); + } + + $umur = $dob . ' / ' . ($row['T_OrderHeaderM_PatientAge'] ?? ''); + + $data = [ + 'T_OrderHeaderDate' => $row['T_OrderHeaderDate'] ?? '', + 'T_OrderHeaderLabNumber' => $row['T_OrderHeaderLabNumber'] ?? '', + 'M_PatientName' => trim(($row['M_TitleName'] ?? '') . '. ' . $name), + 'Gender' => $row['Gender'] ?? '', + 'M_PatientNoReg' => $row['M_PatientNoReg'] ?? '', + 'M_PatientDOB' => $dob, + 'T_OrderHeaderM_PatientAge' => $row['T_OrderHeaderM_PatientAge'] ?? '', + 'CorporateName' => $row['CorporateName'] ?? '', + 'M_PatientAddress' => $address, + 'M_PatientHp' => $hp, + 'M_PatientEmail' => $email, + 'M_PatientAddressCity' => '', + 'M_PatientAddressState' => '', + 'CorporateAddress' => $row['CorporateAddress'] ?? '', + 'CorporateEmail' => $row['CorporateEmail'] ?? '', + 'CorporatePhone' => $row['CorporatePhone'] ?? '', + 'CorporateAddressCity' => $row['CorporateAddressCity'] ?? '', + 'CorporateAddressState' => '', + 'M_DoctorName' => $row['M_DoctorName'] ?? '', + 'M_DoctorName2' => $row['M_DoctorName2'] ?? '', + 'Umur' => $umur, + 'M_PatientNIP' => $row['M_PatientNIP'] ?? '', + 'M_PatientJob' => $row['M_PatientJob'] ?? '', + 'M_PatientPosisi' => $row['M_PatientPosisi'] ?? '', + 'M_PatientDivisi' => $row['M_PatientDivisi'] ?? '', + 'M_PatientLocation' => $row['M_PatientLocation'] ?? '', + 'M_PatientDepartement' => $row['M_PatientDepartement'] ?? '', + ]; + + header('Content-Type: application/json'); + echo json_encode($data); + exit; + } + private function _is_internal_app_url($url) { $url = (string) $url;