feat: add controllers and routes for anggota, bantuan, permohonan transfer
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\ActivityLog;
|
||||
use App\Models\AnggotaKeluarga;
|
||||
use App\Models\RumahMiskin;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class AnggotaKeluargaController extends Controller
|
||||
{
|
||||
public function index(string $idRumah)
|
||||
{
|
||||
RumahMiskin::findOrFail($idRumah);
|
||||
$anggota = AnggotaKeluarga::where('id_rumah', $idRumah)
|
||||
->orderBy('hubungan')
|
||||
->get()
|
||||
->map(fn($a) => [
|
||||
'id' => $a->id,
|
||||
'nama' => $a->nama,
|
||||
'hubungan' => $a->hubungan,
|
||||
'jenis_kelamin' => $a->jenis_kelamin,
|
||||
'tanggal_lahir' => $a->tanggal_lahir?->format('Y-m-d'),
|
||||
'umur' => $a->umur,
|
||||
'pendidikan' => $a->pendidikan,
|
||||
'status_hidup' => $a->status_hidup,
|
||||
]);
|
||||
return response()->json($anggota);
|
||||
}
|
||||
|
||||
public function store(Request $request, string $idRumah)
|
||||
{
|
||||
RumahMiskin::findOrFail($idRumah);
|
||||
$validated = $request->validate([
|
||||
'nama' => 'required|string|max:255',
|
||||
'hubungan' => 'required|in:kepala_keluarga,istri,anak,orang_tua,lainnya',
|
||||
'jenis_kelamin' => 'nullable|in:laki_laki,perempuan',
|
||||
'tanggal_lahir' => 'nullable|date|before:today',
|
||||
'pendidikan' => 'nullable|in:tidak_sekolah,sd,smp,sma,d3,s1_plus',
|
||||
'status_hidup' => 'required|in:hidup,meninggal',
|
||||
]);
|
||||
$anggota = AnggotaKeluarga::create(['id_rumah' => $idRumah, ...$validated]);
|
||||
ActivityLog::record('create', "Tambah anggota: {$anggota->nama} ({$idRumah})", 'anggota', $anggota->id);
|
||||
return response()->json(['success' => true, 'data' => $anggota]);
|
||||
}
|
||||
|
||||
public function update(Request $request, string $idRumah, int $id)
|
||||
{
|
||||
$anggota = AnggotaKeluarga::where('id_rumah', $idRumah)->findOrFail($id);
|
||||
$validated = $request->validate([
|
||||
'nama' => 'required|string|max:255',
|
||||
'hubungan' => 'required|in:kepala_keluarga,istri,anak,orang_tua,lainnya',
|
||||
'jenis_kelamin' => 'nullable|in:laki_laki,perempuan',
|
||||
'tanggal_lahir' => 'nullable|date|before:today',
|
||||
'pendidikan' => 'nullable|in:tidak_sekolah,sd,smp,sma,d3,s1_plus',
|
||||
'status_hidup' => 'required|in:hidup,meninggal',
|
||||
]);
|
||||
$anggota->update($validated);
|
||||
ActivityLog::record('update', "Update anggota: {$anggota->nama} ({$idRumah})", 'anggota', $anggota->id);
|
||||
return response()->json(['success' => true]);
|
||||
}
|
||||
|
||||
public function destroy(string $idRumah, int $id)
|
||||
{
|
||||
$anggota = AnggotaKeluarga::where('id_rumah', $idRumah)->findOrFail($id);
|
||||
$nama = $anggota->nama;
|
||||
$anggota->delete();
|
||||
ActivityLog::record('delete', "Hapus anggota: {$nama} ({$idRumah})", 'anggota', $id);
|
||||
return response()->json(['success' => true]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\ActivityLog;
|
||||
use App\Models\RiwayatBantuan;
|
||||
use App\Models\RumahMiskin;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class BantuanController extends Controller
|
||||
{
|
||||
public function index(string $idRumah)
|
||||
{
|
||||
RumahMiskin::findOrFail($idRumah);
|
||||
$bantuan = RiwayatBantuan::where('id_rumah', $idRumah)
|
||||
->with(['ibadah:id,nama', 'pencatat:id,name'])
|
||||
->orderByDesc('tanggal_bantuan')
|
||||
->get()
|
||||
->map(fn($b) => [
|
||||
'id' => $b->id,
|
||||
'jenis_bantuan' => $b->jenis_bantuan,
|
||||
'keterangan' => $b->keterangan,
|
||||
'tanggal_bantuan' => $b->tanggal_bantuan->format('d/m/Y'),
|
||||
'ibadah_nama' => $b->ibadah?->nama,
|
||||
'pencatat_nama' => $b->pencatat?->name ?? 'Sistem',
|
||||
]);
|
||||
return response()->json($bantuan);
|
||||
}
|
||||
|
||||
public function store(Request $request, string $idRumah)
|
||||
{
|
||||
RumahMiskin::findOrFail($idRumah);
|
||||
$validated = $request->validate([
|
||||
'jenis_bantuan' => 'required|string|max:255',
|
||||
'keterangan' => 'nullable|string',
|
||||
'tanggal_bantuan' => 'required|date',
|
||||
'ibadah_id' => 'nullable|integer|exists:rumah_ibadah,id',
|
||||
]);
|
||||
$bantuan = RiwayatBantuan::create([
|
||||
'id_rumah' => $idRumah,
|
||||
'dicatat_oleh' => auth()->id(),
|
||||
...$validated,
|
||||
]);
|
||||
ActivityLog::record('create', "Catat bantuan: {$bantuan->jenis_bantuan} → {$idRumah}", 'bantuan', $bantuan->id);
|
||||
return response()->json(['success' => true, 'data' => $bantuan]);
|
||||
}
|
||||
|
||||
public function destroy(string $idRumah, int $id)
|
||||
{
|
||||
$bantuan = RiwayatBantuan::where('id_rumah', $idRumah)->findOrFail($id);
|
||||
$jenis = $bantuan->jenis_bantuan;
|
||||
$bantuan->delete();
|
||||
ActivityLog::record('delete', "Hapus riwayat bantuan: {$jenis} ({$idRumah})", 'bantuan', $id);
|
||||
return response()->json(['success' => true]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\ActivityLog;
|
||||
use App\Models\PermohonanTransfer;
|
||||
use App\Models\RumahIbadah;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TransferController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
$user = auth()->user();
|
||||
$query = PermohonanTransfer::with([
|
||||
'dariIbadah:id,nama', 'keIbadah:id,nama',
|
||||
'rumahMiskin:id_rumah,nama_kk', 'pengaju:id,name',
|
||||
])->orderByDesc('created_at');
|
||||
|
||||
if ($user->hasRole('pengurus_ibadah')) {
|
||||
$ibadahIds = RumahIbadah::where('user_id', $user->id)->pluck('id');
|
||||
$query->where(function ($q) use ($ibadahIds) {
|
||||
$q->whereIn('dari_ibadah_id', $ibadahIds)
|
||||
->orWhereIn('ke_ibadah_id', $ibadahIds);
|
||||
});
|
||||
}
|
||||
|
||||
return response()->json($query->limit(100)->get()->map(fn($p) => [
|
||||
'id' => $p->id,
|
||||
'dari_ibadah' => $p->dariIbadah?->nama,
|
||||
'ke_ibadah' => $p->keIbadah?->nama,
|
||||
'ke_ibadah_id' => $p->ke_ibadah_id,
|
||||
'id_rumah' => $p->id_rumah,
|
||||
'nama_kk' => $p->rumahMiskin?->nama_kk,
|
||||
'alasan' => $p->alasan,
|
||||
'status' => $p->status,
|
||||
'catatan_respons' => $p->catatan_respons,
|
||||
'diajukan_oleh' => $p->pengaju?->name,
|
||||
'created_at' => $p->created_at?->format('d/m/Y H:i'),
|
||||
]));
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'dari_ibadah_id' => 'required|integer|exists:rumah_ibadah,id',
|
||||
'ke_ibadah_id' => 'required|integer|exists:rumah_ibadah,id|different:dari_ibadah_id',
|
||||
'id_rumah' => 'required|string|exists:rumah_miskin,id_rumah',
|
||||
'alasan' => 'required|string|max:1000',
|
||||
]);
|
||||
$permohonan = PermohonanTransfer::create([
|
||||
...$validated,
|
||||
'diajukan_oleh' => auth()->id(),
|
||||
'status' => 'pending',
|
||||
]);
|
||||
ActivityLog::record('create', "Ajukan transfer: {$permohonan->id_rumah} → ibadah #{$permohonan->ke_ibadah_id}", 'transfer', $permohonan->id);
|
||||
return response()->json(['success' => true, 'data' => $permohonan]);
|
||||
}
|
||||
|
||||
public function respond(Request $request, int $id)
|
||||
{
|
||||
$permohonan = PermohonanTransfer::findOrFail($id);
|
||||
if ($permohonan->status !== 'pending') {
|
||||
return response()->json(['message' => 'Permohonan sudah diproses'], 422);
|
||||
}
|
||||
|
||||
$validated = $request->validate([
|
||||
'status' => 'required|in:disetujui,ditolak',
|
||||
'catatan_respons' => 'nullable|string|max:500',
|
||||
]);
|
||||
|
||||
$user = auth()->user();
|
||||
if (!$user->hasRole('administrator')) {
|
||||
$ibadahIds = RumahIbadah::where('user_id', $user->id)->pluck('id');
|
||||
if (!$ibadahIds->contains($permohonan->ke_ibadah_id)) {
|
||||
return response()->json(['message' => 'Tidak berhak memproses'], 403);
|
||||
}
|
||||
}
|
||||
|
||||
$permohonan->update([...$validated, 'diproses_oleh' => $user->id]);
|
||||
|
||||
$label = $validated['status'] === 'disetujui' ? 'disetujui' : 'ditolak';
|
||||
ActivityLog::record('update', "Transfer {$label}: permohonan #{$id}", 'transfer', $id);
|
||||
return response()->json(['success' => true]);
|
||||
}
|
||||
}
|
||||
@@ -2,13 +2,16 @@
|
||||
|
||||
use App\Http\Controllers\ActivityLogController;
|
||||
use App\Http\Controllers\AdminUserController;
|
||||
use App\Http\Controllers\AnggotaKeluargaController;
|
||||
use App\Http\Controllers\AuthController;
|
||||
use App\Http\Controllers\BackupController;
|
||||
use App\Http\Controllers\BantuanController;
|
||||
use App\Http\Controllers\ExportController;
|
||||
use App\Http\Controllers\IbadahController;
|
||||
use App\Http\Controllers\ImportController;
|
||||
use App\Http\Controllers\MiskinController;
|
||||
use App\Http\Controllers\SettingController;
|
||||
use App\Http\Controllers\TransferController;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
// Auth routes (public, redirect to /map if already logged in)
|
||||
@@ -24,6 +27,7 @@ Route::middleware('auth')->group(function () {
|
||||
Route::get('/map', fn() => view('map'));
|
||||
Route::get('/data', fn() => view('data'));
|
||||
Route::get('/dashboard', fn() => view('dashboard'))->name('dashboard');
|
||||
Route::get('/permohonan', fn() => view('permohonan'))->name('permohonan');
|
||||
|
||||
// Export routes — semua role authenticated bisa ekspor
|
||||
Route::get('/export/pdf', [ExportController::class, 'allMiskinPDF'])->name('export.pdf.all');
|
||||
@@ -34,6 +38,28 @@ Route::middleware('auth')->group(function () {
|
||||
// API routes moved here for session + CSRF middleware
|
||||
Route::prefix('api')->group(function () {
|
||||
|
||||
// Anggota Keluarga — baca: semua; tulis: administrator + petugas_pendataan
|
||||
Route::get('/miskin/{id}/anggota', [AnggotaKeluargaController::class, 'index']);
|
||||
Route::middleware('role:administrator|petugas_pendataan')->group(function () {
|
||||
Route::post('/miskin/{id}/anggota', [AnggotaKeluargaController::class, 'store']);
|
||||
Route::put('/miskin/{id}/anggota/{aid}', [AnggotaKeluargaController::class, 'update']);
|
||||
Route::delete('/miskin/{id}/anggota/{aid}', [AnggotaKeluargaController::class, 'destroy']);
|
||||
});
|
||||
|
||||
// Riwayat Bantuan — baca: semua; tulis: administrator + petugas + pengurus_ibadah
|
||||
Route::get('/miskin/{id}/bantuan', [BantuanController::class, 'index']);
|
||||
Route::middleware('role:administrator|petugas_pendataan|pengurus_ibadah')->group(function () {
|
||||
Route::post('/miskin/{id}/bantuan', [BantuanController::class, 'store']);
|
||||
Route::delete('/miskin/{id}/bantuan/{bid}', [BantuanController::class, 'destroy']);
|
||||
});
|
||||
|
||||
// Permohonan Transfer — lihat: semua; ajukan+proses: pengurus + admin
|
||||
Route::get('/permohonan', [TransferController::class, 'index']);
|
||||
Route::middleware('role:administrator|pengurus_ibadah')->group(function () {
|
||||
Route::post('/permohonan', [TransferController::class, 'store']);
|
||||
Route::put('/permohonan/{id}/respond', [TransferController::class, 'respond']);
|
||||
});
|
||||
|
||||
// Notifikasi — semua role authenticated
|
||||
Route::get('/notifications', function (\Illuminate\Http\Request $request) {
|
||||
$since = $request->query('since');
|
||||
|
||||
Reference in New Issue
Block a user