fix update report prd

This commit is contained in:
Hanan Askarim
2026-07-15 11:35:26 +07:00
parent a2f3509d78
commit c0cfc3ea88

View File

@@ -3,9 +3,53 @@ defined('BASEPATH') or exit('No direct script access allowed');
require_once(APPPATH . 'libraries/fpdf/fpdf.php'); 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 class Rpt_pr_direct extends MY_Controller
{ {
// ── Properti bersama antar fungsi PDF ───────────────────────────────────── // ── Properti bersama antar fungsi PDF ─────────────────────────────────────
/** @var PrdFpdf */
private $_pdf; private $_pdf;
private $_pageW; private $_pageW;
private $_header_data; private $_header_data;
@@ -40,21 +84,23 @@ class Rpt_pr_direct extends MY_Controller
$header = $this->_get_header($id); $header = $this->_get_header($id);
$details = $this->_get_detail($id); $details = $this->_get_detail($id);
// ── Inisialisasi FPDF ───────────────────────────────────────────── // ── Inisialisasi FPDF custom ──────────────────────────────────────
$this->_pdf = new FPDF('P', 'mm', 'A4'); $this->_pdf = new PrdFpdf('P', 'mm', 'A4');
$this->_pageW = $this->_pdf->GetPageWidth() - 30; // margin kiri+kanan 15+15 $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->_header_data = $header;
$this->_username = $username !== '' ? $username : '-'; $this->_username = $this->_pdf->printUsername;
$this->_pdf->AliasNbPages(); // aktifkan alias total halaman
$this->_pdf->SetMargins(15, 15, 15); $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(); $this->_pdf->AddPage();
// ── Susun halaman PDF ───────────────────────────────────────────── // ── Susun isi halaman ─────────────────────────────────────────────
$this->_pdf_header(); $this->_pdf_header();
$this->_pdf_data($details); $this->_pdf_data($details);
$this->_pdf_terms(); $this->_pdf_terms();
$this->_pdf_footer();
// ── Output ──────────────────────────────────────────────────────── // ── Output ────────────────────────────────────────────────────────
$filename = 'PRD_' . str_replace('/', '-', $header['PurchaseRequestDirectNumber']) . '.pdf'; $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('Cache-Control: private, max-age=0, must-revalidate');
header('Pragma: public'); header('Pragma: public');
echo $this->_pdf->Output('S'); echo $this->_pdf->Output('S');
} catch (Exception $exc) { } catch (Exception $exc) {
$this->sys_error($exc->getMessage()); $this->sys_error($exc->getMessage());
} }
@@ -107,9 +152,11 @@ class Rpt_pr_direct extends MY_Controller
SELECT SELECT
prdd.*, prdd.*,
iu.ItemUnitName, iu.ItemUnitName,
iu.ItemUnitCode iu.ItemUnitCode,
pdc.PurchaseDirectCategoryName
FROM purchase_request_direct_detail prdd FROM purchase_request_direct_detail prdd
LEFT JOIN itemunit iu ON iu.ItemUnitID = prdd.PurchaseRequestDirectDetailItemUnitID LEFT JOIN itemunit iu ON iu.ItemUnitID = prdd.PurchaseRequestDirectDetailItemUnitID
LEFT JOIN purchase_direct_category pdc ON pdc.PurchaseDirectCategoryID = prdd.PurchaseRequestDirectDetailPurchaseRequestDirectCategoryID
WHERE prdd.PurchaseRequestDirectDetailPurchaseRequestDirectID = ? WHERE prdd.PurchaseRequestDirectDetailPurchaseRequestDirectID = ?
AND prdd.PurchaseRequestDirectDetailIsActive = 'Y' AND prdd.PurchaseRequestDirectDetailIsActive = 'Y'
ORDER BY prdd.PurchaseRequestDirectDetailID ASC ORDER BY prdd.PurchaseRequestDirectDetailID ASC
@@ -119,7 +166,7 @@ class Rpt_pr_direct extends MY_Controller
} }
// ========================================================================= // =========================================================================
// PDF SECTION: Header — Judul + Informasi Dokumen (2 kolom, mirip referensi) // PDF SECTION: Header — Judul + Informasi Dokumen (2 kolom)
// ========================================================================= // =========================================================================
private function _pdf_header() private function _pdf_header()
{ {
@@ -128,7 +175,7 @@ class Rpt_pr_direct extends MY_Controller
$header = $this->_header_data; $header = $this->_header_data;
// ── Judul utama ─────────────────────────────────────────────────────── // ── 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->Cell($pageW, 8, 'PURCHASE REQUEST DIRECT (PRD)', 0, 1, 'L');
$pdf->SetDrawColor(0, 0, 0); $pdf->SetDrawColor(0, 0, 0);
$pdf->SetLineWidth(0.5); $pdf->SetLineWidth(0.5);
@@ -136,15 +183,14 @@ class Rpt_pr_direct extends MY_Controller
$pdf->Ln(2); $pdf->Ln(2);
// ── Info dokumen: 2 kolom (kiri & kanan) ───────────────────────────── // ── Info dokumen: 2 kolom (kiri & kanan) ─────────────────────────────
$pdf->SetFont('Arial', '', 9);
$half = $pageW / 2; $half = $pageW / 2;
$lbl = 30; // lebar label $lbl = 30;
$val = $half - $lbl - 4; $val = $half - $lbl - 4;
$left = array( $left = array(
array('Nomor', $header['PurchaseRequestDirectNumber']), array('Nomor', $header['PurchaseRequestDirectNumber']),
array('Tanggal', $this->_fmt_date($header['PurchaseRequestDirectDate'])), 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']), array('Status', $header['PurchaseRequestDirectStatus']),
); );
$right = array( $right = array(
@@ -157,39 +203,41 @@ class Rpt_pr_direct extends MY_Controller
for ($i = 0; $i < $maxRow; $i++) { for ($i = 0; $i < $maxRow; $i++) {
// kolom kiri // kolom kiri
if (isset($left[$i])) { 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($lbl, 5, $left[$i][0], 0, 0, 'L');
$pdf->Cell(4, 5, ':', 0, 0, 'C'); $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'); $pdf->Cell($val, 5, $left[$i][1], 0, 0, 'L');
} else { } else {
$pdf->Cell($half, 5, '', 0, 0); $pdf->Cell($half, 5, '', 0, 0);
} }
// kolom kanan // kolom kanan
if (isset($right[$i])) { 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($lbl, 5, $right[$i][0], 0, 0, 'L');
$pdf->Cell(4, 5, ':', 0, 0, 'C'); $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'); $pdf->Cell($val, 5, $right[$i][1], 0, 1, 'L');
} else { } else {
$pdf->Cell($half, 5, '', 0, 1); $pdf->Cell($half, 5, '', 0, 1);
} }
} }
// Keterangan & catatan (full width) // Keterangan & Catatan (full width)
if (!empty($header['PurchaseRequestDirectDescription'])) { if (!empty($header['PurchaseRequestDirectDescription'])) {
$pdf->SetFont('Arial', '', 9); $pdf->SetFont('Arial_Narrow', '', 9);
$pdf->Cell($lbl, 5, 'Keterangan', 0, 0, 'L'); $pdf->Cell($lbl, 5, 'Keterangan', 0, 0, 'L');
$pdf->Cell(4, 5, ':', 0, 0, 'C'); $pdf->Cell(4, 5, ':', 0, 0, 'C');
$pdf->SetFont('Arial', '', 9);
$pdf->Cell($pageW - $lbl - 4, 5, $header['PurchaseRequestDirectDescription'], 0, 1, 'L'); $pdf->Cell($pageW - $lbl - 4, 5, $header['PurchaseRequestDirectDescription'], 0, 1, 'L');
} }
if (!empty($header['PurchaseRequestDirectNote'])) { if (!empty($header['PurchaseRequestDirectNote'])) {
$pdf->SetFont('Arial', '', 9); $pdf->SetFont('Arial_Narrow', '', 9);
$pdf->Cell($lbl, 5, 'Catatan', 0, 0, 'L'); $pdf->Cell($lbl, 5, 'Catatan', 0, 0, 'L');
$pdf->Cell(4, 5, ':', 0, 0, 'C'); $pdf->Cell(4, 5, ':', 0, 0, 'C');
$pdf->SetFont('Arial', '', 9);
$pdf->Cell($pageW - $lbl - 4, 5, $header['PurchaseRequestDirectNote'], 0, 1, 'L'); $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] ───────────────────────────── // ── Definisi kolom: [label, lebar, align] ─────────────────────────────
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan) // 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( $cols = array(
array('No', 8, 'C'), array('No', 8, 'C'),
array('Nama / Uraian', 57, 'L'), array('Nama', 42, 'L'),
array('Satuan', 20, 'C'), array('Kategori', 25, 'L'),
array('Jml Request', 20, 'R'), array('Unit', 15, 'C'),
array('Jml Disetujui', 20, 'R'), array('Qty Request', 17, 'R'),
array('Harga Est.', 28, 'R'), array('Qty Disetujui', 18, 'R'),
array('Total Est.', 27, 'R'), array('Harga', 28, 'R'),
array('Total', 27, 'R'),
); );
// Header kolom // 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->SetFillColor(220, 220, 220);
$pdf->SetDrawColor(0, 0, 0); $pdf->SetDrawColor(0, 0, 0);
foreach ($cols as $c) { foreach ($cols as $c) {
@@ -228,7 +278,8 @@ class Rpt_pr_direct extends MY_Controller
$pdf->Ln(); $pdf->Ln();
// Baris data // 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); $pdf->SetFillColor(255, 255, 255);
$no = 1; $no = 1;
$total_est = 0; $total_est = 0;
@@ -236,11 +287,12 @@ class Rpt_pr_direct extends MY_Controller
foreach ($details as $d) { foreach ($details as $d) {
$pdf->Cell($cols[0][1], 6, $no, 1, 0, 'C'); $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[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[2][1], 6, $d['PurchaseDirectCategoryName'] ?: '-', 1, 0, 'L');
$pdf->Cell($cols[3][1], 6, $this->_fmt_num($d['PurchaseRequestDirectDetailAmountRequest']), 1, 0, 'R'); $pdf->Cell($cols[3][1], 6, $d['ItemUnitName'], 1, 0, 'C');
$pdf->Cell($cols[4][1], 6, $this->_fmt_num($d['PurchaseRequestDirectDetailAmount']), 1, 0, 'R'); $pdf->Cell($cols[4][1], 6, $this->_fmt_qty($d['PurchaseRequestDirectDetailAmountRequest']), 1, 0, 'R');
$pdf->Cell($cols[5][1], 6, $this->_fmt_rp($d['PurchaseRequestDirectDetailEstimationPrice']), 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['PurchaseRequestDirectDetailTotalEstimationPrice']), 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(); $pdf->Ln();
$total_est += floatval($d['PurchaseRequestDirectDetailTotalEstimationPrice']); $total_est += floatval($d['PurchaseRequestDirectDetailTotalEstimationPrice']);
@@ -248,14 +300,15 @@ class Rpt_pr_direct extends MY_Controller
} }
// Baris TOTAL // Baris TOTAL
$span = array_sum(array_column(array_slice($cols, 0, 6), 1)); $span = array_sum(array_column(array_slice($cols, 0, 7), 1));
$pdf->SetFont('Arial', 'B', 8); $pdf->SetLineWidth(0.3);
$pdf->SetFont('Arial_Narrow', 'B', 9); // bold + size 9 agar menonjol
$pdf->SetFillColor(220, 220, 220); $pdf->SetFillColor(220, 220, 220);
$pdf->Cell($span, 7, 'TOTAL', 1, 0, 'R', true); $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($cols[7][1], 7, $this->_fmt_rp($total_est), 1, 0, 'R', true);
$pdf->Ln(); $pdf->Ln();
// ── Ringkasan nilai (kanan bawah tabel) ────────────────────────────── // ── Ringkasan nilai (rata kanan) ──────────────────────────────────────
$pdf->Ln(4); $pdf->Ln(4);
$summary = array( $summary = array(
array('Total Estimasi', $this->_fmt_rp($header['PurchaseRequestDirectTotalEstimation'])), array('Total Estimasi', $this->_fmt_rp($header['PurchaseRequestDirectTotalEstimation'])),
@@ -270,9 +323,9 @@ class Rpt_pr_direct extends MY_Controller
foreach ($summary as $s) { foreach ($summary as $s) {
$pdf->SetX($offsetX); $pdf->SetX($offsetX);
$pdf->SetFont('Arial', '', 8); $pdf->SetFont('Arial_Narrow', '', 8);
$pdf->Cell($cW1, 5, $s[0], 0, 0, 'L'); $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'); $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.', '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->Cell($pageW, 5, 'Syarat & Ketentuan:', 0, 1, 'L');
$pdf->SetFont('Arial', '', 8); $pdf->SetFont('Arial_Narrow', '', 8);
$pdf->SetTextColor(0, 70, 180); // biru seperti referensi
foreach ($terms as $i => $t) { foreach ($terms as $i => $t) {
$pdf->Cell(6, 5, ($i + 1) . '.', 0, 0, 'R'); $pdf->Cell(6, 5, ($i + 1) . '.', 0, 0, 'R');
$pdf->Cell($pageW - 6, 5, $t, 0, 1, 'L'); $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, ',', '.'); 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) private function _fmt_rp($n)
{ {
return 'Rp ' . number_format(floatval($n), 2, ',', '.'); return 'Rp ' . number_format(floatval($n), 2, ',', '.');