fix report fpdf

This commit is contained in:
Hanan Askarim
2026-07-17 15:39:07 +07:00
committed by sasadib
parent 2c349c4f6e
commit b5028c06dd
13 changed files with 1401 additions and 152 deletions

View File

@@ -40,6 +40,110 @@ class PaymentVoucherFpdf extends FPDF
$this->Cell($colSide, 4, 'Tgl Print : ' . $this->printDate, 0, 0, 'L');
$this->Cell($colCenter + $colSide, 4, '', 0, 1, 'L');
}
// Properties untuk tabel multiline
public $widths;
public $aligns;
public function SetWidths($w)
{
$this->widths = $w;
}
public function SetAligns($a)
{
$this->aligns = $a;
}
public function Row($data, $fill = false, $h = 6)
{
// Hitung tinggi maksimum baris berdasarkan multiline
$nb = 0;
for ($i = 0; $i < count($data); $i++) {
$nb = max($nb, $this->NbLines($this->widths[$i], $data[$i]));
}
$rowH = $h * $nb;
// Cek apakah perlu ganti halaman secara otomatis
$this->CheckPageBreak($rowH);
// Gambar cell pada baris
for ($i = 0; $i < count($data); $i++) {
$w = $this->widths[$i];
$a = isset($this->aligns[$i]) ? $this->aligns[$i] : 'L';
$x = $this->GetX();
$y = $this->GetY();
// Gambar border dan background
$this->Rect($x, $y, $w, $rowH, $fill ? 'DF' : 'D');
// Tulis teks menggunakan MultiCell
$this->MultiCell($w, $h, $data[$i], 0, $a);
// Geser posisi X ke kanan untuk cell berikutnya
$this->SetXY($x + $w, $y);
}
// Pindah baris
$this->Ln($rowH);
}
public function CheckPageBreak($h)
{
// Jika tinggi baris melewati batas, buat halaman baru
if ($this->GetY() + $h > $this->PageBreakTrigger) {
$this->AddPage($this->CurOrientation);
}
}
public function NbLines($w, $txt)
{
// Menghitung jumlah baris yang akan dihasilkan oleh MultiCell
$cw =& $this->CurrentFont['cw'];
if ($w == 0) {
$w = $this->w - $this->rMargin - $this->x;
}
$wmax = ($w - 2 * $this->cMargin) * 1000 / $this->FontSize;
$s = str_replace("\r", '', $txt);
$nb = strlen($s);
if ($nb > 0 && $s[$nb - 1] == "\n") {
$nb--;
}
$sep = -1;
$i = 0;
$j = 0;
$l = 0;
$nl = 1;
while ($i < $nb) {
$c = $s[$i];
if ($c == "\n") {
$i++;
$sep = -1;
$j = $i;
$l = 0;
$nl++;
continue;
}
if ($c == ' ') {
$sep = $i;
}
$l += $cw[$c];
if ($l > $wmax) {
if ($sep == -1) {
if ($i == $j) {
$i++;
}
} else {
$i = $sep + 1;
}
$sep = -1;
$j = $i;
$l = 0;
$nl++;
} else {
$i++;
}
}
return $nl;
}
}
// =============================================================================
@@ -123,12 +227,15 @@ class Rpt_payment_voucher extends MY_Controller
pv.*,
cs.coaAccountNo,
cs.coaDescription,
ct.coaAccountNo AS coaTempAccountNo,
ct.coaDescription AS coaTempDescription,
b.M_BranchName,
IFNULL(uCr.M_UserUsername, '') AS CreatedByName,
IFNULL(uPd.M_UserUsername, '') AS PaidByName,
IFNULL(uRc.M_UserUsername, '') AS PaidReceiveByName
FROM payment_voucher pv
LEFT JOIN coa cs ON cs.coaID = pv.PaymentVoucherCoaSourceID
LEFT JOIN coa ct ON ct.coaID = pv.PaymentVoucherCoaTemporaryID
LEFT JOIN m_branch b ON b.M_BranchCode = pv.PaymentVoucherM_BranchCode
LEFT JOIN m_user uCr ON uCr.M_UserID = pv.PaymentVoucherUserID
LEFT JOIN m_user uPd ON uPd.M_UserID = pv.PaymentVoucherPaidUserID
@@ -145,22 +252,27 @@ class Rpt_payment_voucher extends MY_Controller
return $qry->row_array();
}
// =========================================================================
// DATABASE: Ambil data detail
// =========================================================================
private function _get_detail($id)
{
$sql = "
SELECT
pvd.*,
prd.PurchaseRequestDirectNumber,
prd.PurchaseRequestDirectDescription,
prd.PurchaseRequestDirectNote
prdd.PurchaseRequestDirectDescription AS ItemDescription,
prdd.PurchaseRequestDirectDetailAccount AS ExpenseAccount,
prdd.PurchaseRequestDirectDetailTotalRealitationPrice,
prdd.PurchaseRequestDirectDetailTotalEstimationPrice,
pdc.PurchaseDirectCategoryName,
c.coaDescription AS ExpenseAccountName
FROM payment_voucher_detail pvd
LEFT JOIN purchase_request_direct prd ON prd.PurchaseRequestDirectID = pvd.PaymentVoucherDetailPurchaseRequestDirectID
JOIN purchase_request_direct prd ON prd.PurchaseRequestDirectID = pvd.PaymentVoucherDetailPurchaseRequestDirectID
JOIN purchase_request_direct_detail prdd ON prdd.PurchaseRequestDirectDetailPurchaseRequestDirectID = prd.PurchaseRequestDirectID
AND prdd.PurchaseRequestDirectDetailIsActive = 'Y'
LEFT JOIN purchase_direct_category pdc ON pdc.PurchaseDirectCategoryID = prdd.PurchaseRequestDirectDetailPurchaseRequestDirectCategoryID
LEFT JOIN coa c ON c.coaAccountNo = prdd.PurchaseRequestDirectDetailAccount AND c.coaIsActive = 'Y'
WHERE pvd.PaymentVoucherDetailIsActive = 'Y'
AND pvd.PaymentVoucherDetailPaymentVoucherID = ?
ORDER BY pvd.PaymentVoucherDetailID ASC
ORDER BY pvd.PaymentVoucherDetailID ASC, prdd.PurchaseRequestDirectDetailID ASC
";
$qry = $this->db->query($sql, array($id));
return $qry ? $qry->result_array() : array();
@@ -196,25 +308,43 @@ class Rpt_payment_voucher extends MY_Controller
$coaSource = $header['coaAccountNo'] . ' - ' . $header['coaDescription'];
}
$coaTemp = '';
if (!empty($header['coaTempAccountNo'])) {
$coaTemp = $header['coaTempAccountNo'] . ' - ' . $header['coaTempDescription'];
}
$leftItems = array(
array('Nomor', $header['PaymentVoucherNumber'], true),
array('Tanggal', $this->_fmt_datetime($header['PaymentVoucherDate']), false),
array('Tanggal', $this->_fmt_date($header['PaymentVoucherDate']), false),
array('Sumber Dana', $coaSource, false),
array('Status', $header['PaymentVoucherStatus'] ?: '-', false),
);
if ($coaTemp !== '') {
$leftItems[] = array('Akun Transit', $coaTemp, 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($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);
}
if ($item[0] === 'Sumber Dana' || $item[0] === 'Akun Transit') {
$pdf->MultiCell($valW, 5, $item[1], 0, 'L');
} else {
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
}
}
// Keterangan / Paid Note langsung di bawah Status (tanpa spasi vertikal)
if (!empty($header['PaymentVoucherPaidNote'])) {
@@ -232,10 +362,8 @@ class Rpt_payment_voucher extends MY_Controller
$rightItems = array(
array('Cabang', $header['M_BranchName'] ?: '-'),
array('Tgl Pembayaran', $this->_fmt_datetime($header['PaymentVoucherPaidDate'])),
array('Tgl Pembayaran', $this->_fmt_date($header['PaymentVoucherPaidDate'])),
array('Dibuat Oleh', $header['CreatedByName'] ?: '-'),
array('Dibayar Oleh', $header['PaidByName'] ?: '-'),
array('Diterima Oleh', $header['PaidReceiveByName'] ?: '-'),
);
foreach ($rightItems as $item) {
@@ -263,13 +391,13 @@ class Rpt_payment_voucher extends MY_Controller
// ── Definisi kolom: [label, lebar, align] ─────────────────────────────
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
// 8 + 42 + 55 + 45 + 30 = 180
// 8 + 45 + 30 + 72 + 25 = 180
$cols = array(
array('No', 8, 'C'),
array('No. Request Direct', 42, 'L'),
array('Deskripsi', 55, 'L'),
array('Catatan PR', 45, 'L'),
array('Nominal Bayar', 30, 'R'),
array('No. Request Direct', 45, 'L'),
array('Kategori', 30, 'L'),
array('Deskripsi', 72, 'L'),
array('Nominal Bayar', 25, 'R'),
);
// Header kolom
@@ -282,6 +410,10 @@ class Rpt_payment_voucher extends MY_Controller
}
$pdf->Ln();
// Set lebar dan alignment kolom untuk metode Row()
$pdf->SetWidths(array_column($cols, 1));
$pdf->SetAligns(array_column($cols, 2));
// Baris data
$pdf->SetLineWidth(0.2); // border lebih tipis di data
$pdf->SetFont('Arial_Narrow', '', 8);
@@ -290,14 +422,22 @@ class Rpt_payment_voucher extends MY_Controller
$totalPay = 0;
foreach ($details as $d) {
$pdf->Cell($cols[0][1], 6, $no, 1, 0, 'C');
$pdf->Cell($cols[1][1], 6, $d['PurchaseRequestDirectNumber'] ?: '-', 1, 0, 'L');
$pdf->Cell($cols[2][1], 6, $d['PurchaseRequestDirectDescription'] ?: '-', 1, 0, 'L');
$pdf->Cell($cols[3][1], 6, $d['PurchaseRequestDirectNote'] ?: '-', 1, 0, 'L');
$pdf->Cell($cols[4][1], 6, $this->_fmt_rp($d['PaymentVoucherDetailTotal']), 1, 0, 'R');
$pdf->Ln();
$amount = floatval($d['PurchaseRequestDirectDetailTotalRealitationPrice']);
if ($amount <= 0) {
$amount = floatval($d['PurchaseRequestDirectDetailTotalEstimationPrice']);
}
$totalPay += floatval($d['PaymentVoucherDetailTotal']);
$row_data = array(
$no,
$d['PurchaseRequestDirectNumber'] ?: '-',
$d['PurchaseDirectCategoryName'] ?: '-',
$d['ItemDescription'] ?: '-',
$this->_fmt_rp($amount),
);
$pdf->Row($row_data);
$totalPay += $amount;
$no++;
}

View File

@@ -182,17 +182,47 @@ class Rpt_pr_direct extends MY_Controller
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
$pdf->Ln(2);
// ── Info dokumen: 2 kolom (kiri & kanan) ─────────────────────────────
$startY = $pdf->GetY();
$half = $pageW / 2;
$lbl = 30;
$lbl = 28;
$val = $half - $lbl - 4;
// ── Kolom Kiri ────────────────────────────────────────────────────────
$pdf->SetY($startY);
$left = array(
array('Nomor', $header['PurchaseRequestDirectNumber']),
array('Tanggal', $this->_fmt_date($header['PurchaseRequestDirectDate'])),
array('Tanggal Pelaksanaan', $this->_fmt_date($header['PurchaseRequestDirectDateUse'])),
array('Status', $header['PurchaseRequestDirectStatus']),
array('Nomor', $header['PurchaseRequestDirectNumber'], true),
array('Tanggal', $this->_fmt_date($header['PurchaseRequestDirectDate']), false),
array('Tanggal Pelaksanaan', $this->_fmt_date($header['PurchaseRequestDirectDateUse']), false),
);
foreach ($left as $item) {
$pdf->SetX(15);
$pdf->SetFont('Arial_Narrow', '', 9);
$pdf->Cell($lbl, 5, $item[0], 0, 0, 'L');
$pdf->Cell(4, 5, ':', 0, 0, 'C');
if (isset($item[2]) && $item[2]) {
$pdf->SetFont('Arial_Narrow', 'B', 9);
} else {
$pdf->SetFont('Arial_Narrow', '', 9);
}
$pdf->Cell($val, 5, $item[1], 0, 1, 'L');
}
// Keterangan langsung di bawah info kiri (tanpa spasi vertikal)
if (!empty($header['PurchaseRequestDirectDescription'])) {
$pdf->SetX(15);
$pdf->SetFont('Arial_Narrow', '', 9);
$pdf->Cell($lbl, 5, 'Keterangan', 0, 0, 'L');
$pdf->Cell(4, 5, ':', 0, 0, 'C');
$pdf->MultiCell($val, 5, $header['PurchaseRequestDirectDescription'], 0, 'L');
}
$leftY = $pdf->GetY();
// ── Kolom Kanan ───────────────────────────────────────────────────────
$pdf->SetY($startY);
$rightX = 15 + $half;
$right = array(
array('Cabang', $header['M_BranchName']),
array('Regional', $header['S_RegionalName']),
@@ -200,43 +230,22 @@ class Rpt_pr_direct extends MY_Controller
array('Dibuat Oleh', $header['CreatedByName']),
);
$maxRow = max(count($left), count($right));
for ($i = 0; $i < $maxRow; $i++) {
// kolom kiri
if (isset($left[$i])) {
foreach ($right as $item) {
$pdf->SetX($rightX);
$pdf->SetFont('Arial_Narrow', '', 9);
$pdf->Cell($lbl, 5, $left[$i][0], 0, 0, 'L');
$pdf->Cell(4, 5, ':', 0, 0, 'C');
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_Narrow', '', 9);
$pdf->Cell($lbl, 5, $right[$i][0], 0, 0, 'L');
$pdf->Cell($lbl, 5, $item[0], 0, 0, 'L');
$pdf->Cell(4, 5, ':', 0, 0, 'C');
$pdf->SetFont('Arial_Narrow', '', 9);
$pdf->Cell($val, 5, $right[$i][1], 0, 1, 'L');
} else {
$pdf->Cell($half, 5, '', 0, 1);
}
}
// Keterangan (catatan dihapus)
if (!empty($header['PurchaseRequestDirectDescription'])) {
$pdf->SetFont('Arial_Narrow', '', 9);
$pdf->Cell($lbl, 5, 'Keterangan', 0, 0, 'L');
$pdf->Cell(4, 5, ':', 0, 0, 'C');
$pdf->Cell($pageW - $lbl - 4, 5, $header['PurchaseRequestDirectDescription'], 0, 1, 'L');
if ($item[0] === 'Alamat') {
$pdf->MultiCell($val, 5, $item[1], 0, 'L');
} else {
$pdf->Cell($val, 5, $item[1], 0, 1, 'L');
}
}
$rightY = $pdf->GetY();
$pdf->Ln(4);
$pdf->SetY(max($leftY, $rightY) + 4);
}
// =========================================================================

View File

@@ -202,7 +202,7 @@ class Rpt_pr_direct_approval extends MY_Controller
array('Nomor', $header['PurchaseRequestDirectNumber'], true),
array('Tanggal', $this->_fmt_date($header['PurchaseRequestDirectDate']), false),
array('Tanggal Pelaksanaan', $this->_fmt_date($header['PurchaseRequestDirectDateUse']), false),
array('Status', $header['PurchaseRequestDirectStatus'], false),
array('Tanggal Approved', $this->_fmt_datetime($header['PurchaseRequestDirectApprovedDate'])),
);
foreach ($leftItems as $item) {
@@ -210,7 +210,7 @@ class Rpt_pr_direct_approval extends MY_Controller
$pdf->SetFont('Arial_Narrow', '', 9);
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
$pdf->Cell(4, 5, ':', 0, 0, 'C');
if ($item[2]) {
if (isset($item[2]) && $item[2]) {
$pdf->SetFont('Arial_Narrow', 'B', 9);
} else {
$pdf->SetFont('Arial_Narrow', '', 9);
@@ -245,7 +245,6 @@ class Rpt_pr_direct_approval extends MY_Controller
array('Alamat', $header['M_BranchAddress']),
array('Dibuat Oleh', $header['CreatedByName']),
array('Disetujui Oleh', $header['ApprovedByName']),
array('Tanggal Approved', $this->_fmt_datetime($header['PurchaseRequestDirectApprovedDate'])),
);
foreach ($rightItems as $item) {

View File

@@ -225,9 +225,8 @@ class Rpt_purchase_order_asset extends MY_Controller
}
$leftItems = array(
array('Nomor PO', $header['PurchaseOrderNumber'], true),
array('Tanggal PO', $this->_fmt_date($header['PurchaseOrderDate']), false),
array('No. Referensi', $header['PurchaseOrderRefNumber'] ?: '-', false),
array('Nomor', $header['PurchaseOrderNumber'], true),
array('Tanggal', $this->_fmt_date($header['PurchaseOrderDate']), false),
array('Nama Kontrak', $header['ContractName'] ?: '-', false),
array('Tanggal Kontrak', $this->_fmt_date($header['ContractDate']), false),
array('Periode Kontrak', $periodeKontrak, false),

View File

@@ -0,0 +1,440 @@
<?php
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
// =============================================================================
class PurchaseOrderJasaFpdf 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_purchase_order_jasa extends MY_Controller
{
// ── Properti bersama antar fungsi PDF ─────────────────────────────────────
/** @var PurchaseOrderJasaFpdf */
private $_pdf;
private $_pageW;
private $_header_data;
private $_username;
public function __construct()
{
parent::__construct();
}
public function index()
{
echo "Purchase Order Jasa Report API";
}
// =========================================================================
// ENDPOINT: pdf
// GET/POST: id (PurchaseOrderID), 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 PurchaseOrderJasaFpdf('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 = 'PO_JASA_' . str_replace('/', '-', $header['PurchaseOrderNumber']) . '.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
po.*,
sup.SupplierName,
sup.SupplierAddress,
sup.SupplierPhone,
b.M_BranchName,
b.M_BranchAddress,
r.S_RegionalName,
kj.T_KontrakJasaJenisKontrak AS JenisKontrak,
kj.T_KontrakJasaStartDate AS StartDate,
kj.T_KontrakJasaEndDate AS EndDate,
kj.T_KontrakJasaJumlahPI AS JumlahPI,
kj.T_KontrakJasaStatus AS StatusKontrak
FROM purchase_order po
LEFT JOIN supplier sup ON sup.SupplierID = po.PurchaseOrderSupplierID
LEFT JOIN s_regional r ON r.S_RegionalID = po.PurchaseOrderS_RegionalID
LEFT JOIN t_kontrak_jasa kj ON kj.T_KontrakJasaPurchaseOrderID = po.PurchaseOrderID
AND kj.T_KontrakJasaIsActive = 'Y'
LEFT JOIN m_branch b ON b.M_BranchCode = kj.T_KontrakJasaM_BranchCode
WHERE po.PurchaseOrderIsActive = 'Y'
AND po.PurchaseOrderID = ?
LIMIT 1
";
$qry = $this->db->query($sql, array($id));
if (!$qry || $qry->num_rows() === 0) {
$this->sys_error("Data Purchase Order Jasa tidak ditemukan");
exit;
}
return $qry->row_array();
}
// =========================================================================
// DATABASE: Ambil data detail
// =========================================================================
private function _get_detail($id)
{
$sql = "
SELECT
pos.PurchaseOrderSummaryQty AS RequestQty,
pos.PurchaseOrderSummaryPrice AS SupplierPrice,
pos.PurchaseOrderSummaryDiscountAmount AS DiskonAmount,
pos.PurchaseOrderSummaryTotal AS TempTotal,
item.M_ItemCode,
item.M_ItemDesc,
iu.ItemUnitName,
iu.ItemUnitCode
FROM purchase_order_summary pos
JOIN m_item item ON item.M_ItemID = pos.PurchaseOrderSummaryItemID
AND item.M_ItemIsActive = 'Y'
LEFT JOIN itemunit iu ON iu.ItemUnitID = pos.PurchaseOrderSummaryItemUnitID
AND iu.ItemUnitIsActive = 'Y'
WHERE pos.PurchaseOrderSummaryIsActive = 'Y'
AND pos.PurchaseOrderSummaryPurchaseOrderID = ?
ORDER BY pos.PurchaseOrderSummaryID 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, 'PURCHASE ORDER JASA (SERVICE PO)', 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 = 28;
$valW = $halfW - $lblW - 4;
// ── Kolom Kiri ────────────────────────────────────────────────────────
$pdf->SetY($startY);
// Format Jenis Kontrak
$jenisKontrak = '-';
if (!empty($header['JenisKontrak'])) {
$jenisKontrak = ($header['JenisKontrak'] === 'once') ? 'Sekali Bayar (Once)' : 'Berkala (Recurring)';
}
// Periode kontrak
$periodeJasa = '-';
if (!empty($header['StartDate']) && $header['StartDate'] !== '0000-00-00') {
$periodeJasa = $this->_fmt_date($header['StartDate']) . ' s/d ' . $this->_fmt_date($header['EndDate']);
}
// Jumlah Termin/PI
$jumlahPI = '-';
if (intval($header['JumlahPI'] ?? 0) > 0) {
$jumlahPI = $header['JumlahPI'] . ' Kali Pembayaran';
}
$leftItems = array(
array('Nomor', $header['PurchaseOrderNumber'], true),
array('Tanggal', $this->_fmt_date($header['PurchaseOrderDate']), false),
array('Cabang', $header['M_BranchName'] ?: '-', 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 (tanpa spasi vertikal)
if (!empty($header['PurchaseOrderNote'])) {
$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['PurchaseOrderNote'], 0, 'L');
}
$leftY = $pdf->GetY();
// ── Kolom Kanan ───────────────────────────────────────────────────────
$pdf->SetY($startY);
$rightX = 15 + $halfW;
$rightItems = array(
array('Supplier', $header['SupplierName'] ?: '-'),
array('Alamat Supplier', $header['SupplierAddress'] ?: '-'),
array('Telp Supplier', $header['SupplierPhone'] ?: '-'),
array('Jenis Kontrak', $jenisKontrak),
array('Periode Jasa', $periodeJasa),
array('Termin Bayar', $jumlahPI),
);
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);
if ($item[0] === 'Alamat Supplier') {
$pdf->MultiCell($valW, 5, $item[1], 0, 'L');
} else {
$pdf->Cell($valW, 5, $item[1], 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;
$header = $this->_header_data;
// ── Definisi kolom: [label, lebar, align] ─────────────────────────────
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
// 8 + 65 + 20 + 15 + 25 + 22 + 25 = 180
$cols = array(
array('No', 8, 'C'),
array('Nama', 65, 'L'),
array('Unit', 20, 'C'),
array('Qty', 15, 'R'),
array('Harga Satuan', 25, 'R'),
array('Diskon', 22, 'R'),
array('Total', 25, 'R'),
);
// Header kolom
$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) {
$pdf->Cell($c[1], 7, $c[0], 1, 0, 'C', true);
}
$pdf->Ln();
// Baris data
$pdf->SetLineWidth(0.2); // border lebih tipis di data
$pdf->SetFont('Arial_Narrow', '', 8);
$pdf->SetFillColor(255, 255, 255);
$no = 1;
$subTotal = 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['RequestQty']), 1, 0, 'C');
$pdf->Cell($cols[4][1], 6, $this->_fmt_rp($d['SupplierPrice']), 1, 0, 'R');
$pdf->Cell($cols[5][1], 6, $this->_fmt_rp($d['DiskonAmount']), 1, 0, 'R');
$pdf->Cell($cols[6][1], 6, $this->_fmt_rp($d['TempTotal']), 1, 0, 'R');
$pdf->Ln();
$subTotal += floatval($d['TempTotal']);
$no++;
}
$pdf->Ln(2);
// ── Ringkasan Biaya di Bagian Kanan Bawah ──────────────────────────────
$discountPO = floatval($header['PurchaseOrderDiscountAmount'] ?? 0);
$ppnAmount = floatval($header['PurchaseOrderTaxAmountPpn'] ?? 0);
$pphAmount = floatval($header['PurchaseOrderTaxAmountPph'] ?? 0);
$shipCost = floatval($header['PurchaseOrderShippingCost'] ?? 0);
$grandTotal = floatval($header['PurchaseOrderGrandTotal'] ?? ($subTotal - $discountPO + $ppnAmount - $pphAmount + $shipCost));
$summary = array(
array('Subtotal', $this->_fmt_rp($subTotal)),
);
if ($discountPO > 0) {
$summary[] = array('Diskon PO', '-' . $this->_fmt_rp($discountPO));
}
if ($ppnAmount > 0) {
$summary[] = array('PPN', $this->_fmt_rp($ppnAmount));
}
if ($pphAmount > 0) {
$summary[] = array('PPH', '-' . $this->_fmt_rp($pphAmount));
}
if ($shipCost > 0) {
$summary[] = array('Ongkos Kirim', $this->_fmt_rp($shipCost));
}
$summary[] = array('Grand Total', $this->_fmt_rp($grandTotal));
$cW1 = 47;
$cW2 = 25;
$offsetX = 15 + array_sum(array_column(array_slice($cols, 0, 4), 1)); // Sejajar dengan Harga Satuan ke kanan
foreach ($summary as $s) {
$pdf->SetX($offsetX);
$pdf->SetFont('Arial_Narrow', '', 8);
$pdf->Cell($cW1, 5, $s[0], 0, 0, 'L');
if ($s[0] === 'Grand Total') {
$pdf->SetFont('Arial_Narrow', 'B', 9);
} else {
$pdf->SetFont('Arial_Narrow', 'B', 8);
}
$pdf->Cell($cW2, 5, $s[1], 0, 1, 'R');
}
$pdf->Ln(8);
}
// =========================================================================
// PDF SECTION: Syarat & Ketentuan
// =========================================================================
private function _pdf_terms()
{
$pdf = $this->_pdf;
$pageW = $this->_pageW;
$terms = array(
'Purchase Order (PO) Jasa ini tunduk pada syarat dan ketentuan kontrak pengerjaan yang disepakati.',
'Seluruh termin pembayaran angsuran jasa harus ditagihkan disertai dengan Berita Acara Serah Terima Jasa (BASTJ).',
'Klaim ketidaksesuaian hasil pengerjaan harus dilaporkan langsung ke vendor bersangkutan.',
'PO ini sah secara hukum setelah disetujui dan divalidasi secara digital melalui sistem ERP.'
);
$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, ',', '.');
}
// 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, ',', '.');
}
}

View File

@@ -221,7 +221,6 @@ class Rpt_receive_item_po extends MY_Controller
$leftItems = array(
array('Nomor', $header['ReceiveOrderPoNumber'], true),
array('Tanggal', $this->_fmt_date($header['ReceiveOrderPoIDate']), false),
array('No. Referensi', $header['ReceiveOrderPoRefNumber'] ?: '-', false),
array('No. Surat Jalan', $header['ReceiveOrderPoDONumber'] ?: '-', false),
array('Gudang Penerima', $header['ReceivedWarehouseName'] ?: '-', false),
);
@@ -290,15 +289,14 @@ class Rpt_receive_item_po extends MY_Controller
// ── Definisi kolom: [label, lebar, align] ─────────────────────────────
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
// 8 + 45 + 38 + 20 + 15 + 24 + 30 = 180
// 8 + 75 + 23 + 15 + 27 + 32 = 180
$cols = array(
array('No', 8, 'C'),
array('Nama', 45, 'L'),
array('No. PO', 38, 'L'),
array('Unit', 20, 'C'),
array('Nama', 75, 'L'),
array('Unit', 23, 'C'),
array('Qty', 15, 'C'),
array('Harga', 24, 'R'),
array('Total', 30, 'R'),
array('Harga', 27, 'R'),
array('Total', 32, 'R'),
);
// Header kolom
@@ -321,11 +319,10 @@ class Rpt_receive_item_po extends MY_Controller
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['PurchaseOrderNumber'] ?: '-', 1, 0, 'L');
$pdf->Cell($cols[3][1], 6, $d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'), 1, 0, 'C');
$pdf->Cell($cols[4][1], 6, $this->_fmt_qty($d['ReceiveOrderPoDetailQty']), 1, 0, 'C');
$pdf->Cell($cols[5][1], 6, $this->_fmt_rp($d['ReceiveOrderPoDetailPrice']), 1, 0, 'R');
$pdf->Cell($cols[6][1], 6, $this->_fmt_rp($d['ReceiveOrderPoDetailTotal']), 1, 0, 'R');
$pdf->Cell($cols[2][1], 6, $d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'), 1, 0, 'C');
$pdf->Cell($cols[3][1], 6, $this->_fmt_qty($d['ReceiveOrderPoDetailQty']), 1, 0, 'C');
$pdf->Cell($cols[4][1], 6, $this->_fmt_rp($d['ReceiveOrderPoDetailPrice']), 1, 0, 'R');
$pdf->Cell($cols[5][1], 6, $this->_fmt_rp($d['ReceiveOrderPoDetailTotal']), 1, 0, 'R');
$pdf->Ln();
$grand_tot += floatval($d['ReceiveOrderPoDetailTotal']);
@@ -333,12 +330,12 @@ class Rpt_receive_item_po extends MY_Controller
}
// Baris TOTAL
$span = array_sum(array_column(array_slice($cols, 0, 6), 1));
$span = array_sum(array_column(array_slice($cols, 0, 5), 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($grand_tot), 1, 0, 'R', true);
$pdf->Cell($cols[5][1], 7, $this->_fmt_rp($grand_tot), 1, 0, 'R', true);
$pdf->Ln(6);
// Ringkasan Biaya jika ada Biaya Ekspedisi (mendukung fallback dari PO)
@@ -360,8 +357,8 @@ class Rpt_receive_item_po extends MY_Controller
array('Grand Total', $this->_fmt_rp($grandTotal)),
);
$cW1 = 39;
$cW2 = 30;
$cW1 = 27;
$cW2 = 32;
$offsetX = 15 + array_sum(array_column(array_slice($cols, 0, 4), 1));
foreach ($summary as $s) {

View File

@@ -224,8 +224,6 @@ class Rpt_receive_item_po_inventaris extends MY_Controller
$leftItems = array(
array('Nomor', $header['ReceiveOrderPoNumber'], true),
array('Tanggal', $this->_fmt_date($header['ReceiveOrderPoIDate']), false),
array('No. Referensi', $header['ReceiveOrderPoRefNumber'] ?: '-', false),
array('No. Surat Jalan', $header['ReceiveOrderPoDONumber'] ?: '-', false),
array('Gudang Penerima', $header['ReceivedWarehouseName'] ?: '-', false),
array('Ruangan / Lokasi', $header['RuanganName'] ?: '-', false),
);
@@ -261,6 +259,7 @@ class Rpt_receive_item_po_inventaris extends MY_Controller
array('Supplier', $header['SupplierName'] ?: '-'),
array('Alamat Supplier', $header['SupplierAddress'] ?: '-'),
array('Telp Supplier', $header['SupplierPhone'] ?: '-'),
array('Cabang', $header['M_BranchName'] ?: '-'),
array('Alamat Penerima', $header['M_BranchAddress'] ?: '-'),
);
@@ -294,15 +293,14 @@ class Rpt_receive_item_po_inventaris extends MY_Controller
// ── Definisi kolom: [label, lebar, align] ─────────────────────────────
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
// 8 + 45 + 38 + 20 + 15 + 24 + 30 = 180
// 8 + 75 + 23 + 15 + 27 + 32 = 180
$cols = array(
array('No', 8, 'C'),
array('Nama', 45, 'L'),
array('No. PO', 38, 'L'),
array('Unit', 20, 'C'),
array('Qty', 15, 'R'),
array('Harga', 24, 'R'),
array('Total', 30, 'R'),
array('Nama', 75, 'L'),
array('Unit', 23, 'C'),
array('Qty', 15, 'C'),
array('Harga', 27, 'R'),
array('Total', 32, 'R'),
);
// Header kolom
@@ -325,11 +323,10 @@ class Rpt_receive_item_po_inventaris extends MY_Controller
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['PurchaseOrderNumber'] ?: '-', 1, 0, 'L');
$pdf->Cell($cols[3][1], 6, $d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'), 1, 0, 'C');
$pdf->Cell($cols[4][1], 6, $this->_fmt_qty($d['ReceiveOrderPoDetailQty']), 1, 0, 'C');
$pdf->Cell($cols[5][1], 6, $this->_fmt_rp($d['ReceiveOrderPoDetailPrice']), 1, 0, 'R');
$pdf->Cell($cols[6][1], 6, $this->_fmt_rp($d['ReceiveOrderPoDetailTotal']), 1, 0, 'R');
$pdf->Cell($cols[2][1], 6, $d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'), 1, 0, 'C');
$pdf->Cell($cols[3][1], 6, $this->_fmt_qty($d['ReceiveOrderPoDetailQty']), 1, 0, 'C');
$pdf->Cell($cols[4][1], 6, $this->_fmt_rp($d['ReceiveOrderPoDetailPrice']), 1, 0, 'R');
$pdf->Cell($cols[5][1], 6, $this->_fmt_rp($d['ReceiveOrderPoDetailTotal']), 1, 0, 'R');
$pdf->Ln();
$grand_tot += floatval($d['ReceiveOrderPoDetailTotal']);
@@ -337,12 +334,12 @@ class Rpt_receive_item_po_inventaris extends MY_Controller
}
// Baris TOTAL
$span = array_sum(array_column(array_slice($cols, 0, 6), 1));
$span = array_sum(array_column(array_slice($cols, 0, 5), 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($grand_tot), 1, 0, 'R', true);
$pdf->Cell($cols[5][1], 7, $this->_fmt_rp($grand_tot), 1, 0, 'R', true);
$pdf->Ln(6);
// Ringkasan Biaya jika ada Biaya Ekspedisi (mendukung fallback dari PO)
@@ -364,8 +361,8 @@ class Rpt_receive_item_po_inventaris extends MY_Controller
array('Grand Total', $this->_fmt_rp($grandTotal)),
);
$cW1 = 39;
$cW2 = 30;
$cW1 = 27;
$cW2 = 32;
$offsetX = 15 + array_sum(array_column(array_slice($cols, 0, 4), 1));
foreach ($summary as $s) {

View File

@@ -99,6 +99,7 @@ class Rpt_receive_order_asset extends MY_Controller
// ── Susun isi halaman ─────────────────────────────────────────────
$this->_pdf_header();
$this->_pdf_data($details);
$this->_pdf_inspeksi($details);
$this->_pdf_terms();
// ── Output ────────────────────────────────────────────────────────
@@ -177,13 +178,22 @@ class Rpt_receive_order_asset extends MY_Controller
item.M_ItemDesc,
iu.ItemUnitName,
iu.ItemUnitCode,
po.PurchaseOrderNumber
po.PurchaseOrderNumber,
uP.M_UserUsername AS StaffPenerima,
insp.ReceiveOrderPoInspeksiPengirim AS StaffPengirim,
insp.ReceiveOrderPoInspeksiKeadaanKemasan AS KeadaanKemasan,
insp.ReceiveOrderPoInspeksiKondisiPengiriman AS KondisiPengiriman,
insp.ReceiveOrderPoInspeksiSimpulan AS Simpulan,
insp.ReceiveOrderPoInspeksiCatatan AS CatatanInspeksi
FROM receive_order_po_detail ropd
JOIN m_item item ON item.M_ItemID = ropd.ReceiveOrderPoItemID
AND item.M_ItemIsActive = 'Y'
LEFT JOIN itemunit iu ON iu.ItemUnitID = ropd.ReceiveOrderPoItemUnitID
AND iu.ItemUnitIsActive = 'Y'
LEFT JOIN purchase_order po ON po.PurchaseOrderID = ropd.ReceiveOrderPoDetailPurchaseOrderID
LEFT JOIN receive_order_po_inspeksi insp ON insp.ReceiveOrderPoInspeksiReceiveOrderPoDetailID = ropd.ReceiveOrderPoDetailID
AND insp.ReceiveOrderPoInspeksiIsActive = 'Y'
LEFT JOIN m_user uP ON uP.M_UserID = insp.ReceiveOrderPoInspeksiStaffPenerimaID
WHERE ropd.ReceiveOrderPoDetailIsActive = 'Y'
AND ropd.ReceiveOrderPoDetailReceiveOrderPoID = ?
ORDER BY ropd.ReceiveOrderPoDetailID ASC
@@ -220,7 +230,6 @@ class Rpt_receive_order_asset extends MY_Controller
$leftItems = array(
array('Nomor', $header['ReceiveOrderPoNumber'], true),
array('Tanggal', $this->_fmt_date($header['ReceiveOrderPoIDate']), false),
array('No. Referensi', $header['ReceiveOrderPoRefNumber'] ?: '-', false),
array('Gudang Penerima', $header['ReceivedWarehouseName'] ?: '-', false),
);
@@ -289,15 +298,14 @@ class Rpt_receive_order_asset extends MY_Controller
// ── Definisi kolom: [label, lebar, align] ─────────────────────────────
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
// 8 + 45 + 38 + 20 + 15 + 24 + 30 = 180
// 8 + 75 + 23 + 15 + 27 + 32 = 180
$cols = array(
array('No', 8, 'C'),
array('Nama', 45, 'L'),
array('No. PO', 38, 'L'),
array('Unit', 20, 'C'),
array('Qty', 15, 'R'),
array('Harga', 24, 'R'),
array('Total', 30, 'R'),
array('Nama', 75, 'L'),
array('Unit', 23, 'C'),
array('Qty', 15, 'C'),
array('Harga', 27, 'R'),
array('Total', 32, 'R'),
);
// Header kolom
@@ -320,11 +328,10 @@ class Rpt_receive_order_asset extends MY_Controller
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['PurchaseOrderNumber'] ?: '-', 1, 0, 'L');
$pdf->Cell($cols[3][1], 6, $d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'), 1, 0, 'C');
$pdf->Cell($cols[4][1], 6, $this->_fmt_qty($d['ReceiveOrderPoDetailQty']), 1, 0, 'C');
$pdf->Cell($cols[5][1], 6, $this->_fmt_rp($d['ReceiveOrderPoDetailPrice']), 1, 0, 'R');
$pdf->Cell($cols[6][1], 6, $this->_fmt_rp($d['ReceiveOrderPoDetailTotal']), 1, 0, 'R');
$pdf->Cell($cols[2][1], 6, $d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'), 1, 0, 'C');
$pdf->Cell($cols[3][1], 6, $this->_fmt_qty($d['ReceiveOrderPoDetailQty']), 1, 0, 'C');
$pdf->Cell($cols[4][1], 6, $this->_fmt_rp($d['ReceiveOrderPoDetailPrice']), 1, 0, 'R');
$pdf->Cell($cols[5][1], 6, $this->_fmt_rp($d['ReceiveOrderPoDetailTotal']), 1, 0, 'R');
$pdf->Ln();
$grand_tot += floatval($d['ReceiveOrderPoDetailTotal']);
@@ -332,13 +339,12 @@ class Rpt_receive_order_asset extends MY_Controller
}
// Baris TOTAL
$span = array_sum(array_column(array_slice($cols, 0, 6), 1));
$span = array_sum(array_column(array_slice($cols, 0, 5), 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($grand_tot), 1, 0, 'R', true);
$pdf->Ln(6);
$pdf->Cell($cols[5][1], 7, $this->_fmt_rp($grand_tot), 1, 0, 'R', true);
// Ringkasan Biaya jika ada Biaya Ekspedisi (mendukung fallback dari PO)
$shippingCost = floatval($header['ReceiveOrderShippingCostAmount'] ?? 0);
@@ -350,7 +356,7 @@ class Rpt_receive_order_asset extends MY_Controller
}
if ($shippingCost > 0) {
$pdf->Ln(2);
$pdf->Ln(7);
$grandTotal = $grand_tot + $shippingCost;
$statusPaid = ($isPaid === 'Y') ? ' (Lunas)' : ' (Belum Lunas)';
$summary = array(
@@ -359,8 +365,8 @@ class Rpt_receive_order_asset extends MY_Controller
array('Grand Total', $this->_fmt_rp($grandTotal)),
);
$cW1 = 39;
$cW2 = 30;
$cW1 = 27;
$cW2 = 32;
$offsetX = 15 + array_sum(array_column(array_slice($cols, 0, 4), 1));
foreach ($summary as $s) {
@@ -370,9 +376,79 @@ class Rpt_receive_order_asset extends MY_Controller
$pdf->SetFont('Arial_Narrow', 'B', 8);
$pdf->Cell($cW2, 5, $s[1], 0, 1, 'R');
}
$pdf->Ln(8);
} else {
$pdf->Ln(8);
}
}
$pdf->Ln(8);
// PDF SECTION: Inspeksi & Verifikasi Barang / Aset (Blok Terpisah)
// =========================================================================
private function _pdf_inspeksi($details)
{
$pdf = $this->_pdf;
$pageW = $this->_pageW;
// Cek apakah ada data inspeksi yang terisi
$hasInspeksi = false;
foreach ($details as $d) {
if (!empty($d['Simpulan']) || !empty($d['StaffPenerima']) || !empty($d['CatatanInspeksi'])) {
$hasInspeksi = true;
break;
}
}
if (!$hasInspeksi) {
return;
}
$pdf->Ln(2);
$pdf->SetFont('Arial_Narrow', 'B', 10);
$pdf->Cell($pageW, 6, 'DETAIL HASIL INSPEKSI BARANG / ASET', 0, 1, 'L');
$pdf->SetLineWidth(0.3);
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
$pdf->Ln(2);
$no = 1;
foreach ($details as $d) {
// Lewati jika item ini tidak memiliki data inspeksi sama sekali
if (empty($d['Simpulan']) && empty($d['StaffPenerima']) && empty($d['CatatanInspeksi'])) {
continue;
}
$pdf->SetFont('Arial_Narrow', 'B', 9);
$pdf->Cell($pageW, 5, $no . '. ' . ($d['M_ItemDesc'] ?: ($d['M_ItemCode'] ?: '-')), 0, 1, 'L');
// Indentasi isi detail inspeksi
$lblW = 32;
$valW = $pageW - $lblW - 4;
$items = array(
array('Staff Penerima', $d['StaffPenerima'] ?: '-'),
array('Kurir Pengirim', $d['StaffPengirim'] ?: '-'),
array('Keadaan Kemasan', $d['KeadaanKemasan'] ?: '-'),
array('Kondisi Pengiriman', $d['KondisiPengiriman'] ?: '-'),
array('Simpulan Hasil', $d['Simpulan'] ?: '-'),
array('Catatan Inspeksi', $d['CatatanInspeksi'] ?: '-'),
);
foreach ($items as $item) {
$pdf->SetX(18); // Indent slightly to the right
$pdf->SetFont('Arial_Narrow', '', 9);
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
$pdf->Cell(4, 5, ':', 0, 0, 'C');
$pdf->MultiCell($valW, 5, $item[1], 0, 'L');
}
$pdf->Ln(2);
$pdf->SetDrawColor(200, 200, 200);
$pdf->SetLineWidth(0.1);
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
$pdf->Ln(2);
$pdf->SetDrawColor(0, 0, 0); // restore black
$no++;
}
}
// =========================================================================

View File

@@ -0,0 +1,600 @@
<?php
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
// =============================================================================
class ReceiveOrderJasaFpdf extends FPDF
{
public $printUsername = '-';
public $printDate = '';
// Properties untuk tabel multiline
public $widths;
public $aligns;
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 SetWidths($w)
{
$this->widths = $w;
}
public function SetAligns($a)
{
$this->aligns = $a;
}
public function Row($data, $fill = false, $h = 6)
{
// Hitung tinggi maksimum baris berdasarkan multiline
$nb = 0;
for ($i = 0; $i < count($data); $i++) {
$nb = max($nb, $this->NbLines($this->widths[$i], $data[$i]));
}
$rowH = $h * $nb;
// Cek apakah perlu ganti halaman secara otomatis
$this->CheckPageBreak($rowH);
// Gambar cell pada baris
for ($i = 0; $i < count($data); $i++) {
$w = $this->widths[$i];
$a = isset($this->aligns[$i]) ? $this->aligns[$i] : 'L';
$x = $this->GetX();
$y = $this->GetY();
// Gambar border dan background
$this->Rect($x, $y, $w, $rowH, $fill ? 'DF' : 'D');
// Tulis teks menggunakan MultiCell
$this->MultiCell($w, $h, $data[$i], 0, $a);
// Geser posisi X ke kanan untuk cell berikutnya
$this->SetXY($x + $w, $y);
}
// Pindah baris
$this->Ln($rowH);
}
public function CheckPageBreak($h)
{
// Jika tinggi baris melewati batas, buat halaman baru
if ($this->GetY() + $h > $this->PageBreakTrigger) {
$this->AddPage($this->CurOrientation);
}
}
public function NbLines($w, $txt)
{
// Menghitung jumlah baris yang akan dihasilkan oleh MultiCell
$cw = &$this->CurrentFont['cw'];
if ($w == 0) {
$w = $this->w - $this->rMargin - $this->x;
}
$wmax = ($w - 2 * $this->cMargin) * 1000 / $this->FontSize;
$s = str_replace("\r", '', $txt);
$nb = strlen($s);
if ($nb > 0 && $s[$nb - 1] == "\n") {
$nb--;
}
$sep = -1;
$i = 0;
$j = 0;
$l = 0;
$nl = 1;
while ($i < $nb) {
$c = $s[$i];
if ($c == "\n") {
$i++;
$sep = -1;
$j = $i;
$l = 0;
$nl++;
continue;
}
if ($c == ' ') {
$sep = $i;
}
$l += $cw[$c];
if ($l > $wmax) {
if ($sep == -1) {
if ($i == $j) {
$i++;
}
} else {
$i = $sep + 1;
}
$sep = -1;
$j = $i;
$l = 0;
$nl++;
} else {
$i++;
}
}
return $nl;
}
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_receive_order_jasa extends MY_Controller
{
// ── Properti bersama antar fungsi PDF ─────────────────────────────────────
/** @var ReceiveOrderJasaFpdf */
private $_pdf;
private $_pageW;
private $_header_data;
private $_username;
public function __construct()
{
parent::__construct();
}
public function index()
{
echo "Receive Order Jasa Report API";
}
// =========================================================================
// ENDPOINT: pdf
// GET/POST: id (ReceiveOrderPoID), 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 ReceiveOrderJasaFpdf('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_inspeksi($details);
$this->_pdf_terms();
// ── Output ────────────────────────────────────────────────────────
$filename = 'RO_JASA_' . str_replace('/', '-', $header['ReceiveOrderPoNumber']) . '.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
ro.ReceiveOrderPoID,
ro.ReceiveOrderPoNumber,
ro.ReceiveOrderPoIDate,
ro.ReceiveOrderPoRefNumber,
ro.ReceiveOrderPoNote,
ro.ReceiveOrderPoConfirmed,
sup.SupplierName,
sup.SupplierAddress,
sup.SupplierPhone,
b.M_BranchName,
b.M_BranchAddress,
po.PurchaseOrderNumber,
kj.T_KontrakJasaJenisKontrak AS JenisKontrak,
kj.T_KontrakJasaStartDate AS StartDate,
kj.T_KontrakJasaEndDate AS EndDate,
kj.T_KontrakJasaJumlahPI AS JumlahPI,
kj.T_KontrakJasaUsedCount AS UsedCount
FROM receive_order_po ro
JOIN receive_order_po_detail rod ON rod.ReceiveOrderPoDetailReceiveOrderPoID = ro.ReceiveOrderPoID
AND rod.ReceiveOrderPoDetailIsActive = 'Y'
LEFT JOIN purchase_order po ON po.PurchaseOrderID = rod.ReceiveOrderPoDetailPurchaseOrderID
LEFT JOIN supplier sup ON sup.SupplierID = ro.ReceiveOrderPoSupplierID
LEFT JOIN t_kontrak_jasa kj ON kj.T_KontrakJasaPurchaseOrderID = rod.ReceiveOrderPoDetailPurchaseOrderID
AND kj.T_KontrakJasaM_BranchCode = ro.ReceiveOrderPoM_BranchCode
AND kj.T_KontrakJasaIsActive = 'Y'
LEFT JOIN m_branch b ON b.M_BranchCode = ro.ReceiveOrderPoM_BranchCode
WHERE ro.ReceiveOrderPoIsActive = 'Y'
AND ro.ReceiveOrderPoID = ?
LIMIT 1
";
$qry = $this->db->query($sql, array($id));
if (!$qry || $qry->num_rows() === 0) {
$this->sys_error("Data Receive Order Jasa tidak ditemukan");
exit;
}
return $qry->row_array();
}
// =========================================================================
// DATABASE: Ambil data detail
// =========================================================================
private function _get_detail($id)
{
$sql = "
SELECT
rod.ReceiveOrderPoDetailID,
rod.ReceiveOrderPoDetailQty AS Qty,
rod.ReceiveOrderPoDetailPrice AS Price,
(rod.ReceiveOrderPoDetailQty * rod.ReceiveOrderPoDetailPrice) AS TotalPrice,
item.M_ItemCode,
item.M_ItemDesc,
iu.ItemUnitName,
iu.ItemUnitCode,
insp.OrderJasaInspeksiHasilPengerjaan AS HasilPengerjaan,
insp.OrderJasaInspeksiCatatanPengerjaan AS CatatanPengerjaan,
insp.OrderJasaInspeksiKesimpulan AS Kesimpulan,
insp.OrderJasaInspeksiCatatan AS CatatanKesimpulan,
insp.OrderJasaInspeksiPetugasPengerjaan AS Pekerja,
uP.M_UserUsername AS PemeriksaName
FROM receive_order_po_detail rod
JOIN m_item item ON item.M_ItemID = rod.ReceiveOrderPoItemID
AND item.M_ItemIsActive = 'Y'
LEFT JOIN itemunit iu ON iu.ItemUnitID = rod.ReceiveOrderPoItemUnitID
AND iu.ItemUnitIsActive = 'Y'
LEFT JOIN order_jasa_inspeksi insp ON insp.OrderJasaInspeksiReceiveOrderPoDetailID = rod.ReceiveOrderPoDetailID
AND insp.OrderJasaInspeksiIsActive = 'Y'
LEFT JOIN m_user uP ON uP.M_UserID = insp.OrderJasaInspeksiStaffPemeriksaID
WHERE rod.ReceiveOrderPoDetailIsActive = 'Y'
AND rod.ReceiveOrderPoDetailReceiveOrderPoID = ?
ORDER BY rod.ReceiveOrderPoDetailID 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, 'TANDA TERIMA JASA (RECEIVE ORDER SERVICE)', 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 = 28;
$valW = $halfW - $lblW - 4;
// ── Kolom Kiri ────────────────────────────────────────────────────────
$pdf->SetY($startY);
// Format Jenis Kontrak
$jenisKontrak = '-';
if (!empty($header['JenisKontrak'])) {
$jenisKontrak = ($header['JenisKontrak'] === 'once') ? 'Sekali Bayar (Once)' : 'Berkala (Recurring)';
}
// Periode kontrak
$periodeJasa = '-';
if (!empty($header['StartDate']) && $header['StartDate'] !== '0000-00-00') {
$periodeJasa = $this->_fmt_date($header['StartDate']) . ' s/d ' . $this->_fmt_date($header['EndDate']);
}
// Termin / usedcount
$terminInfo = '-';
if (intval($header['JumlahPI'] ?? 0) > 0) {
$terminInfo = "Termin ke-" . ($header['UsedCount'] ?? 0) . " dari " . $header['JumlahPI'];
}
$leftItems = array(
array('Nomor', $header['ReceiveOrderPoNumber'], true),
array('Tanggal', $this->_fmt_date($header['ReceiveOrderPoIDate']), false),
array('Cabang', $header['M_BranchName'] ?: '-', 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 (tanpa spasi vertikal)
if (!empty($header['ReceiveOrderPoNote'])) {
$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['ReceiveOrderPoNote'], 0, 'L');
}
$leftY = $pdf->GetY();
// ── Kolom Kanan ───────────────────────────────────────────────────────
$pdf->SetY($startY);
$rightX = 15 + $halfW;
$rightItems = array(
array('Supplier', $header['SupplierName'] ?: '-'),
array('Alamat Supplier', $header['SupplierAddress'] ?: '-'),
array('Telp Supplier', $header['SupplierPhone'] ?: '-'),
array('Jenis Kontrak', $jenisKontrak),
array('Periode Jasa', $periodeJasa),
array('Termin Realisasi', $terminInfo),
);
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);
if ($item[0] === 'Alamat Supplier') {
$pdf->MultiCell($valW, 5, $item[1], 0, 'L');
} else {
$pdf->Cell($valW, 5, $item[1], 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;
$header = $this->_header_data;
// ── Definisi kolom: [label, lebar, align] ─────────────────────────────
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
// 8 + 75 + 20 + 15 + 30 + 32 = 180
$cols = array(
array('No', 8, 'C'),
array('Nama', 75, 'L'),
array('Unit', 20, 'C'),
array('Qty', 15, 'C'),
array('Harga', 30, 'R'),
array('Total', 32, 'R'),
);
// Header kolom
$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) {
$pdf->Cell($c[1], 7, $c[0], 1, 0, 'C', true);
}
$pdf->Ln();
// Set lebar dan alignment kolom untuk metode Row()
$pdf->SetWidths(array_column($cols, 1));
$pdf->SetAligns(array_column($cols, 2));
// Baris data
$pdf->SetLineWidth(0.2); // border lebih tipis di data
$pdf->SetFont('Arial_Narrow', '', 8);
$pdf->SetFillColor(255, 255, 255);
$no = 1;
$totalPay = 0;
foreach ($details as $d) {
$row_data = array(
$no,
$d['M_ItemDesc'] ?: ($d['M_ItemCode'] ?: '-'),
$d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'),
$this->_fmt_qty($d['Qty']),
$this->_fmt_rp($d['Price']),
$this->_fmt_rp($d['TotalPrice']),
);
$pdf->Row($row_data);
$totalPay += floatval($d['TotalPrice']);
$no++;
}
// Baris TOTAL
$span = array_sum(array_column(array_slice($cols, 0, 5), 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[5][1], 7, $this->_fmt_rp($totalPay), 1, 0, 'R', true);
$pdf->Ln(8);
}
// =========================================================================
// PDF SECTION: Inspeksi & Verifikasi Jasa (Blok Terpisah)
// =========================================================================
private function _pdf_inspeksi($details)
{
$pdf = $this->_pdf;
$pageW = $this->_pageW;
// Cek apakah ada data inspeksi yang terisi
$hasInspeksi = false;
foreach ($details as $d) {
if (!empty($d['HasilPengerjaan']) || !empty($d['Kesimpulan']) || !empty($d['Pekerja'])) {
$hasInspeksi = true;
break;
}
}
if (!$hasInspeksi) {
return;
}
$pdf->Ln(2);
$pdf->SetFont('Arial_Narrow', 'B', 10);
$pdf->Cell($pageW, 6, 'DETAIL HASIL INSPEKSI & VERIFIKASI JASA', 0, 1, 'L');
$pdf->SetLineWidth(0.3);
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
$pdf->Ln(2);
$no = 1;
foreach ($details as $d) {
// Lewati jika item ini tidak memiliki data inspeksi sama sekali
if (empty($d['HasilPengerjaan']) && empty($d['Kesimpulan']) && empty($d['Pekerja'])) {
continue;
}
$pdf->SetFont('Arial_Narrow', 'B', 9);
$pdf->Cell($pageW, 5, $no . '. ' . ($d['M_ItemDesc'] ?: ($d['M_ItemCode'] ?: '-')), 0, 1, 'L');
// Indentasi isi detail inspeksi
$lblW = 32;
$valW = $pageW - $lblW - 4;
$items = array(
array('Petugas Pengerjaan', $d['Pekerja'] ?: '-'),
array('Staff Pemeriksa', $d['PemeriksaName'] ?: '-'),
array('Hasil Pengerjaan', $d['HasilPengerjaan'] ?: '-'),
array('Catatan Pengerjaan', $d['CatatanPengerjaan'] ?: '-'),
array('Kesimpulan Hasil', $d['Kesimpulan'] ?: '-'),
array('Catatan Pemeriksa', $d['CatatanKesimpulan'] ?: '-'),
);
foreach ($items as $item) {
$pdf->SetX(18); // Indent slightly to the right
$pdf->SetFont('Arial_Narrow', '', 9);
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
$pdf->Cell(4, 5, ':', 0, 0, 'C');
$pdf->MultiCell($valW, 5, $item[1], 0, 'L');
}
$pdf->Ln(2);
$pdf->SetDrawColor(200, 200, 200);
$pdf->SetLineWidth(0.1);
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
$pdf->Ln(2);
$pdf->SetDrawColor(0, 0, 0); // restore black
$no++;
}
}
// =========================================================================
// PDF SECTION: Syarat & Ketentuan
// =========================================================================
private function _pdf_terms()
{
$pdf = $this->_pdf;
$pageW = $this->_pageW;
$terms = array(
'Penerimaan pengerjaan jasa ini berdasarkan hasil verifikasi/inspeksi petugas di lapangan.',
'Tanda Terima Jasa (TTJ) ini sah untuk digunakan sebagai lampiran dokumen penagihan vendor.',
'Jika terdapat komplain/ketidaksesuaian hasil pengerjaan di kemudian hari, harap merujuk ke Berita Acara inspeksi.',
'Dokumen ini dicetak dan divalidasi secara otomatis melalui sistem ERP.'
);
$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, ',', '.');
}
// 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, ',', '.');
}
}

View File

@@ -216,11 +216,10 @@ class Rpt_receive_transfer extends MY_Controller
$pdf->SetY($startY);
$leftItems = array(
array('Nomor SJ', $header['SuratJalanNumber'], true),
array('Tanggal SJ', $this->_fmt_date($header['SuratJalanDate']), false),
array('Nomor', $header['SuratJalanNumber'], true),
array('Tanggal', $this->_fmt_date($header['SuratJalanDate']), false),
array('Tanggal Terima', $this->_fmt_date($header['SuratJalanReceivedDate']), false),
array('Gudang Terima', $header['ReceivedWarehouseName'] ?: '-', false),
array('Status', $header['SuratJalanStatus'], false),
);
foreach ($leftItems as $item) {
@@ -289,15 +288,14 @@ class Rpt_receive_transfer extends MY_Controller
// ── Definisi kolom: [label, lebar, align] ─────────────────────────────
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
// 8 + 59 + 20 + 20 + 20 + 17 + 36 = 180
// 8 + 95 + 20 + 20 + 20 + 17 = 180
$cols = array(
array('No', 8, 'C'),
array('Nama', 59, 'L'),
array('Nama', 95, 'L'),
array('Unit', 20, 'C'),
array('Qty Kirim', 20, 'R'),
array('Qty Terima', 20, 'R'),
array('Selisih', 17, 'R'),
array('No. PR / Ref', 36, 'L'),
);
// Header kolom
@@ -327,7 +325,6 @@ class Rpt_receive_transfer extends MY_Controller
$pdf->Cell($cols[3][1], 6, $this->_fmt_qty($qtyKirim), 1, 0, 'C');
$pdf->Cell($cols[4][1], 6, $this->_fmt_qty($qtyTerima), 1, 0, 'C');
$pdf->Cell($cols[5][1], 6, $this->_fmt_qty($selisih), 1, 0, 'C');
$pdf->Cell($cols[6][1], 6, $d['PurchaseRequestNumber'] ?: '-', 1, 0, 'L');
$pdf->Ln();
$no++;

View File

@@ -197,7 +197,7 @@ class Rpt_stock_request extends MY_Controller
array('Nomor', $header['PurchaseRequestNumber'], true),
array('Ref Nomor', $header['PurchaseRequestRefNumber'] ?: '-', false),
array('Tanggal', $this->_fmt_date($header['PurchaseRequestDate']), false),
array('Status', $header['PurchaseRequestStatus'], false),
array('Tanggal Approved', $this->_fmt_datetime($header['PurchaseRequestApprovedDate'])),
);
foreach ($leftItems as $item) {
@@ -205,7 +205,7 @@ class Rpt_stock_request extends MY_Controller
$pdf->SetFont('Arial_Narrow', '', 9);
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
$pdf->Cell(4, 5, ':', 0, 0, 'C');
if ($item[2]) {
if (isset($item[2]) && $item[2]) {
$pdf->SetFont('Arial_Narrow', 'B', 9);
} else {
$pdf->SetFont('Arial_Narrow', '', 9);
@@ -233,7 +233,6 @@ class Rpt_stock_request extends MY_Controller
array('Kategori', $header['itemCategoryName'] ?: '-'),
array('Dibuat Oleh', $header['CreatedByName']),
array('Disetujui Oleh', $header['ApprovedByName'] ?: '-'),
array('Tanggal Approved', $this->_fmt_datetime($header['PurchaseRequestApprovedDate'])),
);
foreach ($rightItems as $item) {

View File

@@ -204,7 +204,7 @@ class Rpt_stock_request_np extends MY_Controller
array('Nomor', $header['PurchaseRequestNumber'], true),
array('Ref Nomor', $header['PurchaseRequestRefNumber'] ?: '-', false),
array('Tanggal', $this->_fmt_date($header['PurchaseRequestDate']), false),
array('Status', $header['PurchaseRequestStatus'], false),
array('Tanggal Approved', $this->_fmt_datetime($header['PurchaseRequestApprovedDate'])),
);
foreach ($leftItems as $item) {
@@ -212,7 +212,7 @@ class Rpt_stock_request_np extends MY_Controller
$pdf->SetFont('Arial_Narrow', '', 9);
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
$pdf->Cell(4, 5, ':', 0, 0, 'C');
if ($item[2]) {
if (isset($item[2]) && $item[2]) {
$pdf->SetFont('Arial_Narrow', 'B', 9);
} else {
$pdf->SetFont('Arial_Narrow', '', 9);
@@ -240,7 +240,6 @@ class Rpt_stock_request_np extends MY_Controller
array('Kategori', $header['itemCategoryName'] ?: '-'),
array('Dibuat Oleh', $header['CreatedByName']),
array('Disetujui Oleh', $header['ApprovedByName'] ?: '-'),
array('Tanggal Approved', $this->_fmt_datetime($header['PurchaseRequestApprovedDate'])),
);
foreach ($rightItems as $item) {

View File

@@ -211,10 +211,9 @@ class Rpt_surat_jalan extends MY_Controller
$pdf->SetY($startY);
$leftItems = array(
array('Nomor SJ', $header['SuratJalanNumber'], true),
array('Tanggal SJ', $this->_fmt_date($header['SuratJalanDate']), false),
array('Nomor', $header['SuratJalanNumber'], true),
array('Tanggal', $this->_fmt_date($header['SuratJalanDate']), false),
array('No. Transfer', $header['SuratJalanT_GoodsTransferNum'] ?: '-', false),
array('Status', $header['SuratJalanStatus'], false),
);
foreach ($leftItems as $item) {
@@ -283,13 +282,12 @@ class Rpt_surat_jalan extends MY_Controller
// ── Definisi kolom: [label, lebar, align] ─────────────────────────────
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
// 8 + 62 + 20 + 20 + 42 + 28 = 180
// 8 + 104 + 20 + 20 + 28 = 180
$cols = array(
array('No', 8, 'C'),
array('Nama', 62, 'L'),
array('Nama', 104, 'L'),
array('Unit', 20, 'C'),
array('Qty Kirim', 20, 'R'),
array('No. PR / Ref', 42, 'L'),
array('Qty Diterima', 28, 'R'),
);
@@ -314,8 +312,7 @@ class Rpt_surat_jalan extends MY_Controller
$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['SuratJalanDetailQty']), 1, 0, 'C');
$pdf->Cell($cols[4][1], 6, $d['PurchaseRequestNumber'] ?: '-', 1, 0, 'L');
$pdf->Cell($cols[5][1], 6, $this->_fmt_qty($d['SuratJalanDetailQtyReceived']), 1, 0, 'C');
$pdf->Cell($cols[4][1], 6, $this->_fmt_qty($d['SuratJalanDetailQtyReceived']), 1, 0, 'C');
$pdf->Ln();
$no++;