AddFont('Arial_Narrow', '', 'Arial_Narrow.php'); // regular $this->AddFont('Arial_Narrow', 'B', 'Arial_Narrow_B.php'); // bold } public function Footer() { $pageW = $this->GetPageWidth() - 30; // margin 15+15 // ── Posisi: 20mm dari bawah halaman ────────────────────────────────── $this->SetY(-20); // ── Baris 1: Print Oleh (kiri) | Nomor Halaman (tengah) ─────────────── $colSide = ($pageW - 40) / 2; $colCenter = 40; $this->SetFont('Arial_Narrow', '', 7); $this->Cell($colSide, 4, 'Print Oleh : ' . $this->printUsername, 0, 0, 'L'); $this->Cell($colCenter, 4, $this->PageNo() . ' / {nb}', 0, 0, 'C'); $this->Cell($colSide, 4, '', 0, 1, 'R'); // ── Baris 2: Tgl Print (kiri) ────────────────────────────────────────── $this->SetFont('Arial_Narrow', '', 7); $this->Cell($colSide, 4, 'Tgl Print : ' . $this->printDate, 0, 0, 'L'); $this->Cell($colCenter + $colSide, 4, '', 0, 1, 'L'); } } // ============================================================================= // Controller // ============================================================================= class Rpt_request_mutasi extends MY_Controller { // ── Properti bersama antar fungsi PDF ───────────────────────────────────── /** @var RequestMutasiFpdf */ private $_pdf; private $_pageW; private $_header_data; private $_username; public function __construct() { parent::__construct(); } public function index() { echo "Request Mutasi Report API"; } // ========================================================================= // ENDPOINT: pdf // GET/POST: id (MutasiRequestID), username (opsional) // ========================================================================= public function pdf() { try { $id = intval($this->input->get_post('id')); $username = trim($this->input->get_post('username') ?? ''); if ($id <= 0) { $this->sys_error("ID tidak valid"); exit; } // ── Ambil data header & detail dari DB ──────────────────────────── $header = $this->_get_header($id); $details = $this->_get_detail($id); // ── Inisialisasi FPDF custom ────────────────────────────────────── $this->_pdf = new RequestMutasiFpdf('P', 'mm', 'A4'); $this->_pdf->printUsername = $username !== '' ? $username : '-'; $this->_pdf->printDate = date('d-m-Y H:i:s'); $this->_pageW = $this->_pdf->GetPageWidth() - 30; $this->_header_data = $header; $this->_username = $this->_pdf->printUsername; $this->_pdf->AliasNbPages(); // aktifkan alias total halaman $this->_pdf->SetMargins(15, 15, 15); $this->_pdf->SetAutoPageBreak(true, 22); // 22mm ruang footer di bawah $this->_pdf->AddPage(); // ── Susun isi halaman ───────────────────────────────────────────── $this->_pdf_header(); $this->_pdf_data($details); $this->_pdf_terms(); // ── Output ──────────────────────────────────────────────────────── $filename = 'RM_' . str_replace('/', '-', $header['MutasiRequestNumber']) . '.pdf'; header('Content-Type: application/pdf'); header('Content-Disposition: inline; filename="' . $filename . '"'); header('Cache-Control: private, max-age=0, must-revalidate'); header('Pragma: public'); echo $this->_pdf->Output('S'); } catch (Exception $exc) { $this->sys_error($exc->getMessage()); } } // ========================================================================= // DATABASE: Ambil data header // ========================================================================= private function _get_header($id) { $sql = " SELECT mr.*, ic.itemCategoryID, ic.itemCategoryName, a.M_BranchID AS branch_asal_id, a.M_BranchCode AS branch_asal_code, a.M_BranchName AS branch_asal_name, b.M_BranchID AS branch_tujuan_id, b.M_BranchCode AS branch_tujuan_code, b.M_BranchName AS branch_tujuan_name, IFNULL(u.M_UserUsername, '') AS CreatedByName, IFNULL(uv.M_UserUsername, '') AS VerifByName, IFNULL(ua.M_UserUsername, '') AS ApprovedByName FROM mutasi_request mr JOIN item_category ic ON ic.itemCategoryID = mr.MutasiRequestItemCategoryID JOIN m_branch a ON a.M_BranchID = mr.MutasiRequestFromBranchID JOIN m_branch b ON b.M_BranchID = mr.MutasiRequestToBranchID LEFT JOIN m_user u ON u.M_UserID = mr.MutasiRequestUserID LEFT JOIN m_user uv ON uv.M_UserID = mr.MutasiRequestVerifUserID LEFT JOIN m_user ua ON ua.M_UserID = mr.MutasiRequestApprovedUserID WHERE mr.MutasiRequestID = ? LIMIT 1 "; $qry = $this->db->query($sql, array($id)); if (!$qry || $qry->num_rows() === 0) { $this->sys_error("Data Request Mutasi tidak ditemukan"); exit; } return $qry->row_array(); } // ========================================================================= // DATABASE: Ambil data detail // ========================================================================= private function _get_detail($id) { $sql = " SELECT mrd.*, i.M_ItemCode, i.M_ItemDesc, iu.ItemUnitName, iu.ItemUnitCode FROM mutasi_request_detail mrd LEFT JOIN m_item i ON i.M_ItemID = mrd.MutasiRequestDetailM_ItemID LEFT JOIN itemunit iu ON iu.ItemUnitID = mrd.MutasiRequestDetailItemUnitID WHERE mrd.MutasiRequestDetailMutasiRequestID = ? AND mrd.MutasiRequestDetailIsActive = 'Y' ORDER BY mrd.MutasiRequestDetailID ASC "; $qry = $this->db->query($sql, array($id)); return $qry ? $qry->result_array() : array(); } // ========================================================================= // PDF SECTION: Header — Judul + Informasi Dokumen (2 kolom) // ========================================================================= private function _pdf_header() { $pdf = $this->_pdf; $pageW = $this->_pageW; $header = $this->_header_data; // ── Judul utama ─────────────────────────────────────────────────────── $pdf->SetFont('Arial_Narrow', 'B', 14); $pdf->Cell($pageW, 8, 'REQUEST MUTASI REPORT (RM)', 0, 1, 'L'); $pdf->SetDrawColor(0, 0, 0); $pdf->SetLineWidth(0.5); $pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY()); $pdf->Ln(2); $startY = $pdf->GetY(); $halfW = $pageW / 2; $lblW = 30; $valW = $halfW - $lblW - 4; // ── Kolom Kiri ──────────────────────────────────────────────────────── $pdf->SetY($startY); $leftItems = array( array('Nomor', $header['MutasiRequestNumber'], true), array('Tanggal', $this->_fmt_date($header['MutasiRequestDate']), false), array('Status', $header['MutasiRequestStatus'], false), array('Kategori', $header['itemCategoryName'], false), ); foreach ($leftItems as $item) { $pdf->SetX(15); $pdf->SetFont('Arial_Narrow', '', 9); $pdf->Cell($lblW, 5, $item[0], 0, 0, 'L'); $pdf->Cell(4, 5, ':', 0, 0, 'C'); if ($item[2]) { $pdf->SetFont('Arial_Narrow', 'B', 9); } else { $pdf->SetFont('Arial_Narrow', '', 9); } $pdf->Cell($valW, 5, $item[1], 0, 1, 'L'); } // Keterangan (Note) langsung di bawah Status if (!empty($header['MutasiRequestNote'])) { $pdf->SetX(15); $pdf->SetFont('Arial_Narrow', '', 9); $pdf->Cell($lblW, 5, 'Keterangan', 0, 0, 'L'); $pdf->Cell(4, 5, ':', 0, 0, 'C'); $pdf->MultiCell($valW, 5, $header['MutasiRequestNote'], 0, 'L'); } $leftY = $pdf->GetY(); // ── Kolom Kanan ─────────────────────────────────────────────────────── $pdf->SetY($startY); $rightX = 15 + $halfW; $rightItems = array( array('Cabang Asal', $header['branch_asal_name']), array('Cabang Tujuan', $header['branch_tujuan_name']), array('Dibuat Oleh', $header['CreatedByName']), array('Diverifikasi Oleh', $header['VerifByName'] ?: '-'), array('Disetujui Oleh', $header['ApprovedByName'] ?: '-'), ); foreach ($rightItems as $item) { $pdf->SetX($rightX); $pdf->SetFont('Arial_Narrow', '', 9); $pdf->Cell($lblW, 5, $item[0], 0, 0, 'L'); $pdf->Cell(4, 5, ':', 0, 0, 'C'); $pdf->SetFont('Arial_Narrow', '', 9); $pdf->Cell($valW, 5, $item[1], 0, 1, 'L'); } // Tanggal approvals di kolom kanan $pdf->SetX($rightX); $pdf->SetFont('Arial_Narrow', '', 9); $pdf->Cell($lblW, 5, 'Tgl Verifikasi', 0, 0, 'L'); $pdf->Cell(4, 5, ':', 0, 0, 'C'); $pdf->SetFont('Arial_Narrow', '', 9); $pdf->Cell($valW, 5, $this->_fmt_datetime($header['MutasiRequestVerifDate']), 0, 1, 'L'); $pdf->SetX($rightX); $pdf->SetFont('Arial_Narrow', '', 9); $pdf->Cell($lblW, 5, 'Tgl Approved', 0, 0, 'L'); $pdf->Cell(4, 5, ':', 0, 0, 'C'); $pdf->SetFont('Arial_Narrow', '', 9); $pdf->Cell($valW, 5, $this->_fmt_datetime($header['MutasiRequestApprovedDate']), 0, 1, 'L'); $rightY = $pdf->GetY(); // Posisikan Y ke yang paling bawah + margin $pdf->SetY(max($leftY, $rightY) + 4); } // ========================================================================= // PDF SECTION: Data — Tabel detail item + ringkasan nilai // ========================================================================= private function _pdf_data($details) { $pdf = $this->_pdf; $pageW = $this->_pageW; $header = $this->_header_data; // ── Definisi kolom: [label, lebar, align] ───────────────────────────── // Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan) // 8 + 80 + 20 + 20 + 25 + 27 = 180 $cols = array( array('No', 8, 'C'), array('Nama Item', 80, 'L'), array('Unit', 20, 'C'), array('Qty', 20, 'R'), array('Nilai Buku', 25, 'R'), array('Total', 27, 'R'), ); // Header kolom $pdf->SetLineWidth(0.3); $pdf->SetFont('Arial_Narrow', 'B', 8); $pdf->SetFillColor(220, 220, 220); $pdf->SetDrawColor(0, 0, 0); foreach ($cols as $c) { $pdf->Cell($c[1], 7, $c[0], 1, 0, 'C', true); } $pdf->Ln(); // Baris data $pdf->SetLineWidth(0.2); $pdf->SetFont('Arial_Narrow', '', 8); $pdf->SetFillColor(255, 255, 255); $no = 1; $total_val = 0; foreach ($details as $d) { $pdf->Cell($cols[0][1], 6, $no, 1, 0, 'C'); $pdf->Cell($cols[1][1], 6, $d['M_ItemDesc'] ?: ($d['M_ItemCode'] ?: '-'), 1, 0, 'L'); $pdf->Cell($cols[2][1], 6, $d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'), 1, 0, 'C'); $pdf->Cell($cols[3][1], 6, $this->_fmt_qty($d['MutasiRequestDetailQty']), 1, 0, 'R'); $bookValue = floatval($d['MutasiRequestDetailBookValue'] ?? 0); $pdf->Cell($cols[4][1], 6, $this->_fmt_rp($bookValue), 1, 0, 'R'); $pdf->Cell($cols[5][1], 6, $this->_fmt_rp($d['MutasiRequestDetailQty'] * $bookValue), 1, 0, 'R'); $pdf->Ln(); $total_val += floatval($d['MutasiRequestDetailQty'] * $bookValue); $no++; } // Baris TOTAL $span = array_sum(array_column(array_slice($cols, 0, 5), 1)); $pdf->SetLineWidth(0.3); $pdf->SetFont('Arial_Narrow', 'B', 9); $pdf->SetFillColor(220, 220, 220); $pdf->Cell($span, 7, 'TOTAL', 1, 0, 'R', true); $pdf->Cell($cols[5][1], 7, $this->_fmt_rp($total_val), 1, 0, 'R', true); $pdf->Ln(); $pdf->Ln(4); } // ========================================================================= // PDF SECTION: Syarat & Ketentuan // ========================================================================= private function _pdf_terms() { $pdf = $this->_pdf; $pageW = $this->_pageW; $terms = array( 'Mutasi barang ini harus mendapatkan persetujuan dari pejabat berwenang sebelum proses mutasi dilakukan.', 'Barang yang dimutasi harus sesuai dengan spesifikasi dan jumlah yang tercantum dalam dokumen ini.', 'Proses mutasi dilakukan setelah barang diverifikasi dan disetujui oleh pihak terkait.', 'Dokumen ini bersifat internal dan hanya digunakan untuk keperluan proses mutasi barang.', ); $pdf->SetFont('Arial_Narrow', 'B', 9); $pdf->Cell($pageW, 5, 'Syarat & Ketentuan:', 0, 1, 'L'); $pdf->SetFont('Arial_Narrow', '', 8); foreach ($terms as $i => $t) { $pdf->Cell(6, 5, ($i + 1) . '.', 0, 0, 'R'); $pdf->Cell($pageW - 6, 5, $t, 0, 1, 'L'); } } // ========================================================================= // HELPER: Format tampilan // ========================================================================= private function _fmt_date($d) { if (!$d || $d === '0000-00-00') return '-'; return date('d-m-Y', strtotime($d)); } private function _fmt_datetime($d) { if (!$d || $d === '0000-00-00 00:00:00') return '-'; return date('d-m-Y H:i', strtotime($d)); } private function _fmt_num($n) { return number_format(floatval($n), 2, ',', '.'); } private function _fmt_qty($n) { return number_format(floatval($n), 0, ',', '.'); } private function _fmt_rp($n) { return 'Rp ' . number_format(floatval($n), 2, ',', '.'); } }