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 @@ @@ -92,4 +92,4 @@ - \ No newline at end of file + diff --git a/resources/views/produktivitas/petani/sosial-ekonomi/index.blade.php b/resources/views/produktivitas/petani/sosial-ekonomi/index.blade.php new file mode 100644 index 0000000..f173946 --- /dev/null +++ b/resources/views/produktivitas/petani/sosial-ekonomi/index.blade.php @@ -0,0 +1,318 @@ +@extends('layout.main') + +@section('content') +
+ @if (session('success')) +
{{ session('success') }}
+ @endif + + @if ($errors->any()) +
+ +
+ @endif + +
+
+ @include('produktivitas.petani.header', ['petani' => $petani]) + +
+ @csrf + @if($sosialEkonomi) + @method('PUT') + @endif + + + +
+
+
Komposisi Anggota Keluarga
+
+
+ + + @error('jumlah_tanggungan')
{{ $message }}
@enderror +
+
+ + + @error('anak_masih_sekolah')
{{ $message }}
@enderror +
+
+ + + @error('yang_ikut_bekerja')
{{ $message }}
@enderror +
+
+ +
Pendapatan dari Komoditas Utama
+
+ + + + + + + + + + @for($i = 0; $i < 2; $i++) + @php($item = $pendapatanKomoditasUtama->get($i)) + + + + + + @endfor + +
KomoditasPendapatan (Rp)Periode
+ + komoditas) }}"> + + pendapatan) }}"> + + +
+
+ +
Pendapatan dari Komoditas Lain
+
+ + + + + + + + + + @for($i = 0; $i < 2; $i++) + @php($item = $pendapatanKomoditasLainnya->get($i)) + @php($index = $i + 2) + + + + + + @endfor + +
KomoditasPendapatan (Rp)Periode
+ + komoditas) }}"> + + pendapatan) }}"> + + +
+
+ +
Pendapatan di Luar Pertanian
+
+ + + + + + + + + @for($i = 0; $i < 2; $i++) + @php($item = $pendapatanLuarPertanian->get($i)) + + + + + @endfor + +
Jenis PekerjaanEstimasi per Bulan (Rp)
+ jenis_pekerjaan) }}"> + + estimasi_per_bulan) }}"> +
+
+ +
Stabilitas Penghasilan
+
+
+ + + @error('skor_periode_paceklik')
{{ $message }}
@enderror +
+
+ + + @error('bulan_paceklik')
{{ $message }}
@enderror +
+
+ + + @error('sumber_penghasilan_paceklik')
{{ $message }}
@enderror +
+
+ +
Biaya Produksi dan Tabungan
+
+
+ + + @error('total_estimasi_biaya_kebun_per_musim')
{{ $message }}
@enderror +
+
+ + + @error('skor_kemampuan_menabung')
{{ $message }}
@enderror +
+
+ + + @error('estimasi_tabungan_per_bulan')
{{ $message }}
@enderror +
+
+ +
Persepsi Kecukupan Penghasilan
+
+
+ + + @error('skor_kecukupan_penghasilan')
{{ $message }}
@enderror +
+
+ + + @error('alasan_kecukupan_penghasilan')
{{ $message }}
@enderror +
+
+ +
Kondisi Aset & Lahan - Kejelasan Hak Kelola
+
+
+ + + @error('status_kepemilikan_lahan')
{{ $message }}
@enderror +
+
+ + + @error('skor_kejelasan_status_lahan')
{{ $message }}
@enderror +
+
+ + + @error('ada_sertifikat_dokumen')
{{ $message }}
@enderror +
+
+ + + @error('ada_sengketa')
{{ $message }}
@enderror +
+
+
+
+ + + @error('keterangan_sengketa')
{{ $message }}
@enderror +
+
+ + + @error('pihak_membantu_konflik')
{{ $message }}
@enderror +
+
+ + + @error('pihak_membantu_konflik_nama')
{{ $message }}
@enderror +
+
+ + + @error('tahun_bantuan_konflik')
{{ $message }}
@enderror +
+
+ + + @error('status_konflik')
{{ $message }}
@enderror +
+
+ +
+ +
+
+
+
+
+
+
+@endsection + +@push('scripts') + +@endpush diff --git a/routes/web.php b/routes/web.php index c51ac24..ac93d79 100644 --- a/routes/web.php +++ b/routes/web.php @@ -186,7 +186,8 @@ Route::middleware('auth') Route::resource('verifikasi', App\Http\Controllers\Web\Program\VerifikasiController::class)->only('store', 'destroy'); // Petani + Route::get('petani/{petani}/sosial-ekonomi', [App\Http\Controllers\Web\Produktivitas\SosialEkonomiController::class, 'editByPetani'])->name('petani.sosial-ekonomi.edit'); Route::resource('petani', App\Http\Controllers\Web\Produktivitas\PetaniController::class); + Route::resource('sosial-ekonomi', App\Http\Controllers\Web\Produktivitas\SosialEkonomiController::class)->except(['create', 'edit']); Route::resource('petani.lahan-tanaman', App\Http\Controllers\Web\Produktivitas\PetaniLahanController::class); - Route::resource('petani.lahan-tanaman.tanaman', App\Http\Controllers\Web\Produktivitas\PetaniLahanTanamanController::class)->only(['show', 'update', 'destroy']); -}); + Route::resource('petani.lahan-tanaman.tanaman', App\Http\Controllers\Web\Produktivitas\PetaniLahanTanamanController::class)->only(['show', 'update', 'destroy']);});