diff --git a/app/Http/Controllers/Web/Produktivitas/SosialEkonomiController.php b/app/Http/Controllers/Web/Produktivitas/SosialEkonomiController.php new file mode 100644 index 0000000..a229277 --- /dev/null +++ b/app/Http/Controllers/Web/Produktivitas/SosialEkonomiController.php @@ -0,0 +1,264 @@ +where('petani_id', $petaniId) + ->first(); + + $pendapatanKomoditas = $sosialEkonomi?->pendapatanKomoditas ?? collect(); + $pendapatanKomoditasUtama = $pendapatanKomoditas->where('kategori', 'utama')->values(); + $pendapatanKomoditasLainnya = $pendapatanKomoditas->where('kategori', 'lainnya')->values(); + $pendapatanLuarPertanian = $sosialEkonomi?->pendapatanLuarPertanian?->values() ?? collect(); + + return view('produktivitas.petani.sosial-ekonomi.index', compact( + 'petani', + 'sosialEkonomi', + 'pendapatanKomoditasUtama', + 'pendapatanKomoditasLainnya', + 'pendapatanLuarPertanian' + )); + } + + public function index(Request $request): JsonResponse + { + $sosialEkonomi = SosialEkonomi::with([ + 'petani', + 'pendapatanKomoditas', + 'pendapatanLuarPertanian', + ]) + ->when($request->search, function ($query, $search) { + $query->whereHas('petani', function ($petani) use ($search) { + $petani->where('nama', 'like', "%{$search}%"); + }); + }) + ->when($request->petani_id, fn ($query, $petaniId) => $query->where('petani_id', $petaniId)) + ->orderBy('created_at', 'desc') + ->paginate($request->per_page ?? 10); + + return response()->json($sosialEkonomi); + } + + public function store(Request $request): JsonResponse + { + $validated = $this->validateData($request); + + $sosialEkonomi = DB::transaction(function () use ($validated) { + $sosialEkonomi = SosialEkonomi::create($this->sosialEkonomiPayload($validated) + [ + 'created_by' => auth()->id(), + 'updated_by' => auth()->id(), + ]); + + $this->syncPendapatanKomoditas($sosialEkonomi, $validated['pendapatan_komoditas'] ?? []); + $this->syncPendapatanLuarPertanian($sosialEkonomi, $validated['pendapatan_luar_pertanian'] ?? []); + + return $sosialEkonomi->load([ + 'petani', + 'pendapatanKomoditas', + 'pendapatanLuarPertanian', + ]); + }); + + if (!$request->expectsJson()) { + return redirect() + ->route('petani.sosial-ekonomi.edit', $sosialEkonomi->petani_id) + ->with('success', 'Data sosial ekonomi berhasil disimpan.'); + } + + return response()->json([ + 'status' => 'success', + 'message' => 'Data sosial ekonomi berhasil disimpan.', + 'data' => $sosialEkonomi, + ], 201); + } + + public function show(string $id): JsonResponse + { + $sosialEkonomi = SosialEkonomi::with([ + 'petani', + 'pendapatanKomoditas', + 'pendapatanLuarPertanian', + ])->findOrFail($id); + + return response()->json([ + 'status' => 'success', + 'data' => $sosialEkonomi, + ]); + } + + public function update(Request $request, string $id): JsonResponse + { + $sosialEkonomi = SosialEkonomi::findOrFail($id); + $validated = $this->validateData($request, $sosialEkonomi->id); + + $sosialEkonomi = DB::transaction(function () use ($request, $validated, $sosialEkonomi) { + $sosialEkonomi->update($this->sosialEkonomiPayload($validated) + [ + 'updated_by' => auth()->id(), + ]); + + if ($request->has('pendapatan_komoditas')) { + $this->syncPendapatanKomoditas($sosialEkonomi, $validated['pendapatan_komoditas'] ?? []); + } + + if ($request->has('pendapatan_luar_pertanian')) { + $this->syncPendapatanLuarPertanian($sosialEkonomi, $validated['pendapatan_luar_pertanian'] ?? []); + } + + return $sosialEkonomi->load([ + 'petani', + 'pendapatanKomoditas', + 'pendapatanLuarPertanian', + ]); + }); + + if (!$request->expectsJson()) { + return redirect() + ->route('petani.sosial-ekonomi.edit', $sosialEkonomi->petani_id) + ->with('success', 'Data sosial ekonomi berhasil diperbarui.'); + } + + return response()->json([ + 'status' => 'success', + 'message' => 'Data sosial ekonomi berhasil diperbarui.', + 'data' => $sosialEkonomi, + ]); + } + + public function destroy(string $id): JsonResponse + { + $sosialEkonomi = SosialEkonomi::findOrFail($id); + + DB::transaction(function () use ($sosialEkonomi) { + $sosialEkonomi->update(['deleted_by' => auth()->id()]); + $sosialEkonomi->delete(); + }); + + return response()->json([ + 'status' => 'success', + 'message' => 'Data sosial ekonomi berhasil dihapus.', + ]); + } + + private function validateData(Request $request, ?int $id = null): array + { + return $request->validate([ + 'uid' => [ + 'nullable', + 'string', + 'max:255', + Rule::unique('sosial_ekonomi', 'uid')->ignore($id), + ], + 'petani_id' => ['nullable', 'exists:petani,id'], + 'jumlah_tanggungan' => ['nullable', 'integer', 'min:0'], + 'anak_masih_sekolah' => ['nullable', 'integer', 'min:0'], + 'yang_ikut_bekerja' => ['nullable', 'integer', 'min:0'], + 'skor_periode_paceklik' => ['nullable', 'integer', 'min:1', 'max:5'], + 'bulan_paceklik' => ['nullable', 'string', 'max:255'], + 'sumber_penghasilan_paceklik' => ['nullable', 'string'], + 'total_estimasi_biaya_kebun_per_musim' => ['nullable', 'integer', 'min:0'], + 'skor_kemampuan_menabung' => ['nullable', 'integer', 'min:1', 'max:5'], + 'estimasi_tabungan_per_bulan' => ['nullable', 'integer', 'min:0'], + 'skor_kecukupan_penghasilan' => ['nullable', 'integer', 'min:1', 'max:5'], + 'alasan_kecukupan_penghasilan' => ['nullable', 'string'], + 'status_kepemilikan_lahan' => ['nullable', 'string', 'max:255'], + 'skor_kejelasan_status_lahan' => ['nullable', 'integer', 'min:1', 'max:5'], + 'ada_sertifikat_dokumen' => ['nullable', 'boolean'], + 'ada_sengketa' => ['nullable', 'boolean'], + 'keterangan_sengketa' => ['nullable', 'string'], + 'pihak_membantu_konflik' => ['nullable', 'string', 'max:255'], + 'pihak_membantu_konflik_nama' => ['nullable', 'string', 'max:255'], + 'tahun_bantuan_konflik' => ['nullable', 'integer', 'digits:4'], + 'status_konflik' => ['nullable', 'string', 'max:255'], + + 'pendapatan_komoditas' => ['nullable', 'array'], + 'pendapatan_komoditas.*.kategori' => ['required_with:pendapatan_komoditas', 'string', 'in:utama,lainnya'], + 'pendapatan_komoditas.*.komoditas' => ['nullable', 'string', 'max:255'], + 'pendapatan_komoditas.*.pendapatan' => ['nullable', 'integer', 'min:0'], + 'pendapatan_komoditas.*.periode' => ['nullable', 'string', 'in:musim,tahun'], + + 'pendapatan_luar_pertanian' => ['nullable', 'array'], + 'pendapatan_luar_pertanian.*.jenis_pekerjaan' => ['nullable', 'string', 'max:255'], + 'pendapatan_luar_pertanian.*.estimasi_per_bulan' => ['nullable', 'integer', 'min:0'], + ]); + } + + private function sosialEkonomiPayload(array $validated): array + { + return collect($validated) + ->except(['pendapatan_komoditas', 'pendapatan_luar_pertanian']) + ->merge([ + 'uid' => $validated['uid'] ?? 'SEK-' . Str::uuid(), + ]) + ->all(); + } + + private function syncPendapatanKomoditas(SosialEkonomi $sosialEkonomi, array $items): void + { + $sosialEkonomi->pendapatanKomoditas()->delete(); + + foreach ($items as $item) { + if (!$this->hasPendapatanKomoditasValue($item)) { + continue; + } + + $sosialEkonomi->pendapatanKomoditas()->create([ + 'uid' => $item['uid'] ?? 'PKM-' . Str::uuid(), + 'kategori' => $item['kategori'], + 'komoditas' => $item['komoditas'] ?? null, + 'pendapatan' => $item['pendapatan'] ?? null, + 'periode' => $item['periode'] ?? null, + 'created_by' => auth()->id(), + 'updated_by' => auth()->id(), + ]); + } + } + + private function syncPendapatanLuarPertanian(SosialEkonomi $sosialEkonomi, array $items): void + { + $sosialEkonomi->pendapatanLuarPertanian()->delete(); + + foreach ($items as $item) { + if (!$this->hasPendapatanLuarPertanianValue($item)) { + continue; + } + + $sosialEkonomi->pendapatanLuarPertanian()->create([ + 'uid' => $item['uid'] ?? 'PLP-' . Str::uuid(), + 'jenis_pekerjaan' => $item['jenis_pekerjaan'] ?? null, + 'estimasi_per_bulan' => $item['estimasi_per_bulan'] ?? null, + 'created_by' => auth()->id(), + 'updated_by' => auth()->id(), + ]); + } + } + + private function hasPendapatanKomoditasValue(array $item): bool + { + return filled($item['komoditas'] ?? null) + || filled($item['pendapatan'] ?? null) + || filled($item['periode'] ?? null); + } + + private function hasPendapatanLuarPertanianValue(array $item): bool + { + return filled($item['jenis_pekerjaan'] ?? null) + || filled($item['estimasi_per_bulan'] ?? null); + } +} diff --git a/app/Models/Pertanian/PendapatanKomoditas.php b/app/Models/Pertanian/PendapatanKomoditas.php new file mode 100644 index 0000000..917d013 --- /dev/null +++ b/app/Models/Pertanian/PendapatanKomoditas.php @@ -0,0 +1,32 @@ + 'integer', + ]; + + public function sosialEkonomi(): BelongsTo + { + return $this->belongsTo(SosialEkonomi::class, 'sosial_ekonomi_id'); + } +} diff --git a/app/Models/Pertanian/PendapatanLuarPertanian.php b/app/Models/Pertanian/PendapatanLuarPertanian.php new file mode 100644 index 0000000..bf4261f --- /dev/null +++ b/app/Models/Pertanian/PendapatanLuarPertanian.php @@ -0,0 +1,30 @@ + 'integer', + ]; + + public function sosialEkonomi(): BelongsTo + { + return $this->belongsTo(SosialEkonomi::class, 'sosial_ekonomi_id'); + } +} diff --git a/app/Models/Pertanian/SosialEkonomi.php b/app/Models/Pertanian/SosialEkonomi.php new file mode 100644 index 0000000..b87be0e --- /dev/null +++ b/app/Models/Pertanian/SosialEkonomi.php @@ -0,0 +1,73 @@ + 'integer', + 'anak_masih_sekolah' => 'integer', + 'yang_ikut_bekerja' => 'integer', + 'skor_periode_paceklik' => 'integer', + 'total_estimasi_biaya_kebun_per_musim' => 'integer', + 'skor_kemampuan_menabung' => 'integer', + 'estimasi_tabungan_per_bulan' => 'integer', + 'skor_kecukupan_penghasilan' => 'integer', + 'skor_kejelasan_status_lahan' => 'integer', + 'ada_sertifikat_dokumen' => 'boolean', + 'ada_sengketa' => 'boolean', + 'tahun_bantuan_konflik' => 'integer', + ]; + + public function petani(): BelongsTo + { + return $this->belongsTo(Petani::class, 'petani_id'); + } + + public function pendapatanKomoditas(): HasMany + { + return $this->hasMany(PendapatanKomoditas::class, 'sosial_ekonomi_id'); + } + + public function pendapatanLuarPertanian(): HasMany + { + return $this->hasMany(PendapatanLuarPertanian::class, 'sosial_ekonomi_id'); + } +} diff --git a/resources/views/produktivitas/petani/header.blade.php b/resources/views/produktivitas/petani/header.blade.php index dfe2c65..a41b60f 100644 --- a/resources/views/produktivitas/petani/header.blade.php +++ b/resources/views/produktivitas/petani/header.blade.php @@ -82,7 +82,7 @@