diff --git a/app/Http/Controllers/Web/Dashboard/IndikatorPertanianController.php b/app/Http/Controllers/Web/Dashboard/IndikatorPertanianController.php index 2aa64d7..9f4a55c 100644 --- a/app/Http/Controllers/Web/Dashboard/IndikatorPertanianController.php +++ b/app/Http/Controllers/Web/Dashboard/IndikatorPertanianController.php @@ -15,6 +15,7 @@ use App\Models\Pertanian\PraktikBudidaya; use App\Models\Pertanian\Produksi; use App\Models\Pertanian\SkorPetani; use App\Models\Pertanian\SosialEkonomi; +use App\Models\Pertanian\SurveyProduktivitas; use App\Models\Wilayah\DesaKelurahan; use App\Models\Wilayah\KabupatenKota; use App\Models\Wilayah\Kecamatan; @@ -120,6 +121,12 @@ class IndikatorPertanianController extends Controller 'keparahanSerangan' => $this->keparahanSeranganChart($initialFilters), 'statusHakKelolaLahan' => $this->statusHakKelolaLahanChart($initialFilters), 'praktikPemupukan' => $this->praktikPemupukanChart($initialFilters), + 'produksiPerKomoditas' => $this->produksiPerKomoditasChart($initialFilters), + 'produktivitasPerKomoditas' => $this->produktivitasPerKomoditasChart($initialFilters), + 'luasPanenPerKomoditas' => $this->luasPanenPerKomoditasChart($initialFilters), + 'statusPanen' => $this->statusPanenChart($initialFilters), + 'surveyProduktivitasHa' => $this->surveyProduktivitasByUnitChart($initialFilters, 'ha_tahun'), + 'surveyProduktivitasPohon' => $this->surveyProduktivitasByUnitChart($initialFilters, 'pohon_tahun'), ], ]); } @@ -410,6 +417,123 @@ class IndikatorPertanianController extends Controller ); } + private function produksiPerKomoditasChart(array $filters): array + { + $rows = $this->applyProduksiFilters(Produksi::query(), $filters) + ->leftJoin('master_komoditas as k', 'k.id', '=', 'produksi.komoditas_id') + ->whereNotNull('jumlah_panen') + ->selectRaw("COALESCE(k.nama, 'Belum ditentukan') as label") + ->selectRaw('produksi.jumlah_panen') + ->selectRaw('produksi.satuan') + ->get() + ->groupBy('label') + ->map(fn ($items) => round($items->sum( + fn (Produksi $produksi) => $this->toKilograms( + (float) $produksi->jumlah_panen, + (string) $produksi->satuan + ) + ), 2)) + ->filter(fn ($total) => $total > 0) + ->sortDesc(); + + return [ + 'labels' => $rows->keys()->values()->all(), + 'series' => $rows->values()->map(fn ($value) => round((float) $value, 2))->values()->all(), + ]; + } + + private function produktivitasPerKomoditasChart(array $filters): array + { + $rows = $this->applyProduksiFilters(Produksi::query(), $filters) + ->leftJoin('master_komoditas as k', 'k.id', '=', 'produksi.komoditas_id') + ->selectRaw("COALESCE(k.nama, 'Belum ditentukan') as label") + ->selectRaw('produksi.jumlah_panen') + ->selectRaw('produksi.satuan') + ->selectRaw('produksi.luas_panen') + ->selectRaw('produksi.produktivitas') + ->get() + ->groupBy('label') + ->map(function ($items) { + $storedAverage = $items + ->pluck('produktivitas') + ->filter(fn ($value) => (float) $value > 0) + ->avg(); + + if ($storedAverage > 0) { + return round((float) $storedAverage, 2); + } + + $totalProduksiKg = $items->sum( + fn (Produksi $produksi) => $this->toKilograms( + (float) $produksi->jumlah_panen, + (string) $produksi->satuan + ) + ); + $totalLuasPanen = $items->sum(fn (Produksi $produksi) => (float) $produksi->luas_panen); + + return $totalLuasPanen > 0 + ? round($totalProduksiKg / $totalLuasPanen, 2) + : 0; + }) + ->filter(fn ($total) => $total > 0) + ->sortDesc(); + + return [ + 'labels' => $rows->keys()->values()->all(), + 'series' => $rows->values()->map(fn ($value) => round((float) $value, 2))->values()->all(), + ]; + } + + private function luasPanenPerKomoditasChart(array $filters): array + { + $rows = $this->applyProduksiFilters(Produksi::query(), $filters) + ->leftJoin('master_komoditas as k', 'k.id', '=', 'produksi.komoditas_id') + ->whereNotNull('luas_panen') + ->selectRaw("COALESCE(k.nama, 'Belum ditentukan') as label") + ->selectRaw('SUM(produksi.luas_panen) as total') + ->groupBy('k.id', 'k.nama') + ->havingRaw('SUM(produksi.luas_panen) > 0') + ->orderByDesc('total') + ->get(); + + return [ + 'labels' => $rows->pluck('label')->values()->all(), + 'series' => $rows->pluck('total')->map(fn ($value) => round((float) $value, 2))->values()->all(), + ]; + } + + private function statusPanenChart(array $filters): array + { + $rows = $this->applyProduksiFilters(Produksi::query(), $filters) + ->whereNotNull('status_panen') + ->selectRaw("COALESCE(status_panen, 'Belum ditentukan') as label") + ->selectRaw('COUNT(produksi.id) as total') + ->groupBy('status_panen') + ->orderByDesc('total') + ->get(); + + return $this->chartFromRows($rows, fn ($label) => $this->shortEnumLabel((string) $label)); + } + + private function surveyProduktivitasByUnitChart(array $filters, string $unit): array + { + $rows = $this->applySurveyProduktivitasFilters(SurveyProduktivitas::query(), $filters) + ->leftJoin('master_komoditas as k', 'k.id', '=', 'survey_produktivitas.komoditas_id') + ->where('satuan', $unit) + ->whereNotNull('kuantitas') + ->selectRaw("COALESCE(k.nama, 'Belum ditentukan') as label") + ->selectRaw('AVG(survey_produktivitas.kuantitas) as total') + ->groupBy('k.id', 'k.nama') + ->havingRaw('AVG(survey_produktivitas.kuantitas) > 0') + ->orderByDesc('total') + ->get(); + + return [ + 'labels' => $rows->pluck('label')->values()->all(), + 'series' => $rows->pluck('total')->map(fn ($value) => round((float) $value, 2))->values()->all(), + ]; + } + private function chartFromRows($rows, callable $labelResolver): array { return [ @@ -505,6 +629,15 @@ class IndikatorPertanianController extends Controller }); } + private function applySurveyProduktivitasFilters($query, array $filters) + { + return $query + ->whereHas('petani', function ($petani) use ($filters) { + $this->applyPetaniFilters($petani, $filters); + }) + ->when($filters['komoditas'] !== 'all', fn ($query) => $query->where('komoditas_id', $filters['komoditas'])); + } + private function applyTanamanTableFilters($query, array $filters) { return $query diff --git a/resources/views/dashboard/indikator-pertanian.blade.php b/resources/views/dashboard/indikator-pertanian.blade.php index 9d0af4b..6046602 100644 --- a/resources/views/dashboard/indikator-pertanian.blade.php +++ b/resources/views/dashboard/indikator-pertanian.blade.php @@ -146,7 +146,13 @@ #chart-penyakit-tanaman .apexcharts-tooltip, #chart-keparahan-serangan .apexcharts-tooltip, #chart-status-hak-kelola-lahan .apexcharts-tooltip, - #chart-praktik-pemupukan .apexcharts-tooltip { + #chart-praktik-pemupukan .apexcharts-tooltip, + #chart-produksi-komoditas .apexcharts-tooltip, + #chart-produktivitas-komoditas .apexcharts-tooltip, + #chart-luas-panen-komoditas .apexcharts-tooltip, + #chart-status-panen .apexcharts-tooltip, + #chart-survey-produktivitas-ha .apexcharts-tooltip, + #chart-survey-produktivitas-pohon .apexcharts-tooltip { background: transparent !important; border: none !important; box-shadow: none !important; @@ -531,12 +537,100 @@ +