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_pengeluaran_barang extends MY_Controller { // -- Properti bersama antar fungsi PDF ------------------------------------- /** @var RequestPengeluaranBarangFpdf */ private $_pdf; private $_pageW; private $_header_data; private $_username; public function __construct() { parent::__construct(); } public function index() { echo "Request Pengeluaran Barang Report API"; } // ========================================================================= // ENDPOINT: pdf // GET/POST: id (RequestItemOutID), 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 RequestPengeluaranBarangFpdf('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 = 'RIO_' . str_replace('/', '-', $header['RequestItemOutNumber']) . '.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 rio.*, wh.WarehouseCode, wh.WarehouseName, wh.WarehouseType, r.S_RegionalName, d.DivisionCode, d.DivisionName, b.M_BranchName AS BranchName, IFNULL(u.M_UserUsername, '') AS CreatedByName, IFNULL(um.M_UserUsername, '') AS ManagerByName, IFNULL(ua.M_UserUsername, '') AS ApprovedByName, IFNULL(uv.M_UserUsername, '') AS VerifiedByName FROM request_item_out rio LEFT JOIN warehouse wh ON wh.WarehouseID = rio.RequestItemOutWarehouseID AND wh.WarehouseIsActive = 'Y' LEFT JOIN s_regional r ON r.S_RegionalID = rio.RequestItemOutS_RegionalID AND r.S_RegionalIsActive = 'Y' LEFT JOIN m_branch b ON b.M_BranchCode = rio.RequestItemOutM_BranchCode AND b.M_BranchIsActive = 'Y' LEFT JOIN division d ON d.DivisionID = rio.RequestItemOutDivisionID AND d.DivisionIsActive = 'Y' LEFT JOIN m_user u ON u.M_UserID = rio.RequestItemOutUserID LEFT JOIN m_user um ON um.M_UserID = rio.RequestItemOutApprovedManagerUserID LEFT JOIN m_user ua ON ua.M_UserID = rio.RequestItemOutApprovedUserID LEFT JOIN m_user uv ON uv.M_UserID = rio.RequestItemOutVerifiedUserID WHERE rio.RequestItemOutID = ? AND rio.RequestItemOutIsActive = 'Y' LIMIT 1 "; $qry = $this->db->query($sql, array($id)); if (!$qry || $qry->num_rows() === 0) { $this->sys_error("Data Request Pengeluaran Barang tidak ditemukan"); exit; } return $qry->row_array(); } // ========================================================================= // DATABASE: Ambil data detail // ========================================================================= private function _get_detail($id) { $sql = " SELECT rod.*, i.M_ItemCode, i.M_ItemDesc, iu.ItemUnitName, iu.ItemUnitCode FROM request_item_out_detail rod LEFT JOIN m_item i ON i.M_ItemID = rod.RequestItemOutDetailM_ItemID LEFT JOIN itemunit iu ON iu.ItemUnitID = rod.RequestItemOutDetailItemUnitID WHERE rod.RequestItemOutDetailRequestItemOutID = ? AND rod.RequestItemOutDetailIsActive = 'Y' ORDER BY rod.RequestItemOutDetailID 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 PENGELUARAN BARANG', 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 = 32; $valW = $halfW - $lblW - 4; // -- Kolom Kiri ----------------------------------------------------------- $pdf->SetY($startY); $leftItems = array( array('Nomor Request', $header['RequestItemOutNumber'], true), array('Tanggal', $this->_fmt_date($header['RequestItemOutDate']), false), array('Status', $header['RequestItemOutStatus'], false), array('Divisi', $header['DivisionName'] ?: '-', false), array('Gudang', $header['WarehouseName'] ?: '-', false), array('Regional', $header['S_RegionalName'] ?: '-', 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) if (!empty($header['RequestItemOutNote'])) { $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['RequestItemOutNote'], 0, 'L'); } $leftY = $pdf->GetY(); // -- Kolom Kanan ---------------------------------------------------------- $pdf->SetY($startY); $rightX = 15 + $halfW; $rightItems = array( array('Cabang', $header['BranchName'] ?: '-'), array('Dibuat Oleh', $header['CreatedByName'] ?: '-'), array('Dibuat Tgl', $this->_fmt_datetime($header['RequestItemOutCreated'])), array('Approve Manager', $header['ManagerByName'] ?: '-'), array('Tgl Appr. Manager',$header['RequestItemOutApprovedManagerDate'] ? $this->_fmt_datetime($header['RequestItemOutApprovedManagerDate']) : '-'), array('Disetujui Oleh', $header['ApprovedByName'] ?: '-'), array('Tgl Disetujui', $header['RequestItemOutApprovedDate'] ? $this->_fmt_datetime($header['RequestItemOutApprovedDate']) : '-'), ); 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'); } // Verifikasi (hanya tampil jika ada) if (!empty($header['RequestItemOutVerifiedDate'])) { $pdf->SetX($rightX); $pdf->SetFont('Arial_Narrow', '', 9); $pdf->Cell($lblW, 5, 'Diverifikasi Oleh', 0, 0, 'L'); $pdf->Cell(4, 5, ':', 0, 0, 'C'); $pdf->SetFont('Arial_Narrow', '', 9); $pdf->Cell($valW, 5, $header['VerifiedByName'] ?: '-', 0, 1, 'L'); $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['RequestItemOutVerifiedDate']), 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 // ========================================================================= private function _pdf_data($details) { $pdf = $this->_pdf; $pageW = $this->_pageW; // -- Definisi kolom: [label, lebar, align] ------------------------------- // Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan) // 8 + 72 + 20 + 25 + 25 + 30 = 180 $cols = array( array('No', 8, 'C'), array('Nama Item', 72, 'L'), array('Unit', 20, 'C'), array('Qty Request', 25, 'R'), array('Qty Diterima', 25, 'R'), array('Status', 30, 'C'), ); // 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_qty = 0; $total_recv = 0; foreach ($details as $d) { $qty = floatval($d['RequestItemOutDetailQty'] ?? 0); $recvQty = floatval($d['RequestItemOutDetailReceiveQty'] ?? 0); $status = $d['RequestItemOutDetailStatus'] ?? '-'; $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($qty), 1, 0, 'R'); $pdf->Cell($cols[4][1], 6, $this->_fmt_qty($recvQty), 1, 0, 'R'); $pdf->Cell($cols[5][1], 6, $status, 1, 0, 'C'); $pdf->Ln(); $total_qty += $qty; $total_recv += $recvQty; $no++; } // Baris TOTAL $span = array_sum(array_column(array_slice($cols, 0, 3), 1)); $pdf->SetLineWidth(0.3); $pdf->SetFont('Arial_Narrow', 'B', 8); $pdf->SetFillColor(220, 220, 220); $pdf->Cell($span, 7, 'TOTAL', 1, 0, 'R', true); $pdf->Cell($cols[3][1], 7, $this->_fmt_qty($total_qty), 1, 0, 'R', true); $pdf->Cell($cols[4][1], 7, $this->_fmt_qty($total_recv), 1, 0, 'R', true); $pdf->Cell($cols[5][1], 7, '', 1, 0, 'C', true); $pdf->Ln(); $pdf->Ln(4); } // ========================================================================= // PDF SECTION: Syarat & Ketentuan // ========================================================================= private function _pdf_terms() { $pdf = $this->_pdf; $pageW = $this->_pageW; $terms = array( 'Request ini harus disetujui oleh atasan (manager) sebelum diproses lebih lanjut.', 'Barang yang diminta akan dikeluarkan sesuai dengan jumlah yang telah disetujui.', 'Apabila jumlah barang tidak tersedia, maka akan dilakukan pengeluaran sebagian (partial).', 'Dokumen ini bersifat internal dan hanya digunakan untuk keperluan administrasi perusahaan.', ); $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, ',', '.'); } }