db_onedev = $this->load->database('onedev', true); } public function index() { $this->sys_ok([ 'message' => 'Use /tools/inform_consent_cpmi/pdf?T_OrderHeaderID=' ]); } public function pdf() { try { $orderHeaderId = intval($this->input->get('T_OrderHeaderID', true)); if ($orderHeaderId <= 0) { $orderHeaderId = intval($this->input->get('PID', true)); } if ($orderHeaderId <= 0) { $this->sys_error('T_OrderHeaderID mandatory'); return; } $patient = $this->get_patient_data($orderHeaderId); if (!$patient) { $this->sys_error('Order not found'); return; } $content = $this->get_consent_content(); $printBy = trim((string)$this->input->get('username', true)); if ($printBy === '') { $printBy = 'ADMIN'; } $printDate = date('M j, Y g:i A'); require_once APPPATH . 'third_party/fpdf/fpdf.php'; $pdf = new FPDF('P', 'mm', 'A4'); $pdf->SetAutoPageBreak(false); $pdf->SetMargins(10, 10, 10); $this->render_report($pdf, $patient, $content, $printBy, $printDate); header('Content-Type: application/pdf'); header('Content-Disposition: inline; filename="inform_consent_cpmi_' . $orderHeaderId . '.pdf"'); echo $pdf->Output('S'); } catch (Exception $e) { $this->sys_error($e->getMessage()); } } private function get_patient_data($orderHeaderId) { $sql = "SELECT h.T_OrderHeaderID, DATE_FORMAT(h.T_OrderHeaderDate, '%d-%m-%Y') as tanggal, IFNULL(h.T_OrderHeaderM_PatientAge, '') as age, p.M_PatientID, CONCAT(TRIM(IFNULL(t.M_TitleName,'')), ' ', TRIM(IFNULL(p.M_PatientPrefix,'')), ' ', TRIM(IFNULL(p.M_PatientName,'')), ' ', TRIM(IFNULL(p.M_PatientSuffix,''))) AS patient_name, IFNULL(s.M_SexCode, '') as sex_code, DATE_FORMAT(p.M_PatientDOB, '%d-%m-%Y') as dob, IFNULL(pa.M_PatientAddressDescription,'') as alamat, ( SELECT ps.Patient_SignatureUrl FROM patient_signature ps WHERE ps.Patient_SignatureM_PatientID = p.M_PatientID AND ps.Patient_SignatureIsActive = 'Y' ORDER BY ps.Patient_SignatureID DESC LIMIT 1 ) AS signature_url 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 LEFT JOIN m_sex s ON s.M_SexID = p.M_PatientM_SexID LEFT JOIN m_patientaddress pa ON pa.M_PatientAddressM_PatientID = p.M_PatientID AND pa.M_PatientAddressNote = 'Utama' AND pa.M_PatientAddressIsActive = 'Y' WHERE h.T_OrderHeaderID = ? LIMIT 1"; $qry = $this->db_onedev->query($sql, [$orderHeaderId]); return $qry ? $qry->row_array() : null; } private function get_consent_content() { $sql = "SELECT M_InformConsentContent FROM m_informconsent WHERE M_InformConsentType = 'cpmi' AND M_InformConsentIsActive = 'Y' LIMIT 1"; $qry = $this->db_onedev->query($sql); if (!$qry || !$qry->row_array()) { return ''; } return (string)$qry->row_array()['M_InformConsentContent']; } private function render_report($pdf, $patient, $contentHtml, $printBy, $printDate) { $pdf->AddPage(); $logoPath = APPPATH . '../assets/images/logo-ibl-round.png'; if (is_file($logoPath)) { $pdf->Image($logoPath, 14, 21, 22); } $pdf->SetFont('Times', 'B', 17); $pdf->SetXY(40, 18); $pdf->Cell(70, 8, 'KLINIK UTAMA', 0, 1, 'L'); $pdf->SetFont('Times', 'BI', 18); $pdf->SetXY(40, 26); $pdf->Cell(70, 8, 'IMAM', 0, 1, 'L'); $pdf->SetXY(40, 34); $pdf->Cell(70, 8, 'BONJOL', 0, 1, 'L'); $pdf->SetFont('Arial', '', 9); $pdf->SetXY(40, 42); $pdf->Cell(70, 6, 'Jl. Imam Bonjol 173 Semarang', 0, 1, 'L'); $pdf->SetFont('Times', '', 10); $pdf->SetXY(140, 12); $pdf->Cell(55, 6, 'FR/IBL-IB/Lab/PM-4.2/02', 0, 1, 'R'); $pdf->SetFont('Arial', '', 11); $pdf->SetXY(98, 32); $pdf->MultiCell(80, 6, "GENERAL CONSENT\nMEDICAL TEST CPMI", 0, 'L'); $y = 56; $pdf->SetFont('Arial', '', 9); $pdf->SetXY(14, $y); $pdf->Cell(80, 5, 'Saya yang bertanda tangan dibawah ini :', 0, 1, 'L'); $y += 8; $y = $this->line_form($pdf, $y, 'Nama lengkap', trim(preg_replace('/\s+/', ' ', $patient['patient_name']))); $y = $this->line_form($pdf, $y, 'Bin / Binti', '...............................................................'); $ttlUsia = trim($patient['dob']) . ' / ' . trim((string)$patient['age']); $y = $this->line_form($pdf, $y, 'Tanggal lahir / Usia', $ttlUsia . ' tahun'); $y = $this->line_form($pdf, $y, 'Status', 'Kawin / Tidak Kawin'); $y = $this->line_form($pdf, $y, 'Alamat', $patient['alamat']); $y += 2; $blocks = $this->html_to_blocks($contentHtml); $pdf->SetFont('Arial', '', 8.2); $lineH = 5.2; foreach ($blocks as $b) { $indent = (float)$b['indent']; $style = (string)$b['style']; $text = (string)$b['text']; $w = max(20, 182 - $indent); if ($y > 228) { break; } $pdf->SetFont('Arial', $style, 8.2); $pdf->SetXY(14 + $indent, $y); $pdf->MultiCell($w, $lineH, $this->safe_text($text), 0, 'L'); $y = $pdf->GetY(); } $y += 3; $pdf->SetFont('Arial', '', 8); $pdf->SetXY(104, $y - 4); $pdf->Cell(90, 5, 'Semarang, ' . $patient['tanggal'], 0, 1, 'R'); $pdf->SetXY(14, $y); $pdf->Cell(90, 5, 'Petugas yang memberi penjelasan', 0, 0, 'L'); $pdf->Cell(90, 5, 'Yang membuat pernyataan', 0, 1, 'R'); $y += 12; $pdf->SetXY(14, $y); $pdf->Cell(90, 5, '( ................................ )', 0, 0, 'L'); $signaturePath = $this->resolve_signature_path(isset($patient['signature_url']) ? $patient['signature_url'] : ''); if ($signaturePath !== null) { $pdf->Image($signaturePath, 156, $y - 8, 34, 10); } $pdf->SetFont('Arial', 'U', 8.5); $pdf->SetXY(149, $y); $pdf->Cell(54, 5, $this->safe_text(trim(preg_replace('/\s+/', ' ', $patient['patient_name']))), 0, 1, 'C'); $y += 8; $pdf->Line(14, $y, 196, $y); $y += 4; $pdf->SetFont('Arial', '', 10); $pdf->SetXY(14, $y); $pdf->Cell(182, 5, 'CHECK LIST PEMERIKSAAN', 0, 1, 'C'); $y += 6; $labelsPage1 = ['Online Sidik Jari', 'Foto', 'Fisik', 'Darah + Urine', 'Feses', 'Sputum', 'Radiologi']; $this->draw_checklist_table($pdf, 26, $y, $labelsPage1); $pdf->SetFont('Times', '', 7); $pdf->SetXY(14, 286); $pdf->Cell(22, 4, 'Print Oleh :', 0, 0, 'L'); $pdf->Cell(50, 4, $this->safe_text($printBy), 0, 0, 'L'); $pdf->Cell(12, 4, '1', 0, 0, 'C'); $pdf->Cell(6, 4, '/', 0, 0, 'C'); $pdf->Cell(12, 4, '2', 0, 0, 'C'); $date = $this->safe_text($printDate); $dateW = $pdf->GetStringWidth($date); $xDate = max(120, 196 - $dateW); $pdf->SetXY($xDate, 286); $pdf->Cell($dateW + 1, 4, $date, 0, 1, 'L'); $this->render_second_checklist_page($pdf, $printBy, $printDate); } private function render_second_checklist_page($pdf, $printBy, $printDate) { $pdf->AddPage(); $pdf->SetFont('Arial', '', 10); $pdf->SetXY(140, 12); $pdf->Cell(55, 6, 'FR/IBL-IB/Lab/PM-4.2/02', 0, 1, 'R'); $labelsPage2 = ['EKG', 'Audiometri', 'Lain-Lain', 'Cetak Hasil', 'Cek I', 'Cek II', 'Revisi']; $this->draw_checklist_table($pdf, 26, 30, $labelsPage2); $pdf->SetFont('Times', '', 7); $pdf->SetXY(14, 286); $pdf->Cell(22, 4, 'Print Oleh :', 0, 0, 'L'); $pdf->Cell(50, 4, $this->safe_text($printBy), 0, 0, 'L'); $pdf->Cell(12, 4, '2', 0, 0, 'C'); $pdf->Cell(6, 4, '/', 0, 0, 'C'); $pdf->Cell(12, 4, '2', 0, 0, 'C'); $date = $this->safe_text($printDate); $dateW = $pdf->GetStringWidth($date); $xDate = max(120, 196 - $dateW); $pdf->SetXY($xDate, 286); $pdf->Cell($dateW + 1, 4, $date, 0, 1, 'L'); } private function draw_checklist_table($pdf, $xStart, $yStart, $labels) { $cols = count($labels); if ($cols < 1) { return; } $tableW = 156; $colW = $tableW / $cols; $topH = 11; $bottomH = 10; for ($i = 0; $i < $cols; $i++) { $x = $xStart + ($i * $colW); $pdf->Rect($x, $yStart, $colW, $topH); $pdf->Rect($x, $yStart + $topH, $colW, $bottomH); $pdf->Rect($x + 1, $yStart + 1, 4, 4); $label = $labels[$i]; if ($label === 'Online Sidik Jari') { $label = "Online\nSidik Jari"; } elseif ($label === 'Darah + Urine') { $label = "Darah +\nUrine"; } $pdf->SetFont('Arial', '', 8); $pdf->SetXY($x + 5.5, $yStart + 1.5); $pdf->MultiCell($colW - 6, 4, $this->safe_text($label), 0, 'C'); } } private function line_form($pdf, $y, $label, $value) { $pdf->SetFont('Arial', '', 9); $pdf->SetXY(16, $y); $pdf->Cell(28, 5, $this->safe_text($label), 0, 0, 'L'); $pdf->Cell(3, 5, ':', 0, 0, 'C'); $pdf->SetXY(47, $y); $pdf->MultiCell(147, 5, $this->safe_text($value), 0, 'L'); return $pdf->GetY() + 1; } private function html_to_blocks($html) { $input = (string)$html; $input = str_replace(['\\r\\n', '\\n', '\\r'], "\n", $input); $input = str_replace(["\r\n", "\r"], "\n", $input); $blocks = []; $s = preg_replace('//i', "\n", $input); $s = preg_replace('/<\/(div|p|h[1-6]|li)>/i', "$0\n", $s); preg_match_all('/<(h[1-6]|p|li)[^>]*>(.*?)<\/\1>/is', $s, $matches, PREG_SET_ORDER); foreach ($matches as $m) { $tag = strtolower($m[1]); $inner = preg_replace('/<(ul|ol)[^>]*>.*?<\/\1>/is', '', (string)$m[2]); $plain = trim(preg_replace('/\s+/', ' ', html_entity_decode(strip_tags($inner), ENT_QUOTES | ENT_HTML5, 'UTF-8'))); if ($plain === '' || $plain === ':') { continue; } $indent = 0; $style = ''; $text = $plain; if ($tag === 'h1' || $tag === 'h2' || $tag === 'h3' || $tag === 'h4' || $tag === 'h5' || $tag === 'h6') { $style = 'B'; } elseif ($tag === 'li') { if (preg_match('/^[0-9]+\./', $plain) || preg_match('/^[IVX]+\./i', $plain)) { $text = $plain; $indent = 0; } else { $text = '• ' . $plain; $indent = 5; } } elseif ($tag === 'p' && (stripos((string)$m[2], ' $text, 'indent' => $indent, 'style' => $style ]; } return $blocks; } private function safe_text($text) { return iconv('UTF-8', 'windows-1252//TRANSLIT', (string)$text); } private function resolve_signature_path($signatureUrl) { $url = trim((string)$signatureUrl); if ($url === '') { return null; } if (preg_match('#^https?://#i', $url)) { $tmp = sys_get_temp_dir() . '/sig_' . md5($url) . '.png'; if (!is_file($tmp)) { $ctx = stream_context_create([ 'http' => ['timeout' => 3], 'ssl' => ['verify_peer' => false, 'verify_peer_name' => false] ]); $bin = @file_get_contents($url, false, $ctx); if ($bin !== false && strlen($bin) > 0) { @file_put_contents($tmp, $bin); } } return is_file($tmp) ? $tmp : null; } if (strpos($url, '/one-media/') === 0) { $absMedia = rtrim($this->get_media_root(), '/') . $url; if (is_file($absMedia)) { return $absMedia; } $httpHost = isset($_SERVER['HTTP_HOST']) ? trim((string)$_SERVER['HTTP_HOST']) : ''; if ($httpHost === '') { $httpHost = '10.9.20.31'; } return $this->resolve_signature_path('http://' . $httpHost . $url); } if (strpos($url, '/') === 0) { $abs = FCPATH . ltrim($url, '/'); if (is_file($abs)) { return $abs; } } $abs2 = FCPATH . 'assets/uploads/signature/' . ltrim($url, '/'); if (is_file($abs2)) { return $abs2; } return is_file($url) ? $url : null; } private function get_media_root() { if ($this->mediaRoot !== null) { return $this->mediaRoot; } $defaultRoot = '/home/one/project/one/'; $sql = "SELECT S_SystemsMediaUrl FROM conf_systems WHERE S_SystemsID > 0 LIMIT 1"; $qry = $this->db_onedev->query($sql); if ($qry && $qry->row()) { $root = trim((string)$qry->row()->S_SystemsMediaUrl); if ($root !== '') { $this->mediaRoot = rtrim($root, '/') . '/'; return $this->mediaRoot; } } $this->mediaRoot = $defaultRoot; return $this->mediaRoot; } }