Files
be-accone/application/controllers/report/Rpt_pr_direct.php
2026-07-22 08:26:43 +07:00

377 lines
15 KiB
PHP

<?php
defined('BASEPATH') or exit('No direct script access allowed');
require_once(APPPATH . 'libraries/fpdf/fpdf.php');
class Rpt_pr_direct extends MY_Controller
{
// ── Properti bersama antar fungsi PDF ─────────────────────────────────────
private $_pdf;
private $_pageW;
private $_header_data;
private $_username;
public function __construct()
{
parent::__construct();
}
public function index()
{
echo "Purchase Request Direct Report API";
}
// =========================================================================
// ENDPOINT: pdf
// GET/POST: id (PurchaseRequestDirectID), 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 ─────────────────────────────────────────────
$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 : '-';
$this->_pdf->SetMargins(15, 15, 15);
$this->_pdf->SetAutoPageBreak(true, 30); // beri ruang footer
$this->_pdf->AddPage();
// ── Susun halaman PDF ─────────────────────────────────────────────
$this->_pdf_header();
$this->_pdf_data($details);
$this->_pdf_terms();
$this->_pdf_footer();
// ── Output ────────────────────────────────────────────────────────
$filename = 'PRD_' . str_replace('/', '-', $header['PurchaseRequestDirectNumber']) . '.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
prd.*,
b.M_BranchName,
b.M_BranchAddress,
r.S_RegionalName,
IFNULL(u.M_UserUsername,'') AS CreatedByName,
IFNULL(ua.M_UserUsername,'') AS ApprovedByName
FROM purchase_request_direct prd
LEFT JOIN m_branch b ON b.M_BranchCode = prd.PurchaseRequestDirectM_BranchCode
LEFT JOIN s_regional r ON r.S_RegionalID = prd.PurchaseRequestDirectS_RegionalID
LEFT JOIN m_user u ON u.M_UserID = prd.PurchaseRequestCreatedUserID
LEFT JOIN m_user ua ON ua.M_UserID = prd.PurchaseRequestDirectApprovedBy
WHERE prd.PurchaseRequestDirectID = ?
LIMIT 1
";
$qry = $this->db->query($sql, array($id));
if (!$qry || $qry->num_rows() === 0) {
$this->sys_error("Data Purchase Request Direct tidak ditemukan");
exit;
}
return $qry->row_array();
}
// =========================================================================
// DATABASE: Ambil data detail
// =========================================================================
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
";
$qry = $this->db->query($sql, array($id));
return $qry ? $qry->result_array() : array();
}
// =========================================================================
// PDF SECTION: Header — Judul + Informasi Dokumen (2 kolom, mirip referensi)
// =========================================================================
private function _pdf_header()
{
$pdf = $this->_pdf;
$pageW = $this->_pageW;
$header = $this->_header_data;
// ── Judul utama ───────────────────────────────────────────────────────
$pdf->SetFont('Arial', 'B', 14);
$pdf->Cell($pageW, 8, 'PURCHASE REQUEST DIRECT (PRD)', 0, 1, 'L');
$pdf->SetDrawColor(0, 0, 0);
$pdf->SetLineWidth(0.5);
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
$pdf->Ln(2);
// ── Info dokumen: 2 kolom (kiri & kanan) ─────────────────────────────
$pdf->SetFont('Arial', '', 9);
$half = $pageW / 2;
$lbl = 30; // lebar label
$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('Status', $header['PurchaseRequestDirectStatus']),
);
$right = array(
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->Cell($lbl, 5, $left[$i][0], 0, 0, 'L');
$pdf->Cell(4, 5, ':', 0, 0, 'C');
$pdf->SetFont('Arial', 'B', 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->Cell($lbl, 5, $right[$i][0], 0, 0, 'L');
$pdf->Cell(4, 5, ':', 0, 0, 'C');
$pdf->SetFont('Arial', 'B', 9);
$pdf->Cell($val, 5, $right[$i][1], 0, 1, 'L');
} else {
$pdf->Cell($half, 5, '', 0, 1);
}
}
// Keterangan & catatan (full width)
if (!empty($header['PurchaseRequestDirectDescription'])) {
$pdf->SetFont('Arial', '', 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->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');
}
$pdf->Ln(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 + 57 + 20 + 20 + 20 + 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'),
);
// Header kolom
$pdf->SetFont('Arial', '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->SetFont('Arial', '', 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->Ln();
$total_est += floatval($d['PurchaseRequestDirectDetailTotalEstimationPrice']);
$no++;
}
// Baris TOTAL
$span = array_sum(array_column(array_slice($cols, 0, 6), 1));
$pdf->SetFont('Arial', 'B', 8);
$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->Ln();
// ── Ringkasan nilai (kanan bawah tabel) ──────────────────────────────
$pdf->Ln(4);
$summary = array(
array('Total Estimasi', $this->_fmt_rp($header['PurchaseRequestDirectTotalEstimation'])),
array('Adjustment', $this->_fmt_rp($header['PurchaseRequestDirectAdjustment'])),
array('Total Realisasi', $this->_fmt_rp($header['PurchaseRequestDirectTotalRealitation'])),
array('Total Pembayaran', $this->_fmt_rp($header['PurchaseRequestDirectTotalPaid'])),
);
$cW1 = 50;
$cW2 = 40;
$offsetX = 15 + $pageW - $cW1 - $cW2;
foreach ($summary as $s) {
$pdf->SetX($offsetX);
$pdf->SetFont('Arial', '', 8);
$pdf->Cell($cW1, 5, $s[0], 0, 0, 'L');
$pdf->SetFont('Arial', 'B', 8);
$pdf->Cell($cW2, 5, $s[1], 0, 1, 'R');
}
$pdf->Ln(4);
}
// =========================================================================
// PDF SECTION: Syarat & Ketentuan
// =========================================================================
private function _pdf_terms()
{
$pdf = $this->_pdf;
$pageW = $this->_pageW;
$terms = array(
'Pengajuan pembelian ini harus mendapatkan persetujuan dari pejabat berwenang sebelum proses pembelian dilakukan.',
'Barang/jasa yang dibeli harus sesuai dengan spesifikasi dan kebutuhan yang tercantum dalam dokumen ini.',
'Pembayaran dilakukan setelah barang/jasa diterima dan diverifikasi sesuai pesanan.',
'Dokumen ini bersifat internal dan hanya digunakan untuk keperluan proses pengadaan.',
);
$pdf->SetFont('Arial', 'B', 9);
$pdf->Cell($pageW, 5, 'Syarat & Ketentuan:', 0, 1, 'L');
$pdf->SetFont('Arial', '', 8);
$pdf->SetTextColor(0, 70, 180); // biru seperti referensi
foreach ($terms as $i => $t) {
$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();
}
// =========================================================================
// 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_rp($n)
{
return 'Rp ' . number_format(floatval($n), 2, ',', '.');
}
}