From 411d7e021944ed844e090d7efa31b82db009d506 Mon Sep 17 00:00:00 2001 From: Hanan Askarim Date: Wed, 15 Jul 2026 11:35:26 +0700 Subject: [PATCH] fix update report prd --- .../controllers/report/Rpt_pr_direct.php | 238 +++++++++--------- 1 file changed, 126 insertions(+), 112 deletions(-) diff --git a/application/controllers/report/Rpt_pr_direct.php b/application/controllers/report/Rpt_pr_direct.php index 2d6556e..9cd2422 100644 --- a/application/controllers/report/Rpt_pr_direct.php +++ b/application/controllers/report/Rpt_pr_direct.php @@ -3,9 +3,53 @@ defined('BASEPATH') or exit('No direct script access allowed'); require_once(APPPATH . 'libraries/fpdf/fpdf.php'); +// ============================================================================= +// Custom FPDF: override Footer() agar tampil otomatis di SETIAP halaman +// Footer tidak bisa bergeser karena FPDF memanggil Footer() sebelum ganti hal. +// ============================================================================= +class PrdFpdf extends FPDF +{ + public $printUsername = '-'; + public $printDate = ''; + + public function __construct($orientation = 'P', $unit = 'mm', $size = 'A4') + { + parent::__construct($orientation, $unit, $size); + // Daftarkan Arial Narrow — file font ada di fpdf/font/Arial_Narrow.php + $this->AddFont('Arial_Narrow', '', 'Arial_Narrow.php'); // regular + $this->AddFont('Arial_Narrow', 'B', 'Arial_Narrow_B.php'); // bold (Liberation Sans Narrow Bold) + } + + public function Footer() + { + $pageW = $this->GetPageWidth() - 30; // sama dengan 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_pr_direct extends MY_Controller { // ── Properti bersama antar fungsi PDF ───────────────────────────────────── + /** @var PrdFpdf */ private $_pdf; private $_pageW; private $_header_data; @@ -40,21 +84,23 @@ class Rpt_pr_direct extends MY_Controller $header = $this->_get_header($id); $details = $this->_get_detail($id); - // ── Inisialisasi FPDF ───────────────────────────────────────────── - $this->_pdf = new FPDF('P', 'mm', 'A4'); - $this->_pageW = $this->_pdf->GetPageWidth() - 30; // margin kiri+kanan 15+15 - $this->_header_data = $header; - $this->_username = $username !== '' ? $username : '-'; + // ── Inisialisasi FPDF custom ────────────────────────────────────── + $this->_pdf = new PrdFpdf('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, 30); // beri ruang footer + $this->_pdf->SetAutoPageBreak(true, 22); // 22mm ruang footer di bawah $this->_pdf->AddPage(); - // ── Susun halaman PDF ───────────────────────────────────────────── + // ── Susun isi halaman ───────────────────────────────────────────── $this->_pdf_header(); $this->_pdf_data($details); $this->_pdf_terms(); - $this->_pdf_footer(); // ── Output ──────────────────────────────────────────────────────── $filename = 'PRD_' . str_replace('/', '-', $header['PurchaseRequestDirectNumber']) . '.pdf'; @@ -63,7 +109,6 @@ class Rpt_pr_direct extends MY_Controller 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()); } @@ -104,22 +149,24 @@ class Rpt_pr_direct extends MY_Controller private function _get_detail($id) { $sql = " - SELECT - prdd.*, - iu.ItemUnitName, - iu.ItemUnitCode - FROM purchase_request_direct_detail prdd - LEFT JOIN itemunit iu ON iu.ItemUnitID = prdd.PurchaseRequestDirectDetailItemUnitID - WHERE prdd.PurchaseRequestDirectDetailPurchaseRequestDirectID = ? - AND prdd.PurchaseRequestDirectDetailIsActive = 'Y' - ORDER BY prdd.PurchaseRequestDirectDetailID ASC - "; + SELECT + prdd.*, + iu.ItemUnitName, + iu.ItemUnitCode, + pdc.PurchaseDirectCategoryName + FROM purchase_request_direct_detail prdd + LEFT JOIN itemunit iu ON iu.ItemUnitID = prdd.PurchaseRequestDirectDetailItemUnitID + LEFT JOIN purchase_direct_category pdc ON pdc.PurchaseDirectCategoryID = prdd.PurchaseRequestDirectDetailPurchaseRequestDirectCategoryID + WHERE prdd.PurchaseRequestDirectDetailPurchaseRequestDirectID = ? + AND prdd.PurchaseRequestDirectDetailIsActive = 'Y' + ORDER BY prdd.PurchaseRequestDirectDetailID ASC + "; $qry = $this->db->query($sql, array($id)); return $qry ? $qry->result_array() : array(); } // ========================================================================= - // PDF SECTION: Header — Judul + Informasi Dokumen (2 kolom, mirip referensi) + // PDF SECTION: Header — Judul + Informasi Dokumen (2 kolom) // ========================================================================= private function _pdf_header() { @@ -128,7 +175,7 @@ class Rpt_pr_direct extends MY_Controller $header = $this->_header_data; // ── Judul utama ─────────────────────────────────────────────────────── - $pdf->SetFont('Arial', 'B', 14); + $pdf->SetFont('Arial_Narrow', 'B', 14); $pdf->Cell($pageW, 8, 'PURCHASE REQUEST DIRECT (PRD)', 0, 1, 'L'); $pdf->SetDrawColor(0, 0, 0); $pdf->SetLineWidth(0.5); @@ -136,60 +183,61 @@ class Rpt_pr_direct extends MY_Controller $pdf->Ln(2); // ── Info dokumen: 2 kolom (kiri & kanan) ───────────────────────────── - $pdf->SetFont('Arial', '', 9); - $half = $pageW / 2; - $lbl = 30; // lebar label - $val = $half - $lbl - 4; + $half = $pageW / 2; + $lbl = 30; + $val = $half - $lbl - 4; $left = array( array('Nomor', $header['PurchaseRequestDirectNumber']), array('Tanggal', $this->_fmt_date($header['PurchaseRequestDirectDate'])), - array('Tanggal Pakai', $this->_fmt_date($header['PurchaseRequestDirectDateUse'])), + array('Tanggal Pelaksanaan', $this->_fmt_date($header['PurchaseRequestDirectDateUse'])), array('Status', $header['PurchaseRequestDirectStatus']), ); $right = array( - array('Cabang', $header['M_BranchName']), - array('Regional', $header['S_RegionalName']), - array('Alamat', $header['M_BranchAddress']), + array('Cabang', $header['M_BranchName']), + array('Regional', $header['S_RegionalName']), + array('Alamat', $header['M_BranchAddress']), ); $maxRow = max(count($left), count($right)); for ($i = 0; $i < $maxRow; $i++) { // kolom kiri if (isset($left[$i])) { - $pdf->SetFont('Arial', '', 9); + $pdf->SetFont('Arial_Narrow', '', 9); $pdf->Cell($lbl, 5, $left[$i][0], 0, 0, 'L'); $pdf->Cell(4, 5, ':', 0, 0, 'C'); - $pdf->SetFont('Arial', 'B', 9); + if ($left[$i][0] === 'Nomor') { + $pdf->SetFont('Arial_Narrow', 'B', 9); + } else { + $pdf->SetFont('Arial_Narrow', '', 9); + } $pdf->Cell($val, 5, $left[$i][1], 0, 0, 'L'); } else { $pdf->Cell($half, 5, '', 0, 0); } // kolom kanan if (isset($right[$i])) { - $pdf->SetFont('Arial', '', 9); + $pdf->SetFont('Arial_Narrow', '', 9); $pdf->Cell($lbl, 5, $right[$i][0], 0, 0, 'L'); $pdf->Cell(4, 5, ':', 0, 0, 'C'); - $pdf->SetFont('Arial', 'B', 9); + $pdf->SetFont('Arial_Narrow', '', 9); $pdf->Cell($val, 5, $right[$i][1], 0, 1, 'L'); } else { $pdf->Cell($half, 5, '', 0, 1); } } - // Keterangan & catatan (full width) + // Keterangan & Catatan (full width) if (!empty($header['PurchaseRequestDirectDescription'])) { - $pdf->SetFont('Arial', '', 9); + $pdf->SetFont('Arial_Narrow', '', 9); $pdf->Cell($lbl, 5, 'Keterangan', 0, 0, 'L'); $pdf->Cell(4, 5, ':', 0, 0, 'C'); - $pdf->SetFont('Arial', '', 9); $pdf->Cell($pageW - $lbl - 4, 5, $header['PurchaseRequestDirectDescription'], 0, 1, 'L'); } if (!empty($header['PurchaseRequestDirectNote'])) { - $pdf->SetFont('Arial', '', 9); + $pdf->SetFont('Arial_Narrow', '', 9); $pdf->Cell($lbl, 5, 'Catatan', 0, 0, 'L'); $pdf->Cell(4, 5, ':', 0, 0, 'C'); - $pdf->SetFont('Arial', '', 9); $pdf->Cell($pageW - $lbl - 4, 5, $header['PurchaseRequestDirectNote'], 0, 1, 'L'); } @@ -207,19 +255,21 @@ class Rpt_pr_direct extends MY_Controller // ── Definisi kolom: [label, lebar, align] ───────────────────────────── // Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan) - // 8 + 57 + 20 + 20 + 20 + 28 + 27 = 180 + // 8 + 42 + 25 + 15 + 17 + 18 + 28 + 27 = 180 $cols = array( array('No', 8, 'C'), - array('Nama / Uraian', 57, 'L'), - array('Satuan', 20, 'C'), - array('Jml Request', 20, 'R'), - array('Jml Disetujui', 20, 'R'), - array('Harga Est.', 28, 'R'), - array('Total Est.', 27, 'R'), + array('Nama', 42, 'L'), + array('Kategori', 25, 'L'), + array('Unit', 15, 'C'), + array('Qty Request', 17, 'R'), + array('Qty Disetujui', 18, 'R'), + array('Harga', 28, 'R'), + array('Total', 27, 'R'), ); // Header kolom - $pdf->SetFont('Arial', 'B', 8); + $pdf->SetLineWidth(0.3); // border medium + $pdf->SetFont('Arial_Narrow', 'B', 8); $pdf->SetFillColor(220, 220, 220); $pdf->SetDrawColor(0, 0, 0); foreach ($cols as $c) { @@ -228,19 +278,21 @@ class Rpt_pr_direct extends MY_Controller $pdf->Ln(); // Baris data - $pdf->SetFont('Arial', '', 8); + $pdf->SetLineWidth(0.2); // border lebih tipis di data + $pdf->SetFont('Arial_Narrow', '', 8); $pdf->SetFillColor(255, 255, 255); $no = 1; $total_est = 0; foreach ($details as $d) { - $pdf->Cell($cols[0][1], 6, $no, 1, 0, 'C'); - $pdf->Cell($cols[1][1], 6, $d['PurchaseRequestDirectDescription'] ?: $d['ItemUnitName'], 1, 0, 'L'); - $pdf->Cell($cols[2][1], 6, $d['ItemUnitCode'] ?: $d['ItemUnitName'], 1, 0, 'C'); - $pdf->Cell($cols[3][1], 6, $this->_fmt_num($d['PurchaseRequestDirectDetailAmountRequest']), 1, 0, 'R'); - $pdf->Cell($cols[4][1], 6, $this->_fmt_num($d['PurchaseRequestDirectDetailAmount']), 1, 0, 'R'); - $pdf->Cell($cols[5][1], 6, $this->_fmt_rp($d['PurchaseRequestDirectDetailEstimationPrice']), 1, 0, 'R'); - $pdf->Cell($cols[6][1], 6, $this->_fmt_rp($d['PurchaseRequestDirectDetailTotalEstimationPrice']), 1, 0, 'R'); + $pdf->Cell($cols[0][1], 6, $no, 1, 0, 'C'); + $pdf->Cell($cols[1][1], 6, $d['PurchaseRequestDirectDescription'] ?: $d['ItemUnitName'], 1, 0, 'L'); + $pdf->Cell($cols[2][1], 6, $d['PurchaseDirectCategoryName'] ?: '-', 1, 0, 'L'); + $pdf->Cell($cols[3][1], 6, $d['ItemUnitName'], 1, 0, 'C'); + $pdf->Cell($cols[4][1], 6, $this->_fmt_qty($d['PurchaseRequestDirectDetailAmountRequest']), 1, 0, 'R'); + $pdf->Cell($cols[5][1], 6, $this->_fmt_qty($d['PurchaseRequestDirectDetailAmount']), 1, 0, 'R'); + $pdf->Cell($cols[6][1], 6, $this->_fmt_rp($d['PurchaseRequestDirectDetailEstimationPrice']), 1, 0, 'R'); + $pdf->Cell($cols[7][1], 6, $this->_fmt_rp($d['PurchaseRequestDirectDetailTotalEstimationPrice']), 1, 0, 'R'); $pdf->Ln(); $total_est += floatval($d['PurchaseRequestDirectDetailTotalEstimationPrice']); @@ -248,14 +300,15 @@ class Rpt_pr_direct extends MY_Controller } // Baris TOTAL - $span = array_sum(array_column(array_slice($cols, 0, 6), 1)); - $pdf->SetFont('Arial', 'B', 8); + $span = array_sum(array_column(array_slice($cols, 0, 7), 1)); + $pdf->SetLineWidth(0.3); + $pdf->SetFont('Arial_Narrow', 'B', 9); // bold + size 9 agar menonjol $pdf->SetFillColor(220, 220, 220); - $pdf->Cell($span, 7, 'TOTAL', 1, 0, 'R', true); - $pdf->Cell($cols[6][1], 7, $this->_fmt_rp($total_est), 1, 0, 'R', true); + $pdf->Cell($span, 7, 'TOTAL', 1, 0, 'R', true); + $pdf->Cell($cols[7][1], 7, $this->_fmt_rp($total_est), 1, 0, 'R', true); $pdf->Ln(); - // ── Ringkasan nilai (kanan bawah tabel) ────────────────────────────── + // ── Ringkasan nilai (rata kanan) ────────────────────────────────────── $pdf->Ln(4); $summary = array( array('Total Estimasi', $this->_fmt_rp($header['PurchaseRequestDirectTotalEstimation'])), @@ -264,15 +317,15 @@ class Rpt_pr_direct extends MY_Controller array('Total Pembayaran', $this->_fmt_rp($header['PurchaseRequestDirectTotalPaid'])), ); - $cW1 = 50; - $cW2 = 40; + $cW1 = 50; + $cW2 = 40; $offsetX = 15 + $pageW - $cW1 - $cW2; foreach ($summary as $s) { $pdf->SetX($offsetX); - $pdf->SetFont('Arial', '', 8); + $pdf->SetFont('Arial_Narrow', '', 8); $pdf->Cell($cW1, 5, $s[0], 0, 0, 'L'); - $pdf->SetFont('Arial', 'B', 8); + $pdf->SetFont('Arial_Narrow', 'B', 8); $pdf->Cell($cW2, 5, $s[1], 0, 1, 'R'); } @@ -294,59 +347,14 @@ class Rpt_pr_direct extends MY_Controller 'Dokumen ini bersifat internal dan hanya digunakan untuk keperluan proses pengadaan.', ); - $pdf->SetFont('Arial', 'B', 9); + $pdf->SetFont('Arial_Narrow', 'B', 9); $pdf->Cell($pageW, 5, 'Syarat & Ketentuan:', 0, 1, 'L'); - $pdf->SetFont('Arial', '', 8); - $pdf->SetTextColor(0, 70, 180); // biru seperti referensi + $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'); + $pdf->Cell(6, 5, ($i + 1) . '.', 0, 0, 'R'); + $pdf->Cell($pageW - 6, 5, $t, 0, 1, 'L'); } - $pdf->SetTextColor(0, 0, 0); // reset warna - } - - // ========================================================================= - // PDF SECTION: Footer — Print Oleh + Tgl Print + Nomor Halaman - // Dipanggil sekali, ditempatkan di pojok bawah halaman terakhir - // ========================================================================= - private function _pdf_footer() - { - $pdf = $this->_pdf; - $pageW = $this->_pageW; - $header = $this->_header_data; - $username = $this->_username; - - // ── Garis pemisah ───────────────────────────────────────────────────── - $pdf->SetY(-28); - $pdf->SetDrawColor(0, 0, 0); - $pdf->SetLineWidth(0.3); - $pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY()); - $pdf->Ln(1); - - // ── Kolom kiri: Print Oleh & Tgl Print ─────────────────────────────── - $pdf->SetFont('Arial', '', 8); - - $colInfo = $pageW / 2; - - // Print Oleh - $pdf->Cell(20, 4, 'Print Oleh', 0, 0, 'L'); - $pdf->Cell(3, 4, ':', 0, 0, 'C'); - $pdf->SetFont('Arial', 'B', 8); - $pdf->Cell($colInfo - 23, 4, $username, 0, 0, 'L'); - - // Nomor halaman (kanan) - $pdf->SetFont('Arial', '', 8); - $pdf->Cell($colInfo, 4, $pdf->PageNo() . ' / {nb}', 0, 1, 'R'); - - // Tgl Print - $pdf->SetFont('Arial', '', 8); - $pdf->Cell(20, 4, 'Tgl Print', 0, 0, 'L'); - $pdf->Cell(3, 4, ':', 0, 0, 'C'); - $pdf->Cell($colInfo - 23, 4, date('d-m-Y H:i:s'), 0, 1, 'L'); - - // Aktifkan alias {nb} agar jumlah halaman terbaca - $this->_pdf->AliasNbPages(); } // ========================================================================= @@ -369,6 +377,12 @@ class Rpt_pr_direct extends MY_Controller return number_format(floatval($n), 2, ',', '.'); } + // format jumlah/qty: tanpa desimal + private function _fmt_qty($n) + { + return number_format(floatval($n), 0, ',', '.'); + } + private function _fmt_rp($n) { return 'Rp ' . number_format(floatval($n), 2, ',', '.');