karakteristik petani

This commit is contained in:
2026-10-06 17:52:34 +07:00
parent 7fdf9b400d
commit 393cf0d0d1
9 changed files with 5489 additions and 2979 deletions
@@ -11,6 +11,7 @@ use App\Models\Pertanian\Petani;
use App\Models\Pertanian\Komoditas;
use App\Models\Pertanian\Lahan;
use App\Models\Pertanian\PendapatanKomoditas;
use App\Models\Pertanian\SosialEkonomi;
class DemografiPetaniController extends Controller
{
@@ -20,7 +21,35 @@ class DemografiPetaniController extends Controller
abort(403);
}
$petaniCounts = Petani::selectRaw("
return redirect()->route('dashboard.profil-pertanian', array_merge($request->query(), [
'tab' => 'demografi-petani',
]));
}
public function profil(Request $request)
{
if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) {
abort(403);
}
$activeTab = $request->query('tab') === 'indeks-petani'
? 'indeks-petani'
: 'demografi-petani';
$demografiData = $this->contentData($request);
$indeksData = app(IndeksPetaniController::class)->contentData($request);
return view('dashboard.profil-pertanian', [
'activeTab' => $activeTab,
'indeksFilterAction' => route('dashboard.profil-pertanian'),
] + $demografiData + $indeksData);
}
public function contentData(Request $request): array
{
$filteredPetaniIds = $this->filteredPetaniIdsQuery($request);
$petaniCounts = Petani::whereIn('petani.id', clone $filteredPetaniIds)->selectRaw("
COUNT(*) as total,
COUNT(*) FILTER (WHERE jenis_kelamin = true) as laki,
COUNT(*) FILTER (WHERE jenis_kelamin = false) as perempuan
@@ -30,14 +59,18 @@ class DemografiPetaniController extends Controller
$petaniLakilaki = $petaniCounts->laki;
$petaniPerempuan = $petaniCounts->perempuan;
$totalKomoditas = Petani::whereNotNull('komoditas_id')
->distinct()
->count('komoditas_id');
$totalKomoditas = Komoditas::query()
->where('is_utama', true)
->whereHas('petani', fn ($query) => $query->whereIn('petani.id', clone $filteredPetaniIds))
->count();
$totalLuasLahan = Lahan::has('petani')->sum('luas_lahan');
$totalLuasLahan = Lahan::has('petani')
->whereIn('petani_id', clone $filteredPetaniIds)
->sum('luas_lahan');
$ratarataLuasLahan = $totalLuasLahan && $totalPetani ? $totalLuasLahan / $totalPetani : 0;
$umurCounts = Petani::whereNotNull('tanggal_lahir')->selectRaw("
$umurCounts = Petani::whereIn('petani.id', clone $filteredPetaniIds)
->whereNotNull('tanggal_lahir')->selectRaw("
COUNT(*) FILTER (WHERE EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) < 30) as kurang_30,
COUNT(*) FILTER (WHERE EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 30 AND 39) as umur_30_39,
COUNT(*) FILTER (WHERE EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 40 AND 49) as umur_40_49,
@@ -45,7 +78,8 @@ class DemografiPetaniController extends Controller
COUNT(*) FILTER (WHERE EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) >= 60) as umur_60_keatas
")->first();
$pendidikanCounts = Petani::whereNotNull('pendidikan_terakhir')
$pendidikanCounts = Petani::whereIn('petani.id', clone $filteredPetaniIds)
->whereNotNull('pendidikan_terakhir')
->select('pendidikan_terakhir', DB::raw('COUNT(*) as total'))
->groupBy('pendidikan_terakhir')
->pluck('total', 'pendidikan_terakhir');
@@ -59,20 +93,71 @@ class DemografiPetaniController extends Controller
's1_keatas' => (int) ($pendidikanCounts['06_sarjana'] ?? 0) + (int) ($pendidikanCounts['07_magister'] ?? 0),
];
$jumlahTanggunganBuckets = SosialEkonomi::query()
->whereIn('petani_id', clone $filteredPetaniIds)
->whereNotNull('jumlah_tanggungan')
->selectRaw("
COUNT(DISTINCT petani_id) FILTER (WHERE jumlah_tanggungan = 0) as tanggungan_0,
COUNT(DISTINCT petani_id) FILTER (WHERE jumlah_tanggungan BETWEEN 1 AND 2) as tanggungan_1_2,
COUNT(DISTINCT petani_id) FILTER (WHERE jumlah_tanggungan BETWEEN 3 AND 4) as tanggungan_3_4,
COUNT(DISTINCT petani_id) FILTER (WHERE jumlah_tanggungan >= 5) as tanggungan_5_keatas
")
->first();
$jumlahTanggungan = [
'0' => (int) ($jumlahTanggunganBuckets->tanggungan_0 ?? 0),
'1_2' => (int) ($jumlahTanggunganBuckets->tanggungan_1_2 ?? 0),
'3_4' => (int) ($jumlahTanggunganBuckets->tanggungan_3_4 ?? 0),
'5_keatas' => (int) ($jumlahTanggunganBuckets->tanggungan_5_keatas ?? 0),
];
$kelompokTaniBuckets = Petani::query()
->whereIn('petani.id', clone $filteredPetaniIds)
->leftJoin('sosial_ekonomi', function ($join) {
$join->on('sosial_ekonomi.petani_id', '=', 'petani.id')
->whereNull('sosial_ekonomi.deleted_at');
})
->selectRaw("
COUNT(DISTINCT petani.id) FILTER (WHERE sosial_ekonomi.terdaftar_kelompok_tani = 'ya') as terdaftar,
COUNT(DISTINCT petani.id) FILTER (WHERE sosial_ekonomi.terdaftar_kelompok_tani = 'tidak') as tidak_terdaftar,
COUNT(DISTINCT petani.id) FILTER (WHERE sosial_ekonomi.terdaftar_kelompok_tani IS NULL OR sosial_ekonomi.terdaftar_kelompok_tani NOT IN ('ya', 'tidak')) as belum_terisi
")
->first();
$kelompokTani = [
'terdaftar' => (int) ($kelompokTaniBuckets->terdaftar ?? 0),
'tidak_terdaftar' => (int) ($kelompokTaniBuckets->tidak_terdaftar ?? 0),
'belum_terisi' => (int) ($kelompokTaniBuckets->belum_terisi ?? 0),
];
$desaSasaranRows = Petani::query()
->leftJoin('master_desa_kelurahan as desa', 'petani.desa_kelurahan_id', '=', 'desa.id')
->whereIn('petani.id', clone $filteredPetaniIds)
->selectRaw('petani.desa_kelurahan_id as desa_id')
->selectRaw("COALESCE(desa.nama, 'Tidak diketahui') as desa")
->selectRaw('COUNT(*) as total')
->groupBy('petani.desa_kelurahan_id', 'desa.nama')
->orderByDesc('total')
->orderBy('desa')
->get();
$komoditasUtama = Komoditas::query()
->whereHas('petani')
->withCount('petani')
->whereHas('petani', fn ($query) => $query->whereIn('petani.id', clone $filteredPetaniIds))
->withCount(['petani' => fn ($query) => $query->whereIn('petani.id', clone $filteredPetaniIds)])
->orderByDesc('petani_count')
->get(['id', 'nama']);
$luasLahanBuckets = DB::query()->fromSub(
Lahan::query()->select('petani_id')->selectRaw('SUM(luas_lahan) as total_luas')->groupBy('petani_id'),
Lahan::query()
->whereIn('petani_id', clone $filteredPetaniIds)
->select('petani_id')
->selectRaw('luas_lahan'),
'agg'
)->selectRaw("
COUNT(*) FILTER (WHERE total_luas < 5000) as kurang_05,
COUNT(*) FILTER (WHERE total_luas >= 5000 AND total_luas <= 10000) as luas_05_1,
COUNT(*) FILTER (WHERE total_luas > 10000 AND total_luas <= 20000) as luas_1_2,
COUNT(*) FILTER (WHERE total_luas > 20000) as lebih_2
COUNT(DISTINCT petani_id) FILTER (WHERE luas_lahan < 0.5) as kurang_05,
COUNT(DISTINCT petani_id) FILTER (WHERE luas_lahan >= 0.5 AND luas_lahan <= 1) as luas_05_1,
COUNT(DISTINCT petani_id) FILTER (WHERE luas_lahan > 1 AND luas_lahan <= 2) as luas_1_2,
COUNT(DISTINCT petani_id) FILTER (WHERE luas_lahan > 2) as lebih_2
")->first();
$luasLahan = [
@@ -82,12 +167,28 @@ class DemografiPetaniController extends Controller
'lebih_2' => $luasLahanBuckets->lebih_2,
];
$statusKepemilikanLahanRows = Lahan::query()
->whereIn('petani_id', clone $filteredPetaniIds)
->whereNotNull('status_kepemilikan')
->selectRaw('status_kepemilikan as status')
->selectRaw('COUNT(DISTINCT petani_id) as total')
->groupBy('status_kepemilikan')
->orderByDesc('total')
->get();
$pendapatanPerPetaniQuery = PendapatanKomoditas::query()
->join('sosial_ekonomi', 'sosial_ekonomi.id', '=', 'pendapatan_komoditas.sosial_ekonomi_id')
->whereNotNull('sosial_ekonomi.petani_id')
->whereIn('sosial_ekonomi.petani_id', clone $filteredPetaniIds)
->groupBy('sosial_ekonomi.petani_id')
->selectRaw('SUM(pendapatan_komoditas.pendapatan) as total_pendapatan');
$ratarataPenghasilan = (float) DB::query()
->fromSub(clone $pendapatanPerPetaniQuery, 'agg')
->avg('total_pendapatan');
$penghasilanBuckets = DB::query()->fromSub(
PendapatanKomoditas::query()
->join('sosial_ekonomi', 'sosial_ekonomi.id', '=', 'pendapatan_komoditas.sosial_ekonomi_id')
->whereNotNull('sosial_ekonomi.petani_id')
->groupBy('sosial_ekonomi.petani_id')
->selectRaw('SUM(pendapatan_komoditas.pendapatan) as total_pendapatan'),
clone $pendapatanPerPetaniQuery,
'agg'
)->selectRaw("
COUNT(*) FILTER (WHERE total_pendapatan < 1000000) as kurang_1,
@@ -112,6 +213,7 @@ class DemografiPetaniController extends Controller
'total_komoditas' => $totalKomoditas,
'total_luas_lahan' => $totalLuasLahan,
'ratarata_luas_lahan' => $ratarataLuasLahan,
'ratarata_penghasilan' => $ratarataPenghasilan,
'kelompok_umur' => [
'kurang_30' => $umurCounts->kurang_30,
'30_39' => $umurCounts->umur_30_39,
@@ -120,31 +222,94 @@ class DemografiPetaniController extends Controller
'60_keatas' => $umurCounts->umur_60_keatas,
],
'pendidikan' => $pendidikan,
'jumlah_tanggungan' => $jumlahTanggungan,
'kelompok_tani' => $kelompokTani,
'desa_sasaran' => [
'total' => $desaSasaranRows->count(),
'ids' => $desaSasaranRows->pluck('desa_id')->values(),
'labels' => $desaSasaranRows->pluck('desa')->values(),
'series' => $desaSasaranRows->pluck('total')->map(fn ($v) => (int) $v)->values(),
],
'komoditas_utama' => [
'ids' => $komoditasUtama->pluck('id')->values(),
'labels' => $komoditasUtama->pluck('nama')->values(),
'series' => $komoditasUtama->pluck('petani_count')->map(fn ($v) => (int) $v)->values(),
],
'luas_lahan' => $luasLahan,
'status_kepemilikan_lahan' => [
'keys' => $statusKepemilikanLahanRows->pluck('status')->values(),
'labels' => $statusKepemilikanLahanRows
->pluck('status')
->map(fn ($status) => $this->statusLahanLabel((string) $status))
->values(),
'series' => $statusKepemilikanLahanRows->pluck('total')->map(fn ($v) => (int) $v)->values(),
],
'penghasilan' => $penghasilan,
];
$daftarPetani = Petani::with(['komoditas'])
->whereIn('petani.id', clone $filteredPetaniIds)
->withSum('lahans as total_luas_lahan', 'luas_lahan')
->orderBy('id')
->paginate(10);
return view('dashboard.demografi-petani', compact('data', 'daftarPetani'));
return compact('data', 'daftarPetani');
}
private function filteredPetaniIdsQuery(Request $request)
{
$query = Petani::query()
->leftJoin('master_desa_kelurahan as desa', 'petani.desa_kelurahan_id', '=', 'desa.id')
->leftJoin('master_kecamatan as kecamatan', 'desa.kecamatan_id', '=', 'kecamatan.id')
->leftJoin('master_kabupaten_kota as kabupaten', 'kecamatan.kabupaten_kota_id', '=', 'kabupaten.id')
->when($request->filled('provinsi_id'), fn ($query) => $query->where('kabupaten.provinsi_id', $request->provinsi_id))
->when($request->filled('kabupatenKota_id'), fn ($query) => $query->where('kecamatan.kabupaten_kota_id', $request->kabupatenKota_id))
->when($request->filled('kecamatan_id'), fn ($query) => $query->where('desa.kecamatan_id', $request->kecamatan_id))
->when($request->filled('desaKelurahan_id'), fn ($query) => $query->where('petani.desa_kelurahan_id', $request->desaKelurahan_id))
->when($request->filled('komoditas_id'), fn ($query) => $query->where('petani.komoditas_id', $request->komoditas_id));
if ($request->filled('segmen')) {
$query->whereHas('skor', function ($query) use ($request) {
match ($request->segmen) {
'Penggerak' => $query->where('skor_kesiapan_adopsi', '>=', 4),
'Perintis' => $query->where('skor_kesiapan_adopsi', '>=', 3)
->where('skor_kesiapan_adopsi', '<', 4),
'Pemerhati' => $query->where('skor_kesiapan_adopsi', '>=', 2)
->where('skor_kesiapan_adopsi', '<', 3),
'Pemula' => $query->where('skor_kesiapan_adopsi', '>=', 1)
->where('skor_kesiapan_adopsi', '<', 2),
'Belum Lengkap' => $query->where(function ($query) {
$query->whereNull('skor_kesiapan_adopsi')
->orWhere('skor_kesiapan_adopsi', '<', 1);
}),
default => null,
};
});
}
return $query->select('petani.id');
}
private function statusLahanLabel(string $status): string
{
return match ($status) {
'sendiri' => 'Milik Pribadi',
'sewa' => 'Sewa',
'adat' => 'Tanah Adat',
default => ucwords(str_replace('_', ' ', $status)),
};
}
public function data(Request $request)
{
$filteredPetaniIds = $this->filteredPetaniIdsQuery($request);
$pendapatanSub = PendapatanKomoditas::query()
->join('sosial_ekonomi', 'sosial_ekonomi.id', '=', 'pendapatan_komoditas.sosial_ekonomi_id')
->whereColumn('sosial_ekonomi.petani_id', 'petani.id')
->selectRaw('SUM(pendapatan_komoditas.pendapatan)');
$query = Petani::with('komoditas')
->whereIn('petani.id', clone $filteredPetaniIds)
->withSum('lahans as total_luas_lahan', 'luas_lahan')
->addSelect(['total_pendapatan' => $pendapatanSub]);
@@ -187,6 +352,45 @@ class DemografiPetaniController extends Controller
}
}
if ($request->filled('jumlah_tanggungan')) {
$tanggunganQuery = SosialEkonomi::query()
->whereIn('petani_id', clone $filteredPetaniIds)
->whereNotNull('jumlah_tanggungan')
->select('petani_id')
->distinct();
match ($request->jumlah_tanggungan) {
'0' => $tanggunganQuery->where('jumlah_tanggungan', 0),
'1_2' => $tanggunganQuery->whereBetween('jumlah_tanggungan', [1, 2]),
'3_4' => $tanggunganQuery->whereBetween('jumlah_tanggungan', [3, 4]),
'5_keatas' => $tanggunganQuery->where('jumlah_tanggungan', '>=', 5),
default => null,
};
$query->whereIn('petani.id', $tanggunganQuery);
}
if ($request->filled('kelompok_tani')) {
match ($request->kelompok_tani) {
'terdaftar' => $query->whereIn('petani.id', SosialEkonomi::query()
->whereIn('petani_id', clone $filteredPetaniIds)
->where('terdaftar_kelompok_tani', 'ya')
->select('petani_id')
->distinct()),
'tidak_terdaftar' => $query->whereIn('petani.id', SosialEkonomi::query()
->whereIn('petani_id', clone $filteredPetaniIds)
->where('terdaftar_kelompok_tani', 'tidak')
->select('petani_id')
->distinct()),
'belum_terisi' => $query->whereNotIn('petani.id', SosialEkonomi::query()
->whereIn('petani_id', clone $filteredPetaniIds)
->whereIn('terdaftar_kelompok_tani', ['ya', 'tidak'])
->select('petani_id')
->distinct()),
default => null,
};
}
if ($request->filled('komoditas')) {
$query->where('komoditas_id', $request->komoditas);
}
@@ -213,15 +417,28 @@ class DemografiPetaniController extends Controller
}
if ($request->filled('luas_lahan')) {
$lahanQuery = Lahan::query()->select('petani_id')->groupBy('petani_id');
$lahanQuery = Lahan::query()
->whereIn('petani_id', clone $filteredPetaniIds)
->select('petani_id')
->distinct();
match ($request->luas_lahan) {
'kurang_05' => $lahanQuery->havingRaw('SUM(luas_lahan) < 5000'),
'05_1' => $lahanQuery->havingRaw('SUM(luas_lahan) >= 5000 AND SUM(luas_lahan) <= 10000'),
'1_2' => $lahanQuery->havingRaw('SUM(luas_lahan) > 10000 AND SUM(luas_lahan) <= 20000'),
'lebih_2' => $lahanQuery->havingRaw('SUM(luas_lahan) > 20000'),
'kurang_05' => $lahanQuery->where('luas_lahan', '<', 0.5),
'05_1' => $lahanQuery->whereBetween('luas_lahan', [0.5, 1]),
'1_2' => $lahanQuery->where('luas_lahan', '>', 1)->where('luas_lahan', '<=', 2),
'lebih_2' => $lahanQuery->where('luas_lahan', '>', 2),
default => null,
};
$query->whereIn('id', $lahanQuery->pluck('petani_id'));
$query->whereIn('petani.id', $lahanQuery);
}
if ($request->filled('status_kepemilikan_lahan')) {
$query->whereIn('petani.id', Lahan::query()
->whereIn('petani_id', clone $filteredPetaniIds)
->where('status_kepemilikan', $request->status_kepemilikan_lahan)
->select('petani_id')
->distinct());
}
$daftarPetani = $query->orderBy('id')->paginate(10);
@@ -275,4 +492,4 @@ class DemografiPetaniController extends Controller
],
]);
}
}
}