From 609919ba300ec7fb434ddd7d16ce7713df570305 Mon Sep 17 00:00:00 2001 From: SyaharaniSalsabilla Date: Wed, 19 Aug 2026 16:21:42 +0700 Subject: [PATCH] solve dashboard survey petani --- .../Web/Dashboard/SurveyPetaniController.php | 206 +++++++++++++++--- .../views/dashboard/survey-petani.blade.php | 21 +- 2 files changed, 192 insertions(+), 35 deletions(-) diff --git a/app/Http/Controllers/Web/Dashboard/SurveyPetaniController.php b/app/Http/Controllers/Web/Dashboard/SurveyPetaniController.php index 1f1ece3..f35b373 100644 --- a/app/Http/Controllers/Web/Dashboard/SurveyPetaniController.php +++ b/app/Http/Controllers/Web/Dashboard/SurveyPetaniController.php @@ -4,6 +4,7 @@ namespace App\Http\Controllers\Web\Dashboard; use App\Http\Controllers\Controller; use Illuminate\Http\Request; +use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\DB; use Illuminate\Support\Str; @@ -14,6 +15,9 @@ use App\Models\Pertanian\Lahan; use App\Models\Pertanian\Tanaman; use App\Models\Pertanian\SurveyPelatihan; use App\Models\Pertanian\SurveySertifikasi; +use App\Enums\AksesPasar\PraktikFermentasi; +use App\Enums\AksesPasar\SaluranTerdahulu; +use App\Enums\AksesPasar\SkorPengalaman; use BackedEnum; @@ -92,36 +96,34 @@ class SurveyPetaniController extends Controller // Progres pengisian data per petani $progressPetani = Petani::query() - ->select([ - 'id', - 'nama', - ]) - ->withExists([ - 'lahans as has_lahan', - 'praktikBudidaya as has_praktik_budidaya', - 'sosialEkonomi as has_sosial_ekonomi', - 'aksesPasar as has_akses_pasar', + ->select(['id', 'nama', 'komoditas_id']) + ->with([ + 'komoditas:id,nama', + 'lahans', + 'praktikBudidaya', + 'sosialEkonomi', + 'aksesPasar', ]) ->orderBy('nama') ->get() ->map(function ($petani) { $status = [ - 'lahan' => [ - 'label' => 'Lahan', - 'done' => (bool) $petani->has_lahan, - ], - 'praktik_budidaya' => [ - 'label' => 'Praktik Budidaya', - 'done' => (bool) $petani->has_praktik_budidaya, - ], - 'sosial_ekonomi' => [ - 'label' => 'Sosial Ekonomi', - 'done' => (bool) $petani->has_sosial_ekonomi, - ], - 'akses_pasar' => [ - 'label' => 'Akses Pasar', - 'done' => (bool) $petani->has_akses_pasar, - ], + 'lahan' => $this->moduleStatus( + 'Lahan', + $this->hasCompleteLahan($petani) + ), + 'praktik_budidaya' => $this->moduleStatus( + 'Praktik Budidaya', + $this->hasCompletePraktikBudidaya($petani->praktikBudidaya) + ), + 'sosial_ekonomi' => $this->moduleStatus( + 'Sosial Ekonomi', + $this->hasCompleteSosialEkonomi($petani->sosialEkonomi) + ), + 'akses_pasar' => $this->moduleStatus( + 'Akses Pasar', + $this->hasCompleteAksesPasar($petani->aksesPasar) + ), ]; $totalModul = count($status); @@ -131,12 +133,13 @@ class SurveyPetaniController extends Controller ->count(); return [ - 'id' => $petani->id, - 'name' => $petani->nama, - 'status' => $status, - 'done' => $modulSelesai, - 'total' => $totalModul, - 'percent' => $totalModul > 0 + 'id' => $petani->id, + 'name' => $petani->nama, + 'komoditas' => $petani->komoditas?->nama ?? 'Belum ditentukan', + 'status' => $status, + 'done' => $modulSelesai, + 'total' => $totalModul, + 'percent' => $totalModul > 0 ? (int) round(($modulSelesai / $totalModul) * 100) : 0, ]; @@ -278,6 +281,147 @@ class SurveyPetaniController extends Controller ]); } + private function moduleStatus(string $label, bool $done): array + { + return [ + 'label' => $label, + 'done' => $done, + ]; + } + + private function hasCompleteLahan(Petani $petani): bool + { + return $petani->lahans->contains(function ($lahan) { + return $this->allFieldsFilled($lahan, [ + 'luas_lahan', + 'komoditas_id', + 'jenis_komoditas_id', + 'umur_tanaman', + 'kondisi_tanaman', + ]); + }); + } + + private function hasCompletePraktikBudidaya(?Model $praktikBudidaya): bool + { + return $this->allFieldsFilled($praktikBudidaya, [ + 'frekuensi_pemangkasan_utama', + 'pemberian_pupuk', + 'metode_penanganan_opt', + 'frekuensi_sanitasi_lahan', + 'penanganan_gulma', + 'kondisi_pengelolaan_air', + ]); + } + + private function hasCompleteSosialEkonomi(?Model $sosialEkonomi): bool + { + return $this->allFieldsFilled($sosialEkonomi, [ + 'skor_periode_paceklik', + 'skor_kemampuan_menabung', + 'skor_kecukupan_penghasilan', + 'skor_kejelasan_status_lahan', + 'kemauan_mencoba_praktik_baru', + 'pemahaman_mutu_harga', + 'panutan_petani_sukses', + 'kemauan_ikut_program', + 'orientasi_rencana_jangka_panjang', + 'keaktifan_pertemuan_kelompok', + 'peran_dalam_kelompok', + 'manfaat_kelompok_tani', + 'status_rekening_tabungan', + 'pengalaman_kredit_kebun', + 'kondisi_aset_produktif', + 'keterlibatan_program_keuangan_formal', + 'keterikatan_hutang_panen', + 'praktik_ijon', + 'kebebasan_memilih_pembeli', + ]); + } + + private function hasCompleteAksesPasar(?Model $aksesPasar): bool + { + if (! $this->allFieldsFilled($aksesPasar, [ + 'skor_pengalaman', + 'praktik_fermentasi', + 'skor_kesadaran_premium', + 'tingkat_kepercayaan_pembeli_baru', + ])) { + return false; + } + + $skorPengalaman = (int) $aksesPasar->getAttribute('skor_pengalaman'); + + if ( + $skorPengalaman !== SkorPengalaman::BELUM_PERNAH->value + && ! $this->valueIsFilled($aksesPasar->getAttribute('saluran_terdahulu')) + ) { + return false; + } + + if ( + in_array($skorPengalaman, [ + SkorPengalaman::PERNAH_BERHENTI_TIDAK_ADA_AKSES->value, + SkorPengalaman::PERNAH_BERHENTI_MUNGKIN_KEMBALI->value, + ], true) + && ! $this->valueIsFilled($aksesPasar->getAttribute('alasan_berhenti')) + ) { + return false; + } + + if ( + in_array( + SaluranTerdahulu::LAINNYA->value, + $aksesPasar->getAttribute('saluran_terdahulu') ?? [], + true + ) + && ! $this->valueIsFilled($aksesPasar->getAttribute('saluran_terdahulu_lainnya')) + ) { + return false; + } + + if ( + $aksesPasar->getAttribute('praktik_fermentasi') !== PraktikFermentasi::BELUM_PERNAH->value + && ! $this->allFieldsFilled($aksesPasar, [ + 'proses_fermentasi', + 'model_fermentasi_memungkinkan', + ]) + ) { + return false; + } + + return true; + } + + private function allFieldsFilled(?Model $model, array $fields): bool + { + if (! $model) { + return false; + } + + foreach ($fields as $field) { + if (! $this->valueIsFilled($model->getAttribute($field))) { + return false; + } + } + + return true; + } + + private function valueIsFilled(mixed $value): bool + { + if ($value instanceof BackedEnum) { + $value = $value->value; + } + + if (is_array($value)) { + return collect($value) + ->contains(fn ($item) => $this->valueIsFilled($item)); + } + + return ! is_null($value) && $value !== ''; + } + private function pelatihanGapOptions(): array { $enumClass = self::GAP_ENUM_CLASS; diff --git a/resources/views/dashboard/survey-petani.blade.php b/resources/views/dashboard/survey-petani.blade.php index 681e1b2..c7e7ea4 100644 --- a/resources/views/dashboard/survey-petani.blade.php +++ b/resources/views/dashboard/survey-petani.blade.php @@ -401,6 +401,10 @@ Petani + + Komoditas + + Lahan @@ -474,19 +478,28 @@ + + + {{ $petani['komoditas'] }} + + + @foreach ($petani['status'] as $status) @if ($status['done']) @else @@ -533,7 +546,7 @@ @empty - + Belum ada data petani. @@ -818,4 +831,4 @@ -@endsection \ No newline at end of file +@endsection