query('per_page', 10); $search = strtolower($request->query('search', '')); $petani = PetaniCPM::when($search, function ($query, $search) { return $query->where('nama', 'like', "%{$search}%"); }) ->paginate($perPage); return view('ekosistem.petani-cpm.index', compact('petani')); } public function create(): View { if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) { abort(403); } $pendidikan = Pendidikan::options(); $pekerjaan = Pekerjaan::options(); $pernikahan = Pernikahan::options(); $statusKeluarga = HubunganDalamKeluarga::options(); $provinsi = Provinsi::all(); $komoditas = Komoditas::all(); return view('ekosistem.petani-cpm.add', compact('pendidikan', 'pekerjaan', 'pernikahan', 'statusKeluarga', 'provinsi', 'komoditas')); } /** * Store a newly created resource in storage. */ public function store(Request $request): RedirectResponse { if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) { abort(403); } $validatedData = $request->validate([ 'nama' => ['required','string','max:255'], 'jenis_kelamin' => ['required','boolean'], 'tanggal_lahir' => ['required','date'], 'pendidikan_terakhir' => ['required', Rule::enum(Pendidikan::class)], 'alamat' => ['required','string','max:500'], 'desa_kelurahan_id' => ['required','exists:master_desa_kelurahan,id'], 'pekerjaan_utama' => ['required', Rule::enum(Pekerjaan::class)], 'komoditas_id' => ['required','exists:master_komoditas,id'], 'lama_bertani' => ['required','numeric','min:0'], 'luas_lahan' => ['required','numeric','min:0'], 'pekerjaan_sampingan' => ['nullable', Rule::enum(Pekerjaan::class)], 'komoditas_sampingan_id' => ['nullable','exists:master_komoditas,id'], 'lama_bertani_sampingan' => ['nullable','numeric','min:0'], 'luas_lahan_sampingan' => ['nullable','numeric','min:0'], 'status_perkawinan' => ['required', Rule::enum(Pernikahan::class)], 'status_keluarga' => ['required', Rule::enum(HubunganDalamKeluarga::class)], 'jumlah_tanggungan' => ['nullable','integer','min:0'], 'petani_pengumpul' => ['nullable','array'], 'petani_pengumpul.*' => ['in:petani,pengumpul'], ]); PetaniCPM::create([...$validatedData, 'created_by' => auth()->id(), 'updated_by' => auth()->id()]); return redirect()->route('petani-cpm.index')->with('success', 'Data petani CPM berhasil ditambahkan.'); } /** * Display the specified resource. */ public function show(string $id) { if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) { abort(403); } $petani = PetaniCPM::findOrFail($id); return view('ekosistem.petani-cpm.view', compact('petani')); } /** * Show the form for editing the specified resource. */ public function edit(string $id) { if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) { abort(403); } $petani = PetaniCPM::findOrFail($id); $pendidikan = Pendidikan::options(); $pekerjaan = Pekerjaan::options(); $pernikahan = Pernikahan::options(); $statusKeluarga = HubunganDalamKeluarga::options(); $provinsi = Provinsi::all(); $komoditas = Komoditas::all(); return view('ekosistem.petani-cpm.edit', compact('petani', 'pendidikan', 'pekerjaan', 'pernikahan', 'statusKeluarga', 'provinsi', 'komoditas')); } /** * Update the specified resource in storage. */ public function update(Request $request, string $id) { if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) { abort(403); } $petani = PetaniCPM::findOrFail($id); $validatedData = $request->validate([ 'nama' => ['required','string','max:255'], 'jenis_kelamin' => ['required','boolean'], 'tanggal_lahir' => ['required','date'], 'pendidikan_terakhir' => ['required', Rule::enum(Pendidikan::class)], 'alamat' => ['required','string','max:500'], 'desa_kelurahan_id' => ['required','exists:master_desa_kelurahan,id'], 'pekerjaan_utama' => ['required', Rule::enum(Pekerjaan::class)], 'komoditas_id' => ['required','exists:master_komoditas,id'], 'lama_bertani' => ['required','numeric','min:0'], 'luas_lahan' => ['required','numeric','min:0'], 'pekerjaan_sampingan' => ['nullable', Rule::enum(Pekerjaan::class)], 'komoditas_sampingan_id' => ['nullable','exists:master_komoditas,id'], 'lama_bertani_sampingan' => ['nullable','numeric','min:0'], 'luas_lahan_sampingan' => ['nullable','numeric','min:0'], 'status_perkawinan' => ['required', Rule::enum(Pernikahan::class)], 'status_keluarga' => ['required', Rule::enum(HubunganDalamKeluarga::class)], 'jumlah_tanggungan' => ['nullable','integer','min:0'], 'petani_pengumpul' => ['nullable','array'], 'petani_pengumpul.*' => ['in:petani,pengumpul'], ]); $petani->update([...$validatedData, 'updated_by' => auth()->id()]); return redirect()->route('petani-cpm.index')->with('success', 'Data petani CPM berhasil diperbarui.'); } /** * Remove the specified resource from storage. */ public function destroy(string $id) { if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) { abort(403); } $petani = PetaniCPM::findOrFail($id); $petani->update(['deleted_by' => auth()->id()]); $petani->delete(); return redirect()->route('petani-cpm.index')->with('success', 'Data petani CPM berhasil dihapus.'); } public function summary(string $tipe): JsonResponse { switch ($tipe) { case 'jenis_kelamin': return $this->calculateJenisKelamin(); case 'usia': return $this->calculateUsia(); case 'pendidikan': return $this->calculatePendidikan(); } return response()->json([ 'petani' => PetaniCPM::count(), 'pengumpul' => PetaniCPM::where('petani_pengumpul', 'pengumpul')->count(), 'petani' => PetaniCPM::where('petani_pengumpul', 'petani')->count(), ]); } private function calculateJenisKelamin() { $petaniBase = PetaniCPM::query(); return response()->json([ 'total' => (clone $petaniBase)->count(), 'laki_laki' => (clone $petaniBase)->where('jenis_kelamin', 1)->count(), 'perempuan' => (clone $petaniBase)->where('jenis_kelamin', 0)->count(), ]); } private function calculateUsia() { $petaniBase = PetaniCPM::query(); $usiaRataRata = (clone $petaniBase) ->selectRaw('AVG(EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir))) as avg') ->value('avg'); $usiaMayoritas = (clone $petaniBase) ->selectRaw(" CASE WHEN EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 0 AND 4 THEN '0-4' WHEN EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 5 AND 9 THEN '5-9' WHEN EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 10 AND 14 THEN '10-14' WHEN EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 15 AND 19 THEN '15-19' WHEN EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 20 AND 24 THEN '20-24' WHEN EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 25 AND 29 THEN '25-29' WHEN EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 30 AND 34 THEN '30-34' WHEN EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 35 AND 39 THEN '35-39' WHEN EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 40 AND 44 THEN '40-44' WHEN EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 45 AND 49 THEN '45-49' WHEN EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 50 AND 54 THEN '50-54' WHEN EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 55 AND 59 THEN '55-59' WHEN EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 60 AND 64 THEN '60-64' WHEN EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 65 AND 69 THEN '65-69' WHEN EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 70 AND 74 THEN '70-74' ELSE '75+' END as kelompok_usia ") ->groupBy('kelompok_usia') ->orderByRaw('COUNT(*) DESC') ->value('kelompok_usia'); return response()->json([ 'usia_rata_rata' => $usiaRataRata ? round($usiaRataRata, 1) : 0, 'usia_mayoritas' => $usiaMayoritas ?? '-', ]); } private function calculatePendidikan() { $petaniBase = PetaniCPM::query(); $mayoritasValue = (clone $petaniBase) ->selectRaw('pendidikan_terakhir, COUNT(*) as total') ->groupBy('pendidikan_terakhir') ->orderByDesc('total') ->orderByDesc('pendidikan_terakhir') ->value('pendidikan_terakhir'); $tertinggiValue = (clone $petaniBase) ->whereNotNull('pendidikan_terakhir') ->orderByDesc('pendidikan_terakhir') // karena ada prefix angka ->value('pendidikan_terakhir'); $mayoritasLabel = $mayoritasValue?->label() ?? '-'; $tertinggiLabel = $tertinggiValue?->label() ?? '-'; return response()->json([ 'pendidikan_mayoritas' => $mayoritasLabel, 'pendidikan_tertinggi' => $tertinggiLabel, ]); } }