Merge branch 'main' of https://git.probindo.com/Probindo/database-pertani-web
This commit is contained in:
@@ -55,6 +55,48 @@ class SummaryController extends Controller
|
||||
] + $filterData + $this->productionDashboardData($request));
|
||||
}
|
||||
|
||||
public function mapInformation(Request $request)
|
||||
{
|
||||
if (!Gate::allows('super_admin') && !Gate::allows('admin') && !Gate::allows('fasilitator')) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$validated = $request->validate([
|
||||
'level' => ['nullable', 'in:provinsi,kabupaten,kecamatan,desa'],
|
||||
'id' => ['required_with:level', 'integer'],
|
||||
'provinsi_id' => ['nullable', 'integer'],
|
||||
'kabupatenKota_id' => ['nullable', 'integer'],
|
||||
'kecamatan_id' => ['nullable', 'integer'],
|
||||
'desaKelurahan_id' => ['nullable', 'integer'],
|
||||
'komoditas_id' => ['nullable', 'integer'],
|
||||
'segmen' => ['nullable', 'string'],
|
||||
]);
|
||||
|
||||
$filters = [
|
||||
'provinsi_id' => null,
|
||||
'kabupatenKota_id' => null,
|
||||
'kecamatan_id' => null,
|
||||
'desaKelurahan_id' => null,
|
||||
'komoditas_id' => $validated['komoditas_id'] ?? null,
|
||||
'segmen' => $validated['segmen'] ?? null,
|
||||
];
|
||||
$regionFilter = match ($validated['level'] ?? null) {
|
||||
'provinsi' => 'provinsi_id',
|
||||
'kabupaten' => 'kabupatenKota_id',
|
||||
'kecamatan' => 'kecamatan_id',
|
||||
'desa' => 'desaKelurahan_id',
|
||||
default => null,
|
||||
};
|
||||
|
||||
if ($regionFilter) {
|
||||
$filters[$regionFilter] = $validated['id'];
|
||||
}
|
||||
|
||||
$scopedRequest = Request::create('/dashboard/produktivitas/map-information', 'GET', $filters);
|
||||
|
||||
return response()->json($this->productionMapInformationData($scopedRequest));
|
||||
}
|
||||
|
||||
public function pasar(Request $request)
|
||||
{
|
||||
if (!Gate::allows('super_admin') && !Gate::allows('admin') && !Gate::allows('fasilitator')) {
|
||||
@@ -181,6 +223,7 @@ class SummaryController extends Controller
|
||||
$healthSourceName = $tanaman->isNotEmpty() ? 'tanaman' : 'lahan';
|
||||
|
||||
$landMetrics = $this->karakteristikLandMetrics($request);
|
||||
$totalPetani = $landMetrics['total_petani'];
|
||||
$totalLuasLahan = $landMetrics['total_luas_lahan'];
|
||||
$avgLuasPerPetani = $landMetrics['ratarata_luas_lahan'];
|
||||
$actualProductivity = $this->actualProductivityByCommodityChart($request);
|
||||
@@ -190,6 +233,14 @@ class SummaryController extends Controller
|
||||
$aksesPasar = $this->filteredAksesPasar($request);
|
||||
|
||||
$kpiCards = [
|
||||
[
|
||||
'value' => number_format($totalPetani, 0, ',', '.'),
|
||||
'unit' => 'orang',
|
||||
'label' => 'Jumlah Petani',
|
||||
'description' => 'Petani sesuai filter yang dipilih',
|
||||
'icon' => 'tabler-users',
|
||||
'variant' => 'primary',
|
||||
],
|
||||
[
|
||||
'value' => number_format($totalLuasLahan, 2, ',', '.'),
|
||||
'unit' => 'ha',
|
||||
@@ -262,6 +313,121 @@ class SummaryController extends Controller
|
||||
],
|
||||
'levels' => $levels,
|
||||
'cultivationLevels' => $this->productionCultivationMapLevelData($request, $levels),
|
||||
'information' => $this->productionMapInformationData($request),
|
||||
];
|
||||
}
|
||||
|
||||
private function productionMapInformationData(Request $request): array
|
||||
{
|
||||
$filteredMapLahan = (clone $this->filteredLahanQuery($request))
|
||||
->leftJoin('profiles', 'profiles.id', '=', 'map_lahan.profile_id')
|
||||
->leftJoin('petani', 'petani.id', '=', 'map_lahan.petani_id')
|
||||
->tap(fn ($query) => $this->whereActiveMapOwner($query));
|
||||
$mapLahanRows = (clone $filteredMapLahan)->get([
|
||||
'map_lahan.id',
|
||||
'map_lahan.petani_id',
|
||||
'map_lahan.luas_lahan',
|
||||
'map_lahan.serangan_hama',
|
||||
'map_lahan.penyakit_tanaman',
|
||||
'map_lahan.jenis_hama',
|
||||
'map_lahan.jenis_penyakit',
|
||||
]);
|
||||
$petaniIds = $mapLahanRows->pluck('petani_id')->filter()->unique()->values();
|
||||
$commodityRows = (clone $filteredMapLahan)
|
||||
->leftJoin('master_komoditas as map_komoditas', 'map_komoditas.id', '=', 'map_lahan.komoditas_id')
|
||||
->whereNotNull('map_lahan.petani_id')
|
||||
->selectRaw("COALESCE(map_komoditas.nama, 'Belum ditentukan') as nama")
|
||||
->selectRaw('COUNT(DISTINCT map_lahan.petani_id) as jumlah')
|
||||
->groupBy('map_komoditas.nama')
|
||||
->orderByDesc('jumlah')
|
||||
->get()
|
||||
->map(fn ($row) => ['nama' => $row->nama, 'jumlah' => (int) $row->jumlah])
|
||||
->all();
|
||||
|
||||
$tanamanByLahan = DB::table('map_tanaman')
|
||||
->whereNull('map_tanaman.deleted_at')
|
||||
->whereIn('map_tanaman.lahan_id', $mapLahanRows->pluck('id'))
|
||||
->get([
|
||||
'map_tanaman.lahan_id',
|
||||
'map_tanaman.serangan_hama',
|
||||
'map_tanaman.penyakit_tanaman',
|
||||
'map_tanaman.jenis_hama',
|
||||
'map_tanaman.jenis_penyakit',
|
||||
])
|
||||
->groupBy('lahan_id');
|
||||
$optCounts = [];
|
||||
|
||||
foreach ($mapLahanRows as $land) {
|
||||
foreach ($this->productionOptDetails($land, $tanamanByLahan->get($land->id, collect())) as $opt) {
|
||||
$optCounts[$opt] = ($optCounts[$opt] ?? 0) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
arsort($optCounts);
|
||||
|
||||
$mainCommodityIds = DB::table('master_komoditas')
|
||||
->where('is_utama', true)
|
||||
->whereNull('deleted_at')
|
||||
->select('id');
|
||||
$scorePetaniIds = DB::table('petani')
|
||||
->whereIn('petani.id', $petaniIds)
|
||||
->whereIn('petani.komoditas_id', $mainCommodityIds)
|
||||
->select('petani.id')
|
||||
->pluck('petani.id');
|
||||
$scoreQuery = DB::table('petani')
|
||||
->leftJoin('petani_skor', function ($join) {
|
||||
$join->on('petani_skor.petani_id', '=', 'petani.id')
|
||||
->whereNull('petani_skor.deleted_at');
|
||||
})
|
||||
->whereNull('petani.deleted_at')
|
||||
->whereIn('petani.id', $scorePetaniIds);
|
||||
$averageIndex = (clone $scoreQuery)->avg('petani_skor.skor_kesiapan_adopsi');
|
||||
$segmentCase = "CASE
|
||||
WHEN petani_skor.skor_kesiapan_adopsi >= 4 THEN 'Penggerak'
|
||||
WHEN petani_skor.skor_kesiapan_adopsi >= 3 THEN 'Perintis'
|
||||
WHEN petani_skor.skor_kesiapan_adopsi >= 2 THEN 'Pemerhati'
|
||||
WHEN petani_skor.skor_kesiapan_adopsi >= 1 THEN 'Pemula'
|
||||
ELSE 'Belum Lengkap'
|
||||
END";
|
||||
$segmentCounts = (clone $scoreQuery)
|
||||
->selectRaw("{$segmentCase} as segmen")
|
||||
->selectRaw('COUNT(DISTINCT petani.id) as jumlah')
|
||||
->groupByRaw($segmentCase)
|
||||
->get();
|
||||
$segmentPriority = [
|
||||
'Penggerak' => 0,
|
||||
'Perintis' => 1,
|
||||
'Pemerhati' => 2,
|
||||
'Pemula' => 3,
|
||||
'Belum Lengkap' => 4,
|
||||
];
|
||||
$dominantSegment = $segmentCounts
|
||||
->sort(function ($left, $right) use ($segmentPriority) {
|
||||
return ((int) $right->jumlah <=> (int) $left->jumlah)
|
||||
?: (($segmentPriority[$left->segmen] ?? 99) <=> ($segmentPriority[$right->segmen] ?? 99));
|
||||
})
|
||||
->first();
|
||||
$averageSegment = match (true) {
|
||||
$averageIndex === null => 'Belum Lengkap',
|
||||
$averageIndex >= 4 => 'Penggerak',
|
||||
$averageIndex >= 3 => 'Perintis',
|
||||
$averageIndex >= 2 => 'Pemerhati',
|
||||
$averageIndex >= 1 => 'Pemula',
|
||||
default => 'Belum Lengkap',
|
||||
};
|
||||
|
||||
return [
|
||||
'jumlah_petani' => $petaniIds->count(),
|
||||
'jumlah_lahan' => $mapLahanRows->count(),
|
||||
'total_luas_lahan' => (float) $mapLahanRows->sum('luas_lahan'),
|
||||
'petani_per_komoditas' => $commodityRows,
|
||||
'opt' => collect($optCounts)
|
||||
->map(fn ($jumlah, $nama) => ['nama' => $nama, 'jumlah' => $jumlah])
|
||||
->values()
|
||||
->all(),
|
||||
'indeks' => $averageIndex === null ? null : round((float) $averageIndex, 2),
|
||||
'segmen' => $averageSegment,
|
||||
'segmen_dominan' => $dominantSegment->segmen ?? 'Belum Lengkap',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user