first commit
This commit is contained in:
419
iklim_kerja_suhu_report_generator.php
Normal file
419
iklim_kerja_suhu_report_generator.php
Normal file
@@ -0,0 +1,419 @@
|
||||
<?php
|
||||
/**
|
||||
* Iklim Kerja Suhu Report Generator
|
||||
*
|
||||
* Script untuk menghasilkan laporan pengukuran iklim kerja suhu
|
||||
* berdasarkan PMK RI No.2 Tahun 2023
|
||||
*/
|
||||
|
||||
// Konfigurasi database
|
||||
$db_config = [
|
||||
'host' => 'localhost',
|
||||
'username' => 'root',
|
||||
'password' => '',
|
||||
'database' => 'lab_lingkungan_db'
|
||||
];
|
||||
|
||||
// Koneksi ke database
|
||||
function connectDB($config) {
|
||||
try {
|
||||
$conn = new PDO(
|
||||
"mysql:host={$config['host']};dbname={$config['database']}",
|
||||
$config['username'],
|
||||
$config['password']
|
||||
);
|
||||
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
return $conn;
|
||||
} catch(PDOException $e) {
|
||||
die("Koneksi database gagal: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Ambil data laporan berdasarkan ID
|
||||
function getLaporanData($conn, $laporan_id) {
|
||||
$query = "
|
||||
SELECT
|
||||
l.*,
|
||||
p.nama_pelanggan, p.alamat, p.kota, p.provinsi, p.kode_pos,
|
||||
ps.nama AS petugas_sampling,
|
||||
DATE_FORMAT(l.tanggal_pengukuran, '%d %M %Y') AS tanggal_pengukuran_format,
|
||||
DATE_FORMAT(l.tanggal_terbit, '%d %M %Y') AS tanggal_terbit_format
|
||||
FROM
|
||||
laporan_hasil_uji l
|
||||
JOIN
|
||||
master_pelanggan p ON l.pelanggan_id = p.pelanggan_id
|
||||
JOIN
|
||||
master_personel ps ON l.petugas_id = ps.personel_id
|
||||
WHERE
|
||||
l.laporan_id = :laporan_id
|
||||
";
|
||||
|
||||
$stmt = $conn->prepare($query);
|
||||
$stmt->execute(['laporan_id' => $laporan_id]);
|
||||
return $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
// Ambil data hasil pengukuran
|
||||
function getHasilPengukuran($conn, $laporan_id) {
|
||||
$query = "
|
||||
SELECT
|
||||
h.*,
|
||||
ls.nama_lokasi,
|
||||
p.nama_parameter, p.satuan,
|
||||
nab.nilai_minimal, nab.nilai_maksimal, nab.tipe_ruangan,
|
||||
e.nama_peralatan, e.merk, e.model, e.nomor_seri
|
||||
FROM
|
||||
hasil_pengukuran_suhu h
|
||||
JOIN
|
||||
master_lokasi_sampling ls ON h.lokasi_id = ls.lokasi_id
|
||||
JOIN
|
||||
master_parameter p ON h.parameter_id = p.parameter_id
|
||||
JOIN
|
||||
master_nilai_ambang_batas nab ON h.nab_id = nab.nab_id
|
||||
JOIN
|
||||
master_peralatan e ON h.peralatan_id = e.peralatan_id
|
||||
WHERE
|
||||
h.laporan_id = :laporan_id
|
||||
ORDER BY
|
||||
h.hasil_id ASC
|
||||
";
|
||||
|
||||
$stmt = $conn->prepare($query);
|
||||
$stmt->execute(['laporan_id' => $laporan_id]);
|
||||
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
// Ambil data personel untuk tanda tangan
|
||||
function getPersonelData($conn, $personel_id) {
|
||||
$query = "
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
master_personel
|
||||
WHERE
|
||||
personel_id = :personel_id
|
||||
";
|
||||
|
||||
$stmt = $conn->prepare($query);
|
||||
$stmt->execute(['personel_id' => $personel_id]);
|
||||
return $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
// Generate HTML laporan
|
||||
function generateLaporanHTML($laporan, $hasil_pengukuran, $verifikator, $penguji) {
|
||||
ob_start();
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Laporan Hasil Uji Iklim Kerja Suhu</title>
|
||||
<style>
|
||||
@page {
|
||||
size: A4;
|
||||
margin: 1cm;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 12pt;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 21cm;
|
||||
margin: 0 auto;
|
||||
padding: 0.5cm;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.header {
|
||||
position: relative;
|
||||
border-bottom: 2px solid #000;
|
||||
padding-bottom: 10px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.report-number {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
text-align: right;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
.company-code {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
text-align: right;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
.page-number {
|
||||
position: absolute;
|
||||
top: 50px;
|
||||
right: 0;
|
||||
font-size: 72pt;
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.report-title {
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.report-title h1 {
|
||||
font-size: 16pt;
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.report-subtitle {
|
||||
font-size: 12pt;
|
||||
margin: 5px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.client-info {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.client-info-row {
|
||||
display: flex;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.client-info-label {
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
.client-info-colon {
|
||||
width: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.measurement-title {
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
table, th, td {
|
||||
border: 1px solid #000;
|
||||
}
|
||||
|
||||
th, td {
|
||||
padding: 8px;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
th {
|
||||
background-color: #fff;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.reference-header {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.issue-date {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.notes {
|
||||
margin-top: 20px;
|
||||
border: 1px solid #000;
|
||||
padding: 10px;
|
||||
min-height: 100px;
|
||||
}
|
||||
|
||||
.signatures {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.signature-box {
|
||||
width: 30%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.signature-line {
|
||||
margin-top: 80px;
|
||||
border-top: 1px solid #000;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
@media print {
|
||||
.container {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@page {
|
||||
size: A4;
|
||||
margin: 1cm;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="company-code">Kode Lab: FLHU/<?php echo date('y'); ?>/<?php echo date('m'); ?>/<?php echo sprintf('%03d', $laporan['laporan_id']); ?></div>
|
||||
|
||||
<div class="report-title">
|
||||
<h1>LAPORAN HASIL UJI</h1>
|
||||
<p class="report-subtitle">NO : <?php echo $laporan['nomor_laporan']; ?></p>
|
||||
</div>
|
||||
|
||||
<div class="page-number">2</div>
|
||||
|
||||
<div class="client-info">
|
||||
<div class="client-info-row">
|
||||
<div class="client-info-label">Nama Pelanggan</div>
|
||||
<div class="client-info-colon">:</div>
|
||||
<div class="client-info-value"><?php echo $laporan['nama_pelanggan']; ?></div>
|
||||
</div>
|
||||
<div class="client-info-row">
|
||||
<div class="client-info-label">Alamat pelanggan</div>
|
||||
<div class="client-info-colon">:</div>
|
||||
<div class="client-info-value"><?php echo $laporan['alamat'] . ', ' . $laporan['kota'] . ', ' . $laporan['provinsi'] . ' ' . $laporan['kode_pos']; ?></div>
|
||||
</div>
|
||||
<div class="client-info-row">
|
||||
<div class="client-info-label">Petugas sampling</div>
|
||||
<div class="client-info-colon">:</div>
|
||||
<div class="client-info-value"><?php echo $laporan['petugas_sampling']; ?></div>
|
||||
</div>
|
||||
<div class="client-info-row">
|
||||
<div class="client-info-label">Tanggal pengukuran</div>
|
||||
<div class="client-info-colon">:</div>
|
||||
<div class="client-info-value"><?php echo $laporan['tanggal_pengukuran_format']; ?></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="measurement-title">
|
||||
Hasil Pengujian Iklim Kerja Suhu
|
||||
</div>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th rowspan="2">No</th>
|
||||
<th rowspan="2">Lokasi Pengukuran</th>
|
||||
<th rowspan="2">Kode sampel</th>
|
||||
<th rowspan="2">Waktu<br>Pengukuran</th>
|
||||
<th rowspan="2">Hasil</th>
|
||||
<th rowspan="2">Satuan</th>
|
||||
<th rowspan="2">Metode</th>
|
||||
<th colspan="2" class="reference-header">Referensi : PMK RI No.2 Tahun 2023</th>
|
||||
<th rowspan="2">Keterangan</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>NAB</th>
|
||||
<th>Ruang</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $no = 1; foreach ($hasil_pengukuran as $hasil): ?>
|
||||
<tr>
|
||||
<td><?php echo $no++; ?></td>
|
||||
<td><?php echo $hasil['nama_lokasi']; ?></td>
|
||||
<td><?php echo $hasil['kode_sampel']; ?></td>
|
||||
<td><?php
|
||||
echo date('H.i', strtotime($hasil['waktu_pengukuran_mulai'])) . ' - ' .
|
||||
date('H.i', strtotime($hasil['waktu_pengukuran_selesai']));
|
||||
?></td>
|
||||
<td><?php echo number_format($hasil['hasil_pengukuran'], 0); ?></td>
|
||||
<td><?php echo $hasil['satuan']; ?></td>
|
||||
<td><?php echo $hasil['metode']; ?></td>
|
||||
<td><?php echo number_format($hasil['nilai_minimal'], 0) . ' - ' . number_format($hasil['nilai_maksimal'], 0); ?></td>
|
||||
<td><?php echo $hasil['tipe_ruangan']; ?></td>
|
||||
<td><?php echo $hasil['keterangan']; ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="issue-date">
|
||||
Diterbitkan tanggal : <?php echo $laporan['tanggal_terbit_format']; ?>
|
||||
</div>
|
||||
|
||||
<div class="notes">
|
||||
<div>Catatan :</div>
|
||||
<?php echo nl2br($laporan['catatan']); ?>
|
||||
</div>
|
||||
|
||||
<div class="signatures">
|
||||
<div class="signature-box">
|
||||
<div>Diverifikasi oleh,</div>
|
||||
<div class="signature-line"></div>
|
||||
<div><strong><?php echo $verifikator['nama']; ?></strong></div>
|
||||
<div><?php echo $verifikator['jabatan']; ?></div>
|
||||
</div>
|
||||
<div class="signature-box">
|
||||
<div></div>
|
||||
<div class="signature-line"></div>
|
||||
<div></div>
|
||||
</div>
|
||||
<div class="signature-box">
|
||||
<div>Diukur oleh,</div>
|
||||
<div class="signature-line"></div>
|
||||
<div><strong><?php echo $penguji['nama']; ?></strong></div>
|
||||
<div><?php echo $penguji['jabatan']; ?></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
<?php
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
// Proses dan tampilkan laporan
|
||||
function processReport($laporan_id) {
|
||||
global $db_config;
|
||||
|
||||
$conn = connectDB($db_config);
|
||||
|
||||
// Ambil data laporan
|
||||
$laporan = getLaporanData($conn, $laporan_id);
|
||||
|
||||
if (!$laporan) {
|
||||
die("Laporan dengan ID {$laporan_id} tidak ditemukan");
|
||||
}
|
||||
|
||||
// Ambil data hasil pengukuran
|
||||
$hasil_pengukuran = getHasilPengukuran($conn, $laporan_id);
|
||||
|
||||
// Ambil data personel
|
||||
$verifikator = getPersonelData($conn, $laporan['diverifikasi_oleh']);
|
||||
$penguji = getPersonelData($conn, $laporan['petugas_id']);
|
||||
|
||||
// Generate laporan HTML
|
||||
$html = generateLaporanHTML($laporan, $hasil_pengukuran, $verifikator, $penguji);
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
// Jalankan aplikasi (contoh penggunaan)
|
||||
$laporan_id = isset($_GET['id']) ? (int)$_GET['id'] : 1;
|
||||
$html = processReport($laporan_id);
|
||||
echo $html;
|
||||
?>
|
||||
Reference in New Issue
Block a user