247 lines
10 KiB
PHP
247 lines
10 KiB
PHP
<?php
|
||
// api/export_pdf.php v2.0
|
||
// ============================================================
|
||
// Export Laporan PDF menggunakan HTML → browser print
|
||
// (Pure PHP, tanpa library eksternal)
|
||
// ============================================================
|
||
require_once __DIR__ . '/../includes/config.php';
|
||
|
||
$db = getDB();
|
||
|
||
// ── Filter ────────────────────────────────────────────────
|
||
$kelurahan = $_GET['kelurahan'] ?? null;
|
||
$kecamatan = $_GET['kecamatan'] ?? null;
|
||
$kategori = $_GET['kategori'] ?? null;
|
||
$verifikasi = $_GET['verifikasi'] ?? null;
|
||
|
||
$where = "WHERE 1=1";
|
||
$params = [];
|
||
if ($kelurahan) { $where .= " AND w.kelurahan = ?"; $params[] = $kelurahan; }
|
||
if ($kecamatan) { $where .= " AND w.kecamatan = ?"; $params[] = $kecamatan; }
|
||
if ($kategori) { $where .= " AND pm.kategori_kemiskinan = ?"; $params[] = $kategori; }
|
||
if ($verifikasi) { $where .= " AND pm.status_verifikasi = ?"; $params[] = $verifikasi; }
|
||
|
||
// Data penduduk
|
||
$stmt = $db->prepare("
|
||
SELECT pm.nik_kk, pm.nama_kk, pm.no_hp, pm.alamat, pm.rt, pm.rw,
|
||
COALESCE(w.kelurahan,'–') AS kelurahan,
|
||
pm.jumlah_anggota, pm.jumlah_anak_sekolah,
|
||
pm.penghasilan_bulanan, pm.status_pekerjaan,
|
||
pm.kategori_kemiskinan, pm.kondisi_rumah,
|
||
CASE pm.punya_bpjs WHEN 1 THEN 'Ya' ELSE 'Tidak' END AS punya_bpjs,
|
||
pm.status_verifikasi,
|
||
(SELECT GROUP_CONCAT(jb.kode ORDER BY jb.kode SEPARATOR ', ')
|
||
FROM bantuan_penduduk bp JOIN jenis_bantuan jb ON jb.id = bp.bantuan_id
|
||
WHERE bp.penduduk_id = pm.id AND bp.status='aktif') AS bantuan
|
||
FROM penduduk_miskin pm
|
||
LEFT JOIN wilayah w ON w.id = pm.wilayah_id
|
||
$where
|
||
ORDER BY w.kelurahan, pm.kategori_kemiskinan, pm.nama_kk
|
||
");
|
||
$stmt->execute($params);
|
||
$rows = $stmt->fetchAll();
|
||
|
||
// Statistik ringkas
|
||
$statsStmt = $db->prepare("
|
||
SELECT COUNT(*) AS total, SUM(pm.jumlah_anggota) AS jiwa,
|
||
SUM(CASE WHEN pm.kategori_kemiskinan='sangat_miskin' THEN 1 ELSE 0 END) AS sangat_miskin,
|
||
SUM(CASE WHEN pm.kategori_kemiskinan='miskin' THEN 1 ELSE 0 END) AS miskin,
|
||
SUM(CASE WHEN pm.kategori_kemiskinan='hampir_miskin' THEN 1 ELSE 0 END) AS hampir_miskin,
|
||
SUM(CASE WHEN pm.kategori_kemiskinan='mampu' THEN 1 ELSE 0 END) AS mampu,
|
||
SUM(CASE WHEN EXISTS(SELECT 1 FROM bantuan_penduduk bp WHERE bp.penduduk_id=pm.id AND bp.status='aktif') THEN 1 ELSE 0 END) AS penerima
|
||
FROM penduduk_miskin pm LEFT JOIN wilayah w ON w.id = pm.wilayah_id $where
|
||
");
|
||
$statsStmt->execute($params);
|
||
$stats = $statsStmt->fetch();
|
||
|
||
$judul = "LAPORAN DATA PENDUDUK MISKIN";
|
||
$filter = $kelurahan ? " – Kelurahan $kelurahan" : ($kecamatan ? " – Kec. $kecamatan" : " – Seluruh Wilayah");
|
||
$tgl = date('d F Y');
|
||
|
||
// Warna kategori
|
||
function warnaBg(string $k): string {
|
||
return match($k) {
|
||
'sangat_miskin' => '#fee2e2',
|
||
'miskin' => '#fef3c7',
|
||
'hampir_miskin' => '#dcfce7',
|
||
'mampu' => '#dbeafe',
|
||
default => '#f3f4f6',
|
||
};
|
||
}
|
||
function labelKat(string $k): string {
|
||
return match($k) {
|
||
'sangat_miskin' => 'Sangat Miskin',
|
||
'miskin' => 'Miskin',
|
||
'hampir_miskin' => 'Nyaris Miskin',
|
||
'mampu' => 'Mampu',
|
||
default => $k,
|
||
};
|
||
}
|
||
?>
|
||
<!DOCTYPE html>
|
||
<html lang="id">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<title><?= htmlspecialchars($judul . $filter) ?></title>
|
||
<style>
|
||
@page { size: A4 landscape; margin: 15mm 10mm; }
|
||
@media print {
|
||
.no-print { display: none; }
|
||
body { font-size: 8pt; }
|
||
table { font-size: 7.5pt; }
|
||
thead { display: table-header-group; }
|
||
}
|
||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||
body { font-family: Arial, sans-serif; font-size: 9pt; color: #111; background: #fff; }
|
||
|
||
/* Header laporan */
|
||
.kop { text-align: center; border-bottom: 3px double #1e3a5f; padding-bottom: 10px; margin-bottom: 14px; }
|
||
.kop h1 { font-size: 13pt; font-weight: 900; text-transform: uppercase; color: #1e3a5f; }
|
||
.kop h2 { font-size: 11pt; font-weight: 700; margin: 2px 0; }
|
||
.kop p { font-size: 8pt; color: #555; }
|
||
|
||
/* Statistik */
|
||
.stat-grid { display: flex; gap: 8px; margin-bottom: 14px; }
|
||
.stat-box {
|
||
flex: 1; border: 1px solid #ddd; border-radius: 6px;
|
||
padding: 7px 10px; text-align: center; background: #f8faff;
|
||
}
|
||
.stat-box .val { font-size: 16pt; font-weight: 900; color: #1e3a5f; }
|
||
.stat-box .lbl { font-size: 7pt; color: #666; text-transform: uppercase; }
|
||
|
||
/* Tabel */
|
||
table { width: 100%; border-collapse: collapse; margin-top: 4px; }
|
||
th { background: #1e3a5f; color: #fff; padding: 5px 4px; text-align: center; font-size: 7.5pt; border: 1px solid #1e3a5f; }
|
||
td { padding: 4px; border: 1px solid #ddd; vertical-align: top; font-size: 7.5pt; }
|
||
tr:nth-child(even) td { background: #f9fafb; }
|
||
.badge-sm {
|
||
display: inline-block; padding: 1px 5px; border-radius: 3px;
|
||
font-size: 6.5pt; font-weight: bold;
|
||
}
|
||
.c { text-align: center; }
|
||
.r { text-align: right; }
|
||
|
||
/* Footer */
|
||
.footer { margin-top: 20px; display: flex; justify-content: space-between; font-size: 8pt; }
|
||
.ttd-box { text-align: center; width: 200px; }
|
||
.ttd-box .line { border-top: 1px solid #111; margin-top: 50px; padding-top: 3px; font-weight: bold; }
|
||
|
||
/* Print button */
|
||
.no-print { text-align: center; margin: 12px 0; }
|
||
.btn-print {
|
||
background: #1e3a5f; color: #fff; border: none; padding: 8px 24px;
|
||
border-radius: 5px; font-size: 10pt; cursor: pointer; margin-right: 8px;
|
||
}
|
||
.btn-print:hover { background: #274e81; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<!-- Print Button -->
|
||
<div class="no-print">
|
||
<button class="btn-print" onclick="window.print()">🖨 Cetak / Simpan PDF</button>
|
||
<button class="btn-print" style="background:#555;" onclick="window.close()">✕ Tutup</button>
|
||
</div>
|
||
|
||
<!-- Kop Surat -->
|
||
<div class="kop">
|
||
<h1><?= htmlspecialchars($judul) ?></h1>
|
||
<h2>SISTEM INFORMASI GEOGRAFIS KEMISKINAN<?= htmlspecialchars($filter) ?></h2>
|
||
<p>Dicetak pada: <?= $tgl ?> | Total: <?= count($rows) ?> KK</p>
|
||
</div>
|
||
|
||
<!-- Statistik Ringkas -->
|
||
<div class="stat-grid">
|
||
<div class="stat-box"><div class="val"><?= number_format($stats['total']) ?></div><div class="lbl">Total KK</div></div>
|
||
<div class="stat-box"><div class="val"><?= number_format($stats['jiwa']) ?></div><div class="lbl">Total Jiwa</div></div>
|
||
<div class="stat-box" style="background:#fee2e2"><div class="val"><?= number_format($stats['sangat_miskin']) ?></div><div class="lbl">Sangat Miskin</div></div>
|
||
<div class="stat-box" style="background:#fef3c7"><div class="val"><?= number_format($stats['miskin']) ?></div><div class="lbl">Miskin</div></div>
|
||
<div class="stat-box" style="background:#dcfce7"><div class="val"><?= number_format($stats['hampir_miskin']) ?></div><div class="lbl">Nyaris Miskin</div></div>
|
||
<div class="stat-box" style="background:#dbeafe"><div class="val"><?= number_format($stats['mampu']) ?></div><div class="lbl">Mampu</div></div>
|
||
<div class="stat-box"><div class="val"><?= number_format($stats['penerima']) ?></div><div class="lbl">Penerima Bantuan</div></div>
|
||
<div class="stat-box" style="background:#fff7ed"><div class="val"><?= number_format($stats['total'] - $stats['penerima']) ?></div><div class="lbl">Belum Bantuan</div></div>
|
||
</div>
|
||
|
||
<!-- Tabel Data -->
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th style="width:2%">No</th>
|
||
<th style="width:11%">NIK / Nama KK</th>
|
||
<th style="width:6%">Kelurahan</th>
|
||
<th style="width:4%">RT/RW</th>
|
||
<th style="width:13%">Alamat</th>
|
||
<th style="width:3%">Angg.</th>
|
||
<th style="width:3%">Anak</th>
|
||
<th style="width:7%">Penghasilan</th>
|
||
<th style="width:7%">Pekerjaan</th>
|
||
<th style="width:8%">Kategori</th>
|
||
<th style="width:7%">Kondisi Rumah</th>
|
||
<th style="width:4%">BPJS</th>
|
||
<th style="width:11%">Bantuan Diterima</th>
|
||
<th style="width:10%">Status Verifikasi</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<?php $no = 1; foreach ($rows as $r): ?>
|
||
<tr>
|
||
<td class="c"><?= $no++ ?></td>
|
||
<td>
|
||
<small style="color:#666"><?= htmlspecialchars($r['nik_kk']) ?></small><br>
|
||
<strong><?= htmlspecialchars($r['nama_kk']) ?></strong><br>
|
||
<small><?= htmlspecialchars($r['no_hp'] ?? '–') ?></small>
|
||
</td>
|
||
<td class="c"><?= htmlspecialchars($r['kelurahan']) ?></td>
|
||
<td class="c"><?= ($r['rt'] ? $r['rt'].'/'.$r['rw'] : '–') ?></td>
|
||
<td><?= htmlspecialchars($r['alamat'] ?? '–') ?></td>
|
||
<td class="c"><?= $r['jumlah_anggota'] ?></td>
|
||
<td class="c"><?= $r['jumlah_anak_sekolah'] ?></td>
|
||
<td class="r"><?= $r['penghasilan_bulanan'] ? 'Rp '.number_format($r['penghasilan_bulanan'],0,',','.') : '–' ?></td>
|
||
<td><?= htmlspecialchars(ucwords(str_replace('_',' ',$r['status_pekerjaan']))) ?></td>
|
||
<td class="c">
|
||
<span class="badge-sm" style="background:<?= warnaBg($r['kategori_kemiskinan']) ?>">
|
||
<?= labelKat($r['kategori_kemiskinan']) ?>
|
||
</span>
|
||
</td>
|
||
<td class="c"><?= htmlspecialchars(ucwords(str_replace('_',' ',$r['kondisi_rumah']))) ?></td>
|
||
<td class="c"><?= $r['punya_bpjs'] ?></td>
|
||
<td>
|
||
<?php if ($r['bantuan']): ?>
|
||
<?php foreach (explode(', ', $r['bantuan']) as $b): ?>
|
||
<span class="badge-sm" style="background:#dbeafe;color:#1e40af"><?= htmlspecialchars(trim($b)) ?></span>
|
||
<?php endforeach; ?>
|
||
<?php else: ?>
|
||
<span style="color:#dc2626">Belum Ada</span>
|
||
<?php endif; ?>
|
||
</td>
|
||
<td class="c">
|
||
<?php
|
||
$sv = $r['status_verifikasi'];
|
||
$svColor = match($sv) { 'terverifikasi'=>'#dcfce7', 'belum_diverifikasi'=>'#fef3c7', default=>'#fee2e2' };
|
||
?>
|
||
<span class="badge-sm" style="background:<?= $svColor ?>">
|
||
<?= htmlspecialchars(ucwords(str_replace('_',' ',$sv))) ?>
|
||
</span>
|
||
</td>
|
||
</tr>
|
||
<?php endforeach; ?>
|
||
</tbody>
|
||
</table>
|
||
|
||
<!-- Footer / TTD -->
|
||
<div class="footer">
|
||
<div>
|
||
<p>Dicetak: <?= date('d/m/Y H:i') ?> WIB</p>
|
||
<p>Filter: <?= htmlspecialchars(implode(', ', array_filter([$kelurahan, $kecamatan, $kategori ? "Kategori: $kategori" : null])) ?: 'Semua Data') ?></p>
|
||
<p>Sumber: SIG Kemiskinan v2.0</p>
|
||
</div>
|
||
<div class="ttd-box">
|
||
<p>Pontianak, <?= $tgl ?></p>
|
||
<p>Mengetahui,</p>
|
||
<div class="line">Kepala Dinas / Pejabat Berwenang</div>
|
||
</div>
|
||
</div>
|
||
|
||
</body>
|
||
</html>
|