Penambahan tombol PDF di Bukubesar, Neraca, Laba rugi, Neraca saldo, dan Data Barang

Format PDF tersimpan di library semua
This commit is contained in:
2026-06-13 16:03:15 +07:00
parent a371fe3bac
commit 36ad02a222
15 changed files with 2551 additions and 7 deletions
+329
View File
@@ -0,0 +1,329 @@
<?php
require_once(APPPATH . 'third_party/fpdf/fpdf.php');
class PDF extends FPDF
{
// ----------------------------------------------------------------
// PROPERTI HEADER
// ----------------------------------------------------------------
private $nama;
private $alamat;
private $logo;
// ----------------------------------------------------------------
// PROPERTI TABEL
// ----------------------------------------------------------------
private $isTable = false;
private $tableWidth = [];
private $tableHeader = [];
// Konfigurasi tabel A4 Portrait (lebar efektif = 190mm, margin 10+10)
// Tanggal : 22 | No Ref : 28 | Keterangan : 60 | Debit : 26 | Kredit : 26 | Saldo : 28 → TOTAL : 190
private $colWidths = [22, 28, 60, 26, 26, 28];
// ----------------------------------------------------------------
// PROPERTI INFO LAPORAN
// ----------------------------------------------------------------
private $namaAkun = '';
private $periodeStr = '';
// ----------------------------------------------------------------
// SETTER
// ----------------------------------------------------------------
public function setHeaderData($nama, $alamat, $logo = '')
{
$this->nama = $nama;
$this->alamat = $alamat;
$this->logo = $logo;
}
public function setInfoLaporan($namaAkun, $periodeStr)
{
$this->namaAkun = $namaAkun;
$this->periodeStr = $periodeStr;
}
public function setTableHeader($header, $width)
{
$this->tableHeader = $header;
$this->tableWidth = $width;
}
// ----------------------------------------------------------------
// HEADER HALAMAN
// ----------------------------------------------------------------
function Header()
{
// Lebar halaman A4 Portrait = 210mm (area cetak 10..200)
$pageRight = 200;
// Logo (opsional)
if (!empty($this->logo) && file_exists($this->logo)) {
$this->Image($this->logo, 10, 6, 18);
$this->SetXY(31, 10);
} else {
$this->SetXY(10, 10);
}
// Nama perusahaan
$this->SetFont('Arial', 'B', 12);
$this->Cell(0, 6, $this->nama, 0, 1, 'L');
// Alamat
$this->SetFont('Arial', '', 9);
$x = !empty($this->logo) && file_exists($this->logo) ? 31 : 10;
$this->SetX($x);
$this->Cell(0, 5, $this->alamat, 0, 1, 'L');
// Garis pemisah
$this->Ln(2);
$this->SetLineWidth(0.6);
$this->Line(10, $this->GetY(), $pageRight, $this->GetY());
$this->SetLineWidth(0.2);
$this->Line(10, $this->GetY() + 1, $pageRight, $this->GetY() + 1);
$this->Ln(5);
// Judul
$this->SetFont('Arial', 'B', 13);
$this->SetTextColor(245, 140, 0);
$this->Cell(0, 7, 'LAPORAN BUKU BESAR', 0, 1, 'C');
$this->SetTextColor(0, 0, 0);
// Periode
$this->SetFont('Arial', '', 10);
$this->Cell(0, 5, $this->periodeStr, 0, 1, 'C');
$this->Ln(3);
// Info akun & tanggal cetak
$colLabel = 35;
$colSep = 5;
$startX = ($this->GetPageWidth() - array_sum($this->colWidths)) / 2;
$this->SetX($startX);
$this->SetFont('Arial', 'B', 10);
$this->Cell($colLabel, 6, 'Akun');
$this->SetFont('Arial', '', 10);
$this->Cell($colSep, 6, ':');
$this->Cell(0, 6, $this->namaAkun, 0, 1);
$this->SetX($startX);
$this->SetFont('Arial', 'B', 10);
$this->Cell($colLabel, 6, 'Di Cetak Pada');
$this->SetFont('Arial', '', 10);
$this->Cell($colSep, 6, ':');
$this->Cell(0, 6, date('d-m-Y') . ' Jam ' . date('H:i:s'), 0, 1);
$this->Ln(3);
if ($this->isTable && !empty($this->tableHeader)) {
$this->_drawTableHeader();
}
}
// ----------------------------------------------------------------
// FOOTER HALAMAN
// ----------------------------------------------------------------
function Footer()
{
$this->SetY(-10);
$this->SetFont('Arial', 'I', 8);
$this->Cell(0, 5, 'Halaman ' . $this->PageNo(), 0, 0, 'C');
}
// ----------------------------------------------------------------
// HELPER: Gambar baris header tabel
// ----------------------------------------------------------------
private function _drawTableHeader()
{
$startX = ($this->GetPageWidth() - array_sum($this->colWidths)) / 2;
$this->SetX($startX);
$this->SetFillColor(245, 140, 0);
$this->SetTextColor(255, 255, 255);
$this->SetFont('Arial', 'B', 9);
foreach ($this->tableHeader as $k => $v) {
$this->Cell($this->tableWidth[$k], 8, $v, 1, 0, 'C', true);
}
$this->SetTextColor(0, 0, 0);
$this->Ln();
}
// ----------------------------------------------------------------
// TABEL BUKU BESAR
// ----------------------------------------------------------------
public function BukuBesarTable($result)
{
$header = ['Tanggal', 'No Ref', 'Keterangan', 'Debit', 'Kredit', 'Saldo'];
$this->isTable = true;
$this->setTableHeader($header, $this->colWidths);
// Header halaman pertama
$this->_drawTableHeader();
$startX = ($this->GetPageWidth() - array_sum($this->colWidths)) / 2;
$lineH = 5;
$this->SetFont('Arial', '', 9);
if (empty($result)) {
$this->SetX($startX);
$this->SetFont('Arial', 'B', 10);
$this->Cell(array_sum($this->colWidths), 8, 'Tidak ada data', 1, 1, 'C');
$this->isTable = false;
return;
}
$fill = false;
// Batas bawah A4 Portrait (297mm) dikurangi area footer
$pageBreakTrigger = 277;
foreach ($result as $row) {
// Hitung tinggi baris berdasar No Ref & Keterangan (keduanya MultiCell)
$nbRef = $this->NbLines($this->colWidths[1], $row['no_ref']);
$nbKet = $this->NbLines($this->colWidths[2], $row['keterangan']);
$nbLines = max(1, $nbRef, $nbKet);
$rowH = $nbLines * $lineH;
// Ganti halaman jika mendekati batas bawah
if ($this->GetY() + $rowH > $pageBreakTrigger) {
$this->AddPage('P', 'A4');
}
if ($fill) {
$this->SetFillColor(245, 245, 245);
}
$x = $startX;
$y = $this->GetY();
// Tanggal
$this->SetX($x);
$this->Cell($this->colWidths[0], $rowH, date('d-m-Y', strtotime($row['tanggal'])), 1, 0, 'C', $fill);
// No Ref (MultiCell)
$xRef = $this->GetX();
$offsetRef = ($rowH - $nbRef * $lineH) / 2;
// gambar border kotak dulu
$this->Rect($xRef, $y, $this->colWidths[1], $rowH, $fill ? 'DF' : 'D');
$this->SetXY($xRef, $y + $offsetRef);
$this->MultiCell($this->colWidths[1], $lineH, $row['no_ref'], 0, 'C', false);
// Keterangan (MultiCell)
$xKet = $xRef + $this->colWidths[1];
$offsetKet = ($rowH - $nbKet * $lineH) / 2;
$this->Rect($xKet, $y, $this->colWidths[2], $rowH, $fill ? 'DF' : 'D');
$this->SetXY($xKet, $y + $offsetKet);
$this->MultiCell($this->colWidths[2], $lineH, $row['keterangan'], 0, 'L', false);
// Kolom angka
$this->SetXY($xKet + $this->colWidths[2], $y);
$this->Cell($this->colWidths[3], $rowH, number_format($row['debit'], 2, ',', '.'), 1, 0, 'R', $fill);
$this->Cell($this->colWidths[4], $rowH, number_format($row['kredit'], 2, ',', '.'), 1, 0, 'R', $fill);
$this->Cell($this->colWidths[5], $rowH, number_format($row['saldo'], 2, ',', '.'), 1, 0, 'R', $fill);
$this->SetXY($x, $y + $rowH);
$fill = !$fill;
}
$this->isTable = false;
}
// ----------------------------------------------------------------
// BARIS TOTAL
// ----------------------------------------------------------------
public function BukuBesarTotal($totalDebit, $totalKredit, $saldo)
{
$startX = ($this->GetPageWidth() - array_sum($this->colWidths)) / 2;
$labelWidth = $this->colWidths[0] + $this->colWidths[1] + $this->colWidths[2];
$this->SetX($startX);
$this->SetFillColor(255, 204, 102);
$this->SetFont('Arial', 'B', 9);
$this->Cell($labelWidth, 8, 'TOTAL', 1, 0, 'C', true);
$this->Cell($this->colWidths[3], 8, number_format($totalDebit, 2, ',', '.'), 1, 0, 'R', true);
$this->Cell($this->colWidths[4], 8, number_format($totalKredit, 2, ',', '.'), 1, 0, 'R', true);
$this->Cell($this->colWidths[5], 8, number_format($saldo, 2, ',', '.'), 1, 1, 'R', true);
}
// ----------------------------------------------------------------
// TANDA TANGAN
// ----------------------------------------------------------------
public function Pembuat($nama, $jabatan = '')
{
$signWidth = 70;
$signX = 125; // disesuaikan untuk A4 Portrait (210mm)
$this->Ln(10);
$this->SetX($signX);
$this->SetFont('Arial', '', 10);
$this->Cell($signWidth, 6, 'Mengetahui,', 0, 1, 'C');
$this->Ln(10);
$this->SetX($signX);
$this->SetFont('Arial', 'B', 10);
$this->Cell($signWidth, 6, $nama, 0, 1, 'C');
if (!empty($jabatan)) {
$this->SetX($signX);
$this->SetFont('Arial', '', 9);
$this->Cell($signWidth, 5, '(' . $jabatan . ')', 0, 1, 'C');
}
}
// ----------------------------------------------------------------
// HELPER: Hitung jumlah baris MultiCell
// ----------------------------------------------------------------
private function NbLines($w, $txt)
{
$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", '', (string)$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 += isset($cw[ord($c)]) ? $cw[ord($c)] : 600;
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;
}
}