176 lines
7.3 KiB
PHP
176 lines
7.3 KiB
PHP
<?php
|
|
// ============================================================
|
|
// api/reports/index.php — Emergency Reports CRUD (no auth)
|
|
// UI tabs removed; API kept for data integrity & popup access
|
|
// ============================================================
|
|
declare(strict_types=1);
|
|
require_once __DIR__ . '/../../config/bootstrap.php';
|
|
|
|
$method = $_SERVER['REQUEST_METHOD'];
|
|
$action = $_GET['action'] ?? 'list';
|
|
$id = isset($_GET['id']) ? (int)$_GET['id'] : null;
|
|
|
|
switch ("$method:$action") {
|
|
|
|
case 'GET:list':
|
|
case 'GET:': {
|
|
$pdo = Database::get();
|
|
$where = ['1=1'];
|
|
$params = [];
|
|
|
|
if (!empty($_GET['status'])) { $where[] = 'er.status = ?'; $params[] = $_GET['status']; }
|
|
if (!empty($_GET['severity'])) { $where[] = 'er.severity = ?'; $params[] = $_GET['severity']; }
|
|
if (!empty($_GET['household_id'])) { $where[] = 'er.household_id = ?'; $params[] = (int)$_GET['household_id']; }
|
|
if (!empty($_GET['type'])) { $where[] = 'er.type = ?'; $params[] = $_GET['type']; }
|
|
|
|
$whereSQL = implode(' AND ', $where);
|
|
$limit = min((int)($_GET['limit'] ?? 50), 200);
|
|
$offset = max(0, (int)($_GET['offset'] ?? 0));
|
|
|
|
$stmt = $pdo->prepare("
|
|
SELECT er.*, h.head_name, h.address, h.latitude, h.longitude, h.nik
|
|
FROM emergency_reports er
|
|
LEFT JOIN households h ON h.id = er.household_id
|
|
WHERE $whereSQL
|
|
ORDER BY FIELD(er.severity,'kritis','berat','sedang','ringan'),
|
|
FIELD(er.status,'open','in_progress','resolved','closed'),
|
|
er.created_at DESC
|
|
LIMIT $limit OFFSET $offset
|
|
");
|
|
$stmt->execute($params);
|
|
$rows = $stmt->fetchAll();
|
|
|
|
$cntStmt = $pdo->prepare("SELECT COUNT(*) FROM emergency_reports er WHERE $whereSQL");
|
|
$cntStmt->execute($params);
|
|
|
|
foreach ($rows as &$r) { $r['severity_color'] = severityColor($r['severity']); }
|
|
unset($r);
|
|
|
|
Response::success(['reports' => $rows, 'total' => (int)$cntStmt->fetchColumn()]);
|
|
break;
|
|
}
|
|
|
|
case 'GET:show': {
|
|
if (!$id) Response::error('ID is required.', 400);
|
|
$pdo = Database::get();
|
|
$stmt = $pdo->prepare("
|
|
SELECT er.*, h.head_name, h.address, h.latitude, h.longitude, h.nik,
|
|
h.poverty_status, h.dependents, h.income, h.house_condition
|
|
FROM emergency_reports er
|
|
LEFT JOIN households h ON h.id = er.household_id
|
|
WHERE er.id = ?
|
|
");
|
|
$stmt->execute([$id]);
|
|
$row = $stmt->fetch();
|
|
if (!$row) Response::notFound('Report not found.');
|
|
$row['severity_color'] = severityColor($row['severity']);
|
|
Response::success($row);
|
|
break;
|
|
}
|
|
|
|
case 'POST:create': {
|
|
$data = Validator::json();
|
|
$v = Validator::make($data, [
|
|
'household_id' => 'required|integer',
|
|
'type' => 'required|in:sakit,kecelakaan,bencana,kehilangan_pekerjaan,kematian,lainnya',
|
|
'severity' => 'required|in:ringan,sedang,berat,kritis',
|
|
'description' => 'required|string',
|
|
]);
|
|
$v->validate_or_fail();
|
|
|
|
$pdo = Database::get();
|
|
$hh = $pdo->prepare('SELECT id FROM households WHERE id=? AND is_active=1');
|
|
$hh->execute([(int)$data['household_id']]);
|
|
if (!$hh->fetch()) Response::notFound('Household not found.');
|
|
|
|
$existing = $pdo->prepare("
|
|
SELECT id, type, status FROM emergency_reports
|
|
WHERE household_id = ? AND status IN ('open','in_progress') LIMIT 1
|
|
");
|
|
$existing->execute([(int)$data['household_id']]);
|
|
$active = $existing->fetch();
|
|
if ($active) {
|
|
$lbl = ['sakit'=>'Sakit','kecelakaan'=>'Kecelakaan','bencana'=>'Bencana',
|
|
'kehilangan_pekerjaan'=>'Kehilangan Pekerjaan','kematian'=>'Kematian','lainnya'=>'Lainnya'];
|
|
Response::error(
|
|
'Sudah ada laporan aktif: ' . ($lbl[$active['type']] ?? $active['type']) . '. Selesaikan dulu.',
|
|
409
|
|
);
|
|
}
|
|
|
|
$pdo->prepare("INSERT INTO emergency_reports (household_id, type, severity, description, status) VALUES (?,?,?,?,'open')")
|
|
->execute([(int)$data['household_id'], $data['type'], $data['severity'], Validator::sanitizeString($data['description'])]);
|
|
|
|
$newId = (int)$pdo->lastInsertId();
|
|
AuditLog::record('Tambah Laporan Darurat', 'emergency_reports', $newId, null, $data);
|
|
Response::created(['id' => $newId], 'Laporan darurat berhasil dibuat.');
|
|
break;
|
|
}
|
|
|
|
case 'POST:update': {
|
|
requireAuth();
|
|
if (!$id) Response::error('ID is required.', 400);
|
|
$data = Validator::json();
|
|
Validator::make($data, [
|
|
'status' => 'required|in:open,in_progress,resolved,closed',
|
|
'severity' => 'in:ringan,sedang,berat,kritis',
|
|
])->validate_or_fail();
|
|
|
|
$pdo = Database::get();
|
|
$old = $pdo->prepare('SELECT * FROM emergency_reports WHERE id=?');
|
|
$old->execute([$id]);
|
|
$oldRow = $old->fetch();
|
|
if (!$oldRow) Response::notFound('Report not found.');
|
|
|
|
$fields = ['status = ?'];
|
|
$params = [$data['status']];
|
|
if (!empty($data['severity'])) { $fields[] = 'severity = ?'; $params[] = $data['severity']; }
|
|
if (!empty($data['description'])) { $fields[] = 'description = ?'; $params[] = Validator::sanitizeString($data['description']); }
|
|
if (in_array($data['status'], ['resolved','closed']) && !$oldRow['resolved_at']) { $fields[] = 'resolved_at = NOW()'; }
|
|
$params[] = $id;
|
|
|
|
$pdo->prepare('UPDATE emergency_reports SET ' . implode(', ', $fields) . ' WHERE id=?')->execute($params);
|
|
AuditLog::record('Update Laporan Darurat', 'emergency_reports', $id, $oldRow, $data);
|
|
Response::success(['id' => $id], 'Laporan diperbarui.');
|
|
break;
|
|
}
|
|
|
|
case 'POST:resolve': {
|
|
requireAuth();
|
|
if (!$id) Response::error('ID is required.', 400);
|
|
$pdo = Database::get();
|
|
$stmt = $pdo->prepare("UPDATE emergency_reports SET status='resolved', resolved_at=NOW() WHERE id=? AND status NOT IN ('resolved','closed')");
|
|
$stmt->execute([$id]);
|
|
if ($stmt->rowCount() === 0) Response::error('Report not found or already resolved.', 409);
|
|
AuditLog::record('Selesaikan Laporan', 'emergency_reports', $id);
|
|
Response::success(null, 'Laporan diselesaikan.');
|
|
break;
|
|
}
|
|
|
|
case 'POST:delete': {
|
|
requireAdmin();
|
|
if (!$id) Response::error('ID is required.', 400);
|
|
$pdo = Database::get();
|
|
$old = $pdo->prepare('SELECT * FROM emergency_reports WHERE id=?');
|
|
$old->execute([$id]);
|
|
$row = $old->fetch();
|
|
if (!$row) Response::notFound('Report not found.');
|
|
$pdo->prepare('DELETE FROM emergency_reports WHERE id=?')->execute([$id]);
|
|
AuditLog::record('Hapus Laporan Darurat', 'emergency_reports', $id, $row);
|
|
Response::success(null, 'Laporan dihapus.');
|
|
break;
|
|
}
|
|
|
|
default:
|
|
Response::methodNotAllowed();
|
|
}
|
|
|
|
function severityColor(string $s): string
|
|
{
|
|
return match($s) {
|
|
'kritis' => '#d63230', 'berat' => '#f76707',
|
|
'sedang' => '#f59e0b', 'ringan' => '#0b9e73',
|
|
default => '#9ba4b5',
|
|
};
|
|
}
|