220 lines
8.4 KiB
PHP
220 lines
8.4 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/includes/db_init.php';
|
|
require_once __DIR__ . '/includes/layout.php';
|
|
require_once __DIR__ . '/includes/helpers.php';
|
|
|
|
ensure_tables();
|
|
|
|
$pdo = db();
|
|
$errors = [];
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
$kode = trim($_POST['kode_surat'] ?? '');
|
|
$tanggal = $_POST['tanggal_surat'] ?? '';
|
|
$tujuan = trim($_POST['tujuan'] ?? '');
|
|
$perihal = trim($_POST['perihal'] ?? '');
|
|
$departemen = trim($_POST['departemen_pengirim'] ?? '');
|
|
$status = $_POST['status'] ?? 'draft';
|
|
|
|
if ($kode === '') { $errors[] = 'Kode surat wajib diisi.'; }
|
|
if ($tanggal === '') { $errors[] = 'Tanggal surat wajib diisi.'; }
|
|
if ($tujuan === '') { $errors[] = 'Tujuan surat wajib diisi.'; }
|
|
if ($perihal === '') { $errors[] = 'Perihal wajib diisi.'; }
|
|
if ($departemen === '') { $errors[] = 'Departemen pengirim wajib diisi.'; }
|
|
|
|
$filePath = null;
|
|
if (!empty($_FILES['lampiran']['name'])) {
|
|
if ($_FILES['lampiran']['error'] === UPLOAD_ERR_OK) {
|
|
if ($_FILES['lampiran']['size'] <= 8 * 1024 * 1024) {
|
|
$ext = strtolower(pathinfo($_FILES['lampiran']['name'], PATHINFO_EXTENSION));
|
|
$allowed = ['pdf', 'doc', 'docx', 'jpg', 'jpeg', 'png'];
|
|
if (in_array($ext, $allowed, true)) {
|
|
$safeName = preg_replace('/[^a-zA-Z0-9_-]/', '_', pathinfo($_FILES['lampiran']['name'], PATHINFO_FILENAME));
|
|
$targetDir = __DIR__ . '/uploads';
|
|
if (!is_dir($targetDir)) {
|
|
mkdir($targetDir, 0775, true);
|
|
}
|
|
$fileName = 'keluar_' . time() . '_' . $safeName . '.' . $ext;
|
|
$targetPath = $targetDir . '/' . $fileName;
|
|
if (move_uploaded_file($_FILES['lampiran']['tmp_name'], $targetPath)) {
|
|
$filePath = 'uploads/' . $fileName;
|
|
} else {
|
|
$errors[] = 'Gagal mengunggah lampiran.';
|
|
}
|
|
} else {
|
|
$errors[] = 'Format lampiran tidak didukung (pdf/doc/jpg/png).';
|
|
}
|
|
} else {
|
|
$errors[] = 'Ukuran lampiran maksimal 8 MB.';
|
|
}
|
|
} else {
|
|
$errors[] = 'Lampiran gagal diunggah.';
|
|
}
|
|
}
|
|
|
|
if (empty($errors)) {
|
|
$bulan = (int)date('n', strtotime($tanggal));
|
|
$tahun = (int)date('Y', strtotime($tanggal));
|
|
$pdo->beginTransaction();
|
|
$stmt = $pdo->prepare("SELECT MAX(urut) as max_urut FROM surat_keluar WHERE kode_surat = ? AND bulan = ? AND tahun = ?");
|
|
$stmt->execute([$kode, $bulan, $tahun]);
|
|
$maxUrut = (int)($stmt->fetch()['max_urut'] ?? 0);
|
|
$nextUrut = $maxUrut + 1;
|
|
$nomor = format_nomor($kode, $nextUrut, $bulan, $tahun);
|
|
|
|
$insert = $pdo->prepare("INSERT INTO surat_keluar (nomor_surat, kode_surat, urut, bulan, tahun, tanggal_surat, tujuan, perihal, departemen_pengirim, status, file_path) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
|
$insert->execute([
|
|
$nomor,
|
|
$kode,
|
|
$nextUrut,
|
|
$bulan,
|
|
$tahun,
|
|
$tanggal,
|
|
$tujuan,
|
|
$perihal,
|
|
$departemen,
|
|
$status,
|
|
$filePath
|
|
]);
|
|
$pdo->commit();
|
|
|
|
header('Location: /surat_keluar.php?success=1&nomor=' . urlencode($nomor));
|
|
exit;
|
|
}
|
|
}
|
|
|
|
$search = trim($_GET['q'] ?? '');
|
|
$where = '';
|
|
$params = [];
|
|
if ($search !== '') {
|
|
$where = "WHERE nomor_surat LIKE ? OR perihal LIKE ? OR tujuan LIKE ? OR departemen_pengirim LIKE ?";
|
|
$like = '%' . $search . '%';
|
|
$params = [$like, $like, $like, $like];
|
|
}
|
|
|
|
$stmt = $pdo->prepare("SELECT id, nomor_surat, tanggal_surat, tujuan, perihal, departemen_pengirim, status FROM surat_keluar $where ORDER BY tanggal_surat DESC, id DESC LIMIT 50");
|
|
$stmt->execute($params);
|
|
$rows = $stmt->fetchAll();
|
|
|
|
render_header('Surat Keluar', 'keluar');
|
|
?>
|
|
|
|
<?php if (!empty($_GET['success'])): ?>
|
|
<div class="toast-container position-fixed top-0 end-0 p-3">
|
|
<div class="toast text-bg-dark border-0" role="alert" data-bs-delay="4000">
|
|
<div class="toast-body">
|
|
Surat keluar tersimpan. Nomor otomatis:
|
|
<strong><?= h($_GET['nomor'] ?? '') ?></strong>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<div class="row g-3">
|
|
<div class="col-lg-4">
|
|
<div class="card">
|
|
<div class="card-header">Buat Surat Keluar</div>
|
|
<div class="card-body">
|
|
<?php if (!empty($errors)): ?>
|
|
<div class="alert alert-danger">
|
|
<ul class="mb-0">
|
|
<?php foreach ($errors as $error): ?>
|
|
<li><?= h($error) ?></li>
|
|
<?php endforeach; ?>
|
|
</ul>
|
|
</div>
|
|
<?php endif; ?>
|
|
<form method="post" enctype="multipart/form-data">
|
|
<div class="mb-3">
|
|
<label class="form-label">Kode Surat</label>
|
|
<input type="text" name="kode_surat" class="form-control" placeholder="HR/FIN/IT" required value="<?= h($_POST['kode_surat'] ?? '') ?>">
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Tanggal Surat</label>
|
|
<input type="date" name="tanggal_surat" class="form-control" required value="<?= h($_POST['tanggal_surat'] ?? date('Y-m-d')) ?>">
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Tujuan</label>
|
|
<input type="text" name="tujuan" class="form-control" required value="<?= h($_POST['tujuan'] ?? '') ?>">
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Perihal</label>
|
|
<input type="text" name="perihal" class="form-control" required value="<?= h($_POST['perihal'] ?? '') ?>">
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Departemen Pengirim</label>
|
|
<input type="text" name="departemen_pengirim" class="form-control" required value="<?= h($_POST['departemen_pengirim'] ?? '') ?>">
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Status</label>
|
|
<select name="status" class="form-select">
|
|
<?php foreach (['draft' => 'Draft', 'review' => 'Review', 'approved' => 'Approved', 'kirim' => 'Kirim'] as $val => $label): ?>
|
|
<option value="<?= h($val) ?>" <?= (($val === ($_POST['status'] ?? 'draft')) ? 'selected' : '') ?>><?= h($label) ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Lampiran (PDF/DOC/JPG/PNG)</label>
|
|
<input type="file" name="lampiran" class="form-control">
|
|
</div>
|
|
<div class="alert alert-secondary small">
|
|
Nomor surat dibuat otomatis saat disimpan: <strong>KODE/URUT/BULAN_ROMAWI/TAHUN</strong>.
|
|
</div>
|
|
<button type="submit" class="btn btn-primary w-100">Simpan Surat Keluar</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-lg-8">
|
|
<div class="card">
|
|
<div class="card-header d-flex flex-wrap justify-content-between align-items-center gap-2">
|
|
<span>Daftar Surat Keluar</span>
|
|
<form class="d-flex gap-2" method="get">
|
|
<input type="text" name="q" class="form-control" placeholder="Cari nomor/perihal/tujuan" value="<?= h($search) ?>">
|
|
<button class="btn btn-light border" type="submit">Cari</button>
|
|
</form>
|
|
</div>
|
|
<div class="card-body">
|
|
<?php if (empty($rows)): ?>
|
|
<div class="empty-state">Belum ada data surat keluar.</div>
|
|
<?php else: ?>
|
|
<div class="table-responsive">
|
|
<table class="table align-middle">
|
|
<thead>
|
|
<tr>
|
|
<th>Tanggal</th>
|
|
<th>Nomor</th>
|
|
<th>Tujuan</th>
|
|
<th>Perihal</th>
|
|
<th>Departemen</th>
|
|
<th>Status</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($rows as $row): ?>
|
|
<tr>
|
|
<td><?= h($row['tanggal_surat']) ?></td>
|
|
<td>
|
|
<a href="/surat_keluar_view.php?id=<?= h((string)$row['id']) ?>">
|
|
<?= h($row['nomor_surat']) ?>
|
|
</a>
|
|
</td>
|
|
<td><?= h($row['tujuan']) ?></td>
|
|
<td><?= h($row['perihal']) ?></td>
|
|
<td><?= h($row['departemen_pengirim']) ?></td>
|
|
<td><span class="<?= h(status_badge($row['status'], 'keluar')) ?>"><?= h($row['status']) ?></span></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<?php render_footer(); ?>
|