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
+296
View File
@@ -0,0 +1,296 @@
<?php
require_once(APPPATH . 'third_party/fpdf/fpdf.php');
class PDF extends FPDF
{
private $nama;
private $alamat;
private $logo;
private $periodeStr = '';
private $colWidths = [15, 47, 23];
private $gap = 10;
public function setHeaderData($nama, $alamat, $logo = '')
{
$this->nama = $nama;
$this->alamat = $alamat;
$this->logo = $logo;
}
public function setInfoLaporan($periodeStr)
{
$this->periodeStr = $periodeStr;
}
function Header()
{
if (!empty($this->logo) && file_exists($this->logo)) {
$this->Image($this->logo, 10, 6, 18);
$this->SetXY(31, 10);
} else {
$this->SetXY(10, 10);
}
$this->SetFont('Arial', 'B', 12);
$this->Cell(0, 6, $this->nama, 0, 1, 'L');
$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');
$this->Ln(2);
$this->SetLineWidth(0.6);
$this->Line(10, $this->GetY(), 200, $this->GetY());
$this->SetLineWidth(0.2);
$this->Line(10, $this->GetY() + 1, 200, $this->GetY() + 1);
$this->Ln(5);
$this->SetFont('Arial', 'B', 13);
$this->SetTextColor(245, 140, 0);
$this->Cell(0, 7, 'LAPORAN NERACA', 0, 1, 'C');
$this->SetTextColor(0, 0, 0);
$this->SetFont('Arial', '', 10);
$this->Cell(0, 5, $this->periodeStr, 0, 1, 'C');
$this->SetFont('Arial', '', 9);
$this->Cell(0, 5, 'Di Cetak Pada : ' . date('d-m-Y') . ' - ' . date('H:i:s'), 0, 1, 'C');
$this->Ln(4);
$this->_drawSectionHeader();
}
function Footer()
{
$this->SetY(-10);
$this->SetFont('Arial', 'I', 8);
$this->Cell(0, 5, 'Halaman ' . $this->PageNo(), 0, 0, 'C');
}
private function _drawSectionHeader()
{
$startX = $this->_startX();
$tableW = array_sum($this->colWidths);
$this->SetX($startX);
$this->SetFillColor(245, 140, 0);
$this->SetTextColor(255, 255, 255);
$this->SetFont('Arial', 'B', 10);
$this->Cell($tableW, 7, 'ACTIVA', 1, 0, 'C', true);
$this->SetX($startX + $tableW + $this->gap);
$this->Cell($tableW, 7, 'PASIVA', 1, 1, 'C', true);
$this->SetFont('Arial', 'B', 8);
$this->SetFillColor(255, 224, 178);
$this->SetTextColor(0, 0, 0);
$this->SetX($startX);
$this->Cell($this->colWidths[0], 6, 'Kode', 1, 0, 'C', true);
$this->Cell($this->colWidths[1], 6, 'Nama Akun', 1, 0, 'C', true);
$this->Cell($this->colWidths[2], 6, 'Saldo', 1, 0, 'C', true);
$this->SetX($startX + $tableW + $this->gap);
$this->Cell($this->colWidths[0], 6, 'Kode', 1, 0, 'C', true);
$this->Cell($this->colWidths[1], 6, 'Nama Akun', 1, 0, 'C', true);
$this->Cell($this->colWidths[2], 6, 'Saldo', 1, 1, 'C', true);
}
private function _startX()
{
$totalW = (array_sum($this->colWidths) * 2) + $this->gap;
return ($this->GetPageWidth() - $totalW) / 2;
}
/**
* Hitung jumlah baris yang dibutuhkan MultiCell untuk teks tertentu
* pada lebar kolom $w. Diadaptasi dari contoh resmi FPDF.
*/
private function _nbLines($w, $txt)
{
if ($txt === null || $txt === '') return 1;
$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[$c]) ? $cw[$c] : 0;
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;
}
/**
* Render satu baris (kiri+kanan) dengan tinggi sama,
* memakai MultiCell untuk kolom Nama Akun.
*/
private function _drawRow($activaRow, $pasivaRow, $startX, $rightX, $lineH)
{
$wNama = $this->colWidths[1];
$nlA = $activaRow ? $this->_nbLines($wNama, $activaRow['nama']) : 1;
$nlB = $pasivaRow ? $this->_nbLines($wNama, $pasivaRow['nama']) : 1;
$nl = max($nlA, $nlB, 1);
$h = $lineH * $nl;
// page break manual agar baris tidak terpotong
if ($this->GetY() + $h > $this->PageBreakTrigger) {
$this->AddPage($this->CurOrientation);
}
$y = $this->GetY();
// ---------- ACTIVA ----------
$this->SetXY($startX, $y);
if ($activaRow) {
// Kode (auto vertical-center karena pakai Cell dengan tinggi $h)
$this->Cell($this->colWidths[0], $h, $activaRow['kode'], 1, 0, 'C');
// Nama (MultiCell) — vertical center manual
$xNama = $this->GetX();
$this->Rect($xNama, $y, $wNama, $h);
$nLines = $this->_nbLines($wNama, $activaRow['nama']);
$offsetY = ($h - $lineH * $nLines) / 2;
$this->SetXY($xNama, $y + $offsetY);
$this->MultiCell($wNama, $lineH, $activaRow['nama'], 0, 'L');
// Saldo
$this->SetXY($xNama + $wNama, $y);
$this->Cell($this->colWidths[2], $h, number_format($activaRow['saldo'], 0, ',', '.'), 1, 0, 'R');
} else {
$this->Cell($this->colWidths[0], $h, '', 1, 0);
$this->Cell($wNama, $h, '', 1, 0);
$this->Cell($this->colWidths[2], $h, '', 1, 0);
}
// ---------- PASIVA ----------
$this->SetXY($rightX, $y);
if ($pasivaRow) {
$this->Cell($this->colWidths[0], $h, $pasivaRow['kode'], 1, 0, 'C');
$xNama = $this->GetX();
$this->Rect($xNama, $y, $wNama, $h);
$nLines = $this->_nbLines($wNama, $pasivaRow['nama']);
$offsetY = ($h - $lineH * $nLines) / 2;
$this->SetXY($xNama, $y + $offsetY);
$this->MultiCell($wNama, $lineH, $pasivaRow['nama'], 0, 'L');
$this->SetXY($xNama + $wNama, $y);
$this->Cell($this->colWidths[2], $h, number_format($pasivaRow['saldo'], 0, ',', '.'), 1, 0, 'R');
} else {
$this->Cell($this->colWidths[0], $h, '', 1, 0);
$this->Cell($wNama, $h, '', 1, 0);
$this->Cell($this->colWidths[2], $h, '', 1, 0);
}
// pindah ke baris berikutnya
$this->SetXY($startX, $y + $h);
}
public function NeracaTable($activa, $pasiva, $totalActiva, $totalPasiva)
{
$startX = $this->_startX();
$tableW = array_sum($this->colWidths);
$rightX = $startX + $tableW + $this->gap;
$lineH = 5;
$this->SetFont('Arial', '', 8);
$maxRow = max(count($activa), count($pasiva));
for ($i = 0; $i < $maxRow; $i++) {
$this->_drawRow(
isset($activa[$i]) ? $activa[$i] : null,
isset($pasiva[$i]) ? $pasiva[$i] : null,
$startX, $rightX, $lineH
);
}
// ---- BARIS TOTAL ----
if ($this->GetY() + 8 > $this->PageBreakTrigger) {
$this->AddPage('P', 'A4');
}
$y = $this->GetY();
$this->SetFont('Arial', 'B', 8);
$this->SetFillColor(255, 204, 102);
$this->SetXY($startX, $y);
$this->Cell($this->colWidths[0] + $this->colWidths[1], 7, 'TOTAL ACTIVA', 1, 0, 'C', true);
$this->Cell($this->colWidths[2], 7, number_format($totalActiva, 0, ',', '.'), 1, 0, 'R', true);
$this->SetXY($rightX, $y);
$this->Cell($this->colWidths[0] + $this->colWidths[1], 7, 'TOTAL PASIVA', 1, 0, 'C', true);
$this->Cell($this->colWidths[2], 7, number_format($totalPasiva, 0, ',', '.'), 1, 1, 'R', true);
}
public function NeracaRingkasan($laba, $selisih)
{
$startX = $this->_startX();
$tableW = array_sum($this->colWidths) * 2 + $this->gap;
$labelW = $tableW - 40;
$this->Ln(4);
$this->SetX($startX);
$this->SetFont('Arial', 'B', 9);
$this->Cell($labelW, 7, 'Laba Rugi Berjalan', 1, 0, 'L');
$this->SetFont('Arial', '', 9);
$this->Cell(40, 7, number_format($laba, 0, ',', '.'), 1, 1, 'R');
$this->SetX($startX);
$this->SetFont('Arial', 'B', 9);
if (abs($selisih) < 1) {
$this->SetFillColor(198, 239, 206);
$label = 'Selisih (Balance)';
} else {
$this->SetFillColor(255, 199, 206);
$label = 'Selisih (Tidak Balance)';
}
$this->Cell($labelW, 7, $label, 1, 0, 'L', true);
$this->Cell(40, 7, number_format($selisih, 0, ',', '.'), 1, 1, 'R', true);
}
public function Pembuat($nama, $jabatan = '')
{
$startX = $this->_startX();
$tableW = array_sum($this->colWidths) * 2 + $this->gap;
$signWidth = 70;
$signX = $startX + $tableW - $signWidth;
$this->Ln(15);
$this->SetX($signX);
$this->SetFont('Arial', '', 10);
$this->Cell($signWidth, 6, 'Mengetahui,', 0, 1, 'R');
$this->Ln(18);
$this->SetX($signX);
$this->SetFont('Arial', 'B', 10);
$this->Cell($signWidth, 6, $nama, 0, 1, 'R');
if (!empty($jabatan)) {
$this->SetX($signX);
$this->SetFont('Arial', '', 9);
$this->Cell($signWidth, 5, '(' . $jabatan . ')', 0, 1, 'R');
}
}
}