Files
BE_IBL/application/controllers/tools/Inform_consent_cpmi.php
2026-05-24 10:06:07 +07:00

396 lines
14 KiB
PHP

<?php
class Inform_consent_cpmi extends MY_Controller
{
private $mediaRoot = null;
public function __construct()
{
parent::__construct();
$this->db_onedev = $this->load->database('onedev', true);
}
public function index()
{
$this->sys_ok([
'message' => 'Use /tools/inform_consent_cpmi/pdf?T_OrderHeaderID=<id>'
]);
}
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('/<br\s*\/?>/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], '<strong') !== false || preg_match('/^[IVX]+\./i', $plain))) {
$style = 'B';
}
$blocks[] = [
'text' => $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;
}
}