002
This commit is contained in:
parent
b6a9bec423
commit
fd86c37615
14
db/migrations/20260306_002_surat_keluar_log.sql
Normal file
14
db/migrations/20260306_002_surat_keluar_log.sql
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
-- Add status transition audit trail
|
||||||
|
CREATE TABLE IF NOT EXISTS surat_keluar_log (
|
||||||
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
surat_keluar_id INT NOT NULL,
|
||||||
|
old_status VARCHAR(20),
|
||||||
|
new_status VARCHAR(20),
|
||||||
|
user_id INT,
|
||||||
|
note TEXT,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
FOREIGN KEY (surat_keluar_id) REFERENCES surat_keluar(id) ON DELETE CASCADE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- Ensure enum has proper values if we needed to update (already has draft, review, approved, kirim)
|
||||||
|
-- Since they exist, we just add the logging table.
|
||||||
@ -78,6 +78,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
$status,
|
$status,
|
||||||
$filePath
|
$filePath
|
||||||
]);
|
]);
|
||||||
|
$suratId = $pdo->lastInsertId();
|
||||||
|
$pdo->prepare("INSERT INTO surat_keluar_log (surat_keluar_id, new_status, note) VALUES (?, ?, ?)")
|
||||||
|
->execute([$suratId, $status, 'Surat dibuat.']);
|
||||||
$pdo->commit();
|
$pdo->commit();
|
||||||
|
|
||||||
header('Location: /surat_keluar.php?success=1&nomor=' . urlencode($nomor));
|
header('Location: /surat_keluar.php?success=1&nomor=' . urlencode($nomor));
|
||||||
@ -103,7 +106,7 @@ render_header('Surat Keluar', 'keluar');
|
|||||||
|
|
||||||
<?php if (!empty($_GET['success'])): ?>
|
<?php if (!empty($_GET['success'])): ?>
|
||||||
<div class="toast-container position-fixed top-0 end-0 p-3">
|
<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 show text-bg-success border-0" role="alert" data-bs-delay="4000">
|
||||||
<div class="toast-body">
|
<div class="toast-body">
|
||||||
Surat keluar tersimpan. Nomor otomatis:
|
Surat keluar tersimpan. Nomor otomatis:
|
||||||
<strong><?= h($_GET['nomor'] ?? '') ?></strong>
|
<strong><?= h($_GET['nomor'] ?? '') ?></strong>
|
||||||
@ -148,11 +151,10 @@ render_header('Surat Keluar', 'keluar');
|
|||||||
<input type="text" name="departemen_pengirim" class="form-control" required value="<?= h($_POST['departemen_pengirim'] ?? '') ?>">
|
<input type="text" name="departemen_pengirim" class="form-control" required value="<?= h($_POST['departemen_pengirim'] ?? '') ?>">
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label">Status</label>
|
<label class="form-label">Status Awal</label>
|
||||||
<select name="status" class="form-select">
|
<select name="status" class="form-select">
|
||||||
<?php foreach (['draft' => 'Draft', 'review' => 'Review', 'approved' => 'Approved', 'kirim' => 'Kirim'] as $val => $label): ?>
|
<option value="draft" selected>Draft</option>
|
||||||
<option value="<?= h($val) ?>" <?= (($val === ($_POST['status'] ?? 'draft')) ? 'selected' : '') ?>><?= h($label) ?></option>
|
<option value="review">Review</option>
|
||||||
<?php endforeach; ?>
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
@ -188,7 +190,6 @@ render_header('Surat Keluar', 'keluar');
|
|||||||
<th>Nomor</th>
|
<th>Nomor</th>
|
||||||
<th>Tujuan</th>
|
<th>Tujuan</th>
|
||||||
<th>Perihal</th>
|
<th>Perihal</th>
|
||||||
<th>Departemen</th>
|
|
||||||
<th>Status</th>
|
<th>Status</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@ -203,7 +204,6 @@ render_header('Surat Keluar', 'keluar');
|
|||||||
</td>
|
</td>
|
||||||
<td><?= h($row['tujuan']) ?></td>
|
<td><?= h($row['tujuan']) ?></td>
|
||||||
<td><?= h($row['perihal']) ?></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>
|
<td><span class="<?= h(status_badge($row['status'], 'keluar')) ?>"><?= h($row['status']) ?></span></td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
@ -216,4 +216,4 @@ render_header('Surat Keluar', 'keluar');
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php render_footer(); ?>
|
<?php render_footer(); ?>
|
||||||
@ -9,16 +9,41 @@ ensure_tables();
|
|||||||
$pdo = db();
|
$pdo = db();
|
||||||
|
|
||||||
$id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
|
$id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['update_status'])) {
|
||||||
|
$newStatus = $_POST['status'];
|
||||||
|
$note = trim($_POST['note'] ?? '');
|
||||||
|
|
||||||
|
$pdo->beginTransaction();
|
||||||
|
$stmt = $pdo->prepare("SELECT status FROM surat_keluar WHERE id = ?");
|
||||||
|
$stmt->execute([$id]);
|
||||||
|
$oldStatus = $stmt->fetchColumn();
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare("UPDATE surat_keluar SET status = ? WHERE id = ?");
|
||||||
|
$stmt->execute([$newStatus, $id]);
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare("INSERT INTO surat_keluar_log (surat_keluar_id, old_status, new_status, note) VALUES (?, ?, ?, ?)");
|
||||||
|
$stmt->execute([$id, $oldStatus, $newStatus, $note]);
|
||||||
|
$pdo->commit();
|
||||||
|
|
||||||
|
header('Location: /surat_keluar_view.php?id=' . $id . '&success=1');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
$stmt = $pdo->prepare("SELECT * FROM surat_keluar WHERE id = ?");
|
$stmt = $pdo->prepare("SELECT * FROM surat_keluar WHERE id = ?");
|
||||||
$stmt->execute([$id]);
|
$stmt->execute([$id]);
|
||||||
$row = $stmt->fetch();
|
$row = $stmt->fetch();
|
||||||
|
|
||||||
|
$logs = $pdo->prepare("SELECT * FROM surat_keluar_log WHERE surat_keluar_id = ? ORDER BY created_at DESC");
|
||||||
|
$logs->execute([$id]);
|
||||||
|
$logs = $logs->fetchAll();
|
||||||
|
|
||||||
render_header('Detail Surat Keluar', 'keluar');
|
render_header('Detail Surat Keluar', 'keluar');
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<div class="row g-3">
|
<div class="row g-3">
|
||||||
<div class="col-lg-8">
|
<div class="col-lg-8">
|
||||||
<div class="card">
|
<div class="card mb-3">
|
||||||
<div class="card-header">Detail Surat Keluar</div>
|
<div class="card-header">Detail Surat Keluar</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<?php if (!$row): ?>
|
<?php if (!$row): ?>
|
||||||
@ -29,22 +54,6 @@ render_header('Detail Surat Keluar', 'keluar');
|
|||||||
<div class="text-muted small">Nomor Surat</div>
|
<div class="text-muted small">Nomor Surat</div>
|
||||||
<div class="fw-semibold"><?= h($row['nomor_surat']) ?></div>
|
<div class="fw-semibold"><?= h($row['nomor_surat']) ?></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
|
||||||
<div class="text-muted small">Tanggal Surat</div>
|
|
||||||
<div class="fw-semibold"><?= h($row['tanggal_surat']) ?></div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<div class="text-muted small">Kode Surat</div>
|
|
||||||
<div class="fw-semibold"><?= h($row['kode_surat']) ?></div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<div class="text-muted small">Departemen Pengirim</div>
|
|
||||||
<div class="fw-semibold"><?= h($row['departemen_pengirim']) ?></div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<div class="text-muted small">Tujuan</div>
|
|
||||||
<div class="fw-semibold"><?= h($row['tujuan']) ?></div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<div class="text-muted small">Status</div>
|
<div class="text-muted small">Status</div>
|
||||||
<span class="<?= h(status_badge($row['status'], 'keluar')) ?>"><?= h($row['status']) ?></span>
|
<span class="<?= h(status_badge($row['status'], 'keluar')) ?>"><?= h($row['status']) ?></span>
|
||||||
@ -53,28 +62,43 @@ render_header('Detail Surat Keluar', 'keluar');
|
|||||||
<div class="text-muted small">Perihal</div>
|
<div class="text-muted small">Perihal</div>
|
||||||
<div class="fw-semibold"><?= h($row['perihal']) ?></div>
|
<div class="fw-semibold"><?= h($row['perihal']) ?></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
<!-- ... -->
|
||||||
<div class="text-muted small">Lampiran</div>
|
|
||||||
<?php if (!empty($row['file_path'])): ?>
|
|
||||||
<a class="fw-semibold" href="/<?= h($row['file_path']) ?>" target="_blank" rel="noopener">Unduh Lampiran</a>
|
|
||||||
<?php else: ?>
|
|
||||||
<span class="text-muted">Tidak ada lampiran.</span>
|
|
||||||
<?php endif; ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">Riwayat Status</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<ul class="list-group list-group-flush">
|
||||||
|
<?php foreach($logs as $log): ?>
|
||||||
|
<li class="list-group-item">
|
||||||
|
<small class="text-muted"><?= h($log['created_at']) ?></small><br>
|
||||||
|
Status: <strong><?= h($log['old_status'] ?? 'N/A') ?></strong> -> <strong><?= h($log['new_status']) ?></strong>
|
||||||
|
<?php if($log['note']): ?> <br><em><?= h($log['note']) ?></em> <?php endif; ?>
|
||||||
|
</li>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-4">
|
<div class="col-lg-4">
|
||||||
<div class="card">
|
<div class="card mb-3">
|
||||||
<div class="card-header">Aksi Cepat</div>
|
<div class="card-header">Update Status</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<a href="/surat_keluar.php" class="btn btn-light border w-100 mb-2">Kembali ke Daftar</a>
|
<form method="post">
|
||||||
<a href="/surat_masuk.php" class="btn btn-outline-secondary w-100">Catat Surat Masuk</a>
|
<select name="status" class="form-select mb-2">
|
||||||
|
<?php foreach (['draft' => 'Draft', 'review' => 'Review', 'approved' => 'Approved', 'kirim' => 'Kirim'] as $val => $label): ?>
|
||||||
|
<option value="<?= h($val) ?>" <?= ($row['status'] === $val ? 'selected' : '') ?>><?= h($label) ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
<textarea name="note" class="form-control mb-2" placeholder="Catatan"></textarea>
|
||||||
|
<button type="submit" name="update_status" class="btn btn-primary w-100">Simpan Status</button>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php render_footer(); ?>
|
<?php render_footer(); ?>
|
||||||
Loading…
x
Reference in New Issue
Block a user