db_onedev = $this->load->database('onedev', true); $this->load->library('ibl_encryptor'); } // POST /tools/birt_proxy/stream public function stream() { if (!$this->isLogin) { $this->sys_error('Invalid Token'); return; } $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); 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 (!$row) { $this->sys_error("Report code tidak ditemukan: {$report_code}"); return; } $url = $row['Print_TransactionUrl']; $url = str_replace('PT_OrderHeaderID', $order_id, $url); $url = str_replace('PUsername', urlencode($username), $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 BIRT URL dan fetch PDF $full_url = $this->birt_base . $url; $context = stream_context_create([ 'http' => [ 'timeout' => 120, 'method' => 'GET', ] ]); $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 = ?", [$cache_id] ); } if ($pdf === false) { $this->sys_error('Gagal generate report dari BIRT server'); 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 . '"'); header('Content-Length: ' . strlen($pdf)); echo $pdf; exit; } // Hanya return URL (untuk iframe/window.open) — tanpa stream // Frontend membuka URL ini secara langsung public function get_url() { if (!$this->isLogin) { $this->sys_error('Invalid Token'); return; } $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); $row = $this->db_onedev->query( "SELECT Print_TransactionUrl FROM print_transaction WHERE Print_TransactionCode = ? LIMIT 1", [$report_code] )->row_array(); if (!$row) { $this->sys_error("Report code tidak ditemukan: {$report_code}"); return; } $url = $row['Print_TransactionUrl']; $url = str_replace('PT_OrderHeaderID', $order_id, $url); $url = str_replace('PUsername', urlencode($username), $url); $url = str_replace('TS', $tm, $url); // Pre-populate cache — frontend buka URL langsung ke BIRT // Cache hidup 5 menit, cukup untuk BIRT generate PDF if ($order_id > 0) { $this->_populate_cache($order_id); } $this->sys_ok(['url' => $url]); } // Decrypt patient PII dan simpan ke cache private function _populate_cache($order_id) { // Ambil _enc columns dari m_patient via t_orderheader $patient = $this->db_onedev->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_onedev->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->ibl_encryptor; $name = $enc->decrypt($patient['M_PatientName_enc'] ?? '') ?? ''; $dob = $enc->decrypt($patient['M_PatientDOB_enc'] ?? '') ?? date('d-m-Y', strtotime($patient['M_PatientDOB'] ?? 'now')); $hp = $enc->decrypt($patient['M_PatientHP_enc'] ?? '') ?? ''; $email= $enc->decrypt($patient['M_PatientEmail_enc']?? '') ?? ''; $address = $enc->decrypt($addr['M_PatientAddressDescription_enc'] ?? '') ?? ''; // Hapus cache lama untuk order ini + cleanup expired $this->db_onedev->query( "DELETE FROM patient_print_cache WHERE ppc_order_id = ? OR ppc_created < NOW() - INTERVAL 5 MINUTE", [$order_id] ); // Insert cache baru $this->db_onedev->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['M_PatientID'], $name, $dob, $hp, $email, $address] ); return $this->db_onedev->insert_id(); } }