Optimize Demografi & Update Profil Petani

This commit is contained in:
2026-08-13 15:31:04 +07:00
parent b855a857b2
commit 4b26e82afb
3 changed files with 681 additions and 129 deletions
@@ -5,7 +5,6 @@ namespace App\Http\Controllers\Web\Dashboard;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use App\Models\Pertanian\Petani;
use App\Models\Pertanian\Komoditas;
@@ -16,21 +15,30 @@ class DemografiPetaniController extends Controller
{
public function index(Request $request)
{
$totalPetani = Petani::count();
$petaniLakilaki = Petani::where('jenis_kelamin', 1)->count();
$petaniPerempuan = Petani::where('jenis_kelamin', 0)->count();
$totalKomoditas = Petani::whereNotNull('komoditas_id')
->distinct()
->count('komoditas_id');
$totalLuasLahan = Lahan::has('petani')
->sum('luas_lahan');
$ratarataLuasLahan = $totalLuasLahan && $totalPetani ? $totalLuasLahan / $totalPetani : 0;
$petaniCounts = Petani::selectRaw("
COUNT(*) as total,
COUNT(*) FILTER (WHERE jenis_kelamin = true) as laki,
COUNT(*) FILTER (WHERE jenis_kelamin = false) as perempuan
")->first();
$umurKurang30 = Petani::whereNotNull('tanggal_lahir')->whereRaw("EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) < 30")->count();
$umur30sampai39 = Petani::whereNotNull('tanggal_lahir')->whereRaw("EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 30 AND 39")->count();
$umur40sampai49 = Petani::whereNotNull('tanggal_lahir')->whereRaw("EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 40 AND 49")->count();
$umur50sampai59 = Petani::whereNotNull('tanggal_lahir')->whereRaw("EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 50 AND 59")->count();
$umur60keatas = Petani::whereNotNull('tanggal_lahir')->whereRaw("EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) >= 60")->count();
$totalPetani = $petaniCounts->total;
$petaniLakilaki = $petaniCounts->laki;
$petaniPerempuan = $petaniCounts->perempuan;
$totalKomoditas = Petani::whereNotNull('komoditas_id')
->distinct()
->count('komoditas_id');
$totalLuasLahan = Lahan::has('petani')->sum('luas_lahan');
$ratarataLuasLahan = $totalLuasLahan && $totalPetani ? $totalLuasLahan / $totalPetani : 0;
$umurCounts = Petani::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,
COUNT(*) FILTER (WHERE EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 50 AND 59) as umur_50_59,
COUNT(*) FILTER (WHERE EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) >= 60) as umur_60_keatas
")->first();
$pendidikanCounts = Petani::whereNotNull('pendidikan_terakhir')
->select('pendidikan_terakhir', DB::raw('COUNT(*) as total'))
@@ -43,10 +51,7 @@ class DemografiPetaniController extends Controller
'smp' => (int) ($pendidikanCounts['03_smp'] ?? 0),
'sma' => (int) ($pendidikanCounts['04_sma'] ?? 0),
'diploma' => (int) ($pendidikanCounts['05_diploma'] ?? 0),
's1_keatas' =>
(int) ($pendidikanCounts['06_sarjana'] ?? 0) +
(int) ($pendidikanCounts['07_magister'] ?? 0),
's1_keatas' => (int) ($pendidikanCounts['06_sarjana'] ?? 0) + (int) ($pendidikanCounts['07_magister'] ?? 0),
];
$komoditasUtama = Komoditas::query()
@@ -55,30 +60,44 @@ class DemografiPetaniController extends Controller
->orderByDesc('petani_count')
->get(['id', 'nama']);
$luasLahanPerPetani = Lahan::has('petani')
->select('petani_id')
->selectRaw('SUM(luas_lahan) as total_luas')
->groupBy('petani_id')
->get();
$luasLahanBuckets = DB::query()->fromSub(
Lahan::query()->select('petani_id')->selectRaw('SUM(luas_lahan) as total_luas')->groupBy('petani_id'),
'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
")->first();
$luasLahan = [
'kurang_05' => $luasLahanPerPetani->filter(fn ($item) => $item->total_luas < 5000)->count(),
'05_1' => $luasLahanPerPetani->filter(fn ($item) => $item->total_luas >= 5000 && $item->total_luas <= 10000)->count(),
'1_2' => $luasLahanPerPetani->filter(fn ($item) => $item->total_luas > 10000 && $item->total_luas <= 20000)->count(),
'lebih_2' => $luasLahanPerPetani->filter(fn ($item) => $item->total_luas > 20000)->count(),
'kurang_05' => $luasLahanBuckets->kurang_05,
'05_1' => $luasLahanBuckets->luas_05_1,
'1_2' => $luasLahanBuckets->luas_1_2,
'lebih_2' => $luasLahanBuckets->lebih_2,
];
$pendapatanPerPetani = PendapatanKomoditas::with('sosialEkonomi.petani')->get()
->filter(fn ($item) => $item->sosialEkonomi?->petani)
->groupBy(fn ($item) => $item->sosialEkonomi->petani_id)
->map(fn ($items) => $items->sum('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'),
'agg'
)->selectRaw("
COUNT(*) FILTER (WHERE total_pendapatan < 1000000) as kurang_1,
COUNT(*) FILTER (WHERE total_pendapatan >= 1000000 AND total_pendapatan <= 3000000) as p1_3,
COUNT(*) FILTER (WHERE total_pendapatan > 3000000 AND total_pendapatan <= 5000000) as p3_5,
COUNT(*) FILTER (WHERE total_pendapatan > 5000000 AND total_pendapatan <= 10000000) as p5_10,
COUNT(*) FILTER (WHERE total_pendapatan > 10000000) as lebih_10
")->first();
$penghasilan = [
'kurang_1' => $pendapatanPerPetani->filter(fn ($value) => $value < 1000000)->count(),
'1_3' => $pendapatanPerPetani->filter(fn ($value) => $value >= 1000000 && $value <= 3000000)->count(),
'3_5' => $pendapatanPerPetani->filter(fn ($value) => $value > 3000000 && $value <= 5000000)->count(),
'5_10' => $pendapatanPerPetani->filter(fn ($value) => $value > 5000000 && $value <= 10000000)->count(),
'lebih_10' => $pendapatanPerPetani->filter(fn ($value) => $value > 10000000)->count(),
'kurang_1' => $penghasilanBuckets->kurang_1,
'1_3' => $penghasilanBuckets->p1_3,
'3_5' => $penghasilanBuckets->p3_5,
'5_10' => $penghasilanBuckets->p5_10,
'lebih_10' => $penghasilanBuckets->lebih_10,
];
$data = [
@@ -89,72 +108,62 @@ class DemografiPetaniController extends Controller
'total_luas_lahan' => $totalLuasLahan,
'ratarata_luas_lahan' => $ratarataLuasLahan,
'kelompok_umur' => [
'kurang_30' => $umurKurang30,
'30_39' => $umur30sampai39,
'40_49' => $umur40sampai49,
'50_59' => $umur50sampai59,
'60_keatas' => $umur60keatas,
'kurang_30' => $umurCounts->kurang_30,
'30_39' => $umurCounts->umur_30_39,
'40_49' => $umurCounts->umur_40_49,
'50_59' => $umurCounts->umur_50_59,
'60_keatas' => $umurCounts->umur_60_keatas,
],
'pendidikan' => $pendidikan,
'komoditas_utama' => [
'ids' => $komoditasUtama
->pluck('id')
->values(),
'labels' => $komoditasUtama
->pluck('nama')
->values(),
'series' => $komoditasUtama
->pluck('petani_count')
->map(fn ($value) => (int) $value)
->values(),
'ids' => $komoditasUtama->pluck('id')->values(),
'labels' => $komoditasUtama->pluck('nama')->values(),
'series' => $komoditasUtama->pluck('petani_count')->map(fn ($v) => (int) $v)->values(),
],
'luas_lahan' => $luasLahan,
'penghasilan' => $penghasilan,
];
$daftarPetani = Petani::with([
'komoditas'
])
$daftarPetani = Petani::with(['komoditas'])
->withSum('lahans as total_luas_lahan', 'luas_lahan')
->orderBy('id')
->paginate(10);
// dd($daftarPetani);
return view('dashboard.demografi-petani', compact('data', 'daftarPetani'));
}
public function data(Request $request)
{
$query = Petani::with('komoditas')->withSum( 'lahans as total_luas_lahan', 'luas_lahan');
$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')
->withSum('lahans as total_luas_lahan', 'luas_lahan')
->addSelect(['total_pendapatan' => $pendapatanSub]);
if ($request->filled('search')) {
$search = $request->search;
$query->where('nama', 'ILIKE', "%{$search}%" );
$query->where('nama', 'ILIKE', "%{$request->search}%");
}
$pendapatanPerPetani = PendapatanKomoditas::with('sosialEkonomi.petani')->get()
->filter(fn ($item) => $item->sosialEkonomi?->petani)
->groupBy(fn ($item) => $item->sosialEkonomi->petani_id)
->map(fn ($items) => $items->sum('pendapatan'));
if ($request->has('gender') && $request->gender !== '') {
$query->where('jenis_kelamin', $request->gender );
$query->where('jenis_kelamin', $request->gender);
}
if ($request->filled('umur')) {
match ($request->umur) {
'kurang_30' => $query->whereNotNull('tanggal_lahir')
->whereRaw("EXTRACT( YEAR FROM AGE( CURRENT_DATE, tanggal_lahir)) < 30"),
->whereRaw("EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) < 30"),
'30_39' => $query->whereNotNull('tanggal_lahir')
->whereRaw("EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 30 AND 39"),
->whereRaw("EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 30 AND 39"),
'40_49' => $query->whereNotNull('tanggal_lahir')
->whereRaw("EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 40 AND 49"),
->whereRaw("EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 40 AND 49"),
'50_59' => $query->whereNotNull('tanggal_lahir')
->whereRaw("EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 50 AND 59"),
'60_keatas' => $query ->whereNotNull('tanggal_lahir')
->whereRaw("EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) >= 60"),
default => null
->whereRaw("EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 50 AND 59"),
'60_keatas' => $query->whereNotNull('tanggal_lahir')
->whereRaw("EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) >= 60"),
default => null,
};
}
@@ -178,27 +187,34 @@ class DemografiPetaniController extends Controller
}
if ($request->filled('penghasilan')) {
$filteredPendapatan =
match ($request->penghasilan) {
'kurang_1' => $pendapatanPerPetani ->filter(fn ($value) => $value < 1000000 ),
'1_3' => $pendapatanPerPetani->filter( fn ($value) => $value >= 1000000 && $value <= 3000000 ),
'3_5' => $pendapatanPerPetani->filter(fn ($value) => $value > 3000000 && $value <= 5000000 ),
'5_10' => $pendapatanPerPetani->filter(fn ($value) => $value > 5000000 && $value <= 10000000 ),
'lebih_10' => $pendapatanPerPetani->filter(fn ($value) => $value > 10000000 ),
default => collect()
};
[$min, $max] = match ($request->penghasilan) {
'kurang_1' => [null, 999999],
'1_3' => [1000000, 3000000],
'3_5' => [3000001, 5000000],
'5_10' => [5000001, 10000000],
'lebih_10' => [10000001, null],
default => [null, null],
};
$query->whereIn('id', $filteredPendapatan->keys()->values()->all());
$query->whereIn('id', function ($sub) use ($min, $max) {
$sub->from('pendapatan_komoditas')
->join('sosial_ekonomi', 'sosial_ekonomi.id', '=', 'pendapatan_komoditas.sosial_ekonomi_id')
->whereNotNull('sosial_ekonomi.petani_id')
->groupBy('sosial_ekonomi.petani_id')
->select('sosial_ekonomi.petani_id')
->when($min !== null, fn ($q) => $q->havingRaw('SUM(pendapatan_komoditas.pendapatan) >= ?', [$min]))
->when($max !== null, fn ($q) => $q->havingRaw('SUM(pendapatan_komoditas.pendapatan) <= ?', [$max]));
});
}
if ($request->filled('luas_lahan')) {
$lahanQuery = Lahan::query()->select('petani_id')->groupBy('petani_id');
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' ),
'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'),
default => null
default => null,
};
$query->whereIn('id', $lahanQuery->pluck('petani_id'));
}
@@ -215,13 +231,10 @@ class DemografiPetaniController extends Controller
'07_magister' => 'Magister',
];
$rows = collect($daftarPetani->items())->map(function ($petani) use (
$pendidikanLabels,
$pendapatanPerPetani
) {
$rows = collect($daftarPetani->items())->map(function ($petani) use ($pendidikanLabels) {
$umur = $petani->tanggal_lahir ? \Carbon\Carbon::parse($petani->tanggal_lahir)->age : null;
$pendidikanRaw = $petani->getRawOriginal('pendidikan_terakhir');
$pendapatan = $pendapatanPerPetani->get($petani->id);
$pendapatan = $petani->total_pendapatan;
$rentangPenghasilan = match (true) {
$pendapatan === null => '-',
@@ -233,27 +246,27 @@ class DemografiPetaniController extends Controller
};
return [
'id' => $petani->id,
'nama' => $petani->nama ?? '-',
'jenis_kelamin' => $petani->jenis_kelamin,
'gender' => $petani->jenis_kelamin == 1 ? 'Laki-laki' : 'Perempuan',
'umur' => $umur,
'komoditas' => $petani->komoditas?->nama ?? '-',
'luas_lahan' => (float) ($petani->total_luas_lahan ?? 0 ),
'pendidikan' => $pendidikanLabels[$pendidikanRaw ] ?? '-',
'rentang_penghasilan' => $rentangPenghasilan,
'id' => $petani->id,
'nama' => $petani->nama ?? '-',
'jenis_kelamin' => $petani->jenis_kelamin,
'gender' => $petani->jenis_kelamin == 1 ? 'Laki-laki' : 'Perempuan',
'umur' => $umur,
'komoditas' => $petani->komoditas?->nama ?? '-',
'luas_lahan' => (float) ($petani->total_luas_lahan ?? 0),
'pendidikan' => $pendidikanLabels[$pendidikanRaw] ?? '-',
'rentang_penghasilan' => $rentangPenghasilan,
];
});
return response()->json([
'data' => $rows,
'pagination' => [
'current_page' => $daftarPetani->currentPage(),
'last_page' => $daftarPetani->lastPage(),
'per_page' => $daftarPetani->perPage(),
'total' => $daftarPetani->total(),
'from' => $daftarPetani->firstItem(),
'to' => $daftarPetani->lastItem(),
'current_page' => $daftarPetani->currentPage(),
'last_page' => $daftarPetani->lastPage(),
'per_page' => $daftarPetani->perPage(),
'total' => $daftarPetani->total(),
'from' => $daftarPetani->firstItem(),
'to' => $daftarPetani->lastItem(),
],
]);
}
@@ -10,22 +10,32 @@ use App\Models\Pertanian\Petani;
use App\Models\Pertanian\SkorPetani;
use App\Models\Pertanian\Komoditas;
use App\Models\Pertanian\Lahan;
use App\Models\Pertanian\Tanaman;
use App\Models\Pertanian\PraktikBudidaya;
use App\Models\Pertanian\SurveyPanen;
use App\Models\Pertanian\PendapatanKomoditas;
use App\Models\Wilayah\DesaKelurahan;
use App\Models\Profile;
use App\Enums\PraktikBudidaya\FrekuensiPemangkasanUtama;
use App\Enums\PraktikBudidaya\PemberianPupuk;
use App\Enums\PraktikBudidaya\MetodePenangananHamaPenyakit;
use App\Enums\PraktikBudidaya\FrekuensiSanitasiLahan;
use App\Enums\PraktikBudidaya\PenangananGulma;
use App\Enums\PraktikBudidaya\KondisiPengelolaanAir;
class ProfilPetaniController extends Controller
{
private const DIMENSION_LOW_MAX = 2.49;
private const DIMENSION_MEDIUM_MAX = 3.49;
public function index(int $id)
public function index(int $id)
{
$petani = Petani::findOrFail($id);
$skorPetani = SkorPetani::where('petani_id', $id)->first();
$enumerator = Profile::where('user_id', $petani->created_by)->first();
$komoditas = Komoditas::where('id', $petani->komoditas_id)->get();
$lahan = Lahan::where('petani_id', $id )->get();
$petani = Petani::findOrFail($id);
$skorPetani = SkorPetani::where('petani_id', $id)->first();
$enumerator = Profile::where('user_id', $petani->created_by)->first();
$komoditasUtama = Komoditas::where('id', $petani->komoditas_id)->first();
$lahan = Lahan::where('petani_id', $id )->get();
$desaKelurahan = DesaKelurahan::with('kecamatan')
->where('id', $petani->desa_kelurahan_id)
@@ -34,19 +44,142 @@ class ProfilPetaniController extends Controller
$ktpMasked = $petani->ktp ? Str::mask($petani->ktp, '*', 4, -4) : '-';
$profiling = $skorPetani ? $this->buildProfiling($skorPetani) : null;
$tanaman = Tanaman::where('petani_id', $petani->id)
->where('komoditas_id', $petani->komoditas_id)
->first();
if ($tanaman) {
$tahunInputTanaman = $tanaman->updated_at->year;
$umurTanaman = (int) $tanaman->umur_tanaman;
$tahunSekarang = now()->year;
$tahunTanam = $tahunInputTanaman - $umurTanaman;
$umurTanaman = $tahunSekarang - $tahunTanam;
} else {
$tahunTanam = null;
$umurTanaman = null;
}
$praktikBudidaya = PraktikBudidaya::where('petani_id', $petani->id)->first();
$surveyPanen = SurveyPanen::where('petani_id', $petani->id)->first();
$indikatorOnFarm = collect();
if ($praktikBudidaya) {
$indikatorOnFarm = collect([
[
'key' => 'pemangkasan',
'nama' => 'Pemangkasan',
'skor' => $praktikBudidaya->frekuensi_pemangkasan_utama,
'deskripsi' => FrekuensiPemangkasanUtama::tryFrom(
(int) $praktikBudidaya->frekuensi_pemangkasan_utama
)?->label(),
],
[
'key' => 'pemupukan',
'nama' => 'Pemupukan',
'skor' => $praktikBudidaya->pemberian_pupuk,
'deskripsi' => PemberianPupuk::tryFrom(
(int) $praktikBudidaya->pemberian_pupuk
)?->label(),
],
[
'key' => 'opt',
'nama' => 'Hama / Penyakit',
'skor' => $praktikBudidaya->metode_penanganan_opt,
'deskripsi' => MetodePenangananHamaPenyakit::tryFrom(
(int) $praktikBudidaya->metode_penanganan_opt
)?->label(),
],
[
'key' => 'sanitasi',
'nama' => 'Sanitasi Kebun',
'skor' => $praktikBudidaya->frekuensi_sanitasi_lahan,
'deskripsi' => FrekuensiSanitasiLahan::tryFrom(
(int) $praktikBudidaya->frekuensi_sanitasi_lahan
)?->label(),
],
[
'key' => 'gulma',
'nama' => 'Penanganan Gulma',
'skor' => $praktikBudidaya->penanganan_gulma,
'deskripsi' => PenangananGulma::tryFrom(
(int) $praktikBudidaya->penanganan_gulma
)?->label(),
],
[
'key' => 'air',
'nama' => 'Pengelolaan Air',
'skor' => $praktikBudidaya->kondisi_pengelolaan_air,
'deskripsi' => KondisiPengelolaanAir::tryFrom(
(int) $praktikBudidaya->kondisi_pengelolaan_air
)?->label(),
],
])
->map(function ($item) {
$skor = $item['skor'] !== null
? (int) $item['skor']
: null;
return array_merge($item, [
'skor' => $skor,
'persentase' => $skor !== null
? ($skor / 5) * 100
: 0,
'color' => $this->getScoreColor($skor),
]);
});
}
$detailOnFarm = [
'jenis_hama' => $praktikBudidaya?->jenis_hama ?? [],
'jenis_penyakit' => $praktikBudidaya?->jenis_penyakit ?? [],
'konservasi_tanah' => $praktikBudidaya?->kebiasaan_konservasi_tanah ?? [],
];
$data = [
'petani' => $petani,
'skorPetani' => $skorPetani,
'enumerator' => $enumerator,
'komoditas' => $komoditas,
'lahan' => $lahan,
'desaKelurahan' => $desaKelurahan,
'ktpMasked' => $ktpMasked,
'profiling' => $profiling,
'petani' => $petani,
'skorPetani' => $skorPetani,
'enumerator' => $enumerator,
'komoditasUtama' => $komoditasUtama,
'lahan' => $lahan,
'desaKelurahan' => $desaKelurahan,
'ktpMasked' => $ktpMasked,
'profiling' => $profiling,
'tahunTanam' => $tahunTanam,
'umurTanaman' => $umurTanaman,
'surveyPanen' => $surveyPanen,
'praktikBudidaya' => $praktikBudidaya,
'praktikBudidaya' => $praktikBudidaya,
'indikatorOnFarm' => $indikatorOnFarm,
'detailOnFarm' => $detailOnFarm,
];
return view('produktivitas.profil-petani.index', $data);
}
private function getScoreColor(?int $score): string
{
if ($score === null) {
return 'secondary';
}
return match (true) {
$score >= 5 => 'success',
$score >= 4 => 'info',
$score >= 3 => 'primary',
$score >= 2 => 'warning',
default => 'danger',
};
}
private function buildProfiling(SkorPetani $skorPetani): array
{
$skorAkhir = $this->normalizeScore($skorPetani->skor_kesiapan_adopsi);
@@ -54,7 +54,7 @@
</span>
<span class="badge bg-label-secondary d-flex align-items-center gap-1">
<i class="icon-base ti tabler-chocolate icon-xs"></i>
{{ $komoditas->first()->nama }}
{{ $komoditasUtama->nama }}
</span>
@if($petani->sertifikat === 1)
<span class="badge bg-label-secondary d-flex align-items-center gap-1">
@@ -93,11 +93,15 @@
</div>
</div>
</div>
<button type="button" class="btn btn-primary">
<i class="icon-base ti tabler-file-type-pdf icon-sm me-1"></i>
Export PDF
</button>
<div>
<a href="javascript:history.back()" class="btn btn-label-secondary">
<i class="icon-base ti tabler-arrow-left icon-sm me-1"></i>Kembali
</a>
<button type="button" class="btn btn-primary">
<i class="icon-base ti tabler-file-type-pdf icon-sm me-1"></i>
Export PDF
</button>
</div>
</div>
<div class="progress mb-2" style="height: 7px;">
<div class="progress-bar" role="progressbar" style="width: {{ ($skorPetani->skor_kesiapan_adopsi / 5.0) * 100 }}%;" aria-valuenow="{{ $skorPetani->skor_kesiapan_adopsi }}" aria-valuemin="0" aria-valuemax="5.0"></div>
@@ -323,6 +327,408 @@
</div>
@endif
<!-- Detail Profil Petani -->
<div class="row g-6 mt-1">
<div class="col-xl-6 col-12">
<div class="card h-100">
<div class="card-header d-flex align-items-center justify-content-between">
<div class="d-flex align-items-center gap-2">
<i class="icon-base ti tabler-plant-2 text-primary icon-md"></i>
<h5 class="card-title mb-0">D2 - Praktik Budidaya (GAP)</h5>
</div>
<span class="badge bg-label-primary">
Skor: {{ number_format($skorPetani->skor_d2_sistem_praktik_budidaya ?? 0, 1) }}
</span>
</div>
<div class="card-body">
{{-- nanti isi:
- Komoditas
- Tahun tanam
- Estimasi produksi
- Tren produktivitas
- Indikator on-farm
- Fasilitas pasca panen
- Komoditas/tanaman lain
--}}
<div class="row g-3 mb-5">
{{-- Komoditas --}}
<div class="col-md-4">
<div class="border rounded p-3 h-100">
<small class="text-body-secondary d-block mb-1">
Komoditas
</small>
<h6 class="mb-0">
{{ $komoditasUtama->nama ?? '-' }}
</h6>
</div>
</div>
{{-- Tahun Tanam --}}
<div class="col-md-4">
<div class="border rounded p-3 h-100">
<small class="text-body-secondary d-block mb-1">
Tahun Tanam
</small>
<h6 class="mb-0">
{{ $tahunTanam ?? '-' }}
@if($umurTanaman)
<span class="text-body-secondary fw-normal">
({{ $umurTanaman }} th)
</span>
@endif
</h6>
</div>
</div>
{{-- Estimasi Produksi --}}
<div class="col-md-4">
<div class="border rounded p-3 h-100">
<small class="text-body-secondary d-block mb-1">Est. Produksi</small>
<h6 class="mb-1">
{{ number_format($surveyPanen?->hasil_komoditas_utama_permusim ?? 0, 0, ',', '.') }}
Kg/Musim
</h6>
@if($surveyPanen?->disimpan_untuk_sendiri == 1)
<small class="text-body-secondary d-block">
Disimpan:
<span class="fw-medium text-body">
{{ number_format($surveyPanen?->hasil_panen_disimpan ?? 0, 0, ',', '.') }}
Kg/Musim
</span>
@if($surveyPanen?->tujuan_disimpan)
({{ $surveyPanen->tujuan_disimpan }})
@endif
</small>
@else
<small class="text-success">
<i class="icon-base ti tabler-check icon-xs me-1"></i>
Semua di jual
</small>
@endif
</div>
</div>
</div>
<div class="mt-5">
<p class="text-uppercase text-body-secondary fw-medium small mb-4">
Indikator On-Farm
</p>
<div class="d-flex flex-column gap-4">
@foreach($indikatorOnFarm as $indikator)
<div>
<div class="row align-items-center g-3">
{{-- Nama --}}
<div class="col-md-3 col-12">
<span
class="text-body fw-medium"
data-bs-toggle="tooltip"
data-bs-placement="top"
title="{{ $indikator['deskripsi'] ?? '-' }}"
>
{{ $indikator['nama'] }}
</span>
</div>
{{-- Progress --}}
<div class="col-md-7 col-10">
<div
class="progress"
style="height: 7px;"
data-bs-toggle="tooltip"
data-bs-placement="top"
title="{{ $indikator['deskripsi'] ?? '-' }}"
>
<div
class="progress-bar bg-{{ $indikator['color'] }}"
role="progressbar"
style="width: {{ $indikator['persentase'] }}%;"
aria-valuenow="{{ $indikator['skor'] ?? 0 }}"
aria-valuemin="0"
aria-valuemax="5">
</div>
</div>
</div>
{{-- Skor --}}
<div class="col-md-2 col-2 text-end">
@if($indikator['skor'] !== null)
<span class="fw-semibold text-{{ $indikator['color'] }}">
{{ $indikator['skor'] }}/5
</span>
@else
<span class="text-body-secondary">
-
</span>
@endif
</div>
</div>
</div>
@endforeach
</div>
</div>
@if(
!empty($detailOnFarm['jenis_hama']) ||
!empty($detailOnFarm['jenis_penyakit'])
)
<div class="mt-4 p-3 border rounded">
<div class="row g-4">
{{-- Jenis Hama --}}
<div class="col-md-6">
<small class="text-body-secondary d-block mb-2">
Jenis Hama Ditemukan
</small>
<div class="d-flex flex-wrap gap-2">
@forelse($detailOnFarm['jenis_hama'] as $hama)
<span class="badge bg-label-warning">
<i class="icon-base ti tabler-bug icon-xs me-1"></i>
{{ $hama }}
</span>
@empty
<span class="text-body-secondary small">
Tidak ada data hama
</span>
@endforelse
</div>
</div>
{{-- Jenis Penyakit --}}
<div class="col-md-6">
<small class="text-body-secondary d-block mb-2">
Jenis Penyakit Ditemukan
</small>
<div class="d-flex flex-wrap gap-2">
@forelse($detailOnFarm['jenis_penyakit'] as $penyakit)
<span class="badge bg-label-danger">
<i class="icon-base ti tabler-virus icon-xs me-1"></i>
{{ $penyakit }}
</span>
@empty
<span class="text-body-secondary small">
Tidak ada data penyakit
</span>
@endforelse
</div>
</div>
</div>
</div>
@endif
@if(!empty($detailOnFarm['konservasi_tanah']))
<div class="mt-5">
<small class="text-body-secondary fw-medium d-block mb-2">
Kebiasaan Konservasi Tanah
</small>
<div class="d-flex flex-column gap-2">
@foreach($detailOnFarm['konservasi_tanah'] as $konservasi)
<div class="d-flex align-items-start gap-2">
<i class="icon-base ti tabler-circle-check text-success icon-sm mt-1"></i>
<span class="text-body">
{{ $konservasi }}
</span>
</div>
@endforeach
</div>
</div>
@endif
</div>
</div>
</div>
{{-- =========================================================
RIGHT COLUMN
========================================================== --}}
<div class="col-xl-6 col-12">
<div class="d-flex flex-column gap-6">
{{-- =================================================
D4 - SOSIAL EKONOMI
================================================== --}}
<div class="card">
<div class="card-header d-flex align-items-center justify-content-between">
<div class="d-flex align-items-center gap-2">
<i class="icon-base ti tabler-users text-primary icon-md"></i>
<h5 class="card-title mb-0">
D4 - Sosial Ekonomi
</h5>
</div>
<span class="badge bg-label-primary">
{{ number_format($skorPetani->skor_d4_sosial_ekonomi ?? 0, 1) }}
</span>
</div>
<div class="card-body">
{{-- nanti isi:
- Tanggungan keluarga
- Status pendapatan
- Status tabungan
- Keterlibatan lembaga
- Hutang panen
- Ijon
- Program bantuan
--}}
<div class="text-body-secondary text-center py-4">
Detail sosial ekonomi akan ditampilkan di sini
</div>
</div>
</div>
{{-- =================================================
RIWAYAT PELATIHAN
================================================== --}}
<div class="card">
<div class="card-header">
<div class="d-flex align-items-center gap-2">
<i class="icon-base ti tabler-certificate text-primary icon-md"></i>
<h5 class="card-title mb-0">
Riwayat Pelatihan & Sertifikasi
</h5>
</div>
</div>
<div class="card-body">
{{-- nanti isi:
- Pelatihan yang pernah diikuti
- Sertifikasi
- Status sertifikasi
--}}
<div class="text-body-secondary text-center py-4">
Riwayat pelatihan dan sertifikasi akan ditampilkan di sini
</div>
</div>
</div>
{{-- =================================================
D6 - RANTAI NILAI & PASAR
================================================== --}}
<div class="card">
<div class="card-header d-flex align-items-center justify-content-between">
<div class="d-flex align-items-center gap-2">
<i class="icon-base ti tabler-building-store text-primary icon-md"></i>
<h5 class="card-title mb-0">
D6 - Rantai Nilai & Pasar
</h5>
</div>
<span class="badge bg-label-primary">
{{ number_format($skorPetani->skor_d6_rantai_nilai_akses_pasar ?? 0, 1) }}
</span>
</div>
<div class="card-body">
{{-- nanti isi:
- Saluran penjualan
- Harga jual saat ini
- Perubahan harga
- Kebebasan memilih pembeli
- Hambatan mutu / pasar
--}}
<div class="text-body-secondary text-center py-4">
Detail rantai nilai dan pasar akan ditampilkan di sini
</div>
</div>
</div>
</div>
</div>
</div>
<!-- / Detail Profil Petani -->
</div>
@endsection