'boolean', 'tanggal_lahir' => 'date', 'pendidikan_terakhir' => Pendidikan::class, 'status_perkawinan' => Pernikahan::class, ]; public function getUmurAttribute(): ?int { if (! $this->tanggal_lahir) { return null; } return Carbon::parse($this->tanggal_lahir)->age; } public function desaKelurahan(): BelongsTo { return $this->belongsTo(DesaKelurahan::class, 'desa_kelurahan_id'); } public function user(): BelongsTo { return $this->belongsTo(User::class, 'user_id'); } protected static function booted(): void { static::saved(function (Petani $petani) { $skor = SkorPetani::where('petani_id')->orderBy('id')->first(); if (! $skor) { $petaniUid = $petani->uid; $part = explode('-', $petaniUid); $skor = SkorPetani::create([ 'uid' => 'SKR-'.$part[1].'-'.strtoupper(Str::random(10)), 'created_by' => $petani->created_by, 'updated_by' => $petani->updated_by, ]); } }); } public function skor(): HasOne { return $this->hasOne(SkorPetani::class, 'petani_id'); } public function praktikBudidaya(): HasOne { return $this->hasOne(PraktikBudidaya::class, 'petani_id')->latestOfMany(); } public function surveyPanen(): HasOne { return $this->hasOne(surveyPanen::class, 'petani_id')->latestOfMany(); } public function surveyProduktivitas(): HasOne { return $this->hasOne(surveyProduktivitas::class, 'petani_id')->latestOfMany(); } public function lahans(): HasMany { return $this->hasMany(Lahan::class, 'petani_id'); } public function sosialEkonomi(): HasOne { return $this->hasOne(SosialEkonomi::class, 'petani_id'); } public function aksesPasar(): HasOne { return $this->hasOne(AksesPasar::class, 'petani_id'); } public function skorLahanTanaman(): ?float { if (! Schema::hasTable('map_lahan')) { return null; } $lahan = $this->lahans()->get(); if ($lahan->isEmpty()) { return null; } $nilaiKondisi = $lahan ->map(fn ($item) => match ($this->enumValue($item->kondisi_tanaman)) { 'baik' => 5, 'sedang' => 3, 'buruk' => 1, 'mati' => 0, default => null, }) ->filter(fn ($value) => ! is_null($value)); if ($nilaiKondisi->isEmpty()) { return null; } return round($nilaiKondisi->avg() * 0.1, 1); } public function skorPraktikBudidaya(): ?float { if (! Schema::hasTable('praktik_budidaya')) { return null; } $praktikBudidaya = $this->praktikBudidaya()->first(); if (! $praktikBudidaya) { return null; } $nilai = collect([ $praktikBudidaya->frekuensi_pemangkasan_utama, $praktikBudidaya->pemberian_pupuk, $praktikBudidaya->metode_penanganan_opt, $praktikBudidaya->frekuensi_sanitasi_lahan, $praktikBudidaya->penanganan_gulma, $praktikBudidaya->kondisi_pengelolaan_air, $praktikBudidaya->nilai_konservasi_tanah, ])->filter(fn ($value) => ! is_null($value) && $value !== ''); if ($nilai->isEmpty()) { return null; } return round($nilai->sum(fn ($value) => (int) $value) * 0.2, 1); } public function skorPendidikan(): ?float { if (! $this->pendidikan_terakhir) { return null; } $nilai = match ($this->enumValue($this->pendidikan_terakhir)) { Pendidikan::TIDAK_SEKOLAH->value => 1, Pendidikan::SD->value => 2, Pendidikan::SMP->value => 3, Pendidikan::SMA->value, Pendidikan::PESANTREN->value, Pendidikan::LAINNYA->value => 4, Pendidikan::DIPLOMA->value, Pendidikan::SARJANA->value, Pendidikan::MAGISTER->value, Pendidikan::DOKTOR->value => 5, default => null, }; return is_null($nilai) ? null : round($nilai * 0.1, 1); } public function skorSosialEkonomi(): ?float { if (! Schema::hasTable('sosial_ekonomi')) { return null; } $sosialEkonomi = $this->sosialEkonomi()->first(); if (! $sosialEkonomi) { return null; } $nilai = collect([ $this->enumValue($sosialEkonomi->skor_periode_paceklik), $this->enumValue($sosialEkonomi->skor_kemampuan_menabung), $this->enumValue($sosialEkonomi->skor_kecukupan_penghasilan), $this->enumValue($sosialEkonomi->skor_kejelasan_status_lahan), $this->enumValue($sosialEkonomi->kemauan_mencoba_praktik_baru), $this->enumValue($sosialEkonomi->pemahaman_mutu_harga), $this->enumValue($sosialEkonomi->panutan_petani_sukses), $this->enumValue($sosialEkonomi->kemauan_ikut_program), $this->enumValue($sosialEkonomi->orientasi_rencana_jangka_panjang), $this->enumValue($sosialEkonomi->keaktifan_pertemuan_kelompok), $this->enumValue($sosialEkonomi->peran_dalam_kelompok), $this->enumValue($sosialEkonomi->manfaat_kelompok_tani), $this->enumValue($sosialEkonomi->status_rekening_tabungan), $this->enumValue($sosialEkonomi->pengalaman_kredit_kebun), $this->enumValue($sosialEkonomi->kondisi_aset_produktif), $this->enumValue($sosialEkonomi->keterlibatan_program_keuangan_formal), $this->enumValue($sosialEkonomi->keterikatan_hutang_panen), $this->enumValue($sosialEkonomi->praktik_ijon), $this->enumValue($sosialEkonomi->kebebasan_memilih_pembeli), ])->filter(fn ($value) => ! is_null($value) && $value !== '' && (int) $value > 0); if ($nilai->isEmpty()) { return null; } return round($nilai->sum(fn ($value) => (int) $value) * 0.2, 1); } public function skorAksesPasar(): ?float { if (! Schema::hasTable('akses_pasar')) { return null; } $aksesPasar = $this->aksesPasar()->first(); if (! $aksesPasar) { return null; } $nilai = collect(Schema::getColumnListing($aksesPasar->getTable())) ->filter(fn ($field) => str_starts_with($field, 'skor_')) ->map(fn ($field) => $aksesPasar->getAttribute($field)) ->filter(fn ($value) => ! is_null($value) && $value !== ''); if ($nilai->isEmpty()) { return null; } return round($nilai->sum(fn ($value) => (int) $value) * 0.1, 1); } public function skorSegmenPetani(): ?float { $nilai = collect([ $this->skorLahanTanaman(), $this->skorPraktikBudidaya(), $this->skorPendidikan(), $this->skorSosialEkonomi(), $this->skorAksesPasar(), ])->filter(fn ($value) => ! is_null($value)); if ($nilai->isEmpty()) { return null; } return round($nilai->sum(), 1); } public function segmenPetani(): ?string { $skor = $this->skorSegmenPetani(); if (is_null($skor)) { return null; } return match (true) { $skor >= 4.0 => 'Penggerak', $skor >= 3.0 => 'Perintis', $skor >= 2.0 => 'Pemerhati', $skor >= 1.0 => 'Pemula', default => 'Belum tersegmentasi', }; } private function enumValue(mixed $value): mixed { return $value instanceof \BackedEnum ? $value->value : $value; } }