solve dashboard survey petani
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -401,6 +401,10 @@
|
||||
Petani
|
||||
</th>
|
||||
|
||||
<th style="font-size:10px;letter-spacing:.7px;text-transform:uppercase">
|
||||
Komoditas
|
||||
</th>
|
||||
|
||||
<th class="text-center"
|
||||
style="font-size:10px;letter-spacing:.7px;text-transform:uppercase">
|
||||
Lahan
|
||||
@@ -474,19 +478,28 @@
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<span
|
||||
class="badge bg-label-secondary text-secondary"
|
||||
title="{{ $petani['komoditas'] }}"
|
||||
>
|
||||
{{ $petani['komoditas'] }}
|
||||
</span>
|
||||
</td>
|
||||
|
||||
@foreach ($petani['status'] as $status)
|
||||
<td class="text-center">
|
||||
@if ($status['done'])
|
||||
<span
|
||||
class="badge rounded-pill bg-label-success text-success"
|
||||
title="{{ $status['label'] }} sudah diisi"
|
||||
title="{{ $status['label'] }} lengkap"
|
||||
>
|
||||
<i class="ti tabler-check"></i>
|
||||
</span>
|
||||
@else
|
||||
<span
|
||||
class="badge rounded-pill bg-label-secondary text-secondary"
|
||||
title="{{ $status['label'] }} belum diisi"
|
||||
title="{{ $status['label'] }} belum lengkap"
|
||||
>
|
||||
<i class="ti tabler-minus"></i>
|
||||
</span>
|
||||
@@ -533,7 +546,7 @@
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="7" class="text-center text-muted py-4">
|
||||
<td colspan="8" class="text-center text-muted py-4">
|
||||
Belum ada data petani.
|
||||
</td>
|
||||
</tr>
|
||||
@@ -818,4 +831,4 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@endsection
|
||||
|
||||
Reference in New Issue
Block a user