56 Commits
Author SHA1 Message Date
Syaharani 539239b507 bumdes 2026-09-16 11:09:08 +07:00
afriadirahman a76b014056 Update Kelompok Tani & APP AGERA 2026-09-06 19:09:37 +07:00
Althaf d50c292cf7 instrumen koperasi 2026-09-03 13:17:16 +07:00
Althaf dacaec7a86 Merge branch 'main' of https://git.probindo.com/Probindo/database-pertani-web 2026-08-27 11:48:55 +07:00
Althaf 6967eafe98 add instrumen koperasi 2026-08-27 11:48:42 +07:00
Syaharani 118cda625a filter dashboard indikator pertanian 2026-08-20 17:24:31 +07:00
irwan.l.cahyono a3f7cb4669 filter segmen 2026-08-20 01:52:05 +07:00
irwan.l.cahyono ec009a2c55 indeks petani dan ajax 2026-08-20 01:10:56 +07:00
afriadirahman b63dafdaee Update Profile Petani 2026-08-20 01:01:27 +07:00
Althaf b97f682cd3 Merge branch 'main' of https://git.probindo.com/Probindo/database-pertani-web 2026-08-19 16:42:31 +07:00
Althaf 404019bab6 Added Score 2026-08-19 16:42:03 +07:00
Syaharani 609919ba30 solve dashboard survey petani 2026-08-19 16:21:42 +07:00
irwan.l.cahyono 047cb4a779 link ke profil 2026-08-19 10:37:17 +07:00
irwan.l.cahyono 530c297b53 revisi jumlahpetani 2026-08-19 01:57:52 +07:00
Syaharani 8fbf68e6ef solve keanggotaan kelompok tani 2026-08-18 14:05:46 +07:00
Syaharani ac8b370248 update dashboard indikator pertanian 2026-08-18 14:04:44 +07:00
Syaharani 88762f7afb update dashboard indikator pertanian 2026-08-13 17:00:00 +07:00
Syaharani b96de514e3 solve dashboard indikator pertanian 2026-08-13 16:31:11 +07:00
Syaharani 6830142a82 solve dashboard indikator pertanian 2026-08-13 16:07:55 +07:00
afriadirahman 4b26e82afb Optimize Demografi & Update Profil Petani 2026-08-13 15:31:04 +07:00
Syaharani b855a857b2 solve dashboard indikator pertanian 2026-08-13 13:07:03 +07:00
afriadirahman ba7520a23c Update Demografi Petani 2026-08-12 17:49:24 +07:00
afriadirahman 0b333ab4e9 Update Profil Detail Petani 2026-08-12 17:33:53 +07:00
Althaf 3b1f15d5b3 fixed aksespasar 2026-08-11 16:19:10 +07:00
Althaf 605506bba8 Merge branch 'main' of https://git.probindo.com/Probindo/database-pertani-web 2026-08-11 15:40:27 +07:00
afriadirahman c960ba14b1 Update Demografi Petani 2026-08-11 15:13:28 +07:00
Syaharani a4f38998d5 dashboard indikator pertanian 2026-08-07 16:09:24 +07:00
Syaharani 0d9f6c0b64 indikator pertanian 2026-08-07 15:56:37 +07:00
irwan.l.cahyono 81775b0c13 Merge branch 'main' of https://git.probindo.com/Probindo/database-pertani-web 2026-08-07 15:00:32 +07:00
irwan.l.cahyono ba1a318d09 soft deleted petani 2026-08-07 15:00:30 +07:00
afriadirahman 0761d64254 Merge branch 'main' of https://git.probindo.com/Probindo/database-pertani-web 2026-08-07 14:32:48 +07:00
afriadirahman 67c3c6c809 Update demografi dashboard 2026-08-07 14:32:40 +07:00
irwan.l.cahyono 04387268cd indeks petani 2026-08-07 14:31:16 +07:00
irwan.l.cahyono 946fabb9a5 lahan skor has petani 2026-08-07 14:17:06 +07:00
irwan.l.cahyono 0a0c86d648 Merge branch 'main' of https://git.probindo.com/Probindo/database-pertani-web 2026-08-07 12:59:26 +07:00
irwan.l.cahyono 8b21fab8b8 dashboard indeks petani 2026-08-07 12:59:25 +07:00
afriadirahman 16a0a3c56c Update Icon Demografi Dashboard 2026-08-07 11:33:08 +07:00
afriadirahman d4c6b64ba6 Update Sidebar Demografi Petani 2026-08-07 11:20:05 +07:00
afriadirahman b4089d72b3 Update Dashboard Demografi Petani 2026-08-07 11:17:53 +07:00
afriadirahman 01990ccec1 Merge branch 'main' of https://git.probindo.com/Probindo/database-pertani-web 2026-08-06 13:29:42 +07:00
irwan.l.cahyono 8aed88a31f dashboard indeks petani 2026-08-05 01:20:19 +07:00
irwan.l.cahyono 4aa0780802 dashboard profil petani komp 4 2026-08-03 13:08:01 +07:00
afriadirahman 4e41246382 Update Profile Petani Dashboard 2026-08-03 12:53:20 +07:00
Althaf 43fe9e5f7f Merge branch 'main' of https://git.probindo.com/Probindo/database-pertani-web 2026-08-03 09:22:47 +07:00
irwan.l.cahyono c8d1994d3b dashboard profil petani 2026-07-30 15:23:34 +07:00
Althaf cf0f4b47b4 update akses pasar 2026-07-30 11:14:31 +07:00
irwan.l.cahyono 24a8016710 petani booted skor 2026-07-29 16:52:51 +07:00
irwan.l.cahyono 20e1eee6ff skor petani domain komponen hitung 2026-07-29 16:27:33 +07:00
afriadirahman c0432cd5f8 Update Sidebar Filter Fasilitator 2026-07-29 16:12:31 +07:00
irwan.l.cahyono 0ce0936a80 skor petani update 2026-07-29 16:05:43 +07:00
Syaharani 502c932f21 Merge branch 'main' of https://git.probindo.com/Probindo/database-pertani-web 2026-07-28 16:54:37 +07:00
Syaharani e60a66eeb7 bumdes: profil & add pengurus bumdes 2026-07-28 16:54:27 +07:00
afriadirahman 4475cd0098 Update Logo Sidebar 2026-07-28 16:18:41 +07:00
afriadirahman 67c111a2b3 Update Logo Agromonev & Agropro 2026-07-28 16:10:47 +07:00
Syaharani 3bcaa3ea50 solve survey produktivitas 2026-07-27 10:14:36 +07:00
Syaharani bed9a6f620 solve 2026-07-23 18:26:24 +07:00
90 changed files with 17518 additions and 463 deletions
@@ -0,0 +1,26 @@
<?php
namespace App\Enums\AksesPasar;
enum TingkatKepercayaanPembeli: int
{
case SANGAT_PERCAYA = 1;
case CUKUP_PERCAYA = 2;
case RAGU_RAGU = 3;
case TIDAK_PERCAYA = 4;
public static function options(): array
{
return [
['value' => self::SANGAT_PERCAYA->value, 'label' => 'Sangat percaya, berani langsung coba'],
['value' => self::CUKUP_PERCAYA->value, 'label' => 'Cukup percaya, tapi hati hati'],
['value' => self::RAGU_RAGU->value, 'label' => 'Ragu ragu'],
['value' => self::TIDAK_PERCAYA->value, 'label' => 'Tidak percaya, enggan mencoba'],
];
}
public static function values(): array
{
return array_column(self::cases(), 'value');
}
}
+46
View File
@@ -0,0 +1,46 @@
<?php
namespace App\Enums\Bumdes;
enum JabatanBumdes: string
{
case DIREKTUR = 'direktur';
case DIREKTUR_KETUA = 'direktur_ketua';
case SEKRETARIS = 'sekretaris';
case BENDAHARA = 'bendahara';
case KEPALA_UNIT_USAHA = 'kepala_unit_usaha';
case PENGAWAS = 'pengawas';
case PENASIHAT = 'penasihat';
case ANGGOTA = 'anggota';
case STAF_OPERASIONAL = 'staf_operasional';
case LAINNYA = 'lainnya';
public function label(): string
{
return match ($this) {
self::DIREKTUR => 'Direktur/Ketua',
self::DIREKTUR_KETUA => 'Direktur/Ketua',
self::SEKRETARIS => 'Sekretaris',
self::BENDAHARA => 'Bendahara',
self::KEPALA_UNIT_USAHA => 'Kepala Unit Usaha',
self::PENGAWAS => 'Pengawas',
self::PENASIHAT => 'Penasihat',
self::ANGGOTA => 'Anggota',
self::STAF_OPERASIONAL => 'Staf Operasional',
self::LAINNYA => 'Lainnya',
};
}
public static function options(): array
{
return collect([
self::DIREKTUR_KETUA,
self::SEKRETARIS,
self::BENDAHARA,
self::LAINNYA,
])->map(fn ($case) => [
'value' => $case->value,
'label' => $case->label(),
])->toArray();
}
}
+10
View File
@@ -0,0 +1,10 @@
<?php
namespace App\Enums\Koperasi;
enum PosisiKoperasi: string
{
case PENGURUS = 'Pengurus koperasi';
case ANGGOTA = 'Anggota koperasi';
case PENDAMPING = 'Pendamping koperasi';
}
@@ -0,0 +1,580 @@
<?php
namespace App\Http\Controllers\Web\Bumdes;
use App\Enums\Bumdes\JabatanBumdes;
use App\Enums\Pendidikan;
use App\Http\Controllers\Controller;
use App\Models\Bumdes\KelembagaanAktorBumdes;
use App\Models\Bumdes\PengurusBumdes;
use App\Models\Wilayah\Provinsi;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Str;
use Illuminate\Validation\Rule;
class PengurusBumdesController extends Controller
{
public function index(Request $request)
{
if (! Gate::any(['super_admin', 'admin', 'fasilitator'])) {
abort(403);
}
$query = PengurusBumdes::with([
...$this->wilayahRelationsWithoutProgramScope(),
'creator:id,name',
])
->orderBy('created_at', 'desc');
if ($request->search) {
$query->where(function ($query) use ($request) {
$query->where('nama', 'like', '%' . $request->search . '%')
->orWhere('jabatan', 'like', '%' . $request->search . '%')
->orWhere('jabatan_lainnya', 'like', '%' . $request->search . '%');
});
}
if (auth()->user()->role->value === 'fasilitator') {
$query->where('created_by', auth()->id());
}
$summaryQuery = clone $query;
$totalPengurus = (clone $summaryQuery)->count();
$totalLakiLaki = (clone $summaryQuery)->where('jenis_kelamin', true)->count();
$totalPerempuan = (clone $summaryQuery)->where('jenis_kelamin', false)->count();
$totalDesaKelurahan = (clone $summaryQuery)->distinct('desa_kelurahan_id')->count('desa_kelurahan_id');
$totalJabatan = (clone $summaryQuery)->distinct('jabatan')->count('jabatan');
$pengurus = $query->paginate($request->per_page ?? 10);
$userRole = auth()->user()->role->value;
$showEnumerator = in_array($userRole, ['super_admin', 'admin']);
return view('bumdes.profil.index', compact(
'pengurus',
'totalPengurus',
'totalLakiLaki',
'totalPerempuan',
'totalDesaKelurahan',
'totalJabatan',
'showEnumerator'
));
}
public function create()
{
if (! Gate::any(['super_admin', 'admin', 'fasilitator'])) {
abort(403);
}
$provinsi = $this->provinsiOptions();
$jabatan = JabatanBumdes::options();
$pendidikan = Pendidikan::options();
return view('bumdes.profil.add', compact('provinsi', 'jabatan', 'pendidikan'));
}
public function store(Request $request)
{
if (! Gate::any(['super_admin', 'admin', 'fasilitator'])) {
abort(403);
}
$validatedData = $this->validatedData($request);
$pengurus = PengurusBumdes::create([
...$this->formatData($validatedData),
'uid' => 'BMD-' . strtoupper(Str::random(10)),
'created_by' => auth()->id(),
'updated_by' => auth()->id(),
]);
return redirect()->route('bumdes.edit', $pengurus->id)->with('success', 'Data pengurus BUMDes berhasil ditambahkan.');
}
public function show(string $id)
{
return redirect()->route('bumdes.edit', $id);
}
public function edit(string $id)
{
if (! Gate::any(['super_admin', 'admin', 'fasilitator'])) {
abort(403);
}
$pengurus = $this->pengurusQuery()
->with($this->wilayahRelationsWithoutProgramScope())
->findOrFail($id);
$provinsi = $this->provinsiOptions();
$jabatan = JabatanBumdes::options();
$pendidikan = Pendidikan::options();
return view('bumdes.profil.edit', compact('pengurus', 'provinsi', 'jabatan', 'pendidikan'));
}
public function update(Request $request, string $id)
{
if (! Gate::any(['super_admin', 'admin', 'fasilitator'])) {
abort(403);
}
$pengurus = $this->pengurusQuery()->findOrFail($id);
$validatedData = $this->validatedData($request);
$pengurus->update([
...$this->formatData($validatedData),
'updated_by' => auth()->id(),
]);
return redirect()->route('bumdes.edit', $pengurus->id)->with('success', 'Data pengurus BUMDes berhasil diupdate.');
}
public function destroy(string $id)
{
if (! Gate::any(['super_admin', 'admin', 'fasilitator'])) {
abort(403);
}
$pengurus = $this->pengurusQuery()->findOrFail($id);
$pengurus->update(['deleted_by' => auth()->id()]);
$pengurus->delete();
return response()->json(['message' => 'Data pengurus BUMDes berhasil dihapus.']);
}
public function kelembagaanAktor(string $id)
{
if (! Gate::any(['super_admin', 'admin', 'fasilitator'])) {
abort(403);
}
$pengurus = $this->pengurusQuery()
->with([
...$this->wilayahRelationsWithoutProgramScope(),
'kelembagaanAktor',
])
->findOrFail($id);
$kelembagaanAktor = $pengurus->kelembagaanAktor;
return view('bumdes.kelembagaan-aktor.index', array_merge(
compact('pengurus', 'kelembagaanAktor'),
$this->kelembagaanAktorOptions()
));
}
public function storeKelembagaanAktor(Request $request, string $id)
{
if (! Gate::any(['super_admin', 'admin', 'fasilitator'])) {
abort(403);
}
$pengurus = $this->pengurusQuery()->findOrFail($id);
$validatedData = $this->validatedKelembagaanAktorData($request);
KelembagaanAktorBumdes::updateOrCreate(
['pengurus_bumdes_id' => $pengurus->id],
[
...$this->formatKelembagaanAktorData($validatedData),
'created_by' => $pengurus->kelembagaanAktor?->created_by ?? auth()->id(),
'updated_by' => auth()->id(),
]
);
return redirect()
->route('bumdes.kelembagaan-aktor.index', $pengurus->id)
->with('success', 'Data kelembagaan dan aktor BUMDes berhasil disimpan.');
}
private function pengurusQuery()
{
$query = PengurusBumdes::query();
if (auth()->user()->role->value === 'fasilitator') {
$query->where('created_by', auth()->id());
}
return $query;
}
private function provinsiOptions()
{
return Provinsi::withoutGlobalScope('program')
->select('id', 'kode', 'nama')
->orderBy('kode', 'asc')
->get();
}
private function wilayahRelationsWithoutProgramScope(): array
{
return [
'desaKelurahan' => fn ($query) => $query->withoutGlobalScope('program')->select('id', 'nama', 'kecamatan_id'),
'desaKelurahan.kecamatan' => fn ($query) => $query->withoutGlobalScope('program')->select('id', 'nama', 'kabupaten_kota_id'),
'desaKelurahan.kecamatan.kabupatenKota' => fn ($query) => $query->withoutGlobalScope('program')->select('id', 'nama', 'provinsi_id'),
'desaKelurahan.kecamatan.kabupatenKota.provinsi' => fn ($query) => $query->withoutGlobalScope('program')->select('id', 'nama'),
];
}
private function validatedData(Request $request): array
{
return $request->validate([
'nama' => ['required', 'string', 'max:255'],
'jenis_kelamin' => ['required', 'boolean'],
'tempat_lahir' => ['required', 'string', 'max:255'],
'tanggal_lahir' => ['required', 'date_format:d-m-Y'],
'pendidikan_terakhir' => ['required', Rule::enum(Pendidikan::class)],
'alamat' => ['required', 'string', 'max:500'],
'desa_kelurahan_id' => ['required', 'exists:master_desa_kelurahan,id'],
'nomor_telepon' => ['nullable', 'digits_between:11,13'],
'jabatan' => ['required', Rule::enum(JabatanBumdes::class)],
'jabatan_lainnya' => ['nullable', 'required_if:jabatan,' . JabatanBumdes::LAINNYA->value, 'string', 'max:255'],
'lama_menjabat_tahun' => ['required', 'integer', 'min:0', 'max:80'],
], [
'nama.required' => 'Nama harus diisi.',
'jenis_kelamin.required' => 'Jenis kelamin harus dipilih.',
'tempat_lahir.required' => 'Tempat lahir harus diisi.',
'tanggal_lahir.required' => 'Tanggal lahir harus diisi.',
'tanggal_lahir.date_format' => 'Tanggal lahir harus menggunakan format tanggal yang valid.',
'pendidikan_terakhir.required' => 'Pendidikan terakhir harus dipilih.',
'alamat.required' => 'Alamat harus diisi.',
'desa_kelurahan_id.required' => 'Desa kelurahan harus dipilih.',
'desa_kelurahan_id.exists' => 'Desa kelurahan tidak ditemukan.',
'nomor_telepon.digits_between' => 'Nomor telepon harus berupa angka 11 sampai 13 digit.',
'jabatan.required' => 'Jabatan/peran harus dipilih.',
'jabatan_lainnya.required_if' => 'Jabatan lainnya harus diisi.',
'lama_menjabat_tahun.required' => 'Lama menjabat harus diisi.',
'lama_menjabat_tahun.integer' => 'Lama menjabat harus berupa angka tahun.',
]);
}
private function formatData(array $data): array
{
$data['tanggal_lahir'] = Carbon::createFromFormat('d-m-Y', $data['tanggal_lahir'])->format('Y-m-d');
$data['tanggal_mulai_menjabat'] = Carbon::now()
->subYears((int) $data['lama_menjabat_tahun'])
->format('Y-m-d');
if (($data['jabatan'] ?? null) !== JabatanBumdes::LAINNYA->value) {
$data['jabatan_lainnya'] = null;
}
return $data;
}
private function validatedKelembagaanAktorData(Request $request): array
{
$this->normalizeKelembagaanAktorInput($request);
$maxYear = now()->year + 1;
return $request->validate([
'status_badan_hukum' => ['nullable', Rule::in(array_keys($this->statusBadanHukumOptions()))],
'nomor_dasar_hukum' => ['nullable', 'string', 'max:255'],
'tahun_dasar_hukum' => ['nullable', 'integer', 'digits:4', 'min:1900', 'max:' . $maxYear],
'status_keaktifan' => ['nullable', Rule::in(array_keys($this->statusKeaktifanOptions()))],
'alasan_tidak_aktif' => ['nullable', 'string'],
'unit_usaha' => ['nullable', 'array'],
'unit_usaha.*' => ['string', Rule::in(array_keys($this->unitUsahaOptions()))],
'unit_usaha_jasa_lainnya' => ['nullable', 'string', 'max:255'],
'status_unit_komoditas' => ['nullable', Rule::in(array_keys($this->statusUnitKomoditasOptions()))],
'nama_unit_komoditas' => ['nullable', 'string', 'max:255'],
'status_ad_art' => ['nullable', Rule::in(array_keys($this->statusAdArtOptions()))],
'tahun_ad_art' => ['nullable', 'integer', 'digits:4', 'min:1900', 'max:' . $maxYear],
'pengurus_inti' => ['nullable', 'array'],
'pengurus_inti.*.jabatan' => ['nullable', 'string', 'max:255'],
'pengurus_inti.*.nama' => ['nullable', 'string', 'max:255'],
'pengurus_inti.*.aktif' => ['nullable', 'boolean'],
'memiliki_staf' => ['nullable', 'boolean'],
'jumlah_staf' => ['nullable', 'integer', 'min:0'],
'unit_usaha_staf' => ['nullable', 'string'],
'modal_awal' => ['nullable', 'integer', 'min:0'],
'tahun_modal_awal' => ['nullable', 'integer', 'digits:4', 'min:1900', 'max:' . $maxYear],
'pernah_penambahan_modal' => ['nullable', 'boolean'],
'penambahan_modal' => ['nullable', 'array'],
'penambahan_modal.*.tahun' => ['nullable', 'integer', 'digits:4', 'min:1900', 'max:' . $maxYear],
'penambahan_modal.*.jumlah' => ['nullable', 'integer', 'min:0'],
'aset_produktif' => ['nullable', 'array'],
'aset_produktif.*.aset' => ['nullable', 'string', 'max:255'],
'aset_produktif.*.dipilih' => ['nullable', 'boolean'],
'aset_produktif.*.jumlah' => ['nullable', 'string', 'max:255'],
'aset_produktif.*.kondisi' => ['nullable', 'string', 'max:255'],
'aset_produktif_lainnya' => ['nullable', 'string', 'max:255'],
'status_kepemilikan_aset' => ['nullable', Rule::in(array_keys($this->statusKepemilikanAsetOptions()))],
'infrastruktur_pascapanen' => ['nullable', 'array'],
'infrastruktur_pascapanen.*.infrastruktur' => ['nullable', 'string', 'max:255'],
'infrastruktur_pascapanen.*.dipilih' => ['nullable', 'boolean'],
'infrastruktur_pascapanen.*.jumlah' => ['nullable', 'string', 'max:255'],
'infrastruktur_pascapanen.*.kondisi' => ['nullable', Rule::in(array_keys($this->kondisiInfrastrukturOptions()))],
'infrastruktur_pascapanen_lainnya' => ['nullable', 'string', 'max:255'],
], $this->kelembagaanAktorValidationMessages(), $this->kelembagaanAktorValidationAttributes());
}
private function normalizeKelembagaanAktorInput(Request $request): void
{
foreach (['modal_awal'] as $field) {
if ($request->has($field)) {
$request->merge([$field => preg_replace('/\D/', '', (string) $request->input($field))]);
}
}
$penambahanModal = collect($request->input('penambahan_modal', []))
->map(function ($row) {
if (isset($row['jumlah'])) {
$row['jumlah'] = preg_replace('/\D/', '', (string) $row['jumlah']);
}
return $row;
})
->all();
if ($request->has('penambahan_modal')) {
$request->merge(['penambahan_modal' => $penambahanModal]);
}
}
private function formatKelembagaanAktorData(array $data): array
{
$payload = array_merge([
'status_badan_hukum' => null,
'nomor_dasar_hukum' => null,
'tahun_dasar_hukum' => null,
'status_keaktifan' => null,
'alasan_tidak_aktif' => null,
'unit_usaha' => [],
'unit_usaha_jasa_lainnya' => null,
'status_unit_komoditas' => null,
'nama_unit_komoditas' => null,
'status_ad_art' => null,
'tahun_ad_art' => null,
'pengurus_inti' => [],
'memiliki_staf' => null,
'jumlah_staf' => null,
'unit_usaha_staf' => null,
'modal_awal' => null,
'tahun_modal_awal' => null,
'pernah_penambahan_modal' => null,
'penambahan_modal' => [],
'aset_produktif' => [],
'aset_produktif_lainnya' => null,
'status_kepemilikan_aset' => null,
'infrastruktur_pascapanen' => [],
'infrastruktur_pascapanen_lainnya' => null,
], $data);
$payload['unit_usaha'] = array_values($payload['unit_usaha'] ?? []);
$payload['pengurus_inti'] = $this->filterRows($payload['pengurus_inti'] ?? [], ['nama', 'aktif']);
$payload['penambahan_modal'] = $this->filterRows($payload['penambahan_modal'] ?? [], ['tahun', 'jumlah']);
$payload['aset_produktif'] = $this->filterRows($payload['aset_produktif'] ?? [], ['dipilih', 'jumlah', 'kondisi']);
$payload['infrastruktur_pascapanen'] = $this->filterRows($payload['infrastruktur_pascapanen'] ?? [], ['dipilih', 'jumlah', 'kondisi']);
if (($payload['status_keaktifan'] ?? null) !== 'tidak_aktif_vakum') {
$payload['alasan_tidak_aktif'] = null;
}
if (! in_array('jasa_lainnya', $payload['unit_usaha'], true)) {
$payload['unit_usaha_jasa_lainnya'] = null;
}
if (($payload['status_unit_komoditas'] ?? null) !== 'ya') {
$payload['nama_unit_komoditas'] = null;
}
if (($payload['status_ad_art'] ?? null) !== 'ada_lengkap') {
$payload['tahun_ad_art'] = null;
}
if (! (bool) ($payload['memiliki_staf'] ?? false)) {
$payload['jumlah_staf'] = null;
$payload['unit_usaha_staf'] = null;
}
if (! (bool) ($payload['pernah_penambahan_modal'] ?? false)) {
$payload['penambahan_modal'] = null;
}
if (! collect($payload['aset_produktif'] ?? [])->contains(fn ($row) => ($row['aset'] ?? null) === 'lainnya')) {
$payload['aset_produktif_lainnya'] = null;
}
if (! collect($payload['infrastruktur_pascapanen'] ?? [])->contains(fn ($row) => ($row['infrastruktur'] ?? null) === 'lainnya')) {
$payload['infrastruktur_pascapanen_lainnya'] = null;
}
return $payload;
}
private function filterRows(array $rows, array $valueKeys): array
{
return collect($rows)
->map(function ($row) {
return collect($row)
->map(fn ($value) => $value === '' ? null : $value)
->all();
})
->filter(function ($row) use ($valueKeys) {
foreach ($valueKeys as $key) {
if (filled($row[$key] ?? null)) {
return true;
}
}
return false;
})
->values()
->all();
}
private function kelembagaanAktorOptions(): array
{
return [
'statusBadanHukumOptions' => $this->statusBadanHukumOptions(),
'statusKeaktifanOptions' => $this->statusKeaktifanOptions(),
'unitUsahaOptions' => $this->unitUsahaOptions(),
'statusUnitKomoditasOptions' => $this->statusUnitKomoditasOptions(),
'statusAdArtOptions' => $this->statusAdArtOptions(),
'pengurusIntiRows' => $this->pengurusIntiRows(),
'asetProduktifRows' => $this->asetProduktifRows(),
'statusKepemilikanAsetOptions' => $this->statusKepemilikanAsetOptions(),
'infrastrukturPascapanenRows' => $this->infrastrukturPascapanenRows(),
'kondisiInfrastrukturOptions' => $this->kondisiInfrastrukturOptions(),
];
}
private function statusBadanHukumOptions(): array
{
return [
'sudah_berbadan_hukum' => 'Sudah berbadan hukum (terdaftar Kemenkumham)',
'proses_pendaftaran' => 'Proses pendaftaran',
'belum_berbadan_hukum' => 'Belum berbadan hukum',
'tidak_tahu' => 'Tidak tahu',
];
}
private function statusKeaktifanOptions(): array
{
return [
'aktif_penuh' => 'Aktif beroperasi penuh',
'aktif_terbatas' => 'Aktif tapi terbatas (sebagian unit usaha berjalan)',
'tidak_aktif_vakum' => 'Tidak aktif/vakum',
'berdiri_belum_beroperasi' => 'Sudah berdiri tapi belum pernah beroperasi',
];
}
private function unitUsahaOptions(): array
{
return [
'simpan_pinjam' => 'Simpan pinjam',
'perdagangan_toko_desa' => 'Perdagangan/toko desa',
'pengelolaan_air_bersih' => 'Pengelolaan air bersih',
'wisata_desa_agrowisata' => 'Wisata desa/agrowisata',
'pengelolaan_hasil_pertanian_komoditas' => 'Pengelolaan hasil pertanian/komoditas',
'penyewaan_alat_aset' => 'Penyewaan alat/aset',
'jasa_lainnya' => 'Jasa lainnya',
];
}
private function statusUnitKomoditasOptions(): array
{
return [
'ya' => 'Ya, ada unit khusus',
'ditangani_pengurus_inti' => 'Tidak ada unit khusus, ditangani langsung pengurus inti',
'direncanakan' => 'Belum ada, masih direncanakan',
];
}
private function statusAdArtOptions(): array
{
return [
'ada_lengkap' => 'Ada, lengkap',
'ada_tidak_lengkap' => 'Ada tapi tidak lengkap',
'tidak_ada' => 'Tidak ada',
'tidak_tahu' => 'Tidak tahu',
];
}
private function pengurusIntiRows(): array
{
return [
'penasihat_kepala_desa' => 'Penasihat (Kepala Desa)',
'ketua_pengawas' => 'Ketua Pengawas',
'direktur_ketua_bumdes' => 'Direktur/Ketua BUMDes',
'sekretaris' => 'Sekretaris',
'bendahara' => 'Bendahara',
'kepala_unit_usaha_komoditas' => 'Kepala Unit Usaha Komoditas',
'lainnya' => 'Lainnya',
];
}
private function asetProduktifRows(): array
{
return [
'bangunan_kantor' => 'Bangunan / kantor',
'gudang_penyimpanan' => 'Gudang penyimpanan',
'kendaraan_operasional_angkut' => 'Kendaraan operasional/angkut',
'lahan_usaha' => 'Lahan usaha',
'alat_pengolahan_komoditas' => 'Alat pengolahan komoditas',
'lainnya' => 'Lainnya',
];
}
private function statusKepemilikanAsetOptions(): array
{
return [
'milik_bumdes_sendiri' => 'Milik BUMDes sendiri',
'milik_desa_dipinjamkan_dikelola' => 'Milik desa (dipinjamkan/dikelola)',
'sewa_pinjam_pihak_lain' => 'Sewa/pinjam pihak lain',
];
}
private function infrastrukturPascapanenRows(): array
{
return [
'gudang_penyimpanan_hasil_panen' => 'Gudang penyimpanan hasil panen',
'alat_mesin_pengering' => 'Alat/mesin pengering',
'mesin_pulper_huller' => 'Mesin pulper/huller',
'timbangan' => 'Timbangan',
'alat_sortasi' => 'Alat sortasi',
'lainnya' => 'Lainnya',
];
}
private function kondisiInfrastrukturOptions(): array
{
return [
'baik_berfungsi' => 'Baik dan berfungsi',
'rusak_tidak_terpakai' => 'Rusak/tidak terpakai',
];
}
private function kelembagaanAktorValidationMessages(): array
{
return [
'integer' => ':attribute harus berupa angka.',
'digits' => ':attribute harus terdiri dari :digits digit.',
'min' => ':attribute tidak boleh kurang dari :min.',
'max' => ':attribute tidak valid.',
'in' => ':attribute tidak valid.',
'array' => ':attribute harus berupa daftar data.',
'boolean' => ':attribute harus dipilih.',
];
}
private function kelembagaanAktorValidationAttributes(): array
{
return [
'status_badan_hukum' => 'Status badan hukum',
'nomor_dasar_hukum' => 'Nomor dasar hukum',
'tahun_dasar_hukum' => 'Tahun dasar hukum',
'status_keaktifan' => 'Status keaktifan',
'unit_usaha' => 'Unit usaha',
'status_unit_komoditas' => 'Unit usaha komoditas',
'status_ad_art' => 'Dokumen AD/ART',
'memiliki_staf' => 'Status staf/karyawan',
'jumlah_staf' => 'Jumlah staf',
'modal_awal' => 'Modal awal',
'tahun_modal_awal' => 'Tahun modal awal',
'pernah_penambahan_modal' => 'Status penambahan modal',
'status_kepemilikan_aset' => 'Status kepemilikan aset',
];
}
}
@@ -0,0 +1,278 @@
<?php
namespace App\Http\Controllers\Web\Dashboard;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Gate;
use App\Models\Pertanian\Petani;
use App\Models\Pertanian\Komoditas;
use App\Models\Pertanian\Lahan;
use App\Models\Pertanian\PendapatanKomoditas;
class DemografiPetaniController extends Controller
{
public function index(Request $request)
{
if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) {
abort(403);
}
$petaniCounts = Petani::selectRaw("
COUNT(*) as total,
COUNT(*) FILTER (WHERE jenis_kelamin = true) as laki,
COUNT(*) FILTER (WHERE jenis_kelamin = false) as perempuan
")->first();
$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'))
->groupBy('pendidikan_terakhir')
->pluck('total', 'pendidikan_terakhir');
$pendidikan = [
'tidak_sekolah' => (int) ($pendidikanCounts['01_tidak_sekolah'] ?? 0),
'sd' => (int) ($pendidikanCounts['02_sd'] ?? 0),
'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),
];
$komoditasUtama = Komoditas::query()
->whereHas('petani')
->withCount('petani')
->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'),
'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' => $luasLahanBuckets->kurang_05,
'05_1' => $luasLahanBuckets->luas_05_1,
'1_2' => $luasLahanBuckets->luas_1_2,
'lebih_2' => $luasLahanBuckets->lebih_2,
];
$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' => $penghasilanBuckets->kurang_1,
'1_3' => $penghasilanBuckets->p1_3,
'3_5' => $penghasilanBuckets->p3_5,
'5_10' => $penghasilanBuckets->p5_10,
'lebih_10' => $penghasilanBuckets->lebih_10,
];
$data = [
'total_petani' => $totalPetani,
'petani_lakilaki' => $petaniLakilaki,
'petani_perempuan' => $petaniPerempuan,
'total_komoditas' => $totalKomoditas,
'total_luas_lahan' => $totalLuasLahan,
'ratarata_luas_lahan' => $ratarataLuasLahan,
'kelompok_umur' => [
'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 ($v) => (int) $v)->values(),
],
'luas_lahan' => $luasLahan,
'penghasilan' => $penghasilan,
];
$daftarPetani = Petani::with(['komoditas'])
->withSum('lahans as total_luas_lahan', 'luas_lahan')
->orderBy('id')
->paginate(10);
return view('dashboard.demografi-petani', compact('data', 'daftarPetani'));
}
public function data(Request $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')
->withSum('lahans as total_luas_lahan', 'luas_lahan')
->addSelect(['total_pendapatan' => $pendapatanSub]);
if ($request->filled('search')) {
$query->where('nama', 'ILIKE', "%{$request->search}%");
}
if ($request->has('gender') && $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"),
'30_39' => $query->whereNotNull('tanggal_lahir')
->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"),
'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,
};
}
if ($request->filled('pendidikan')) {
$pendidikanMap = [
'tidak_sekolah' => ['01_tidak_sekolah'],
'sd' => ['02_sd'],
'smp' => ['03_smp'],
'sma' => ['04_sma'],
'diploma' => ['05_diploma'],
's1_keatas' => ['06_sarjana', '07_magister'],
];
if (isset($pendidikanMap[$request->pendidikan])) {
$query->whereIn('pendidikan_terakhir', $pendidikanMap[$request->pendidikan]);
}
}
if ($request->filled('komoditas')) {
$query->where('komoditas_id', $request->komoditas);
}
if ($request->filled('penghasilan')) {
[$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', 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'),
'1_2' => $lahanQuery->havingRaw('SUM(luas_lahan) > 10000 AND SUM(luas_lahan) <= 20000'),
'lebih_2' => $lahanQuery->havingRaw('SUM(luas_lahan) > 20000'),
default => null,
};
$query->whereIn('id', $lahanQuery->pluck('petani_id'));
}
$daftarPetani = $query->orderBy('id')->paginate(10);
$pendidikanLabels = [
'01_tidak_sekolah' => 'Tidak Sekolah',
'02_sd' => 'SD',
'03_smp' => 'SMP',
'04_sma' => 'SMA',
'05_diploma' => 'Diploma',
'06_sarjana' => 'Sarjana',
'07_magister' => 'Magister',
];
$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 = $petani->total_pendapatan;
$rentangPenghasilan = match (true) {
$pendapatan === null => '-',
$pendapatan < 1000000 => '< Rp1 juta',
$pendapatan <= 3000000 => 'Rp1 - 3 juta',
$pendapatan <= 5000000 => 'Rp3 - 5 juta',
$pendapatan <= 10000000 => 'Rp5 - 10 juta',
default => '> Rp10 juta',
};
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,
];
});
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(),
],
]);
}
}
@@ -0,0 +1,658 @@
<?php
namespace App\Http\Controllers\Web\Dashboard;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\JsonResponse;
use App\Models\Pertanian\Petani;
use App\Models\Pertanian\Komoditas;
use App\Models\Pertanian\Lahan;
use App\Models\Pertanian\Tanaman;
use App\Models\Pertanian\SkorPetani;
use App\Models\Wilayah\Provinsi;
use App\Models\Wilayah\KabupatenKota;
use App\Models\Wilayah\Kecamatan;
use App\Models\Wilayah\DesaKelurahan;
class IndeksPetaniController extends Controller
{
private function filters(Request $request): array
{
return [
'desaKelurahan_id' => $request->desaKelurahan_id,
'kecamatan_id' => $request->kecamatan_id,
'kabupatenKota_id' => $request->kabupatenKota_id,
'provinsi_id' => $request->provinsi_id,
'komoditas_id' => $request->komoditas_id,
'segmen' => $request->segmen,
];
}
private function petaniQuery(array $filters): \Illuminate\Database\Eloquent\Builder
{
$petaniQuery = Petani::query()
->join('master_desa_kelurahan', 'petani.desa_kelurahan_id', '=', 'master_desa_kelurahan.id')
->join('master_kecamatan', 'master_desa_kelurahan.kecamatan_id', '=', 'master_kecamatan.id')
->join('master_kabupaten_kota', 'master_kecamatan.kabupaten_kota_id', '=', 'master_kabupaten_kota.id')
->join('master_provinsi', 'master_kabupaten_kota.provinsi_id', '=', 'master_provinsi.id')
->whereNull('petani.deleted_at')
->when($filters['provinsi_id'], fn($q, $id) => $q->where('master_kabupaten_kota.provinsi_id', $id))
->when($filters['kabupatenKota_id'], fn($q, $id) => $q->where('master_kecamatan.kabupaten_kota_id', $id))
->when($filters['kecamatan_id'], fn($q, $id) => $q->where('master_desa_kelurahan.kecamatan_id', $id))
->when($filters['desaKelurahan_id'], fn($q, $id) => $q->where('petani.desa_kelurahan_id', $id))
->when($filters['komoditas_id'], fn($q, $id) => $q->where('petani.komoditas_id', $id));
return $petaniQuery;
}
private function skorPetaniQuery(array $filters, array $komoditas): \Illuminate\Database\Eloquent\Builder
{
$skor = SkorPetani::query()
->join('petani', 'petani_skor.petani_id', '=', 'petani.id')
->join('master_desa_kelurahan', 'petani.desa_kelurahan_id', '=', 'master_desa_kelurahan.id')
->join('master_kecamatan', 'master_desa_kelurahan.kecamatan_id', '=', 'master_kecamatan.id')
->join('master_kabupaten_kota', 'master_kecamatan.kabupaten_kota_id', '=', 'master_kabupaten_kota.id')
->join('master_provinsi', 'master_kabupaten_kota.provinsi_id', '=', 'master_provinsi.id')
->whereNull('petani.deleted_at')
->when($filters['provinsi_id'], fn($q, $id) => $q->where('master_kabupaten_kota.provinsi_id', $id))
->when($filters['kabupatenKota_id'], fn($q, $id) => $q->where('master_kecamatan.kabupaten_kota_id', $id))
->when($filters['kecamatan_id'], fn($q, $id) => $q->where('master_desa_kelurahan.kecamatan_id', $id))
->when($filters['desaKelurahan_id'], fn($q, $id) => $q->where('petani.desa_kelurahan_id', $id))
->whereIn('petani.komoditas_id', $komoditas);
if ($filters['segmen']) {
$skor->where(function ($q) use ($filters) {
match ($filters['segmen']) {
'Penggerak' => $q->where('skor_kesiapan_adopsi', '>=', 4),
'Perintis' => $q->where(function($q) {
$q->where('skor_kesiapan_adopsi', '>=', 3)
->where('skor_kesiapan_adopsi', '<', 4);
}),
'Pemerhati' => $q->where(function($q) {
$q->where('skor_kesiapan_adopsi', '>=', 2)
->where('skor_kesiapan_adopsi', '<', 3);
}),
'Pemula' => $q->where(function($q) {
$q->where('skor_kesiapan_adopsi', '>=', 1)
->where('skor_kesiapan_adopsi', '<', 2);
}),
'Belum Lengkap' => $q->where(function ($q) {
$q->whereNull('skor_kesiapan_adopsi')
->orWhere('skor_kesiapan_adopsi', '<', 1);
}),
default => null,
};
});
}
return $skor;
}
public function index(Request $request)
{
if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) {
abort(403);
}
$filters = $this->filters($request);
$title = 'Dashboard Profil Petani';
$komoditas = Komoditas::where('is_utama', true)->get();
$petaniQuery = $this->petaniQuery($filters);
$desaKelurahan = $petaniQuery->clone()
->selectRaw("
master_desa_kelurahan.id as desa_kelurahan_id,
master_desa_kelurahan.nama as desa_kelurahan,
master_desa_kelurahan.path as path,
master_kecamatan.id as kecamatan_id,
master_kecamatan.nama as kecamatan,
master_kabupaten_kota.id as kabupaten_id,
master_kabupaten_kota.nama as kabupaten,
master_provinsi.id as provinsi_id,
master_provinsi.nama as provinsi
")
->distinct()
->get();
$wilayah = $desaKelurahan
->groupBy('provinsi_id')
->map(function ($provinsi) {
return [
'id' => $provinsi->first()->provinsi_id,
'nama' => $provinsi->first()->provinsi,
'kabupaten' => $provinsi
->groupBy('kabupaten_id')
->map(function ($kabupaten) {
return [
'id' => $kabupaten->first()->kabupaten_id,
'nama' => $kabupaten->first()->kabupaten,
'kecamatan' => $kabupaten
->groupBy('kecamatan_id')
->map(function ($kecamatan) {
return [
'id' => $kecamatan->first()->kecamatan_id,
'nama' => $kecamatan->first()->kecamatan,
'desa' => $kecamatan->map(function ($desa) {
return [
'id' => $desa->desa_kelurahan_id,
'nama' => $desa->desa_kelurahan,
'path' => $desa->path,
];
})->values(),
];
})->values(),
];
})->values(),
];
})->values();
return view('dashboard.indeks-petani', array_merge($filters,
compact(
'komoditas',
'desaKelurahan',
'wilayah',
)));
}
public function summary(Request $request): JsonResponse
{
$filters = $this->filters($request);
$petaniQuery = $this->petaniQuery($filters);
$komoditas = Komoditas::where('is_utama', true)
->when($filters['komoditas_id'], fn($q, $id) => $q->where('id', $id))->get();
$countKomoditas = $petaniQuery->clone()
->whereHas('komoditas', fn ($query) => $query->where('is_utama', true))
->distinct()->count('komoditas_id');
$filteredPetaniIds = $petaniQuery
->clone()
->select('petani.id')
->distinct()
->pluck('petani.id');
$sumLahan = Lahan::has('petani')->whereIn('petani_id', $filteredPetaniIds)->whereIn('komoditas_id', $komoditas->pluck('id'))->sum('luas_lahan');
$avgLahan = Lahan::has('petani')->whereIn('petani_id', $filteredPetaniIds)->whereIn('komoditas_id', $komoditas->pluck('id'))->avg('luas_lahan');
$countDesa = $petaniQuery->clone()->whereIn('komoditas_id', $komoditas->pluck('id'))->distinct()->count('desa_kelurahan_id');
$countKecamatan = $petaniQuery->clone()->whereIn('komoditas_id', $komoditas->pluck('id'))->distinct()->count('master_kecamatan.id');
$skorQuery = $this->skorPetaniQuery($filters, $komoditas->pluck('id')->toArray());
$avgSkor = $skorQuery->clone()->avg('skor_kesiapan_adopsi');
if ($avgSkor >= 4.0) {
$avgSegmen = 'Penggerak';
} elseif ($avgSkor >= 3.0) {
$avgSegmen = 'Perintis';
} elseif ($avgSkor >= 2.0) {
$avgSegmen = 'Pemerhati';
} elseif ($avgSkor >= 1.0) {
$avgSegmen = 'Pemula';
} else {
$avgSegmen = 'Belum Lengkap';
}
return response()->json([
'petani' => $petaniQuery->clone()->count(),
'komoditas' => $countKomoditas,
'sum_lahan' => $sumLahan,
'avg_lahan' => $avgLahan,
'desa' => $countDesa,
'kecamatan' => $countKecamatan,
'skor' => $avgSkor,
'segmen' => $avgSegmen
]);
}
private function segments(): array
{
$segments = [
[
'name' => 'Penggerak',
'range' => '4.0 - 5.0',
'icon' => 'tabler-crown',
'color' => 'success',
],
[
'name' => 'Perintis',
'range' => '3.0 - 3.9',
'icon' => 'tabler-flag',
'color' => 'info',
],
[
'name' => 'Pemerhati',
'range' => '2.0 - 2.9',
'icon' => 'tabler-eye',
'color' => 'warning',
],
[
'name' => 'Pemula',
'range' => '1.0 - 1.9',
'icon' => 'tabler-seedling',
'color' => 'danger',
],
];
return $segments;
}
private function cases(): string
{
$case = "
CASE
WHEN skor_kesiapan_adopsi >= 4.0 THEN 'Penggerak'
WHEN skor_kesiapan_adopsi >= 3.0 THEN 'Perintis'
WHEN skor_kesiapan_adopsi >= 2.0 THEN 'Pemerhati'
WHEN skor_kesiapan_adopsi >= 1.0 THEN 'Pemula'
ELSE 'Belum Lengkap'
END
";
return $case;
}
public function segmen(Request $request): JsonResponse
{
$filters = $this->filters($request);
$segments = $this->segments();
$case = $this->cases();
$komoditas = Komoditas::where('is_utama', true)
->when($filters['komoditas_id'], fn($q, $id) => $q->where('id', $id))->get();
$skorQuery = $this->skorPetaniQuery($filters, $komoditas->pluck('id')->toArray());
$countSegmentasi = $skorQuery->clone()
->selectRaw("$case AS segmen, COUNT(*) AS total")
->groupByRaw($case)
->get();
$series = collect($segments)
->map(function ($segment) use ($countSegmentasi) {
return $countSegmentasi
->where('segmen', $segment['name'])
->sum('total');
})
->values();
$countPetani = $series->sum();
$persentase = collect($segments)
->map(function ($segment) use ($countSegmentasi, $countPetani) {
$total = $countSegmentasi
->where('segmen', $segment['name'])
->sum('total');
return $countPetani > 0
? ($total / $countPetani) * 100
: 0;
})
->values();
return response()->json([
'series' => $series,
'persentase' => $persentase,
]);
}
public function segmenByKomoditas(Request $request): JsonResponse
{
$filters = $this->filters($request);
$segments = $this->segments();
$case = $this->cases();
$komoditas = Komoditas::where('is_utama', true)
->when($filters['komoditas_id'], fn($q, $id) => $q->where('id', $id))->get();
$skorQuery = $this->skorPetaniQuery($filters, $komoditas->pluck('id')->toArray());
$countSegmentasiByKomoditas = $skorQuery->clone()
->selectRaw("
petani.komoditas_id,
$case AS segmen,
COUNT(petani.id) AS total
")
->groupBy('petani.komoditas_id')
->groupByRaw($case)
->get();
$seriesSegmentasiKomoditas = collect($segments)->map(function ($segment) use ($countSegmentasiByKomoditas, $komoditas) {
return [
'name' => $segment['name'],
'data' => $komoditas->map(function ($item) use ($countSegmentasiByKomoditas, $segment) {
return optional(
$countSegmentasiByKomoditas->first(function ($row) use ($item, $segment) {
return $row->komoditas_id == $item->id
&& $row->segmen == $segment['name'];
})
)->total ?? 0;
})->values(),
];
})->values();
return response()->json([
'categories' => $komoditas->pluck('nama')->values(),
'series' => $seriesSegmentasiKomoditas,
]);
}
public function dimensi(Request $request): JsonResponse
{
$filters = $this->filters($request);
$komoditas = Komoditas::where('is_utama', true)
->when($filters['komoditas_id'], fn($q, $id) => $q->where('id', $id))->get();
$skorQuery = $this->skorPetaniQuery($filters, $komoditas->pluck('id')->toArray());
$avgDimensi = $skorQuery->clone()
->selectRaw("
avg(skor_d2_sistem_praktik_budidaya) as skor_d2_sistem_praktik_budidaya,
avg(skor_d4_sosial_ekonomi) as skor_d4_sosial_ekonomi,
avg(skor_d6_rantai_nilai_akses_pasar) as skor_d6_rantai_nilai_akses_pasar")
->first();
return response()->json([
'radarDimensi' => [
round($avgDimensi->skor_d2_sistem_praktik_budidaya, 2),
round($avgDimensi->skor_d4_sosial_ekonomi, 2),
round($avgDimensi->skor_d6_rantai_nilai_akses_pasar, 2),
]
]);
}
public function komponen(Request $request): JsonResponse
{
$filters = $this->filters($request);
$komoditas = Komoditas::where('is_utama', true)
->when($filters['komoditas_id'], fn($q, $id) => $q->where('id', $id))->get();
$skorQuery = $this->skorPetaniQuery($filters, $komoditas->pluck('id')->toArray());
$avgKomponen = $skorQuery->clone()
->selectRaw("avg(skor_komp_1_d4_k3_motivasi_kapasitas_adopsi) as skor_komp_1_d4_k3_motivasi_kapasitas_adopsi,
avg(skor_komp_2_d4_k2_ekonomi_rumah_tangga) as skor_komp_2_d4_k2_ekonomi_rumah_tangga,
avg(skor_komp_3_d2_praktik_budidaya_gap) as skor_komp_3_d2_praktik_budidaya_gap,
avg(skor_komp_4_d4_k4_keterlibatan_kelembagaan) as skor_komp_4_d4_k4_keterlibatan_kelembagaan,
avg(skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan) as skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan,
avg(skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar) as skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar")
->first();
return response()->json([
'radarKomponen' => [
round($avgKomponen->skor_komp_1_d4_k3_motivasi_kapasitas_adopsi, 2),
round($avgKomponen->skor_komp_2_d4_k2_ekonomi_rumah_tangga, 2),
round($avgKomponen->skor_komp_3_d2_praktik_budidaya_gap, 2),
round($avgKomponen->skor_komp_4_d4_k4_keterlibatan_kelembagaan, 2),
round($avgKomponen->skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan, 2),
round($avgKomponen->skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar, 2)
]
]);
}
public function map(Request $request): JsonResponse
{
$filters = $this->filters($request);
$segments = $this->segments();
$colors = collect($segments)
->pluck('color')
->map(fn($c) => "var(--bs-{$c})")
->values();
$segmentStyles = collect($segments)->keyBy('name');
$case = $this->cases();
$petaniQuery = $this->petaniQuery($filters);
$desaKelurahan = $petaniQuery->clone()
->selectRaw("
master_desa_kelurahan.id as desa_kelurahan_id,
master_desa_kelurahan.nama as desa_kelurahan,
master_desa_kelurahan.path as path,
master_kecamatan.id as kecamatan_id,
master_kecamatan.nama as kecamatan,
master_kabupaten_kota.id as kabupaten_id,
master_kabupaten_kota.nama as kabupaten,
master_provinsi.id as provinsi_id,
master_provinsi.nama as provinsi
")
->distinct()
->get();
$komoditas = Komoditas::where('is_utama', true)
->when($filters['komoditas_id'], fn($q, $id) => $q->where('id', $id))->get();
$skorQuery = $this->skorPetaniQuery($filters, $komoditas->pluck('id')->toArray());
$mapSegmentasi = $skorQuery->clone()
->selectRaw("petani.desa_kelurahan_id,
$case AS segmen,
COUNT(petani.id) AS total
")
->groupBy('petani.desa_kelurahan_id')
->groupByRaw($case)
->get();
$mapAvgSkorSegmentasi = $skorQuery->clone()
->selectRaw("petani.desa_kelurahan_id,
COUNT(petani.id) AS jumlah_petani,
avg(skor_kesiapan_adopsi) AS skor,
CASE
WHEN AVG(skor_kesiapan_adopsi) >= 4 THEN 'Penggerak'
WHEN AVG(skor_kesiapan_adopsi) >= 3 THEN 'Perintis'
WHEN AVG(skor_kesiapan_adopsi) >= 2 THEN 'Pemerhati'
WHEN AVG(skor_kesiapan_adopsi) >= 1 THEN 'Pemula'
ELSE 'Belum Lengkap'
END AS segmen
")
->groupBy('petani.desa_kelurahan_id')
->get();
$segmenDominan = $mapSegmentasi
->groupBy('desa_kelurahan_id')
->map(function ($items) {
return $items->sortByDesc('total')->first();
});
$mapAvgSkorSegmentasi->each(function ($item) use ($segmenDominan) {
$dominan = $segmenDominan->get($item->desa_kelurahan_id);
$item->segmen_dominan = $dominan?->segmen;
$item->jumlah_dominan = $dominan?->total;
});
$segmentasiByDesa = $mapAvgSkorSegmentasi->keyBy('desa_kelurahan_id');
$desaLookup = $desaKelurahan->keyBy('desa_kelurahan_id');
$mapDesaSegmentasi = $segmentasiByDesa->map(function ($segmentasi, $desaId) use ($desaLookup) {
$desa = $desaLookup->get($desaId);
if (!$desa) {
return null;
}
$desa->segmentasi = $segmentasi;
return $desa;
})->filter()->values();
return response()->json($mapDesaSegmentasi);
}
public function desa(Request $request): JsonResponse
{
$filters = $this->filters($request);
$segments = $this->segments();
$colors = collect($segments)
->pluck('color')
->map(fn($c) => "var(--bs-{$c})")
->values();
$segmentStyles = collect($segments)->keyBy('name');
$case = $this->cases();
$petaniQuery = $this->petaniQuery($filters);
$desaKelurahan = $petaniQuery->clone()
->selectRaw("
master_desa_kelurahan.id as desa_kelurahan_id,
master_desa_kelurahan.nama as desa_kelurahan,
master_desa_kelurahan.path as path,
master_kecamatan.id as kecamatan_id,
master_kecamatan.nama as kecamatan,
master_kabupaten_kota.id as kabupaten_id,
master_kabupaten_kota.nama as kabupaten,
master_provinsi.id as provinsi_id,
master_provinsi.nama as provinsi
")
->distinct()
->get();
$komoditas = Komoditas::where('is_utama', true)
->when($filters['komoditas_id'], fn($q, $id) => $q->where('id', $id))->get();
$skorQuery = $this->skorPetaniQuery($filters, $komoditas->pluck('id')->toArray());
$mapSegmentasi = $skorQuery->clone()
->selectRaw("petani.desa_kelurahan_id,
$case AS segmen,
COUNT(petani.id) AS total
")
->groupBy('petani.desa_kelurahan_id')
->groupByRaw($case)
->get();
$mapAvgSkorSegmentasi = $skorQuery->clone()
->selectRaw("petani.desa_kelurahan_id,
COUNT(petani.id) AS jumlah_petani,
avg(skor_kesiapan_adopsi) AS skor,
CASE
WHEN AVG(skor_kesiapan_adopsi) >= 4 THEN 'Penggerak'
WHEN AVG(skor_kesiapan_adopsi) >= 3 THEN 'Perintis'
WHEN AVG(skor_kesiapan_adopsi) >= 2 THEN 'Pemerhati'
WHEN AVG(skor_kesiapan_adopsi) >= 1 THEN 'Pemula'
ELSE 'Belum Lengkap'
END AS segmen
")
->groupBy('petani.desa_kelurahan_id')
->get();
$segmenDominan = $mapSegmentasi
->groupBy('desa_kelurahan_id')
->map(function ($items) {
return $items->sortByDesc('total')->first();
});
$mapAvgSkorSegmentasi->each(function ($item) use ($segmenDominan) {
$dominan = $segmenDominan->get($item->desa_kelurahan_id);
$item->segmen_dominan = $dominan?->segmen;
$item->jumlah_dominan = $dominan?->total;
});
$segmentasiByDesa = $mapAvgSkorSegmentasi->keyBy('desa_kelurahan_id');
$desaLookup = $desaKelurahan->keyBy('desa_kelurahan_id');
$mapDesaSegmentasi = $segmentasiByDesa->map(function ($segmentasi, $desaId) use ($desaLookup) {
$desa = $desaLookup->get($desaId);
if (!$desa) {
return null;
}
$desa->segmentasi = $segmentasi;
return $desa;
})->filter()->values();
$rows = $mapDesaSegmentasi->map(function ($desa) use ($segmentStyles) {
$style = $segmentStyles[$desa->segmentasi->segmen] ?? ['color' => 'secondary'];
$styleDominan = $segmentStyles[$desa->segmentasi->segmen_dominan] ?? ['color' => 'secondary'];
return [
'desa' => $desa->desa_kelurahan,
'jumlah_petani' => $desa->segmentasi->jumlah_petani,
'segmen' => $desa->segmentasi->segmen,
'skor' => $desa->segmentasi->skor,
'segmen_dominan' => $desa->segmentasi->segmen_dominan,
'jumlah_dominan' => $desa->segmentasi->jumlah_dominan,
'color' => $style['color'],
'color_dominan' => $styleDominan['color'],
];
});
return response()->json($rows);
}
public function data(Request $request): JsonResponse
{
$filters = $this->filters($request);
$segments = $this->segments();
$colors = collect($segments)
->pluck('color')
->map(fn($c) => "var(--bs-{$c})")
->values();
$segmentStyles = collect($segments)->keyBy('name');
$petaniQuery = $this->petaniQuery($filters);
$komoditas = Komoditas::where('is_utama', true)
->when($filters['komoditas_id'], fn($q, $id) => $q->where('id', $id))->get();
$daftarPetani = $petaniQuery->clone()
->select('petani.*')
->whereIn('komoditas_id', $komoditas->pluck('id'))
->get();
$data = $daftarPetani
->filter(function ($item) use ($filters) {
if (!$filters['segmen']) {
return true;
}
$segmen = $item->skor ? $item->segmen() : 'Belum Lengkap';
return $segmen === $filters['segmen'];
})
->map(function ($item) use ($segmentStyles) {
$segmen = $item->skor
? $item->segmen()
: null;
$style = $segmentStyles[$segmen]
?? ['color' => 'secondary'];
return [
'id' => $item->id,
'nama' => $item->nama,
'desa' => $item->desaKelurahan?->nama,
'desa_kelurahan_id' => $item->desa_kelurahan_id,
'komoditas' => $item->komoditas?->nama,
'luas_lahan' => $item->lahans?->sum('luas_lahan') ?? 0,
'skor' => $item->skor
? $item->skor->skor_kesiapan_adopsi
: null,
'segmen' => $segmen,
'color' => $style['color'],
'url' => route('dashboard.profil-petani', $item->id),
];
})
->values();
return response()->json($data);
}
}
@@ -0,0 +1,769 @@
<?php
namespace App\Http\Controllers\Web\Dashboard;
use App\Enums\KeparahanSerangan;
use App\Enums\PenyakitTanaman;
use App\Enums\PraktikBudidaya\PemberianPupuk;
use App\Enums\SeranganHama;
use App\Enums\SosialEkonomi\StatusKepemilikanLahanSosialEkonomi;
use App\Http\Controllers\Controller;
use App\Models\Pertanian\Komoditas;
use App\Models\Pertanian\Lahan;
use App\Models\Pertanian\Petani;
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;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class IndikatorPertanianController extends Controller
{
public function index(Request $request)
{
$kabupatenOptions = $this->kabupatenOptions();
$ngadaOption = collect($kabupatenOptions)->first(
fn ($option) => str_contains(strtolower($option['label']), 'ngada')
);
$initialFilters = $this->selectedFilters($request, $ngadaOption['value'] ?? 'all');
$totalPetani = $this->applyPetaniFilters(Petani::query(), $initialFilters)->count();
$totalLuasLahan = ((float) $this->applyLahanFilters(Lahan::query(), $initialFilters)->sum('luas_lahan')) / 10000;
$rataRataLuasLahan = $totalPetani > 0
? $totalLuasLahan / $totalPetani
: 0;
$totalProduksiKg = $this->totalProduksiKg($initialFilters);
$rataRataProduksiKg = $totalPetani > 0
? $totalProduksiKg / $totalPetani
: 0;
$rataRataProduktivitas = $totalLuasLahan > 0
? $totalProduksiKg / $totalLuasLahan
: 0;
$filterOptions = [
[
'key' => 'kabupaten',
'label' => 'Kabupaten',
'options' => $kabupatenOptions,
'icon' => 'tabler-map-pin',
'readonly' => true,
],
[
'key' => 'kecamatan',
'label' => 'Kecamatan',
'options' => $this->kecamatanOptions(),
],
[
'key' => 'desa',
'label' => 'Desa',
'options' => $this->desaOptions(),
],
[
'key' => 'komoditas',
'label' => 'Komoditas',
'options' => $this->komoditasOptions(),
],
[
'key' => 'segmentasi',
'label' => 'Segmentasi',
'options' => $this->segmentasiOptions(),
],
];
$summaryData = [
[
'value' => number_format($totalPetani, 0, ',', '.'),
'label' => 'Petani Terdata',
'description' => 'Total petani yang masuk sistem',
'icon' => 'tabler-users',
'variant' => 'primary',
],
[
'value' => number_format($totalLuasLahan, 2, ',', '.').' ha',
'label' => 'Total Luas Lahan',
'description' => 'Rata-rata '.number_format($rataRataLuasLahan, 2, ',', '.').' ha/petani',
'icon' => 'tabler-mountain',
'variant' => 'success',
],
[
'value' => number_format($totalProduksiKg, 0, ',', '.').' kg',
'label' => 'Total Produksi (Semua Komoditas)',
'description' => 'Rata-rata '.number_format($rataRataProduksiKg, 0, ',', '.').' kg/petani',
'icon' => 'tabler-wheat',
'variant' => 'warning',
],
[
'value' => number_format($rataRataProduktivitas, 0, ',', '.').' kg/ha',
'label' => 'Rata-rata Produktivitas',
'description' => 'Semua komoditas berdasarkan total produksi dan luas lahan',
'icon' => 'tabler-chart-bar',
'variant' => 'info',
],
];
return view('dashboard.indikator-pertanian', [
'title' => 'Indikator Pertanian',
'initialFilters' => $initialFilters,
'filterOptions' => $filterOptions,
'summaryData' => $summaryData,
'chartData' => [
'petaniPerKomoditas' => $this->petaniPerKomoditasChart($initialFilters),
'luasLahanPerKecamatan' => $this->luasLahanPerKecamatanChart($initialFilters),
'kondisiTanaman' => $this->kondisiTanamanChart($initialFilters),
'statusKepemilikanLahan' => $this->statusKepemilikanLahanChart($initialFilters),
'seranganHama' => $this->seranganHamaChart($initialFilters),
'penyakitTanaman' => $this->penyakitTanamanChart($initialFilters),
'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'),
],
]);
}
private function selectedFilters(Request $request, string $defaultKabupaten): array
{
$filters = [
'kabupaten' => $defaultKabupaten,
'kecamatan' => $this->validFilterValue($request->query('kecamatan'), Kecamatan::class),
'desa' => $this->validFilterValue($request->query('desa'), DesaKelurahan::class),
'komoditas' => $this->validFilterValue($request->query('komoditas'), Komoditas::class),
'segmentasi' => $this->validSegmentasi((string) $request->query('segmentasi', 'all')),
];
if ($filters['desa'] !== 'all') {
$desa = DesaKelurahan::query()->find($filters['desa']);
if (! $desa || ($filters['kecamatan'] !== 'all' && (string) $desa->kecamatan_id !== $filters['kecamatan'])) {
$filters['desa'] = 'all';
}
}
if ($filters['kecamatan'] === 'all') {
$filters['desa'] = 'all';
}
return $filters;
}
private function validFilterValue(mixed $value, string $modelClass): string
{
if (! $value || $value === 'all') {
return 'all';
}
return $modelClass::query()->whereKey($value)->exists()
? (string) $value
: 'all';
}
private function validSegmentasi(string $value): string
{
return in_array($value, [
'Penggerak',
'Perintis',
'Pemerhati',
'Pemula',
'Belum tersegmentasi',
'all',
], true) ? $value : 'all';
}
private function kabupatenOptions(): array
{
return $this->withAllOption(
'Semua Kabupaten',
KabupatenKota::query()
->orderBy('nama')
->get(['id', 'kode', 'nama'])
->map(fn (KabupatenKota $kabupaten) => [
'value' => (string) $kabupaten->id,
'label' => $this->kabupatenLabel($kabupaten),
])
->values()
->all()
);
}
private function kecamatanOptions(): array
{
return $this->withAllOption(
'Semua Kecamatan',
Kecamatan::query()
->orderBy('nama')
->get(['id', 'nama'])
->map(fn (Kecamatan $kecamatan) => [
'value' => (string) $kecamatan->id,
'label' => $kecamatan->nama,
])
->values()
->all()
);
}
private function desaOptions(): array
{
return $this->withAllOption(
'Semua Desa',
DesaKelurahan::query()
->orderBy('nama')
->get(['id', 'nama', 'kecamatan_id'])
->map(fn (DesaKelurahan $desa) => [
'value' => (string) $desa->id,
'label' => $desa->nama,
'parent' => (string) $desa->kecamatan_id,
])
->values()
->all()
);
}
private function komoditasOptions(): array
{
return $this->withAllOption(
'Semua Komoditas',
Komoditas::query()
->orderBy('nama')
->get(['id', 'nama'])
->map(fn (Komoditas $komoditas) => [
'value' => (string) $komoditas->id,
'label' => $komoditas->nama,
])
->values()
->all()
);
}
private function segmentasiOptions(): array
{
// Aggregate bucket counts in SQL instead of pulling every skor_kesiapan_adopsi
// value into PHP just to map/filter/unique it.
$row = SkorPetani::query()->selectRaw("
COUNT(*) FILTER (WHERE skor_kesiapan_adopsi >= 4) as penggerak,
COUNT(*) FILTER (WHERE skor_kesiapan_adopsi >= 3 AND skor_kesiapan_adopsi < 4) as perintis,
COUNT(*) FILTER (WHERE skor_kesiapan_adopsi >= 2 AND skor_kesiapan_adopsi < 3) as pemerhati,
COUNT(*) FILTER (WHERE skor_kesiapan_adopsi >= 1 AND skor_kesiapan_adopsi < 2) as pemula,
COUNT(*) FILTER (WHERE skor_kesiapan_adopsi IS NOT NULL AND skor_kesiapan_adopsi < 1) as belum_tersegmentasi
")->first();
$order = [
'Penggerak' => $row->penggerak,
'Perintis' => $row->perintis,
'Pemerhati' => $row->pemerhati,
'Pemula' => $row->pemula,
'Belum tersegmentasi' => $row->belum_tersegmentasi,
];
$segments = collect($order)
->filter(fn ($count) => $count > 0)
->keys()
->map(fn ($segment) => [
'value' => $segment,
'label' => $segment,
])
->values()
->all();
return $this->withAllOption('Semua Segmentasi', $segments);
}
private function totalProduksiKg(array $filters): float
{
$expr = $this->kgCaseExpr('jumlah_panen', 'satuan');
return (float) ($this->applyProduksiFilters(Produksi::query(), $filters)
->whereNotNull('jumlah_panen')
->selectRaw("SUM({$expr}) as total")
->value('total') ?? 0);
}
private function petaniPerKomoditasChart(array $filters): array
{
$rows = $this->applyPetaniFilters(Petani::query(), $filters)
->leftJoin('master_komoditas as k', 'k.id', '=', 'petani.komoditas_id')
->selectRaw("COALESCE(k.nama, 'Belum ditentukan') as label")
->selectRaw('COUNT(petani.id) as total')
->groupBy('k.id', 'k.nama')
->orderByDesc('total')
->get();
return [
'labels' => $rows->pluck('label')->values()->all(),
'series' => $rows->pluck('total')->map(fn ($value) => (int) $value)->values()->all(),
];
}
private function luasLahanPerKecamatanChart(array $filters): array
{
$rows = $this->applyLahanFilters(Lahan::query(), $filters)
->leftJoin('master_desa_kelurahan as d', 'd.id', '=', 'map_lahan.desa_kelurahan_id')
->leftJoin('master_kecamatan as k', 'k.id', '=', 'd.kecamatan_id')
->selectRaw("COALESCE(k.nama, 'Belum ditentukan') as label")
->selectRaw('SUM(map_lahan.luas_lahan) / 10000 as total')
->groupBy('k.id', 'k.nama')
->havingRaw('SUM(map_lahan.luas_lahan) > 0')
->orderByDesc('total')
->limit(8)
->get()
->filter(fn ($row) => round((float) $row->total, 2) > 0)
->values();
return [
'labels' => $rows->pluck('label')->values()->all(),
'series' => $rows->pluck('total')->map(fn ($value) => round((float) $value, 2))->values()->all(),
];
}
private function kondisiTanamanChart(array $filters): array
{
$rows = $this->applyTanamanTableFilters(DB::table('map_tanaman'), $filters)
->whereNull('map_tanaman.deleted_at')
->whereNotNull('map_tanaman.kondisi_tanaman')
->selectRaw('map_tanaman.kondisi_tanaman as label')
->selectRaw('COUNT(map_tanaman.id) as total')
->groupBy('map_tanaman.kondisi_tanaman')
->orderByDesc('total')
->get();
if ($rows->isEmpty()) {
$rows = $this->applyLahanFilters(Lahan::query(), $filters)
->whereNull('deleted_at')
->whereNotNull('kondisi_tanaman')
->selectRaw('kondisi_tanaman as label')
->selectRaw('COUNT(map_lahan.id) as total')
->groupBy('kondisi_tanaman')
->orderByDesc('total')
->get();
}
return [
'labels' => $rows->pluck('label')->map(fn ($label) => $this->shortEnumLabel((string) $label))->values()->all(),
'series' => $rows->pluck('total')->map(fn ($value) => (int) $value)->values()->all(),
];
}
private function seranganHamaChart(array $filters): array
{
return $this->tanamanAttributeChart(
$filters,
'serangan_hama',
fn ($label) => $this->enumLabel(SeranganHama::class, (string) $label)
);
}
private function penyakitTanamanChart(array $filters): array
{
return $this->tanamanAttributeChart(
$filters,
'penyakit_tanaman',
fn ($label) => $this->enumLabel(PenyakitTanaman::class, (string) $label)
);
}
private function keparahanSeranganChart(array $filters): array
{
return $this->tanamanAttributeChart(
$filters,
'keparahan_serangan',
fn ($label) => $this->keparahanSeranganLabel((string) $label)
);
}
private function statusKepemilikanLahanChart(array $filters): array
{
$rows = $this->applyLahanFilters(Lahan::query(), $filters)
->whereNotNull('status_kepemilikan')
->selectRaw('status_kepemilikan as label')
->selectRaw('COUNT(map_lahan.id) as total')
->groupBy('status_kepemilikan')
->orderByDesc('total')
->get();
return $this->chartFromRows($rows, fn ($label) => $this->shortEnumLabel((string) $label));
}
private function statusHakKelolaLahanChart(array $filters): array
{
$rows = $this->applySosialEkonomiFilters(SosialEkonomi::query(), $filters)
->whereNotNull('status_kepemilikan_lahan')
->selectRaw('status_kepemilikan_lahan as label')
->selectRaw('COUNT(sosial_ekonomi.id) as total')
->groupBy('status_kepemilikan_lahan')
->orderByDesc('total')
->get();
return $this->chartFromRows(
$rows,
fn ($label) => $this->enumLabel(StatusKepemilikanLahanSosialEkonomi::class, (string) $label)
);
}
private function praktikPemupukanChart(array $filters): array
{
$rows = $this->applyPraktikBudidayaFilters(PraktikBudidaya::query(), $filters)
->whereNotNull('pemberian_pupuk')
->selectRaw('pemberian_pupuk as label')
->selectRaw('COUNT(praktik_budidaya.id) as total')
->groupBy('pemberian_pupuk')
->orderBy('pemberian_pupuk')
->get();
return $this->chartFromRows(
$rows,
fn ($label) => $this->pemberianPupukLabel((int) $label)
);
}
private function produksiPerKomoditasChart(array $filters): array
{
$expr = $this->kgCaseExpr('produksi.jumlah_panen', 'produksi.satuan');
$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("SUM({$expr}) as total")
->groupBy('k.id', 'k.nama')
->get()
->filter(fn ($row) => round((float) $row->total, 2) > 0)
->sortByDesc('total')
->values();
return [
'labels' => $rows->pluck('label')->values()->all(),
'series' => $rows->pluck('total')->map(fn ($value) => round((float) $value, 2))->values()->all(),
];
}
private function produktivitasPerKomoditasChart(array $filters): array
{
$expr = $this->kgCaseExpr('produksi.jumlah_panen', 'produksi.satuan');
$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('AVG(produksi.produktivitas) FILTER (WHERE produksi.produktivitas > 0) as avg_prod')
->selectRaw("SUM({$expr}) as total_kg")
->selectRaw('SUM(produksi.luas_panen) as total_luas')
->groupBy('k.id', 'k.nama')
->get()
->map(function ($row) {
$avgProd = (float) $row->avg_prod;
$totalLuas = (float) $row->total_luas;
$totalKg = (float) $row->total_kg;
$value = $avgProd > 0
? $avgProd
: ($totalLuas > 0 ? $totalKg / $totalLuas : 0);
return (object) ['label' => $row->label, 'total' => round($value, 2)];
})
->filter(fn ($row) => $row->total > 0)
->sortByDesc('total')
->values();
return [
'labels' => $rows->pluck('label')->values()->all(),
'series' => $rows->pluck('total')->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 [
'labels' => $rows
->pluck('label')
->map(fn ($label) => $labelResolver($label))
->values()
->all(),
'series' => $rows
->pluck('total')
->map(fn ($value) => (int) $value)
->values()
->all(),
];
}
private function tanamanAttributeChart(array $filters, string $field, callable $labelResolver): array
{
$qualifiedField = 'map_tanaman.'.$field;
$rows = $this->applyTanamanTableFilters(DB::table('map_tanaman'), $filters)
->whereNull('map_tanaman.deleted_at')
->whereNotNull($qualifiedField)
->selectRaw($qualifiedField.' as label')
->selectRaw('COUNT(map_tanaman.id) as total')
->groupBy($qualifiedField)
->orderByDesc('total')
->get();
if ($rows->isEmpty()) {
$rows = $this->applyLahanFilters(Lahan::query(), $filters)
->whereNotNull($field)
->selectRaw($field.' as label')
->selectRaw('COUNT(map_lahan.id) as total')
->groupBy($field)
->orderByDesc('total')
->get();
}
return $this->chartFromRows($rows, $labelResolver);
}
private function applyPetaniFilters($query, array $filters)
{
return $query
->when($filters['kecamatan'] !== 'all', function ($query) use ($filters) {
$query->whereHas('desaKelurahan', fn ($desa) => $desa->where('kecamatan_id', $filters['kecamatan']));
})
->when($filters['desa'] !== 'all', fn ($query) => $query->where('desa_kelurahan_id', $filters['desa']))
->when($filters['komoditas'] !== 'all', fn ($query) => $query->where('komoditas_id', $filters['komoditas']))
->when($filters['segmentasi'] !== 'all', function ($query) use ($filters) {
$query->whereHas('skor', function ($skor) use ($filters) {
$this->applySegmentasiRange($skor, $filters['segmentasi']);
});
});
}
private function applyLahanFilters($query, array $filters)
{
return $query
->when($filters['kecamatan'] !== 'all', function ($query) use ($filters) {
$query->whereHas('desaKelurahan', fn ($desa) => $desa->where('kecamatan_id', $filters['kecamatan']));
})
->when($filters['desa'] !== 'all', fn ($query) => $query->where('desa_kelurahan_id', $filters['desa']))
->when($filters['komoditas'] !== 'all', fn ($query) => $query->where('komoditas_id', $filters['komoditas']))
->when($filters['segmentasi'] !== 'all', function ($query) use ($filters) {
$query->whereIn('petani_id', $this->segmentasiPetaniIdsQuery($filters['segmentasi']));
});
}
private function applyProduksiFilters($query, array $filters)
{
return $query
->when($filters['kecamatan'] !== 'all' || $filters['desa'] !== 'all' || $filters['segmentasi'] !== 'all', function ($query) use ($filters) {
$query->whereHas('lahan', function ($lahan) use ($filters) {
$this->applyLahanFilters($lahan, $filters);
});
})
->when($filters['komoditas'] !== 'all', fn ($query) => $query->where('komoditas_id', $filters['komoditas']));
}
private function applySosialEkonomiFilters($query, array $filters)
{
return $query->whereHas('petani', function ($petani) use ($filters) {
$this->applyPetaniFilters($petani, $filters);
});
}
private function applyPraktikBudidayaFilters($query, array $filters)
{
return $query->whereHas('petani', function ($petani) use ($filters) {
$this->applyPetaniFilters($petani, $filters);
});
}
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
->leftJoin('map_lahan as l', 'l.id', '=', 'map_tanaman.lahan_id')
->when($filters['kecamatan'] !== 'all', function ($query) use ($filters) {
$query
->leftJoin('master_desa_kelurahan as d', 'd.id', '=', 'l.desa_kelurahan_id')
->where('d.kecamatan_id', $filters['kecamatan']);
})
->when($filters['desa'] !== 'all', fn ($query) => $query->where('l.desa_kelurahan_id', $filters['desa']))
->when($filters['komoditas'] !== 'all', fn ($query) => $query->where('map_tanaman.komoditas_id', $filters['komoditas']))
->when($filters['segmentasi'] !== 'all', function ($query) use ($filters) {
$query->where(function ($query) use ($filters) {
$query
->whereIn('map_tanaman.petani_id', $this->segmentasiPetaniIdsQuery($filters['segmentasi']))
->orWhereIn('l.petani_id', $this->segmentasiPetaniIdsQuery($filters['segmentasi']));
});
});
}
private function segmentasiPetaniIdsQuery(string $segmentasi)
{
return Petani::query()
->select('id')
->whereHas('skor', function ($skor) use ($segmentasi) {
$this->applySegmentasiRange($skor, $segmentasi);
});
}
private function applySegmentasiRange($query, string $segmentasi)
{
return match ($segmentasi) {
'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),
default => $query->where(function ($query) {
$query->whereNull('skor_kesiapan_adopsi')->orWhere('skor_kesiapan_adopsi', '<', 1);
}),
};
}
/**
* SQL CASE expression converting a jumlah/satuan pair to kilograms,
* so aggregation happens in the database instead of pulling every
* row of `produksi` into PHP to sum with toKilograms().
*/
private function kgCaseExpr(string $jumlahColumn, string $satuanColumn): string
{
return "CASE LOWER({$satuanColumn})
WHEN 'ton' THEN {$jumlahColumn} * 1000
WHEN 'kuintal' THEN {$jumlahColumn} * 100
WHEN 'kwintal' THEN {$jumlahColumn} * 100
ELSE {$jumlahColumn}
END";
}
private function shortEnumLabel(string $value): string
{
return str($value)
->replace('_', ' ')
->headline()
->toString();
}
private function enumLabel(string $enumClass, int|string $value): string
{
$case = $enumClass::tryFrom($value);
if (! $case) {
return $this->shortEnumLabel((string) $value);
}
return method_exists($case, 'label')
? $case->label()
: $this->shortEnumLabel((string) $case->value);
}
private function keparahanSeranganLabel(string $value): string
{
return match (KeparahanSerangan::tryFrom($value)) {
KeparahanSerangan::RINGAN => 'Ringan',
KeparahanSerangan::SEDANG => 'Sedang',
KeparahanSerangan::BERAT => 'Parah',
default => $this->shortEnumLabel($value),
};
}
private function pemberianPupukLabel(int $value): string
{
return match (PemberianPupuk::tryFrom($value)) {
PemberianPupuk::TIDAK_PERNAH => 'Tidak pernah',
PemberianPupuk::JENIS_DOSIS_WAKTU_TIDAK_MENENTU => 'Tidak menentu',
PemberianPupuk::JENIS_SESUAI_DOSIS_TIDAK_MENENTU => 'Jenis sesuai',
PemberianPupuk::JENIS_DOSIS_SESUAI_WAKTU_CUKUP_TEPAT => 'Cukup tepat',
PemberianPupuk::JENIS_DOSIS_SESUAI_WAKTU_TEPAT => 'Tepat & rutin',
default => $this->shortEnumLabel((string) $value),
};
}
private function toKilograms(float $value, string $unit): float
{
return match (strtolower($unit)) {
'ton' => $value * 1000,
'kuintal', 'kwintal' => $value * 100,
default => $value,
};
}
private function withAllOption(string $label, array $options): array
{
return array_merge([
[
'value' => 'all',
'label' => $label,
],
], $options);
}
private function kabupatenLabel(KabupatenKota $kabupaten): string
{
return preg_replace('/^(kabupaten|kota)\s+/i', '', $kabupaten->nama);
}
private function segmentLabel(float $score): string
{
return match (true) {
$score >= 4.0 => 'Penggerak',
$score >= 3.0 => 'Perintis',
$score >= 2.0 => 'Pemerhati',
$score >= 1.0 => 'Pemula',
default => 'Belum tersegmentasi',
};
}
}
@@ -0,0 +1,798 @@
<?php
namespace App\Http\Controllers\Web\Dashboard;
use App\Enums\KeparahanSerangan;
use App\Enums\PenyakitTanaman;
use App\Enums\PraktikBudidaya\PemberianPupuk;
use App\Enums\SeranganHama;
use App\Enums\SosialEkonomi\StatusKepemilikanLahanSosialEkonomi;
use App\Http\Controllers\Controller;
use App\Models\Pertanian\Komoditas;
use App\Models\Pertanian\Lahan;
use App\Models\Pertanian\Petani;
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;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class IndikatorPertanianController extends Controller
{
public function index(Request $request)
{
$defaultKabupatenId = $this->defaultKabupatenId();
$initialFilters = $this->selectedFilters($request, $defaultKabupatenId);
$payload = $this->dashboardPayload($initialFilters);
$filterOptions = [
[
'key' => 'kabupaten',
'label' => 'Kabupaten',
'options' => $this->kabupatenOptions(),
'icon' => 'tabler-map-pin',
'readonly' => true,
],
[
'key' => 'kecamatan',
'label' => 'Kecamatan',
'options' => $this->withAllOption('Semua Kecamatan', []),
],
[
'key' => 'desa',
'label' => 'Desa',
'options' => $this->withAllOption('Semua Desa', []),
],
[
'key' => 'komoditas',
'label' => 'Komoditas',
'options' => $this->withAllOption('Semua Komoditas', []),
],
[
'key' => 'segmentasi',
'label' => 'Segmentasi',
'options' => $this->withAllOption('Semua Segmentasi', []),
],
];
return view('dashboard.indikator-pertanian', [
'title' => 'Indikator Pertanian',
'initialFilters' => $initialFilters,
'filterOptions' => $filterOptions,
] + $payload);
}
public function data(Request $request)
{
if ($request->query('mode') === 'filter-options') {
return response()->json([
'komoditas' => $this->komoditasOptions(),
'segmentasi' => $this->segmentasiOptions(),
]);
}
$filters = $this->selectedFilters($request, $this->defaultKabupatenId());
return response()->json([
'filters' => $filters,
] + $this->dashboardPayload($filters));
}
private function defaultKabupatenId(): string
{
$ngadaOption = collect($this->kabupatenOptions())->first(
fn ($option) => str_contains(strtolower($option['label']), 'ngada')
);
return $ngadaOption['value'] ?? 'all';
}
private function dashboardPayload(array $filters): array
{
return [
'summaryData' => $this->summaryData($filters),
'chartData' => $this->chartData($filters),
];
}
private function summaryData(array $filters): array
{
$totalPetani = $this->applyPetaniFilters(Petani::query(), $filters)->count();
// $totalLuasLahan = ((float) $this->applyLahanFilters(Lahan::query(), $filters)->sum('luas_lahan')) / 10000;
$totalLuasLahan = $this->applyLahanFilters(Lahan::has('petani'), $filters)->sum('luas_lahan');
$rataRataLuasLahan = $totalPetani > 0
? $totalLuasLahan / $totalPetani
: 0;
$totalProduksiKg = $this->totalProduksiKg($filters);
$rataRataProduksiKg = $totalPetani > 0
? $totalProduksiKg / $totalPetani
: 0;
$rataRataProduktivitas = $totalLuasLahan > 0
? $totalProduksiKg / $totalLuasLahan
: 0;
return [
[
'value' => number_format($totalPetani, 0, ',', '.'),
'label' => 'Petani Terdata',
'description' => 'Total petani yang masuk sistem',
'icon' => 'tabler-users',
'variant' => 'primary',
],
[
'value' => number_format($totalLuasLahan, 2, ',', '.').' ha',
'label' => 'Total Luas Lahan',
'description' => 'Rata-rata '.number_format($rataRataLuasLahan, 2, ',', '.').' ha/petani',
'icon' => 'tabler-mountain',
'variant' => 'success',
],
[
'value' => number_format($totalProduksiKg, 0, ',', '.').' kg',
'label' => 'Total Produksi (Semua Komoditas)',
'description' => 'Rata-rata '.number_format($rataRataProduksiKg, 0, ',', '.').' kg/petani',
'icon' => 'tabler-wheat',
'variant' => 'warning',
],
[
'value' => number_format($rataRataProduktivitas, 0, ',', '.').' kg/ha',
'label' => 'Rata-rata Produktivitas',
'description' => 'Semua komoditas berdasarkan total produksi dan luas lahan',
'icon' => 'tabler-chart-bar',
'variant' => 'info',
],
];
}
private function chartData(array $filters): array
{
return [
'petaniPerKomoditas' => $this->petaniPerKomoditasChart($filters),
'luasLahanPerKecamatan' => $this->luasLahanPerKecamatanChart($filters),
'kondisiTanaman' => $this->kondisiTanamanChart($filters),
'statusKepemilikanLahan' => $this->statusKepemilikanLahanChart($filters),
'seranganHama' => $this->seranganHamaChart($filters),
'penyakitTanaman' => $this->penyakitTanamanChart($filters),
'keparahanSerangan' => $this->keparahanSeranganChart($filters),
'statusHakKelolaLahan' => $this->statusHakKelolaLahanChart($filters),
'praktikPemupukan' => $this->praktikPemupukanChart($filters),
'produksiPerKomoditas' => $this->produksiPerKomoditasChart($filters),
'produktivitasPerKomoditas' => $this->produktivitasPerKomoditasChart($filters),
'luasPanenPerKomoditas' => $this->luasPanenPerKomoditasChart($filters),
'statusPanen' => $this->statusPanenChart($filters),
'surveyProduktivitasHa' => $this->surveyProduktivitasByUnitChart($filters, 'ha_tahun'),
'surveyProduktivitasPohon' => $this->surveyProduktivitasByUnitChart($filters, 'pohon_tahun'),
];
}
private function selectedFilters(Request $request, string $defaultKabupaten): array
{
$filters = [
'kabupaten' => $defaultKabupaten,
'kecamatan' => $this->validFilterValue($request->query('kecamatan'), Kecamatan::class),
'desa' => $this->validFilterValue($request->query('desa'), DesaKelurahan::class),
'komoditas' => $this->validFilterValue($request->query('komoditas'), Komoditas::class),
'segmentasi' => $this->validSegmentasi((string) $request->query('segmentasi', 'all')),
];
if ($filters['desa'] !== 'all') {
$desa = DesaKelurahan::query()->find($filters['desa']);
if (! $desa || ($filters['kecamatan'] !== 'all' && (string) $desa->kecamatan_id !== $filters['kecamatan'])) {
$filters['desa'] = 'all';
}
}
if ($filters['kecamatan'] === 'all') {
$filters['desa'] = 'all';
}
return $filters;
}
private function validFilterValue(mixed $value, string $modelClass): string
{
if (! $value || $value === 'all') {
return 'all';
}
return $modelClass::query()->whereKey($value)->exists()
? (string) $value
: 'all';
}
private function validSegmentasi(string $value): string
{
return in_array($value, [
'Penggerak',
'Perintis',
'Pemerhati',
'Pemula',
'Belum tersegmentasi',
'all',
], true) ? $value : 'all';
}
private function kabupatenOptions(): array
{
return $this->withAllOption(
'Semua Kabupaten',
KabupatenKota::query()
->orderBy('nama')
->get(['id', 'kode', 'nama'])
->map(fn (KabupatenKota $kabupaten) => [
'value' => (string) $kabupaten->id,
'label' => $this->kabupatenLabel($kabupaten),
])
->values()
->all()
);
}
private function kecamatanOptions(): array
{
return $this->withAllOption(
'Semua Kecamatan',
Kecamatan::query()
->orderBy('nama')
->get(['id', 'nama'])
->map(fn (Kecamatan $kecamatan) => [
'value' => (string) $kecamatan->id,
'label' => $kecamatan->nama,
])
->values()
->all()
);
}
private function desaOptions(): array
{
return $this->withAllOption(
'Semua Desa',
DesaKelurahan::query()
->orderBy('nama')
->get(['id', 'nama', 'kecamatan_id'])
->map(fn (DesaKelurahan $desa) => [
'value' => (string) $desa->id,
'label' => $desa->nama,
'parent' => (string) $desa->kecamatan_id,
])
->values()
->all()
);
}
private function komoditasOptions(): array
{
return $this->withAllOption(
'Semua Komoditas',
Komoditas::query()
->orderBy('nama')
->get(['id', 'nama'])
->map(fn (Komoditas $komoditas) => [
'value' => (string) $komoditas->id,
'label' => $komoditas->nama,
])
->values()
->all()
);
}
private function segmentasiOptions(): array
{
$segments = SkorPetani::query()
->whereNotNull('skor_kesiapan_adopsi')
->pluck('skor_kesiapan_adopsi')
->map(fn ($score) => $this->segmentLabel((float) $score))
->filter()
->unique()
->sortBy(fn ($segment) => array_search($segment, [
'Penggerak',
'Perintis',
'Pemerhati',
'Pemula',
'Belum tersegmentasi',
], true))
->map(fn ($segment) => [
'value' => $segment,
'label' => $segment,
])
->values()
->all();
return $this->withAllOption('Semua Segmentasi', $segments);
}
private function totalProduksiKg(array $filters): float
{
return $this->applyProduksiFilters(Produksi::query(), $filters)
->whereNotNull('jumlah_panen')
->get(['jumlah_panen', 'satuan'])
->sum(fn (Produksi $produksi) => $this->toKilograms(
(float) $produksi->jumlah_panen,
(string) $produksi->satuan
));
}
private function petaniPerKomoditasChart(array $filters): array
{
$rows = $this->applyPetaniFilters(Petani::query(), $filters)
->leftJoin('master_komoditas as k', 'k.id', '=', 'petani.komoditas_id')
->selectRaw("COALESCE(k.nama, 'Belum ditentukan') as label")
->selectRaw('COUNT(petani.id) as total')
->groupBy('k.id', 'k.nama')
->orderByDesc('total')
->get();
return [
'labels' => $rows->pluck('label')->values()->all(),
'series' => $rows->pluck('total')->map(fn ($value) => (int) $value)->values()->all(),
];
}
private function luasLahanPerKecamatanChart(array $filters): array
{
$rows = $this->applyLahanFilters(Lahan::query(), $filters)
->leftJoin('master_desa_kelurahan as d', 'd.id', '=', 'map_lahan.desa_kelurahan_id')
->leftJoin('master_kecamatan as k', 'k.id', '=', 'd.kecamatan_id')
->selectRaw("COALESCE(k.nama, 'Belum ditentukan') as label")
->selectRaw('SUM(map_lahan.luas_lahan) / 10000 as total')
->groupBy('k.id', 'k.nama')
->havingRaw('SUM(map_lahan.luas_lahan) > 0')
->orderByDesc('total')
->limit(8)
->get()
->filter(fn ($row) => round((float) $row->total, 2) > 0)
->values();
return [
'labels' => $rows->pluck('label')->values()->all(),
'series' => $rows->pluck('total')->map(fn ($value) => round((float) $value, 2))->values()->all(),
];
}
private function kondisiTanamanChart(array $filters): array
{
$rows = $this->applyTanamanTableFilters(DB::table('map_tanaman'), $filters)
->whereNull('map_tanaman.deleted_at')
->whereNotNull('map_tanaman.kondisi_tanaman')
->selectRaw('map_tanaman.kondisi_tanaman as label')
->selectRaw('COUNT(map_tanaman.id) as total')
->groupBy('map_tanaman.kondisi_tanaman')
->orderByDesc('total')
->get();
if ($rows->isEmpty()) {
$rows = $this->applyLahanFilters(Lahan::query(), $filters)
->whereNull('deleted_at')
->whereNotNull('kondisi_tanaman')
->selectRaw('kondisi_tanaman as label')
->selectRaw('COUNT(map_lahan.id) as total')
->groupBy('kondisi_tanaman')
->orderByDesc('total')
->get();
}
return [
'labels' => $rows->pluck('label')->map(fn ($label) => $this->shortEnumLabel((string) $label))->values()->all(),
'series' => $rows->pluck('total')->map(fn ($value) => (int) $value)->values()->all(),
];
}
private function seranganHamaChart(array $filters): array
{
return $this->tanamanAttributeChart(
$filters,
'serangan_hama',
fn ($label) => $this->enumLabel(SeranganHama::class, (string) $label)
);
}
private function penyakitTanamanChart(array $filters): array
{
return $this->tanamanAttributeChart(
$filters,
'penyakit_tanaman',
fn ($label) => $this->enumLabel(PenyakitTanaman::class, (string) $label)
);
}
private function keparahanSeranganChart(array $filters): array
{
return $this->tanamanAttributeChart(
$filters,
'keparahan_serangan',
fn ($label) => $this->keparahanSeranganLabel((string) $label)
);
}
private function statusKepemilikanLahanChart(array $filters): array
{
$rows = $this->applyLahanFilters(Lahan::query(), $filters)
->whereNotNull('status_kepemilikan')
->selectRaw('status_kepemilikan as label')
->selectRaw('COUNT(map_lahan.id) as total')
->groupBy('status_kepemilikan')
->orderByDesc('total')
->get();
return $this->chartFromRows($rows, fn ($label) => $this->shortEnumLabel((string) $label));
}
private function statusHakKelolaLahanChart(array $filters): array
{
$rows = $this->applySosialEkonomiFilters(SosialEkonomi::query(), $filters)
->whereNotNull('status_kepemilikan_lahan')
->selectRaw('status_kepemilikan_lahan as label')
->selectRaw('COUNT(sosial_ekonomi.id) as total')
->groupBy('status_kepemilikan_lahan')
->orderByDesc('total')
->get();
return $this->chartFromRows(
$rows,
fn ($label) => $this->enumLabel(StatusKepemilikanLahanSosialEkonomi::class, (string) $label)
);
}
private function praktikPemupukanChart(array $filters): array
{
$rows = $this->applyPraktikBudidayaFilters(PraktikBudidaya::query(), $filters)
->whereNotNull('pemberian_pupuk')
->selectRaw('pemberian_pupuk as label')
->selectRaw('COUNT(praktik_budidaya.id) as total')
->groupBy('pemberian_pupuk')
->orderBy('pemberian_pupuk')
->get();
return $this->chartFromRows(
$rows,
fn ($label) => $this->pemberianPupukLabel((int) $label)
);
}
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 [
'labels' => $rows
->pluck('label')
->map(fn ($label) => $labelResolver($label))
->values()
->all(),
'series' => $rows
->pluck('total')
->map(fn ($value) => (int) $value)
->values()
->all(),
];
}
private function tanamanAttributeChart(array $filters, string $field, callable $labelResolver): array
{
$qualifiedField = 'map_tanaman.'.$field;
$rows = $this->applyTanamanTableFilters(DB::table('map_tanaman'), $filters)
->whereNull('map_tanaman.deleted_at')
->whereNotNull($qualifiedField)
->selectRaw($qualifiedField.' as label')
->selectRaw('COUNT(map_tanaman.id) as total')
->groupBy($qualifiedField)
->orderByDesc('total')
->get();
if ($rows->isEmpty()) {
$rows = $this->applyLahanFilters(Lahan::query(), $filters)
->whereNotNull($field)
->selectRaw($field.' as label')
->selectRaw('COUNT(map_lahan.id) as total')
->groupBy($field)
->orderByDesc('total')
->get();
}
return $this->chartFromRows($rows, $labelResolver);
}
private function applyPetaniFilters($query, array $filters)
{
return $query
->when($filters['kecamatan'] !== 'all', function ($query) use ($filters) {
$query->whereHas('desaKelurahan', fn ($desa) => $desa->where('kecamatan_id', $filters['kecamatan']));
})
->when($filters['desa'] !== 'all', fn ($query) => $query->where('desa_kelurahan_id', $filters['desa']))
->when($filters['komoditas'] !== 'all', fn ($query) => $query->where('komoditas_id', $filters['komoditas']))
->when($filters['segmentasi'] !== 'all', function ($query) use ($filters) {
$query->whereHas('skor', function ($skor) use ($filters) {
$this->applySegmentasiRange($skor, $filters['segmentasi']);
});
});
}
private function applyLahanFilters($query, array $filters)
{
return $query
->when($filters['kecamatan'] !== 'all', function ($query) use ($filters) {
$query->whereHas('desaKelurahan', fn ($desa) => $desa->where('kecamatan_id', $filters['kecamatan']));
})
->when($filters['desa'] !== 'all', fn ($query) => $query->where('desa_kelurahan_id', $filters['desa']))
->when($filters['komoditas'] !== 'all', fn ($query) => $query->where('komoditas_id', $filters['komoditas']))
->when($filters['segmentasi'] !== 'all', function ($query) use ($filters) {
$query->whereIn('petani_id', $this->segmentasiPetaniIdsQuery($filters['segmentasi']));
});
}
private function applyProduksiFilters($query, array $filters)
{
return $query
->when($filters['kecamatan'] !== 'all' || $filters['desa'] !== 'all' || $filters['segmentasi'] !== 'all', function ($query) use ($filters) {
$query->whereHas('lahan', function ($lahan) use ($filters) {
$this->applyLahanFilters($lahan, $filters);
});
})
->when($filters['komoditas'] !== 'all', fn ($query) => $query->where('komoditas_id', $filters['komoditas']));
}
private function applySosialEkonomiFilters($query, array $filters)
{
return $query->whereHas('petani', function ($petani) use ($filters) {
$this->applyPetaniFilters($petani, $filters);
});
}
private function applyPraktikBudidayaFilters($query, array $filters)
{
return $query->whereHas('petani', function ($petani) use ($filters) {
$this->applyPetaniFilters($petani, $filters);
});
}
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
->leftJoin('map_lahan as l', 'l.id', '=', 'map_tanaman.lahan_id')
->when($filters['kecamatan'] !== 'all', function ($query) use ($filters) {
$query
->leftJoin('master_desa_kelurahan as d', 'd.id', '=', 'l.desa_kelurahan_id')
->where('d.kecamatan_id', $filters['kecamatan']);
})
->when($filters['desa'] !== 'all', fn ($query) => $query->where('l.desa_kelurahan_id', $filters['desa']))
->when($filters['komoditas'] !== 'all', fn ($query) => $query->where('map_tanaman.komoditas_id', $filters['komoditas']))
->when($filters['segmentasi'] !== 'all', function ($query) use ($filters) {
$query->where(function ($query) use ($filters) {
$query
->whereIn('map_tanaman.petani_id', $this->segmentasiPetaniIdsQuery($filters['segmentasi']))
->orWhereIn('l.petani_id', $this->segmentasiPetaniIdsQuery($filters['segmentasi']));
});
});
}
private function segmentasiPetaniIdsQuery(string $segmentasi)
{
return Petani::query()
->select('id')
->whereHas('skor', function ($skor) use ($segmentasi) {
$this->applySegmentasiRange($skor, $segmentasi);
});
}
private function applySegmentasiRange($query, string $segmentasi)
{
return match ($segmentasi) {
'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),
default => $query->where(function ($query) {
$query->whereNull('skor_kesiapan_adopsi')->orWhere('skor_kesiapan_adopsi', '<', 1);
}),
};
}
private function shortEnumLabel(string $value): string
{
return str($value)
->replace('_', ' ')
->headline()
->toString();
}
private function enumLabel(string $enumClass, int|string $value): string
{
$case = $enumClass::tryFrom($value);
if (! $case) {
return $this->shortEnumLabel((string) $value);
}
return method_exists($case, 'label')
? $case->label()
: $this->shortEnumLabel((string) $case->value);
}
private function keparahanSeranganLabel(string $value): string
{
return match (KeparahanSerangan::tryFrom($value)) {
KeparahanSerangan::RINGAN => 'Ringan',
KeparahanSerangan::SEDANG => 'Sedang',
KeparahanSerangan::BERAT => 'Parah',
default => $this->shortEnumLabel($value),
};
}
private function pemberianPupukLabel(int $value): string
{
return match (PemberianPupuk::tryFrom($value)) {
PemberianPupuk::TIDAK_PERNAH => 'Tidak pernah',
PemberianPupuk::JENIS_DOSIS_WAKTU_TIDAK_MENENTU => 'Tidak menentu',
PemberianPupuk::JENIS_SESUAI_DOSIS_TIDAK_MENENTU => 'Jenis sesuai',
PemberianPupuk::JENIS_DOSIS_SESUAI_WAKTU_CUKUP_TEPAT => 'Cukup tepat',
PemberianPupuk::JENIS_DOSIS_SESUAI_WAKTU_TEPAT => 'Tepat & rutin',
default => $this->shortEnumLabel((string) $value),
};
}
private function toKilograms(float $value, string $unit): float
{
return match (strtolower($unit)) {
'ton' => $value * 1000,
'kuintal', 'kwintal' => $value * 100,
default => $value,
};
}
private function withAllOption(string $label, array $options): array
{
return array_merge([
[
'value' => 'all',
'label' => $label,
],
], $options);
}
private function kabupatenLabel(KabupatenKota $kabupaten): string
{
return preg_replace('/^(kabupaten|kota)\s+/i', '', $kabupaten->nama);
}
private function segmentLabel(float $score): string
{
return match (true) {
$score >= 4.0 => 'Penggerak',
$score >= 3.0 => 'Perintis',
$score >= 2.0 => 'Pemerhati',
$score >= 1.0 => 'Pemula',
default => 'Belum tersegmentasi',
};
}
}
@@ -22,10 +22,13 @@ class ProfilPetaniController extends Controller
}
$title = 'Dashboard Profil Petani';
$komoditas = Komoditas::where('is_utama', true)->get();
$komoditas = Komoditas::select('id', 'nama')->where('is_utama', true)->get();
$komoditasIds = $komoditas->pluck('id');
$petani = Petani::pluck('id');
$lahan = Lahan::whereIn('petani_id', $petani)->get();
$petaniIds = fn () => Petani::query()->select('id');
$lahanIds = fn () => Lahan::query()
->whereIn('petani_id', $petaniIds())
->select('id');
$petaniSummary = Petani::select(
'komoditas_id',
@@ -38,14 +41,14 @@ class ProfilPetaniController extends Controller
DB::raw('COUNT(*) as total'),
DB::raw('SUM(luas_lahan) as luas_lahan')
)
->whereIn('petani_id', $petani)
->whereIn('petani_id', $petaniIds())
->groupBy('komoditas_id')
->get();
$tanamanSummary = Tanaman::select(
'komoditas_id',
DB::raw('COUNT(*) as total')
)
->whereIn('lahan_id', $lahan->pluck('id'))
->whereIn('lahan_id', $lahanIds())
->groupBy('komoditas_id')
->get();
@@ -59,7 +62,7 @@ class ProfilPetaniController extends Controller
END
";
$skorSummary = SkorPetani::selectRaw("$case AS segmen, COUNT(*) AS total")
->whereIn('petani_id', $petani)
->whereIn('petani_id', $petaniIds())
->groupByRaw($case)
->get();
@@ -70,16 +73,15 @@ class ProfilPetaniController extends Controller
$case AS segmen,
COUNT(petani.id) AS total
")
->whereIn('petani_skor.petani_id', $petani)
->whereIn('petani_skor.petani_id', $petaniIds())
->groupBy('petani.komoditas_id')
->groupByRaw($case)
->get();
$skorAverage = SkorPetani::query()
->join('petani', 'petani_skor.petani_id', '=', 'petani.id')
->whereIn('petani_id', $petani)
->whereIn('petani.komoditas_id', $komoditas->pluck('id'))
->whereIn('petani_id', $petaniIds())
->whereIn('petani.komoditas_id', $komoditasIds)
->avg('skor_kesiapan_adopsi');
if ($skorAverage >= 4.0) {
$segmenAverage = 'Penggerak';
@@ -95,8 +97,8 @@ class ProfilPetaniController extends Controller
$skorDimensi = SkorPetani::query()
->join('petani', 'petani_skor.petani_id', '=', 'petani.id')
->whereIn('petani_id', $petani)
->whereIn('petani.komoditas_id', $komoditas->pluck('id'))
->whereIn('petani_id', $petaniIds())
->whereIn('petani.komoditas_id', $komoditasIds)
->selectRaw("
avg(skor_d2_sistem_praktik_budidaya) as skor_d2_sistem_praktik_budidaya,
avg(skor_d4_sosial_ekonomi) as skor_d4_sosial_ekonomi,
@@ -105,20 +107,20 @@ class ProfilPetaniController extends Controller
$skorKomponen = SkorPetani::query()
->join('petani', 'petani_skor.petani_id', '=', 'petani.id')
->whereIn('petani_id', $petani)
->whereIn('petani.komoditas_id', $komoditas->pluck('id'))
->whereIn('petani_id', $petaniIds())
->whereIn('petani.komoditas_id', $komoditasIds)
->selectRaw("avg(skor_komp_1_d4_k3_motivasi_kapasitas_adopsi) as skor_komp_1_d4_k3_motivasi_kapasitas_adopsi,
avg(skor_komp_2_d4_k2_ekonomi_rumah_tangga) as skor_komp_2_d4_k2_ekonomi_rumah_tangga,
avg(skor_komp_3_d2_praktik_budidaya_gap) as skor_komp_3_d2_praktik_budidaya_gap,
avg(skor_komp_4_d4_k4_keterlibatan_kelembagaan) as skor_komp_4_d4_k4_keterlibatan_kelembagaan,
avg(skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan) as skor_komp_5_d4_k5_k6_akses_kebebasan_keuanga,
avg(skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan) as skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan,
avg(skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar) as skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar")
->first();
$skorMultiDimensi = SkorPetani::query()
->join('petani', 'petani_skor.petani_id', '=', 'petani.id')
->whereIn('petani_id', $petani)
->whereIn('petani.komoditas_id', $komoditas->pluck('id'))
->whereIn('petani_id', $petaniIds())
->whereIn('petani.komoditas_id', $komoditasIds)
->selectRaw("$case AS segmen,
avg(skor_kesiapan_adopsi) as skor_kesiapan_adopsi,
avg(skor_d2_sistem_praktik_budidaya) as skor_d2_sistem_praktik_budidaya,
@@ -127,9 +129,29 @@ class ProfilPetaniController extends Controller
->groupByRaw($case)
->get();
$petani = Petani::with(['skor'])
->whereIn('id', $petani)
->whereIn('komoditas_id', $komoditas->pluck('id'))
$skorMultiKomponen = SkorPetani::query()
->join('petani', 'petani_skor.petani_id', '=', 'petani.id')
->whereIn('petani_id', $petaniIds())
->whereIn('petani.komoditas_id', $komoditasIds)
->selectRaw("$case AS segmen,
avg(skor_kesiapan_adopsi) as skor_kesiapan_adopsi,
avg(skor_komp_1_d4_k3_motivasi_kapasitas_adopsi) as skor_komp_1_d4_k3_motivasi_kapasitas_adopsi,
avg(skor_komp_2_d4_k2_ekonomi_rumah_tangga) as skor_komp_2_d4_k2_ekonomi_rumah_tangga,
avg(skor_komp_3_d2_praktik_budidaya_gap) as skor_komp_3_d2_praktik_budidaya_gap,
avg(skor_komp_4_d4_k4_keterlibatan_kelembagaan) as skor_komp_4_d4_k4_keterlibatan_kelembagaan,
avg(skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan) as skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan,
avg(skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar) as skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar")
->groupByRaw($case)
->get();
$petani = Petani::query()
->select('id', 'nama', 'jenis_kelamin', 'tanggal_lahir', 'komoditas_id')
->with([
'komoditas:id,nama',
'skor:id,petani_id,skor_kesiapan_adopsi,skor_d2_sistem_praktik_budidaya,skor_d4_sosial_ekonomi,skor_d6_rantai_nilai_akses_pasar,skor_komp_1_d4_k3_motivasi_kapasitas_adopsi,skor_komp_2_d4_k2_ekonomi_rumah_tangga,skor_komp_3_d2_praktik_budidaya_gap,skor_komp_4_d4_k4_keterlibatan_kelembagaan,skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan,skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar',
])
->whereIn('komoditas_id', $komoditasIds)
->orderBy('nama')
->get();
return view('dashboard.petani', compact('title',
@@ -144,6 +166,7 @@ class ProfilPetaniController extends Controller
'skorDimensi',
'skorKomponen',
'skorMultiDimensi',
'skorMultiKomponen',
'petani',
));
}
@@ -34,12 +34,42 @@ class SummaryController extends Controller
$totalpetani = Profile::where('role', 'petani')->count();
$totallahan = Lahan::whereNotNull('path')->count();
$petaniList = Profile::where('role', 'petani')
->with(['lahan.tanaman.komoditas', 'desaKelurahan'])
$petaniList = Profile::select('id', 'nama', 'role', 'desa_kelurahan_id')
->where('role', 'petani')
->with([
'lahan:id,profile_id,luas_lahan',
'desaKelurahan:id,nama,kecamatan_id',
])
->paginate(20);
$allLahan = Lahan::whereNotNull('path')
->with(['profile', 'tanaman.komoditas', 'desaKelurahan.kecamatan.kabupatenKota.provinsi'])
$lahanSummaryByDesa = Lahan::whereNotNull('path')
->whereNotNull('desa_kelurahan_id')
->select('desa_kelurahan_id')
->selectRaw('COUNT(*) as total_lahan')
->selectRaw('COALESCE(SUM(luas_lahan), 0) as total_luas')
->groupBy('desa_kelurahan_id')
->get();
$desaList = DesaKelurahan::select('id', 'nama', 'path', 'kecamatan_id')
->whereIn('id', $lahanSummaryByDesa->pluck('desa_kelurahan_id')->filter()->unique()->values())
->with([
'kecamatan:id,nama,path,kabupaten_kota_id',
'kecamatan.kabupatenKota:id,nama,path,provinsi_id',
'kecamatan.kabupatenKota.provinsi:id,nama,path',
])
->get()
->keyBy('id');
$mapLahanLimit = min(max((int) $request->integer('map_lahan_limit', 500), 0), 2000);
$mapLahan = Lahan::whereNotNull('path')
->select('id', 'profile_id', 'desa_kelurahan_id', 'path', 'luas_lahan')
->with([
'profile:id,nama',
'tanaman:id,lahan_id,komoditas_id',
'tanaman.komoditas:id,nama',
])
->orderByDesc('updated_at')
->limit($mapLahanLimit)
->get();
$geoProvinsi = [];
@@ -48,47 +78,51 @@ class SummaryController extends Controller
$geoDesa = [];
$geoLahan = [];
foreach ($allLahan as $lahan) {
$desa = $lahan->desaKelurahan;
foreach ($lahanSummaryByDesa as $summary) {
$desa = $desaList->get($summary->desa_kelurahan_id);
$kec = $desa ? $desa->kecamatan : null;
$kab = $kec ? $kec->kabupatenKota : null;
$prov = $kab ? $kab->provinsi : null;
$totalLahan = (int) $summary->total_lahan;
$totalLuas = (float) $summary->total_luas;
if ($prov && $prov->path) {
if (!isset($geoProvinsi[$prov->id])) {
$geoProvinsi[$prov->id] = ['id' => $prov->id, 'nama' => $prov->nama, 'polygon' => $prov->path, 'total_lahan' => 0, 'total_luas' => 0];
}
$geoProvinsi[$prov->id]['total_lahan']++;
$geoProvinsi[$prov->id]['total_luas'] += $lahan->luas_lahan;
$geoProvinsi[$prov->id]['total_lahan'] += $totalLahan;
$geoProvinsi[$prov->id]['total_luas'] += $totalLuas;
}
if ($kab && $kab->path) {
if (!isset($geoKabupaten[$kab->id])) {
$geoKabupaten[$kab->id] = ['id' => $kab->id, 'parent_id' => $prov->id ?? null, 'nama' => $kab->nama, 'polygon' => $kab->path, 'total_lahan' => 0, 'total_luas' => 0];
}
$geoKabupaten[$kab->id]['total_lahan']++;
$geoKabupaten[$kab->id]['total_luas'] += $lahan->luas_lahan;
$geoKabupaten[$kab->id]['total_lahan'] += $totalLahan;
$geoKabupaten[$kab->id]['total_luas'] += $totalLuas;
}
if ($kec && $kec->path) {
if (!isset($geoKecamatan[$kec->id])) {
$geoKecamatan[$kec->id] = ['id' => $kec->id, 'parent_id' => $kab->id ?? null, 'nama' => $kec->nama, 'polygon' => $kec->path, 'total_lahan' => 0, 'total_luas' => 0];
}
$geoKecamatan[$kec->id]['total_lahan']++;
$geoKecamatan[$kec->id]['total_luas'] += $lahan->luas_lahan;
$geoKecamatan[$kec->id]['total_lahan'] += $totalLahan;
$geoKecamatan[$kec->id]['total_luas'] += $totalLuas;
}
if ($desa && $desa->path) {
if (!isset($geoDesa[$desa->id])) {
$geoDesa[$desa->id] = ['id' => $desa->id, 'parent_id' => $kec->id ?? null, 'nama' => $desa->nama, 'polygon' => $desa->path, 'total_lahan' => 0, 'total_luas' => 0];
}
$geoDesa[$desa->id]['total_lahan']++;
$geoDesa[$desa->id]['total_luas'] += $lahan->luas_lahan;
$geoDesa[$desa->id]['total_lahan'] += $totalLahan;
$geoDesa[$desa->id]['total_luas'] += $totalLuas;
}
}
foreach ($mapLahan as $lahan) {
$geoLahan[] = [
'id' => $lahan->id,
'parent_id' => $desa->id ?? null,
'parent_id' => $lahan->desa_kelurahan_id,
'polygon' => $lahan->path,
'nama_petani' => $lahan->profile->nama ?? 'N/A',
'luas' => $lahan->luas_lahan,
@@ -4,6 +4,7 @@ namespace App\Http\Controllers\Web\Dashboard;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
@@ -14,6 +15,9 @@ use App\Models\Pertanian\Lahan;
use App\Models\Pertanian\Tanaman;
use App\Models\Pertanian\SurveyPelatihan;
use App\Models\Pertanian\SurveySertifikasi;
use App\Enums\AksesPasar\PraktikFermentasi;
use App\Enums\AksesPasar\SaluranTerdahulu;
use App\Enums\AksesPasar\SkorPengalaman;
use BackedEnum;
@@ -63,7 +67,8 @@ class SurveyPetaniController extends Controller
->orderByDesc('petani_count')
->get();
$totalPetani = (int) $komoditasCollection->sum('petani_count');
// $totalPetani = (int) $komoditasCollection->sum('petani_count');
$totalPetani = Petani::count();
$circumference = 2 * pi() * 46;
$komoditas = $komoditasCollection
@@ -91,36 +96,34 @@ class SurveyPetaniController extends Controller
// Progres pengisian data per petani
$progressPetani = Petani::query()
->select([
'id',
'nama',
])
->withExists([
'lahans as has_lahan',
'praktikBudidaya as has_praktik_budidaya',
'sosialEkonomi as has_sosial_ekonomi',
'aksesPasar as has_akses_pasar',
->select(['id', 'nama', 'komoditas_id'])
->with([
'komoditas:id,nama',
'lahans',
'praktikBudidaya',
'sosialEkonomi',
'aksesPasar',
])
->orderBy('nama')
->get()
->map(function ($petani) {
$status = [
'lahan' => [
'label' => 'Lahan',
'done' => (bool) $petani->has_lahan,
],
'praktik_budidaya' => [
'label' => 'Praktik Budidaya',
'done' => (bool) $petani->has_praktik_budidaya,
],
'sosial_ekonomi' => [
'label' => 'Sosial Ekonomi',
'done' => (bool) $petani->has_sosial_ekonomi,
],
'akses_pasar' => [
'label' => 'Akses Pasar',
'done' => (bool) $petani->has_akses_pasar,
],
'lahan' => $this->moduleStatus(
'Lahan',
$this->hasCompleteLahan($petani)
),
'praktik_budidaya' => $this->moduleStatus(
'Praktik Budidaya',
$this->hasCompletePraktikBudidaya($petani->praktikBudidaya)
),
'sosial_ekonomi' => $this->moduleStatus(
'Sosial Ekonomi',
$this->hasCompleteSosialEkonomi($petani->sosialEkonomi)
),
'akses_pasar' => $this->moduleStatus(
'Akses Pasar',
$this->hasCompleteAksesPasar($petani->aksesPasar)
),
];
$totalModul = count($status);
@@ -130,12 +133,13 @@ class SurveyPetaniController extends Controller
->count();
return [
'id' => $petani->id,
'name' => $petani->nama,
'status' => $status,
'done' => $modulSelesai,
'total' => $totalModul,
'percent' => $totalModul > 0
'id' => $petani->id,
'name' => $petani->nama,
'komoditas' => $petani->komoditas?->nama ?? 'Belum ditentukan',
'status' => $status,
'done' => $modulSelesai,
'total' => $totalModul,
'percent' => $totalModul > 0
? (int) round(($modulSelesai / $totalModul) * 100)
: 0,
];
@@ -144,8 +148,9 @@ class SurveyPetaniController extends Controller
// Ringkasan lahan
$totalLuasLahan = ((float) Lahan::query()
->sum('luas_lahan')) / 10000;
// $totalLuasLahan = ((float) Lahan::query()
// ->sum('luas_lahan')) / 10000;
$totalLuasLahan = Lahan::has('petani')->sum('luas_lahan');
// Jumlah tanaman berdasarkan komoditas petani
@@ -276,6 +281,147 @@ class SurveyPetaniController extends Controller
]);
}
private function moduleStatus(string $label, bool $done): array
{
return [
'label' => $label,
'done' => $done,
];
}
private function hasCompleteLahan(Petani $petani): bool
{
return $petani->lahans->contains(function ($lahan) {
return $this->allFieldsFilled($lahan, [
'luas_lahan',
'komoditas_id',
'jenis_komoditas_id',
'umur_tanaman',
'kondisi_tanaman',
]);
});
}
private function hasCompletePraktikBudidaya(?Model $praktikBudidaya): bool
{
return $this->allFieldsFilled($praktikBudidaya, [
'frekuensi_pemangkasan_utama',
'pemberian_pupuk',
'metode_penanganan_opt',
'frekuensi_sanitasi_lahan',
'penanganan_gulma',
'kondisi_pengelolaan_air',
]);
}
private function hasCompleteSosialEkonomi(?Model $sosialEkonomi): bool
{
return $this->allFieldsFilled($sosialEkonomi, [
'skor_periode_paceklik',
'skor_kemampuan_menabung',
'skor_kecukupan_penghasilan',
'skor_kejelasan_status_lahan',
'kemauan_mencoba_praktik_baru',
'pemahaman_mutu_harga',
'panutan_petani_sukses',
'kemauan_ikut_program',
'orientasi_rencana_jangka_panjang',
'keaktifan_pertemuan_kelompok',
'peran_dalam_kelompok',
'manfaat_kelompok_tani',
'status_rekening_tabungan',
'pengalaman_kredit_kebun',
'kondisi_aset_produktif',
'keterlibatan_program_keuangan_formal',
'keterikatan_hutang_panen',
'praktik_ijon',
'kebebasan_memilih_pembeli',
]);
}
private function hasCompleteAksesPasar(?Model $aksesPasar): bool
{
if (! $this->allFieldsFilled($aksesPasar, [
'skor_pengalaman',
'praktik_fermentasi',
'skor_kesadaran_premium',
'tingkat_kepercayaan_pembeli_baru',
])) {
return false;
}
$skorPengalaman = (int) $aksesPasar->getAttribute('skor_pengalaman');
if (
$skorPengalaman !== SkorPengalaman::BELUM_PERNAH->value
&& ! $this->valueIsFilled($aksesPasar->getAttribute('saluran_terdahulu'))
) {
return false;
}
if (
in_array($skorPengalaman, [
SkorPengalaman::PERNAH_BERHENTI_TIDAK_ADA_AKSES->value,
SkorPengalaman::PERNAH_BERHENTI_MUNGKIN_KEMBALI->value,
], true)
&& ! $this->valueIsFilled($aksesPasar->getAttribute('alasan_berhenti'))
) {
return false;
}
if (
in_array(
SaluranTerdahulu::LAINNYA->value,
$aksesPasar->getAttribute('saluran_terdahulu') ?? [],
true
)
&& ! $this->valueIsFilled($aksesPasar->getAttribute('saluran_terdahulu_lainnya'))
) {
return false;
}
if (
$aksesPasar->getAttribute('praktik_fermentasi') !== PraktikFermentasi::BELUM_PERNAH->value
&& ! $this->allFieldsFilled($aksesPasar, [
'proses_fermentasi',
'model_fermentasi_memungkinkan',
])
) {
return false;
}
return true;
}
private function allFieldsFilled(?Model $model, array $fields): bool
{
if (! $model) {
return false;
}
foreach ($fields as $field) {
if (! $this->valueIsFilled($model->getAttribute($field))) {
return false;
}
}
return true;
}
private function valueIsFilled(mixed $value): bool
{
if ($value instanceof BackedEnum) {
$value = $value->value;
}
if (is_array($value)) {
return collect($value)
->contains(fn ($item) => $this->valueIsFilled($item));
}
return ! is_null($value) && $value !== '';
}
private function pelatihanGapOptions(): array
{
$enumClass = self::GAP_ENUM_CLASS;
@@ -55,19 +55,7 @@ class FormBasisDataController extends Controller
], 404);
}
$validated = $request->validate([
'parent_id' => ['nullable', 'exists:ekosistem_basis_data_form,id'],
'tipe' => ['required', Rule::enum(LayoutForm::class)],
'column_width' => [
Rule::requiredIf($request->tipe === LayoutForm::COLUMN->value),
'nullable', 'integer', 'min:1', 'max:12'],
'kolom_id' => [
Rule::requiredIf($request->tipe === LayoutForm::VALUE->value),
'nullable', 'exists:ekosistem_basis_data_kolom,id'],
'section_label' => [
Rule::requiredIf($request->tipe === LayoutForm::SECTION->value),
'nullable', 'string'],
]);
$validated = $this->validateFormPayload($request, $tabelId);
FormBasisData::create([...$validated,
'tabel_id' => $tabelId,
@@ -115,19 +103,7 @@ class FormBasisDataController extends Controller
], 404);
}
$validated = $request->validate([
'parent_id' => ['nullable', 'exists:ekosistem_basis_data_form,id'],
'tipe' => ['required', Rule::enum(LayoutForm::class)],
'column_width' => [
Rule::requiredIf($request->tipe === LayoutForm::COLUMN->value),
'nullable', 'integer', 'min:1', 'max:12'],
'kolom_id' => [
Rule::requiredIf($request->tipe === LayoutForm::VALUE->value),
'nullable', 'exists:ekosistem_basis_data_kolom,id'],
'section_label' => [
Rule::requiredIf($request->tipe === LayoutForm::SECTION->value),
'nullable', 'string'],
]);
$validated = $this->validateFormPayload($request, $tabelId, $form);
$form->update([...$validated,
'updated_by' => auth()->user()->id
@@ -293,4 +269,88 @@ class FormBasisDataController extends Controller
'message' => 'Formulir basis data berhasil diperbarui.'
], 200);
}
private function validateFormPayload(Request $request, string $tabelId, ?FormBasisData $form = null): array
{
$tipe = $request->input('tipe');
$needsParent = in_array($tipe, [LayoutForm::COLUMN->value, LayoutForm::VALUE->value], true);
$mustBeRoot = in_array($tipe, [LayoutForm::ROW->value, LayoutForm::SECTION->value, LayoutForm::HR_LINE->value], true);
$validator = Validator::make($request->all(), [
'parent_id' => [
Rule::requiredIf($needsParent),
Rule::prohibitedIf($mustBeRoot),
'nullable',
Rule::exists('ekosistem_basis_data_form', 'id')
->where(fn ($query) => $query
->where('tabel_id', $tabelId)
->whereNull('deleted_at')),
],
'tipe' => ['required', Rule::enum(LayoutForm::class)],
'column_width' => [
Rule::requiredIf($tipe === LayoutForm::COLUMN->value),
'nullable', 'integer', 'min:1', 'max:12'
],
'kolom_id' => [
Rule::requiredIf($tipe === LayoutForm::VALUE->value),
'nullable',
Rule::exists('ekosistem_basis_data_kolom', 'id')
->where(fn ($query) => $query
->where('tabel_id', $tabelId)
->whereNull('deleted_at')),
],
'section_label' => [
Rule::requiredIf($tipe === LayoutForm::SECTION->value),
'nullable', 'string'
],
]);
$validator->after(function ($validator) use ($request, $tabelId, $form) {
if ($validator->errors()->isNotEmpty() || !$request->filled('parent_id')) {
return;
}
if ($form && (int) $request->input('parent_id') === (int) $form->id) {
$validator->errors()->add('parent_id', 'Induk formulir tidak boleh menunjuk ke dirinya sendiri.');
return;
}
$layout = LayoutForm::from($request->input('tipe'));
$expectedParent = match ($layout) {
LayoutForm::COLUMN => LayoutForm::ROW,
LayoutForm::VALUE => LayoutForm::COLUMN,
default => null,
};
if (!$expectedParent) {
return;
}
$parent = FormBasisData::where('tabel_id', $tabelId)->find($request->input('parent_id'));
if (!$parent || $parent->tipe !== $expectedParent) {
$validator->errors()->add('parent_id', 'Induk formulir tidak sesuai dengan tipe formulir.');
}
});
$validated = $validator->validate();
$layout = LayoutForm::from($validated['tipe']);
if (in_array($layout, [LayoutForm::ROW, LayoutForm::SECTION, LayoutForm::HR_LINE], true)) {
$validated['parent_id'] = null;
}
if ($layout !== LayoutForm::COLUMN) {
$validated['column_width'] = null;
}
if ($layout !== LayoutForm::VALUE) {
$validated['kolom_id'] = null;
}
if ($layout !== LayoutForm::SECTION) {
$validated['section_label'] = null;
}
return $validated;
}
}
@@ -0,0 +1,177 @@
<?php
namespace App\Http\Controllers\Web\Koperasi;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Koperasi\PengurusKoperasi;
class PengurusKoperasiController extends Controller
{
public function index(Request $request)
{
$query = PengurusKoperasi::query();
if ($request->filled('search')) {
$search = $request->search;
$query->where('nama_lengkap', 'like', "%{$search}%")
->orWhere('nama_koperasi', 'like', "%{$search}%");
}
$perPage = $request->get('per_page', 10);
$pengurus = $query->latest()->paginate($perPage);
$totalPengurus = PengurusKoperasi::count();
$totalKoperasi = PengurusKoperasi::distinct('nama_koperasi')->count('nama_koperasi');
$totalJabatan = PengurusKoperasi::distinct('posisi_dalam_koperasi')->count('posisi_dalam_koperasi');
return view('koperasi.profil.index', compact(
'pengurus',
'totalPengurus',
'totalKoperasi',
'totalJabatan',
));
}
public function create()
{
return view('koperasi.profil.add');
}
public function edit($id)
{
$pengurus = PengurusKoperasi::findOrFail($id);
return view('koperasi.profil.edit', compact('pengurus'));
}
public function update(Request $request, $id)
{
$validatedData = $request->validate([
'nama_lengkap' => 'required|string|max:255',
'posisi_dalam_koperasi' => 'required|string|max:255',
'tahun_bergabung' => 'nullable|integer',
'no_hp' => 'nullable|string|max:20',
'alamat_tinggal' => 'nullable|string',
'nama_koperasi' => 'required|string|max:255',
'jenis_koperasi' => 'required|string|max:255',
'jenis_koperasi_lainnya'=> 'nullable|string|max:255',
'alamat_koperasi' => 'nullable|string',
'skala_operasi' => 'required|string|max:255',
'tahun_berdiri' => 'nullable|integer',
'jumlah_anggota_awal' => 'nullable|integer',
'jumlah_anggota_dewasa' => 'nullable|integer',
'jumlah_anggota_anak' => 'nullable|integer',
'jumlah_pengurus' => 'nullable|integer',
'shu_2025' => 'nullable|numeric',
'shu_2024' => 'nullable|numeric',
'shu_2023' => 'nullable|numeric',
]);
if ($validatedData['jenis_koperasi'] === 'Lainnya' && !empty($validatedData['jenis_koperasi_lainnya'])) {
$validatedData['jenis_koperasi'] = $validatedData['jenis_koperasi_lainnya'];
}
unset($validatedData['jenis_koperasi_lainnya']);
$pengurus = PengurusKoperasi::findOrFail($id);
$pengurus->update($validatedData);
return redirect()->route('koperasi.pengurus.index')
->with('success', 'Profil Koperasi berhasil diperbarui!');
}
public function survey(Request $request, $id)
{
$pengurus = PengurusKoperasi::findOrFail($id);
$step = $request->query('step', 1);
if ($step == 1) {
return view('koperasi.kelembagaan-aktor.index', compact('pengurus'));
} elseif ($step == 2) {
return view('koperasi.rantai-nilai-akses-pasar.index', compact('pengurus'));
} elseif ($step == 3) {
return view('koperasi.sosial-ekonomi.index', compact('pengurus'));
}
abort(404);
}
public function surveyStore(Request $request, $id)
{
$pengurus = PengurusKoperasi::findOrFail($id);
$step = $request->query('step', 1);
$data = $request->except(['_token', 'pengurus_koperasi_id']);
foreach ($data as $key => $value) {
if (is_array($value)) {
$data[$key] = json_encode($value);
}
}
$pengurus->update($data);
if ($step == 1) {
if ($request->has('agregasi_komoditas') && str_contains($data['agregasi_komoditas'], 'Tidak terlibat')) {
return redirect()->route('koperasi.pengurus.survey', ['id' => $id, 'step' => 3])
->with('success', 'Data Kelembagaan tersimpan! (Melewati Rantai Nilai)');
}
return redirect()->route('koperasi.pengurus.survey', ['id' => $id, 'step' => 2])
->with('success', 'Data Kelembagaan berhasil disimpan!');
}
if ($step == 2) {
return redirect()->route('koperasi.pengurus.survey', ['id' => $id, 'step' => 3])
->with('success', 'Data Rantai Nilai berhasil disimpan!');
}
if ($step == 3) {
return redirect()->route('koperasi.pengurus.index')
->with('success', 'Seluruh data survei berhasil diselesaikan dan disimpan!');
}
return redirect()->back();
}
public function store(Request $request)
{
$validatedData = $request->validate([
'nama_lengkap' => 'required|string|max:255',
'posisi_dalam_koperasi' => 'required|string|max:255',
'tahun_bergabung' => 'nullable|integer',
'no_hp' => 'nullable|string|max:20',
'alamat_tinggal' => 'nullable|string',
'nama_koperasi' => 'required|string|max:255',
'jenis_koperasi' => 'required|string|max:255',
'jenis_koperasi_lainnya'=> 'nullable|string|max:255',
'alamat_koperasi' => 'nullable|string',
'skala_operasi' => 'required|string|max:255',
'tahun_berdiri' => 'nullable|integer',
'jumlah_anggota_awal' => 'nullable|integer',
'jumlah_anggota_dewasa' => 'nullable|integer',
'jumlah_anggota_anak' => 'nullable|integer',
'jumlah_pengurus' => 'nullable|integer',
'shu_2025' => 'nullable|numeric',
'shu_2024' => 'nullable|numeric',
'shu_2023' => 'nullable|numeric',
]);
if ($validatedData['jenis_koperasi'] === 'Lainnya' && !empty($validatedData['jenis_koperasi_lainnya'])) {
$validatedData['jenis_koperasi'] = $validatedData['jenis_koperasi_lainnya'];
}
unset($validatedData['jenis_koperasi_lainnya']);
$pengurus = PengurusKoperasi::create($validatedData);
return redirect()->route('koperasi.pengurus.index')
->with('success', 'Profil Koperasi berhasil ditambahkan! Silakan klik tombol hijau untuk mulai survei.');
}
public function destroy($id)
{
$pengurus = PengurusKoperasi::findOrFail($id);
$pengurus->delete();
return redirect()->route('koperasi.pengurus.index')
->with('success', 'Data pengurus koperasi berhasil dihapus!');
}
}
@@ -51,9 +51,13 @@ class DesaKelurahanController extends Controller
return response()->json($desa);
}
public function getByKecamatan($kecamatan_id)
public function getByKecamatan(Request $request, $kecamatan_id)
{
$desa = DesaKelurahan::where('kecamatan_id', $kecamatan_id)
$query = $request->boolean('all_wilayah')
? DesaKelurahan::withoutGlobalScope('program')
: DesaKelurahan::query();
$desa = $query->where('kecamatan_id', $kecamatan_id)
->orderBy('nama', 'asc')
->get();
@@ -51,9 +51,13 @@ class KabupatenKotaController extends Controller
return response()->json($kabupaten);
}
public function getByProvinsi($provinsi_id)
public function getByProvinsi(Request $request, $provinsi_id)
{
$kabupaten = KabupatenKota::where('provinsi_id', $provinsi_id)
$query = $request->boolean('all_wilayah')
? KabupatenKota::withoutGlobalScope('program')
: KabupatenKota::query();
$kabupaten = $query->where('provinsi_id', $provinsi_id)
->orderBy('nama', 'asc')
->get();
@@ -51,9 +51,13 @@ class KecamatanController extends Controller
return response()->json($kecamatan);
}
public function getByKabupaten($kabupaten_id)
public function getByKabupaten(Request $request, $kabupaten_id)
{
$kecamatan = Kecamatan::where('kabupaten_kota_id', $kabupaten_id)
$query = $request->boolean('all_wilayah')
? Kecamatan::withoutGlobalScope('program')
: Kecamatan::query();
$kecamatan = $query->where('kabupaten_kota_id', $kabupaten_id)
->orderBy('nama', 'asc')
->get();
@@ -16,6 +16,7 @@ use App\Enums\AksesPasar\SkorPengalaman;
use App\Enums\AksesPasar\SaluranTerdahulu;
use App\Enums\AksesPasar\PraktikFermentasi;
use App\Enums\AksesPasar\SkorKesadaranPremium;
use App\Enums\AksesPasar\TingkatKepercayaanPembeli;
class AksesPasarController extends Controller
{
@@ -113,6 +114,7 @@ class AksesPasarController extends Controller
'praktikFermentasiOptions' => PraktikFermentasi::options(),
'praktikBelumPernahValue' => PraktikFermentasi::BELUM_PERNAH->value,
'skorKesadaranPremiumOptions' => SkorKesadaranPremium::options(),
'tingkatKepercayaanOptions' => TingkatKepercayaanPembeli::options(),
'skorPengalamanBerhentiValues' => [
SkorPengalaman::PERNAH_BERHENTI_TIDAK_ADA_AKSES->value,
SkorPengalaman::PERNAH_BERHENTI_MUNGKIN_KEMBALI->value
@@ -154,6 +156,9 @@ class AksesPasarController extends Controller
'skor_kesadaran_premium' => ['nullable', 'integer', Rule::in(SkorKesadaranPremium::values())],
'sumber_info_premium' => ['nullable', 'string', 'max:255'],
'tingkat_kepercayaan_pembeli_baru' => ['nullable', 'integer', Rule::in(TingkatKepercayaanPembeli::values())],
'alasan_kepercayaan_pembeli_baru' => ['nullable', 'string'],
'harga_jual' => ['nullable', 'array'],
'harga_jual.*.bentuk_produk' => ['nullable', 'string'],
@@ -0,0 +1,153 @@
<?php
namespace App\Http\Controllers\Web\Produktivitas;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Str;
use Illuminate\Validation\Rule;
use App\Models\Pertanian\KelompokTani;
use App\Models\Pertanian\AsetKelompokTani;
class AsetKelompokTaniController extends Controller
{
public const JENIS_ASET_BAKU = [
'Bibit/alat produksi',
'Pupuk (stok kelompok)',
'Pulper/alat kupas',
'Lantai jemur',
'Kotak/wadah fermentasi',
'Kas/simpanan kelompok',
'Gudang/tempat simpan',
'Timbangan',
];
private function authorizeAccess(): void
{
if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) {
abort(403);
}
}
private function redirectToSection(string $url, string $section, string $message)
{
return redirect($url . '#section-' . $section)->with([
'success' => $message,
'success_section' => $section,
]);
}
public function index(KelompokTani $kelompokTani)
{
$this->authorizeAccess();
$kelompokTani->load('aset');
return view('produktivitas.survey-kelompok-tani.aset-keuangan', compact('kelompokTani'));
}
public function update(Request $request, KelompokTani $kelompokTani)
{
$this->authorizeAccess();
$validated = $request->validate([
'aset' => ['required', 'array'],
'aset.*.jenis_aset' => ['required', Rule::in(self::JENIS_ASET_BAKU)],
'aset.*.status_aset' => ['nullable', 'boolean'],
'aset.*.status_pengelolaan_aset' => ['nullable', 'string', 'max:100'],
'aset.*.kondisi_aset' => ['nullable', 'string', 'max:100'],
]);
foreach ($validated['aset'] as $item) {
$jenisAset = $item['jenis_aset'];
$ada = (bool) ($item['status_aset'] ?? false);
$existing = $kelompokTani->aset()->where('jenis_aset', $jenisAset)->first()
?? $kelompokTani->aset()->onlyTrashed()->where('jenis_aset', $jenisAset)->latest('id')->first();
if (!$ada) {
if ($existing && !$existing->trashed()) {
$existing->update(['deleted_by' => auth()->id()]);
$existing->delete();
}
continue;
}
if ($existing) {
if ($existing->trashed()) {
$existing->restore();
}
$existing->update([
'status_aset' => true,
'status_pengelolaan_aset' => $item['status_pengelolaan_aset'] ?? $existing->status_pengelolaan_aset,
'kondisi_aset' => $item['kondisi_aset'] ?? $existing->kondisi_aset,
'deleted_by' => null,
'updated_by' => auth()->id(),
]);
continue;
}
$kelompokTani->aset()->create([
'uid' => 'AKT-' . strtoupper(Str::random(10)),
'jenis_aset' => $jenisAset,
'status_aset' => true,
'status_pengelolaan_aset' => $item['status_pengelolaan_aset'] ?? '-',
'kondisi_aset' => $item['kondisi_aset'] ?? '-',
'created_by' => auth()->id(),
'updated_by' => auth()->id(),
]);
}
return $this->redirectToSection(route('kelompok-tani.aset-keuangan.index', $kelompokTani->id), 'aset-baku', 'Data aset produktif berhasil disimpan.');
}
public function store(Request $request, KelompokTani $kelompokTani)
{
$this->authorizeAccess();
$validated = $request->validate([
'aset_lainnya' => ['nullable', 'array'],
'aset_lainnya.*.jenis_aset' => ['nullable', 'string', 'max:255', Rule::notIn(self::JENIS_ASET_BAKU)],
'aset_lainnya.*.status_pengelolaan_aset' => ['nullable', 'string', 'max:100'],
'aset_lainnya.*.kondisi_aset' => ['nullable', 'string', 'max:100'],
], [
'aset_lainnya.*.jenis_aset.not_in' => 'Jenis aset ini sudah ada di daftar baku di atas.',
]);
foreach ($validated['aset_lainnya'] ?? [] as $item) {
$jenisAset = trim($item['jenis_aset'] ?? '');
if ($jenisAset === '') {
continue;
}
$kelompokTani->aset()->create([
'uid' => 'AKT-' . strtoupper(Str::random(10)),
'jenis_aset' => $jenisAset,
'status_aset' => true,
'status_pengelolaan_aset' => $item['status_pengelolaan_aset'] ?? '-',
'kondisi_aset' => $item['kondisi_aset'] ?? '-',
'created_by' => auth()->id(),
'updated_by' => auth()->id(),
]);
}
return $this->redirectToSection(route('kelompok-tani.aset-keuangan.index', $kelompokTani->id), 'aset-lainnya', 'Aset lainnya berhasil ditambahkan.');
}
public function destroy(KelompokTani $kelompokTani, AsetKelompokTani $aset)
{
$this->authorizeAccess();
abort_unless($aset->survey_kelompok_tani_id === $kelompokTani->id, 404);
abort_if(in_array($aset->jenis_aset, self::JENIS_ASET_BAKU), 422, 'Aset baku diatur lewat checklist, bukan dihapus langsung.');
$aset->update(['deleted_by' => auth()->id()]);
$aset->delete();
return $this->redirectToSection(route('kelompok-tani.aset-keuangan.index', $kelompokTani->id), 'aset-lainnya', 'Aset lainnya berhasil dihapus.');
}
}
@@ -0,0 +1,97 @@
<?php
namespace App\Http\Controllers\Web\Produktivitas;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Str;
use App\Models\Pertanian\KelompokTani;
use App\Models\Pertanian\BantuanKelompokTani;
class BantuanKelompokTaniController extends Controller
{
private function authorizeAccess(): void
{
if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) {
abort(403);
}
}
private function redirectToSection(string $url, string $section, string $message)
{
return redirect($url . '#section-' . $section)->with([
'success' => $message,
'success_section' => $section,
]);
}
private function redirectToSectionWithError(string $url, string $section, string $message)
{
return redirect($url . '#section-' . $section)->with([
'error' => $message,
'error_section' => $section,
]);
}
public function index(KelompokTani $kelompokTani)
{
$this->authorizeAccess();
$kelompokTani->load('bantuan');
return view('produktivitas.survey-kelompok-tani.bantuan-penilaian', compact('kelompokTani'));
}
public function store(Request $request, KelompokTani $kelompokTani)
{
$this->authorizeAccess();
if (!$kelompokTani->pernah_mendapatkan_bantuan) {
return $this->redirectToSectionWithError(
route('kelompok-tani.bantuan-penilaian.index', $kelompokTani->id),
'status-bantuan',
'Set status jadi "Pernah" dulu sebelum menambahkan daftar bantuan/program.'
);
}
$validated = $request->validate([
'bantuan' => ['nullable', 'array'],
'bantuan.*.nama_program' => ['nullable', 'string', 'max:255'],
'bantuan.*.penyelenggara' => ['nullable', 'string', 'max:255'],
'bantuan.*.bentuk_bantuan' => ['nullable', 'string', 'max:255'],
'bantuan.*.tahun' => ['nullable', 'integer', 'min:1900', 'max:' . date('Y')],
]);
foreach ($validated['bantuan'] ?? [] as $item) {
if (empty($item['nama_program']) && empty($item['penyelenggara']) && empty($item['bentuk_bantuan'])) {
continue;
}
$kelompokTani->bantuan()->create([
'uid' => 'BKT-' . strtoupper(Str::random(10)),
'nama_program' => $item['nama_program'] ?? null,
'penyelenggara' => $item['penyelenggara'] ?? null,
'bentuk_bantuan' => $item['bentuk_bantuan'] ?? null,
'tahun' => $item['tahun'] ?? null,
'created_by' => auth()->id(),
'updated_by' => auth()->id(),
]);
}
return $this->redirectToSection(route('kelompok-tani.bantuan-penilaian.index', $kelompokTani->id), 'bantuan', 'Data bantuan berhasil ditambahkan.');
}
public function destroy(KelompokTani $kelompokTani, BantuanKelompokTani $bantuan)
{
$this->authorizeAccess();
abort_unless($bantuan->survey_kelompok_tani_id === $kelompokTani->id, 404);
$bantuan->update(['deleted_by' => auth()->id()]);
$bantuan->delete();
return $this->redirectToSection(route('kelompok-tani.bantuan-penilaian.index', $kelompokTani->id), 'bantuan', 'Data bantuan berhasil dihapus.');
}
}
@@ -0,0 +1,81 @@
<?php
namespace App\Http\Controllers\Web\Produktivitas;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Str;
use App\Models\Pertanian\KelompokTani;
use App\Models\Pertanian\PengurusKelompokTani;
class PengurusKelompokTaniController extends Controller
{
private function authorizeAccess(): void
{
if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) {
abort(403);
}
}
private function redirectToSection(string $url, string $section, string $message)
{
return redirect($url . '#section-' . $section)->with([
'success' => $message,
'success_section' => $section,
]);
}
public function index(KelompokTani $kelompokTani)
{
$this->authorizeAccess();
$kelompokTani->load('pengurus');
return view('produktivitas.survey-kelompok-tani.pengurus-anggota', compact('kelompokTani'));
}
public function store(Request $request, KelompokTani $kelompokTani)
{
$this->authorizeAccess();
$validated = $request->validate([
'pengurus' => ['nullable', 'array'],
'pengurus.*.nama_pengurus' => ['nullable', 'string', 'max:255'],
'pengurus.*.jabatan' => ['nullable', 'string', 'max:255'],
'pengurus.*.kontak' => ['nullable', 'string', 'max:50'],
'pengurus.*.status' => ['nullable', 'boolean'],
]);
foreach ($validated['pengurus'] ?? [] as $item) {
if (empty($item['nama_pengurus']) && empty($item['jabatan']) && empty($item['kontak'])) {
continue;
}
$kelompokTani->pengurus()->create([
'uid' => 'PKT-' . strtoupper(Str::random(10)),
'nama_pengurus' => $item['nama_pengurus'] ?? null,
'jabatan' => $item['jabatan'] ?? null,
'kontak' => $item['kontak'] ?? null,
'status' => $item['status'] ?? false,
'created_by' => auth()->id(),
'updated_by' => auth()->id(),
]);
}
return $this->redirectToSection(route('kelompok-tani.pengurus-anggota.index', $kelompokTani->id), 'pengurus', 'Data pengurus berhasil ditambahkan.');
}
public function destroy(KelompokTani $kelompokTani, PengurusKelompokTani $pengurus)
{
$this->authorizeAccess();
abort_unless($pengurus->survey_kelompok_tani_id === $kelompokTani->id, 404);
$pengurus->update(['deleted_by' => auth()->id()]);
$pengurus->delete();
return $this->redirectToSection(route('kelompok-tani.pengurus-anggota.index', $kelompokTani->id), 'pengurus', 'Data pengurus berhasil dihapus.');
}
}
@@ -34,9 +34,16 @@ class PetaniController extends Controller
abort(403);
}
$provinsi = Provinsi::orderBy('kode', 'asc')->get();
$provinsi = Provinsi::select('id', 'kode', 'nama')->orderBy('kode', 'asc')->get();
$query = Petani::with('desakelurahan')
$query = Petani::with([
'desaKelurahan:id,nama,kecamatan_id',
'desaKelurahan.kecamatan:id,nama,kabupaten_kota_id',
'desaKelurahan.kecamatan.kabupatenKota:id,nama,provinsi_id',
'desaKelurahan.kecamatan.kabupatenKota.provinsi:id,nama',
'komoditas:id,nama',
'skor:id,petani_id,skor_kesiapan_adopsi',
])
->orderBy('created_at', 'desc');
if ($request->search) {
@@ -53,12 +60,12 @@ class PetaniController extends Controller
$summaryPetaniIds = (clone $query)->pluck('id');
$petani = $query->paginate($request->per_page ?? 10);
$komoditas = Komoditas::where('is_utama', true)->get();
$lahan = Lahan::whereIn('petani_id', $summaryPetaniIds)
->whereIn('komoditas_id', $komoditas->pluck('id'))
->get();
$tanaman = Tanaman::whereIn('lahan_id', $lahan->pluck('id'))
->get();
$komoditas = Komoditas::select('id', 'nama')->where('is_utama', true)->get();
$lahanQuery = Lahan::whereIn('petani_id', $summaryPetaniIds)
->whereIn('komoditas_id', $komoditas->pluck('id'));
$lahanIds = (clone $lahanQuery)->pluck('id');
$totalLuasLahan = (clone $lahanQuery)->sum('luas_lahan');
$totalTanaman = Tanaman::whereIn('lahan_id', $lahanIds)->count();
$case = "
CASE
@@ -74,7 +81,7 @@ class PetaniController extends Controller
->groupByRaw($case)
->get();
return view('produktivitas.petani.index', compact('petani', 'provinsi', 'lahan', 'komoditas', 'tanaman', 'skor'));
return view('produktivitas.petani.index', compact('petani', 'provinsi', 'komoditas', 'skor', 'totalLuasLahan', 'totalTanaman'));
}
public function create()
@@ -0,0 +1,878 @@
<?php
namespace App\Http\Controllers\Web\Produktivitas;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
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\SosialEkonomi;
use App\Models\Pertanian\SurveyPelatihan;
use App\Models\Pertanian\SurveySertifikasi;
use App\Models\Pertanian\AksesPasar;
use App\Models\Pertanian\HargaJualPanen;
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;
use App\Enums\SosialEkonomi\SkorKecukupanPenghasilan;
use App\Enums\SosialEkonomi\SkorKemampuanMenabung;
use App\Enums\SosialEkonomi\TerdaftarKelompokTani;
use App\Enums\SosialEkonomi\PeranDalamKelompok;
use App\Enums\SosialEkonomi\StatusRekeningTabungan;
use App\Enums\SosialEkonomi\PengalamanKreditKebun;
use App\Enums\SosialEkonomi\KeterikatanHutangPanen;
use App\Enums\SosialEkonomi\PraktikIjon;
use App\Enums\SosialEkonomi\KebebasanMemilihPembeli;
class ProfilPetaniController extends Controller
{
private const DIMENSION_LOW_MAX = 2.49;
private const DIMENSION_MEDIUM_MAX = 3.49;
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();
$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)
->first();
$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();
$sosialEkonomi = SosialEkonomi::where('petani_id', $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 ?? [],
];
$d4SosialEkonomi = null;
$terdaftarKelompok = $sosialEkonomi->terdaftar_kelompok_tani;
$peranKelompok = $sosialEkonomi->peran_dalam_kelompok;
if ($sosialEkonomi) {
$kecukupanPenghasilan = $sosialEkonomi->skor_kecukupan_penghasilan;
$kemampuanMenabung = $sosialEkonomi->skor_kemampuan_menabung;
$rekening = $sosialEkonomi->status_rekening_tabungan;
$kredit = $sosialEkonomi->pengalaman_kredit_kebun;
$hutangPanen = $sosialEkonomi->keterikatan_hutang_panen;
$ijon = $sosialEkonomi->praktik_ijon;
$programKeuanganRaw = $sosialEkonomi->status_program_keuangan_formal ?? [];
$namaProgram = [
'pkh' => 'PKH',
'blt' => 'BLT',
'kur' => 'KUR',
'kredit_koperasi_resmi' => 'Kredit Koperasi',
'credit_union_cu' => 'Credit Union (CU)',
'pinjaman_bumdes' => 'Pinjaman BUMDes',
'modal_hibah_dinas_pertanian' => 'Hibah Dinas Pertanian',
];
$programBantuan = collect($programKeuanganRaw)->map(function ($status, $key) use ($namaProgram) {
$statusMeta = match ($status) {
'sedang_menerima' => [
'label' => 'Sedang Menerima',
'short' => 'Aktif',
'color' => 'success',
'icon' => 'tabler-circle-check',
],
'pernah_tapi_tidak_lagi' => [
'label' => 'Pernah, Tidak Lagi',
'short' => 'Pernah',
'color' => 'info',
'icon' => 'tabler-history',
],
'belum_pernah' => [
'label' => 'Belum Pernah',
'short' => 'Belum Pernah',
'color' => 'secondary',
'icon' => 'tabler-minus',
],
default => [
'label' => Str::headline($status),
'short' => Str::headline($status),
'color' => 'secondary',
'icon' => 'tabler-help-circle',
],
};
return [
'key' => $key,
'nama' => $namaProgram[$key] ?? Str::headline($key),
'status' => $status,
'label' => $statusMeta['label'],
'short' => $statusMeta['short'],
'color' => $statusMeta['color'],
'icon' => $statusMeta['icon'],
];
})
->values();
$d4SosialEkonomi = [
'jumlah_tanggungan' => $sosialEkonomi->jumlah_tanggungan,
'kecukupan_penghasilan' => [
'skor' => $kecukupanPenghasilan?->value,
'label' => $kecukupanPenghasilan?->label(),
'color' => $this->getScoreColor(
$kecukupanPenghasilan?->value
),
],
'kemampuan_menabung' => [
'skor' => $kemampuanMenabung?->value,
'label' => $kemampuanMenabung?->label(),
'color' => $this->getScoreColor(
$kemampuanMenabung?->value
),
],
'status_kepemilikan_lahan' => $sosialEkonomi->status_kepemilikan_lahan,
'kelembagaan' => [
'terdaftar' =>
$terdaftarKelompok === TerdaftarKelompokTani::YA,
'status' =>
$terdaftarKelompok?->label(),
'peran' =>
$peranKelompok?->label(),
],
'kondisi_keuangan' => [
'rekening' => [
'label' => $rekening?->label(),
'value' => $rekening?->value,
'color' => $this->getFinancialColor(
$rekening?->value
),
'icon' => 'tabler-building-bank',
],
'kredit' => [
'label' => $kredit?->label(),
'value' => $kredit?->value,
'color' => $this->getFinancialColor(
$kredit?->value
),
'icon' => 'tabler-credit-card',
],
'hutang_panen' => [
'label' => $hutangPanen?->label(),
'value' => $hutangPanen?->value,
'color' => $this->getFinancialColor(
$hutangPanen?->value
),
'icon' => 'tabler-coins',
],
'ijon' => [
'label' => $ijon?->label(),
'value' => $ijon?->value,
'color' => $this->getFinancialColor(
$ijon?->value
),
'icon' => 'tabler-link',
],
],
'program_bantuan' => $programBantuan,
];
}
$surveyPelatihan = SurveyPelatihan::where('petani_id', $id)
->orderByDesc('tahun_pelaksanaan')
->get();
$surveySertifikasi = SurveySertifikasi::where('petani_id', $id)
->orderByDesc('tahun_pelaksanaan')
->get();
$aksesPasar = AksesPasar::where('petani_id', $id)->first();
$saluranTerdahulu = collect($aksesPasar?->saluran_terdahulu ?? [] );
$d6SaluranPasar = [
[
'key' => 'tengkulak',
'label' => 'Tengkulak',
'icon' => 'tabler-user-dollar',
'aktif' => $saluranTerdahulu->contains(
fn ($item) => Str::contains(
Str::lower($item),
['tengkulak', 'pedagang lokal']
)
),
],
[
'key' => 'koperasi',
'label' => 'Koperasi',
'icon' => 'tabler-users-group',
'aktif' => $saluranTerdahulu->contains(
fn ($item) => Str::contains(
Str::lower($item),
'koperasi'
)
),
],
[
'key' => 'bumdes',
'label' => 'BUMDes',
'icon' => 'tabler-building-community',
'aktif' => $saluranTerdahulu->contains(
fn ($item) => Str::contains(
Str::lower($item),
'bumdes'
)
),
],
[
'key' => 'eksportir',
'label' => 'Eksportir',
'icon' => 'tabler-plane-departure',
'aktif' => $saluranTerdahulu->contains(
fn ($item) => Str::contains(
Str::lower($item),
'eksportir'
)
),
],
];
$hargaJualPanen = HargaJualPanen::where('petani_id', $id)->get();
$d6HargaJual = $hargaJualPanen->map(function ($item) {
$hargaSekarang = $item->harga_panen_terakhir !== null
? (float) $item->harga_panen_terakhir
: null;
$hargaTahunLalu = $item->harga_tahun_lalu !== null
? (float) $item->harga_tahun_lalu
: null;
$perubahan = null;
if (
$hargaSekarang !== null &&
$hargaTahunLalu !== null &&
$hargaTahunLalu > 0
) {
$perubahan = (
($hargaSekarang - $hargaTahunLalu)
/ $hargaTahunLalu
) * 100;
}
return [
'bentuk_produk' => $item->bentuk_produk,
'harga_sekarang' => $hargaSekarang,
'harga_tahun_lalu' => $hargaTahunLalu,
'harga_dua_tahun_lalu' =>
$item->harga_dua_tahun_lalu !== null
? (float) $item->harga_dua_tahun_lalu
: null,
'perubahan' => $perubahan,
'trend' => match (true) {
$perubahan === null => 'neutral',
$perubahan > 0 => 'up',
$perubahan < 0 => 'down',
default => 'stable',
},
];
});
$kebebasanPembeli = $sosialEkonomi?->kebebasan_memilih_pembeli;
$d6RantaiNilai = [
'saluran_pasar' => $d6SaluranPasar,
'harga_jual' => $d6HargaJual,
'kebebasan_memilih_pembeli' => [
'skor' => $kebebasanPembeli?->value,
'label' => $kebebasanPembeli?->label(),
'persentase' => $kebebasanPembeli
? ($kebebasanPembeli->value / 5) * 100
: 0,
'color' => $this->getScoreColor(
$kebebasanPembeli?->value
),
],
];
$data = [
'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,
'sosialEkonomi' => $sosialEkonomi,
'd4SosialEkonomi' => $d4SosialEkonomi,
'surveyPelatihan' => $surveyPelatihan,
'surveySertifikasi' => $surveySertifikasi,
'aksesPasar' => $aksesPasar,
'd6SaluranPasar' => $d6SaluranPasar,
'hargaJualPanen' => $hargaJualPanen,
'd6HargaJual' => $d6HargaJual,
'kebebasanPembeli' => $kebebasanPembeli,
'd6RantaiNilai' => $d6RantaiNilai
];
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 getFinancialColor(?int $score): string
{
if ($score === null || $score === 0) {
return 'secondary';
}
return match (true) {
$score >= 5 => 'success',
$score >= 4 => 'info',
$score >= 2 => 'warning',
default => 'danger',
};
}
private function buildProfiling(SkorPetani $skorPetani): array
{
$skorAkhir = $this->normalizeScore($skorPetani->skor_kesiapan_adopsi);
$segmen = $this->getSegmen($skorAkhir);
$dimensions = [
'd2' => [
'kode' => 'D2',
'nama' => 'Sistem & Praktik Budidaya',
'skor' => $this->normalizeScore(
$skorPetani->skor_d2_sistem_praktik_budidaya
),
],
'd4' => [
'kode' => 'D4',
'nama' => 'Sosial-Ekonomi Rumah Tangga',
'skor' => $this->normalizeScore(
$skorPetani->skor_d4_sosial_ekonomi
),
],
'd6' => [
'kode' => 'D6',
'nama' => 'Rantai Nilai & Akses Pasar',
'skor' => $this->normalizeScore(
$skorPetani->skor_d6_rantai_nilai_akses_pasar
),
],
];
foreach ($dimensions as $key => $dimension) {
$dimensions[$key]['level'] = $this->getDimensionLevel($dimension['skor']);
}
$components = collect([
[
'key' => 'motivasi',
'nama' => 'Motivasi & Kapasitas Adopsi',
'short' => 'Motivasi',
'dimensi' => 'D4',
'bobot' => 25,
'icon' => 'tabler-bulb',
'skor' => $this->normalizeScore($skorPetani->skor_komp_1_d4_k3_motivasi_kapasitas_adopsi),
],
[
'key' => 'ekonomi',
'nama' => 'Kondisi Ekonomi Rumah Tangga',
'short' => 'Ekonomi',
'dimensi' => 'D4',
'bobot' => 20,
'icon' => 'tabler-home-dollar',
'skor' => $this->normalizeScore($skorPetani->skor_komp_2_d4_k2_ekonomi_rumah_tangga),
],
[
'key' => 'gap',
'nama' => 'Praktik Budidaya & GAP',
'short' => 'Budidaya / GAP',
'dimensi' => 'D2',
'bobot' => 20,
'icon' => 'tabler-plant-2',
'skor' => $this->normalizeScore($skorPetani->skor_komp_3_d2_praktik_budidaya_gap),
],
[
'key' => 'kelembagaan',
'nama' => 'Keterlibatan Kelembagaan',
'short' => 'Kelembagaan',
'dimensi' => 'D4',
'bobot' => 15,
'icon' => 'tabler-users-group',
'skor' => $this->normalizeScore($skorPetani->skor_komp_4_d4_k4_keterlibatan_kelembagaan),
],
[
'key' => 'keuangan',
'nama' => 'Akses & Kebebasan Keuangan',
'short' => 'Keuangan',
'dimensi' => 'D4',
'bobot' => 10,
'icon' => 'tabler-building-bank',
'skor' => $this->normalizeScore($skorPetani->skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan),
],
[
'key' => 'pasar',
'nama' => 'Rantai Nilai & Akses Pasar',
'short' => 'Akses Pasar',
'dimensi' => 'D6',
'bobot' => 10,
'icon' => 'tabler-building-store',
'skor' => $this->normalizeScore($skorPetani->skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar),
],
]);
$availableComponents = $components
->filter(fn ($item) => $item['skor'] !== null)
->values();
$strengths = $availableComponents
->sortByDesc('skor')
->take(2)
->values();
$barriers = $availableComponents
->filter(fn ($item) => $item['skor'] < 3)
->sortBy('skor')
->values();
$specialPattern = $this->detectSpecialPattern(
$segmen,
$dimensions,
$skorPetani
);
$title = $this->buildProfileTitle(
$segmen,
$specialPattern,
$barriers
);
$narrative = $this->buildNarrative(
$segmen,
$specialPattern,
$strengths,
$barriers
);
$recommendations = $this->buildRecommendations(
$specialPattern,
$barriers
);
return [
'skor_akhir' => $skorAkhir,
'segmen' => $segmen,
'title' => $title,
'dimensions' => $dimensions,
'components' => $components,
'strengths' => $strengths,
'barriers' => $barriers,
'special_pattern' => $specialPattern,
'narrative' => $narrative,
'recommendations' => $recommendations,
];
}
private function normalizeScore($score): ?float
{
if ($score === null || $score === '') {
return null;
}
$score = (float) $score;
if ($score <= 0) {
return null;
}
return $score;
}
private function getSegmen(?float $score): string
{
if ($score === null) {
return 'Belum Dinilai';
}
return match (true) {
$score >= 4.0 => 'Penggerak',
$score >= 3.0 => 'Perintis',
$score >= 2.0 => 'Pemerhati',
default => 'Pemula',
};
}
private function getDimensionLevel(?float $score): string
{
if ($score === null) {
return 'belum_dinilai';
}
if ($score <= self::DIMENSION_LOW_MAX) {
return 'rendah';
}
if ($score <= self::DIMENSION_MEDIUM_MAX) {
return 'sedang';
}
return 'tinggi';
}
private function detectSpecialPattern(
string $segmen,
array $dimensions,
SkorPetani $skorPetani
): ?array {
$d2 = $dimensions['d2']['level'];
$d4 = $dimensions['d4']['level'];
$d6 = $dimensions['d6']['level'];
if (
$segmen === 'Perintis' &&
$d4 === 'tinggi' &&
$d2 === 'rendah' &&
$d6 === 'sedang'
) {
return [
'kode' => 'perintis_teknis',
'nama' => 'Perintis dengan Hambatan Teknis',
'prioritas' => 'gap',
];
}
if (
$segmen === 'Perintis' &&
$d4 === 'tinggi' &&
in_array($d2, ['sedang', 'tinggi']) && $d6 === 'rendah'
) {
return [
'kode' => 'perintis_pasar',
'nama' => 'Perintis dengan Hambatan Pasar',
'prioritas' => 'pasar',
];
}
if (
$segmen === 'Pemerhati' &&
$d4 === 'sedang' &&
$d2 === 'rendah' &&
$d6 === 'sedang'
) {
return [
'kode' => 'pemerhati_teknis',
'nama' => 'Pemerhati Teknis',
'prioritas' => 'gap',
];
}
if (
$segmen === 'Pemula' &&
$d4 === 'rendah' &&
$d2 === 'rendah' &&
$d6 === 'rendah'
) {
return [
'kode' => 'pemula_struktural',
'nama' => 'Pemula Struktural',
'prioritas' => 'struktural',
];
}
return null;
}
private function buildProfileTitle(
string $segmen,
?array $specialPattern,
$barriers
): string {
if ($specialPattern) {
return $specialPattern['nama'];
}
if ($barriers->isNotEmpty()) {
$mainBarrier = $barriers->first();
return $segmen . ' dengan Prioritas ' . $mainBarrier['short'];
}
return $segmen . ' dengan Profil Relatif Seimbang';
}
private function buildNarrative(
string $segmen,
?array $specialPattern,
$strengths,
$barriers
): string {
if ($specialPattern) {
return match ($specialPattern['kode']) {
'perintis_teknis' =>
'Petani memiliki fondasi sosial-ekonomi yang relatif siap '
. 'untuk berkembang, tetapi penerapannya belum sepenuhnya '
. 'tercermin dalam praktik budidaya. Hambatan utama berada '
. 'pada aspek teknis di lapangan.',
'perintis_pasar' =>
'Petani memiliki fondasi sosial-ekonomi dan kesiapan '
. 'budidaya yang relatif baik, tetapi manfaat ekonominya '
. 'masih dibatasi oleh rantai nilai dan akses pasar.',
'pemerhati_teknis' =>
'Petani telah memiliki sebagian fondasi untuk berkembang, '
. 'namun praktik budidaya masih menjadi hambatan utama. '
. 'Pendekatan berbasis demonstrasi hasil nyata akan lebih '
. 'relevan sebelum intervensi teknis yang lebih lanjut.',
'pemula_struktural' =>
'Petani menghadapi hambatan pada beberapa dimensi sekaligus. '
. 'Kondisi sosial-ekonomi, praktik budidaya, serta akses '
. 'pasar perlu dibaca bersama untuk menentukan hambatan '
. 'mendasar yang paling mendesak.',
default =>
$this->buildGenericNarrative($segmen, $strengths, $barriers),
};
}
return $this->buildGenericNarrative($segmen, $strengths, $barriers);
}
private function buildGenericNarrative(
string $segmen,
$strengths,
$barriers
): string {
$text = 'Petani berada pada segmen ' . $segmen . '. ';
if ($strengths->isNotEmpty()) {
$strengthNames = $strengths->pluck('nama')->implode(' dan ');
$text .= 'Kekuatan relatif terlihat pada ' . $strengthNames . '. ';
}
if ($barriers->isNotEmpty()) {
$barrierNames = $barriers->take(3)->pluck('nama')->implode(', ');
$text .=
'Area yang masih memerlukan perhatian terutama pada ' . $barrierNames . '. Prioritas intervensi sebaiknya mengikuti ' . 'hambatan dengan skor paling rendah.';
} else {
$text .= 'Tidak terdapat komponen dengan skor rendah yang ' . 'menonjol. Pendampingan dapat difokuskan pada ' . 'pemeliharaan dan penguatan capaian yang sudah ada.';
}
return $text;
}
private function buildRecommendations(
?array $specialPattern,
$barriers
): array {
if ($specialPattern) {
$specialRecommendation = match ($specialPattern['kode']) {
'perintis_teknis' => [
'Prioritaskan pendampingan GAP langsung di lapangan.',
'Perkuat koneksi petani terhadap sumber input dan pelatihan teknis.',
],
'perintis_pasar' => [
'Perkuat koneksi ke saluran pasar yang lebih baik.',
'Fasilitasi akses pembeli, negosiasi, atau penguatan koperasi.',
],
'pemerhati_teknis' => [
'Gunakan demonstrasi lapangan untuk menunjukkan hasil nyata.',
'Lakukan pendampingan teknis secara bertahap sebelum pelatihan formal.',
],
'pemula_struktural' => [
'Identifikasi hambatan dasar seperti lahan, hutang, atau logistik.',
'Tangani hambatan struktural sebelum mendorong adopsi praktik baru.',
],
default => [],
};
if (!empty($specialRecommendation)) {
return $specialRecommendation;
}
}
$recommendationMap = [
'motivasi' => 'Gunakan demonstrasi hasil nyata, role model, dan pendekatan perubahan secara bertahap.',
'ekonomi' => 'Perkuat ruang gerak ekonomi rumah tangga sebelum mendorong investasi atau perubahan praktik yang berisiko.',
'gap' => 'Prioritaskan pendampingan praktik budidaya dan GAP langsung di kebun.',
'kelembagaan' => 'Perkuat keterlibatan petani dalam kelompok tani sebagai ruang belajar dan penguatan posisi tawar.',
'keuangan' => 'Tinjau akses keuangan formal serta kemungkinan ikatan hutang panen atau ijon yang membatasi ruang gerak petani.',
'pasar' => 'Perkuat koneksi dengan pembeli dan saluran pasar alternatif serta kemampuan negosiasi petani.',
];
return $barriers->take(3)->map(
fn ($item) =>
$recommendationMap[$item['key']] ?? null
)->filter()->values()->all();
}
}
@@ -398,15 +398,17 @@ class SosialEkonomiController extends Controller
}
if ($section === 'keanggotaan_kelompok') {
$terdaftarKelompokTani = $request->input('terdaftar_kelompok_tani') === TerdaftarKelompokTani::YA->value;
$rules = array_merge($rules, [
'terdaftar_kelompok_tani' => ['nullable', 'string', Rule::in(TerdaftarKelompokTani::values())],
'nama_kelompok_tani' => ['required_if:terdaftar_kelompok_tani,' . TerdaftarKelompokTani::YA->value, 'nullable', 'string', 'max:255'],
'lama_bergabung_kelompok_tahun' => ['required_if:terdaftar_kelompok_tani,' . TerdaftarKelompokTani::YA->value, 'nullable', 'integer', 'min:0'],
'kedekatan_sesama_anggota' => ['required_if:terdaftar_kelompok_tani,' . TerdaftarKelompokTani::YA->value, 'nullable', 'string', Rule::in(KedekatanSesamaAnggota::values())],
'keaktifan_pertemuan_kelompok' => ['required', 'integer', Rule::in(KeaktifanPertemuanKelompok::values())],
'topik_biasa_dibahas' => ['required', 'string'],
'peran_dalam_kelompok' => ['required', 'integer', Rule::in(PeranDalamKelompok::values())],
'manfaat_kelompok_tani' => ['required', 'integer', Rule::in(ManfaatKelompokTani::values())],
'keaktifan_pertemuan_kelompok' => [Rule::requiredIf($terdaftarKelompokTani), 'nullable', 'integer', Rule::in(KeaktifanPertemuanKelompok::values())],
'topik_biasa_dibahas' => [Rule::requiredIf($terdaftarKelompokTani), 'nullable', 'string'],
'peran_dalam_kelompok' => [Rule::requiredIf($terdaftarKelompokTani), 'nullable', 'integer', Rule::in(PeranDalamKelompok::values())],
'manfaat_kelompok_tani' => [Rule::requiredIf($terdaftarKelompokTani), 'nullable', 'integer', Rule::in(ManfaatKelompokTani::values())],
'status_kartu_tani' => ['nullable', 'string', Rule::in(StatusKartuTani::values())],
'bisa_beli_pupuk_bersubsidi' => ['nullable', 'string', Rule::in(BisaBeliPupukBersubsidi::values())],
'manfaat_lain_kartu_tani' => ['nullable', 'string'],
@@ -633,6 +635,10 @@ class SosialEkonomiController extends Controller
$payload['nama_kelompok_tani'] = null;
$payload['lama_bergabung_kelompok_tahun'] = null;
$payload['kedekatan_sesama_anggota'] = null;
$payload['keaktifan_pertemuan_kelompok'] = KeaktifanPertemuanKelompok::TIDAK_PERNAH_HADIR->value;
$payload['topik_biasa_dibahas'] = null;
$payload['peran_dalam_kelompok'] = PeranDalamKelompok::ANGGOTA_PASIF->value;
$payload['manfaat_kelompok_tani'] = ManfaatKelompokTani::TIDAK_ADA_MANFAAT->value;
}
if (
@@ -976,8 +982,11 @@ class SosialEkonomiController extends Controller
'terdaftarKelompokTaniTidakValue' => TerdaftarKelompokTani::TIDAK->value,
'kedekatanSesamaAnggotaOptions' => KedekatanSesamaAnggota::options(),
'keaktifanPertemuanKelompokOptions' => KeaktifanPertemuanKelompok::options(),
'keaktifanPertemuanKelompokLowestValue' => KeaktifanPertemuanKelompok::TIDAK_PERNAH_HADIR->value,
'peranDalamKelompokOptions' => PeranDalamKelompok::options(),
'peranDalamKelompokLowestValue' => PeranDalamKelompok::ANGGOTA_PASIF->value,
'manfaatKelompokTaniOptions' => ManfaatKelompokTani::options(),
'manfaatKelompokTaniLowestValue' => ManfaatKelompokTani::TIDAK_ADA_MANFAAT->value,
'statusKartuTaniOptions' => StatusKartuTani::options(),
'bisaBeliPupukBersubsidiOptions' => BisaBeliPupukBersubsidi::options(),
'statusRekeningTabunganOptions' => StatusRekeningTabungan::options(),
@@ -0,0 +1,346 @@
<?php
namespace App\Http\Controllers\Web\Produktivitas;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Str;
use App\Models\Pertanian\KelompokTani;
use App\Models\Wilayah\Provinsi;
use App\Models\Pertanian\Komoditas;
class SurveyKelompokTaniController extends Controller
{
private function authorizeAccess(): void
{
if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) {
abort(403);
}
}
private function redirectToSection(string $url, string $section, string $message)
{
return redirect($url . '#section-' . $section)->with([
'success' => $message,
'success_section' => $section,
]);
}
public function index(Request $request)
{
$kelompokTani = KelompokTani::query()
->when($request->search, fn ($query, $search) => $query->where('nama_kelompok', 'like', "%{$search}%"))
->latest()
->paginate($request->per_page ?? 10)
->appends($request->query());
return view('produktivitas.survey-kelompok-tani.index', compact('kelompokTani'));
}
public function create()
{
$this->authorizeAccess();
$provinsi = Provinsi::orderBy('kode', 'asc')->get();
$komoditas = Komoditas::where('is_utama', true)->get();
return view('produktivitas.survey-kelompok-tani.add', compact('provinsi', 'komoditas'));
}
public function store(Request $request)
{
$this->authorizeAccess();
$validated = $this->validateIdentitas($request);
if (($validated['jenis_kelompok'] ?? null) === 'Lainnya') {
$validated['jenis_kelompok'] = $validated['jenis_kelompok_lainnya'];
}
unset($validated['jenis_kelompok_lainnya']);
$kelompokTani = KelompokTani::create([
...$validated,
'uid' => 'KLP-' . strtoupper(Str::random(10)),
'created_by' => auth()->id(),
'updated_by' => auth()->id(),
]);
return $this->redirectToSection(route('kelompok-tani.edit', $kelompokTani->id), 'identitas', 'Data kelompok tani berhasil ditambahkan.');
}
private function editUrl(KelompokTani $kelompokTani, string $section = 'identitas'): string
{
$url = route('kelompok-tani.edit', $kelompokTani->id);
return $section === 'identitas' ? $url : $url . '?section=' . $section;
}
public function edit(Request $request, KelompokTani $kelompokTani)
{
$this->authorizeAccess();
return match ($request->query('section', 'identitas')) {
'kelembagaan' => view('produktivitas.survey-kelompok-tani.kelembagaan', compact('kelompokTani')),
'aktivitas-fungsi' => view('produktivitas.survey-kelompok-tani.aktivitas-fungsi', compact('kelompokTani')),
'sosial-konflik' => view('produktivitas.survey-kelompok-tani.sosial-konflik', compact('kelompokTani')),
default => view('produktivitas.survey-kelompok-tani.edit', [
'kelompokTani' => $kelompokTani,
'provinsi' => Provinsi::orderBy('kode', 'asc')->get(),
'komoditas' => Komoditas::where('is_utama', true)->get(),
]),
};
}
public function update(Request $request, KelompokTani $kelompokTani)
{
$this->authorizeAccess();
return match ($request->input('section', 'identitas')) {
'ringkasan-pengurus' => $this->updateRingkasanPengurus($request, $kelompokTani),
'kelembagaan' => $this->updateKelembagaan($request, $kelompokTani),
'aktivitas-fungsi' => $this->updateAktivitasFungsi($request, $kelompokTani),
'kas' => $this->updateKasSimpanPinjam($request, $kelompokTani),
'sosial-konflik' => $this->updateSosialKonflik($request, $kelompokTani),
'status-bantuan' => $this->updateStatusBantuan($request, $kelompokTani),
'penilaian' => $this->updatePenilaian($request, $kelompokTani),
default => $this->updateIdentitas($request, $kelompokTani),
};
}
public function destroy(string $id)
{
$this->authorizeAccess();
$kelompokTani = KelompokTani::findOrFail($id);
$kelompokTani->update(['deleted_by' => auth()->id()]);
$kelompokTani->delete();
return response()->json(['message' => 'Data kelompok tani berhasil dihapus.']);
}
private function validateIdentitas(Request $request)
{
return $request->validate([
// Data Responden
'nama_responden' => ['required', 'string', 'max:255'],
'jabatan_responden' => ['nullable', 'string', 'max:255'],
'kontak_responden' => ['nullable', 'string', 'max:20'],
// Identitas Kelompok Tani
'nama_kelompok' => ['required', 'string', 'max:255'],
'desa_kelurahan_id' => ['required', 'exists:master_desa_kelurahan,id'],
'dusun' => ['nullable', 'string', 'max:255'],
'tahun_berdiri' => ['nullable', 'digits:4', 'integer', 'min:1900', 'max:' . date('Y')],
'jenis_kelompok' => ['required', 'string', 'max:50'],
'jenis_kelompok_lainnya' => ['required_if:jenis_kelompok,Lainnya', 'nullable', 'string', 'max:255'],
'nama_gapoktan' => ['nullable', 'string', 'max:255'],
'komoditas_id' => ['nullable', 'array'],
'komoditas_id.*' => ['exists:master_komoditas,id'],
], [
'nama_responden.required' => 'Nama responden wajib diisi.',
'nama_kelompok.required' => 'Nama kelompok wajib diisi.',
'desa_kelurahan_id.required' => 'Desa/Kelurahan wajib dipilih.',
'desa_kelurahan_id.exists' => 'Desa/Kelurahan tidak ditemukan.',
'jenis_kelompok.required' => 'Jenis kelompok wajib dipilih.',
'jenis_kelompok_lainnya.required_if' => 'Sebutkan jenis kelompok lainnya.',
'tahun_berdiri.digits' => 'Tahun berdiri harus 4 digit.',
]);
}
private function updateIdentitas(Request $request, KelompokTani $kelompokTani)
{
$validated = $this->validateIdentitas($request);
if (($validated['jenis_kelompok'] ?? null) === 'Lainnya') {
$validated['jenis_kelompok'] = $validated['jenis_kelompok_lainnya'];
}
unset($validated['jenis_kelompok_lainnya']);
$kelompokTani->update([
...$validated,
'updated_by' => auth()->id(),
]);
return $this->redirectToSection(route('kelompok-tani.edit', $kelompokTani->id), 'identitas', 'Data kelompok tani berhasil diperbarui.');
}
private function updateRingkasanPengurus(Request $request, KelompokTani $kelompokTani)
{
$validated = $request->validate([
'jumlah_pengurus' => ['nullable', 'integer', 'min:0'],
'jumlah_pengurus_aktif' => ['nullable', 'integer', 'min:0'],
'jumlah_anggota_terdaftar' => ['nullable', 'integer', 'min:0'],
'jumlah_anggota_aktif' => ['nullable', 'integer', 'min:0'],
'jumlah_pengurus_laki_laki' => ['nullable', 'integer', 'min:0'],
'jumlah_pengurus_perempuan' => ['nullable', 'integer', 'min:0'],
'jumlah_anggota_laki_laki' => ['nullable', 'integer', 'min:0'],
'jumlah_anggota_perempuan' => ['nullable', 'integer', 'min:0'],
'jumlah_anggota_pemuda_laki_laki' => ['nullable', 'integer', 'min:0'],
'jumlah_anggota_pemuda_perempuan' => ['nullable', 'integer', 'min:0'],
]);
$kelompokTani->update([
...$validated,
'updated_by' => auth()->id(),
]);
return $this->redirectToSection(route('kelompok-tani.pengurus-anggota.index', $kelompokTani->id), 'ringkasan', 'Ringkasan pengurus & anggota berhasil disimpan.');
}
private function updateKelembagaan(Request $request, KelompokTani $kelompokTani)
{
$validated = $request->validate([
// Cakupan Wilayah Kelompok
'cakupan_wilayah' => ['nullable', 'string', 'max:50'],
'nama_wilayah_cakupan' => ['nullable', 'string'],
// Status Legalitas Kelompok
'status_legalitas' => ['nullable', 'string', 'max:50'],
'nomor_sk' => ['nullable', 'string', 'max:100'],
'tanggal_tahun_penerbitan_sk' => ['nullable', 'string', 'max:30'],
// Kualitas Kepemimpinan
'tingkat_keaktifan_ketua' => ['nullable', 'string', 'max:30'],
'status_pembagian_peran' => ['nullable', 'string', 'max:30'],
'status_dokumentasi_rapat' => ['nullable', 'string', 'max:30'],
// Frekuensi Pertemuan Rutin
'frekuensi_pertemuan' => ['nullable', 'string', 'max:50'],
'tanggal_pertemuan_terakhir' => ['nullable', 'date'],
]);
$kelompokTani->update([
...$validated,
'updated_by' => auth()->id(),
]);
return $this->redirectToSection($this->editUrl($kelompokTani, 'kelembagaan'), 'kelembagaan', 'Data kelembagaan berhasil disimpan.');
}
private function resolveLainnya(?array $selected, ?string $lainnyaText): ?array
{
if (empty($selected)) {
return $selected;
}
return array_values(array_map(function ($item) use ($lainnyaText) {
return $item === 'Lainnya' && filled($lainnyaText) ? $lainnyaText : $item;
}, $selected));
}
private function updateAktivitasFungsi(Request $request, KelompokTani $kelompokTani)
{
$validated = $request->validate([
// Kegiatan Konkret yang Sudah Berjalan
'kegiatan_terlaksana' => ['nullable', 'array'],
'kegiatan_terlaksana.*' => ['string', 'max:255'],
'kegiatan_terlaksana_lainnya' => ['nullable', 'string', 'max:255'],
'estimasi_panen_minimal' => ['nullable', 'numeric', 'min:0'],
'estimasi_panen_maksimal' => ['nullable', 'numeric', 'min:0', 'gte:estimasi_panen_minimal'],
'satuan_hasil_panen' => ['nullable', 'string', 'max:20'],
'tindakan_hasil_panen' => ['nullable', 'array'],
'tindakan_hasil_panen.*' => ['string', 'max:255'],
// Peran dan Fungsi Kelompok
'fungsi_kelompok_bagi_anggota' => ['nullable', 'array'],
'fungsi_kelompok_bagi_anggota.*' => ['string', 'max:255'],
'fungsi_kelompok_lainnya' => ['nullable', 'string', 'max:255'],
], [
'estimasi_panen_maksimal.gte' => 'Estimasi panen maksimal tidak boleh kurang dari estimasi minimal.',
]);
$validated['kegiatan_terlaksana'] = $this->resolveLainnya(
$validated['kegiatan_terlaksana'] ?? null,
$validated['kegiatan_terlaksana_lainnya'] ?? null
);
unset($validated['kegiatan_terlaksana_lainnya']);
$validated['fungsi_kelompok_bagi_anggota'] = $this->resolveLainnya(
$validated['fungsi_kelompok_bagi_anggota'] ?? null,
$validated['fungsi_kelompok_lainnya'] ?? null
);
unset($validated['fungsi_kelompok_lainnya']);
$kelompokTani->update([
...$validated,
'updated_by' => auth()->id(),
]);
return $this->redirectToSection($this->editUrl($kelompokTani, 'aktivitas-fungsi'), 'aktivitas-fungsi', 'Data aktivitas & fungsi kelompok berhasil disimpan.');
}
private function updateKasSimpanPinjam(Request $request, KelompokTani $kelompokTani)
{
$validated = $request->validate([
'pembukuan_kas' => ['nullable', 'string', 'max:50'],
'pengelola_kas' => ['nullable', 'string', 'max:255'],
'masalah_pengelolaan_kas_simpan_pinjam' => ['nullable', 'string', 'max:255'],
'deskripsi_masalah_pengelolaan_kas_simpan_pinjam' => ['nullable', 'string'],
]);
$kelompokTani->update([
...$validated,
'updated_by' => auth()->id(),
]);
return $this->redirectToSection(route('kelompok-tani.aset-keuangan.index', $kelompokTani->id), 'kas', 'Data kas/simpan-pinjam berhasil disimpan.');
}
private function updateSosialKonflik(Request $request, KelompokTani $kelompokTani)
{
$validated = $request->validate([
// Keterlibatan Perempuan
'partisipasi_perempuan' => ['nullable', 'string', 'max:255'],
// Riwayat Konflik Internal Kelompok
'konflik_kelompok' => ['nullable', 'string', 'max:255'],
'topik_konflik' => ['nullable', 'string', 'max:255'],
'penyelesaian_konflik' => ['nullable', 'string'],
]);
if (!in_array($validated['konflik_kelompok'] ?? null, ['Pernah, sudah selesai', 'Pernah, masih berlanjut/belum selesai'])) {
$validated['topik_konflik'] = null;
$validated['penyelesaian_konflik'] = null;
}
$kelompokTani->update([
...$validated,
'updated_by' => auth()->id(),
]);
return $this->redirectToSection($this->editUrl($kelompokTani, 'sosial-konflik'), 'sosial-konflik', 'Data sosial & konflik berhasil disimpan.');
}
private function updateStatusBantuan(Request $request, KelompokTani $kelompokTani)
{
$validated = $request->validate([
'pernah_mendapatkan_bantuan' => ['required', 'boolean'],
]);
$kelompokTani->update([
...$validated,
'updated_by' => auth()->id(),
]);
return $this->redirectToSection(route('kelompok-tani.bantuan-penilaian.index', $kelompokTani->id), 'status-bantuan', 'Status akses bantuan berhasil disimpan.');
}
private function updatePenilaian(Request $request, KelompokTani $kelompokTani)
{
$validated = $request->validate([
'potensi_kelompok' => ['nullable', 'string', 'max:50'],
'alasan_penilaian_potensi' => ['nullable', 'string'],
]);
$kelompokTani->update([
...$validated,
'updated_by' => auth()->id(),
]);
return $this->redirectToSection(route('kelompok-tani.bantuan-penilaian.index', $kelompokTani->id), 'penilaian', 'Penilaian potensi kelompok berhasil disimpan.');
}
}
@@ -3,26 +3,43 @@
namespace App\Http\Controllers\Web\Produktivitas;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use App\Models\Pertanian\Petani;
use App\Models\Pertanian\SurveyProduktivitas;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
class SurveyProduktivitasController extends Controller
{
public function store($petaniId, Request $request)
{
$petani = Petani::findOrFail($petaniId);
$validated = $request->validate([
'produktivitas_komoditas' => ['required', 'array'],
'produktivitas_komoditas.*.komoditas_id' => ['nullable', 'exists:master_komoditas,id'],
'produktivitas_komoditas.*.hasil_panen_3_musim' => ['nullable', 'numeric'],
'produktivitas_komoditas.*.satuan' => ['nullable', 'string'],
$validator = Validator::make($request->all(), [
'produktivitas_komoditas' => ['required', 'array', 'min:1'],
'produktivitas_komoditas.*.komoditas_id' => ['required', 'exists:master_komoditas,id'],
'produktivitas_komoditas.*.hasil_panen_3_musim' => ['required', 'numeric', 'min:0'],
'produktivitas_komoditas.*.satuan' => ['required', 'in:ha_tahun,pohon_tahun'],
], [
'produktivitas_komoditas.required' => 'Minimal satu data produktivitas harus diisi.',
'produktivitas_komoditas.*.komoditas_id.required' => 'Komoditas wajib dipilih.',
'produktivitas_komoditas.*.komoditas_id.exists' => 'Komoditas yang dipilih tidak valid.',
'produktivitas_komoditas.*.hasil_panen_3_musim.required' => 'Hasil panen wajib diisi.',
'produktivitas_komoditas.*.hasil_panen_3_musim.numeric' => 'Hasil panen harus berupa angka.',
'produktivitas_komoditas.*.hasil_panen_3_musim.min' => 'Hasil panen tidak boleh kurang dari 0.',
'produktivitas_komoditas.*.satuan.required' => 'Satuan wajib dipilih.',
'produktivitas_komoditas.*.satuan.in' => 'Satuan yang dipilih tidak valid.',
]);
if ($validator->fails()) {
return $this->redirectBackToFragment($request)->withErrors($validator)->withInput();
}
$validated = $validator->validated();
foreach ($validated['produktivitas_komoditas'] as $row) {
SurveyProduktivitas::create([
'uid' => 'SPV-' . strtoupper(Str::random(10)),
'uid' => 'SPV-'.strtoupper(Str::random(10)),
'petani_id' => $petani->id,
'komoditas_id' => $row['komoditas_id'],
'kuantitas' => $row['hasil_panen_3_musim'],
@@ -51,10 +68,10 @@ class SurveyProduktivitasController extends Controller
{
$fragment = $request->input('redirect_fragment');
if (!is_string($fragment) || !preg_match('/^[A-Za-z0-9_-]+$/', $fragment)) {
if (! is_string($fragment) || ! preg_match('/^[A-Za-z0-9_-]+$/', $fragment)) {
return back();
}
return redirect()->to(Str::before(url()->previous(), '#') . '#' . $fragment);
return redirect()->to(Str::before(url()->previous(), '#').'#'.$fragment);
}
}
@@ -0,0 +1,71 @@
<?php
namespace App\Models\Bumdes;
use App\Models\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
class KelembagaanAktorBumdes extends Model
{
use SoftDeletes;
protected $table = 'bumdes_kelembagaan_aktor';
protected $fillable = [
'pengurus_bumdes_id',
'status_badan_hukum',
'nomor_dasar_hukum',
'tahun_dasar_hukum',
'status_keaktifan',
'alasan_tidak_aktif',
'unit_usaha',
'unit_usaha_jasa_lainnya',
'status_unit_komoditas',
'nama_unit_komoditas',
'status_ad_art',
'tahun_ad_art',
'pengurus_inti',
'memiliki_staf',
'jumlah_staf',
'unit_usaha_staf',
'modal_awal',
'tahun_modal_awal',
'pernah_penambahan_modal',
'penambahan_modal',
'aset_produktif',
'aset_produktif_lainnya',
'status_kepemilikan_aset',
'infrastruktur_pascapanen',
'infrastruktur_pascapanen_lainnya',
'created_by',
'updated_by',
'deleted_by',
];
protected $casts = [
'tahun_dasar_hukum' => 'integer',
'tahun_ad_art' => 'integer',
'unit_usaha' => 'array',
'pengurus_inti' => 'array',
'memiliki_staf' => 'boolean',
'jumlah_staf' => 'integer',
'modal_awal' => 'decimal:2',
'tahun_modal_awal' => 'integer',
'pernah_penambahan_modal' => 'boolean',
'penambahan_modal' => 'array',
'aset_produktif' => 'array',
'infrastruktur_pascapanen' => 'array',
];
public function pengurusBumdes(): BelongsTo
{
return $this->belongsTo(PengurusBumdes::class, 'pengurus_bumdes_id');
}
public function creator(): BelongsTo
{
return $this->belongsTo(User::class, 'created_by');
}
}
+114
View File
@@ -0,0 +1,114 @@
<?php
namespace App\Models\Bumdes;
use App\Enums\Bumdes\JabatanBumdes;
use App\Enums\Pendidikan;
use App\Models\User;
use App\Models\Wilayah\DesaKelurahan;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\SoftDeletes;
class PengurusBumdes extends Model
{
use SoftDeletes;
protected $table = 'bumdes_pengurus';
protected $fillable = [
'uid',
'nama',
'jenis_kelamin',
'tempat_lahir',
'tanggal_lahir',
'pendidikan_terakhir',
'alamat',
'desa_kelurahan_id',
'nomor_telepon',
'jabatan',
'jabatan_lainnya',
'lama_menjabat_tahun',
'tanggal_mulai_menjabat',
'created_by',
'updated_by',
'deleted_by',
];
protected $casts = [
'jenis_kelamin' => 'boolean',
'tanggal_lahir' => 'date',
'pendidikan_terakhir' => Pendidikan::class,
'tanggal_mulai_menjabat' => 'date',
'jabatan' => JabatanBumdes::class,
];
public function getUsiaAttribute(): ?int
{
if (! $this->tanggal_lahir) {
return null;
}
return Carbon::parse($this->tanggal_lahir)->age;
}
public function getLamaMenjabatAttribute(): string
{
if (! is_null($this->lama_menjabat_tahun)) {
return $this->lama_menjabat_tahun . ' tahun';
}
if (! $this->tanggal_mulai_menjabat) {
return '-';
}
$tanggalMulai = Carbon::parse($this->tanggal_mulai_menjabat)->startOfDay();
if ($tanggalMulai->isFuture()) {
return 'Belum mulai';
}
$selisih = $tanggalMulai->diff(Carbon::now());
$bagian = [];
if ($selisih->y > 0) {
$bagian[] = $selisih->y . ' tahun';
}
if ($selisih->m > 0) {
$bagian[] = $selisih->m . ' bulan';
}
if (empty($bagian)) {
return $selisih->d . ' hari';
}
return implode(' ', $bagian);
}
public function getNamaJabatanAttribute(): string
{
if ($this->jabatan === JabatanBumdes::LAINNYA && $this->jabatan_lainnya) {
return $this->jabatan_lainnya;
}
return $this->jabatan?->label() ?? '-';
}
public function desaKelurahan(): BelongsTo
{
return $this->belongsTo(DesaKelurahan::class, 'desa_kelurahan_id');
}
public function creator(): BelongsTo
{
return $this->belongsTo(User::class, 'created_by');
}
public function kelembagaanAktor(): HasOne
{
return $this->hasOne(KelembagaanAktorBumdes::class, 'pengurus_bumdes_id');
}
}
-1
View File
@@ -56,7 +56,6 @@ class FormBasisData extends Model
public function form(): HasMany
{
return $this->hasMany(FormBasisData::class, 'parent_id')
->with('form')
->orderBy('urutan');
}
+65
View File
@@ -0,0 +1,65 @@
<?php
namespace App\Models\Koperasi;
use Illuminate\Database\Eloquent\Model;
class PengurusKoperasi extends Model
{
protected $table = 'pengurus_koperasi';
protected $fillable = [
// Profil Dassar
'nama_lengkap', 'posisi_dalam_koperasi', 'tahun_bergabung',
'no_hp', 'alamat_tinggal',
// Profil Koperasi
'nama_koperasi', 'jenis_koperasi', 'alamat_koperasi',
'skala_operasi', 'tahun_berdiri',
// Anggota & Pengurus
'jumlah_anggota_awal', 'jumlah_anggota_dewasa', 'jumlah_anggota_anak', 'jumlah_pengurus',
// SHU
'shu_2025', 'shu_2024', 'shu_2023',
// Kelembagaan & Manajemen
'sejarah_lembaga', 'fokus_komoditas', 'detail_fokus_komoditas',
'ad_art', 'tahun_ad_art', 'layanan_koperasi', 'layanan_lainnya',
'pelatihan_produksi', 'pelatihan_pascapanen', 'pelatihan_pengolahan',
'pelatihan_keuangan', 'pelatihan_pemasaran', 'pelatihan_lainnya',
'status_pembukuan', 'format_pembukuan', 'pertemuan_rutin', 'pertemuan_lainnya',
'kasus_kredit_macet', 'sanksi_kredit_macet', 'efektivitas_sanksi',
'faktor_manajemen', 'faktor_manajemen_lainnya', 'keterlibatan_rantai_nilai',
'agregasi_komoditas', 'agregasi_komoditas_lainnya', 'fasilitas_koperasi', 'fasilitas_lainnya',
'pengolahan_lanjutan', 'detail_pengolahan_lanjutan', 'cara_penentuan_harga',
'kontrak_offtaker', 'kontrak_komoditas',
// Akses Pasar & Rantai Nilai Eksternal
'sumber_pasokan', 'sumber_pasokan_lainnya', 'bentuk_pembelian',
'volume_beli_sekarang', 'volume_beli_1_tahun', 'volume_beli_2_tahun',
'tujuan_penjualan', 'tujuan_penjualan_lainnya', 'bentuk_penjualan',
'volume_jual_sekarang', 'volume_jual_1_tahun', 'volume_jual_2_tahun',
'sifat_hubungan_bisnis', 'sifat_hubungan_lainnya', 'mekanisme_pembayaran', 'status_perjanjian_tertulis',
// Harga Komoditas
'harga_segar_sekarang', 'harga_segar_1_tahun', 'harga_segar_2_tahun',
'harga_basah_sekarang', 'harga_basah_1_tahun', 'harga_basah_2_tahun',
'harga_kering_sekarang', 'harga_kering_1_tahun', 'harga_kering_2_tahun',
'harga_fermentasi_sekarang', 'harga_fermentasi_1_tahun', 'harga_fermentasi_2_tahun',
'cara_menetapkan_harga_pasar', 'cara_menetapkan_harga_lainnya',
// Praktik Kualitas & Pascapanen
'praktik_sortasi', 'standar_sortasi', 'praktik_pengeringan', 'cara_pengeringan',
'praktik_fermentasi', 'model_fermentasi', 'proses_fermentasi',
'harga_premium_rupiah', 'harga_premium_persen',
// Sosial Ekonomi
'simpanan_terbesar', 'momen_simpanan_terbesar',
'alasan_pinjaman', 'alasan_pinjaman_lainnya', 'pembayaran_selain_uang',
'bentuk_pembayaran_barang', 'bentuk_pembayaran_lainnya', 'perhitungan_harga_pasar', 'alasan_bukan_harga_pasar',
// PENILAIAN ENUMERATOR
'enum_potensi', 'enum_alasan_potensi', 'enum_kebutuhan', 'enum_kebutuhan_lain', 'enum_keterbukaan'
];
}
+2
View File
@@ -31,6 +31,8 @@ class AksesPasar extends Model
'model_fermentasi_memungkinkan',
'skor_kesadaran_premium',
'sumber_info_premium',
'tingkat_kepercayaan_pembeli_baru',
'alasan_kepercayaan_pembeli_baru',
'waktu_mulai_wawancara',
'waktu_selesai_wawancara',
'skor_kepercayaan_responden',
+37
View File
@@ -0,0 +1,37 @@
<?php
namespace App\Models\Pertanian;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class AsetKelompokTani extends Model
{
use HasFactory, SoftDeletes;
protected $table = 'survey_aset_kelompok_tani';
protected $fillable = [
'uid',
'survey_kelompok_tani_id',
'jenis_aset',
'status_aset',
'status_pengelolaan_aset',
'kondisi_aset',
'created_by',
'updated_by',
'deleted_by',
];
protected $casts = [
'status_aset' => 'boolean',
];
public function kelompokTani(): BelongsTo
{
return $this->belongsTo(KelompokTani::class, 'survey_kelompok_tani_id');
}
}
@@ -0,0 +1,33 @@
<?php
namespace App\Models\Pertanian;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class BantuanKelompokTani extends Model
{
use HasFactory, SoftDeletes;
protected $table = 'survey_bantuan_kelompok_tani';
protected $fillable = [
'uid',
'survey_kelompok_tani_id',
'nama_program',
'penyelenggara',
'bentuk_bantuan',
'tahun',
'created_by',
'updated_by',
'deleted_by',
];
public function kelompokTani(): BelongsTo
{
return $this->belongsTo(KelompokTani::class, 'survey_kelompok_tani_id');
}
}
+136
View File
@@ -0,0 +1,136 @@
<?php
namespace App\Models\Pertanian;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use App\Models\Wilayah\DesaKelurahan;
class KelompokTani extends Model
{
use HasFactory, SoftDeletes;
protected $table = 'survey_kelompok_tani';
protected $fillable = [
'uid',
// Data Responden
'nama_responden',
'jabatan_responden',
'kontak_responden',
// Identitas Kelompok Tani
'nama_kelompok',
'desa_kelurahan_id',
'dusun',
'tahun_berdiri',
'jenis_kelompok',
'nama_gapoktan',
'komoditas_id',
// Pengurus & Anggota Kelompok
'jumlah_pengurus',
'jumlah_pengurus_aktif',
'jumlah_anggota_terdaftar',
'jumlah_anggota_aktif',
'jumlah_pengurus_laki_laki',
'jumlah_pengurus_perempuan',
'jumlah_anggota_laki_laki',
'jumlah_anggota_perempuan',
'jumlah_anggota_pemuda_laki_laki',
'jumlah_anggota_pemuda_perempuan',
// Cakupan Wilayah Kelompok
'cakupan_wilayah',
'nama_wilayah_cakupan',
// Status Legalitas Kelompok
'status_legalitas',
'nomor_sk',
'tanggal_tahun_penerbitan_sk',
// Kualitas Kepemimpinan
'tingkat_keaktifan_ketua',
'status_pembagian_peran',
'status_dokumentasi_rapat',
// Frekuensi Pertemuan Rutin
'frekuensi_pertemuan',
'tanggal_pertemuan_terakhir',
// Kegiatan Konkret yang Sudah Berjalan
'kegiatan_terlaksana',
'estimasi_panen_minimal',
'estimasi_panen_maksimal',
'satuan_hasil_panen',
'tindakan_hasil_panen',
// Peran & Fungsi Kelompok
'fungsi_kelompok_bagi_anggota',
// Kapasitas Pengelolaan Kas/Simpan Pinjam
'pembukuan_kas',
'pengelola_kas',
'masalah_pengelolaan_kas_simpan_pinjam',
'deskripsi_masalah_pengelolaan_kas_simpan_pinjam',
// Keterlibatan Perempuan
'partisipasi_perempuan',
// Konflik Internal
'konflik_kelompok',
'topik_konflik',
'penyelesaian_konflik',
// Pengalaman Bantuan
'pernah_mendapatkan_bantuan',
// Postensi Sebagai Mitra Agregasi/Pengolahan Kolektif
'potensi_kelompok',
'alasan_penilaian_potensi',
// Audit
'created_by',
'updated_by',
'deleted_by',
];
protected $casts = [
'komoditas_id' => 'array',
'tindakan_hasil_panen' => 'array',
'fungsi_kelompok_bagi_anggota' => 'array',
'kegiatan_terlaksana' => 'array',
'pernah_mendapatkan_bantuan' => 'boolean',
'tanggal_pertemuan_terakhir' => 'date',
'estimasi_panen_minimal' => 'decimal:2',
'estimasi_panen_maksimal' => 'decimal:2',
];
public function desaKelurahan()
{
return $this->belongsTo(DesaKelurahan::class, 'desa_kelurahan_id');
}
public function pengurus()
{
return $this->hasMany(PengurusKelompokTani::class, 'survey_kelompok_tani_id');
}
public function aset()
{
return $this->hasMany(AsetKelompokTani::class, 'survey_kelompok_tani_id');
}
public function bantuan()
{
return $this->hasMany(BantuanKelompokTani::class, 'survey_kelompok_tani_id');
}
}
+2 -1
View File
@@ -18,6 +18,7 @@ use App\Enums\KondisiTanaman;
use App\Enums\SeranganHama;
use App\Enums\PenyakitTanaman;
use App\Enums\KeparahanSerangan;
use App\Models\Pertanian\Petani;
class Lahan extends Model
{
@@ -98,7 +99,7 @@ class Lahan extends Model
public function petani(): BelongsTo
{
return $this->belongsTo(Profile::class, 'petani_id');
return $this->belongsTo(Petani::class, 'petani_id');
}
public function komoditas(): BelongsTo
@@ -0,0 +1,37 @@
<?php
namespace App\Models\Pertanian;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class PengurusKelompokTani extends Model
{
use HasFactory, SoftDeletes;
protected $table = 'survey_pengurus_kelompok_tani';
protected $fillable = [
'uid',
'survey_kelompok_tani_id',
'nama_pengurus',
'jabatan',
'kontak',
'status',
'created_by',
'updated_by',
'deleted_by',
];
protected $casts = [
'status' => 'boolean',
];
public function kelompokTani(): BelongsTo
{
return $this->belongsTo(KelompokTani::class, 'survey_kelompok_tani_id');
}
}
+8 -8
View File
@@ -94,15 +94,15 @@ class Petani extends Model
protected static function booted(): void
{
static::saved(function (Petani $petani) {
$skor = SkorPetani::where('petani_id')->orderBy('id')->first();
if (! $skor) {
$skor = SkorPetani::where('petani_id', $petani->id)->orderBy('id')->first();
if (!$skor) {
$petaniUid = $petani->uid;
$part = explode('-', $petaniUid);
$skor = SkorPetani::create([
'uid' => 'SKR-'.$part[1].'-'.strtoupper(Str::random(10)),
'petani_id' => $petani->id,
'uid' => 'SKR-' . $part[1] . '-' . strtoupper(Str::random(10)),
'created_by' => $petani->created_by,
'updated_by' => $petani->updated_by,
'updated_by' => $petani->updated_by
]);
}
});
@@ -339,7 +339,7 @@ class Petani extends Model
$skor >= 3.0 => 'Perintis',
$skor >= 2.0 => 'Pemerhati',
$skor >= 1.0 => 'Pemula',
default => 'Belum tersegmentasi',
default => 'Belum lengkap',
};
}
@@ -365,10 +365,10 @@ class Petani extends Model
} elseif ($skor->skor_kesiapan_adopsi >= 1.0) {
return 'Pemula';
} else {
return 'Belum tersegmentasi';
return 'Belum lengkap';
}
return 'Belum tersegmentasi';
return 'Belum lengkap';
}
public function keteranganSegmen(): ?string
+23 -13
View File
@@ -4,6 +4,9 @@ namespace App\Models\Pertanian;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use App\Models\Pertanian\Petani;
class SkorPetani extends Model
{
@@ -57,6 +60,7 @@ class SkorPetani extends Model
'skor_d6_k1_6_pengalaman_menjual_ke_saluran_berbeda',
'skor_d6_k4_1_kesadaran_akses_pasar_premium',
'skor_d6_k5_1_hambatan_mutu',
'skor_d6_k5_2_tingkat_kepercayaan_pembeli',
'created_by',
'updated_by',
@@ -102,7 +106,7 @@ class SkorPetani extends Model
$skorPetani->skor_d4_k5_1_kepemilikan_rekening +
$skorPetani->skor_d4_k5_2_pengalaman_kredit_formal +
$skorPetani->skor_d4_k5_3_kepemilikan_aset_produktif +
$skorPetani->skor_d4_k5_4_5_akses_program_bantuan
$skorPetani->skor_d4_k5_4_akses_program_bantuan
) / 4 +
(
$skorPetani->skor_d4_k6_3_keberadaan_hutang_terkait_panen +
@@ -113,30 +117,36 @@ class SkorPetani extends Model
$skorPetani->skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar = (
$skorPetani->skor_d6_k1_6_pengalaman_menjual_ke_saluran_berbeda +
$skorPetani->skor_d6_k4_1_kesadaran_akses_pasar_premium +
$skorPetani->skor_d6_k5_1_hambatan_mutu
) / 3;
$skorPetani->skor_d6_k5_1_hambatan_mutu +
$skorPetani->skor_d6_k5_2_tingkat_kepercayaan_pembeli
) / 4;
$skorPetani->skor_d2_sistem_praktik_budidaya = (
$skorPetani->skor_komp_3_d2_praktik_budidaya_gap
);
$skorPetani->skor_d4_sosial_ekonomi = (
$skorPetani->skor_komp_1_d4_k3_motivasi_kapasitas_adopsi
);
$skorPetani->skor_d6_rantai_nilai_akses_pasar = (
$skorPetani->skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar * 0.25 +
$skorPetani->skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar
);
$skorPetani->skor_d4_sosial_ekonomi = (
$skorPetani->skor_komp_1_d4_k3_motivasi_kapasitas_adopsi * 0.25 +
$skorPetani->skor_komp_2_d4_k2_ekonomi_rumah_tangga * 0.20 +
$skorPetani->skor_komp_4_d4_k4_keterlibatan_kelembagaan * 0.15 +
$skorPetani->skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan * 0.10
) / 0.70;
$skorPetani->skor_kesiapan_adopsi = (
$skorPetani->skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar * 0.25 +
$skorPetani->skor_komp_2_d4_k2_ekonomi_rumah_tangga * 0.20 +
$skorPetani->skor_komp_3_d2_praktik_budidaya_gap * 0.20 +
$skorPetani->skor_komp_4_d4_k4_keterlibatan_kelembagaan * 0.15 +
$skorPetani->skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan * 0.10 +
$skorPetani->skor_komp_1_d4_k3_motivasi_kapasitas_adopsi * 0.10
$skorPetani->skor_komp_1_d4_k3_motivasi_kapasitas_adopsi * 0.25 + // D4
$skorPetani->skor_komp_2_d4_k2_ekonomi_rumah_tangga * 0.20 + // D4
$skorPetani->skor_komp_3_d2_praktik_budidaya_gap * 0.20 + // D2
$skorPetani->skor_komp_4_d4_k4_keterlibatan_kelembagaan * 0.15 + // D4
$skorPetani->skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan * 0.10 + // D4
$skorPetani->skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar * 0.10 // D6
);
});
}
public function petani(): BelongsTo
{
return $this->belongsTo(Petani::class, 'petani_id');
}
}
@@ -0,0 +1,142 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('survey_kelompok_tani', function (Blueprint $table) {
$table->id();
$table->string('uid')->unique();
// Data Responden
$table->string('nama_responden')->nullable();
$table->string('jabatan_responden')->nullable();
$table->string('kontak_responden')->nullable();
// Identitas Kelompok Tani
$table->string('nama_kelompok')->nullable();
$table->foreignId('desa_kelurahan_id')->nullable()->constrained('master_desa_kelurahan');
$table->string('dusun')->nullable();
$table->year('tahun_berdiri')->nullable();
$table->string('jenis_kelompok', 50)->nullable();
$table->string('nama_gapoktan')->nullable();
$table->jsonb('komoditas_id')->nullable();
// Pengurus & Anggota Kelompok
$table->unsignedInteger('jumlah_pengurus')->nullable();
$table->unsignedInteger('jumlah_pengurus_aktif')->nullable();
$table->unsignedInteger('jumlah_anggota_terdaftar')->nullable();
$table->unsignedInteger('jumlah_anggota_aktif')->nullable();
$table->unsignedInteger('jumlah_pengurus_laki_laki')->nullable();
$table->unsignedInteger('jumlah_pengurus_perempuan')->nullable();
$table->unsignedInteger('jumlah_anggota_laki_laki')->nullable();
$table->unsignedInteger('jumlah_anggota_perempuan')->nullable();
$table->unsignedInteger('jumlah_anggota_pemuda_laki_laki')->nullable();
$table->unsignedInteger('jumlah_anggota_pemuda_perempuan')->nullable();
// Cakupan Wilayah Kelompok
$table->string('cakupan_wilayah')->nullable();
$table->text('nama_wilayah_cakupan')->nullable();
// Status Legalitas Kelompok
$table->string('status_legalitas', 50)->nullable();
$table->string('nomor_sk', 100)->nullable();
$table->string('tanggal_tahun_penerbitan_sk', 30)->nullable();
// Kualitas Kepemimpinan
$table->string('tingkat_keaktifan_ketua', 30)->nullable();
$table->string('status_pembagian_peran', 30)->nullable();
$table->string('status_dokumentasi_rapat', 30)->nullable();
// Frekuensi Pertemuan Rutin
$table->string('frekuensi_pertemuan', 50)->nullable();
$table->date('tanggal_pertemuan_terakhir')->nullable();
// Kegiatan Kongkret yang Sudah Berjalan
$table->jsonb('kegiatan_terlaksana')->nullable();
$table->decimal('estimasi_panen_minimal', 10, 2)->nullable();
$table->decimal('estimasi_panen_maksimal', 10, 2)->nullable();
$table->string('satuan_hasil_panen')->nullable();
$table->jsonb('tindakan_hasil_panen')->nullable();
// Peran & Fungsi Kelompok
$table->jsonb('fungsi_kelompok_bagi_anggota')->nullable();
// Kapasitas Pengelolaan Kas/Simpan-Pinjam Kelompok
$table->string('pembukuan_kas', 50)->nullable();
$table->string('pengelola_kas')->nullable();
$table->string('masalah_pengelolaan_kas_simpan_pinjam')->nullable();
$table->text('deskripsi_masalah_pengelolaan_kas_simpan_pinjam')->nullable();
// Keterlibatan Perempuan
$table->string('partisipasi_perempuan')->nullable();
// Riwayat konflik Internal Kelompok
$table->string('konflik_kelompok')->nullable();
$table->string('topik_konflik')->nullable();
$table->text('penyelesaian_konflik')->nullable();
// Pengalaman Akses Bantuan
$table->boolean('pernah_mendapatkan_bantuan')->nullable();
// Postensi Sebagai Mitra Agregasi/Pengolahan Kolektif
$table->string('potensi_kelompok')->nullable();
$table->text('alasan_penilaian_potensi')->nullable();
$table->foreignId('created_by')->nullable()->constrained('users')->onDelete('set null');
$table->foreignId('updated_by')->nullable()->constrained('users')->onDelete('set null');
$table->foreignId('deleted_by')->nullable()->constrained('users')->onDelete('set null');
$table->timestamps();
$table->softDeletes();
});
Schema::create('survey_pengurus_kelompok_tani', function (Blueprint $table) {
$table->id();
$table->string('uid')->unique();
$table->foreignId('survey_kelompok_tani_id')->nullable()->constrained('survey_kelompok_tani')->cascadeOnUpdate()->cascadeOnDelete();
$table->string('nama_pengurus');
$table->string('jabatan');
$table->string('kontak');
$table->boolean('status');
$table->foreignId('created_by')->nullable()->constrained('users')->onDelete('set null');
$table->foreignId('updated_by')->nullable()->constrained('users')->onDelete('set null');
$table->foreignId('deleted_by')->nullable()->constrained('users')->onDelete('set null');
$table->timestamps();
$table->softDeletes();
});
Schema::create('survey_aset_kelompok_tani', function (Blueprint $table) {
$table->id();
$table->string('uid')->unique();
$table->foreignId('survey_kelompok_tani_id')->nullable()->constrained('survey_kelompok_tani')->cascadeOnUpdate()->cascadeOnDelete();
$table->string('jenis_aset');
$table->boolean('status_aset');
$table->string('status_pengelolaan_aset');
$table->string('kondisi_aset');
$table->foreignId('created_by')->nullable()->constrained('users')->onDelete('set null');
$table->foreignId('updated_by')->nullable()->constrained('users')->onDelete('set null');
$table->foreignId('deleted_by')->nullable()->constrained('users')->onDelete('set null');
$table->timestamps();
$table->softDeletes();
});
Schema::create('survey_bantuan_kelompok_tani', function (Blueprint $table) {
$table->id();
$table->string('uid')->unique();
$table->foreignId('survey_kelompok_tani_id')->nullable()->constrained('survey_kelompok_tani')->cascadeOnUpdate()->cascadeOnDelete();
$table->string('nama_program');
$table->string('penyelenggara');
$table->string('bentuk_bantuan');
$table->year('tahun');
$table->foreignId('created_by')->nullable()->constrained('users')->onDelete('set null');
$table->foreignId('updated_by')->nullable()->constrained('users')->onDelete('set null');
$table->foreignId('deleted_by')->nullable()->constrained('users')->onDelete('set null');
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('survey_bantuan_kelompok_tani');
Schema::dropIfExists('survey_aset_kelompok_tani');
Schema::dropIfExists('survey_pengurus_kelompok_tani');
Schema::dropIfExists('survey_kelompok_tani');
}
};
@@ -0,0 +1,38 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('bumdes_pengurus', function (Blueprint $table) {
$table->id();
$table->string('uid')->unique();
$table->string('nama');
$table->boolean('jenis_kelamin');
$table->string('tempat_lahir')->nullable();
$table->date('tanggal_lahir');
$table->string('pendidikan_terakhir')->nullable();
$table->text('alamat')->nullable();
$table->foreignId('desa_kelurahan_id')->nullable()->constrained('master_desa_kelurahan')->onDelete('set null');
$table->string('nomor_telepon')->nullable();
$table->string('jabatan');
$table->string('jabatan_lainnya')->nullable();
$table->unsignedSmallInteger('lama_menjabat_tahun')->nullable();
$table->date('tanggal_mulai_menjabat');
$table->foreignId('created_by')->nullable()->constrained('users')->onDelete('set null');
$table->foreignId('updated_by')->nullable()->constrained('users')->onDelete('set null');
$table->foreignId('deleted_by')->nullable()->constrained('users')->onDelete('set null');
$table->timestamps();
$table->softDeletes();
});
}
public function down(): void
{
Schema::dropIfExists('bumdes_pengurus');
}
};
@@ -0,0 +1,42 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::table('bumdes_pengurus', function (Blueprint $table) {
if (! Schema::hasColumn('bumdes_pengurus', 'pendidikan_terakhir')) {
$table->string('pendidikan_terakhir')->nullable()->after('tanggal_lahir');
}
if (! Schema::hasColumn('bumdes_pengurus', 'jabatan_lainnya')) {
$table->string('jabatan_lainnya')->nullable()->after('jabatan');
}
if (! Schema::hasColumn('bumdes_pengurus', 'lama_menjabat_tahun')) {
$table->unsignedSmallInteger('lama_menjabat_tahun')->nullable()->after('jabatan_lainnya');
}
});
}
public function down(): void
{
Schema::table('bumdes_pengurus', function (Blueprint $table) {
if (Schema::hasColumn('bumdes_pengurus', 'lama_menjabat_tahun')) {
$table->dropColumn('lama_menjabat_tahun');
}
if (Schema::hasColumn('bumdes_pengurus', 'jabatan_lainnya')) {
$table->dropColumn('jabatan_lainnya');
}
if (Schema::hasColumn('bumdes_pengurus', 'pendidikan_terakhir')) {
$table->dropColumn('pendidikan_terakhir');
}
});
}
};
@@ -0,0 +1,26 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('akses_pasar', function (Blueprint $table) {
$table->tinyInteger('tingkat_kepercayaan_pembeli_baru')->nullable()->after('sumber_info_premium');
$table->text('alasan_kepercayaan_pembeli_baru')->nullable()->after('tingkat_kepercayaan_pembeli_baru');
});
}
public function down(): void
{
Schema::table('akses_pasar', function (Blueprint $table) {
$table->dropColumn(['tingkat_kepercayaan_pembeli_baru', 'alasan_kepercayaan_pembeli_baru']);
});
}
};
@@ -0,0 +1,144 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('pengurus_koperasi', function (Blueprint $table) {
$table->id();
// --- PROFIL DASAR ---
$table->string('nama_lengkap');
$table->string('posisi_dalam_koperasi');
$table->integer('tahun_bergabung')->nullable();
$table->string('no_hp', 20)->nullable();
$table->text('alamat_tinggal')->nullable();
$table->string('nama_koperasi');
$table->text('alamat_koperasi')->nullable();
$table->string('jenis_koperasi');
$table->string('skala_operasi');
$table->integer('tahun_berdiri')->nullable();
// --- ANGGOTA & PENGURUS ---
$table->integer('jumlah_anggota_awal')->nullable();
$table->integer('jumlah_anggota_dewasa')->nullable();
$table->integer('jumlah_anggota_anak')->nullable();
$table->integer('jumlah_pengurus')->nullable();
// --- SHU ---
$table->bigInteger('shu_2025')->nullable();
$table->bigInteger('shu_2024')->nullable();
$table->bigInteger('shu_2023')->nullable();
// --- KELEMBAGAAN & MANAJEMEN ---
$table->text('sejarah_lembaga')->nullable();
$table->string('fokus_komoditas')->nullable();
$table->string('detail_fokus_komoditas')->nullable();
$table->string('ad_art')->nullable();
$table->integer('tahun_ad_art')->nullable();
$table->text('layanan_koperasi')->nullable();
$table->string('layanan_lainnya')->nullable();
// Pelatihan
$table->string('pelatihan_produksi')->nullable();
$table->string('pelatihan_pascapanen')->nullable();
$table->string('pelatihan_pengolahan')->nullable();
$table->string('pelatihan_keuangan')->nullable();
$table->string('pelatihan_pemasaran')->nullable();
$table->string('pelatihan_lainnya')->nullable();
// Operasional
$table->string('status_pembukuan')->nullable();
$table->string('format_pembukuan')->nullable();
$table->string('pertemuan_rutin')->nullable();
$table->string('pertemuan_lainnya')->nullable();
$table->string('kasus_kredit_macet')->nullable();
$table->string('sanksi_kredit_macet')->nullable();
$table->string('efektivitas_sanksi')->nullable();
$table->text('faktor_manajemen')->nullable();
$table->string('faktor_manajemen_lainnya')->nullable();
// Rantai Nilai & Fasilitas Internal
$table->text('keterlibatan_rantai_nilai')->nullable();
$table->text('agregasi_komoditas')->nullable();
$table->string('agregasi_komoditas_lainnya')->nullable();
$table->text('fasilitas_koperasi')->nullable();
$table->string('fasilitas_lainnya')->nullable();
$table->string('pengolahan_lanjutan')->nullable();
$table->string('detail_pengolahan_lanjutan')->nullable();
$table->text('cara_penentuan_harga')->nullable();
$table->string('kontrak_offtaker')->nullable();
$table->string('kontrak_komoditas')->nullable();
// --- AKSES PASAR & RANTAI NILAI EKSTERNAL ---
$table->text('sumber_pasokan')->nullable();
$table->string('sumber_pasokan_lainnya')->nullable();
$table->text('bentuk_pembelian')->nullable();
$table->integer('volume_beli_sekarang')->nullable();
$table->integer('volume_beli_1_tahun')->nullable();
$table->integer('volume_beli_2_tahun')->nullable();
$table->text('tujuan_penjualan')->nullable();
$table->string('tujuan_penjualan_lainnya')->nullable();
$table->text('bentuk_penjualan')->nullable();
$table->integer('volume_jual_sekarang')->nullable();
$table->integer('volume_jual_1_tahun')->nullable();
$table->integer('volume_jual_2_tahun')->nullable();
$table->text('sifat_hubungan_bisnis')->nullable();
$table->string('sifat_hubungan_lainnya')->nullable();
$table->string('mekanisme_pembayaran')->nullable();
$table->string('status_perjanjian_tertulis')->nullable();
// Harga Komoditas
$table->bigInteger('harga_segar_sekarang')->nullable();
$table->bigInteger('harga_segar_1_tahun')->nullable();
$table->bigInteger('harga_segar_2_tahun')->nullable();
$table->bigInteger('harga_basah_sekarang')->nullable();
$table->bigInteger('harga_basah_1_tahun')->nullable();
$table->bigInteger('harga_basah_2_tahun')->nullable();
$table->bigInteger('harga_kering_sekarang')->nullable();
$table->bigInteger('harga_kering_1_tahun')->nullable();
$table->bigInteger('harga_kering_2_tahun')->nullable();
$table->bigInteger('harga_fermentasi_sekarang')->nullable();
$table->bigInteger('harga_fermentasi_1_tahun')->nullable();
$table->bigInteger('harga_fermentasi_2_tahun')->nullable();
$table->text('cara_menetapkan_harga_pasar')->nullable();
$table->string('cara_menetapkan_harga_lainnya')->nullable();
// Praktik Kualitas & Pascapanen
$table->string('praktik_sortasi')->nullable();
$table->string('standar_sortasi')->nullable();
$table->string('praktik_pengeringan')->nullable();
$table->string('cara_pengeringan')->nullable();
$table->string('praktik_fermentasi')->nullable();
$table->text('model_fermentasi')->nullable();
$table->text('proses_fermentasi')->nullable();
$table->bigInteger('harga_premium_rupiah')->nullable();
$table->integer('harga_premium_persen')->nullable();
// --- SOSIAL EKONOMI ---
$table->bigInteger('simpanan_terbesar')->nullable();
$table->string('momen_simpanan_terbesar')->nullable();
$table->text('alasan_pinjaman')->nullable();
$table->string('alasan_pinjaman_lainnya')->nullable();
$table->string('pembayaran_selain_uang')->nullable();
$table->text('bentuk_pembayaran_barang')->nullable();
$table->string('bentuk_pembayaran_lainnya')->nullable();
$table->string('perhitungan_harga_pasar')->nullable();
$table->string('alasan_bukan_harga_pasar')->nullable();
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('pengurus_koperasi');
}
};
@@ -0,0 +1,50 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('bumdes_kelembagaan_aktor', function (Blueprint $table) {
$table->id();
$table->foreignId('pengurus_bumdes_id')->unique()->constrained('bumdes_pengurus')->onDelete('cascade');
$table->string('status_badan_hukum')->nullable();
$table->string('nomor_dasar_hukum')->nullable();
$table->unsignedSmallInteger('tahun_dasar_hukum')->nullable();
$table->string('status_keaktifan')->nullable();
$table->text('alasan_tidak_aktif')->nullable();
$table->json('unit_usaha')->nullable();
$table->string('unit_usaha_jasa_lainnya')->nullable();
$table->string('status_unit_komoditas')->nullable();
$table->string('nama_unit_komoditas')->nullable();
$table->string('status_ad_art')->nullable();
$table->unsignedSmallInteger('tahun_ad_art')->nullable();
$table->json('pengurus_inti')->nullable();
$table->boolean('memiliki_staf')->nullable();
$table->unsignedInteger('jumlah_staf')->nullable();
$table->text('unit_usaha_staf')->nullable();
$table->decimal('modal_awal', 18, 2)->nullable();
$table->unsignedSmallInteger('tahun_modal_awal')->nullable();
$table->boolean('pernah_penambahan_modal')->nullable();
$table->json('penambahan_modal')->nullable();
$table->json('aset_produktif')->nullable();
$table->string('aset_produktif_lainnya')->nullable();
$table->string('status_kepemilikan_aset')->nullable();
$table->json('infrastruktur_pascapanen')->nullable();
$table->string('infrastruktur_pascapanen_lainnya')->nullable();
$table->foreignId('created_by')->nullable()->constrained('users')->onDelete('set null');
$table->foreignId('updated_by')->nullable()->constrained('users')->onDelete('set null');
$table->foreignId('deleted_by')->nullable()->constrained('users')->onDelete('set null');
$table->timestamps();
$table->softDeletes();
});
}
public function down(): void
{
Schema::dropIfExists('bumdes_kelembagaan_aktor');
}
};
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 421 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 328 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 359 KiB

+3 -3
View File
@@ -71,13 +71,13 @@ window.templateName = document.documentElement.getAttribute('data-template');
if (typeof TemplateCustomizer !== 'undefined') {
window.templateCustomizer = new TemplateCustomizer({
displayCustomizer: true,
displayCustomizer: false,
lang: localStorage.getItem('templateCustomizer-' + templateName + '--Lang') || 'en', // Set default language here
// defaultPrimaryColor: '#D11BB4',
defaultPrimaryColor: '#2a7233',
// defaultSkin: 1,
// defaultTheme: 'system',
// defaultSemiDark: true,
// defaultContentLayout: 'wide',
defaultContentLayout: 'wide',
// defaultHeaderType: 'static',
// defaultMenuCollapsed: true,
// defaultNavbarType: 'static',
+17 -2
View File
@@ -14,7 +14,7 @@
name="viewport"
content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" />
<meta name="robots" content="noindex, nofollow" />
<title>Agomonev | {{ $title ?? 'Auth' }} </title>
<title>AGERA | {{ $title ?? 'Auth' }} </title>
<meta name="description" content="" />
@@ -26,7 +26,7 @@
<meta name="apple-mobile-web-app-status-bar-style" content="default">
<!-- Favicon -->
<link rel="icon" type="image/x-icon" href="../../assets/img/favicon/favicon.ico" />
<link rel="icon" type="image/svg+xml" href="{{ asset('assets/img/logo/agera_icon.svg') }}" />
<!-- Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
@@ -72,6 +72,21 @@
<!--? Config: Mandatory theme config file contain global vars & default theme options, Set your preferred theme option in this file. -->
<script src="{{ asset('assets/js/config.js') }}"></script>
<style>
.agera-logo {
width: 200px;
height: auto;
max-height: 78px;
object-fit: contain;
display: block;
}
.app-brand-logo.demo {
width: auto;
height: auto;
}
</style>
</head>
<body>
+2 -14
View File
@@ -6,24 +6,12 @@
<div class="app-brand justify-content-center mb-6">
<a href="{{ route('home') }}" class="app-brand-link">
<span class="app-brand-logo demo">
<span class="text-primary">
<svg width="32" height="24" viewBox="0 0 32 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<!-- Daun Bagian Kiri -->
<path opacity="0.3" d="M16 2.5C16 2.5 5 6.5 5 15.5C5 20.5 11 23.5 16 23.5V2.5Z" fill="currentColor" />
<!-- Daun Bagian Kanan -->
<path opacity="0.6" d="M16 2.5C16 2.5 27 6.5 27 15.5C27 20.5 21 23.5 16 23.5V2.5Z" fill="currentColor" />
<!-- Grafik Pertumbuhan (Monev) -->
<path d="M2 19L10 11L15 15L27 4" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" />
<!-- Titik Target/Pencapaian -->
<circle cx="27" cy="4" r="2.5" fill="currentColor" />
</svg>
</span>
<img src="{{ asset('assets/img/logo/agera_side.svg') }}" alt="AGERA" class="agera-logo">
</span>
<span class="app-brand-text demo menu-text fw-bold ms-3" style="text-transform: capitalize;">AgroMonev</span>
</a>
</div>
<!-- /Logo -->
<h4 class="mb-1">Selamat datang di AgroMonev!</h4>
<h4 class="mb-1">Selamat datang di AGERA!</h4>
<p class="mb-6">Silakan masuk ke akun Anda</p>
@if ($errors->any())
<div class="alert alert-danger">
+2 -30
View File
@@ -6,40 +6,12 @@
<div class="app-brand justify-content-center mb-6">
<a href="{{ route('home') }}" class="app-brand-link">
<span class="app-brand-logo demo">
<span class="text-primary">
<svg width="32" height="24" viewBox="0 0 32 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.3"
d="M16 2.5C16 2.5 5 6.5 5 15.5C5 20.5 11 23.5 16 23.5V2.5Z"
fill="#2E7D32" />
<path opacity="0.6"
d="M16 2.5C16 2.5 27 6.5 27 15.5C27 20.5 21 23.5 16 23.5V2.5Z"
fill="#2E7D32" />
<path d="M2 19L10 11L15 15"
stroke="#0054A6"
stroke-width="2.5"
stroke-linecap="round"
stroke-linejoin="round" />
<path d="M15 15L27 4"
stroke="#ED1C24"
stroke-width="2.5"
stroke-linecap="round"
stroke-linejoin="round" />
<circle cx="27" cy="4" r="2.5" fill="#ED1C24" />
</svg>
</span>
</span>
<span class="app-brand-text demo menu-text fw-bold ms-3" style="text-transform: capitalize;">
AgroMonev
<img src="{{ asset('assets/img/logo/agera_side.svg') }}" alt="AGERA" class="agera-logo">
</span>
</a>
</div>
<!-- /Logo -->
<h4 class="mb-1">Buat akun AgroMonev</h4>
<h4 class="mb-1">Buat akun AGERA</h4>
<p class="mb-6">Lengkapi data berikut untuk membuat akun baru.</p>
<form id="formAuthentication" class="mb-6" action="{{ route('auth.createAccount') }}" method="POST">
@@ -0,0 +1,530 @@
@extends('layout.main')
@php
$fieldValue = function (string $field, $default = null) use ($kelembagaanAktor) {
return old($field, data_get($kelembagaanAktor, $field, $default));
};
$arrayValue = function (string $field) use ($fieldValue) {
return (array) $fieldValue($field, []);
};
$rowValue = function (string $field, string $keyName, string $key) use ($fieldValue) {
return collect((array) $fieldValue($field, []))->firstWhere($keyName, $key) ?? [];
};
$rupiahValue = function ($value) {
if (! filled($value)) {
return '';
}
if (is_numeric($value)) {
return number_format((float) $value, 0, ',', '.');
}
return preg_replace('/\D/', '', (string) $value);
};
@endphp
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
@if (session('success'))
<div class="alert alert-success">{{ session('success') }}</div>
@endif
@if ($errors->any())
<div class="alert alert-danger">
<ul class="mb-0">
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
@include('bumdes.profil.header', ['pengurus' => $pengurus])
<form method="POST" action="{{ route('bumdes.kelembagaan-aktor.store', $pengurus->id) }}" id="kelembagaanAktorForm">
@csrf
<div class="card mb-6">
<div class="card-header border-bottom">
<h5 class="card-title mb-0">Status Keberadaan, Keaktifan, Kepengurusan dan Modal BUMDes</h5>
</div>
<div class="card-body pt-6">
<h5 class="pb-4 border-bottom mb-4">Status Keberadaan dan Keaktifan</h5>
<div class="mb-5 form-control-validation">
<label class="form-label d-block fw-semibold">Apakah BUMDes sudah berbadan hukum?</label>
<div class="d-flex flex-column">
@foreach($statusBadanHukumOptions as $value => $label)
<div>
<div class="form-check">
<input class="form-check-input" type="radio" id="status-badan-hukum-{{ $value }}" name="status_badan_hukum" value="{{ $value }}" @checked($fieldValue('status_badan_hukum') === $value)>
<label class="form-check-label" for="status-badan-hukum-{{ $value }}">{{ $label }}</label>
</div>
</div>
@endforeach
</div>
@error('status_badan_hukum')<div class="invalid-feedback d-block">{{ $message }}</div>@enderror
</div>
<div class="row">
<div class="col-md-6 mb-5 form-control-validation">
<label class="form-label" for="nomor-dasar-hukum">Dasar hukum pendirian BUMDes (Peraturan Desa/SK) - Nomor</label>
<input type="text" class="form-control @error('nomor_dasar_hukum') is-invalid @enderror" id="nomor-dasar-hukum" name="nomor_dasar_hukum" value="{{ $fieldValue('nomor_dasar_hukum') }}" placeholder="Contoh: Perdes No. 02/2024">
@error('nomor_dasar_hukum')<div class="invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-5 form-control-validation">
<label class="form-label" for="tahun-dasar-hukum">Tahun ditetapkan</label>
<input type="number" class="form-control @error('tahun_dasar_hukum') is-invalid @enderror" id="tahun-dasar-hukum" name="tahun_dasar_hukum" value="{{ $fieldValue('tahun_dasar_hukum') }}" placeholder="Contoh: 2024">
@error('tahun_dasar_hukum')<div class="invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="mb-5 form-control-validation">
<label class="form-label d-block fw-semibold">Bagaimana status keaktifan BUMDes?</label>
<div class="d-flex flex-column">
@foreach($statusKeaktifanOptions as $value => $label)
<div>
<div class="form-check">
<input class="form-check-input" type="radio" id="status-keaktifan-{{ $value }}" name="status_keaktifan" value="{{ $value }}" @checked($fieldValue('status_keaktifan') === $value)>
<label class="form-check-label" for="status-keaktifan-{{ $value }}">{{ $label }}</label>
</div>
</div>
@endforeach
</div>
@error('status_keaktifan')<div class="invalid-feedback d-block">{{ $message }}</div>@enderror
</div>
<div class="mb-5 form-control-validation" id="alasan-tidak-aktif-wrapper">
<label class="form-label" for="alasan-tidak-aktif">Jika tidak aktif/vakum, apa alasan utamanya?</label>
<textarea class="form-control @error('alasan_tidak_aktif') is-invalid @enderror" id="alasan-tidak-aktif" name="alasan_tidak_aktif" rows="2" placeholder="Tuliskan alasan utama BUMDes tidak aktif/vakum">{{ $fieldValue('alasan_tidak_aktif') }}</textarea>
@error('alasan_tidak_aktif')<div class="invalid-feedback">{{ $message }}</div>@enderror
</div>
<h5 class="pb-4 border-bottom mb-4 mt-4">Unit Usaha dan Dokumen Kelembagaan</h5>
<div class="mb-5 form-control-validation">
<label class="form-label d-block fw-semibold">Unit usaha yang dimiliki BUMDes saat ini (boleh pilih lebih dari satu)</label>
<div class="d-flex flex-column">
@foreach($unitUsahaOptions as $value => $label)
<div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="unit-usaha-{{ $value }}" name="unit_usaha[]" value="{{ $value }}" @checked(in_array($value, $arrayValue('unit_usaha'), true))>
<label class="form-check-label" for="unit-usaha-{{ $value }}">{{ $label }}</label>
</div>
</div>
@endforeach
</div>
@error('unit_usaha')<div class="invalid-feedback d-block">{{ $message }}</div>@enderror
</div>
<div class="row" id="unit-usaha-jasa-lainnya-wrapper">
<div class="col-md-6 mb-5 form-control-validation">
<label class="form-label" for="unit-usaha-jasa-lainnya">Jasa lainnya</label>
<input type="text" class="form-control @error('unit_usaha_jasa_lainnya') is-invalid @enderror" id="unit-usaha-jasa-lainnya" name="unit_usaha_jasa_lainnya" value="{{ $fieldValue('unit_usaha_jasa_lainnya') }}" placeholder="Sebutkan jasa lainnya">
@error('unit_usaha_jasa_lainnya')<div class="invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="mb-5 form-control-validation">
<label class="form-label d-block fw-semibold">Apakah ada unit usaha khusus yang menangani komoditas kopi/kakao/vanili/kemiri?</label>
<div class="d-flex flex-column">
@foreach($statusUnitKomoditasOptions as $value => $label)
<div>
<div class="form-check">
<input class="form-check-input" type="radio" id="status-unit-komoditas-{{ $value }}" name="status_unit_komoditas" value="{{ $value }}" @checked($fieldValue('status_unit_komoditas') === $value)>
<label class="form-check-label" for="status-unit-komoditas-{{ $value }}">{{ $label }}</label>
</div>
</div>
@endforeach
</div>
@error('status_unit_komoditas')<div class="invalid-feedback d-block">{{ $message }}</div>@enderror
</div>
<div class="row" id="nama-unit-komoditas-wrapper">
<div class="col-md-6 mb-5 form-control-validation">
<label class="form-label" for="nama-unit-komoditas">Nama unit usaha komoditas</label>
<input type="text" class="form-control @error('nama_unit_komoditas') is-invalid @enderror" id="nama-unit-komoditas" name="nama_unit_komoditas" value="{{ $fieldValue('nama_unit_komoditas') }}" placeholder="Contoh: Unit Pengolahan Kopi">
@error('nama_unit_komoditas')<div class="invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="mb-5 form-control-validation">
<label class="form-label d-block fw-semibold">Apakah ada dokumen kelembagaan (AD/ART)?</label>
<div class="d-flex flex-column">
@foreach($statusAdArtOptions as $value => $label)
<div>
<div class="form-check">
<input class="form-check-input" type="radio" id="status-ad-art-{{ $value }}" name="status_ad_art" value="{{ $value }}" @checked($fieldValue('status_ad_art') === $value)>
<label class="form-check-label" for="status-ad-art-{{ $value }}">{{ $label }}</label>
</div>
</div>
@endforeach
</div>
@error('status_ad_art')<div class="invalid-feedback d-block">{{ $message }}</div>@enderror
</div>
<div class="row" id="tahun-ad-art-wrapper">
<div class="col-md-3 mb-5 form-control-validation">
<label class="form-label" for="tahun-ad-art">Terakhir diperbarui tahun</label>
<input type="number" class="form-control @error('tahun_ad_art') is-invalid @enderror" id="tahun-ad-art" name="tahun_ad_art" value="{{ $fieldValue('tahun_ad_art') }}" placeholder="Contoh: 2024">
@error('tahun_ad_art')<div class="invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<h5 class="pb-4 border-bottom mb-4 mt-4">Kepengurusan dan Staf</h5>
<label class="form-label d-block fw-semibold">Catat pengurus inti yang aktif menjabat saat ini</label>
<div class="table-responsive mb-5">
<table class="table table-bordered align-middle">
<thead>
<tr>
<th style="width: 30%;">Jabatan</th>
<th>Nama</th>
<th style="width: 22%;">Keaktifan</th>
</tr>
</thead>
<tbody>
@foreach($pengurusIntiRows as $key => $label)
@php
$savedRow = $rowValue('pengurus_inti', 'jabatan', $key);
$aktifValue = old("pengurus_inti.$loop->index.aktif", data_get($savedRow, 'aktif'));
@endphp
<tr>
<td>
<input type="hidden" name="pengurus_inti[{{ $loop->index }}][jabatan]" value="{{ $key }}">
{{ $label }}
</td>
<td>
<input type="text" class="form-control" name="pengurus_inti[{{ $loop->index }}][nama]" value="{{ old("pengurus_inti.$loop->index.nama", data_get($savedRow, 'nama')) }}">
</td>
<td>
<div class="d-flex flex-column">
<div class="form-check mb-0">
<input class="form-check-input" type="radio" id="pengurus-inti-{{ $key }}-aktif" name="pengurus_inti[{{ $loop->index }}][aktif]" value="1" @checked((string) $aktifValue === '1')>
<label class="form-check-label" for="pengurus-inti-{{ $key }}-aktif">Aktif</label>
</div>
<div class="form-check mb-0">
<input class="form-check-input" type="radio" id="pengurus-inti-{{ $key }}-tidak" name="pengurus_inti[{{ $loop->index }}][aktif]" value="0" @checked((string) $aktifValue === '0')>
<label class="form-check-label" for="pengurus-inti-{{ $key }}-tidak">Tidak</label>
</div>
</div>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
<div class="mb-5 form-control-validation">
<label class="form-label d-block fw-semibold">Apakah BUMDes memiliki staf/karyawan di luar pengurus inti?</label>
<div class="d-flex flex-column">
<div class="form-check">
<input class="form-check-input" type="radio" id="memiliki-staf-ya" name="memiliki_staf" value="1" @checked((string) $fieldValue('memiliki_staf') === '1')>
<label class="form-check-label" for="memiliki-staf-ya">Ya</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" id="memiliki-staf-tidak" name="memiliki_staf" value="0" @checked((string) $fieldValue('memiliki_staf') === '0')>
<label class="form-check-label" for="memiliki-staf-tidak">Tidak ada, dikelola langsung pengurus</label>
</div>
</div>
@error('memiliki_staf')<div class="invalid-feedback d-block">{{ $message }}</div>@enderror
</div>
<div class="row" id="staf-detail-wrapper">
<div class="col-md-3 mb-5 form-control-validation">
<label class="form-label" for="jumlah-staf">Jumlah staf</label>
<div class="input-group">
<input type="number" min="0" class="form-control @error('jumlah_staf') is-invalid @enderror" id="jumlah-staf" name="jumlah_staf" value="{{ $fieldValue('jumlah_staf') }}">
<span class="input-group-text">orang</span>
</div>
@error('jumlah_staf')<div class="invalid-feedback d-block">{{ $message }}</div>@enderror
</div>
<div class="col-md-9 mb-5 form-control-validation">
<label class="form-label" for="unit-usaha-staf">Jika ada, untuk unit usaha apa staf tersebut bekerja?</label>
<input type="text" class="form-control @error('unit_usaha_staf') is-invalid @enderror" id="unit-usaha-staf" name="unit_usaha_staf" value="{{ $fieldValue('unit_usaha_staf') }}" placeholder="Contoh: Unit perdagangan/toko desa">
@error('unit_usaha_staf')<div class="invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<h5 class="pb-4 border-bottom mb-4 mt-4">Modal dan Aset</h5>
<div class="row">
<div class="col-md-4 mb-5 form-control-validation">
<label class="form-label" for="modal-awal">Besaran modal awal BUMDes (jika diketahui)</label>
<div class="input-group">
<span class="input-group-text">Rp</span>
<input type="text" inputmode="numeric" class="form-control rupiah-input @error('modal_awal') is-invalid @enderror" id="modal-awal" name="modal_awal" value="{{ $rupiahValue($fieldValue('modal_awal')) }}">
</div>
@error('modal_awal')<div class="invalid-feedback d-block">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-5 form-control-validation">
<label class="form-label" for="tahun-modal-awal">Tahun diterima</label>
<input type="number" class="form-control @error('tahun_modal_awal') is-invalid @enderror" id="tahun-modal-awal" name="tahun_modal_awal" value="{{ $fieldValue('tahun_modal_awal') }}" placeholder="Contoh: 2024">
@error('tahun_modal_awal')<div class="invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="mb-5 form-control-validation">
<label class="form-label d-block fw-semibold">Apakah BUMDes pernah menerima penambahan modal sejak pertama kali berdiri?</label>
<div class="d-flex flex-column">
<div class="form-check">
<input class="form-check-input" type="radio" id="penambahan-modal-ya" name="pernah_penambahan_modal" value="1" @checked((string) $fieldValue('pernah_penambahan_modal') === '1')>
<label class="form-check-label" for="penambahan-modal-ya">Ya, pernah</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" id="penambahan-modal-tidak" name="pernah_penambahan_modal" value="0" @checked((string) $fieldValue('pernah_penambahan_modal') === '0')>
<label class="form-check-label" for="penambahan-modal-tidak">Tidak pernah menerima penambahan modal</label>
</div>
</div>
@error('pernah_penambahan_modal')<div class="invalid-feedback d-block">{{ $message }}</div>@enderror
</div>
<div id="penambahan-modal-wrapper">
<label class="form-label d-block fw-semibold">Jika BUMDes pernah menerima penambahan modal, isi rincian penambahan modal 3 tahun terakhir</label>
<div class="table-responsive mb-5">
<table class="table table-bordered align-middle">
<thead>
<tr>
<th>Tahun</th>
<th>Jumlah (Rp)</th>
</tr>
</thead>
<tbody>
@for($i = 0; $i < 3; $i++)
@php $savedRow = data_get($fieldValue('penambahan_modal', []), $i, []); @endphp
<tr>
<td>
<input type="number" class="form-control" name="penambahan_modal[{{ $i }}][tahun]" value="{{ old("penambahan_modal.$i.tahun", data_get($savedRow, 'tahun')) }}" placeholder="Contoh: 2024">
</td>
<td>
<div class="input-group">
<span class="input-group-text">Rp</span>
<input type="text" inputmode="numeric" class="form-control rupiah-input" name="penambahan_modal[{{ $i }}][jumlah]" value="{{ $rupiahValue(old("penambahan_modal.$i.jumlah", data_get($savedRow, 'jumlah'))) }}">
</div>
</td>
</tr>
@endfor
</tbody>
</table>
</div>
</div>
<label class="form-label d-block fw-semibold">Aset produktif yang dimiliki BUMDes (boleh pilih lebih dari satu, lewati jika tidak ada)</label>
<div class="table-responsive mb-5">
<table class="table table-bordered align-middle">
<thead>
<tr>
<th style="width: 34%;">Aset Produktif</th>
<th>Jumlah</th>
<th>Kondisi</th>
</tr>
</thead>
<tbody>
@foreach($asetProduktifRows as $key => $label)
@php
$savedRow = $rowValue('aset_produktif', 'aset', $key);
$dipilih = old("aset_produktif.$loop->index.dipilih", data_get($savedRow, 'dipilih'));
@endphp
<tr>
<td>
<input type="hidden" name="aset_produktif[{{ $loop->index }}][aset]" value="{{ $key }}">
<div class="form-check">
<input class="form-check-input aset-produktif-check" type="checkbox" id="aset-produktif-{{ $key }}" name="aset_produktif[{{ $loop->index }}][dipilih]" value="1" data-target="{{ $key }}" @checked((string) $dipilih === '1')>
<label class="form-check-label" for="aset-produktif-{{ $key }}">{{ $label }}</label>
</div>
@if($key === 'lainnya')
<input type="text" class="form-control mt-2" id="aset-produktif-lainnya" name="aset_produktif_lainnya" value="{{ $fieldValue('aset_produktif_lainnya') }}" placeholder="Sebutkan aset lainnya">
@endif
</td>
<td>
<input type="text" class="form-control" name="aset_produktif[{{ $loop->index }}][jumlah]" value="{{ old("aset_produktif.$loop->index.jumlah", data_get($savedRow, 'jumlah')) }}">
</td>
<td>
<input type="text" class="form-control" name="aset_produktif[{{ $loop->index }}][kondisi]" value="{{ old("aset_produktif.$loop->index.kondisi", data_get($savedRow, 'kondisi')) }}" placeholder="Contoh: Baik, rusak ringan">
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
<div class="mb-5 form-control-validation">
<label class="form-label d-block fw-semibold">Status kepemilikan aset (lewati jika tidak ada)</label>
<div class="d-flex flex-column">
@foreach($statusKepemilikanAsetOptions as $value => $label)
<div>
<div class="form-check">
<input class="form-check-input" type="radio" id="status-kepemilikan-aset-{{ $value }}" name="status_kepemilikan_aset" value="{{ $value }}" @checked($fieldValue('status_kepemilikan_aset') === $value)>
<label class="form-check-label" for="status-kepemilikan-aset-{{ $value }}">{{ $label }}</label>
</div>
</div>
@endforeach
</div>
@error('status_kepemilikan_aset')<div class="invalid-feedback d-block">{{ $message }}</div>@enderror
</div>
<label class="form-label d-block fw-semibold">Ketersediaan infrastruktur pascapanen untuk komoditas kopi/kakao/vanili/kemiri</label>
<div class="table-responsive mb-5">
<table class="table table-bordered align-middle">
<thead>
<tr>
<th style="width: 34%;">Infrastruktur Pascapanen</th>
<th>Jumlah</th>
<th style="width: 34%;">Kondisi</th>
</tr>
</thead>
<tbody>
@foreach($infrastrukturPascapanenRows as $key => $label)
@php
$savedRow = $rowValue('infrastruktur_pascapanen', 'infrastruktur', $key);
$dipilih = old("infrastruktur_pascapanen.$loop->index.dipilih", data_get($savedRow, 'dipilih'));
$kondisiValue = old("infrastruktur_pascapanen.$loop->index.kondisi", data_get($savedRow, 'kondisi'));
@endphp
<tr>
<td>
<input type="hidden" name="infrastruktur_pascapanen[{{ $loop->index }}][infrastruktur]" value="{{ $key }}">
<div class="form-check">
<input class="form-check-input infrastruktur-check" type="checkbox" id="infrastruktur-{{ $key }}" name="infrastruktur_pascapanen[{{ $loop->index }}][dipilih]" value="1" data-target="{{ $key }}" @checked((string) $dipilih === '1')>
<label class="form-check-label" for="infrastruktur-{{ $key }}">{{ $label }}</label>
</div>
@if($key === 'lainnya')
<input type="text" class="form-control mt-2" id="infrastruktur-pascapanen-lainnya" name="infrastruktur_pascapanen_lainnya" value="{{ $fieldValue('infrastruktur_pascapanen_lainnya') }}" placeholder="Sebutkan infrastruktur lainnya">
@endif
</td>
<td>
<input type="text" class="form-control" name="infrastruktur_pascapanen[{{ $loop->index }}][jumlah]" value="{{ old("infrastruktur_pascapanen.$loop->index.jumlah", data_get($savedRow, 'jumlah')) }}">
</td>
<td>
<div class="d-flex flex-column">
@foreach($kondisiInfrastrukturOptions as $kondisi => $kondisiLabel)
<div class="form-check mb-0">
<input class="form-check-input" type="radio" id="infrastruktur-{{ $key }}-{{ $kondisi }}" name="infrastruktur_pascapanen[{{ $loop->parent->index }}][kondisi]" value="{{ $kondisi }}" @checked($kondisiValue === $kondisi)>
<label class="form-check-label" for="infrastruktur-{{ $key }}-{{ $kondisi }}">{{ $kondisiLabel }}</label>
</div>
@endforeach
</div>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
<div class="mt-4 text-end">
<a href="{{ route('bumdes.index') }}" class="btn btn-secondary me-2 wave-effect wave-light">Kembali</a>
<button type="submit" class="btn btn-success data-submit wave-effect wave-light">
<i class="ti tabler-device-floppy me-2"></i>Simpan Kelembagaan dan Aktor
</button>
</div>
</div>
</div>
</form>
</div>
@endsection
@push('scripts')
<script>
'use strict';
$(document).ready(function () {
function onlyDigits(value) {
return String(value || '').replace(/\D/g, '');
}
function formatRupiah(value) {
return onlyDigits(value).replace(/\B(?=(\d{3})+(?!\d))/g, '.');
}
function toggleWrapper($wrapper, enabled) {
$wrapper.toggleClass('d-none', !enabled);
setFieldsEnabled($wrapper, enabled);
}
function setFieldsEnabled($wrapper, enabled) {
$wrapper.find('input, textarea, select').prop('disabled', !enabled);
if (!enabled) {
$wrapper.find('input:not([type="radio"]):not([type="checkbox"]), textarea').val('');
$wrapper.find('input[type="radio"], input[type="checkbox"]').prop('checked', false);
}
}
function syncStatusKeaktifan() {
setFieldsEnabled($('#alasan-tidak-aktif-wrapper'), $('input[name="status_keaktifan"]:checked').val() === 'tidak_aktif_vakum');
}
function syncUnitUsahaLainnya() {
toggleWrapper($('#unit-usaha-jasa-lainnya-wrapper'), $('input[name="unit_usaha[]"][value="jasa_lainnya"]').is(':checked'));
}
function syncUnitKomoditas() {
toggleWrapper($('#nama-unit-komoditas-wrapper'), $('input[name="status_unit_komoditas"]:checked').val() === 'ya');
}
function syncAdArt() {
toggleWrapper($('#tahun-ad-art-wrapper'), $('input[name="status_ad_art"]:checked').val() === 'ada_lengkap');
}
function syncStaf() {
setFieldsEnabled($('#staf-detail-wrapper'), $('input[name="memiliki_staf"]:checked').val() === '1');
}
function syncPenambahanModal() {
setFieldsEnabled($('#penambahan-modal-wrapper'), $('input[name="pernah_penambahan_modal"]:checked').val() === '1');
}
function syncAsetLainnya() {
$('#aset-produktif-lainnya').prop('disabled', !$('input.aset-produktif-check[data-target="lainnya"]').is(':checked'));
if ($('#aset-produktif-lainnya').prop('disabled')) {
$('#aset-produktif-lainnya').val('');
}
}
function syncInfrastrukturLainnya() {
$('#infrastruktur-pascapanen-lainnya').prop('disabled', !$('input.infrastruktur-check[data-target="lainnya"]').is(':checked'));
if ($('#infrastruktur-pascapanen-lainnya').prop('disabled')) {
$('#infrastruktur-pascapanen-lainnya').val('');
}
}
$(document).on('input', '.rupiah-input', function () {
const cursorAtEnd = this.selectionStart === this.value.length;
this.value = formatRupiah(this.value);
if (cursorAtEnd) {
this.setSelectionRange(this.value.length, this.value.length);
}
});
$('.rupiah-input').each(function () {
this.value = formatRupiah(this.value);
});
$('input[name="status_keaktifan"]').on('change', syncStatusKeaktifan);
$('input[name="unit_usaha[]"]').on('change', syncUnitUsahaLainnya);
$('input[name="status_unit_komoditas"]').on('change', syncUnitKomoditas);
$('input[name="status_ad_art"]').on('change', syncAdArt);
$('input[name="memiliki_staf"]').on('change', syncStaf);
$('input[name="pernah_penambahan_modal"]').on('change', syncPenambahanModal);
$('.aset-produktif-check').on('change', syncAsetLainnya);
$('.infrastruktur-check').on('change', syncInfrastrukturLainnya);
$('#kelembagaanAktorForm').on('submit', function () {
$(this).find('.rupiah-input').each(function () {
this.value = onlyDigits(this.value);
});
});
syncStatusKeaktifan();
syncUnitUsahaLainnya();
syncUnitKomoditas();
syncAdArt();
syncStaf();
syncPenambahanModal();
syncAsetLainnya();
syncInfrastrukturLainnya();
});
</script>
@endpush
@@ -0,0 +1,280 @@
@php
$prefix = $mode . '-bumdes';
$currentProvinsiId = old('provinsi_id', $pengurus?->desaKelurahan?->kecamatan?->kabupatenKota?->provinsi_id);
$currentKabupaten = $pengurus?->desaKelurahan?->kecamatan?->kabupatenKota;
$currentKecamatan = $pengurus?->desaKelurahan?->kecamatan;
$currentDesa = $pengurus?->desaKelurahan;
$currentJabatan = $pengurus?->jabatan instanceof \App\Enums\Bumdes\JabatanBumdes ? $pengurus->jabatan->value : $pengurus?->jabatan;
$currentPendidikan = $pengurus?->pendidikan_terakhir instanceof \App\Enums\Pendidikan ? $pengurus->pendidikan_terakhir->value : $pengurus?->pendidikan_terakhir;
@endphp
<h5 class="pb-4 border-bottom mb-4">Data Pribadi</h5>
<div class="row">
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="{{ $prefix }}-nama">Nama Pengurus BUMDes<span class="text-danger">*</span></label>
<input type="text" class="form-control @error('nama') is-invalid @enderror" id="{{ $prefix }}-nama" name="nama" placeholder="Contoh: John Doe" value="{{ old('nama', $pengurus?->nama) }}" />
@error('nama')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="{{ $prefix }}-jenis-kelamin">Jenis Kelamin<span class="text-danger">*</span></label>
<select class="form-control @error('jenis_kelamin') is-invalid @enderror" id="{{ $prefix }}-jenis-kelamin" name="jenis_kelamin">
<option value="">Pilih Jenis Kelamin</option>
<option value="1" {{ old('jenis_kelamin', $pengurus?->jenis_kelamin) == '1' ? 'selected' : '' }}>Laki-laki</option>
<option value="0" {{ old('jenis_kelamin', $pengurus?->jenis_kelamin) == '0' ? 'selected' : '' }}>Perempuan</option>
</select>
@error('jenis_kelamin')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="{{ $prefix }}-tempat-lahir">Tempat Lahir<span class="text-danger">*</span></label>
<input type="text" class="form-control @error('tempat_lahir') is-invalid @enderror" id="{{ $prefix }}-tempat-lahir" name="tempat_lahir" placeholder="Contoh: Ngada" value="{{ old('tempat_lahir', $pengurus?->tempat_lahir) }}" />
@error('tempat_lahir')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="{{ $prefix }}-tanggal-lahir">Tanggal Lahir<span class="text-danger">*</span></label>
<input type="text" class="form-control @error('tanggal_lahir') is-invalid @enderror" id="{{ $prefix }}-tanggal-lahir" name="tanggal_lahir" value="{{ old('tanggal_lahir', $pengurus?->tanggal_lahir?->format('d-m-Y')) }}" />
@error('tanggal_lahir')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="row">
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="{{ $prefix }}-pendidikan-terakhir">Pendidikan Terakhir<span class="text-danger">*</span></label>
<select class="form-control @error('pendidikan_terakhir') is-invalid @enderror" id="{{ $prefix }}-pendidikan-terakhir" name="pendidikan_terakhir">
<option value="">Pilih Pendidikan Terakhir</option>
@foreach($pendidikan as $value)
<option value="{{ $value['value'] }}" {{ old('pendidikan_terakhir', $currentPendidikan) == $value['value'] ? 'selected' : '' }}>{{ $value['label'] }}</option>
@endforeach
</select>
@error('pendidikan_terakhir')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<h5 class="pb-4 border-bottom mb-4 mt-4">Peran Kepengurusan BUMDes</h5>
<div class="row">
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="{{ $prefix }}-jabatan">Jabatan/Peran<span class="text-danger">*</span></label>
<select class="form-control @error('jabatan') is-invalid @enderror" id="{{ $prefix }}-jabatan" name="jabatan">
<option value="">Pilih Jabatan/Peran</option>
@foreach($jabatan as $value)
<option value="{{ $value['value'] }}" {{ old('jabatan', $currentJabatan) == $value['value'] ? 'selected' : '' }}>{{ $value['label'] }}</option>
@endforeach
</select>
@error('jabatan')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation {{ old('jabatan', $currentJabatan) === \App\Enums\Bumdes\JabatanBumdes::LAINNYA->value ? '' : 'd-none' }}" id="{{ $prefix }}-jabatan-lainnya-wrapper">
<label class="form-label" for="{{ $prefix }}-jabatan-lainnya">Jabatan Lainnya<span class="text-danger">*</span></label>
<input type="text" class="form-control @error('jabatan_lainnya') is-invalid @enderror" id="{{ $prefix }}-jabatan-lainnya" name="jabatan_lainnya" placeholder="Contoh: Kepala Unit Usaha" value="{{ old('jabatan_lainnya', $pengurus?->jabatan_lainnya) }}" />
@error('jabatan_lainnya')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="{{ $prefix }}-lama-menjabat">Lama Menjabat (Tahun)<span class="text-danger">*</span></label>
<input type="number" min="0" max="80" class="form-control @error('lama_menjabat_tahun') is-invalid @enderror" id="{{ $prefix }}-lama-menjabat" name="lama_menjabat_tahun" placeholder="Contoh: 2" value="{{ old('lama_menjabat_tahun', $pengurus?->lama_menjabat_tahun) }}" />
@error('lama_menjabat_tahun')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<h5 class="pb-4 border-bottom mb-4 mt-4">Domisili dan Kontak</h5>
<div class="row">
<div class="col-md-12 mb-4 form-control-validation">
<label class="form-label" for="{{ $prefix }}-alamat">Alamat<span class="text-danger">*</span></label>
<textarea class="form-control @error('alamat') is-invalid @enderror" id="{{ $prefix }}-alamat" name="alamat" rows="2" placeholder="Contoh: Jl. Nama Jalan, Nama Dusun">{{ old('alamat', $pengurus?->alamat) }}</textarea>
@error('alamat')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="row">
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="{{ $prefix }}-provinsi">Provinsi<span class="text-danger">*</span></label>
<select class="form-control @error('provinsi_id') is-invalid @enderror" id="{{ $prefix }}-provinsi" name="provinsi_id">
<option value="">Pilih Provinsi</option>
@foreach($provinsi as $p)
<option value="{{ $p->id }}" {{ $currentProvinsiId == $p->id ? 'selected' : '' }}>{{ $p->nama }}</option>
@endforeach
</select>
@error('provinsi_id')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="{{ $prefix }}-kabupaten">Kabupaten/Kota<span class="text-danger">*</span></label>
<select class="form-control @error('kabupaten_id') is-invalid @enderror" id="{{ $prefix }}-kabupaten" name="kabupaten_id">
<option value="">Pilih Kabupaten/Kota</option>
@if($currentKabupaten)
<option value="{{ $currentKabupaten->id }}" selected>{{ $currentKabupaten->nama }}</option>
@endif
</select>
@error('kabupaten_id')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="{{ $prefix }}-kecamatan">Kecamatan<span class="text-danger">*</span></label>
<select class="form-control @error('kecamatan_id') is-invalid @enderror" id="{{ $prefix }}-kecamatan" name="kecamatan_id">
<option value="">Pilih Kecamatan</option>
@if($currentKecamatan)
<option value="{{ $currentKecamatan->id }}" selected>{{ $currentKecamatan->nama }}</option>
@endif
</select>
@error('kecamatan_id')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="{{ $prefix }}-desa">Desa/Kelurahan<span class="text-danger">*</span></label>
<select class="form-control @error('desa_kelurahan_id') is-invalid @enderror" id="{{ $prefix }}-desa" name="desa_kelurahan_id">
<option value="">Pilih Desa/Kelurahan</option>
@if($currentDesa)
<option value="{{ $currentDesa->id }}" selected>{{ $currentDesa->nama }}</option>
@endif
</select>
@error('desa_kelurahan_id')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="row">
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="{{ $prefix }}-nomor-telepon">No HP</label>
<input type="text" class="form-control @error('nomor_telepon') is-invalid @enderror" id="{{ $prefix }}-nomor-telepon" name="nomor_telepon" placeholder="Contoh: 081234567890" value="{{ old('nomor_telepon', $pengurus?->nomor_telepon) }}" minlength="11" maxlength="13" />
@error('nomor_telepon')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
@push('scripts')
<script>
'use strict';
$(document).ready(function () {
const prefix = '#{{ $prefix }}';
const lainnyaValue = '{{ \App\Enums\Bumdes\JabatanBumdes::LAINNYA->value }}';
$(`${prefix}-jenis-kelamin, ${prefix}-pendidikan-terakhir, ${prefix}-jabatan`).select2();
$(`${prefix}-tanggal-lahir`).flatpickr({
dateFormat: 'd-m-Y'
});
function toggleJabatanLainnya() {
const isLainnya = $(`${prefix}-jabatan`).val() === lainnyaValue;
$(`${prefix}-jabatan-lainnya-wrapper`).toggleClass('d-none', !isLainnya);
if (!isLainnya) {
$(`${prefix}-jabatan-lainnya`).val('');
}
}
$(`${prefix}-jabatan`).on('change', toggleJabatanLainnya);
toggleJabatanLainnya();
$(`${prefix}-provinsi`).select2().change(function(e) {
e.preventDefault();
const provinsiId = $(this).val();
$(`${prefix}-kabupaten`).prop('disabled', !provinsiId).val('').trigger('change');
$(`${prefix}-kecamatan`).prop('disabled', true).val('').trigger('change');
$(`${prefix}-desa`).prop('disabled', true).val('').trigger('change');
if (provinsiId) {
$.ajax({
url: '{{ route("kabupatenkota.byprovinsi", ":id") }}'.replace(':id', provinsiId) + '?all_wilayah=1',
method: 'GET',
success: function(data) {
$(`${prefix}-kabupaten`).empty().append('<option value="">Pilih Kabupaten/Kota</option>');
data.forEach(function(kabupaten) {
$(`${prefix}-kabupaten`).append('<option value="' + kabupaten.id + '">' + kabupaten.nama + '</option>');
});
}
});
}
});
$(`${prefix}-kabupaten`).select2().change(function(e) {
e.preventDefault();
const kabupatenId = $(this).val();
$(`${prefix}-kecamatan`).prop('disabled', !kabupatenId).val('').trigger('change');
$(`${prefix}-desa`).prop('disabled', true).val('').trigger('change');
if (kabupatenId) {
$.ajax({
url: '{{ route("kecamatan.bykabupatenkota", ":id") }}'.replace(':id', kabupatenId) + '?all_wilayah=1',
method: 'GET',
success: function(data) {
$(`${prefix}-kecamatan`).empty().append('<option value="">Pilih Kecamatan</option>');
data.forEach(function(kecamatan) {
$(`${prefix}-kecamatan`).append('<option value="' + kecamatan.id + '">' + kecamatan.nama + '</option>');
});
}
});
}
});
$(`${prefix}-kecamatan`).select2().change(function(e) {
e.preventDefault();
const kecamatanId = $(this).val();
$(`${prefix}-desa`).prop('disabled', !kecamatanId).val('').trigger('change');
if (kecamatanId) {
$.ajax({
url: '{{ route("desakelurahan.bykecamatan", ":id") }}'.replace(':id', kecamatanId) + '?all_wilayah=1',
method: 'GET',
success: function(data) {
$(`${prefix}-desa`).empty().append('<option value="">Pilih Desa/Kelurahan</option>');
data.forEach(function(desa) {
$(`${prefix}-desa`).append('<option value="' + desa.id + '">' + desa.nama + '</option>');
});
}
});
}
});
$(`${prefix}-desa`).select2();
$('#{{ $mode }}BumdesForm').validate({
rules: {
nama: { required: true },
jenis_kelamin: { required: true },
tempat_lahir: { required: true },
tanggal_lahir: { required: true },
pendidikan_terakhir: { required: true },
jabatan: { required: true },
jabatan_lainnya: {
required: function() {
return $(`${prefix}-jabatan`).val() === lainnyaValue;
}
},
lama_menjabat_tahun: { required: true, digits: true, min: 0, max: 80 },
alamat: { required: true },
provinsi_id: { required: true },
kabupaten_id: { required: true },
kecamatan_id: { required: true },
desa_kelurahan_id: { required: true },
nomor_telepon: { required: false, digits: true, minlength: 11, maxlength: 13 }
},
messages: {
nama: { required: 'Nama pengurus BUMDes wajib diisi' },
jenis_kelamin: { required: 'Jenis kelamin wajib dipilih' },
tempat_lahir: { required: 'Tempat lahir wajib diisi' },
tanggal_lahir: { required: 'Tanggal lahir wajib diisi' },
pendidikan_terakhir: { required: 'Pendidikan terakhir wajib dipilih' },
jabatan: { required: 'Jabatan/peran wajib dipilih' },
jabatan_lainnya: { required: 'Jabatan lainnya wajib diisi' },
lama_menjabat_tahun: {
required: 'Lama menjabat wajib diisi',
digits: 'Lama menjabat harus berupa angka tahun',
min: 'Lama menjabat tidak boleh kurang dari 0 tahun',
max: 'Lama menjabat tidak boleh lebih dari 80 tahun'
},
alamat: { required: 'Alamat wajib diisi' },
provinsi_id: { required: 'Provinsi wajib dipilih' },
kabupaten_id: { required: 'Kabupaten/Kota wajib dipilih' },
kecamatan_id: { required: 'Kecamatan wajib dipilih' },
desa_kelurahan_id: { required: 'Desa/Kelurahan wajib dipilih' },
nomor_telepon: {
digits: 'Nomor telepon harus berupa angka',
minlength: 'Nomor telepon minimal 11 digit',
maxlength: 'Nomor telepon maksimal 13 digit'
}
},
errorElement: 'div',
errorPlacement: function (error, element) {
error.addClass('invalid-feedback');
element.closest('.form-control-validation').append(error);
},
highlight: function (element) {
$(element).addClass('is-invalid');
},
unhighlight: function (element) {
$(element).removeClass('is-invalid');
}
});
});
</script>
@endpush
@@ -0,0 +1,34 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
@if ($errors->any())
<div class="alert alert-danger">
<ul class="mb-0">
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
@include('bumdes.profil.header', ['pengurus' => null])
<div class="card mb-6">
<div class="card-header border-bottom">
<h5 class="card-title mb-0">Tambah Profil Pengurus BUMDes</h5>
</div>
<div class="card-body pt-6">
<form id="addBumdesForm" action="{{ route('bumdes.store') }}" method="POST">
@csrf
@include('bumdes.profil._form', ['pengurus' => null, 'mode' => 'add'])
<div class="mt-4 text-end">
<a href="{{ route('bumdes.index') }}" class="btn btn-secondary me-2 wave-effect wave-light">Kembali</a>
<button type="submit" class="btn btn-success data-submit wave-effect wave-light"><i class="ti tabler-device-floppy me-2"></i> Simpan Profil</button>
</div>
</form>
</div>
</div>
</div>
@endsection
@@ -0,0 +1,39 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
@if (session('success'))
<div class="alert alert-success">{{ session('success') }}</div>
@endif
@if ($errors->any())
<div class="alert alert-danger">
<ul class="mb-0">
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
@include('bumdes.profil.header', ['pengurus' => $pengurus])
<div class="card mb-6">
<div class="card-header border-bottom">
<h5 class="card-title mb-0">Edit Profil Pengurus BUMDes</h5>
</div>
<div class="card-body pt-6">
<form id="editBumdesForm" action="{{ route('bumdes.update', $pengurus->id) }}" method="POST">
@csrf
@method('PUT')
@include('bumdes.profil._form', ['pengurus' => $pengurus, 'mode' => 'edit'])
<div class="mt-4 text-end">
<a href="{{ route('bumdes.index') }}" class="btn btn-secondary me-2 wave-effect wave-light">Kembali</a>
<button type="submit" class="btn btn-success data-submit wave-effect wave-light"><i class="ti tabler-device-floppy me-2"></i> Simpan Profil</button>
</div>
</form>
</div>
</div>
</div>
@endsection
@@ -0,0 +1,162 @@
<style>
@media (min-width: 768px) {
.nav-pills-custom-spacing {
display: flex;
width: 100%;
gap: 0.5rem;
flex-wrap: nowrap !important;
overflow-x: auto;
}
.nav-pills-custom-spacing::-webkit-scrollbar {
display: none;
}
.nav-pills-custom-spacing .nav-item {
margin-right: 0 !important;
flex: 1;
}
.nav-pills-custom-spacing .nav-link {
display: flex;
justify-content: center;
align-items: center;
padding-left: 0.5rem !important;
padding-right: 0.5rem !important;
width: 100%;
white-space: nowrap;
font-size: 0.9375rem !important;
}
.nav-pills-custom-spacing .nav-link i {
margin-right: 0.4rem !important;
}
}
</style>
@php
$jenisKelamin = isset($pengurus)
? ($pengurus->jenis_kelamin ? 'Laki-laki' : 'Perempuan')
: 'Jenis Kelamin';
$jabatanLabel = isset($pengurus) ? $pengurus->nama_jabatan : 'Jabatan/Peran';
$domisili = isset($pengurus) && $pengurus->desaKelurahan
? $pengurus->desaKelurahan->nama . ', ' . $pengurus->desaKelurahan->kecamatan?->nama . ', ' . $pengurus->desaKelurahan->kecamatan?->kabupatenKota?->nama . ', ' . $pengurus->desaKelurahan->kecamatan?->kabupatenKota?->provinsi?->nama
: 'Desa/Kelurahan, Kecamatan, Kabupaten/Kota, Provinsi';
@endphp
<div class="row mb-4">
<div class="col-md-4 mb-2 mb-md-0">
<div class="card h-100">
<div class="card-body p-3">
<h6 class="card-title mb-2">Profil Pengurus BUMDes</h6>
<div class="d-flex justify-content-start align-items-center mb-3">
<div class="avatar me-2">
<span class="avatar-initial rounded bg-label-primary">
<i class="icon-base ti tabler-user-check icon-22px"></i>
</span>
</div>
<div class="d-flex flex-column">
<h6 class="mb-0" style="font-size: 0.9rem;">{{ isset($pengurus) ? $pengurus->nama : 'Tambah Pengurus BUMDes Baru' }}</h6>
<span class="text-muted" style="font-size: 0.75rem;">{{ $jenisKelamin }}</span>
<span class="text-muted" style="font-size: 0.75rem;">Jabatan: {{ $jabatanLabel }}</span>
</div>
</div>
<hr class="my-2">
<h6 class="mb-1" style="font-size: 0.85rem;">Domisili</h6>
<p class="mb-0 text-muted" style="font-size: 0.75rem;">Alamat: {{ isset($pengurus) ? $pengurus->alamat : 'Alamat' }}</p>
<p class="mb-0 text-muted" style="font-size: 0.75rem; line-height: 1.3;">{{ $domisili }}</p>
</div>
</div>
</div>
<div class="col-md-8 d-flex flex-column">
<div class="card mb-2 flex-grow-1">
<div class="card-widget-separator-wrapper h-100">
<div class="card-body card-widget-separator py-2 h-100 d-flex flex-column justify-content-center">
<div class="row gy-2">
<div class="col-sm-6 col-lg-4">
<div class="d-flex justify-content-between align-items-center card-widget-1 border-end h-100 pe-3">
<div>
<p class="mb-0 text-muted" style="font-size: 0.75rem;">Jenis Kelamin</p>
<h5 class="mb-0">{{ $jenisKelamin }}</h5>
<p class="mb-0" style="font-size: 0.75rem;">
<span class="me-1">{{ isset($pengurus) ? ($pengurus->usia . ' tahun') : 'Belum terisi' }}</span>
</p>
</div>
<span class="avatar">
<span class="avatar-initial rounded">
<i class="icon-base ti tabler-users icon-22px text-heading"></i>
</span>
</span>
</div>
</div>
<div class="col-sm-6 col-lg-4">
<div class="d-flex justify-content-between align-items-center card-widget-1 border-end h-100 px-3">
<div>
<p class="mb-0 text-muted" style="font-size: 0.75rem;">Jabatan</p>
<h5 class="mb-0">{{ $jabatanLabel }}</h5>
<p class="mb-0" style="font-size: 0.75rem;">
<span class="me-1">{{ isset($pengurus) ? $pengurus->lama_menjabat : 'Belum terisi' }}</span>
</p>
</div>
<span class="avatar">
<span class="avatar-initial rounded">
<i class="icon-base ti tabler-briefcase icon-22px text-heading"></i>
</span>
</span>
</div>
</div>
<div class="col-sm-6 col-lg-4">
<div class="d-flex justify-content-between align-items-center card-widget-1 h-100 ps-3">
<div>
<p class="mb-0 text-muted" style="font-size: 0.75rem;">Domisili</p>
<h5 class="mb-0">{{ isset($pengurus) ? ($pengurus->desaKelurahan?->nama ?? '-') : '-' }}</h5>
<p class="mb-0" style="font-size: 0.75rem;">
<span class="me-1">{{ isset($pengurus) ? ($pengurus->desaKelurahan?->kecamatan?->nama ?? '-') : 'Belum terisi' }}</span>
</p>
</div>
<span class="avatar">
<span class="avatar-initial rounded">
<i class="icon-base ti tabler-map-pin icon-22px text-heading"></i>
</span>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="card flex-grow-1">
<div class="card-body py-3 d-flex align-items-center">
<div class="w-100">
<p class="mb-1 text-muted" style="font-size: 0.75rem;">Alamat Domisili</p>
<h6 class="mb-0">{{ isset($pengurus) ? ($pengurus->alamat ?: '-') : '-' }}</h6>
<p class="mb-0 text-muted" style="font-size: 0.75rem;">{{ $domisili }}</p>
</div>
</div>
</div>
</div>
</div>
<div class="nav-align-top">
<ul class="nav nav-pills flex-column flex-md-row mb-6 row-gap-2 nav-pills-custom-spacing">
<li class="nav-item">
<a class="nav-link {{ request()->routeIs('bumdes.create') || request()->routeIs('bumdes.edit') ? 'active' : '' }}" href="{{ isset($pengurus) ? route('bumdes.edit', $pengurus->id) : route('bumdes.create') }}">
<i class="icon-base ti tabler-user-check icon-sm"></i>Profil
</a>
</li>
<li class="nav-item">
@if(isset($pengurus))
<a class="nav-link {{ request()->routeIs('bumdes.kelembagaan-aktor.*') ? 'active' : '' }}" href="{{ route('bumdes.kelembagaan-aktor.index', $pengurus->id) }}">
<i class="icon-base ti tabler-building-community icon-sm"></i>Kelembagaan dan Aktor
</a>
@else
<a class="nav-link" href="#" disabled data-bs-original-title="Kelembagaan dan Aktor, isi profil terlebih dahulu" data-bs-toggle="tooltip" data-bs-placement="top">
<i class="icon-base ti tabler-building-community icon-sm"></i>Kelembagaan dan Aktor
</a>
@endif
</li>
</ul>
</div>
@@ -0,0 +1,158 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
<div class="d-flex flex-row gap-3 mb-4">
<div class="w-25">
<x-summary-card
title="Pengurus BUMDes"
count="{{ $totalPengurus }}"
subtitle="{{ $totalLakiLaki }} Laki-laki, {{ $totalPerempuan }} Perempuan"
icon="user-check"
color="primary"
/>
</div>
<div class="w-25">
<x-summary-card
title="Desa/Kelurahan"
count="{{ $totalDesaKelurahan }}"
subtitle="desa/kelurahan memiliki data pengurus"
icon="map-pin"
color="success"
/>
</div>
<div class="w-25">
<x-summary-card
title="Jabatan/Peran"
count="{{ $totalJabatan }}"
subtitle="jenis jabatan/peran terdata"
icon="briefcase"
color="info"
/>
</div>
</div>
<div class="card">
<div class="card-header border-bottom">
<h5 class="card-title mb-0">Data Pengurus BUMDes</h5>
</div>
<div class="card-body border-bottom pt-4">
<form method="GET" action="{{ route('bumdes.index') }}" class="d-flex justify-content-between align-items-center row gap-3 gap-md-0">
<div class="col-md-auto">
<div class="d-flex align-items-center">
<label class="me-2 text-nowrap">Show</label>
<select name="per_page" class="form-select form-select-sm w-auto" onchange="this.form.submit()">
<option value="10" {{ request('per_page') == 10 ? 'selected' : '' }}>10</option>
<option value="25" {{ request('per_page') == 25 ? 'selected' : '' }}>25</option>
</select>
<label class="ms-2 text-nowrap">entries</label>
</div>
</div>
<div class="col-md-auto d-flex gap-2">
<div class="input-group input-group-sm w-auto">
<input type="text" name="search" class="form-control" placeholder="Cari Nama..." value="{{ request('search') }}">
<button type="submit" class="btn btn-outline-primary"><i class="ti tabler-search"></i></button>
</div>
<a href="{{ route('bumdes.create') }}" class="btn btn-sm btn-primary">
<i class="ti tabler-plus me-1"></i> Tambah
</a>
</div>
</form>
</div>
<div class="table-responsive text-nowrap">
<table class="table table-hover">
<thead class="border-top">
<tr>
<th>No</th>
<th>Nama</th>
<th>Jenis Kelamin</th>
<th>Usia</th>
<th>Desa/Kelurahan</th>
<th>Jabatan/Peran</th>
<th>Lama Menjabat</th>
@if($showEnumerator)
<th>Nama Enumerator</th>
@endif
<th>Aksi</th>
</tr>
</thead>
<tbody>
@forelse($pengurus as $item)
<tr>
<td>{{ ($pengurus->firstItem() ?? 0) + $loop->index }}</td>
<td><span class="text-heading">{{ $item->nama }}</span></td>
<td><span class="text-muted">{{ $item->jenis_kelamin ? 'Laki-laki' : 'Perempuan' }}</span></td>
<td><span class="text-muted">{{ $item->usia }} tahun</span></td>
<td>
<span class="text-muted">
{{ $item->desaKelurahan?->nama }},
{{ $item->desaKelurahan?->kecamatan?->nama }},
{{ $item->desaKelurahan?->kecamatan?->kabupatenKota?->nama }},
{{ $item->desaKelurahan?->kecamatan?->kabupatenKota?->provinsi?->nama }}
</span>
</td>
<td>{{ $item->nama_jabatan }}</td>
<td><span class="text-muted">{{ $item->lama_menjabat }}</span></td>
@if($showEnumerator)
<td><span class="text-muted">{{ $item->creator?->name ?? '-' }}</span></td>
@endif
<td>
<div class="d-flex align-items-center">
<a href="{{ route('bumdes.edit', $item->id) }}" class="btn btn-icon btn-text-secondary rounded-pill edit-record"><i class="ti tabler-edit ti-md"></i></a>
<a href="javascript:;" class="btn btn-icon btn-text-secondary rounded-pill delete-record" data-id="{{ $item->id }}" data-nama="{{ $item->nama }}"><i class="ti tabler-trash ti-md"></i></a>
</div>
</td>
</tr>
@empty
<tr>
<td colspan="{{ $showEnumerator ? 9 : 8 }}" class="text-center py-4">Tidak ada data ditemukan.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<div class="card-footer d-flex justify-content-center justify-content-md-end border-top">
{{ $pengurus->appends(request()->query())->links('pagination::bootstrap-5') }}
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
'use strict';
const csrfToken = "{{ csrf_token() }}";
$(document).ready(function () {
$(document).on('click', '.delete-record', function () {
const id = $(this).data('id');
const name = $(this).data('nama');
Swal.fire({
title: 'Apakah Anda yakin?',
text: `Profile "${name}" akan dihapus secara permanen!`,
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Ya, Hapus!',
customClass: { confirmButton: 'btn btn-primary me-3', cancelButton: 'btn btn-label-secondary' },
buttonsStyling: false
}).then(function (result) {
if (result.value) {
$.ajax({
url: '{{ route('bumdes.destroy', ':id') }}'.replace(':id', id),
type: 'DELETE',
headers: { 'X-CSRF-TOKEN': csrfToken },
success: function (res) {
Swal.fire({ icon: 'success', title: 'Terhapus!', text: res.message, showConfirmButton: false, timer: 1500 })
.then(() => window.location.reload());
},
error: () => Swal.fire({ icon: 'error', title: 'Gagal!', text: 'Terjadi kesalahan sistem.' })
});
}
});
});
});
</script>
@endpush
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+207 -222
View File
@@ -1,6 +1,35 @@
@extends('layout.main')
@section('content')
@php
$totalPetani = $petaniSummary->sum('total');
$segments = [
[
'name' => 'Penggerak',
'range' => '4.0 - 5.0',
'icon' => 'tabler-crown',
'color' => 'success',
],
[
'name' => 'Perintis',
'range' => '3.0 - 3.9',
'icon' => 'tabler-flag',
'color' => 'info',
],
[
'name' => 'Pemerhati',
'range' => '2.0 - 2.9',
'icon' => 'tabler-eye',
'color' => 'warning',
],
[
'name' => 'Pemula',
'range' => '1.0 - 1.9',
'icon' => 'tabler-seedling',
'color' => 'danger',
],
];
@endphp
<div class="container-xxl flex-grow-1 container-p-y">
<div class="row g-6">
<div class="col-lg-3 col-sm-6">
@@ -12,9 +41,9 @@
<i class="icon-base ti tabler-user-check icon-28px"></i>
</span>
</div>
<h4 class="mb-0">{{ $petaniSummary->sum('total') }}</h4>
<h4 class="mb-0">{{ $totalPetani }}</h4>
</div>
<p class="mb-1">Petani</p>
<p class="mb-1">Total Petani</p>
<p class="mb-0">
<span class="text-heading fw-medium me-2">{{ $petaniSummary->count('total') }}</span>
<small class="text-body-secondary">komoditas utama</small>
@@ -41,29 +70,6 @@
</div>
</div>
</div>
<!-- <div class="col-lg-6 col-sm-12">
<div class="card card-border-shadow-danger h-100">
<div class="card-body">
<div class="d-flex align-items-center mb-2">
<div class="avatar me-4">
<span class="avatar-initial rounded bg-label-danger">
<i class="icon-base ti tabler-seedling icon-28px"></i>
</span>
</div>
<h4 class="mb-0">{{ $tanamanSummary->sum('total') }}</h4>
</div>
<p class="mb-1">Tanaman Komoditas Utama</p>
<div class="d-flex justify-content-between mb-2">
@foreach($komoditas as $k)
<p class="mb-0">
<span class="text-heading fw-medium me-2">{{ $tanamanSummary->where('komoditas_id', $k->id)->sum('total') }}</span>
<small class="text-body-danger">tanaman {{ $k->nama }}</small>
</p>
@endforeach
</div>
</div>
</div>
</div> -->
<div class="col-lg-3 col-sm-6">
<div class="card card-border-shadow-info h-100">
<div class="card-body">
@@ -78,7 +84,6 @@
<p class="mb-1">Rata-rata Indeks Kesiapan Adopsi</p>
<p class="mb-0">
<span class="text-heading fw-medium me-2">{{ $segmenAverage }}</span>
<small class="text-body-info">komoditas utama</small>
</p>
</div>
</div>
@@ -95,146 +100,92 @@
</div>
</div>
<div class="card-body">
<table class="table card-table table-border-top-0 table-border-bottom-0">
<table class="table card-table table-border-top-0 table-border-bottom-0 data-table">
<thead>
<tr>
<th></th>
<th class="text-end pe-0">Petani</th>
<th class="text-end pe-0">%</th>
</tr>
</thead>
<tbody>
@foreach ($segments as $segment)
@php
$total = $skorSummary->where('segmen', $segment['name'])->sum('total');
$persen = $totalPetani ? ($total / $totalPetani) * 100 : 0;
@endphp
<tr>
<td class="w-60 ps-0"></td>
<td class="text-end pe-0">Petani</td>
<td class="text-end pe-0">%</td>
</tr>
<tr>
<td class="w-60 ps-0">
<td>
<div class="d-flex justify-content-start align-items-center">
<div class="me-2">
<i class="icon-base ti tabler-crown icon-lg text-heading"></i>
</div>
<div>
<h6 class="mb-0 fw-normal text-success">Penggerak (4.0 - 5.0)</h6>
<!-- <small class="text-body-secondary text-wrap">Siap menjadi peserta agrolab utama dan panutan bagi petani lain</small> -->
<i class="icon-base ti {{ $segment['icon'] }} icon-lg text-{{ $segment['color'] }}"></i>
</div>
<span class="text-{{ $segment['color'] }}">
{{ $segment['name'] }}
<small class="text-body-secondary">({{ $segment['range'] }})</small>
</span>
</div>
</td>
<td class="text-end pe-0">
<span>{{ $skorSummary->where('segmen', 'Penggerak')->sum('total') }} petani</span>
</td>
<td class="text-end pe-0">
<span>{{ number_format(($skorSummary->where('segmen', 'Penggerak')->sum('total') / $petaniSummary->sum('total')) * 100, 2) }}%</span>
</td>
</tr>
<tr>
<td class="w-60 ps-0">
<div class="d-flex justify-content-start align-items-center">
<div class="me-2">
<i class="icon-base ti tabler-flag icon-lg text-heading"></i>
</div>
<div>
<h6 class="mb-0 fw-normal text-info">Perintis (3.0 - 3.9)</h6>
<!-- <small class="text-body-secondary text-wrap">Berpotensi berkembang menjadi Penggerak dengan dukungan yang tepat</small> -->
</div>
</div>
</td>
<td class="text-end pe-0">
<span>{{ $skorSummary->where('segmen', 'Perintis')->sum('total') }} petani</span>
</td>
<td class="text-end pe-0">
<span>{{ number_format(($skorSummary->where('segmen', 'Perintis')->sum('total') / $petaniSummary->sum('total')) * 100, 2) }}%</span>
</td>
</tr>
<tr>
<td class="w-60 ps-0">
<div class="d-flex justify-content-start align-items-center">
<div class="me-2">
<i class="icon-base ti tabler-eye icon-lg text-heading text-success"></i>
</div>
<div>
<h6 class="mb-0 fw-normal text-warning">Pemerhati (2.0 - 2.9)</h6>
<!-- <small class="text-body-secondary text-wrap">Perlu melihat bukti hasil nyata dari Penggerak sebelum mau bergerak</small> -->
</div>
</div>
</td>
<td class="text-end pe-0">
<span>{{ $skorSummary->where('segmen', 'Pemerhati')->sum('total') }} petani</span>
</td>
<td class="text-end pe-0">
<span>{{ number_format(($skorSummary->where('segmen', 'Pemerhati')->sum('total') / $petaniSummary->sum('total')) * 100, 2) }}%</span>
</td>
</tr>
<tr>
<td class="w-60 ps-0">
<div class="d-flex justify-content-start align-items-center">
<div class="me-2">
<i class="icon-base ti tabler-seedling icon-lg text-heading"></i>
</div>
<div>
<h6 class="mb-0 fw-normal text-danger">Pemula (1.0 - 1.9)</h6>
<!-- <small class="text-body-secondary text-wrap">Butuh penanganan hambatan dasar terlebih dahulu sebelum intervensi langsung</small> -->
</div>
</div>
</td>
<td class="text-end pe-0">
<span>{{ $skorSummary->where('segmen', 'Pemula')->sum('total') }} petani</span>
</td>
<td class="text-end pe-0">
<span>{{ number_format(($skorSummary->where('segmen', 'Pemula')->sum('total') / $petaniSummary->sum('total')) * 100, 2) }}%</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- <div class="col-lg-6 col-sm-12">
<div class="card h-100">
<div class="card-header d-flex justify-content-between align-items-center">
<div class="card-title mb-0">
<h5 class="m-0 me-2">Segmentasi Petani Komoditas</h5>
<p class="card-subtitle">berdasarkan mayoritas segmentasi</p>
</div>
</div>
<div class="card-body">
<table class="table card-table table-border-top-0 table-border-bottom-0">
<tbody>
@foreach ($komoditas as $k)
<?php
$max = $skorKomoditasSummary->where('komoditas_id', $k->id)
->whereIn('segmen', ['Penggerak', 'Perintis', 'Pemerhati', 'Pemula'])
->sortByDesc('total')
->first();
?>
<tr>
<td class="w-40 ps-0">
<h6 class="mb-0 fw-normal text-heading">{{ $k->nama }}</h6>
</td>
<td class="pe-0">
@if(isset($max))
@if($max->segmen == 'Penggerak')
<span class="text-success">Petani Penggerak</span>
@elseif($max->segmen == 'Perintis')
<span class="text-info">Petani Perintis</span>
@elseif($max->segmen == 'Pemerhati')
<span class="text-warning">Petani Pemerhati</span>
@elseif($max->segmen == 'Pemula')
<span class="text-danger">Petani Pemula</span>
@else
<span>Belum Lengkap</span>
@endif
@else
<span>Belum Tersegmentasi</span>
@endif
</td>
<td class="text-end pe-0">
<span>{{ isset($max) ? $max->total : 0 }} Petani</span>
</td>
<td class="text-end pe-0">
<span>{{ isset($max) ? number_format(($max->total / $petaniSummary->sum('total')) * 100, 2) : 0 }}%</span>
</td>
<td class="text-end pe-0">{{ number_format($total) }}</td>
<td class="text-end pe-0">{{ number_format($persen, 2) }}%</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div> -->
</div>
<div class="col-lg-6 col-sm-12">
<div class="card h-100">
<div class="card-header d-flex justify-content-between align-items-center">
<div class="card-title mb-0">
<h5 class="m-0 me-2">Segmentasi Petani</h5>
<p class="card-subtitle">per komoditas</p>
</div>
</div>
<div class="card-body">
<table class="table card-table table-border-top-0 table-border-bottom-0 data-table">
<thead>
<tr>
<th></th>
@foreach ($komoditas as $k)
<th class="text-end pe-0">{{ $k->nama }}</th>
@endforeach
</tr>
</thead>
<tbody>
@foreach ($segments as $segment)
<tr>
<td>
<div class="d-flex justify-content-start align-items-center">
<div class="me-2">
<i class="icon-base ti {{ $segment['icon'] }} icon-lg text-{{ $segment['color'] }}"></i>
</div>
<span class="text-{{ $segment['color'] }}">
{{ $segment['name'] }}
<small class="text-body-secondary">({{ $segment['range'] }})</small>
</span>
</div>
</td>
@foreach ($komoditas as $k)
@php
$jumlah = $skorKomoditasSummary->where('segmen', $segment['name'])->where('komoditas_id', $k->id)->sum('total');
@endphp
<td class="text-end pe-0">{{ number_format($jumlah) }}</td>
@endforeach
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="row g-6 py-4">
<div class="col-lg-6 col-sm-12">
<div class="card h-100">
<div class="card-header d-flex justify-content-between align-items-center">
@@ -244,115 +195,124 @@
</div>
</div>
<div class="card-body">
<table class="table card-table table-border-top-0 table-border-bottom-0">
<table class="table card-table table-border-top-0 table-border-bottom-0 data-table">
<thead>
<tr>
<th></th>
<th class="text-end pe-0">Indeks</th>
<th class="text-end pe-0">D1</th>
<th class="text-end pe-0">D2</th>
<th class="text-end pe-0">D3</th>
</tr>
</thead>
<tbody>
@foreach ($segments as $segment)
@php
$skor = $skorMultiDimensi->firstWhere('segmen', $segment['name']);
@endphp
<tr>
<td class="w-60 ps-0"></td>
<td class="text-end pe-0">Indeks</td>
<td class="text-end pe-0">D1</td>
<td class="text-end pe-0">D2</td>
<td class="text-end pe-0">D3</td>
</tr>
<tr>
<td class="w-60 ps-0">
<td>
<div class="d-flex justify-content-start align-items-center">
<div class="me-2">
<i class="icon-base ti tabler-crown icon-lg text-heading"></i>
<i class="icon-base ti {{ $segment['icon'] }} icon-lg text-{{ $segment['color'] }}"></i>
</div>
<div>
<h6 class="mb-0 fw-normal text-success">Penggerak (4.0 - 5.0)</h6>
<!-- <small class="text-body-secondary text-wrap">Siap menjadi peserta agrolab utama dan panutan bagi petani lain</small> -->
<h6 class="mb-0 fw-normal text-{{ $segment['color'] }}">
{{ $segment['name'] }}
<small class="text-body-secondary">({{ $segment['range'] }})</small>
</h6>
</div>
</div>
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Penggerak')->value('skor_kesiapan_adopsi'), 2, '.', ',') }}</span>
{{ number_format($skor?->skor_kesiapan_adopsi ?? 0, 2, '.', ',') }}
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Penggerak')->value('skor_d2_sistem_praktik_budidaya'), 2, '.', ',') }}</span>
{{ number_format($skor?->skor_d2_sistem_praktik_budidaya ?? 0, 2, '.', ',') }}
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Penggerak')->value('skor_d4_sosial_ekonomi'), 2, '.', ',') }}</span>
{{ number_format($skor?->skor_d4_sosial_ekonomi ?? 0, 2, '.', ',') }}
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Penggerak')->value('skor_d6_rantai_nilai_akses_pasar'), 2, '.', ',') }}</span>
{{ number_format($skor?->skor_d6_rantai_nilai_akses_pasar ?? 0, 2, '.', ',') }}
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
<div class="col-lg-6 col-sm-12">
<div class="card h-100">
<div class="card-header d-flex justify-content-between align-items-center">
<div class="card-title mb-0">
<h5 class="m-0 me-2">Segmentasi Multi Komponen Petani</h5>
<p class="card-subtitle">untuk semua komoditas</p>
</div>
</div>
<div class="card-body">
<table class="table card-table table-border-top-0 table-border-bottom-0 data-table">
<thead>
<tr>
<td class="w-60 ps-0">
<th></th>
<th class="text-end pe-0">Indeks</th>
<th class="text-end pe-0">K1</th>
<th class="text-end pe-0">K2</th>
<th class="text-end pe-0">K3</th>
<th class="text-end pe-0">K4</th>
<th class="text-end pe-0">K5</th>
<th class="text-end pe-0">K6</th>
</tr>
</thead>
<tbody>
@foreach ($segments as $segment)
@php
$skor = $skorMultiKomponen->firstWhere('segmen', $segment['name']);
@endphp
<tr>
<td class="">
<div class="d-flex justify-content-start align-items-center">
<div class="me-2">
<i class="icon-base ti tabler-flag icon-lg text-heading"></i>
<i class="icon-base ti {{ $segment['icon'] }} icon-lg text-{{ $segment['color'] }}"></i>
</div>
<div>
<h6 class="mb-0 fw-normal text-info">Perintis (3.0 - 3.9)</h6>
<!-- <small class="text-body-secondary text-wrap">Berpotensi berkembang menjadi Penggerak dengan dukungan yang tepat</small> -->
<h6 class="mb-0 fw-normal text-{{ $segment['color'] }}">
{{ $segment['name'] }}
<small class="text-body-secondary">({{ $segment['range'] }})</small>
</h6>
</div>
</div>
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Perintis')->value('skor_kesiapan_adopsi'), 2, '.', ',') }}</span>
<span>{{ number_format($skor?->skor_kesiapan_adopsi, 2, '.', ',') }}</span>
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Perintis')->value('skor_d2_sistem_praktik_budidaya'), 2, '.', ',') }}</span>
<span>{{ number_format($skor?->skor_komp_1_d4_k3_motivasi_kapasitas_adopsi, 2, '.', ',') }}</span>
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Perintis')->value('skor_d4_sosial_ekonomi'), 2, '.', ',') }}</span>
<span>{{ number_format($skor?->skor_komp_2_d4_k2_ekonomi_rumah_tangga, 2, '.', ',') }}</span>
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Perintis')->value('skor_d6_rantai_nilai_akses_pasar'), 2, '.', ',') }}</span>
<span>{{ number_format($skor?->skor_komp_3_d2_praktik_budidaya_gap, 2, '.', ',') }}</span>
</td>
</tr>
<tr>
<td class="w-60 ps-0">
<div class="d-flex justify-content-start align-items-center">
<div class="me-2">
<i class="icon-base ti tabler-eye icon-lg text-heading text-success"></i>
</div>
<div>
<h6 class="mb-0 fw-normal text-warning">Pemerhati (2.0 - 2.9)</h6>
<!-- <small class="text-body-secondary text-wrap">Perlu melihat bukti hasil nyata dari Penggerak sebelum mau bergerak</small> -->
</div>
</div>
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Pemerhati')->value('skor_kesiapan_adopsi'), 2, '.', ',') }}</span>
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Pemerhati')->value('skor_d2_sistem_praktik_budidaya'), 2, '.', ',') }}</span>
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Pemerhati')->value('skor_d4_sosial_ekonomi'), 2, '.', ',') }}</span>
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Pemerhati')->value('skor_d6_rantai_nilai_akses_pasar'), 2, '.', ',') }}</span>
</td>
</tr>
<tr>
<td class="w-60 ps-0">
<div class="d-flex justify-content-start align-items-center">
<div class="me-2">
<i class="icon-base ti tabler-seedling icon-lg text-heading"></i>
</div>
<div>
<h6 class="mb-0 fw-normal text-danger">Pemula (1.0 - 1.9)</h6>
<!-- <small class="text-body-secondary text-wrap">Butuh penanganan hambatan dasar terlebih dahulu sebelum intervensi langsung</small> -->
</div>
</div>
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Pemula')->value('skor_kesiapan_adopsi'), 2, '.', ',') }}</span>
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Pemula')->value('skor_d2_sistem_praktik_budidaya'), 2, '.', ',') }}</span>
<span>{{ number_format($skor?->skor_komp_4_d4_k4_keterlibatan_kelembagaan, 2, '.', ',') }}</span>
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Pemula')->value('skor_d4_sosial_ekonomi'), 2, '.', ',') }}</span>
<span>{{ number_format($skor?->skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan, 2, '.', ',') }}</span>
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Pemula')->value('skor_d6_rantai_nilai_akses_pasar'), 2, '.', ',') }}</span>
<span>{{ number_format($skor?->skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar, 2, '.', ',') }}</span>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
@@ -443,6 +403,13 @@
<th>D2</th>
<th>D4</th>
<th>D6</th>
<th>K1</th>
<th>K2</th>
<th>K3</th>
<th>K4</th>
<th>K5</th>
<th>K6</th>
</tr>
</thead>
<tbody>
@foreach ($petani as $item)
@@ -466,6 +433,12 @@
<td>{{ number_format($item->skor?->skor_d2_sistem_praktik_budidaya, 2, '.', ',') }}</td>
<td>{{ number_format($item->skor?->skor_d4_sosial_ekonomi, 2, '.', ',') }}</td>
<td>{{ number_format($item->skor?->skor_d6_rantai_nilai_akses_pasar, 2, '.', ',') }}</td>
<td>{{ number_format($item->skor?->skor_komp_1_d4_k3_motivasi_kapasitas_adopsi, 2, '.', ',') }}</td>
<td>{{ number_format($item->skor?->skor_komp_2_d4_k2_ekonomi_rumah_tangga, 2, '.', ',') }}</td>
<td>{{ number_format($item->skor?->skor_komp_3_d2_praktik_budidaya_gap, 2, '.', ',') }}</td>
<td>{{ number_format($item->skor?->skor_komp_4_d4_k4_keterlibatan_kelembagaan, 2, '.', ',') }}</td>
<td>{{ number_format($item->skor?->skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan, 2, '.', ',') }}</td>
<td>{{ number_format($item->skor?->skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar, 2, '.', ',') }}</td>
</tr>
@endforeach
</tbody>
@@ -484,6 +457,17 @@
<script>
$(document).ready(function() {
$('.data-table').DataTable({
"paging": false,
"lengthChange": true,
"searching": false,
"ordering": false,
"info": false,
"autoWidth": false,
"responsive": false,
"scrollX": true
});
$("#tabel-petani").DataTable({
"paging": true,
"lengthChange": true,
@@ -491,7 +475,8 @@
"ordering": false,
"info": true,
"autoWidth": false,
"responsive": true,
"responsive": false,
"scrollX": true
})
@@ -401,6 +401,10 @@
Petani
</th>
<th style="font-size:10px;letter-spacing:.7px;text-transform:uppercase">
Komoditas
</th>
<th class="text-center"
style="font-size:10px;letter-spacing:.7px;text-transform:uppercase">
Lahan
@@ -474,19 +478,28 @@
</div>
</td>
<td>
<span
class="badge bg-label-secondary text-secondary"
title="{{ $petani['komoditas'] }}"
>
{{ $petani['komoditas'] }}
</span>
</td>
@foreach ($petani['status'] as $status)
<td class="text-center">
@if ($status['done'])
<span
class="badge rounded-pill bg-label-success text-success"
title="{{ $status['label'] }} sudah diisi"
title="{{ $status['label'] }} lengkap"
>
<i class="ti tabler-check"></i>
</span>
@else
<span
class="badge rounded-pill bg-label-secondary text-secondary"
title="{{ $status['label'] }} belum diisi"
title="{{ $status['label'] }} belum lengkap"
>
<i class="ti tabler-minus"></i>
</span>
@@ -533,7 +546,7 @@
</tr>
@empty
<tr>
<td colspan="7" class="text-center text-muted py-4">
<td colspan="8" class="text-center text-muted py-4">
Belum ada data petani.
</td>
</tr>
@@ -818,4 +831,4 @@
</div>
</div>
</div>
@endsection
@endsection
@@ -0,0 +1,306 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
@include('koperasi.profil.header', ['pengurus' => $pengurus])
<div class="card shadow-sm border-0 mb-4">
<div class="card-body p-0">
<form action="{{ route('koperasi.pengurus.survey.store', ['id' => $pengurus->id ?? 0, 'step' => 1]) }}" method="POST" class="p-4 p-md-5">
@csrf
<input type="hidden" name="pengurus_koperasi_id" value="{{ $pengurus->id ?? '' }}">
<h5 class="text-muted fw-bold border-bottom pb-2 mb-2">KELEMBAGAAN & AKTOR SISTEM</h5>
<p class="text-muted small mb-3">Memetakan potensi dan kesiapan koperasi sebagai agregator atau mitra pengelola rantai nilai komoditas.</p>
<h5 class="text-muted pb-2 mt-7 mb-5">KOPERASI & BUMDes</h5>
<h5 class="pb-3 border-bottom mb-5 mt-7">Keberadaan Koperasi</h5>
<div class="mb-4">
<h6 class="form-label">Bagaimana sejarah awal pendirian koperasi/CU bapak/ibu? Apa tujuan/cita-cita bersama yang ingin dicapai saat itu?</h6>
<textarea class="form-control" name="sejarah_lembaga" rows="3" placeholder="Ceritakan sejarah singkat...">{{ old('sejarah_lembaga', $pengurus->sejarah_lembaga) }}</textarea>
</div>
<div class="row mb-4">
<div class="col-md-6 mb-3">
<h6 class="form-label">Apakah koperasi ini memiliki fokus pada pengembangan komoditas pertanian tertentu?</h6>
<div class="form-check mb-2">
<input class="form-check-input trigger-toggle" type="radio" name="fokus_komoditas" value="Tidak" id="fokusTidak" data-target="fokusYaInput" data-action="hide" {{ old('fokus_komoditas', $pengurus->fokus_komoditas) == 'Tidak' ? 'checked' : '' }}>
<label class="form-check-label" for="fokusTidak">Tidak</label>
</div>
<div class="form-check d-flex align-items-center gap-2">
<input class="form-check-input trigger-toggle" type="radio" name="fokus_komoditas" value="Ya" id="fokusYa" data-target="fokusYaInput" data-action="show" {{ old('fokus_komoditas', $pengurus->fokus_komoditas) == 'Ya' ? 'checked' : '' }}>
<label class="form-check-label text-nowrap" for="fokusYa">Ya, sebutkan:</label>
<input type="text" class="form-control form-control-sm w-75 {{ old('fokus_komoditas', $pengurus->fokus_komoditas) == 'Ya' ? '' : 'd-none' }}" id="fokusYaInput" name="detail_fokus_komoditas" placeholder="Contoh: Kopi, Vanili" value="{{ old('detail_fokus_komoditas', $pengurus->detail_fokus_komoditas) }}">
</div>
</div>
<div class="col-md-6 mb-3">
<h6 class="form-label">Apakah ada dokumen kelembagaan (AD/ART)?</h6>
<div class="form-check d-flex align-items-center gap-2 mb-2">
<input class="form-check-input trigger-toggle" type="radio" name="ad_art" value="Ada, lengkap" id="adArtAda" data-target="adArtTahun" data-action="show" {{ old('ad_art', $pengurus->ad_art) == 'Ada, lengkap' ? 'checked' : '' }}>
<label class="form-check-label text-nowrap" for="adArtAda">Ada, lengkap, terakhir diperbarui tahun:</label>
<input type="number" class="form-control form-control-sm w-25 {{ old('ad_art', $pengurus->ad_art) == 'Ada, lengkap' ? '' : 'd-none' }}" id="adArtTahun" name="tahun_ad_art" placeholder="2020" value="{{ old('tahun_ad_art', $pengurus->tahun_ad_art) }}">
</div>
<div class="form-check"><input class="form-check-input trigger-toggle" type="radio" name="ad_art" value="Ada tapi tidak lengkap" data-target="adArtTahun" data-action="hide" {{ old('ad_art', $pengurus->ad_art) == 'Ada tapi tidak lengkap' ? 'checked' : '' }}><label class="form-check-label">Ada tapi tidak lengkap</label></div>
<div class="form-check"><input class="form-check-input trigger-toggle" type="radio" name="ad_art" value="Tidak ada" data-target="adArtTahun" data-action="hide" {{ old('ad_art', $pengurus->ad_art) == 'Tidak ada' ? 'checked' : '' }}><label class="form-check-label">Tidak ada</label></div>
<div class="form-check"><input class="form-check-input trigger-toggle" type="radio" name="ad_art" value="Tidak tahu" data-target="adArtTahun" data-action="hide" {{ old('ad_art', $pengurus->ad_art) == 'Tidak tahu' ? 'checked' : '' }}><label class="form-check-label">Tidak tahu</label></div>
</div>
</div>
<h5 class="pb-3 border-bottom mb-10 mt-4">Ketersediaan Layanan</h5>
<div class="mb-4">
<h6 class="form-label">Apa saja layanan yang disediakan oleh koperasi bapak/ibu untuk anggota koperasi?</h6>
<div class="form-check"><input class="form-check-input" type="checkbox" name="layanan_koperasi[]" value="Simpan pinjam" id="cekSimpanPinjam" {{ str_contains($pengurus->layanan_koperasi ?? '', 'Simpan pinjam') ? 'checked' : '' }}><label class="form-check-label">Simpan pinjam</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" name="layanan_koperasi[]" value="Pengadaan input produksi" {{ str_contains($pengurus->layanan_koperasi ?? '', 'Pengadaan input produksi') ? 'checked' : '' }}><label class="form-check-label">Pengadaan input produksi</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" name="layanan_koperasi[]" value="Pemasaran hasil" {{ str_contains($pengurus->layanan_koperasi ?? '', 'Pemasaran hasil') ? 'checked' : '' }}><label class="form-check-label">Pemasaran hasil</label></div>
<div class="form-check d-flex align-items-center gap-2 mt-2">
<input class="form-check-input trigger-toggle-check" type="checkbox" name="layanan_koperasi[]" value="Lainnya" data-target="layananLainnya" {{ str_contains($pengurus->layanan_koperasi ?? '', 'Lainnya') ? 'checked' : '' }}>
<label class="form-check-label text-nowrap">Lainnya, sebutkan:</label>
<input type="text" class="form-control form-control-sm w-50 {{ str_contains($pengurus->layanan_koperasi ?? '', 'Lainnya') ? '' : 'd-none' }}" id="layananLainnya" name="layanan_lainnya" placeholder="..." value="{{ old('layanan_lainnya', $pengurus->layanan_lainnya) }}">
</div>
</div>
<div class="mb-10">
<h6 class="form-label">Apakah terdapat program/pelatihan untuk meningkatkan kapasitas anggota koperasi?</h6>
<div class="table-responsive mb-5">
<table class="table table-sm w-75">
<thead class="table-primary ">
<tr><th style="border-top-left-radius: 8px; border-bottom-left-radius: 8px; border: none;">Jenis Pelatihan</th><th class="text-center " style="width: 100px; border: none;">Ya</th><th class="text-center" style="border-top-right-radius: 8px; border-bottom-right-radius: 8px; width: 100px; border: none;">Tidak</th></tr>
</thead>
<tbody>
<tr><td>Pelatihan produksi pertanian</td><td class="text-center"><input class="form-check-input" type="radio" name="pelatihan_produksi" value="Ya" {{ old('pelatihan_produksi', $pengurus->pelatihan_produksi) == 'Ya' ? 'checked' : '' }}></td><td class="text-center"><input class="form-check-input" type="radio" name="pelatihan_produksi" value="Tidak" {{ old('pelatihan_produksi', $pengurus->pelatihan_produksi) == 'Tidak' ? 'checked' : '' }}></td></tr>
<tr><td>Pelatihan penanganan pascapanen</td><td class="text-center"><input class="form-check-input" type="radio" name="pelatihan_pascapanen" value="Ya" {{ old('pelatihan_pascapanen', $pengurus->pelatihan_pascapanen) == 'Ya' ? 'checked' : '' }}></td><td class="text-center"><input class="form-check-input" type="radio" name="pelatihan_pascapanen" value="Tidak" {{ old('pelatihan_pascapanen', $pengurus->pelatihan_pascapanen) == 'Tidak' ? 'checked' : '' }}></td></tr>
<tr><td>Pelatihan pengolahan produk (setengah jadi/jadi)</td><td class="text-center"><input class="form-check-input" type="radio" name="pelatihan_pengolahan" value="Ya" {{ old('pelatihan_pengolahan', $pengurus->pelatihan_pengolahan) == 'Ya' ? 'checked' : '' }}></td><td class="text-center"><input class="form-check-input" type="radio" name="pelatihan_pengolahan" value="Tidak" {{ old('pelatihan_pengolahan', $pengurus->pelatihan_pengolahan) == 'Tidak' ? 'checked' : '' }}></td></tr>
<tr><td>Pelatihan manajemen keuangan/pembukuan</td><td class="text-center"><input class="form-check-input" type="radio" name="pelatihan_keuangan" value="Ya" {{ old('pelatihan_keuangan', $pengurus->pelatihan_keuangan) == 'Ya' ? 'checked' : '' }}></td><td class="text-center"><input class="form-check-input" type="radio" name="pelatihan_keuangan" value="Tidak" {{ old('pelatihan_keuangan', $pengurus->pelatihan_keuangan) == 'Tidak' ? 'checked' : '' }}></td></tr>
<tr><td>Pelatihan pengemasan dan pemasaran</td><td class="text-center"><input class="form-check-input" type="radio" name="pelatihan_pemasaran" value="Ya" {{ old('pelatihan_pemasaran', $pengurus->pelatihan_pemasaran) == 'Ya' ? 'checked' : '' }}></td><td class="text-center"><input class="form-check-input" type="radio" name="pelatihan_pemasaran" value="Tidak" {{ old('pelatihan_pemasaran', $pengurus->pelatihan_pemasaran) == 'Tidak' ? 'checked' : '' }}></td></tr>
</tbody>
</table>
</div>
<div class="d-flex align-items-center gap-2 mt-2 mb-5">
<label class="form-label mb-0">Lainnya, sebutkan:</label>
<input type="text" class="form-control form-control-sm w-50" name="pelatihan_lainnya" placeholder="Pelatihan lainnya..." value="{{ old('pelatihan_lainnya', $pengurus->pelatihan_lainnya) }}">
</div>
</div>
<h5 class="pb-3 border-bottom mb-10 mt-4">Kapasitas Pengelolaan</h5>
<div class="row mb-4">
<div class="col-md-6 mb-1">
<h6 class="form-label">Apakah sudah ada pencatatan/pembukuan keuangan?</h6>
<div class="form-check"><input class="form-check-input" type="radio" name="status_pembukuan" value="Sudah" {{ old('status_pembukuan', $pengurus->status_pembukuan) == 'Sudah' ? 'checked' : '' }}><label class="form-check-label">Sudah</label></div>
<div class="form-check"><input class="form-check-input" type="radio" name="status_pembukuan" value="Belum ada" {{ old('status_pembukuan', $pengurus->status_pembukuan) == 'Belum ada' ? 'checked' : '' }}><label class="form-check-label">Belum ada</label></div>
</div>
<div class="col-md-6 mb-3">
<h6 class="form-label">Format pembukuan yang dilakukan:</h6>
<div class="form-check"><input class="form-check-input" type="radio" name="format_pembukuan" value="Manual/buku kas" {{ old('format_pembukuan', $pengurus->format_pembukuan) == 'Manual/buku kas' ? 'checked' : '' }}><label class="form-check-label">Manual/buku kas</label></div>
<div class="form-check"><input class="form-check-input" type="radio" name="format_pembukuan" value="Digital/file Excel" {{ old('format_pembukuan', $pengurus->format_pembukuan) == 'Digital/file Excel' ? 'checked' : '' }}><label class="form-check-label">Digital/file Excel</label></div>
<div class="form-check"><input class="form-check-input" type="radio" name="format_pembukuan" value="Aplikasi khusus" {{ old('format_pembukuan', $pengurus->format_pembukuan) == 'Aplikasi khusus' ? 'checked' : '' }}><label class="form-check-label">Aplikasi keuangan khusus</label></div>
<div class="form-check"><input class="form-check-input" type="radio" name="format_pembukuan" value="Tidak ada" {{ old('format_pembukuan', $pengurus->format_pembukuan) == 'Tidak ada' ? 'checked' : '' }}><label class="form-check-label">Tidak ada</label></div>
</div>
</div>
<div class="mb-4">
<h6 class="form-label mb-3">Berapa kali diadakan pertemuan rutin anggota koperasi untuk membahas <br> rencana kerja dan pertanggungjawaban keuangan?</h6>
<div class="form-check"><input class="form-check-input trigger-toggle" type="radio" name="pertemuan_rutin" value="Satu bulan sekali" data-target="pertemuanLainnya" data-action="hide" {{ old('pertemuan_rutin', $pengurus->pertemuan_rutin) == 'Satu bulan sekali' ? 'checked' : '' }}><label class="form-check-label">Satu bulan sekali</label></div>
<div class="form-check "><input class="form-check-input trigger-toggle" type="radio" name="pertemuan_rutin" value="Satu tahun sekali" data-target="pertemuanLainnya" data-action="hide" {{ old('pertemuan_rutin', $pengurus->pertemuan_rutin) == 'Satu tahun sekali' ? 'checked' : '' }}><label class="form-check-label">Satu tahun sekali</label></div>
<div class="form-check form-check-inline d-inline-flex align-items-center gap-2">
<input class="form-check-input trigger-toggle" type="radio" name="pertemuan_rutin" value="Lainnya" data-target="pertemuanLainnya" data-action="show" {{ old('pertemuan_rutin', $pengurus->pertemuan_rutin) == 'Lainnya' ? 'checked' : '' }}>
<label class="form-check-label text-nowrap">Lainnya:</label>
<input type="text" class="form-control form-control-sm {{ old('pertemuan_rutin', $pengurus->pertemuan_rutin) == 'Lainnya' ? '' : 'd-none' }}" id="pertemuanLainnya" name="pertemuan_lainnya" placeholder="..." value="{{ old('pertemuan_lainnya', $pengurus->pertemuan_lainnya) }}">
</div>
</div>
<div id="blok-simpan-pinjam" class="p-3 mb-4 rounded border border-primary bg-label-primary {{ str_contains($pengurus->layanan_koperasi ?? '', 'Simpan pinjam') ? '' : 'd-none' }}">
<h6 class="fw-bold text-primary mb-3"><i class="ti tabler-info-circle me-1"></i>Khusus Koperasi Simpan Pinjam</h6>
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label">Tingkat/persentase kredit macet di koperasi?</label>
<select class="form-select form-select-sm" name="kasus_kredit_macet">
<option value="" selected disabled>Pilih...</option>
<option value="<10%" {{ old('kasus_kredit_macet', $pengurus->kasus_kredit_macet) == '<10%' ? 'selected' : '' }}> < 10% </option>
<option value="10-25%" {{ old('kasus_kredit_macet', $pengurus->kasus_kredit_macet) == '10-25%' ? 'selected' : '' }}>10 - 25%</option>
<option value="25-50%" {{ old('kasus_kredit_macet', $pengurus->kasus_kredit_macet) == '25-50%' ? 'selected' : '' }}>25 - 50%</option>
<option value="50-75%" {{ old('kasus_kredit_macet', $pengurus->kasus_kredit_macet) == '50-75%' ? 'selected' : '' }}>50 - 75%</option>
<option value=">75%" {{ old('kasus_kredit_macet', $pengurus->kasus_kredit_macet) == '>75%' ? 'selected' : '' }}> > 75% </option>
</select>
</div>
<div class="col-md-6 mb-3">
<label class="form-label">Apakah ada sanksi untuk anggota dengan kredit macet?</label>
<div class="form-check form-check-inline"><input class="form-check-input" type="radio" name="sanksi_kredit_macet" value="Ada" {{ old('sanksi_kredit_macet', $pengurus->sanksi_kredit_macet) == 'Ada' ? 'checked' : '' }}><label class="form-check-label">Ada</label></div>
<div class="form-check form-check-inline"><input class="form-check-input" type="radio" name="sanksi_kredit_macet" value="Tidak ada" {{ old('sanksi_kredit_macet', $pengurus->sanksi_kredit_macet) == 'Tidak ada' ? 'checked' : '' }}><label class="form-check-label">Tidak ada</label></div>
</div>
<div class="col-md-6 mb-3">
<label class="form-label">Jika ada, apakah sanksi tersebut efektif?</label>
<select class="form-select form-select-sm" name="efektivitas_sanksi">
<option value="" selected disabled>Pilih efektivitas...</option>
<option value="Sangat efektif" {{ old('efektivitas_sanksi', $pengurus->efektivitas_sanksi) == 'Sangat efektif' ? 'selected' : '' }}>Sangat efektif</option>
<option value="Efektif" {{ old('efektivitas_sanksi', $pengurus->efektivitas_sanksi) == 'Efektif' ? 'selected' : '' }}>Efektif</option>
<option value="Biasa Saja" {{ old('efektivitas_sanksi', $pengurus->efektivitas_sanksi) == 'Biasa Saja' ? 'selected' : '' }}>Biasa Saja</option>
<option value="Kurang Efektif" {{ old('efektivitas_sanksi', $pengurus->efektivitas_sanksi) == 'Kurang Efektif' ? 'selected' : '' }}>Kurang Efektif</option>
<option value="Tidak Efektif" {{ old('efektivitas_sanksi', $pengurus->efektivitas_sanksi) == 'Tidak Efektif' ? 'selected' : '' }}>Tidak Efektif</option>
</select>
</div>
</div>
</div>
<div class="mb-10">
<h6 class="form-label mb-3">Apa faktor utama yang menyebabkan manajemen pengelolaan dalam koperasi efektif/tidak efektif?</h6>
<div class="form-check "><input class="form-check-input" type="checkbox" name="faktor_manajemen[]" value="Rasa saling percaya" {{ str_contains($pengurus->faktor_manajemen ?? '', 'Rasa saling percaya') ? 'checked' : '' }}><label class="form-check-label">Rasa saling percaya</label></div>
<div class="form-check "><input class="form-check-input" type="checkbox" name="faktor_manajemen[]" value="Kepemimpinan koperasi" {{ str_contains($pengurus->faktor_manajemen ?? '', 'Kepemimpinan koperasi') ? 'checked' : '' }}><label class="form-check-label">Kepemimpinan koperasi</label></div>
<div class="form-check "><input class="form-check-input" type="checkbox" name="faktor_manajemen[]" value="Jumlah anggota" {{ str_contains($pengurus->faktor_manajemen ?? '', 'Jumlah anggota') ? 'checked' : '' }}><label class="form-check-label">Jumlah anggota</label></div>
<div class="form-check "><input class="form-check-input" type="checkbox" name="faktor_manajemen[]" value="Catatan/pembukuan rapi" {{ str_contains($pengurus->faktor_manajemen ?? '', 'Catatan/pembukuan rapi') ? 'checked' : '' }}><label class="form-check-label">Catatan/pembukuan rapi</label></div>
<div class="form-check d-inline-flex align-items-center gap-2 mt-2 mt-md-0">
<input class="form-check-input trigger-toggle-check" type="checkbox" name="faktor_manajemen[]" value="Lainnya" data-target="faktorLainnya" {{ str_contains($pengurus->faktor_manajemen ?? '', 'Lainnya') ? 'checked' : '' }}>
<label class="form-check-label text-nowrap">Lainnya, Sebutkan:</label>
<input type="text" class="form-control form-control-sm {{ str_contains($pengurus->faktor_manajemen ?? '', 'Lainnya') ? '' : 'd-none' }}" id="faktorLainnya" name="faktor_manajemen_lainnya" placeholder="..." value="{{ old('faktor_manajemen_lainnya', $pengurus->faktor_manajemen_lainnya) }}">
</div>
</div>
<h5 class="pb-3 border-bottom mb-10 mt-4">Pengalaman dalam mengelola rantai nilai komoditas pertanian</h5>
<div class="mb-4">
<label class="form-label">Apakah koperasi Bapak/Ibu terlibat dalam proses rantai nilai berikut ini?</label>
<div class="row g-2">
<div class="col-md-6"><div class="form-check"><input class="form-check-input" type="checkbox" name="keterlibatan_rantai_nilai[]" value="Penyediaan input" {{ str_contains($pengurus->keterlibatan_rantai_nilai ?? '', 'Penyediaan input') ? 'checked' : '' }}><label class="form-check-label">Penyediaan input (pupuk, bibit, dll)</label></div></div>
<div class="col-md-6"><div class="form-check"><input class="form-check-input" type="checkbox" name="keterlibatan_rantai_nilai[]" value="Agregasi" {{ str_contains($pengurus->keterlibatan_rantai_nilai ?? '', 'Agregasi') ? 'checked' : '' }}><label class="form-check-label">Agregasi (pengumpulan) produk pertanian dan perkebunan</label></div></div>
<div class="col-md-6"><div class="form-check"><input class="form-check-input" type="checkbox" name="keterlibatan_rantai_nilai[]" value="Pemasaran mentah" {{ str_contains($pengurus->keterlibatan_rantai_nilai ?? '', 'Pemasaran mentah') ? 'checked' : '' }}><label class="form-check-label">Pemasaran produk mentah (belum diolah)</label></div></div>
<div class="col-md-6"><div class="form-check"><input class="form-check-input" type="checkbox" name="keterlibatan_rantai_nilai[]" value="Pengolahan barang jadi" {{ str_contains($pengurus->keterlibatan_rantai_nilai ?? '', 'Pengolahan barang jadi') ? 'checked' : '' }}><label class="form-check-label">Pengolahan produk pangan menjadi bahan setengah jadi/barang jadi</label></div></div>
<div class="col-md-6"><div class="form-check"><input class="form-check-input" type="checkbox" name="keterlibatan_rantai_nilai[]" value="Pemasaran olahan" {{ str_contains($pengurus->keterlibatan_rantai_nilai ?? '', 'Pemasaran olahan') ? 'checked' : '' }}><label class="form-check-label">Pemasaran produk pertanian olahan</label></div></div>
<div class="col-md-6"><div class="form-check"><input class="form-check-input" type="checkbox" name="keterlibatan_rantai_nilai[]" value="Jual langsung konsumen" {{ str_contains($pengurus->keterlibatan_rantai_nilai ?? '', 'Jual langsung konsumen') ? 'checked' : '' }}><label class="form-check-label">Penjualan langsung ke konsumen akhir</label></div></div>
<div class="col-md-6"><div class="form-check"><input class="form-check-input" type="checkbox" name="keterlibatan_rantai_nilai[]" value="Tidak terlibat kegiatan di atas" {{ str_contains($pengurus->keterlibatan_rantai_nilai ?? '', 'Tidak terlibat kegiatan di atas') ? 'checked' : '' }}><label class="form-check-label">Tidak terlibat kegiatan di atas</label></div></div>
</div>
</div>
<div class="mb-10">
<h6 class="mb-3">Jika terlibat dalam proses agregasi, komoditas apa saja yang di agregasi oleh koperasi?</h6>
<div class="form-check form-check-inline mt-2"><input class="form-check-input opsi-agregasi" type="checkbox" name="agregasi_komoditas[]" value="Kopi" {{ str_contains($pengurus->agregasi_komoditas ?? '', 'Kopi') ? 'checked' : '' }}><label class="form-check-label">Kopi</label></div>
<div class="form-check form-check-inline mt-2"><input class="form-check-input opsi-agregasi" type="checkbox" name="agregasi_komoditas[]" value="Kakao" {{ str_contains($pengurus->agregasi_komoditas ?? '', 'Kakao') ? 'checked' : '' }}><label class="form-check-label">Kakao</label></div>
<div class="form-check form-check-inline mt-2"><input class="form-check-input opsi-agregasi" type="checkbox" name="agregasi_komoditas[]" value="Vanili" {{ str_contains($pengurus->agregasi_komoditas ?? '', 'Vanili') ? 'checked' : '' }}><label class="form-check-label">Vanili</label></div>
<div class="form-check form-check-inline mt-2"><input class="form-check-input opsi-agregasi" type="checkbox" name="agregasi_komoditas[]" value="Kemiri" {{ str_contains($pengurus->agregasi_komoditas ?? '', 'Kemiri') ? 'checked' : '' }}><label class="form-check-label">Kemiri</label></div>
<div class="form-check form-check-inline d-inline-flex align-items-center gap-2 mt-2">
<input class="form-check-input trigger-toggle-check opsi-agregasi" type="checkbox" name="agregasi_komoditas[]" value="Lainnya" data-target="komoditasLainnya" {{ str_contains($pengurus->agregasi_komoditas ?? '', 'Lainnya') ? 'checked' : '' }}>
<label class="form-check-label text-nowrap">Lainnya, sebutkan:</label>
<input type="text" class="form-control form-control-sm w-auto {{ str_contains($pengurus->agregasi_komoditas ?? '', 'Lainnya') ? '' : 'd-none' }}" id="komoditasLainnya" name="agregasi_komoditas_lainnya" placeholder="..." value="{{ old('agregasi_komoditas_lainnya', $pengurus->agregasi_komoditas_lainnya) }}">
</div>
<div class="form-check mt-3">
<input class="form-check-input" type="checkbox" name="agregasi_komoditas[]" value="Tidak terlibat" id="triggerSkipD6" {{ str_contains($pengurus->agregasi_komoditas ?? '', 'Tidak terlibat') ? 'checked' : '' }}>
<label class="form-check-label" for="triggerSkipD6">Tidak terlibat proses agregasi <small class="text-danger">(Mencentang ini akan melewati bagian D6)</small></label>
</div>
</div>
<div id="blok-sisa-d5" style="{{ str_contains($pengurus->agregasi_komoditas ?? '', 'Tidak terlibat') ? 'display: none;' : 'display: block;' }}">
<div class="mb-10">
<h6 class="mb-3">Fasilitas pengolahan pascapanen apa saja yang dikelola oleh koperasi saat ini?</h6>
<div class="form-check form-check-inline"><input class="form-check-input" type="checkbox" name="fasilitas_koperasi[]" value="Gudang penyimpanan" {{ str_contains($pengurus->fasilitas_koperasi ?? '', 'Gudang penyimpanan') ? 'checked' : '' }}><label class="form-check-label">Gudang</label></div>
<div class="form-check form-check-inline"><input class="form-check-input" type="checkbox" name="fasilitas_koperasi[]" value="Alat pengering" {{ str_contains($pengurus->fasilitas_koperasi ?? '', 'Alat pengering') ? 'checked' : '' }}><label class="form-check-label">Alat pengering</label></div>
<div class="form-check form-check-inline"><input class="form-check-input" type="checkbox" name="fasilitas_koperasi[]" value="Mesin pemecah" {{ str_contains($pengurus->fasilitas_koperasi ?? '', 'Mesin pemecah') ? 'checked' : '' }}><label class="form-check-label">Mesin pemecah</label></div>
<div class="form-check form-check-inline"><input class="form-check-input" type="checkbox" name="fasilitas_koperasi[]" value="Mesin penggiling" {{ str_contains($pengurus->fasilitas_koperasi ?? '', 'Mesin penggiling') ? 'checked' : '' }}><label class="form-check-label">Mesin penggiling</label></div>
<div class="form-check form-check-inline"><input class="form-check-input" type="checkbox" name="fasilitas_koperasi[]" value="Mesin sortasi" {{ str_contains($pengurus->fasilitas_koperasi ?? '', 'Mesin sortasi') ? 'checked' : '' }}><label class="form-check-label">Mesin sortasi</label></div>
<div class="form-check form-check-inline d-inline-flex align-items-center gap-2">
<input class="form-check-input trigger-toggle-check" type="checkbox" name="fasilitas_koperasi[]" value="Lainnya" data-target="fasilitasLainnya" {{ str_contains($pengurus->fasilitas_koperasi ?? '', 'Lainnya') ? 'checked' : '' }}>
<label class="form-check-label text-nowrap">Lainnya:</label>
<input type="text" class="form-control form-control-sm {{ str_contains($pengurus->fasilitas_koperasi ?? '', 'Lainnya') ? '' : 'd-none' }}" id="fasilitasLainnya" name="fasilitas_lainnya" placeholder="..." value="{{ old('fasilitas_lainnya', $pengurus->fasilitas_lainnya) }}">
</div>
</div>
<div class="mb-10">
<h6 class="mb-3">Apakah koperasi melakukan pengolahan lanjutan untuk menaikkan nilai jual <br> (seperti pengeringan, fermentasi, penepungan, pengemasan)?</h6>
<div class="form-check d-flex align-items-center gap-2 mb-2">
<input class="form-check-input trigger-toggle" type="radio" name="pengolahan_lanjutan" value="Ya" id="pengolahanYa" data-target="pengolahanYaInput" data-action="show" {{ old('pengolahan_lanjutan', $pengurus->pengolahan_lanjutan) == 'Ya' ? 'checked' : '' }}>
<label class="form-check-label text-nowrap" for="pengolahanYa">Ya, sebutkan:</label>
<input type="text" class="form-control form-control-sm w-50 {{ old('pengolahan_lanjutan', $pengurus->pengolahan_lanjutan) == 'Ya' ? '' : 'd-none' }}" id="pengolahanYaInput" name="detail_pengolahan_lanjutan" placeholder="Contoh: Fermentasi biji kopi" value="{{ old('detail_pengolahan_lanjutan', $pengurus->detail_pengolahan_lanjutan) }}">
</div>
<div class="form-check">
<input class="form-check-input trigger-toggle" type="radio" name="pengolahan_lanjutan" value="Tidak" id="pengolahanTidak" data-target="pengolahanYaInput" data-action="hide" {{ old('pengolahan_lanjutan', $pengurus->pengolahan_lanjutan) == 'Tidak' ? 'checked' : '' }}>
<label class="form-check-label" for="pengolahanTidak">Tidak</label>
</div>
</div>
<div class="mb-10">
<h6 class="mb-3">Bagaimana cara pengurus koperasi menentukan harga beli di tingkat petani anggota? (Transparan/fluktuasi/kualitas mutu)</h6>
<textarea class="form-control" name="cara_penentuan_harga" rows="3" placeholder="Jelaskan mekanisme penetapan harga...">{{ old('cara_penentuan_harga', $pengurus->cara_penentuan_harga) }}</textarea>
</div>
<div class="mb-4">
<h6 class="mb-3">Adakah kontrak kerjasama antara koperasi dengan mitra pembeli utama (offtaker) atau perusahaan?</h6>
<div class="form-check d-flex align-items-center gap-2 mb-2">
<input class="form-check-input trigger-toggle" type="radio" name="kontrak_offtaker" value="Ada" id="kontrakAda" data-target="kontrakAdaInput" data-action="show" {{ old('kontrak_offtaker', $pengurus->kontrak_offtaker) == 'Ada' ? 'checked' : '' }}>
<label class="form-check-label text-nowrap" for="kontrakAda">Ada, sebutkan komoditasnya:</label>
<input type="text" class="form-control form-control-sm w-50 {{ old('kontrak_offtaker', $pengurus->kontrak_offtaker) == 'Ada' ? '' : 'd-none' }}" id="kontrakAdaInput" name="kontrak_komoditas" placeholder="Contoh: Kopi Robusta" value="{{ old('kontrak_komoditas', $pengurus->kontrak_komoditas) }}">
</div>
<div class="form-check">
<input class="form-check-input trigger-toggle" type="radio" name="kontrak_offtaker" value="Tidak ada" data-target="kontrakAdaInput" data-action="hide" {{ old('kontrak_offtaker', $pengurus->kontrak_offtaker) == 'Tidak ada' ? 'checked' : '' }}>
<label class="form-check-label" for="kontrakAda">Tidak ada</label>
</div>
</div>
</div>
<div class="d-flex justify-content-between mt-5 border-top pt-4">
<div></div>
<div class="ms-auto">
<button type="submit" class="btn btn-primary">
Simpan & Selanjutnya <i class="ti tabler-arrow-right ms-1"></i>
</button>
</div>
</div>
</form>
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
$(document).ready(function() {
$('.trigger-toggle').change(function() {
let target = $(this).data('target');
let action = $(this).data('action');
if (action === 'show') {
$('#' + target).removeClass('d-none').focus();
} else {
$('#' + target).addClass('d-none').val('');
}
});
$('.trigger-toggle-check').change(function() {
let target = $(this).data('target');
if ($(this).is(':checked')) {
$('#' + target).removeClass('d-none').focus();
} else {
$('#' + target).addClass('d-none').val('');
}
});
$('#cekSimpanPinjam').on('change', function() {
if($(this).is(':checked')) {
$('#blok-simpan-pinjam').removeClass('d-none').hide().slideDown();
} else {
$('#blok-simpan-pinjam').slideUp(function() {
$(this).addClass('d-none');
});
}
});
$('#triggerSkipD6').on('change', function() {
if ($(this).is(':checked')) {
$('#blok-sisa-d5').slideUp();
$('.opsi-agregasi').prop('checked', false);
$('#komoditasLainnya').addClass('d-none').val('');
} else {
$('#blok-sisa-d5').slideDown();
}
});
$('.opsi-agregasi').on('change', function() {
if ($(this).is(':checked')) {
$('#triggerSkipD6').prop('checked', false);
$('#blok-sisa-d5').slideDown();
}
});
});
</script>
@endpush
@@ -0,0 +1,149 @@
<h6 class="fw-bold mb-3">Data Pribadi Responden</h6>
<div class="row mb-4">
<div class="col-md-6 mb-3">
<label class="form-label">Nama Lengkap <span class="text-danger">*</span></label>
<input type="text" class="form-control @error('nama_lengkap') is-invalid @enderror" name="nama_lengkap" value="{{ old('nama_lengkap', $pengurus->nama_lengkap ?? '') }}" placeholder="Contoh: Budi Santoso" required>
@error('nama_lengkap')<div class="invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-6 mb-3">
<label class="form-label">Posisi dalam Koperasi <span class="text-danger">*</span></label>
<select class="form-select @error('posisi_dalam_koperasi') is-invalid @enderror" name="posisi_dalam_koperasi" required>
<option value="" disabled {{ !isset($pengurus) ? 'selected' : '' }}>Pilih Posisi</option>
<option value="Pengurus koperasi" {{ old('posisi_dalam_koperasi', $pengurus->posisi_dalam_koperasi ?? '') == 'Pengurus koperasi' ? 'selected' : '' }}>Pengurus koperasi</option>
<option value="Anggota koperasi" {{ old('posisi_dalam_koperasi', $pengurus->posisi_dalam_koperasi ?? '') == 'Anggota koperasi' ? 'selected' : '' }}>Anggota koperasi</option>
<option value="Pendamping koperasi" {{ old('posisi_dalam_koperasi', $pengurus->posisi_dalam_koperasi ?? '') == 'Pendamping koperasi' ? 'selected' : '' }}>Pendamping koperasi</option>
</select>
@error('posisi_dalam_koperasi')<div class="invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-6 mb-3">
<label class="form-label">Tahun Bergabung Koperasi</label>
<input type="number" class="form-control @error('tahun_bergabung') is-invalid @enderror" name="tahun_bergabung" value="{{ old('tahun_bergabung', $pengurus->tahun_bergabung ?? '') }}" placeholder="Contoh: 2020" min="1900" max="{{ date('Y') }}">
</div>
<div class="col-md-6 mb-3">
<label class="form-label">No. Handphone</label>
<input type="text" class="form-control @error('no_hp') is-invalid @enderror" name="no_hp" value="{{ old('no_hp', $pengurus->no_hp ?? '') }}" placeholder="Contoh: 08123456789">
</div>
<div class="col-md-12 mb-3">
<label class="form-label">Alamat Tinggal</label>
<textarea class="form-control @error('alamat_tinggal') is-invalid @enderror" name="alamat_tinggal" rows="2" placeholder="Masukkan alamat domisili lengkap">{{ old('alamat_tinggal', $pengurus->alamat_tinggal ?? '') }}</textarea>
</div>
</div>
<h6 class="fw-bold mb-3 pt-3 border-top">Profil Koperasi</h6>
<div class="mb-3">
<label class="form-label">Nama Koperasi <span class="text-danger">*</span></label>
<input type="text" class="form-control @error('nama_koperasi') is-invalid @enderror" name="nama_koperasi" value="{{ old('nama_koperasi', $pengurus->nama_koperasi ?? '') }}" placeholder="Contoh: Koperasi Tani Makmur" required>
@error('nama_koperasi')<div class="invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="mb-3">
<label class="form-label d-block">Jenis Koperasi <span class="text-danger">*</span></label>
<div class="row g-2">
@foreach(['Koperasi Produksi', 'Koperasi Simpan Pinjam', 'Koperasi Pemasaran', 'Koperasi Desa'] as $jenis)
<div class="col-md-3">
<div class="form-check">
<input class="form-check-input" type="radio" name="jenis_koperasi" id="jenis_{{ $loop->index }}" value="{{ $jenis }}" {{ old('jenis_koperasi', $pengurus->jenis_koperasi ?? '') == $jenis ? 'checked' : '' }} required>
<label class="form-check-label" for="jenis_{{ $loop->index }}">{{ $jenis }}</label>
</div>
</div>
@endforeach
</div>
<div class="mt-2 d-flex align-items-center">
@php
$isLainnya = isset($pengurus) && !in_array($pengurus->jenis_koperasi, ['Koperasi Produksi', 'Koperasi Simpan Pinjam', 'Koperasi Pemasaran', 'Koperasi Desa']) && $pengurus->jenis_koperasi != null;
@endphp
<div class="form-check me-3">
<input class="form-check-input" type="radio" name="jenis_koperasi" id="jenis_lainnya" value="Lainnya" {{ old('jenis_koperasi') == 'Lainnya' || $isLainnya ? 'checked' : '' }}>
<label class="form-check-label" for="jenis_lainnya">Lainnya, sebutkan:</label>
</div>
<input type="text" class="form-control form-control-sm w-50" name="jenis_koperasi_lainnya" value="{{ old('jenis_koperasi_lainnya', $isLainnya ? $pengurus->jenis_koperasi : '') }}" placeholder="Sebutkan jenis koperasi...">
</div>
</div>
<div class="mb-3">
<label class="form-label">Alamat Koperasi</label>
<textarea class="form-control @error('alamat_koperasi') is-invalid @enderror" name="alamat_koperasi" rows="2" placeholder="Masukkan alamat lengkap koperasi">{{ old('alamat_koperasi', $pengurus->alamat_koperasi ?? '') }}</textarea>
</div>
<div class="mb-3">
<label class="form-label d-block">Skala Operasi Koperasi <span class="text-danger">*</span></label>
<div class="row g-2">
@foreach(['Level Dusun', 'Lintas Dusun', 'Level Desa', 'Lintas Desa', 'Level Kecamatan', 'Lintas Kecamatan', 'Level Kabupaten', 'Lintas Kabupaten'] as $skala)
<div class="col-md-3">
<div class="form-check">
<input class="form-check-input" type="radio" name="skala_operasi" id="skala_{{ $loop->index }}" value="{{ $skala }}" {{ old('skala_operasi', $pengurus->skala_operasi ?? '') == $skala ? 'checked' : '' }} required>
<label class="form-check-label" for="skala_{{ $loop->index }}">{{ $skala }}</label>
</div>
</div>
@endforeach
</div>
</div>
<div class="row mb-3">
<div class="col-md-6 mb-3">
<label class="form-label">Tahun Berdiri</label>
<input type="number" class="form-control" name="tahun_berdiri" value="{{ old('tahun_berdiri', $pengurus->tahun_berdiri ?? '') }}" placeholder="Contoh: 2015" min="1900" max="{{ date('Y') }}">
</div>
<div class="col-md-6 mb-3">
<label class="form-label">Jumlah Anggota Awal Berdiri</label>
<div class="input-group">
<input type="number" class="form-control" name="jumlah_anggota_awal" value="{{ old('jumlah_anggota_awal', $pengurus->jumlah_anggota_awal ?? '') }}" placeholder="0" min="0">
<span class="input-group-text">orang</span>
</div>
</div>
</div>
<div class="row mb-3">
<div class="col-md-6 mb-3">
<label class="form-label">Jumlah Anggota (per Desember 2025)</label>
<div class="row g-2">
<div class="col-6">
<div class="input-group">
<input type="number" class="form-control" name="jumlah_anggota_dewasa" value="{{ old('jumlah_anggota_dewasa', $pengurus->jumlah_anggota_dewasa ?? '') }}" placeholder="Dewasa" min="0">
<span class="input-group-text">dewasa</span>
</div>
</div>
<div class="col-6">
<div class="input-group">
<input type="number" class="form-control" name="jumlah_anggota_anak" value="{{ old('jumlah_anggota_anak', $pengurus->jumlah_anggota_anak ?? '') }}" placeholder="Anak-anak" min="0">
<span class="input-group-text">anak-anak</span>
</div>
</div>
</div>
</div>
<div class="col-md-6 mb-3">
<label class="form-label">Jumlah Pengurus Sekarang</label>
<div class="input-group">
<input type="number" class="form-control" name="jumlah_pengurus" value="{{ old('jumlah_pengurus', $pengurus->jumlah_pengurus ?? '') }}" placeholder="0" min="0">
<span class="input-group-text">orang</span>
</div>
</div>
</div>
<div class="mb-4">
<label class="form-label d-block fw-semibold">Jumlah Sisa Hasil Usaha (SHU)</label>
<div class="row g-3">
<div class="col-md-4">
<label class="form-label small text-muted">2025:</label>
<div class="input-group">
<span class="input-group-text">Rp.</span>
<input type="number" class="form-control" name="shu_2025" value="{{ old('shu_2025', $pengurus->shu_2025 ?? '') }}" placeholder="0">
</div>
</div>
<div class="col-md-4">
<label class="form-label small text-muted">2024:</label>
<div class="input-group">
<span class="input-group-text">Rp.</span>
<input type="number" class="form-control" name="shu_2024" value="{{ old('shu_2024', $pengurus->shu_2024 ?? '') }}" placeholder="0">
</div>
</div>
<div class="col-md-4">
<label class="form-label small text-muted">2023:</label>
<div class="input-group">
<span class="input-group-text">Rp.</span>
<input type="number" class="form-control" name="shu_2023" value="{{ old('shu_2023', $pengurus->shu_2023 ?? '') }}" placeholder="0">
</div>
</div>
</div>
</div>
@@ -0,0 +1,35 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
@if ($errors->any())
<div class="alert alert-danger">
<ul class="mb-0">
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
@include('koperasi.profil.header', ['pengurus' => null])
<div class="card mb-6">
<div class="card-header border-bottom">
<h5 class="card-title mb-0">Tambah Profil Dasar Koperasi</h5>
</div>
<div class="card-body pt-6">
<form action="{{ route('koperasi.pengurus.store') }}" method="POST">
@csrf
@include('koperasi.profil._form', ['pengurus' => null])
<div class="mt-4 text-end">
<a href="{{ route('koperasi.pengurus.index') }}" class="btn btn-secondary me-2 wave-effect wave-light">Batal / Kembali</a>
<button type="submit" class="btn btn-success data-submit wave-effect wave-light"><i class="ti tabler-device-floppy me-2"></i> Simpan Profil</button>
</div>
</form>
</div>
</div>
</div>
@endsection
@@ -0,0 +1,38 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
@if ($errors->any())
<div class="alert alert-danger">
<ul class="mb-0">
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
@include('koperasi.profil.header', ['pengurus' => $pengurus])
<div class="card mb-6">
<div class="card-header border-bottom">
<h5 class="card-title mb-0">Edit Profil Dasar Koperasi</h5>
</div>
<div class="card-body pt-6">
<form action="{{ route('koperasi.pengurus.update', $pengurus->id) }}" method="POST">
@csrf
@method('PUT')
@include('koperasi.profil._form', ['pengurus' => $pengurus])
<div class="mt-4 text-end">
<a href="{{ route('koperasi.pengurus.index') }}" class="btn btn-secondary me-2 wave-effect wave-light">Batal / Kembali</a>
<button type="submit" class="btn btn-success data-submit wave-effect wave-light">
<i class="ti tabler-device-floppy me-2"></i> Simpan Perubahan
</button>
</div>
</form>
</div>
</div>
</div>
@endsection
@@ -0,0 +1,191 @@
<style>
@media (min-width: 768px) {
.nav-pills-custom-spacing {
display: flex;
width: 100%;
gap: 0.5rem;
flex-wrap: nowrap !important;
overflow-x: auto;
}
.nav-pills-custom-spacing::-webkit-scrollbar {
display: none;
}
.nav-pills-custom-spacing .nav-item {
margin-right: 0 !important;
flex: 1;
}
.nav-pills-custom-spacing .nav-link {
display: flex;
justify-content: center;
align-items: center;
padding-left: 0.5rem !important;
padding-right: 0.5rem !important;
width: 100%;
white-space: nowrap;
font-size: 0.9375rem !important;
}
.nav-pills-custom-spacing .nav-link i {
margin-right: 0.4rem !important;
}
}
</style>
@php
$namaLengkap = isset($pengurus) ? $pengurus->nama_lengkap : 'Tambah Profil Baru';
$namaKoperasi = isset($pengurus) ? $pengurus->nama_koperasi : 'Nama Koperasi';
$jabatanLabel = isset($pengurus) ? $pengurus->posisi_dalam_koperasi : 'Posisi/Jabatan';
$noHp = isset($pengurus) ? $pengurus->no_hp : 'Belum terisi';
$domisili = isset($pengurus) ? $pengurus->alamat_tinggal : 'Alamat Domisili Pengurus';
@endphp
<div class="row mb-4">
<div class="col-md-4 mb-2 mb-md-0">
<div class="card h-100">
<div class="card-body p-3">
<h6 class="card-title mb-2">Profil Pengurus Koperasi</h6>
<div class="d-flex justify-content-start align-items-center mb-3">
<div class="avatar me-2">
<span class="avatar-initial rounded bg-label-primary">
<i class="icon-base ti tabler-user-check icon-22px"></i>
</span>
</div>
<div class="d-flex flex-column">
<h6 class="mb-0" style="font-size: 0.9rem;">{{ $namaLengkap }}</h6>
<span class="text-muted" style="font-size: 0.75rem;">{{ $namaKoperasi }}</span>
<span class="text-muted" style="font-size: 0.75rem;">Jabatan: {{ $jabatanLabel }}</span>
</div>
</div>
<hr class="my-2">
<h6 class="mb-1" style="font-size: 0.85rem;">Kontak & Domisili</h6>
<p class="mb-0 text-muted" style="font-size: 0.75rem;">No. HP: {{ $noHp }}</p>
<p class="mb-0 text-muted" style="font-size: 0.75rem; line-height: 1.3;">{{ $domisili }}</p>
</div>
</div>
</div>
<div class="col-md-8 d-flex flex-column">
<div class="card mb-2 flex-grow-1">
<div class="card-widget-separator-wrapper h-100">
<div class="card-body card-widget-separator py-2 h-100 d-flex flex-column justify-content-center">
<div class="row gy-2">
<div class="col-sm-6 col-lg-4">
<div class="d-flex justify-content-between align-items-center card-widget-1 border-end h-100 pe-3">
<div>
<p class="mb-0 text-muted" style="font-size: 0.75rem;">Koperasi</p>
<h5 class="mb-0 text-truncate" style="max-width: 120px;" title="{{ $namaKoperasi }}">{{ $namaKoperasi }}</h5>
<p class="mb-0" style="font-size: 0.75rem;">
<span class="me-1">{{ isset($pengurus) ? $pengurus->jenis_koperasi : 'Belum terisi' }}</span>
</p>
</div>
<span class="avatar">
<span class="avatar-initial rounded">
<i class="icon-base ti tabler-building-store icon-22px text-heading"></i>
</span>
</span>
</div>
</div>
<div class="col-sm-6 col-lg-4">
<div class="d-flex justify-content-between align-items-center card-widget-1 border-end h-100 px-3">
<div>
<p class="mb-0 text-muted" style="font-size: 0.75rem;">Posisi</p>
<h5 class="mb-0">{{ $jabatanLabel }}</h5>
<p class="mb-0" style="font-size: 0.75rem;">
<span class="me-1">Thn Gabung: {{ isset($pengurus) ? ($pengurus->tahun_bergabung ?: '-') : '-' }}</span>
</p>
</div>
<span class="avatar">
<span class="avatar-initial rounded">
<i class="icon-base ti tabler-briefcase icon-22px text-heading"></i>
</span>
</span>
</div>
</div>
<div class="col-sm-6 col-lg-4">
<div class="d-flex justify-content-between align-items-center card-widget-1 h-100 ps-3">
<div>
<p class="mb-0 text-muted" style="font-size: 0.75rem;">Skala Operasi</p>
<h5 class="mb-0">{{ isset($pengurus) ? $pengurus->skala_operasi : '-' }}</h5>
</div>
<span class="avatar">
<span class="avatar-initial rounded">
<i class="icon-base ti tabler-map-pin icon-22px text-heading"></i>
</span>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="card flex-grow-1">
<div class="card-body py-3 d-flex align-items-center">
<div class="w-100">
<p class="mb-1 text-muted" style="font-size: 0.75rem;">Alamat Koperasi</p>
<h6 class="mb-0">{{ isset($pengurus) ? ($pengurus->alamat_koperasi ?: '-') : '-' }}</h6>
</div>
</div>
</div>
</div>
</div>
<div class="nav-align-top">
<ul class="nav nav-pills flex-column flex-md-row mb-6 row-gap-2 nav-pills-custom-spacing" id="main-tab-nav">
<li class="nav-item">
<a class="nav-link {{ request()->routeIs('koperasi.pengurus.create') || request()->routeIs('koperasi.pengurus.edit') ? 'active' : '' }}" href="{{ isset($pengurus) ? route('koperasi.pengurus.edit', $pengurus->id) : route('koperasi.pengurus.create') }}">
<i class="icon-base ti tabler-user-check icon-sm"></i>Profil Dasar
</a>
</li>
@php
$currentStep = request()->query('step', 1);
$isSurvey = request()->routeIs('koperasi.pengurus.survey');
$disabledAttr = !isset($pengurus) ? 'disabled data-bs-toggle="tooltip" data-bs-placement="top" title="Simpan profil dasar terlebih dahulu"' : '';
@endphp
<li class="nav-item">
<a class="nav-link {{ ($isSurvey && $currentStep == 1) ? 'active bg-primary text-white' : 'text-muted' }}"
href="{{ isset($pengurus) ? route('koperasi.pengurus.survey', [$pengurus->id, 'step' => 1]) : '#' }}" {!! $disabledAttr !!}>
<i class="icon-base ti tabler-building-bank icon-sm"></i>Kelembagaan-Aktor Sistem
</a>
</li>
<li class="nav-item">
<a class="nav-link {{ ($isSurvey && $currentStep == 2) ? 'active bg-primary text-white' : 'text-muted' }}"
href="{{ isset($pengurus) ? route('koperasi.pengurus.survey', [$pengurus->id, 'step' => 2]) : '#' }}" {!! $disabledAttr !!}>
<i class="icon-base ti tabler-truck-delivery icon-sm"></i>Rantai Nilai-Akses Pasar
</a>
</li>
<li class="nav-item">
<a class="nav-link {{ ($isSurvey && $currentStep == 3) ? 'active bg-primary text-white' : 'text-muted' }}"
href="{{ isset($pengurus) ? route('koperasi.pengurus.survey', [$pengurus->id, 'step' => 3]) : '#' }}" {!! $disabledAttr !!}>
<i class="icon-base ti tabler-users icon-sm"></i>Sosial Ekonomi
</a>
</li>
</ul>
</div>
<script>
function jumpToStep(step) {
$('.step-content').addClass('d-none');
$('#step-' + step).removeClass('d-none');
$('.survey-tab-link').removeClass('active');
$('#tab-step-' + step).addClass('active');
if (history.pushState) {
window.history.replaceState(null, null, '#step-' + step);
}
}
$(document).ready(function() {
let hash = window.location.hash;
if (hash && hash.startsWith('#step-')) {
let stepNum = parseInt(hash.replace('#step-', ''));
if (stepNum >= 1 && stepNum <= 4) {
jumpToStep(stepNum);
}
}
});
</script>
@@ -0,0 +1,160 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
<div class="d-flex flex-row gap-3 mb-4">
<div class="w-25">
<x-summary-card
title="Pengurus Koperasi"
count="{{ $totalPengurus ?? 0 }}"
subtitle="Total responden terdata"
icon="user-check"
color="primary"
/>
</div>
<div class="w-25">
<x-summary-card
title="Koperasi Terdata"
count="{{ $totalKoperasi ?? 0 }}"
subtitle="Unit Koperasi yang terdata"
icon="map-pin"
color="success"
/>
</div>
<div class="w-25">
<x-summary-card
title="Jabatan/Peran"
count="{{ $totalJabatan ?? 0 }}"
subtitle="Jenis jabatan/peran terdata"
icon="briefcase"
color="info"
/>
</div>
</div>
<div class="card">
<div class="card-header border-bottom">
<h5 class="card-title mb-0">Data Pengurus Koperasi</h5>
</div>
<div class="card-body border-bottom pt-4">
<form method="GET" action="{{ route('koperasi.pengurus.index') }}" class="d-flex justify-content-between align-items-center row gap-3 gap-md-0">
<div class="col-md-auto">
<div class="d-flex align-items-center">
<label class="me-2 text-nowrap">Show</label>
<select name="per_page" class="form-select form-select-sm w-auto" onchange="this.form.submit()">
<option value="10" {{ request('per_page') == 10 ? 'selected' : '' }}>10</option>
<option value="25" {{ request('per_page') == 25 ? 'selected' : '' }}>25</option>
</select>
<label class="ms-2 text-nowrap">entries</label>
</div>
</div>
<div class="col-md-auto d-flex gap-2">
<div class="input-group input-group-sm w-auto">
<input type="text" name="search" class="form-control" placeholder="Cari Nama..." value="{{ request('search') }}">
<button type="submit" class="btn btn-outline-primary"><i class="ti tabler-search"></i></button>
</div>
<a href="{{ route('koperasi.pengurus.create') }}" class="btn btn-sm btn-primary">
<i class="ti tabler-plus me-1"></i> Tambah
</a>
</div>
</form>
</div>
<div class="table-responsive text-nowrap">
<table class="table table-hover">
<thead class="border-top">
<tr>
<th>No</th>
<th>Nama Pengurus</th>
<th>Posisi</th>
<th>Nama Koperasi</th>
<th>Jenis Koperasi</th>
<th>Skala Operasi</th>
@if($showEnumerator ?? true)
<th>Nama Enumerator</th>
@endif
<th>Aksi</th>
</tr>
</thead>
<tbody>
@forelse($pengurus ?? [] as $item)
<tr>
<td>{{ (($pengurus->firstItem() ?? 1) - 1) + $loop->iteration }}</td>
<td><span class="text-heading">{{ $item->nama_lengkap }}</span></td>
<td><span class="text-muted">{{ $item->posisi_dalam_koperasi }}</span></td>
<td><span class="text-muted">{{ $item->nama_koperasi }}</span></td>
<td><span class="text-muted">{{ $item->jenis_koperasi }}</span></td>
<td><span class="text-muted">{{ $item->skala_operasi }}</span></td>
@if($showEnumerator ?? true)
<td><span class="text-muted">{{ $item->creator?->name ?? '-' }}</span></td>
@endif
<td>
<div class="d-flex align-items-center">
<a href="{{ route('koperasi.pengurus.edit', $item->id) }}" class="btn btn-icon btn-text-secondary rounded-pill edit-record">
<i class="ti tabler-edit ti-md"></i>
</a>
<a href="javascript:;" class="btn btn-icon btn-text-secondary rounded-pill delete-record" data-id="{{ $item->id }}" data-nama="{{ $item->nama_lengkap }}">
<i class="ti tabler-trash ti-md"></i>
</a>
</div>
</td>
</tr>
@empty
<tr>
<td colspan="{{ ($showEnumerator ?? true) ? 8 : 7 }}" class="text-center py-4">Tidak ada data ditemukan.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<div class="card-footer d-flex justify-content-center justify-content-md-end border-top">
@if(isset($pengurus) && $pengurus instanceof \Illuminate\Pagination\LengthAwarePaginator && $pengurus->hasPages())
{{ $pengurus->appends(request()->query())->links('pagination::bootstrap-5') }}
@endif
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
'use strict';
const csrfToken = "{{ csrf_token() }}";
$(document).ready(function () {
$(document).on('click', '.delete-record', function () {
const id = $(this).data('id');
const name = $(this).data('nama');
Swal.fire({
title: 'Apakah Anda yakin?',
text: `Profil "${name}" akan dihapus secara permanen!`,
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Ya, Hapus!',
cancelButtonText: 'Batal',
customClass: { confirmButton: 'btn btn-primary me-3', cancelButton: 'btn btn-label-secondary' },
buttonsStyling: false
}).then(function (result) {
if (result.value) {
$.ajax({
url: '{{ route('koperasi.pengurus.destroy', ':id') }}'.replace(':id', id),
type: 'DELETE' ,
headers: { 'X-CSRF-TOKEN': csrfToken },
success: function (res) {
Swal.fire({ icon: 'success', title: 'Terhapus!', text: res.message, showConfirmButton: false, timer: 1500 })
.then(() => window.location.reload());
},
error: () => Swal.fire({ icon: 'error', title: 'Gagal!', text: 'Terjadi kesalahan sistem.' })
});
}
});
});
});
</script>
@endpush
@@ -0,0 +1,302 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
@include('koperasi.profil.header', ['pengurus' => $pengurus])
<div class="card shadow-sm border-0 mb-4">
<div class="card-body p-0">
<form action="{{ route('koperasi.pengurus.survey.store', ['id' => $pengurus->id ?? 0, 'step' => 2]) }}" method="POST" class="p-4 p-md-5">
@csrf
<input type="hidden" name="pengurus_koperasi_id" value="{{ $pengurus->id ?? '' }}">
<h5 class="fw-bold border-bottom pb-2 mb-4">RANTAI NILAI & AKSES PASAR</h5>
<div class="alert alert-warning mb-4">Ditanyakan khusus untuk Koperasi yang melakukan kegiatan jual beli/agregasi.</div>
<h6 class="fw-bold text-dark mt-5">K2. Harga di Setiap Titik</h6>
<h5 class="pb-3 border-bottom mb-10 mt-4">Saluran Pembelian/Sumber Pasokan</h5>
<div class="mb-4">
<h6 class="form-label fw-semibold mb-2">Dari mana Koperasi biasanya memperoleh pasokan komoditas ini? (Boleh pilih >1)</h6>
<div class="form-check form-check-inline"><input class="form-check-input" type="checkbox" name="sumber_pasokan[]" value="Anggota" {{ str_contains($pengurus->sumber_pasokan ?? '', 'Anggota') ? 'checked' : '' }}><label class="form-check-label">Anggota kelompok tani langsung</label></div>
<div class="form-check form-check-inline"><input class="form-check-input" type="checkbox" name="sumber_pasokan[]" value="Petani non-anggota" {{ str_contains($pengurus->sumber_pasokan ?? '', 'Petani non-anggota') ? 'checked' : '' }}><label class="form-check-label">Petani non-anggota</label></div>
<div class="form-check form-check-inline"><input class="form-check-input" type="checkbox" name="sumber_pasokan[]" value="Pengumpul/sub-agen" {{ str_contains($pengurus->sumber_pasokan ?? '', 'Pengumpul/sub-agen') ? 'checked' : '' }}><label class="form-check-label">Pengumpul/sub-agen desa</label></div>
<div class="form-check form-check-inline"><input class="form-check-input" type="checkbox" name="sumber_pasokan[]" value="Campuran" {{ str_contains($pengurus->sumber_pasokan ?? '', 'Campuran') ? 'checked' : '' }}><label class="form-check-label">Campuran</label></div>
<div class="form-check d-flex align-items-center gap-2 mt-2">
<input class="form-check-input trigger-toggle-check" type="checkbox" name="sumber_pasokan[]" value="Lainnya" data-target="sumberLainnya" {{ str_contains($pengurus->sumber_pasokan ?? '', 'Lainnya') ? 'checked' : '' }}>
<label class="form-check-label text-nowrap">Lainnya:</label>
<input type="text" class="form-control form-control-sm w-auto {{ str_contains($pengurus->sumber_pasokan ?? '', 'Lainnya') ? '' : 'd-none' }}" id="sumberLainnya" name="sumber_pasokan_lainnya" value="{{ old('sumber_pasokan_lainnya', $pengurus->sumber_pasokan_lainnya) }}">
</div>
</div>
<div class="row mb-4">
<div class="col-md-4 mb-3">
<label class="form-label fw-semibold">Bentuk produk yang dibeli:</label>
<div class="form-check"><input class="form-check-input" type="checkbox" name="bentuk_pembelian[]" value="Buah segar hasil petik" {{ str_contains($pengurus->bentuk_pembelian ?? '', 'Buah segar hasil petik') ? 'checked' : '' }}><label class="form-check-label">Buah segar hasil petik</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" name="bentuk_pembelian[]" value="Biji basah" {{ str_contains($pengurus->bentuk_pembelian ?? '', 'Biji basah') ? 'checked' : '' }}><label class="form-check-label">Biji basah</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" name="bentuk_pembelian[]" value="Biji kering/kupas" {{ str_contains($pengurus->bentuk_pembelian ?? '', 'Biji kering/kupas') ? 'checked' : '' }}><label class="form-check-label">Biji kering/biji kupas</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" name="bentuk_pembelian[]" value="Produk terfermentasi" {{ str_contains($pengurus->bentuk_pembelian ?? '', 'Produk terfermentasi') ? 'checked' : '' }}><label class="form-check-label">Produk terfermentasi</label></div>
</div>
<div class="col-md-8 mb-3">
<label class="form-label fw-semibold">Estimasi volume yang dibeli (Kg):</label>
<div class="d-flex gap-2 mb-2">
<span class="input-group-text w-50">Panen terakhir</span>
<input type="number" class="form-control" name="volume_beli_sekarang" placeholder="kg" value="{{ old('volume_beli_sekarang', $pengurus->volume_beli_sekarang) }}">
</div>
<div class="d-flex gap-2 mb-2">
<span class="input-group-text w-50">Tahun lalu</span>
<input type="number" class="form-control" name="volume_beli_1_tahun" placeholder="kg" value="{{ old('volume_beli_1_tahun', $pengurus->volume_beli_1_tahun) }}">
</div>
<div class="d-flex gap-2">
<span class="input-group-text w-50">Dua tahun lalu</span>
<input type="number" class="form-control" name="volume_beli_2_tahun" placeholder="kg" value="{{ old('volume_beli_2_tahun', $pengurus->volume_beli_2_tahun) }}">
</div>
</div>
</div>
<h5 class="pb-3 border-bottom mb-10 mt-4">Saluran Penjualan Utama</h5>
<div class="mb-4">
<h6 class="form-label fw-semibold">Kepada siapa Koperasi biasanya menjual hasil yang dikumpulkan? (Boleh pilih >1)</h6>
<div class="row g-2">
<div class="col-md-6"><div class="form-check"><input class="form-check-input" type="checkbox" name="tujuan_penjualan[]" value="Offtaker/Eksportir" {{ str_contains($pengurus->tujuan_penjualan ?? '', 'Offtaker/Eksportir') ? 'checked' : '' }}><label class="form-check-label">Offtaker/eksportir langsung</label></div></div>
<div class="col-md-6"><div class="form-check"><input class="form-check-input" type="checkbox" name="tujuan_penjualan[]" value="Pedagang besar" {{ str_contains($pengurus->tujuan_penjualan ?? '', 'Pedagang besar') ? 'checked' : '' }}><label class="form-check-label">Pedagang besar/pengepul kabupaten</label></div></div>
<div class="col-md-6"><div class="form-check"><input class="form-check-input" type="checkbox" name="tujuan_penjualan[]" value="Koperasi/BUMDes lain" {{ str_contains($pengurus->tujuan_penjualan ?? '', 'Koperasi/BUMDes lain') ? 'checked' : '' }}><label class="form-check-label">Koperasi atau BUMDes lain</label></div></div>
<div class="col-md-6"><div class="form-check"><input class="form-check-input" type="checkbox" name="tujuan_penjualan[]" value="Eceran" {{ str_contains($pengurus->tujuan_penjualan ?? '', 'Eceran') ? 'checked' : '' }}><label class="form-check-label">Dijual eceran/pasar lokal</label></div></div>
<div class="col-md-6"><div class="form-check"><input class="form-check-input" type="checkbox" name="tujuan_penjualan[]" value="Belum pernah" {{ str_contains($pengurus->tujuan_penjualan ?? '', 'Belum pernah') ? 'checked' : '' }}><label class="form-check-label">Belum pernah (masih disimpan)</label></div></div>
<div class="col-md-6">
<div class="form-check d-flex align-items-center gap-2">
<input class="form-check-input trigger-toggle-check" type="checkbox" name="tujuan_penjualan[]" value="Lainnya" data-target="jualLainnya" {{ str_contains($pengurus->tujuan_penjualan ?? '', 'Lainnya') ? 'checked' : '' }}>
<label class="form-check-label text-nowrap">Lainnya:</label>
<input type="text" class="form-control form-control-sm w-75 {{ str_contains($pengurus->tujuan_penjualan ?? '', 'Lainnya') ? '' : 'd-none' }}" id="jualLainnya" name="tujuan_penjualan_lainnya" value="{{ old('tujuan_penjualan_lainnya', $pengurus->tujuan_penjualan_lainnya) }}">
</div>
</div>
</div>
</div>
<div class="row mb-4 border-bottom pb-4">
<div class="col-md-4 mb-3">
<label class="form-label fw-semibold">Bentuk produk yang dijual:</label>
<div class="form-check"><input class="form-check-input" type="checkbox" name="bentuk_penjualan[]" value="Buah segar hasil petik" {{ str_contains($pengurus->bentuk_penjualan ?? '', 'Buah segar hasil petik') ? 'checked' : '' }}><label class="form-check-label">Buah segar hasil petik</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" name="bentuk_penjualan[]" value="Biji basah" {{ str_contains($pengurus->bentuk_penjualan ?? '', 'Biji basah') ? 'checked' : '' }}><label class="form-check-label">Biji basah</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" name="bentuk_penjualan[]" value="Biji kering/kupas" {{ str_contains($pengurus->bentuk_penjualan ?? '', 'Biji kering/kupas') ? 'checked' : '' }}><label class="form-check-label">Biji kering/biji kupas</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" name="bentuk_penjualan[]" value="Produk terfermentasi" {{ str_contains($pengurus->bentuk_penjualan ?? '', 'Produk terfermentasi') ? 'checked' : '' }}><label class="form-check-label">Produk terfermentasi</label></div>
</div>
<div class="col-md-8 mb-3">
<label class="form-label fw-semibold">Estimasi volume yang terjual (Kg):</label>
<div class="d-flex gap-2 mb-2">
<span class="input-group-text w-50">Panen terakhir</span>
<input type="number" class="form-control" name="volume_jual_sekarang" placeholder="kg" value="{{ old('volume_jual_sekarang', $pengurus->volume_jual_sekarang) }}">
</div>
<div class="d-flex gap-2 mb-2">
<span class="input-group-text w-50">Tahun lalu</span>
<input type="number" class="form-control" name="volume_jual_1_tahun" placeholder="kg" value="{{ old('volume_jual_1_tahun', $pengurus->volume_jual_1_tahun) }}">
</div>
<div class="d-flex gap-2">
<span class="input-group-text w-50">Dua tahun lalu</span>
<input type="number" class="form-control" name="volume_jual_2_tahun" placeholder="kg" value="{{ old('volume_jual_2_tahun', $pengurus->volume_jual_2_tahun) }}">
</div>
</div>
</div>
<h5 class="pb-3 border-bottom mb-10 mt-4">Sifat Hubungan dengan Petani Pemasok</h5>
<div class="mb-4">
<label class="form-label fw-semibold">Sifat Hubungan dengan Petani Pemasok (Boleh pilih >1)</label>
<div class="form-check"><input class="form-check-input" type="checkbox" name="sifat_hubungan_bisnis[]" value="Bebas" {{ str_contains($pengurus->sifat_hubungan_bisnis ?? '', 'Bebas') ? 'checked' : '' }}><label class="form-check-label">Bebas/tidak terikat petani bebas menjual kapan saja tanpa ikatan</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" name="sifat_hubungan_bisnis[]" value="Langganan tetap" {{ str_contains($pengurus->sifat_hubungan_bisnis ?? '', 'Langganan tetap') ? 'checked' : '' }}><label class="form-check-label">Langganan tetap rutin menjual, tapi tanpa perjanjian formal</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" name="sifat_hubungan_bisnis[]" value="Berbasis hutang" {{ str_contains($pengurus->sifat_hubungan_bisnis ?? '', 'Berbasis hutang') ? 'checked' : '' }}><label class="form-check-label">Berbasis hutang/pinjaman menjual karena punya pinjaman</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" name="sifat_hubungan_bisnis[]" value="Titip jual" {{ str_contains($pengurus->sifat_hubungan_bisnis ?? '', 'Titip jual') ? 'checked' : '' }}><label class="form-check-label">Titip jual (konsinyasi) petani dibayar setelah hasil terjual</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" name="sifat_hubungan_bisnis[]" value="Komitmen volume" {{ str_contains($pengurus->sifat_hubungan_bisnis ?? '', 'Komitmen volume') ? 'checked' : '' }}><label class="form-check-label">Ada komitmen volume kesepakatan volume berkala</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" name="sifat_hubungan_bisnis[]" value="Semi-kontrak" {{ str_contains($pengurus->sifat_hubungan_bisnis ?? '', 'Semi-kontrak') ? 'checked' : '' }}><label class="form-check-label">Semi-kontrak kesepakatan harga, volume, & waktu</label></div>
<div class="form-check d-flex align-items-center gap-2 mt-2">
<input class="form-check-input trigger-toggle-check" type="checkbox" name="sifat_hubungan_bisnis[]" value="Lainnya" data-target="sifatLainnya" {{ str_contains($pengurus->sifat_hubungan_bisnis ?? '', 'Lainnya') ? 'checked' : '' }}>
<label class="form-check-label text-nowrap">Lainnya:</label>
<input type="text" class="form-control form-control-sm w-50 {{ str_contains($pengurus->sifat_hubungan_bisnis ?? '', 'Lainnya') ? '' : 'd-none' }}" id="sifatLainnya" name="sifat_hubungan_lainnya" value="{{ old('sifat_hubungan_lainnya', $pengurus->sifat_hubungan_lainnya) }}">
</div>
</div>
<div class="row border-bottom mb-4 mt-4">
<div class="col-md-6 mb-3">
<label class="form-label fw-semibold">Mekanisme pembayaran ke petani?</label>
<div class="form-check"><input class="form-check-input" type="radio" name="mekanisme_pembayaran" value="Tunai" {{ old('mekanisme_pembayaran', $pengurus->mekanisme_pembayaran) == 'Tunai' ? 'checked' : '' }}><label class="form-check-label">Tunai langsung</label></div>
<div class="form-check"><input class="form-check-input" type="radio" name="mekanisme_pembayaran" value="Tempo" {{ old('mekanisme_pembayaran', $pengurus->mekanisme_pembayaran) == 'Tempo' ? 'checked' : '' }}><label class="form-check-label">Sistem tempo/dibayar kemudian</label></div>
<div class="form-check"><input class="form-check-input" type="radio" name="mekanisme_pembayaran" value="Campuran" {{ old('mekanisme_pembayaran', $pengurus->mekanisme_pembayaran) == 'Campuran' ? 'checked' : '' }}><label class="form-check-label">Campuran, tergantung situasi</label></div>
</div>
<div class="col-md-6 mb-3">
<label class="form-label fw-semibold">Apakah ada perjanjian/kontrak sebelum pembelian?</label>
<div class="form-check"><input class="form-check-input" type="radio" name="status_perjanjian_tertulis" value="Tertulis" {{ old('status_perjanjian_tertulis', $pengurus->status_perjanjian_tertulis) == 'Tertulis' ? 'checked' : '' }}><label class="form-check-label">Ada, tertulis</label></div>
<div class="form-check"><input class="form-check-input" type="radio" name="status_perjanjian_tertulis" value="Lisan" {{ old('status_perjanjian_tertulis', $pengurus->status_perjanjian_tertulis) == 'Lisan' ? 'checked' : '' }}><label class="form-check-label">Ada, kesepakatan lisan saja</label></div>
<div class="form-check"><input class="form-check-input" type="radio" name="status_perjanjian_tertulis" value="Tidak ada" {{ old('status_perjanjian_tertulis', $pengurus->status_perjanjian_tertulis) == 'Tidak ada' ? 'checked' : '' }}><label class="form-check-label">Tidak ada perjanjian</label></div>
</div>
</div>
<h6 class="fw-bold text-dark mt-5">K2. Harga di Setiap Titik</h6>
<div class="mb-4">
<h5 class="pb-3 border-bottom mb-10 mt-4">Harga Beli Koperasi dari Petani (Rp/kg)</h5>
<div class="table-responsive">
<table class="table table-sm align-middle">
<thead class="table-primary">
<tr>
<th style="border-top-left-radius: 8px; border-bottom-left-radius: 8px; border: none;">BENTUK PRODUK</th>
<th style="border: none;">PANEN TERAKHIR</th>
<th style="border: none;">TAHUN LALU</th>
<th style="border-top-right-radius: 8px; border-bottom-right-radius: 8px; border: none;">DUA TAHUN LALU</th>
</tr>
</thead>
<tbody>
<tr>
<td>Buah segar petik</td>
<td><div class="input-group input-group-sm"><span class="input-group-text">Rp</span><input type="number" class="form-control" name="harga_segar_sekarang" value="{{ old('harga_segar_sekarang', $pengurus->harga_segar_sekarang) }}"></div></td>
<td><div class="input-group input-group-sm"><span class="input-group-text">Rp</span><input type="number" class="form-control" name="harga_segar_1_tahun" value="{{ old('harga_segar_1_tahun', $pengurus->harga_segar_1_tahun) }}"></div></td>
<td><div class="input-group input-group-sm"><span class="input-group-text">Rp</span><input type="number" class="form-control" name="harga_segar_2_tahun" value="{{ old('harga_segar_2_tahun', $pengurus->harga_segar_2_tahun) }}"></div></td>
</tr>
<tr>
<td>Biji basah</td>
<td><div class="input-group input-group-sm"><span class="input-group-text">Rp</span><input type="number" class="form-control" name="harga_basah_sekarang" value="{{ old('harga_basah_sekarang', $pengurus->harga_basah_sekarang) }}"></div></td>
<td><div class="input-group input-group-sm"><span class="input-group-text">Rp</span><input type="number" class="form-control" name="harga_basah_1_tahun" value="{{ old('harga_basah_1_tahun', $pengurus->harga_basah_1_tahun) }}"></div></td>
<td><div class="input-group input-group-sm"><span class="input-group-text">Rp</span><input type="number" class="form-control" name="harga_basah_2_tahun" value="{{ old('harga_basah_2_tahun', $pengurus->harga_basah_2_tahun) }}"></div></td>
</tr>
<tr>
<td>Biji kering/kupas</td>
<td><div class="input-group input-group-sm"><span class="input-group-text">Rp</span><input type="number" class="form-control" name="harga_kering_sekarang" value="{{ old('harga_kering_sekarang', $pengurus->harga_kering_sekarang) }}"></div></td>
<td><div class="input-group input-group-sm"><span class="input-group-text">Rp</span><input type="number" class="form-control" name="harga_kering_1_tahun" value="{{ old('harga_kering_1_tahun', $pengurus->harga_kering_1_tahun) }}"></div></td>
<td><div class="input-group input-group-sm"><span class="input-group-text">Rp</span><input type="number" class="form-control" name="harga_kering_2_tahun" value="{{ old('harga_kering_2_tahun', $pengurus->harga_kering_2_tahun) }}"></div></td>
</tr>
<tr>
<td>Terfermentasi</td>
<td><div class="input-group input-group-sm"><span class="input-group-text">Rp</span><input type="number" class="form-control" name="harga_fermentasi_sekarang" value="{{ old('harga_fermentasi_sekarang', $pengurus->harga_fermentasi_sekarang) }}"></div></td>
<td><div class="input-group input-group-sm"><span class="input-group-text">Rp</span><input type="number" class="form-control" name="harga_fermentasi_1_tahun" value="{{ old('harga_fermentasi_1_tahun', $pengurus->harga_fermentasi_1_tahun) }}"></div></td>
<td><div class="input-group input-group-sm"><span class="input-group-text">Rp</span><input type="number" class="form-control" name="harga_fermentasi_2_tahun" value="{{ old('harga_fermentasi_2_tahun', $pengurus->harga_fermentasi_2_tahun) }}"></div></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="mb-4">
<label class="form-label fw-semibold">Bagaimana cara Koperasi menetapkan harga beli dari petani?</label>
<div class="form-check"><input class="form-check-input" type="checkbox" name="cara_menetapkan_harga_pasar[]" value="Ikut pasar" {{ str_contains($pengurus->cara_menetapkan_harga_pasar ?? '', 'Ikut pasar') ? 'checked' : '' }}><label class="form-check-label">Mengikuti harga pasar/tengkulak setempat</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" name="cara_menetapkan_harga_pasar[]" value="Kalkulasi biaya" {{ str_contains($pengurus->cara_menetapkan_harga_pasar ?? '', 'Kalkulasi biaya') ? 'checked' : '' }}><label class="form-check-label">Ditetapkan sendiri berdasarkan kalkulasi biaya</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" name="cara_menetapkan_harga_pasar[]" value="Harga offtaker" {{ str_contains($pengurus->cara_menetapkan_harga_pasar ?? '', 'Harga offtaker') ? 'checked' : '' }}><label class="form-check-label">Mengikuti harga dari offtaker/mitra</label></div>
<div class="form-check d-inline-flex align-items-center gap-2 mt-2">
<input class="form-check-input trigger-toggle-check" type="checkbox" name="cara_menetapkan_harga_pasar[]" value="Lainnya" data-target="hargaLainnya" {{ str_contains($pengurus->cara_menetapkan_harga_pasar ?? '', 'Lainnya') ? 'checked' : '' }}>
<label class="form-check-label text-nowrap">Lainnya:</label>
<input type="text" class="form-control form-control-sm w-auto {{ str_contains($pengurus->cara_menetapkan_harga_pasar ?? '', 'Lainnya') ? '' : 'd-none' }}" id="hargaLainnya" name="cara_menetapkan_harga_lainnya" value="{{ old('cara_menetapkan_harga_lainnya', $pengurus->cara_menetapkan_harga_lainnya) }}">
</div>
</div>
<div id="blok-k3" class="mt-5 pt-3 border-top border-primary">
<h6 class="fw-bold text-primary mb-4"><i></i>K3. Peluang Nilai Tambah (Pengolahan Pascapanen)</h6>
<h5 class="pb-3 border-bottom mb-4 mt-4">Sortasi & Pemilihan Kualitas</h5>
<div class="mb-4">
<label class="form-label fw-semibold">Apakah Koperasi melakukan sortasi/pemilihan kualitas hasil panen sebelum dijual?</label> <br>
<div class="form-check form-check-inline"><input class="form-check-input trigger-toggle" type="radio" name="praktik_sortasi" value="Ya rutin" data-target="sortasiInput" data-action="show" {{ old('praktik_sortasi', $pengurus->praktik_sortasi) == 'Ya rutin' ? 'checked' : '' }}><label class="form-check-label">Ya, rutin berstandar</label></div>
<div class="form-check form-check-inline"><input class="form-check-input trigger-toggle" type="radio" name="praktik_sortasi" value="Ya tidak konsisten" data-target="sortasiInput" data-action="show" {{ old('praktik_sortasi', $pengurus->praktik_sortasi) == 'Ya tidak konsisten' ? 'checked' : '' }}><label class="form-check-label">Ya, tidak konsisten</label></div>
<div class="form-check form-check-inline"><input class="form-check-input trigger-toggle" type="radio" name="praktik_sortasi" value="Belum pernah" data-target="sortasiInput" data-action="hide" {{ old('praktik_sortasi', $pengurus->praktik_sortasi) == 'Belum pernah' ? 'checked' : '' }}><label class="form-check-label">Belum pernah</label></div>
<!-- Blok ini dinamis hapus d-none jika Ya rutin / Ya tidak konsisten -->
<div class="mt-2 {{ in_array(old('praktik_sortasi', $pengurus->praktik_sortasi), ['Ya rutin', 'Ya tidak konsisten']) ? '' : 'd-none' }}" id="sortasiInput">
<label class="form-label small text-muted mb-1">Jika ya, standar/kriteria sortasi yang digunakan:</label>
<input type="text" class="form-control form-control-sm w-75" name="standar_sortasi" placeholder="Contoh: Ukuran biji, kadar air..." value="{{ old('standar_sortasi', $pengurus->standar_sortasi) }}">
</div>
</div>
<h5 class="pb-3 border-bottom mb-4 mt-4">Praktik Pengeringan</h5>
<div class="mb-4">
<label class="form-label fw-semibold">Apakah Koperasi melakukan pengeringan hasil panen?</label> <br>
<div class="form-check form-check-inline"><input class="form-check-input trigger-toggle" type="radio" name="praktik_pengeringan" value="Ya rutin" data-target="keringInput" data-action="show" {{ old('praktik_pengeringan', $pengurus->praktik_pengeringan) == 'Ya rutin' ? 'checked' : '' }}><label class="form-check-label">Ya, rutin</label></div>
<div class="form-check form-check-inline"><input class="form-check-input trigger-toggle" type="radio" name="praktik_pengeringan" value="Kadang" data-target="keringInput" data-action="show" {{ old('praktik_pengeringan', $pengurus->praktik_pengeringan) == 'Kadang' ? 'checked' : '' }}><label class="form-check-label">Kadang-kadang</label></div>
<div class="form-check form-check-inline"><input class="form-check-input trigger-toggle" type="radio" name="praktik_pengeringan" value="Tidak" data-target="keringInput" data-action="hide" {{ old('praktik_pengeringan', $pengurus->praktik_pengeringan) == 'Tidak' ? 'checked' : '' }}><label class="form-check-label">Tidak pernah</label></div>
<div class="mt-2 {{ in_array(old('praktik_pengeringan', $pengurus->praktik_pengeringan), ['Ya rutin', 'Kadang']) ? '' : 'd-none' }}" id="keringInput">
<label class="form-label small text-muted mb-1">Jika ya, cara dan tempat pengeringan:</label>
<input type="text" class="form-control form-control-sm w-75" name="cara_pengeringan" placeholder="Contoh: Jemur matahari di lantai jemur..." value="{{ old('cara_pengeringan', $pengurus->cara_pengeringan) }}">
</div>
</div>
<h5 class="pb-3 border-bottom mb-4 mt-4">Praktik Fermentasi</h5>
<div class="mb-4">
<label class="form-label fw-semibold">Apakah Koperasi melakukan/memfasilitasi fermentasi/pengepresan?</label> <br>
<div class="form-check form-check-inline"><input class="form-check-input trigger-toggle" type="radio" name="praktik_fermentasi" value="Ya rutin" data-target="fermInput" data-action="show" {{ old('praktik_fermentasi', $pengurus->praktik_fermentasi) == 'Ya rutin' ? 'checked' : '' }}><label class="form-check-label">Ya, rutin</label></div>
<div class="form-check form-check-inline"><input class="form-check-input trigger-toggle" type="radio" name="praktik_fermentasi" value="Pernah coba" data-target="fermInput" data-action="show" {{ old('praktik_fermentasi', $pengurus->praktik_fermentasi) == 'Pernah coba' ? 'checked' : '' }}><label class="form-check-label">Pernah mencoba</label></div>
<div class="form-check form-check-inline"><input class="form-check-input trigger-toggle" type="radio" name="praktik_fermentasi" value="Belum, direncakan" data-target="fermInput" data-action="hide" {{ old('praktik_fermentasi', $pengurus->praktik_fermentasi) == 'Belum, direncakan' ? 'checked' : '' }}><label class="form-check-label">Belum pernah (direncanakan)</label></div>
<div class="form-check form-check-inline"><input class="form-check-input trigger-toggle" type="radio" name="praktik_fermentasi" value="Belum, tidak" data-target="fermInput" data-action="hide" {{ old('praktik_fermentasi', $pengurus->praktik_fermentasi) == 'Belum, tidak' ? 'checked' : '' }}><label class="form-check-label">Belum pernah (tidak direncanakan)</label></div>
<div class="mt-3 p-3 bg-light rounded {{ in_array(old('praktik_fermentasi', $pengurus->praktik_fermentasi), ['Ya rutin', 'Pernah coba']) ? '' : 'd-none' }}" id="fermInput">
<label class="form-label small fw-bold mb-2">Model fermentasi (Boleh pilih >1):</label>
<div class="form-check form-check-inline"><input class="form-check-input" type="checkbox" name="model_fermentasi[]" value="Individual" {{ str_contains($pengurus->model_fermentasi ?? '', 'Individual') ? 'checked' : '' }}><label class="form-check-label">Individual</label></div>
<div class="form-check form-check-inline"><input class="form-check-input" type="checkbox" name="model_fermentasi[]" value="Kolektif" {{ str_contains($pengurus->model_fermentasi ?? '', 'Kolektif') ? 'checked' : '' }}><label class="form-check-label">Kolektif kelompok</label></div>
<div class="form-check form-check-inline"><input class="form-check-input" type="checkbox" name="model_fermentasi[]" value="Unit desa" {{ str_contains($pengurus->model_fermentasi ?? '', 'Unit desa') ? 'checked' : '' }}><label class="form-check-label">Unit pengolah desa</label></div>
<div class="form-check form-check-inline"><input class="form-check-input" type="checkbox" name="model_fermentasi[]" value="Campuran" {{ str_contains($pengurus->model_fermentasi ?? '', 'Campuran') ? 'checked' : '' }}><label class="form-check-label">Campuran</label></div>
<br>
<label class="form-label small fw-bold mt-3 mb-1">Bagaimana prosesnya dilakukan:</label>
<textarea class="form-control form-control-sm" name="proses_fermentasi" rows="2">{{ old('proses_fermentasi', $pengurus->proses_fermentasi) }}</textarea>
</div>
</div>
<div class="mb-4">
<h5 class="pb-3 border-bottom mb-4 mt-4">Besaran Premium Harga</h5>
<p class="small text-muted mb-2">Menurut pengalaman/pengamatan Koperasi, berapa kenaikan harga yang dapat dicapai jika sortasi/pengeringan/fermentasi standar diterapkan?</p>
<div class="d-flex align-items-center gap-3">
<div class="input-group input-group-sm w-auto">
<span class="input-group-text">Rp</span>
<input type="number" class="form-control" name="harga_premium_rupiah" placeholder="0" value="{{ old('harga_premium_rupiah', $pengurus->harga_premium_rupiah) }}">
<span class="input-group-text">/kg</span>
</div>
<span class="fw-bold text-muted">ATAU</span>
<div class="input-group input-group-sm w-auto">
<input type="number" class="form-control" name="harga_premium_persen" placeholder="0" max="100" value="{{ old('harga_premium_persen', $pengurus->harga_premium_persen) }}">
<span class="input-group-text">%</span>
</div>
</div>
</div>
</div>
<div class="d-flex justify-content-between mt-5 border-top pt-4">
<a href="{{ route('koperasi.pengurus.survey', ['id' => $pengurus->id ?? 0, 'step' => 1]) }}" class="btn btn-label-secondary">
<i class="ti tabler-arrow-left me-1"></i> Sebelumnya
</a>
<div class="ms-auto">
<button type="submit" class="btn btn-primary">
Simpan & Selanjutnya <i class="ti tabler-arrow-right ms-1"></i>
</button>
</div>
</div>
</form>
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
$('.trigger-toggle-check').change(function() {
let target = $(this).data('target');
if ($(this).is(':checked')) {
$('#' + target).removeClass('d-none').focus();
} else {
$('#' + target).addClass('d-none').val('');
}
});
$('.trigger-toggle').change(function() {
let target = $(this).data('target');
let action = $(this).data('action');
if (action === 'show') {
$('#' + target).removeClass('d-none').focus();
} else {
$('#' + target).addClass('d-none').val('');
}
});
</script>
@endpush
@@ -0,0 +1,153 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
@include('koperasi.profil.header', ['pengurus' => $pengurus])
<div class="card shadow-sm border-0 mb-4">
<div class="card-body p-0">
<form action="{{ route('koperasi.pengurus.survey.store', ['id' => $pengurus->id ?? 0, 'step' => 3]) }}" method="POST" class="p-4 p-md-5">
@csrf
<input type="hidden" name="pengurus_koperasi_id" value="{{ $pengurus->id ?? '' }}">
<h5 class="fw-bold text-dark mb-4">SOSIAL-EKONOMI RUMAH TANGGA</h5>
<div class="border-bottom pb-4 mb-4">
<h6 class="text-muted fw-normal mb-1">bagian tentang kendala & tantangan</h6>
<p class="text-muted small mb-0">Kuesioner bagian ini ditujukan untuk memetakan kestabilan finansial anggota koperasi yang bersangkutan</p>
</div>
<h6 class="fw-bold text-dark mb-3">K2 KONDISI EKONOMI RUMAH TANGGA</h6>
<h6 class="fw-semibold text-dark mb-4">Stabilitas penghasilan sepanjang tahun</h6>
<div class="row mb-4">
<div class="col-md-6 mb-3">
<label class="form-label">Berapa nominal simpanan wajib terbesar (secara perorangan) yang disetorkan oleh anggota koperasi ini?</label>
<div class="input-group">
<span class="input-group-text">Rp.</span>
<input type="number" class="form-control" name="simpanan_terbesar" placeholder="0" value="{{ old('simpanan_terbesar', $pengurus->simpanan_terbesar) }}">
</div>
</div>
<div class="col-md-6 mb-3">
<label class="form-label">Pada bulan dan momen apa, simpanan wajib anggota koperasi secara rata-rata lebih tinggi, daripada setoran pada bulan lainnya?</label>
<input type="text" class="form-control" name="momen_simpanan_terbesar" placeholder="..." value="{{ old('momen_simpanan_terbesar', $pengurus->momen_simpanan_terbesar) }}">
</div>
</div>
<div id="blok-alasan-pinjaman" class="mb-4 p-3 bg-label-warning rounded border border-warning">
<label class="form-label fw-semibold text-dark">
<i class="ti tabler-bulb text-warning me-1"></i>(Tanyakan jika koperasi merupakan koperasi simpan pinjam) Apa alasan/keperluan utama anggota melakukan pinjaman kepada koperasi?
</label>
<div class="row g-2 mt-1">
<div class="col-md-4"><div class="form-check"><input class="form-check-input" type="checkbox" name="alasan_pinjaman[]" value="Produksi" {{ str_contains($pengurus->alasan_pinjaman ?? '', 'Produksi') ? 'checked' : '' }}><label class="form-check-label">Keperluan produksi</label></div></div>
<div class="col-md-4"><div class="form-check"><input class="form-check-input" type="checkbox" name="alasan_pinjaman[]" value="Pendidikan" {{ str_contains($pengurus->alasan_pinjaman ?? '', 'Pendidikan') ? 'checked' : '' }}><label class="form-check-label">Pendidikan</label></div></div>
<div class="col-md-4"><div class="form-check"><input class="form-check-input" type="checkbox" name="alasan_pinjaman[]" value="Kesehatan" {{ str_contains($pengurus->alasan_pinjaman ?? '', 'Kesehatan') ? 'checked' : '' }}><label class="form-check-label">Kesehatan</label></div></div>
<div class="col-md-4"><div class="form-check"><input class="form-check-input" type="checkbox" name="alasan_pinjaman[]" value="Acara keluarga" {{ str_contains($pengurus->alasan_pinjaman ?? '', 'Acara keluarga') ? 'checked' : '' }}><label class="form-check-label">Acara keluarga/adat/hari besar</label></div></div>
<div class="col-md-4"><div class="form-check"><input class="form-check-input" type="checkbox" name="alasan_pinjaman[]" value="Renovasi" {{ str_contains($pengurus->alasan_pinjaman ?? '', 'Renovasi') ? 'checked' : '' }}><label class="form-check-label">Renovasi rumah</label></div></div>
<div class="col-md-4"><div class="form-check"><input class="form-check-input" type="checkbox" name="alasan_pinjaman[]" value="Sekunder" {{ str_contains($pengurus->alasan_pinjaman ?? '', 'Sekunder') ? 'checked' : '' }}><label class="form-check-label">Kebutuhan sekunder</label></div></div>
<div class="col-12 mt-2">
<div class="form-check d-inline-flex align-items-center gap-2">
<input class="form-check-input trigger-toggle-check" type="checkbox" name="alasan_pinjaman[]" value="Lainnya" data-target="alasanLainnya" {{ str_contains($pengurus->alasan_pinjaman ?? '', 'Lainnya') ? 'checked' : '' }}>
<label class="form-check-label text-nowrap">Lainnya, sebutkan:</label>
<input type="text" class="form-control form-control-sm {{ str_contains($pengurus->alasan_pinjaman ?? '', 'Lainnya') ? '' : 'd-none' }}" id="alasanLainnya" name="alasan_pinjaman_lainnya" value="{{ old('alasan_pinjaman_lainnya', $pengurus->alasan_pinjaman_lainnya) }}">
</div>
</div>
</div>
</div>
<div id="blok-ikatan-keuangan" class="mt-5">
<h6 class="fw-bold text-dark mb-3">K6 IKATAN KEUANGAN</h6>
<h6 class="fw-semibold text-dark mb-3">Keterlibatan Koperasi Simpan Pinjam dengan Petani Anggota Koperasi</h6>
<div class="alert alert-outline-warning small py-2 mb-4">
<i class="ti tabler-bulb text-warning me-1"></i> Tanyakan jika koperasi merupakan koperasi simpan pinjam<br>
<i class="ti tabler-bulb text-warning me-1"></i> Pertanyaan pada bagian ini sensitif untuk sebagian orang, enumerator perlu melakukan strategi penggalian data tertentu kepada responden yang diwawancarai
</div>
<div class="mb-4">
<label class="form-label">Apakah terdapat mekanisme pembayaran pinjaman oleh petani anggota koperasi, dalam bentuk selain uang, misalnya hasil bumi?</label>
<div class="form-check form-check-inline"><input class="form-check-input trigger-toggle" type="radio" name="pembayaran_selain_uang" value="Ada" data-target="bentukBayarBlok" data-action="show" {{ old('pembayaran_selain_uang', $pengurus->pembayaran_selain_uang) == 'Ada' ? 'checked' : '' }}><label class="form-check-label">Ada</label></div>
<div class="form-check form-check-inline"><input class="form-check-input trigger-toggle" type="radio" name="pembayaran_selain_uang" value="Tidak ada" data-target="bentukBayarBlok" data-action="hide" {{ old('pembayaran_selain_uang', $pengurus->pembayaran_selain_uang) == 'Tidak ada' ? 'checked' : '' }}><label class="form-check-label">Tidak ada</label></div>
</div>
<div id="bentukBayarBlok" class="p-3 bg-light rounded {{ old('pembayaran_selain_uang', $pengurus->pembayaran_selain_uang) == 'Ada' ? '' : 'd-none' }}">
<div class="mb-4">
<label class="form-label">Jika Ada, apa bentuk pembayaran oleh petani anggota, yang dapat diterima koperasi selain dalam bentuk uang?</label>
<div class="form-check">
<input class="form-check-input trigger-hasil-bumi" type="checkbox" name="bentuk_pembayaran_barang[]" id="chkHasilBumi" value="Hasil bumi" {{ str_contains($pengurus->bentuk_pembayaran_barang ?? '', 'Hasil bumi') ? 'checked' : '' }}>
<label class="form-check-label" for="chkHasilBumi">Hasil bumi (hasil panen)</label>
</div>
<div class="form-check"><input class="form-check-input" type="checkbox" name="bentuk_pembayaran_barang[]" value="Ganti jasa" {{ str_contains($pengurus->bentuk_pembayaran_barang ?? '', 'Ganti jasa') ? 'checked' : '' }}><label class="form-check-label">Ganti jasa/tenaga harian</label></div>
<div class="form-check d-flex align-items-center gap-2 mt-2">
<input class="form-check-input trigger-toggle-check" type="checkbox" name="bentuk_pembayaran_barang[]" value="Lainnya" data-target="bentukBayarLainnya" {{ str_contains($pengurus->bentuk_pembayaran_barang ?? '', 'Lainnya') ? 'checked' : '' }}>
<label class="form-check-label text-nowrap">Lainnya, sebutkan:</label>
<input type="text" class="form-control form-control-sm w-50 {{ str_contains($pengurus->bentuk_pembayaran_barang ?? '', 'Lainnya') ? '' : 'd-none' }}" id="bentukBayarLainnya" name="bentuk_pembayaran_lainnya" value="{{ old('bentuk_pembayaran_lainnya', $pengurus->bentuk_pembayaran_lainnya) }}">
</div>
</div>
<div class="mb-2 {{ str_contains($pengurus->bentuk_pembayaran_barang ?? '', 'Hasil bumi') ? '' : 'd-none' }}" id="blokHitungPasar">
<label class="form-label">Jika pembayaran pinjaman dilakukan dalam bentuk penukaran hasil bumi, apakah hasil bumi tersebut dihitung berdasarkan harga yang berlaku di pasaran?</label><br>
<div class="form-check form-check-inline"><input class="form-check-input trigger-toggle" type="radio" name="perhitungan_harga_pasar" value="Ya" data-target="alasanPasar" data-action="hide" {{ old('perhitungan_harga_pasar', $pengurus->perhitungan_harga_pasar) == 'Ya' ? 'checked' : '' }}><label class="form-check-label">Ya</label></div>
<div class="form-check form-check-inline d-inline-flex align-items-center gap-2">
<input class="form-check-input trigger-toggle" type="radio" name="perhitungan_harga_pasar" value="Tidak" data-target="alasanPasar" data-action="show" {{ old('perhitungan_harga_pasar', $pengurus->perhitungan_harga_pasar) == 'Tidak' ? 'checked' : '' }}>
<label class="form-check-label text-nowrap">Tidak, sebutkan alasannya:</label>
<input type="text" class="form-control form-control-sm {{ old('perhitungan_harga_pasar', $pengurus->perhitungan_harga_pasar) == 'Tidak' ? '' : 'd-none' }}" id="alasanPasar" name="alasan_bukan_harga_pasar" value="{{ old('alasan_bukan_harga_pasar', $pengurus->alasan_bukan_harga_pasar) }}">
</div>
</div>
</div>
</div>
<div class="d-flex justify-content-between mt-5 border-top pt-4">
<a href="{{ route('koperasi.pengurus.survey', ['id' => $pengurus->id ?? 0, 'step' => 2]) }}" class="btn btn-label-secondary">
<i class="ti tabler-arrow-left me-1"></i> Sebelumnya
</a>
<div class="ms-auto">
<button type="submit" class="btn btn-success">
<i class="ti tabler-device-floppy me-1"></i> Selesaikan Survei
</button>
</div>
</div>
</form>
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
$('.trigger-toggle-check').change(function() {
let target = $(this).data('target');
if ($(this).is(':checked')) {
$('#' + target).removeClass('d-none').focus();
} else {
$('#' + target).addClass('d-none').val('');
}
});
$('.trigger-toggle').change(function() {
let target = $(this).data('target');
let action = $(this).data('action');
if (action === 'show') {
$('#' + target).removeClass('d-none').focus();
} else {
$('#' + target).addClass('d-none').val('');
}
});
$(document).ready(function() {
$('.trigger-hasil-bumi').on('change', function() {
if ($(this).is(':checked')) {
$('#blokHitungPasar').removeClass('d-none').hide().slideDown();
} else {
$('#blokHitungPasar').slideUp(function() {
$(this).addClass('d-none');
$('input[name="perhitungan_harga_pasar"]').prop('checked', false);
$('#alasanPasar').addClass('d-none').val('');
});
}
});
});
</script>
@endpush
+22 -2
View File
@@ -15,7 +15,7 @@
name="viewport"
content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" />
<meta name="robots" content="noindex, nofollow" />
<title>AgroMonev | {{ $title ?? 'Database Petani' }}</title>
<title>AGERA | {{ $title ?? 'Database Petani' }}</title>
<meta name="description" content="" />
@@ -26,7 +26,7 @@
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="default">
<link rel="icon" type="image/x-icon" href="../../assets/img/favicon/favicon.ico" />
<link rel="icon" type="image/svg+xml" href="{{ asset('assets/img/logo/agera_icon.svg') }}" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
@@ -64,6 +64,26 @@
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
<style>
.agera-logo {
width: 200px;
height: auto;
max-height: 78px;
object-fit: contain;
display: block;
}
.app-brand-logo.demo {
width: auto;
height: auto;
}
.app-brand.demo {
height: 98px;
padding-top: 10px;
padding-bottom: 10px;
}
</style>
@stack('style')
<script src="{{ asset('assets/vendor/js/helpers.js') }}"></script>
+70 -25
View File
@@ -2,19 +2,11 @@
<div class="app-brand demo ">
<a href="{{ route('home') }}" class="app-brand-link">
<span class="app-brand-logo demo">
<span>
<svg width="32" height="24" viewBox="0 0 32 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.3" d="M16 2.5C16 2.5 5 6.5 5 15.5C5 20.5 11 23.5 16 23.5V2.5Z" fill="#28a745" />
<path opacity="0.6" d="M16 2.5C16 2.5 27 6.5 27 15.5C27 20.5 21 23.5 16 23.5V2.5Z" fill="#28a745" />
<path d="M2 19L10 11L15 15" stroke="#0054A6" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" />
<path d="M15 15L27 4" stroke="#ED1C24" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" />
<circle cx="27" cy="4" r="2.5" fill="#ED1C24" />
</svg>
</span>
</span>
<span class="app-brand-text demo menu-text fw-bold ms-3" style="text-transform: capitalize;">
AgroMonev
<img
src="{{ asset('assets/img/logo/agera_side.svg') }}"
alt="AGERA"
class="agera-logo"
>
</span>
</a>
@@ -36,7 +28,7 @@
<li class="menu-item active open">
<a href="javascript:void(0);" class="menu-link menu-toggle">
<i class="menu-icon icon-base ti tabler-smart-home"></i>
<div data-i18n="Dashboards">Dashboards</div>
<div data-i18n="Dashboard">Dashboard</div>
</a>
@if(in_array($userRole, ['super_admin', 'admin']) && env('APP_NAME') == 'AgroMonev')
@@ -49,6 +41,30 @@
</ul>
@endif
@if(in_array($userRole, ['super_admin', 'admin']) && env('APP_NAME') == 'AgroMonev')
<ul class="menu-sub">
<li class="menu-item {{ request()->routeIs('dashboard.indeks-petani') ? 'active' : '' }}">
<a href="{{ route('dashboard.indeks-petani') }}" class="menu-link">
<div data-i18n="Indeks Petani">Indeks Petani</div>
</a>
</li>
</ul>
<ul class="menu-sub">
<li class="menu-item {{ request()->routeIs('dashboard.demografi-petani') ? 'active' : '' }}">
<a href="{{ route('dashboard.demografi-petani') }}" class="menu-link">
<div data-i18n="Demografi Petani">Demografi Petani</div>
</a>
</li>
</ul>
<ul class="menu-sub">
<li class="menu-item {{ request()->routeIs('dashboard.indikator-pertanian') ? 'active' : '' }}">
<a href="{{ route('dashboard.indikator-pertanian') }}" class="menu-link">
<div data-i18n="Indikator Pertanian">Indikator Pertanian</div>
</a>
</li>
</ul>
@endif
@if(in_array($userRole, ['super_admin', 'admin', 'fasilitator']) && env('APP_NAME') == 'AgroMonev')
<ul class="menu-sub">
<li class="menu-item {{ request()->routeIs('dashboard.survey-petani') ? 'active' : '' }}">
@@ -57,29 +73,58 @@
</a>
</li>
</ul>
<ul class="menu-sub">
<!-- <ul class="menu-sub">
<li class="menu-item {{ request()->routeIs('dashboard.petani') ? 'active' : '' }}">
<a href="{{ route('dashboard.petani') }}" class="menu-link">
<div data-i18n="Profil Petani">Profil Petani</div>
</a>
</li>
</ul> -->
@endif
@if(in_array($userRole, ['super_admin', 'admin']) && env('APP_NAME') == 'AgroMonev-xx')
<ul class="menu-sub">
<li class="menu-item {{ request()->routeIs('dashboard.bumdes') ? 'active' : '' }}">
<a href="{{ route('dashboard.bumdes') }}" class="menu-link">
<div data-i18n="Profil Pengurus BUMDes">Profil Pengurus BUMDes</div>
</a>
</li>
</ul>
@endif
</li>
@endif
@if(in_array($userRole, ['fasilitator', 'super_admin', 'admin']) && env('APP_NAME') == 'AgroMonev')
<li class="menu-header small">
<span class="menu-header-text" data-i18n="Data Pertanian">Data Pertanian</span>
</li>
<li class="menu-item {{ request()->routeIs('petani.*') ? 'active' : '' }}">
<a href="{{ route('petani.index') }}" class="menu-link">
<i class="menu-icon icon-base ti tabler-file-description"></i>
<div data-i18n="Profil Petani">Profil Petani</div>
</a>
</li>
<li class="menu-header small">
<span class="menu-header-text" data-i18n="Data Pertanian">Data Pertanian</span>
</li>
<li class="menu-item {{ request()->routeIs('petani.*') ? 'active' : '' }}">
<a href="{{ route('petani.index') }}" class="menu-link">
<i class="menu-icon icon-base ti tabler-file-description"></i>
<div data-i18n="Profil Petani">Profil Petani</div>
</a>
</li>
@if(in_array($userRole, ['super_admin', 'admin']) && env('APP_NAME') == 'AgroMonev')
<li class="menu-item {{ request()->routeIs('kelompok-tani.*') ? 'active' : '' }}">
<a href="{{ route('kelompok-tani.index') }}" class="menu-link">
<i class="menu-icon icon-base ti tabler-file-description"></i>
<div data-i18n="Profil Kelompok Tani">Profil Kelompok Tani</div>
</a>
</li>
<li class="menu-item {{ request()->routeIs('bumdes.*') ? 'active' : '' }}">
<a href="{{ route('bumdes.index') }}" class="menu-link">
<i class="menu-icon icon-base ti tabler-file-description"></i>
<div data-i18n="Profil BUMDes">Profil BUMDes</div>
</a>
</li>
<li class="menu-item {{ request()->routeIs('koperasi.*') ? 'active' : '' }}">
<a href="{{ route('koperasi.pengurus.index') }}" class="menu-link">
<i class="menu-icon icon-base ti tabler-file-description"></i>
<div data-i18n="Profil Pengurus Koperasi">Profil Pengurus Koperasi</div>
</a>
</li>
@endif
@endif
@if(in_array($userRole, ['super_admin', 'admin']) && env('APP_NAME') == 'AgroPro')
<!-- Ekosistem -->
<li class="menu-header small">
@@ -207,6 +207,37 @@
</div>
</div>
<h5 class="pb-3 border-bottom mb-4 mt-4">KEPERCAYAAN & PERSEPSI RISIKO</h5>
<div class="row">
<div class="col-md-6 mb-4 form-control-validation">
<label class="form-label d-block mb-2" for="tingkat-kepercayaan">Seberapa percaya Bapak/Ibu untuk menjual ke pembeli atau pasar baru, di luar pembeli yang biasa?</label>
@foreach($tingkatKepercayaanOptions as $option)
<div class="form-check mb-2">
<input class="form-check-input @error('tingkat_kepercayaan_pembeli_baru') is-invalid @enderror"
type="radio"
id="tingkat-kepercayaan-{{ $option['value'] }}"
name="tingkat_kepercayaan_pembeli_baru"
value="{{ $option['value'] }}"
{{ (string) old('tingkat_kepercayaan_pembeli_baru', $aksesPasar?->tingkat_kepercayaan_pembeli_baru) === (string) $option['value'] ? 'checked' : '' }}>
<label class="form-check-label" for="tingkat-kepercayaan-{{ $option['value'] }}">
{{ $option['label'] }}
</label>
</div>
@endforeach
@error('tingkat_kepercayaan_pembeli_baru')<div class="invalid-feedback d-block">{{ $message }}</div>@enderror
</div>
<div class="col-md-6 mb-4 form-control-validation">
<label class="form-label mb-2" for="alasan-kepercayaan">Apa yang membuat Bapak/Ibu ragu atau yakin untuk mencoba pembeli baru?</label>
<textarea class="form-control @error('alasan_kepercayaan_pembeli_baru') is-invalid @enderror"
id="alasan-kepercayaan"
name="alasan_kepercayaan_pembeli_baru"
rows="4"
placeholder="Tuliskan alasannya di sini...">{{ old('alasan_kepercayaan_pembeli_baru', $aksesPasar?->alasan_kepercayaan_pembeli_baru) }}</textarea>
@error('alasan_kepercayaan_pembeli_baru')<div class="invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="mt-4 text-end">
<button type="submit" class="btn btn-success">
<i class="icon-base ti tabler-device-floppy me-1_5 icon-sm"></i>Simpan Akses Pasar
@@ -15,8 +15,8 @@
<div class="w-25">
<x-summary-card
title="Lahan & Tanaman"
count="{{ number_format(($lahan?->sum('luas_lahan') ?? 0) / 10000, 2, ',', '.') }} ha"
subtitle="{{ $tanaman?->count() }} tanaman dari {{ $komoditas?->count() }} komoditas utama"
count="{{ number_format(($totalLuasLahan ?? 0) / 10000, 2, ',', '.') }} ha"
subtitle="{{ $totalTanaman ?? 0 }} tanaman dari {{ $komoditas?->count() }} komoditas utama"
icon="trees"
color="success"
/>
@@ -1598,42 +1598,66 @@
action="{{ route('petani.survey-produktivitas.store', $petani->id) }}"
class="form-repeater">
@csrf
<input type="hidden" name="redirect_fragment" value="section-kehilangan-hasil">
<input type="hidden" name="redirect_fragment" value="section-produktivitas">
@php
$produktivitasRows = old('produktivitas_komoditas');
if (!is_array($produktivitasRows) || count($produktivitasRows) === 0) {
$produktivitasRows = [
[
'komoditas_id' => null,
'hasil_panen_3_musim' => null,
'satuan' => null,
],
];
}
@endphp
<div data-repeater-list="produktivitas_komoditas">
@foreach ($produktivitasRows as $index => $produktivitasRow)
<div data-repeater-item>
<div class="row align-items-end">
<div class="col-md-4 mb-3">
<label class="form-label">Komoditas</label>
<select name="komoditas_id" class="form-select">
<select name="komoditas_id" class="form-select @error('produktivitas_komoditas.' . $index . '.komoditas_id') is-invalid @enderror">
<option value="">Pilih Komoditas</option>
@foreach ($komoditas as $item)
<option value="{{ $item->id }}">{{ $item->nama }}</option>
<option value="{{ $item->id }}" @selected((string) data_get($produktivitasRow, 'komoditas_id') === (string) $item->id)>{{ $item->nama }}</option>
@endforeach
</select>
@error('produktivitas_komoditas.' . $index . '.komoditas_id')
<div class="invalid-feedback d-block">{{ $message }}</div>
@enderror
</div>
<div class="col-md-3 mb-3">
<label class="form-label">Hasil</label>
<div class="input-group">
<input type="number" name="hasil_panen_3_musim" class="form-control" step="0.01" min="0">
<input type="number" name="hasil_panen_3_musim" class="form-control @error('produktivitas_komoditas.' . $index . '.hasil_panen_3_musim') is-invalid @enderror" step="0.01" min="0" value="{{ data_get($produktivitasRow, 'hasil_panen_3_musim') }}">
<span class="input-group-text">Kg</span>
</div>
@error('produktivitas_komoditas.' . $index . '.hasil_panen_3_musim')
<div class="invalid-feedback d-block">{{ $message }}</div>
@enderror
</div>
<div class="col-md-3 mb-3">
<label class="form-label d-block">Satuan</label>
<label class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="satuan" value="ha_tahun">
<input class="form-check-input @error('produktivitas_komoditas.' . $index . '.satuan') is-invalid @enderror" type="radio" name="satuan" value="ha_tahun" @checked(data_get($produktivitasRow, 'satuan') === 'ha_tahun')>
<span class="form-check-label">Ha/Tahun</span>
</label>
<label class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="satuan" value="pohon_tahun">
<input class="form-check-input @error('produktivitas_komoditas.' . $index . '.satuan') is-invalid @enderror" type="radio" name="satuan" value="pohon_tahun" @checked(data_get($produktivitasRow, 'satuan') === 'pohon_tahun')>
<span class="form-check-label">Pohon/Tahun</span>
</label>
@error('produktivitas_komoditas.' . $index . '.satuan')
<div class="invalid-feedback d-block">{{ $message }}</div>
@enderror
</div>
<div class="col-md-2 mb-3">
@@ -1645,6 +1669,7 @@
</div>
<hr>
</div>
@endforeach
</div>
<div class="mt-4 d-flex justify-content-between">
@@ -1064,6 +1064,9 @@
const pernahJualHargaLebihTinggiPernah = @json($pernahJualHargaLebihTinggiPernahValue);
const panutanPetaniSuksesTidakAda = String(@json($panutanPetaniSuksesTidakAdaValue));
const terdaftarKelompokTaniYa = @json($terdaftarKelompokTaniYaValue);
const keaktifanPertemuanKelompokLowest = String(@json($keaktifanPertemuanKelompokLowestValue));
const peranDalamKelompokLowest = String(@json($peranDalamKelompokLowestValue));
const manfaatKelompokTaniLowest = String(@json($manfaatKelompokTaniLowestValue));
const statusRekeningTidakPunya = String(@json($statusRekeningTidakPunyaValue));
const pengalamanKreditPerluAlasan = @json($pengalamanKreditPerluAlasanValues).map(String);
const alasanKreditLainnya = @json($alasanKreditLainnyaValue);
@@ -1475,12 +1478,17 @@
function syncTerdaftarKelompokFields() {
const isTerdaftar = $('input[name="terdaftar_kelompok_tani"]:checked').val() === terdaftarKelompokTaniYa;
const $fields = $('#nama-kelompok-tani, #lama-bergabung-kelompok, #kedekatan-sesama-anggota');
const $fields = $('#nama-kelompok-tani, #lama-bergabung-kelompok, #kedekatan-sesama-anggota, #topik-biasa-dibahas')
.add('input[name="keaktifan_pertemuan_kelompok"], input[name="peran_dalam_kelompok"], input[name="manfaat_kelompok_tani"]');
$fields.prop('disabled', !isTerdaftar);
if (!isTerdaftar) {
$fields.val('');
$('#nama-kelompok-tani, #lama-bergabung-kelompok, #topik-biasa-dibahas').val('');
$('input[name="keaktifan_pertemuan_kelompok"][value="' + keaktifanPertemuanKelompokLowest + '"]').prop('checked', true);
$('input[name="peran_dalam_kelompok"][value="' + peranDalamKelompokLowest + '"]').prop('checked', true);
$('input[name="manfaat_kelompok_tani"][value="' + manfaatKelompokTaniLowest + '"]').prop('checked', true);
$('#kedekatan-sesama-anggota').val('');
$('#kedekatan-sesama-anggota').trigger('change.select2');
}
}
@@ -1060,6 +1060,9 @@
const pernahJualHargaLebihTinggiPernah = @json($pernahJualHargaLebihTinggiPernahValue);
const panutanPetaniSuksesTidakAda = String(@json($panutanPetaniSuksesTidakAdaValue));
const terdaftarKelompokTaniYa = @json($terdaftarKelompokTaniYaValue);
const keaktifanPertemuanKelompokLowest = String(@json($keaktifanPertemuanKelompokLowestValue));
const peranDalamKelompokLowest = String(@json($peranDalamKelompokLowestValue));
const manfaatKelompokTaniLowest = String(@json($manfaatKelompokTaniLowestValue));
const statusRekeningTidakPunya = String(@json($statusRekeningTidakPunyaValue));
const pengalamanKreditPerluAlasan = @json($pengalamanKreditPerluAlasanValues).map(String);
const alasanKreditLainnya = @json($alasanKreditLainnyaValue);
@@ -1471,12 +1474,17 @@
function syncTerdaftarKelompokFields() {
const isTerdaftar = $('input[name="terdaftar_kelompok_tani"]:checked').val() === terdaftarKelompokTaniYa;
const $fields = $('#nama-kelompok-tani, #lama-bergabung-kelompok, #kedekatan-sesama-anggota');
const $fields = $('#nama-kelompok-tani, #lama-bergabung-kelompok, #kedekatan-sesama-anggota, #topik-biasa-dibahas')
.add('input[name="keaktifan_pertemuan_kelompok"], input[name="peran_dalam_kelompok"], input[name="manfaat_kelompok_tani"]');
$fields.prop('disabled', !isTerdaftar);
if (!isTerdaftar) {
$fields.val('');
$('#nama-kelompok-tani, #lama-bergabung-kelompok, #topik-biasa-dibahas').val('');
$('input[name="keaktifan_pertemuan_kelompok"][value="' + keaktifanPertemuanKelompokLowest + '"]').prop('checked', true);
$('input[name="peran_dalam_kelompok"][value="' + peranDalamKelompokLowest + '"]').prop('checked', true);
$('input[name="manfaat_kelompok_tani"][value="' + manfaatKelompokTaniLowest + '"]').prop('checked', true);
$('#kedekatan-sesama-anggota').val('');
$('#kedekatan-sesama-anggota').trigger('change.select2');
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,37 @@
{{--
Partial notif per-card. Dipakai di dalam tiap <div class="card"> supaya notif sukses/gagal
muncul tepat di atas card yang barusan disubmit, bukan di paling atas halaman.
Params:
- $section (string) kunci section, harus sama dengan yang dipakai controller di redirectToSection().
- $errorFields (array, optional) daftar nama field/wildcard (mis. 'aset.*') milik card ini,
dipakai buat nentuin apakah error validasi yang ada punya card ini.
--}}
@if(session('success') && session('success_section') === $section)
<div class="alert alert-success alert-dismissible" role="alert">
{{ session('success') }}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
@endif
@if(session('error') && session('error_section') === $section)
<div class="alert alert-danger alert-dismissible" role="alert">
{{ session('error') }}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
@endif
@if(!empty($errorFields) && $errors->has($errorFields))
<div class="alert alert-danger alert-dismissible" role="alert">
<ul class="mb-0">
@foreach($errorFields as $field)
@foreach($errors->get($field) as $messages)
@foreach((array) $messages as $message)
<li>{{ $message }}</li>
@endforeach
@endforeach
@endforeach
</ul>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
@endif
@@ -0,0 +1,287 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
@if ($errors->any())
<div class="alert alert-danger">
<ul class="mb-0">
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
@include('produktivitas.survey-kelompok-tani.header', ['kelompokTani' => null])
<div class="row">
<div class="col-md-12">
<div class="card mb-6">
<div class="card-body pt-6">
<form id="addKelompokTaniForm" action="{{ route('kelompok-tani.store') }}" method="POST">
@csrf
<h5 class="pb-4 border-bottom mb-4">Data Responden</h5>
<div class="row">
<div class="col-md-4 mb-4 form-control-validation">
<label class="form-label" for="add-kt-nama-responden">Nama Responden<span class="text-danger">*</span></label>
<input type="text" class="form-control @error('nama_responden') is-invalid @enderror" id="add-kt-nama-responden" name="nama_responden"
placeholder="Cth: John Doe" value="{{ old('nama_responden') }}" />
@error('nama_responden')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-4 mb-4 form-control-validation">
<label class="form-label" for="add-kt-jabatan-responden">Jabatan Responden</label>
<input type="text" class="form-control @error('jabatan_responden') is-invalid @enderror" id="add-kt-jabatan-responden" name="jabatan_responden"
placeholder="Cth: Ketua Kelompok" value="{{ old('jabatan_responden') }}" />
@error('jabatan_responden')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-4 mb-4 form-control-validation">
<label class="form-label" for="add-kt-kontak-responden">Kontak Responden (No. HP)</label>
<input type="text" class="form-control @error('kontak_responden') is-invalid @enderror" id="add-kt-kontak-responden" name="kontak_responden"
placeholder="Cth: 081234567890" value="{{ old('kontak_responden') }}" />
@error('kontak_responden')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<h5 class="pb-4 border-bottom mb-4 mt-4">Identitas Kelompok Tani</h5>
<div class="row">
<div class="col-md-6 mb-4 form-control-validation">
<label class="form-label" for="add-kt-nama-kelompok">Nama Kelompok Tani<span class="text-danger">*</span></label>
<input type="text" class="form-control @error('nama_kelompok') is-invalid @enderror" id="add-kt-nama-kelompok" name="nama_kelompok"
placeholder="Cth: Kelompok Tani Maju Bersama" value="{{ old('nama_kelompok') }}" />
@error('nama_kelompok')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-kt-dusun">Dusun</label>
<input type="text" class="form-control @error('dusun') is-invalid @enderror" id="add-kt-dusun" name="dusun"
placeholder="Cth: Dusun I" value="{{ old('dusun') }}" />
@error('dusun')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-kt-tahun-berdiri">Tahun Berdiri</label>
<input type="number" class="form-control @error('tahun_berdiri') is-invalid @enderror" id="add-kt-tahun-berdiri" name="tahun_berdiri"
placeholder="Cth: 2015" min="1900" max="{{ date('Y') }}" value="{{ old('tahun_berdiri') }}" />
@error('tahun_berdiri')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="row">
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-kt-provinsi">Provinsi<span class="text-danger">*</span></label>
<select class="form-control @error('provinsi_id') is-invalid @enderror" id="add-kt-provinsi" name="provinsi_id">
<option value="">Pilih Provinsi</option>
@foreach($provinsi as $p)
<option value="{{ $p->id }}" {{ old('provinsi_id') == $p->id ? 'selected' : '' }}>{{ $p->nama }}</option>
@endforeach
</select>
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-kt-kabupaten">Kabupaten/Kota<span class="text-danger">*</span></label>
<select class="form-control @error('kabupaten_id') is-invalid @enderror" id="add-kt-kabupaten" name="kabupaten_id" disabled>
<option value="">Pilih Kabupaten/Kota</option>
</select>
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-kt-kecamatan">Kecamatan<span class="text-danger">*</span></label>
<select class="form-control @error('kecamatan_id') is-invalid @enderror" id="add-kt-kecamatan" name="kecamatan_id" disabled>
<option value="">Pilih Kecamatan</option>
</select>
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-kt-desa">Desa/Kelurahan<span class="text-danger">*</span></label>
<select class="form-control @error('desa_kelurahan_id') is-invalid @enderror" id="add-kt-desa" name="desa_kelurahan_id" disabled>
<option value="">Pilih Desa/Kelurahan</option>
</select>
@error('desa_kelurahan_id')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="row">
<div class="col-md-4 mb-4 form-control-validation">
<label class="form-label" for="add-kt-jenis-kelompok">Terdaftar/Dikenal Sebagai<span class="text-danger">*</span></label>
<select class="form-control @error('jenis_kelompok') is-invalid @enderror" id="add-kt-jenis-kelompok" name="jenis_kelompok">
<option value="">Pilih Jenis Kelompok</option>
<option value="Kelompok Tani (Poktan)" {{ old('jenis_kelompok') == 'Kelompok Tani (Poktan)' ? 'selected' : '' }}>Kelompok Tani (Poktan)</option>
<option value="Kelompok Wanita Tani (KWT)" {{ old('jenis_kelompok') == 'Kelompok Wanita Tani (KWT)' ? 'selected' : '' }}>Kelompok Wanita Tani (KWT)</option>
<option value="Gabungan Kelompok Tani (Gapoktan)" {{ old('jenis_kelompok') == 'Gabungan Kelompok Tani (Gapoktan)' ? 'selected' : '' }}>Gabungan Kelompok Tani (Gapoktan)</option>
<option value="Kelompok Pemuda Tani" {{ old('jenis_kelompok') == 'Kelompok Pemuda Tani' ? 'selected' : '' }}>Kelompok Pemuda Tani</option>
<option value="Asosiasi Petani" {{ old('jenis_kelompok') == 'Asosiasi Petani' ? 'selected' : '' }}>Asosiasi Petani</option>
<option value="Lainnya" {{ old('jenis_kelompok') == 'Lainnya' ? 'selected' : '' }}>Lainnya</option>
</select>
@error('jenis_kelompok')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-4 mb-4 form-control-validation" id="add-kt-jenis-kelompok-lainnya-wrapper" style="display: none;">
<label class="form-label" for="add-kt-jenis-kelompok-lainnya">Sebutkan Jenis Kelompok</label>
<input type="text" class="form-control @error('jenis_kelompok_lainnya') is-invalid @enderror" id="add-kt-jenis-kelompok-lainnya" name="jenis_kelompok_lainnya"
value="{{ old('jenis_kelompok_lainnya') }}" />
@error('jenis_kelompok_lainnya')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-4 mb-4 form-control-validation" id="add-kt-nama-gapoktan-wrapper" style="display: none;">
<label class="form-label" for="add-kt-nama-gapoktan">Nama Gapoktan</label>
<input type="text" class="form-control @error('nama_gapoktan') is-invalid @enderror" id="add-kt-nama-gapoktan" name="nama_gapoktan"
placeholder="Cth: Gapoktan Sumber Makmur" value="{{ old('nama_gapoktan') }}" />
@error('nama_gapoktan')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="row">
<div class="col-md-6 mb-4 form-control-validation">
<label class="form-label">Komoditas Utama</label>
<select id="add-kt-komoditas" name="komoditas_id[]" class="form-select @error('komoditas_id') is-invalid @enderror" multiple>
@foreach($komoditas as $k)
<option value="{{ $k->id }}" {{ collect(old('komoditas_id'))->contains($k->id) ? 'selected' : '' }}>{{ $k->nama }}</option>
@endforeach
</select>
@error('komoditas_id')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="mt-4 text-end">
<a href="{{ route('kelompok-tani.index') }}" class="btn btn-secondary me-2 wave-effect wave-light">Kembali</a>
<button type="submit" class="btn btn-success data-submit wave-effect wave-light"><i class="ti tabler-device-floppy me-2"></i> Simpan & Lanjutkan</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
'use strict';
$(document).ready(function () {
$('#add-kt-jenis-kelompok, #add-kt-komoditas').select2();
function toggleJenisKelompokFields() {
var jenisKelompok = $('#add-kt-jenis-kelompok').val();
if (jenisKelompok === 'Lainnya') {
$('#add-kt-jenis-kelompok-lainnya-wrapper').show();
} else {
$('#add-kt-jenis-kelompok-lainnya-wrapper').hide();
$('#add-kt-jenis-kelompok-lainnya').val('');
}
if (jenisKelompok === 'Gabungan Kelompok Tani (Gapoktan)') {
$('#add-kt-nama-gapoktan-wrapper').show();
} else {
$('#add-kt-nama-gapoktan-wrapper').hide();
$('#add-kt-nama-gapoktan').val('');
}
}
toggleJenisKelompokFields();
$('#add-kt-jenis-kelompok').on('change', toggleJenisKelompokFields);
$('#add-kt-provinsi').select2().on('change', function (e) {
e.preventDefault();
var provinsiId = $(this).val();
$('#add-kt-kabupaten').prop('disabled', !provinsiId).empty().append('<option value="">Pilih Kabupaten/Kota</option>').trigger('change');
$('#add-kt-kecamatan').prop('disabled', true).empty().append('<option value="">Pilih Kecamatan</option>').trigger('change');
$('#add-kt-desa').prop('disabled', true).empty().append('<option value="">Pilih Desa/Kelurahan</option>').trigger('change');
if (provinsiId) {
$.ajax({
url: '{{ route("kabupatenkota.byprovinsi", ":id") }}'.replace(':id', provinsiId),
method: 'GET',
success: function (data) {
$('#add-kt-kabupaten').prop('disabled', false);
data.forEach(function (kabupaten) {
$('#add-kt-kabupaten').append('<option value="' + kabupaten.id + '">' + kabupaten.nama + '</option>');
});
}
});
}
});
$('#add-kt-kabupaten').select2().on('change', function (e) {
e.preventDefault();
var kabupatenId = $(this).val();
$('#add-kt-kecamatan').prop('disabled', !kabupatenId).empty().append('<option value="">Pilih Kecamatan</option>').trigger('change');
$('#add-kt-desa').prop('disabled', true).empty().append('<option value="">Pilih Desa/Kelurahan</option>').trigger('change');
if (kabupatenId) {
$.ajax({
url: '{{ route("kecamatan.bykabupatenkota", ":id") }}'.replace(':id', kabupatenId),
method: 'GET',
success: function (data) {
$('#add-kt-kecamatan').prop('disabled', false);
data.forEach(function (kecamatan) {
$('#add-kt-kecamatan').append('<option value="' + kecamatan.id + '">' + kecamatan.nama + '</option>');
});
}
});
}
});
$('#add-kt-kecamatan').select2().on('change', function (e) {
e.preventDefault();
var kecamatanId = $(this).val();
$('#add-kt-desa').prop('disabled', !kecamatanId).empty().append('<option value="">Pilih Desa/Kelurahan</option>').trigger('change');
if (kecamatanId) {
$.ajax({
url: '{{ route("desakelurahan.bykecamatan", ":id") }}'.replace(':id', kecamatanId),
method: 'GET',
success: function (data) {
$('#add-kt-desa').prop('disabled', false);
data.forEach(function (desa) {
$('#add-kt-desa').append('<option value="' + desa.id + '">' + desa.nama + '</option>');
});
}
});
}
});
$('#add-kt-desa').select2();
$('#addKelompokTaniForm').validate({
rules: {
nama_responden: { required: true },
nama_kelompok: { required: true },
provinsi_id: { required: true },
kabupaten_id: { required: true },
kecamatan_id: { required: true },
desa_kelurahan_id: { required: true },
jenis_kelompok: { required: true },
jenis_kelompok_lainnya: {
required: function () {
return $('#add-kt-jenis-kelompok').val() === 'Lainnya';
}
},
tahun_berdiri: { min: 1900, max: new Date().getFullYear() }
},
messages: {
nama_responden: { required: 'Nama responden wajib diisi' },
nama_kelompok: { required: 'Nama kelompok wajib diisi' },
provinsi_id: { required: 'Provinsi wajib diisi' },
kabupaten_id: { required: 'Kabupaten/Kota wajib diisi' },
kecamatan_id: { required: 'Kecamatan wajib diisi' },
desa_kelurahan_id: { required: 'Desa/Kelurahan wajib diisi' },
jenis_kelompok: { required: 'Jenis kelompok wajib dipilih' },
jenis_kelompok_lainnya: { required: 'Sebutkan jenis kelompoknya' }
},
errorElement: 'div',
errorPlacement: function (error, element) {
error.addClass('invalid-feedback');
if (element.hasClass('select2-hidden-accessible')) {
element.closest('.form-control-validation').append(error);
} else {
element.closest('.mb-4, .form-control-validation').append(error);
}
},
highlight: function (element) {
$(element).addClass('is-invalid');
},
unhighlight: function (element) {
$(element).removeClass('is-invalid');
},
submitHandler: function (form) {
form.submit();
}
});
});
</script>
@endpush
@@ -0,0 +1,198 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
@include('produktivitas.survey-kelompok-tani.header', ['kelompokTani' => $kelompokTani])
@php
$kegiatanOptions = [
'Pertemuan/diskusi rutin',
'Pelatihan bersama',
'Pengadaan input bersama (pupuk/bibit)',
'Pengolahan pascapanen bersama',
'Pemasaran/penjualan kolektif',
'Simpan pinjam kelompok',
'Mengumpulkan hasil panen',
];
$tindakanOptions = [
'Difermentasi',
'Disetorkan ke BUMDes/Koperasi',
'Dijual langsung ke tengkulak/Offtaker',
'Dijual untuk pendanaan kelompok',
];
$fungsiOptions = [
'Pendampingan/penguatan praktik budidaya (GAP) di kebun anggota',
'Pengumpulan/agregasi hasil panen anggota',
'Penyalur informasi & program bantuan dari pemerintah/NGO ke anggota',
'Advokasi/perwakilan kepentingan anggota ke pihak luar',
'Belum ada fungsi spesifik yang berjalan',
];
$kegiatanSelected = old('kegiatan_terlaksana', $kelompokTani->kegiatan_terlaksana ?? []);
$kegiatanLainnyaValue = collect($kegiatanSelected)->first(fn ($v) => !in_array($v, $kegiatanOptions));
$kegiatanLainnyaChecked = old('kegiatan_terlaksana_lainnya', $kegiatanLainnyaValue) !== null;
$tindakanSelected = old('tindakan_hasil_panen', $kelompokTani->tindakan_hasil_panen ?? []);
$fungsiSelected = old('fungsi_kelompok_bagi_anggota', $kelompokTani->fungsi_kelompok_bagi_anggota ?? []);
$fungsiLainnyaValue = collect($fungsiSelected)->first(fn ($v) => !in_array($v, $fungsiOptions));
$fungsiLainnyaChecked = old('fungsi_kelompok_lainnya', $fungsiLainnyaValue) !== null;
@endphp
<div class="card mb-6" id="section-aktivitas-fungsi">
<div class="card-body pt-6">
@include('produktivitas.survey-kelompok-tani._alert', [
'section' => 'aktivitas-fungsi',
'errorFields' => ['kegiatan_terlaksana.*', 'kegiatan_terlaksana_lainnya', 'estimasi_panen_minimal', 'estimasi_panen_maksimal', 'satuan_hasil_panen', 'tindakan_hasil_panen.*', 'fungsi_kelompok_bagi_anggota.*', 'fungsi_kelompok_lainnya'],
])
<form method="POST" action="{{ route('kelompok-tani.update', $kelompokTani->id) }}">
@csrf
@method('PUT')
<input type="hidden" name="section" value="aktivitas-fungsi">
<h5 class="pb-4 border-bottom mb-4">Kegiatan Konkret yang Sudah Berjalan</h5>
<p class="text-muted" style="font-size: 0.8rem; margin-top: -0.75rem;">
Kegiatan yang sudah benar-benar dilaksanakan, bukan rencana. Boleh pilih lebih dari satu.
</p>
<div class="row mb-2">
@foreach($kegiatanOptions as $option)
<div class="col-md-4 mb-2">
<div class="form-check">
<input class="form-check-input kegiatan-checkbox" type="checkbox" name="kegiatan_terlaksana[]" value="{{ $option }}"
id="kegiatan-{{ $loop->index }}" {{ in_array($option, $kegiatanSelected) ? 'checked' : '' }}
@if($option === 'Mengumpulkan hasil panen') data-toggle-panen @endif>
<label class="form-check-label" for="kegiatan-{{ $loop->index }}">{{ $option }}</label>
</div>
</div>
@endforeach
<div class="col-md-4 mb-2">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="kegiatan_terlaksana[]" value="Lainnya" id="kegiatan-lainnya-check" {{ $kegiatanLainnyaChecked ? 'checked' : '' }}>
<label class="form-check-label" for="kegiatan-lainnya-check">Lainnya</label>
</div>
</div>
</div>
<div class="row" id="kegiatan-lainnya-wrapper" style="display: none;">
<div class="col-md-6 mb-4 form-control-validation">
<input type="text" class="form-control @error('kegiatan_terlaksana_lainnya') is-invalid @enderror" name="kegiatan_terlaksana_lainnya"
id="kegiatan-lainnya-text" placeholder="Sebutkan kegiatan lainnya"
value="{{ old('kegiatan_terlaksana_lainnya', $kegiatanLainnyaValue) }}" />
@error('kegiatan_terlaksana_lainnya')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div id="panen-wrapper" style="display: none;">
<h6 class="pb-2 mt-3">Detail Hasil Panen</h6>
<div class="row">
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="af-panen-min">Estimasi Panen Minimal</label>
<input type="number" step="0.01" min="0" class="form-control @error('estimasi_panen_minimal') is-invalid @enderror" id="af-panen-min" name="estimasi_panen_minimal"
value="{{ old('estimasi_panen_minimal', $kelompokTani->estimasi_panen_minimal) }}" />
@error('estimasi_panen_minimal')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="af-panen-max">Estimasi Panen Maksimal</label>
<input type="number" step="0.01" min="0" class="form-control @error('estimasi_panen_maksimal') is-invalid @enderror" id="af-panen-max" name="estimasi_panen_maksimal"
value="{{ old('estimasi_panen_maksimal', $kelompokTani->estimasi_panen_maksimal) }}" />
@error('estimasi_panen_maksimal')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="af-satuan-panen">Satuan</label>
<select class="form-control @error('satuan_hasil_panen') is-invalid @enderror" id="af-satuan-panen" name="satuan_hasil_panen">
<option value="">Pilih Satuan</option>
<option value="kg" {{ old('satuan_hasil_panen', $kelompokTani->satuan_hasil_panen) == 'kg' ? 'selected' : '' }}>Kg</option>
<option value="ton" {{ old('satuan_hasil_panen', $kelompokTani->satuan_hasil_panen) == 'ton' ? 'selected' : '' }}>Ton</option>
</select>
@error('satuan_hasil_panen')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<label class="form-label d-block">Hasil Panen Kelompok Biasanya Dilanjutkan untuk Apa?</label>
<div class="row mb-4">
@foreach($tindakanOptions as $option)
<div class="col-md-6 mb-2">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="tindakan_hasil_panen[]" value="{{ $option }}"
id="tindakan-{{ $loop->index }}" {{ in_array($option, $tindakanSelected) ? 'checked' : '' }}>
<label class="form-check-label" for="tindakan-{{ $loop->index }}">{{ $option }}</label>
</div>
</div>
@endforeach
</div>
</div>
<h5 class="pb-4 border-bottom mb-4 mt-4">Peran dan Fungsi Kelompok</h5>
<p class="text-muted" style="font-size: 0.8rem; margin-top: -0.75rem;">
Fungsi yang melekat secara struktural pada kelompok ini, terlepas dari seberapa sering kegiatannya berjalan.
</p>
<div class="row mb-2">
@foreach($fungsiOptions as $option)
<div class="col-md-6 mb-2">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="fungsi_kelompok_bagi_anggota[]" value="{{ $option }}"
id="fungsi-{{ $loop->index }}" {{ in_array($option, $fungsiSelected) ? 'checked' : '' }}>
<label class="form-check-label" for="fungsi-{{ $loop->index }}">{{ $option }}</label>
</div>
</div>
@endforeach
<div class="col-md-6 mb-2">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="fungsi_kelompok_bagi_anggota[]" value="Lainnya" id="fungsi-lainnya-check" {{ $fungsiLainnyaChecked ? 'checked' : '' }}>
<label class="form-check-label" for="fungsi-lainnya-check">Lainnya</label>
</div>
</div>
</div>
<div class="row" id="fungsi-lainnya-wrapper" style="display: none;">
<div class="col-md-6 mb-4 form-control-validation">
<input type="text" class="form-control @error('fungsi_kelompok_lainnya') is-invalid @enderror" name="fungsi_kelompok_lainnya"
id="fungsi-lainnya-text" placeholder="Sebutkan fungsi lainnya"
value="{{ old('fungsi_kelompok_lainnya', $fungsiLainnyaValue) }}" />
@error('fungsi_kelompok_lainnya')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="mt-4 text-end">
<button type="submit" class="btn btn-success wave-effect wave-light">
<i class="ti tabler-device-floppy me-2"></i> Simpan Aktivitas & Fungsi
</button>
</div>
</form>
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
'use strict';
$(document).ready(function () {
function toggleLainnya(checkboxSelector, wrapperSelector, textInputSelector) {
var $checkbox = $(checkboxSelector);
var $wrapper = $(wrapperSelector);
function sync() {
if ($checkbox.is(':checked')) {
$wrapper.show();
} else {
$wrapper.hide();
$(textInputSelector).val('');
}
}
sync();
$checkbox.on('change', sync);
}
toggleLainnya('#kegiatan-lainnya-check', '#kegiatan-lainnya-wrapper', '#kegiatan-lainnya-text');
toggleLainnya('#fungsi-lainnya-check', '#fungsi-lainnya-wrapper', '#fungsi-lainnya-text');
function togglePanen() {
var checked = $('[data-toggle-panen]').is(':checked');
$('#panen-wrapper').toggle(checked);
}
togglePanen();
$('[data-toggle-panen]').on('change', togglePanen);
});
</script>
@endpush
@@ -0,0 +1,373 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
@include('produktivitas.survey-kelompok-tani.header', ['kelompokTani' => $kelompokTani])
@php
$jenisAsetBaku = \App\Http\Controllers\Web\Produktivitas\AsetKelompokTaniController::JENIS_ASET_BAKU;
$asetTersimpan = $kelompokTani->aset->keyBy('jenis_aset');
$asetLainnyaList = $kelompokTani->aset->filter(fn ($a) => !in_array($a->jenis_aset, $jenisAsetBaku));
$statusPengelolaanOptions = ['Swadaya', 'Hibah', 'Pinjaman', 'Sewa'];
$kondisiOptions = ['Berfungsi', 'Perlu perbaikan/evaluasi', 'Rusak/tidak bisa dipakai', 'Mangkrak'];
@endphp
{{-- ASET PRODUKTIF --}}
<div class="card mb-6" id="section-aset-baku">
<div class="card-body pt-6">
@include('produktivitas.survey-kelompok-tani._alert', [
'section' => 'aset-baku',
'errorFields' => ['aset.*'],
])
<h5 class="pb-4 border-bottom mb-4">Aset Produktif Milik Kelompok</h5>
<form method="POST" action="{{ route('kelompok-tani.aset-keuangan.update', $kelompokTani->id) }}">
@csrf
@method('PUT')
<div class="table-responsive mb-4">
<table class="table table-bordered align-middle">
<thead>
<tr>
<th style="min-width: 180px;">Jenis Aset</th>
<th style="width: 140px;">Ada/Tidak</th>
<th style="min-width: 180px;">Status Pengelolaan</th>
<th style="min-width: 200px;">Kondisi</th>
</tr>
</thead>
<tbody>
@foreach($jenisAsetBaku as $index => $jenis)
@php $row = $asetTersimpan->get($jenis); @endphp
<tr>
<td>
<input type="hidden" name="aset[{{ $index }}][jenis_aset]" value="{{ $jenis }}">
{{ $jenis }}
</td>
<td>
<div class="form-check">
<input class="form-check-input aset-status-radio" type="radio" name="aset[{{ $index }}][status_aset]" value="1" id="aset-{{ $index }}-ada" data-row="{{ $index }}" {{ $row?->status_aset ? 'checked' : '' }}>
<label class="form-check-label" for="aset-{{ $index }}-ada">Ada</label>
</div>
<div class="form-check">
<input class="form-check-input aset-status-radio" type="radio" name="aset[{{ $index }}][status_aset]" value="0" id="aset-{{ $index }}-tidak" data-row="{{ $index }}" {{ !$row || !$row->status_aset ? 'checked' : '' }}>
<label class="form-check-label" for="aset-{{ $index }}-tidak">Tidak</label>
</div>
</td>
<td>
<select class="form-select form-select-sm aset-detail-select" name="aset[{{ $index }}][status_pengelolaan_aset]" {{ !$row?->status_aset ? 'disabled' : '' }}>
<option value="">-</option>
@foreach($statusPengelolaanOptions as $option)
<option value="{{ $option }}" {{ $row?->status_pengelolaan_aset == $option ? 'selected' : '' }}>{{ $option }}</option>
@endforeach
</select>
</td>
<td>
<select class="form-select form-select-sm aset-detail-select" name="aset[{{ $index }}][kondisi_aset]" {{ !$row?->status_aset ? 'disabled' : '' }}>
<option value="">-</option>
@foreach($kondisiOptions as $option)
<option value="{{ $option }}" {{ $row?->kondisi_aset == $option ? 'selected' : '' }}>{{ $option }}</option>
@endforeach
</select>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
<div class="text-end">
<button type="submit" class="btn btn-success wave-effect wave-light">
<i class="ti tabler-device-floppy me-2"></i> Simpan Aset Produktif
</button>
</div>
</form>
</div>
</div>
{{-- ASET LAINNYA (di luar 8 jenis baku, bisa lebih dari satu) --}}
<div class="card mb-6" id="section-aset-lainnya">
<div class="card-body pt-6">
@include('produktivitas.survey-kelompok-tani._alert', [
'section' => 'aset-lainnya',
'errorFields' => ['aset_lainnya.*'],
])
<h5 class="pb-4 border-bottom mb-4">Aset Lainnya</h5>
{{-- DATA LAMA --}}
@if($asetLainnyaList->isNotEmpty())
@foreach($asetLainnyaList as $row)
<div class="row align-items-end border-bottom pb-3 mb-3">
<div class="col-md-4">
<label class="form-label">Jenis Aset</label>
<input type="text" class="form-control" value="{{ $row->jenis_aset }}" disabled>
</div>
<div class="col-md-3">
<label class="form-label">Status Pengelolaan</label>
<input type="text" class="form-control" value="{{ $row->status_pengelolaan_aset }}" disabled>
</div>
<div class="col-md-4">
<label class="form-label">Kondisi</label>
<input type="text" class="form-control" value="{{ $row->kondisi_aset }}" disabled>
</div>
<div class="col-md-1">
<form method="POST" action="{{ route('kelompok-tani.aset-keuangan.destroy', [$kelompokTani->id, $row->id]) }}" class="delete-db-form">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-outline-danger">
<i class="icon-base ti tabler-trash icon-sm"></i>
</button>
</form>
</div>
</div>
@endforeach
@else
<p class="text-muted mb-4">Belum ada aset lainnya di luar daftar baku.</p>
@endif
{{-- TOMBOL PEMBUKA — form tambah disembunyikan dulu karena aset lainnya sifatnya opsional --}}
@php $bukaFormAsetLainnya = old('aset_lainnya') || $errors->has('aset_lainnya.*'); @endphp
<button type="button" class="btn btn-outline-success" id="btn-toggle-aset-lainnya" style="display: {{ $bukaFormAsetLainnya ? 'none' : 'inline-block' }};">
<i class="icon-base ti tabler-plus me-1_5 icon-sm"></i> Tambahkan Aset Lainnya
</button>
{{-- FORM TAMBAH DATA BARU — tetap kebuka kalau baru gagal validasi, biar isian & errornya kelihatan --}}
<div id="aset-lainnya-form-wrapper" style="display: {{ $bukaFormAsetLainnya ? 'block' : 'none' }};" class="mt-4">
<form method="POST" action="{{ route('kelompok-tani.aset-keuangan.store', $kelompokTani->id) }}" class="form-repeater-aset-lainnya">
@csrf
<div data-repeater-list="aset_lainnya">
<div data-repeater-item>
<div class="row align-items-end">
<div class="col-md-4 mb-3">
<label class="form-label">Jenis Aset</label>
<input type="text" class="form-control aset-lainnya-input" name="jenis_aset" placeholder="Cth: Mesin pengering">
</div>
<div class="col-md-3 mb-3">
<label class="form-label">Status Pengelolaan</label>
<select class="form-select aset-lainnya-select" name="status_pengelolaan_aset">
<option value="">-</option>
@foreach($statusPengelolaanOptions as $option)
<option value="{{ $option }}">{{ $option }}</option>
@endforeach
</select>
</div>
<div class="col-md-4 mb-3">
<label class="form-label">Kondisi</label>
<select class="form-select aset-lainnya-select" name="kondisi_aset">
<option value="">-</option>
@foreach($kondisiOptions as $option)
<option value="{{ $option }}">{{ $option }}</option>
@endforeach
</select>
</div>
<div class="col-md-1 mb-3">
<button type="button" class="btn btn-outline-danger btn-delete-aset-lainnya" data-repeater-delete disabled>
<i class="icon-base ti tabler-trash icon-sm"></i>
</button>
</div>
</div>
<hr>
</div>
</div>
<div class="mt-4 d-flex justify-content-between">
<button type="button" class="btn btn-outline-success" id="btn-tambah-baris-aset-lainnya" data-repeater-create disabled>
<i class="icon-base ti tabler-plus me-1_5 icon-sm"></i> Tambah Baris
</button>
<button type="submit" class="btn btn-success">
<i class="icon-base ti tabler-check me-1_5 icon-sm"></i> Simpan Aset Lainnya
</button>
</div>
</form>
</div>
</div>
</div>
{{-- KAS / SIMPAN-PINJAM --}}
<div class="card mb-6" id="section-kas">
<div class="card-body pt-6">
@include('produktivitas.survey-kelompok-tani._alert', [
'section' => 'kas',
'errorFields' => ['pembukuan_kas', 'pengelola_kas', 'masalah_pengelolaan_kas_simpan_pinjam', 'deskripsi_masalah_pengelolaan_kas_simpan_pinjam'],
])
<h5 class="pb-4 border-bottom mb-4">Kapasitas Pengelolaan Kas/Simpan-Pinjam Kelompok</h5>
<p class="text-muted" style="font-size: 0.8rem; margin-top: -0.75rem;">
Hanya isi bagian ini jika kelompok memiliki kas/simpan-pinjam (lihat baris "Kas/simpanan kelompok" di tabel aset).
</p>
<form method="POST" action="{{ route('kelompok-tani.update', $kelompokTani->id) }}">
@csrf
@method('PUT')
<input type="hidden" name="section" value="kas">
<div class="row">
<div class="col-md-4 mb-4 form-control-validation">
<label class="form-label" for="ak-pembukuan-kas">Pembukuan/Pencatatan Keuangan Kas</label>
<select class="form-control @error('pembukuan_kas') is-invalid @enderror" id="ak-pembukuan-kas" name="pembukuan_kas">
<option value="">Pilih Status Pembukuan</option>
@foreach([
'Tidak ada pencatatan sama sekali',
'Ada, tapi tidak rutin/tidak rapi',
'Ada, rutin dan rapi',
] as $option)
<option value="{{ $option }}" {{ old('pembukuan_kas', $kelompokTani->pembukuan_kas) == $option ? 'selected' : '' }}>{{ $option }}</option>
@endforeach
</select>
@error('pembukuan_kas')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-4 mb-4 form-control-validation">
<label class="form-label" for="ak-pengelola-kas">Siapa yang Mengelola/Memegang Kas</label>
<input type="text" class="form-control @error('pengelola_kas') is-invalid @enderror" id="ak-pengelola-kas" name="pengelola_kas"
value="{{ old('pengelola_kas', $kelompokTani->pengelola_kas) }}" />
@error('pengelola_kas')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-4 mb-4 form-control-validation">
<label class="form-label" for="ak-masalah-kas">Pernah Ada Masalah Pengelolaan Kas?</label>
<select class="form-control @error('masalah_pengelolaan_kas_simpan_pinjam') is-invalid @enderror" id="ak-masalah-kas" name="masalah_pengelolaan_kas_simpan_pinjam">
<option value="">Pilih Status</option>
@foreach([
'Tidak pernah ada masalah',
'Pernah, sudah selesai',
'Pernah, masih berlanjut/belum selesai',
] as $option)
<option value="{{ $option }}" {{ old('masalah_pengelolaan_kas_simpan_pinjam', $kelompokTani->masalah_pengelolaan_kas_simpan_pinjam) == $option ? 'selected' : '' }}>{{ $option }}</option>
@endforeach
</select>
@error('masalah_pengelolaan_kas_simpan_pinjam')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="row" id="ak-deskripsi-masalah-wrapper" style="display: none;">
<div class="col-md-12 mb-4 form-control-validation">
<label class="form-label" for="ak-deskripsi-masalah">Ceritakan Singkat</label>
<textarea class="form-control @error('deskripsi_masalah_pengelolaan_kas_simpan_pinjam') is-invalid @enderror" id="ak-deskripsi-masalah" name="deskripsi_masalah_pengelolaan_kas_simpan_pinjam" rows="2">{{ old('deskripsi_masalah_pengelolaan_kas_simpan_pinjam', $kelompokTani->deskripsi_masalah_pengelolaan_kas_simpan_pinjam) }}</textarea>
@error('deskripsi_masalah_pengelolaan_kas_simpan_pinjam')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="text-end">
<button type="submit" class="btn btn-success wave-effect wave-light">
<i class="ti tabler-device-floppy me-2"></i> Simpan Kas/Simpan-Pinjam
</button>
</div>
</form>
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
'use strict';
$(document).ready(function () {
function toggleDeskripsiMasalah() {
var val = $('#ak-masalah-kas').val();
$('#ak-deskripsi-masalah-wrapper').toggle(val === 'Pernah, sudah selesai' || val === 'Pernah, masih berlanjut/belum selesai');
}
toggleDeskripsiMasalah();
$('#ak-masalah-kas').on('change', toggleDeskripsiMasalah);
// Status Pengelolaan & Kondisi cuma relevan kalau asetnya "Ada" — disable & kosongkan
// begitu "Tidak" dipilih, biar tidak ada kesan barang yang tidak ada tapi diisi detailnya.
$('.aset-status-radio').on('change', function () {
var $row = $(this).closest('tr');
var ada = $(this).val() === '1';
$row.find('.aset-detail-select').prop('disabled', !ada);
if (!ada) {
$row.find('.aset-detail-select').val('');
}
});
// Tombol pembuka form "Aset Lainnya" (disembunyikan dulu karena opsional)
$('#btn-toggle-aset-lainnya').on('click', function () {
$('#aset-lainnya-form-wrapper').slideDown();
$(this).hide();
});
// Repeater "Aset Lainnya"
var $form = $('.form-repeater-aset-lainnya');
var $btnTambah = $('#btn-tambah-baris-aset-lainnya');
function getRows() {
return $form.find('[data-repeater-item]');
}
function rowAdaIsi($row) {
return String($row.find('input[name="jenis_aset"]').val() || '').trim() !== '';
}
function updateButtons() {
var $rows = getRows();
var $lastRow = $rows.last();
$rows.each(function () {
var $row = $(this);
$row.find('.btn-delete-aset-lainnya').prop('disabled', !rowAdaIsi($row));
});
$btnTambah.prop('disabled', !rowAdaIsi($lastRow));
}
$form.repeater({
initEmpty: false,
show: function () {
var $row = $(this);
$row.find('.aset-lainnya-input').val('');
$row.find('.aset-lainnya-select').val('');
$row.find('.btn-delete-aset-lainnya').prop('disabled', true);
$row.slideDown();
setTimeout(updateButtons, 50);
},
hide: function (deleteElement) {
var $row = $(this);
if (!rowAdaIsi($row)) {
return;
}
Swal.fire({
title: 'Hapus baris ini?',
text: 'Baris ini hanya akan dihapus dari form.',
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Ya, hapus',
cancelButtonText: 'Batal',
customClass: { confirmButton: 'btn btn-danger me-3', cancelButton: 'btn btn-label-secondary' },
buttonsStyling: false
}).then(function (result) {
if (result.isConfirmed) {
$row.slideUp(deleteElement);
setTimeout(updateButtons, 300);
}
});
}
});
$(document).on('input keyup change', '.form-repeater-aset-lainnya input[name="jenis_aset"]', updateButtons);
updateButtons();
$(document).on('submit', '.delete-db-form', function (e) {
e.preventDefault();
var form = this;
Swal.fire({
title: 'Hapus aset ini?',
text: 'Data yang sudah dihapus tidak bisa dikembalikan.',
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Ya, hapus',
cancelButtonText: 'Batal',
customClass: { confirmButton: 'btn btn-danger me-3', cancelButton: 'btn btn-label-secondary' },
buttonsStyling: false
}).then(function (result) {
if (result.isConfirmed) {
form.submit();
}
});
});
});
</script>
@endpush
@@ -0,0 +1,295 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
@include('produktivitas.survey-kelompok-tani.header', ['kelompokTani' => $kelompokTani])
{{-- STATUS AKSES BANTUAN --}}
<div class="card mb-6" id="section-status-bantuan">
<div class="card-body pt-6">
@include('produktivitas.survey-kelompok-tani._alert', [
'section' => 'status-bantuan',
'errorFields' => ['pernah_mendapatkan_bantuan'],
])
<h5 class="pb-4 border-bottom mb-4">Pengalaman Akses Bantuan/Program</h5>
<form method="POST" action="{{ route('kelompok-tani.update', $kelompokTani->id) }}">
@csrf
@method('PUT')
<input type="hidden" name="section" value="status-bantuan">
<div class="row">
<div class="col-md-6 mb-4 form-control-validation">
<label class="form-label d-block">Apakah kelompok ini pernah mendapatkan bantuan atau akses program dari pemerintah/lembaga lain?</label>
@php $pernahBantuan = old('pernah_mendapatkan_bantuan', $kelompokTani->pernah_mendapatkan_bantuan); @endphp
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="pernah_mendapatkan_bantuan" value="1" id="sb-pernah" {{ $pernahBantuan ? 'checked' : '' }}>
<label class="form-check-label" for="sb-pernah">Pernah</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="pernah_mendapatkan_bantuan" value="0" id="sb-belum" {{ !is_null($pernahBantuan) && !$pernahBantuan ? 'checked' : '' }}>
<label class="form-check-label" for="sb-belum">Belum Pernah</label>
</div>
@error('pernah_mendapatkan_bantuan')<div class="error invalid-feedback d-block">{{ $message }}</div>@enderror
</div>
</div>
<div class="text-end">
<button type="submit" class="btn btn-success wave-effect wave-light">
<i class="ti tabler-device-floppy me-2"></i> Simpan Status
</button>
</div>
</form>
</div>
</div>
{{-- DAFTAR PROGRAM / BANTUAN --}}
<div class="card mb-6" id="section-bantuan">
<div class="card-body pt-6">
@include('produktivitas.survey-kelompok-tani._alert', [
'section' => 'bantuan',
'errorFields' => ['bantuan.*'],
])
<h5 class="pb-4 border-bottom mb-4">Daftar Program/Bantuan yang Pernah Diterima</h5>
<p class="text-muted mb-0" id="bantuan-list-placeholder" style="display: none;">
Set status di atas jadi <strong>"Pernah"</strong> dulu untuk mengisi daftar program/bantuan.
</p>
<div id="bantuan-list-content">
{{-- DATA LAMA --}}
@if($kelompokTani->bantuan->count() > 0)
@foreach($kelompokTani->bantuan as $row)
<div class="row align-items-end border-bottom pb-3 mb-3">
<div class="col-md-3">
<label class="form-label">Nama Program/Bantuan</label>
<input type="text" class="form-control" value="{{ $row->nama_program }}" disabled>
</div>
<div class="col-md-3">
<label class="form-label">Penyelenggara</label>
<input type="text" class="form-control" value="{{ $row->penyelenggara }}" disabled>
</div>
<div class="col-md-3">
<label class="form-label">Bentuk Bantuan</label>
<input type="text" class="form-control" value="{{ $row->bentuk_bantuan }}" disabled>
</div>
<div class="col-md-2">
<label class="form-label">Tahun</label>
<input type="text" class="form-control" value="{{ $row->tahun }}" disabled>
</div>
<div class="col-md-1">
<form method="POST" action="{{ route('kelompok-tani.bantuan-penilaian.destroy', [$kelompokTani->id, $row->id]) }}" class="delete-db-form">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-outline-danger">
<i class="icon-base ti tabler-trash icon-sm"></i>
</button>
</form>
</div>
</div>
@endforeach
@else
<p class="text-muted mb-4">Belum ada data program/bantuan.</p>
@endif
{{-- FORM TAMBAH DATA BARU --}}
<form method="POST" action="{{ route('kelompok-tani.bantuan-penilaian.store', $kelompokTani->id) }}" class="form-repeater-bantuan">
@csrf
<div data-repeater-list="bantuan">
<div data-repeater-item>
<div class="row align-items-end">
<div class="col-md-3 mb-3">
<label class="form-label">Nama Program/Bantuan</label>
<input type="text" class="form-control bantuan-input" name="nama_program" placeholder="Cth: Bantuan Bibit Kakao">
</div>
<div class="col-md-3 mb-3">
<label class="form-label">Penyelenggara</label>
<input type="text" class="form-control bantuan-input" name="penyelenggara" placeholder="Cth: Dinas Pertanian">
</div>
<div class="col-md-3 mb-3">
<label class="form-label">Bentuk Bantuan</label>
<input type="text" class="form-control bantuan-input" name="bentuk_bantuan" placeholder="Cth: Bibit, pupuk, pelatihan">
</div>
<div class="col-md-2 mb-3">
<label class="form-label">Tahun</label>
<input type="number" class="form-control" name="tahun" placeholder="Cth: 2023" min="1900" max="{{ date('Y') }}">
</div>
<div class="col-md-1 mb-3">
<button type="button" class="btn btn-outline-danger btn-delete-bantuan" data-repeater-delete disabled>
<i class="icon-base ti tabler-trash icon-sm"></i>
</button>
</div>
</div>
<hr>
</div>
</div>
<div class="mt-4 d-flex justify-content-between">
<button type="button" class="btn btn-outline-success" id="btn-tambah-bantuan" data-repeater-create disabled>
<i class="icon-base ti tabler-plus me-1_5 icon-sm"></i> Tambah Baris
</button>
<button type="submit" class="btn btn-success">
<i class="icon-base ti tabler-check me-1_5 icon-sm"></i> Simpan Daftar Bantuan
</button>
</div>
</form>
</div>
</div>
</div>
{{-- POTENSI MITRA AGREGASI --}}
<div class="card mb-6" id="section-penilaian">
<div class="card-body pt-6">
@include('produktivitas.survey-kelompok-tani._alert', [
'section' => 'penilaian',
'errorFields' => ['potensi_kelompok', 'alasan_penilaian_potensi'],
])
<h5 class="pb-4 border-bottom mb-4">Potensi sebagai Mitra Agregasi/Pengolahan Kolektif</h5>
<p class="text-muted" style="font-size: 0.8rem; margin-top: -0.75rem;">
Ini penilaian enumerator, bukan pernyataan langsung dari responden — dasarkan pada kombinasi kegiatan, fungsi, dan aset yang sudah tergali di tab-tab sebelumnya.
</p>
<form method="POST" action="{{ route('kelompok-tani.update', $kelompokTani->id) }}">
@csrf
@method('PUT')
<input type="hidden" name="section" value="penilaian">
<div class="row">
<div class="col-md-4 mb-4 form-control-validation">
<label class="form-label" for="pn-potensi-kelompok">Tingkat Potensi</label>
<select class="form-control @error('potensi_kelompok') is-invalid @enderror" id="pn-potensi-kelompok" name="potensi_kelompok">
<option value="">Pilih Tingkat Potensi</option>
<option value="Rendah" {{ old('potensi_kelompok', $kelompokTani->potensi_kelompok) == 'Rendah' ? 'selected' : '' }}>Rendah — belum ada kapasitas/aktivitas yang mendukung</option>
<option value="Sedang" {{ old('potensi_kelompok', $kelompokTani->potensi_kelompok) == 'Sedang' ? 'selected' : '' }}>Sedang — ada sebagian kapasitas, perlu penguatan lebih jauh</option>
<option value="Tinggi" {{ old('potensi_kelompok', $kelompokTani->potensi_kelompok) == 'Tinggi' ? 'selected' : '' }}>Tinggi — kapasitas dan aktivitas sudah mendukung peran ini</option>
</select>
@error('potensi_kelompok')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-8 mb-4 form-control-validation">
<label class="form-label" for="pn-alasan-penilaian">Alasan Penilaian</label>
<textarea class="form-control @error('alasan_penilaian_potensi') is-invalid @enderror" id="pn-alasan-penilaian" name="alasan_penilaian_potensi" rows="2">{{ old('alasan_penilaian_potensi', $kelompokTani->alasan_penilaian_potensi) }}</textarea>
@error('alasan_penilaian_potensi')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="text-end">
<button type="submit" class="btn btn-success wave-effect wave-light">
<i class="ti tabler-device-floppy me-2"></i> Simpan Penilaian
</button>
</div>
</form>
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
'use strict';
$(function () {
$('#pn-potensi-kelompok').select2();
// Daftar bantuan cuma relevan kalau status-nya "Pernah" — biar nggak kontradiktif
// (jawab "Belum Pernah" tapi daftar bantuannya keisi).
function toggleDaftarBantuan() {
var pernah = $('#sb-pernah').is(':checked');
$('#bantuan-list-content').toggle(pernah);
$('#bantuan-list-placeholder').toggle(!pernah);
}
toggleDaftarBantuan();
$('#sb-pernah, #sb-belum').on('change', toggleDaftarBantuan);
var $form = $('.form-repeater-bantuan');
var $btnTambah = $('#btn-tambah-bantuan');
function getRows() {
return $form.find('[data-repeater-item]');
}
function rowAdaIsi($row) {
return $row.find('.bantuan-input').toArray().some(function (input) {
return String($(input).val() || '').trim() !== '';
});
}
function rowLengkap($row) {
var $inputs = $row.find('.bantuan-input');
return $inputs.toArray().every(function (input) {
return String($(input).val() || '').trim() !== '';
});
}
function updateButtons() {
var $rows = getRows();
var $lastRow = $rows.last();
$rows.each(function () {
var $row = $(this);
$row.find('.btn-delete-bantuan').prop('disabled', !rowAdaIsi($row));
});
$btnTambah.prop('disabled', !rowLengkap($lastRow));
}
$form.repeater({
initEmpty: false,
show: function () {
var $row = $(this);
$row.find('.bantuan-input, input[name="tahun"]').val('');
$row.find('.btn-delete-bantuan').prop('disabled', true);
$row.slideDown();
setTimeout(updateButtons, 50);
},
hide: function (deleteElement) {
var $row = $(this);
if (!rowAdaIsi($row)) {
return;
}
Swal.fire({
title: 'Hapus baris ini?',
text: 'Baris ini hanya akan dihapus dari form.',
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Ya, hapus',
cancelButtonText: 'Batal',
customClass: { confirmButton: 'btn btn-danger me-3', cancelButton: 'btn btn-label-secondary' },
buttonsStyling: false
}).then(function (result) {
if (result.isConfirmed) {
$row.slideUp(deleteElement);
setTimeout(updateButtons, 300);
}
});
}
});
$(document).on('input keyup change', '.form-repeater-bantuan .bantuan-input', updateButtons);
updateButtons();
$(document).on('submit', '.delete-db-form', function (e) {
e.preventDefault();
var form = this;
Swal.fire({
title: 'Hapus data ini?',
text: 'Data yang sudah dihapus tidak bisa dikembalikan.',
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Ya, hapus',
cancelButtonText: 'Batal',
customClass: { confirmButton: 'btn btn-danger me-3', cancelButton: 'btn btn-label-secondary' },
buttonsStyling: false
}).then(function (result) {
if (result.isConfirmed) {
form.submit();
}
});
});
});
</script>
@endpush
@@ -0,0 +1,298 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
@include('produktivitas.survey-kelompok-tani.header', ['kelompokTani' => $kelompokTani])
<div class="row">
<div class="col-md-12">
<div class="card mb-6" id="section-identitas">
<div class="card-body pt-6">
@include('produktivitas.survey-kelompok-tani._alert', [
'section' => 'identitas',
'errorFields' => ['nama_responden', 'jabatan_responden', 'kontak_responden', 'nama_kelompok', 'desa_kelurahan_id', 'dusun', 'tahun_berdiri', 'jenis_kelompok', 'jenis_kelompok_lainnya', 'nama_gapoktan', 'komoditas_id.*'],
])
<form id="editKelompokTaniForm" action="{{ route('kelompok-tani.update', $kelompokTani->id) }}" method="POST">
@csrf
@method('PUT')
<h5 class="pb-4 border-bottom mb-4">Data Responden</h5>
<div class="row">
<div class="col-md-4 mb-4 form-control-validation">
<label class="form-label" for="edit-kt-nama-responden">Nama Responden<span class="text-danger">*</span></label>
<input type="text" class="form-control @error('nama_responden') is-invalid @enderror" id="edit-kt-nama-responden" name="nama_responden"
placeholder="Cth: John Doe" value="{{ old('nama_responden', $kelompokTani->nama_responden) }}" />
@error('nama_responden')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-4 mb-4 form-control-validation">
<label class="form-label" for="edit-kt-jabatan-responden">Jabatan Responden</label>
<input type="text" class="form-control @error('jabatan_responden') is-invalid @enderror" id="edit-kt-jabatan-responden" name="jabatan_responden"
placeholder="Cth: Ketua Kelompok" value="{{ old('jabatan_responden', $kelompokTani->jabatan_responden) }}" />
@error('jabatan_responden')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-4 mb-4 form-control-validation">
<label class="form-label" for="edit-kt-kontak-responden">Kontak Responden (No. HP)</label>
<input type="text" class="form-control @error('kontak_responden') is-invalid @enderror" id="edit-kt-kontak-responden" name="kontak_responden"
placeholder="Cth: 081234567890" value="{{ old('kontak_responden', $kelompokTani->kontak_responden) }}" />
@error('kontak_responden')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<h5 class="pb-4 border-bottom mb-4 mt-4">Identitas Kelompok Tani</h5>
<div class="row">
<div class="col-md-6 mb-4 form-control-validation">
<label class="form-label" for="edit-kt-nama-kelompok">Nama Kelompok Tani<span class="text-danger">*</span></label>
<input type="text" class="form-control @error('nama_kelompok') is-invalid @enderror" id="edit-kt-nama-kelompok" name="nama_kelompok"
placeholder="Cth: Kelompok Tani Maju Bersama" value="{{ old('nama_kelompok', $kelompokTani->nama_kelompok) }}" />
@error('nama_kelompok')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="edit-kt-dusun">Dusun</label>
<input type="text" class="form-control @error('dusun') is-invalid @enderror" id="edit-kt-dusun" name="dusun"
placeholder="Cth: Dusun I" value="{{ old('dusun', $kelompokTani->dusun) }}" />
@error('dusun')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="edit-kt-tahun-berdiri">Tahun Berdiri</label>
<input type="number" class="form-control @error('tahun_berdiri') is-invalid @enderror" id="edit-kt-tahun-berdiri" name="tahun_berdiri"
placeholder="Cth: 2015" min="1900" max="{{ date('Y') }}" value="{{ old('tahun_berdiri', $kelompokTani->tahun_berdiri) }}" />
@error('tahun_berdiri')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="row">
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="edit-kt-provinsi">Provinsi<span class="text-danger">*</span></label>
<select class="form-control @error('provinsi_id') is-invalid @enderror" id="edit-kt-provinsi" name="provinsi_id">
<option value="">Pilih Provinsi</option>
@foreach($provinsi as $p)
<option value="{{ $p->id }}" {{ old('provinsi_id', $kelompokTani->desaKelurahan?->kecamatan?->kabupatenKota?->provinsi_id) == $p->id ? 'selected' : '' }}>{{ $p->nama }}</option>
@endforeach
</select>
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="edit-kt-kabupaten">Kabupaten/Kota<span class="text-danger">*</span></label>
<select class="form-control @error('kabupaten_id') is-invalid @enderror" id="edit-kt-kabupaten" name="kabupaten_id">
<option value="">Pilih Kabupaten/Kota</option>
@if($kelompokTani->desaKelurahan?->kecamatan?->kabupatenKota)
<option value="{{ $kelompokTani->desaKelurahan->kecamatan->kabupatenKota->id }}" selected>{{ $kelompokTani->desaKelurahan->kecamatan->kabupatenKota->nama }}</option>
@endif
</select>
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="edit-kt-kecamatan">Kecamatan<span class="text-danger">*</span></label>
<select class="form-control @error('kecamatan_id') is-invalid @enderror" id="edit-kt-kecamatan" name="kecamatan_id">
<option value="">Pilih Kecamatan</option>
@if($kelompokTani->desaKelurahan?->kecamatan)
<option value="{{ $kelompokTani->desaKelurahan->kecamatan->id }}" selected>{{ $kelompokTani->desaKelurahan->kecamatan->nama }}</option>
@endif
</select>
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="edit-kt-desa">Desa/Kelurahan<span class="text-danger">*</span></label>
<select class="form-control @error('desa_kelurahan_id') is-invalid @enderror" id="edit-kt-desa" name="desa_kelurahan_id">
<option value="">Pilih Desa/Kelurahan</option>
@if($kelompokTani->desaKelurahan)
<option value="{{ $kelompokTani->desaKelurahan->id }}" selected>{{ $kelompokTani->desaKelurahan->nama }}</option>
@endif
</select>
@error('desa_kelurahan_id')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="row">
<div class="col-md-4 mb-4 form-control-validation">
<label class="form-label" for="edit-kt-jenis-kelompok">Terdaftar/Dikenal Sebagai<span class="text-danger">*</span></label>
@php
$jenisKelompokOptions = [
'Kelompok Tani (Poktan)',
'Kelompok Wanita Tani (KWT)',
'Gabungan Kelompok Tani (Gapoktan)',
'Kelompok Pemuda Tani',
'Asosiasi Petani',
];
$currentJenisKelompok = old('jenis_kelompok', $kelompokTani->jenis_kelompok);
$isJenisKelompokLainnya = $currentJenisKelompok && !in_array($currentJenisKelompok, $jenisKelompokOptions);
@endphp
<select class="form-control @error('jenis_kelompok') is-invalid @enderror" id="edit-kt-jenis-kelompok" name="jenis_kelompok">
<option value="">Pilih Jenis Kelompok</option>
@foreach($jenisKelompokOptions as $option)
<option value="{{ $option }}" {{ $currentJenisKelompok == $option ? 'selected' : '' }}>{{ $option }}</option>
@endforeach
<option value="Lainnya" {{ old('jenis_kelompok') == 'Lainnya' || $isJenisKelompokLainnya ? 'selected' : '' }}>Lainnya</option>
</select>
@error('jenis_kelompok')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-4 mb-4 form-control-validation" id="edit-kt-jenis-kelompok-lainnya-wrapper" style="display: none;">
<label class="form-label" for="edit-kt-jenis-kelompok-lainnya">Sebutkan Jenis Kelompok</label>
<input type="text" class="form-control @error('jenis_kelompok_lainnya') is-invalid @enderror" id="edit-kt-jenis-kelompok-lainnya" name="jenis_kelompok_lainnya"
value="{{ old('jenis_kelompok_lainnya', $isJenisKelompokLainnya ? $currentJenisKelompok : null) }}" />
@error('jenis_kelompok_lainnya')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-4 mb-4 form-control-validation" id="edit-kt-nama-gapoktan-wrapper" style="display: none;">
<label class="form-label" for="edit-kt-nama-gapoktan">Nama Gapoktan</label>
<input type="text" class="form-control @error('nama_gapoktan') is-invalid @enderror" id="edit-kt-nama-gapoktan" name="nama_gapoktan"
placeholder="Cth: Gapoktan Sumber Makmur" value="{{ old('nama_gapoktan', $kelompokTani->nama_gapoktan) }}" />
@error('nama_gapoktan')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="row">
<div class="col-md-6 mb-4 form-control-validation">
<label class="form-label">Komoditas Utama</label>
<select id="edit-kt-komoditas" name="komoditas_id[]" class="form-select @error('komoditas_id') is-invalid @enderror" multiple>
@foreach($komoditas as $k)
<option value="{{ $k->id }}" {{ collect(old('komoditas_id', $kelompokTani->komoditas_id))->contains($k->id) ? 'selected' : '' }}>{{ $k->nama }}</option>
@endforeach
</select>
@error('komoditas_id')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="mt-4 text-end">
<a href="{{ route('kelompok-tani.index') }}" class="btn btn-secondary me-2 wave-effect wave-light">Kembali</a>
<button type="submit" class="btn btn-success data-submit wave-effect wave-light"><i class="ti tabler-device-floppy me-2"></i> Simpan</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
'use strict';
$(document).ready(function () {
$('#edit-kt-jenis-kelompok, #edit-kt-komoditas').select2();
function toggleJenisKelompokFields() {
var jenisKelompok = $('#edit-kt-jenis-kelompok').val();
if (jenisKelompok === 'Lainnya') {
$('#edit-kt-jenis-kelompok-lainnya-wrapper').show();
} else {
$('#edit-kt-jenis-kelompok-lainnya-wrapper').hide();
$('#edit-kt-jenis-kelompok-lainnya').val('');
}
if (jenisKelompok === 'Gabungan Kelompok Tani (Gapoktan)') {
$('#edit-kt-nama-gapoktan-wrapper').show();
} else {
$('#edit-kt-nama-gapoktan-wrapper').hide();
$('#edit-kt-nama-gapoktan').val('');
}
}
toggleJenisKelompokFields();
$('#edit-kt-jenis-kelompok').on('change', toggleJenisKelompokFields);
$('#edit-kt-provinsi').select2().on('change', function (e) {
e.preventDefault();
var provinsiId = $(this).val();
$('#edit-kt-kabupaten').empty().append('<option value="">Pilih Kabupaten/Kota</option>').trigger('change');
$('#edit-kt-kecamatan').empty().append('<option value="">Pilih Kecamatan</option>').trigger('change');
$('#edit-kt-desa').empty().append('<option value="">Pilih Desa/Kelurahan</option>').trigger('change');
if (provinsiId) {
$.ajax({
url: '{{ route("kabupatenkota.byprovinsi", ":id") }}'.replace(':id', provinsiId),
method: 'GET',
success: function (data) {
data.forEach(function (kabupaten) {
$('#edit-kt-kabupaten').append('<option value="' + kabupaten.id + '">' + kabupaten.nama + '</option>');
});
}
});
}
});
$('#edit-kt-kabupaten').select2().on('change', function (e) {
e.preventDefault();
var kabupatenId = $(this).val();
$('#edit-kt-kecamatan').empty().append('<option value="">Pilih Kecamatan</option>').trigger('change');
$('#edit-kt-desa').empty().append('<option value="">Pilih Desa/Kelurahan</option>').trigger('change');
if (kabupatenId) {
$.ajax({
url: '{{ route("kecamatan.bykabupatenkota", ":id") }}'.replace(':id', kabupatenId),
method: 'GET',
success: function (data) {
data.forEach(function (kecamatan) {
$('#edit-kt-kecamatan').append('<option value="' + kecamatan.id + '">' + kecamatan.nama + '</option>');
});
}
});
}
});
$('#edit-kt-kecamatan').select2().on('change', function (e) {
e.preventDefault();
var kecamatanId = $(this).val();
$('#edit-kt-desa').empty().append('<option value="">Pilih Desa/Kelurahan</option>').trigger('change');
if (kecamatanId) {
$.ajax({
url: '{{ route("desakelurahan.bykecamatan", ":id") }}'.replace(':id', kecamatanId),
method: 'GET',
success: function (data) {
data.forEach(function (desa) {
$('#edit-kt-desa').append('<option value="' + desa.id + '">' + desa.nama + '</option>');
});
}
});
}
});
$('#edit-kt-desa').select2();
$('#editKelompokTaniForm').validate({
rules: {
nama_responden: { required: true },
nama_kelompok: { required: true },
provinsi_id: { required: true },
kabupaten_id: { required: true },
kecamatan_id: { required: true },
desa_kelurahan_id: { required: true },
jenis_kelompok: { required: true },
jenis_kelompok_lainnya: {
required: function () {
return $('#edit-kt-jenis-kelompok').val() === 'Lainnya';
}
},
tahun_berdiri: { min: 1900, max: new Date().getFullYear() }
},
messages: {
nama_responden: { required: 'Nama responden wajib diisi' },
nama_kelompok: { required: 'Nama kelompok wajib diisi' },
provinsi_id: { required: 'Provinsi wajib diisi' },
kabupaten_id: { required: 'Kabupaten/Kota wajib diisi' },
kecamatan_id: { required: 'Kecamatan wajib diisi' },
desa_kelurahan_id: { required: 'Desa/Kelurahan wajib diisi' },
jenis_kelompok: { required: 'Jenis kelompok wajib dipilih' },
jenis_kelompok_lainnya: { required: 'Sebutkan jenis kelompoknya' }
},
errorElement: 'div',
errorPlacement: function (error, element) {
error.addClass('invalid-feedback');
if (element.hasClass('select2-hidden-accessible')) {
element.closest('.form-control-validation').append(error);
} else {
element.closest('.mb-4, .form-control-validation').append(error);
}
},
highlight: function (element) {
$(element).addClass('is-invalid');
},
unhighlight: function (element) {
$(element).removeClass('is-invalid');
},
submitHandler: function (form) {
form.submit();
}
});
});
</script>
@endpush
@@ -0,0 +1,216 @@
<style>
@media (min-width: 768px) {
.nav-pills-custom-spacing {
display: flex;
width: 100%;
gap: 0.5rem;
flex-wrap: nowrap !important;
overflow-x: auto;
}
.nav-pills-custom-spacing::-webkit-scrollbar {
display: none;
}
.nav-pills-custom-spacing .nav-item {
margin-right: 0 !important;
flex: 1;
}
.nav-pills-custom-spacing .nav-link {
display: flex;
justify-content: center;
align-items: center;
padding-left: 0.5rem !important;
padding-right: 0.5rem !important;
width: 100%;
white-space: nowrap;
font-size: 0.9375rem !important;
}
.nav-pills-custom-spacing .nav-link i {
margin-right: 0.4rem !important;
}
}
</style>
@php
$namaKomoditas = isset($kelompokTani) && $kelompokTani->komoditas_id
? \App\Models\Pertanian\Komoditas::whereIn('id', $kelompokTani->komoditas_id)->pluck('nama')
: collect();
$lokasiKelompok = isset($kelompokTani)
? collect([$kelompokTani->dusun, $kelompokTani->desaKelurahan?->nama, $kelompokTani->desaKelurahan?->kecamatan?->nama])
->filter()
->implode(', ')
: null;
@endphp
<div class="card mb-6">
<div class="card-body p-3">
<div class="d-flex justify-content-start align-items-center flex-wrap row-gap-2">
<div class="avatar avatar-lg me-3">
<span class="avatar-initial rounded bg-label-primary">
<i class="icon-base ti tabler-users-group icon-28px"></i>
</span>
</div>
<div class="d-flex flex-column">
<h5 class="mb-0">{{ isset($kelompokTani) ? $kelompokTani->nama_kelompok : 'Tambah Kelompok Tani Baru' }}</h5>
<span class="text-muted" style="font-size: 0.8rem;">
{{ $lokasiKelompok ?: 'Lengkapi identitas & data responden untuk memulai' }}
</span>
@if(isset($kelompokTani) && ($kelompokTani->jenis_kelompok || $namaKomoditas->isNotEmpty() || $kelompokTani->nama_gapoktan))
<div class="d-flex flex-wrap gap-1 mt-2">
@if($kelompokTani->jenis_kelompok)
<span class="badge bg-label-secondary">{{ $kelompokTani->jenis_kelompok }}</span>
@endif
@if($kelompokTani->nama_gapoktan)
<span class="badge bg-label-info">Gapoktan: {{ $kelompokTani->nama_gapoktan }}</span>
@endif
@foreach($namaKomoditas as $nama)
<span class="badge bg-label-success">{{ $nama }}</span>
@endforeach
</div>
@endif
</div>
</div>
@if(isset($kelompokTani))
<hr class="my-3">
<div class="row gy-3">
<div class="col-sm-6 col-lg-3 d-flex align-items-center">
<span class="avatar avatar-sm me-2">
<span class="avatar-initial rounded-circle bg-label-primary">
<i class="icon-base ti tabler-user icon-16px"></i>
</span>
</span>
<div>
<p class="mb-0 text-muted" style="font-size: 0.75rem;">Nama Responden</p>
<span class="fw-medium" style="font-size: 0.85rem;">{{ $kelompokTani->nama_responden ?: '-' }}</span>
</div>
</div>
<div class="col-sm-6 col-lg-3 d-flex align-items-center">
<span class="avatar avatar-sm me-2">
<span class="avatar-initial rounded-circle bg-label-primary">
<i class="icon-base ti tabler-briefcase icon-16px"></i>
</span>
</span>
<div>
<p class="mb-0 text-muted" style="font-size: 0.75rem;">Jabatan Responden</p>
<span class="fw-medium" style="font-size: 0.85rem;">{{ $kelompokTani->jabatan_responden ?: '-' }}</span>
</div>
</div>
<div class="col-sm-6 col-lg-3 d-flex align-items-center">
<span class="avatar avatar-sm me-2">
<span class="avatar-initial rounded-circle bg-label-primary">
<i class="icon-base ti tabler-phone icon-16px"></i>
</span>
</span>
<div>
<p class="mb-0 text-muted" style="font-size: 0.75rem;">Kontak Responden</p>
<span class="fw-medium" style="font-size: 0.85rem;">{{ $kelompokTani->kontak_responden ?: '-' }}</span>
</div>
</div>
<div class="col-sm-6 col-lg-3 d-flex align-items-center">
<span class="avatar avatar-sm me-2">
<span class="avatar-initial rounded-circle bg-label-primary">
<i class="icon-base ti tabler-calendar-event icon-16px"></i>
</span>
</span>
<div>
<p class="mb-0 text-muted" style="font-size: 0.75rem;">Tahun Berdiri</p>
<span class="fw-medium" style="font-size: 0.85rem;">{{ $kelompokTani->tahun_berdiri ?: '-' }}</span>
</div>
</div>
</div>
@endif
</div>
</div>
<div class="nav-align-top">
<ul class="nav nav-pills flex-column flex-md-row mb-6 row-gap-2 nav-pills-custom-spacing">
<li class="nav-item">
<a class="nav-link {{ request()->routeIs('kelompok-tani.create') || (request()->routeIs('kelompok-tani.edit') && !request()->query('section')) ? 'active' : '' }}"
href="{{ isset($kelompokTani) ? route('kelompok-tani.edit', $kelompokTani->id) : route('kelompok-tani.create') }}">
<i class="icon-base ti tabler-id-badge-2 me-1_5 icon-sm"></i>Identitas & Responden
</a>
</li>
<li class="nav-item">
@if(isset($kelompokTani))
<a class="nav-link {{ request()->routeIs('kelompok-tani.pengurus-anggota.*') ? 'active' : '' }}"
href="{{ route('kelompok-tani.pengurus-anggota.index', $kelompokTani->id) }}">
<i class="icon-base ti tabler-users-group me-1_5 icon-sm"></i>Pengurus & Anggota
</a>
@else
<a class="nav-link" href="#" data-bs-toggle="tooltip" data-bs-placement="top"
data-bs-original-title="Simpan Identitas & Responden terlebih dahulu">
<i class="icon-base ti tabler-users-group me-1_5 icon-sm"></i>Pengurus & Anggota
</a>
@endif
</li>
<li class="nav-item">
@if(isset($kelompokTani))
<a class="nav-link {{ request()->routeIs('kelompok-tani.edit') && request()->query('section') === 'kelembagaan' ? 'active' : '' }}"
href="{{ route('kelompok-tani.edit', $kelompokTani->id) }}?section=kelembagaan">
<i class="icon-base ti tabler-building-community me-1_5 icon-sm"></i>Kelembagaan
</a>
@else
<a class="nav-link" href="#" data-bs-toggle="tooltip" data-bs-placement="top"
data-bs-original-title="Simpan Identitas & Responden terlebih dahulu">
<i class="icon-base ti tabler-building-community me-1_5 icon-sm"></i>Kelembagaan
</a>
@endif
</li>
<li class="nav-item">
@if(isset($kelompokTani))
<a class="nav-link {{ request()->routeIs('kelompok-tani.edit') && request()->query('section') === 'aktivitas-fungsi' ? 'active' : '' }}"
href="{{ route('kelompok-tani.edit', $kelompokTani->id) }}?section=aktivitas-fungsi">
<i class="icon-base ti tabler-clipboard-list me-1_5 icon-sm"></i>Aktivitas & Fungsi
</a>
@else
<a class="nav-link" href="#" data-bs-toggle="tooltip" data-bs-placement="top"
data-bs-original-title="Simpan Identitas & Responden terlebih dahulu">
<i class="icon-base ti tabler-clipboard-list me-1_5 icon-sm"></i>Aktivitas & Fungsi
</a>
@endif
</li>
<li class="nav-item">
@if(isset($kelompokTani))
<a class="nav-link {{ request()->routeIs('kelompok-tani.aset-keuangan.*') ? 'active' : '' }}"
href="{{ route('kelompok-tani.aset-keuangan.index', $kelompokTani->id) }}">
<i class="icon-base ti tabler-wallet me-1_5 icon-sm"></i>Aset & Keuangan
</a>
@else
<a class="nav-link" href="#" data-bs-toggle="tooltip" data-bs-placement="top"
data-bs-original-title="Simpan Identitas & Responden terlebih dahulu">
<i class="icon-base ti tabler-wallet me-1_5 icon-sm"></i>Aset & Keuangan
</a>
@endif
</li>
<li class="nav-item">
@if(isset($kelompokTani))
<a class="nav-link {{ request()->routeIs('kelompok-tani.edit') && request()->query('section') === 'sosial-konflik' ? 'active' : '' }}"
href="{{ route('kelompok-tani.edit', $kelompokTani->id) }}?section=sosial-konflik">
<i class="icon-base ti tabler-heart-handshake me-1_5 icon-sm"></i>Sosial & Konflik
</a>
@else
<a class="nav-link" href="#" data-bs-toggle="tooltip" data-bs-placement="top"
data-bs-original-title="Simpan Identitas & Responden terlebih dahulu">
<i class="icon-base ti tabler-heart-handshake me-1_5 icon-sm"></i>Sosial & Konflik
</a>
@endif
</li>
<li class="nav-item">
@if(isset($kelompokTani))
<a class="nav-link {{ request()->routeIs('kelompok-tani.bantuan-penilaian.*') ? 'active' : '' }}"
href="{{ route('kelompok-tani.bantuan-penilaian.index', $kelompokTani->id) }}">
<i class="icon-base ti tabler-report me-1_5 icon-sm"></i>Bantuan & Penilaian
</a>
@else
<a class="nav-link" href="#" data-bs-toggle="tooltip" data-bs-placement="top"
data-bs-original-title="Simpan Identitas & Responden terlebih dahulu">
<i class="icon-base ti tabler-report me-1_5 icon-sm"></i>Bantuan & Penilaian
</a>
@endif
</li>
</ul>
</div>
@@ -0,0 +1,111 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
<div class="card">
<div class="card-header border-bottom">
<h5 class="card-title mb-0">Data Kelompok Tani</h5>
</div>
<div class="card-body border-bottom pt-4">
<form method="GET" action="{{ route('kelompok-tani.index') }}" class="d-flex justify-content-between align-items-center row gap-3 gap-md-0">
<div class="col-md-auto">
<div class="d-flex align-items-center">
<label class="me-2 text-nowrap">Show</label>
<select name="per_page" class="form-select form-select-sm w-auto" onchange="this.form.submit()">
<option value="10" {{ request('per_page') == 10 ? 'selected' : '' }}>10</option>
<option value="25" {{ request('per_page') == 25 ? 'selected' : '' }}>25</option>
</select>
<label class="ms-2 text-nowrap">entries</label>
</div>
</div>
<div class="col-md-auto d-flex gap-2">
<div class="input-group input-group-sm w-auto">
<input type="text" name="search" class="form-control" placeholder="Cari Nama..." value="{{ request('search') }}">
<button type="submit" class="btn btn-outline-primary"><i class="ti tabler-search"></i></button>
</div>
<a href="{{ route('kelompok-tani.create') }}" class="btn btn-sm btn-primary">
<i class="ti tabler-plus me-1"></i> Tambah
</a>
</div>
</form>
</div>
<div class="table-responsive text-nowrap">
<table class="table table-hover">
<thead class="border-top">
<tr>
<th>No</th>
<th>Nama Kelompok</th>
<th>Desa/Kelurahan</th>
<th>Jenis Kelompok</th>
<th>Tahun Berdiri</th>
<th>Nama Responden</th>
<th>Aksi</th>
</tr>
</thead>
<tbody>
@forelse($kelompokTani as $index => $item)
<tr>
<td>{{ $loop->iteration }}</td>
<td><span class="text-heading">{{ $item->nama_kelompok }}</span></td>
<td><span class="text-muted">{{ $item->desaKelurahan?->nama }}</span></td>
<td><span class="text-muted">{{ $item->jenis_kelompok }}</span></td>
<td><span class="text-muted">{{ $item->tahun_berdiri }}</span></td>
<td><span class="text-muted">{{ $item->nama_responden }}</span></td>
<td>
<div class="d-flex align-items-center">
<a href="{{ route('kelompok-tani.edit', $item->id) }}" class="btn btn-icon btn-text-secondary rounded-pill edit-record"><i class="ti tabler-edit ti-md"></i></a>
<a href="javascript:;" class="btn btn-icon btn-text-secondary rounded-pill delete-record" data-id="{{ $item->id }}" data-nama="{{ $item->nama_kelompok }}"><i class="ti tabler-trash ti-md"></i></a>
</div>
</td>
</tr>
@empty
<tr><td colspan="7" class="text-center py-4">Tidak ada data ditemukan.</td></tr>
@endforelse
</tbody>
</table>
</div>
<div class="card-footer d-flex justify-content-center justify-content-md-end border-top">
{{ $kelompokTani->appends(request()->query())->links('pagination::bootstrap-5') }}
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
'use strict';
const csrfToken = "{{ csrf_token() }}";
$(document).ready(function () {
$(document).on('click', '.delete-record', function () {
const id = $(this).data('id');
const name = $(this).data('nama');
Swal.fire({
title: 'Apakah Anda yakin?',
text: `Data kelompok tani "${name}" akan dihapus secara permanen!`,
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Ya, Hapus!',
customClass: { confirmButton: 'btn btn-primary me-3', cancelButton: 'btn btn-label-secondary' },
buttonsStyling: false
}).then(function (result) {
if (result.value) {
$.ajax({
url: '{{ route('kelompok-tani.destroy', ':id') }}'.replace(':id', id),
type: 'DELETE',
headers: { 'X-CSRF-TOKEN': csrfToken },
success: function (res) {
Swal.fire({ icon: 'success', title: 'Terhapus!', text: res.message, showConfirmButton: false, timer: 1500 })
.then(() => window.location.reload());
},
error: () => Swal.fire({ icon: 'error', title: 'Gagal!', text: 'Terjadi kesalahan sistem.' })
});
}
});
});
});
</script>
@endpush
@@ -0,0 +1,167 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
@include('produktivitas.survey-kelompok-tani.header', ['kelompokTani' => $kelompokTani])
<div class="card mb-6" id="section-kelembagaan">
<div class="card-body pt-6">
@include('produktivitas.survey-kelompok-tani._alert', [
'section' => 'kelembagaan',
'errorFields' => ['cakupan_wilayah', 'nama_wilayah_cakupan', 'status_legalitas', 'nomor_sk', 'tanggal_tahun_penerbitan_sk', 'tingkat_keaktifan_ketua', 'status_pembagian_peran', 'status_dokumentasi_rapat', 'frekuensi_pertemuan', 'tanggal_pertemuan_terakhir'],
])
<form method="POST" action="{{ route('kelompok-tani.update', $kelompokTani->id) }}">
@csrf
@method('PUT')
<input type="hidden" name="section" value="kelembagaan">
<h5 class="pb-4 border-bottom mb-4">Cakupan Wilayah Kelompok</h5>
<div class="row">
<div class="col-md-4 mb-4 form-control-validation">
<label class="form-label" for="klb-cakupan-wilayah">Cakupan Wilayah Keanggotaan</label>
<select class="form-control @error('cakupan_wilayah') is-invalid @enderror" id="klb-cakupan-wilayah" name="cakupan_wilayah">
<option value="">Pilih Cakupan Wilayah</option>
@foreach(['RT', 'RW', 'Desa', 'Kecamatan', 'Kabupaten'] as $option)
<option value="{{ $option }}" {{ old('cakupan_wilayah', $kelompokTani->cakupan_wilayah) == $option ? 'selected' : '' }}>{{ $option }}</option>
@endforeach
</select>
<small class="text-muted">Pilih satu level cakupan wilayah terluas.</small>
@error('cakupan_wilayah')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-8 mb-4 form-control-validation">
<label class="form-label" for="klb-nama-wilayah-cakupan">Nama Wilayah yang Termasuk Cakupan</label>
<textarea class="form-control @error('nama_wilayah_cakupan') is-invalid @enderror" id="klb-nama-wilayah-cakupan" name="nama_wilayah_cakupan" rows="2"
placeholder="Cth: Desa Sukamaju, Desa Sukamakmur">{{ old('nama_wilayah_cakupan', $kelompokTani->nama_wilayah_cakupan) }}</textarea>
@error('nama_wilayah_cakupan')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<h5 class="pb-4 border-bottom mb-4 mt-4">Status Legalitas Kelompok</h5>
<div class="row">
<div class="col-md-6 mb-4 form-control-validation">
<label class="form-label" for="klb-status-legalitas">Status SK/Dokumen Pendaftaran</label>
<select class="form-control @error('status_legalitas') is-invalid @enderror" id="klb-status-legalitas" name="status_legalitas">
<option value="">Pilih Status Legalitas</option>
@foreach([
'Belum ada SK/dokumen apa pun',
'Sedang proses pengajuan',
'Sudah ada SK dari desa/kecamatan',
'Sudah ada SK dan terdaftar di Dinas/Kabupaten',
'Tidak tahu',
] as $option)
<option value="{{ $option }}" {{ old('status_legalitas', $kelompokTani->status_legalitas) == $option ? 'selected' : '' }}>{{ $option }}</option>
@endforeach
</select>
@error('status_legalitas')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="klb-nomor-sk">Nomor SK (jika ada)</label>
<input type="text" class="form-control @error('nomor_sk') is-invalid @enderror" id="klb-nomor-sk" name="nomor_sk"
value="{{ old('nomor_sk', $kelompokTani->nomor_sk) }}" />
@error('nomor_sk')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="klb-tanggal-penerbitan-sk">Tanggal/Tahun Penerbitan</label>
<input type="text" class="form-control @error('tanggal_tahun_penerbitan_sk') is-invalid @enderror" id="klb-tanggal-penerbitan-sk" name="tanggal_tahun_penerbitan_sk"
placeholder="Cth: 12-01-2020 atau 2020" value="{{ old('tanggal_tahun_penerbitan_sk', $kelompokTani->tanggal_tahun_penerbitan_sk) }}" />
@error('tanggal_tahun_penerbitan_sk')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<h5 class="pb-4 border-bottom mb-4 mt-4">Kualitas Kepemimpinan</h5>
<div class="row">
<div class="col-md-4 mb-4 form-control-validation">
<label class="form-label" for="klb-keaktifan-ketua">Keaktifan Ketua Kelompok</label>
<select class="form-control @error('tingkat_keaktifan_ketua') is-invalid @enderror" id="klb-keaktifan-ketua" name="tingkat_keaktifan_ketua">
<option value="">Pilih Tingkat Keaktifan</option>
@foreach([
'Tidak aktif/jarang hadir',
'Cukup aktif',
'Sangat aktif dan menjalankan tanggung jawab dengan baik',
] as $option)
<option value="{{ $option }}" {{ old('tingkat_keaktifan_ketua', $kelompokTani->tingkat_keaktifan_ketua) == $option ? 'selected' : '' }}>{{ $option }}</option>
@endforeach
</select>
@error('tingkat_keaktifan_ketua')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-4 mb-4 form-control-validation">
<label class="form-label" for="klb-pembagian-peran">Pembagian Peran Pengurus</label>
<select class="form-control @error('status_pembagian_peran') is-invalid @enderror" id="klb-pembagian-peran" name="status_pembagian_peran">
<option value="">Pilih Status Pembagian Peran</option>
@foreach([
'Tidak ada pembagian peran',
'Ada tapi tidak berjalan',
'Ada dan berjalan dengan baik',
] as $option)
<option value="{{ $option }}" {{ old('status_pembagian_peran', $kelompokTani->status_pembagian_peran) == $option ? 'selected' : '' }}>{{ $option }}</option>
@endforeach
</select>
@error('status_pembagian_peran')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-4 mb-4 form-control-validation">
<label class="form-label" for="klb-dokumentasi-rapat">Dokumentasi Rapat (Notulen/Daftar Hadir)</label>
<select class="form-control @error('status_dokumentasi_rapat') is-invalid @enderror" id="klb-dokumentasi-rapat" name="status_dokumentasi_rapat">
<option value="">Pilih Status Dokumentasi</option>
@foreach([
'Tidak ada',
'Ada, tidak rutin',
'Ada, rutin setiap pertemuan',
] as $option)
<option value="{{ $option }}" {{ old('status_dokumentasi_rapat', $kelompokTani->status_dokumentasi_rapat) == $option ? 'selected' : '' }}>{{ $option }}</option>
@endforeach
</select>
@error('status_dokumentasi_rapat')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<h5 class="pb-4 border-bottom mb-4 mt-4">Frekuensi Pertemuan Rutin</h5>
<div class="row">
<div class="col-md-6 mb-4 form-control-validation">
<label class="form-label" for="klb-frekuensi-pertemuan">Frekuensi Pertemuan</label>
<select class="form-control @error('frekuensi_pertemuan') is-invalid @enderror" id="klb-frekuensi-pertemuan" name="frekuensi_pertemuan">
<option value="">Pilih Frekuensi Pertemuan</option>
@foreach([
'Tidak pernah/sudah tidak aktif',
'Tidak rutin/tidak terjadwal',
'1x per 2-3 bulan',
'1x per bulan',
'Lebih dari 1x per bulan',
] as $option)
<option value="{{ $option }}" {{ old('frekuensi_pertemuan', $kelompokTani->frekuensi_pertemuan) == $option ? 'selected' : '' }}>{{ $option }}</option>
@endforeach
</select>
@error('frekuensi_pertemuan')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-6 mb-4 form-control-validation">
<label class="form-label" for="klb-tanggal-pertemuan-terakhir">Tanggal Pertemuan Terakhir</label>
<input type="text" class="form-control @error('tanggal_pertemuan_terakhir') is-invalid @enderror" id="klb-tanggal-pertemuan-terakhir" name="tanggal_pertemuan_terakhir"
value="{{ old('tanggal_pertemuan_terakhir', $kelompokTani->tanggal_pertemuan_terakhir?->format('Y-m-d')) }}" />
@error('tanggal_pertemuan_terakhir')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="mt-4 text-end">
<button type="submit" class="btn btn-success wave-effect wave-light">
<i class="ti tabler-device-floppy me-2"></i> Simpan Kelembagaan
</button>
</div>
</form>
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
'use strict';
$(document).ready(function () {
$('#klb-cakupan-wilayah, #klb-status-legalitas, #klb-keaktifan-ketua, #klb-pembagian-peran, #klb-dokumentasi-rapat, #klb-frekuensi-pertemuan').select2();
$('#klb-tanggal-pertemuan-terakhir').flatpickr({
dateFormat: 'Y-m-d',
altInput: true,
altFormat: 'd-m-Y'
});
});
</script>
@endpush
@@ -0,0 +1,318 @@
@extends('layout.main')
@push('style')
<style>
.status-switch-row {
display: flex !important;
align-items: center !important;
gap: 12px !important;
white-space: nowrap !important;
}
.status-switch-row .switch {
width: 52px !important;
min-width: 52px !important;
max-width: 52px !important;
padding-left: 0 !important;
margin: 0 !important;
position: relative !important;
display: inline-block !important;
flex: 0 0 52px !important;
}
.status-switch-row .switch-toggle-slider {
left: 0 !important;
}
</style>
@endpush
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
@include('produktivitas.survey-kelompok-tani.header', ['kelompokTani' => $kelompokTani])
{{-- RINGKASAN JUMLAH & KOMPOSISI GENDER --}}
<div class="card mb-6" id="section-ringkasan">
<div class="card-body pt-6">
@include('produktivitas.survey-kelompok-tani._alert', [
'section' => 'ringkasan',
'errorFields' => ['jumlah_pengurus', 'jumlah_pengurus_aktif', 'jumlah_anggota_terdaftar', 'jumlah_anggota_aktif', 'jumlah_pengurus_laki_laki', 'jumlah_pengurus_perempuan', 'jumlah_anggota_laki_laki', 'jumlah_anggota_perempuan', 'jumlah_anggota_pemuda_laki_laki', 'jumlah_anggota_pemuda_perempuan'],
])
<form method="POST" action="{{ route('kelompok-tani.update', $kelompokTani->id) }}">
@csrf
@method('PUT')
<input type="hidden" name="section" value="ringkasan-pengurus">
<h5 class="pb-4 border-bottom mb-4">Jumlah Pengurus & Anggota</h5>
<div class="row">
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="pa-jumlah-pengurus">Jumlah Pengurus (total)</label>
<input type="number" min="0" class="form-control @error('jumlah_pengurus') is-invalid @enderror" id="pa-jumlah-pengurus" name="jumlah_pengurus"
value="{{ old('jumlah_pengurus', $kelompokTani->jumlah_pengurus) }}" />
@error('jumlah_pengurus')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="pa-jumlah-pengurus-aktif">Jumlah Pengurus Aktif</label>
<input type="number" min="0" class="form-control @error('jumlah_pengurus_aktif') is-invalid @enderror" id="pa-jumlah-pengurus-aktif" name="jumlah_pengurus_aktif"
value="{{ old('jumlah_pengurus_aktif', $kelompokTani->jumlah_pengurus_aktif) }}" />
@error('jumlah_pengurus_aktif')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="pa-jumlah-anggota-terdaftar">Jumlah Anggota Terdaftar</label>
<input type="number" min="0" class="form-control @error('jumlah_anggota_terdaftar') is-invalid @enderror" id="pa-jumlah-anggota-terdaftar" name="jumlah_anggota_terdaftar"
value="{{ old('jumlah_anggota_terdaftar', $kelompokTani->jumlah_anggota_terdaftar) }}" />
@error('jumlah_anggota_terdaftar')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="pa-jumlah-anggota-aktif">Jumlah Anggota Aktif <small class="text-muted">(hadir pertemuan rutin)</small></label>
<input type="number" min="0" class="form-control @error('jumlah_anggota_aktif') is-invalid @enderror" id="pa-jumlah-anggota-aktif" name="jumlah_anggota_aktif"
value="{{ old('jumlah_anggota_aktif', $kelompokTani->jumlah_anggota_aktif) }}" />
@error('jumlah_anggota_aktif')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<h5 class="pb-4 border-bottom mb-4 mt-4">Komposisi Gender</h5>
<div class="row">
<div class="col-md-4 mb-4">
<label class="form-label d-block">Jumlah Pengurus (Laki-laki / Perempuan)</label>
<div class="d-flex gap-2">
<input type="number" min="0" class="form-control @error('jumlah_pengurus_laki_laki') is-invalid @enderror" name="jumlah_pengurus_laki_laki"
placeholder="Laki-laki" value="{{ old('jumlah_pengurus_laki_laki', $kelompokTani->jumlah_pengurus_laki_laki) }}" />
<input type="number" min="0" class="form-control @error('jumlah_pengurus_perempuan') is-invalid @enderror" name="jumlah_pengurus_perempuan"
placeholder="Perempuan" value="{{ old('jumlah_pengurus_perempuan', $kelompokTani->jumlah_pengurus_perempuan) }}" />
</div>
</div>
<div class="col-md-4 mb-4">
<label class="form-label d-block">Jumlah Anggota (Laki-laki / Perempuan)</label>
<div class="d-flex gap-2">
<input type="number" min="0" class="form-control @error('jumlah_anggota_laki_laki') is-invalid @enderror" name="jumlah_anggota_laki_laki"
placeholder="Laki-laki" value="{{ old('jumlah_anggota_laki_laki', $kelompokTani->jumlah_anggota_laki_laki) }}" />
<input type="number" min="0" class="form-control @error('jumlah_anggota_perempuan') is-invalid @enderror" name="jumlah_anggota_perempuan"
placeholder="Perempuan" value="{{ old('jumlah_anggota_perempuan', $kelompokTani->jumlah_anggota_perempuan) }}" />
</div>
</div>
<div class="col-md-4 mb-4">
<label class="form-label d-block">Jumlah Anggota Pemuda (16-30 th) <small class="text-muted">L / P</small></label>
<div class="d-flex gap-2">
<input type="number" min="0" class="form-control @error('jumlah_anggota_pemuda_laki_laki') is-invalid @enderror" name="jumlah_anggota_pemuda_laki_laki"
placeholder="Laki-laki" value="{{ old('jumlah_anggota_pemuda_laki_laki', $kelompokTani->jumlah_anggota_pemuda_laki_laki) }}" />
<input type="number" min="0" class="form-control @error('jumlah_anggota_pemuda_perempuan') is-invalid @enderror" name="jumlah_anggota_pemuda_perempuan"
placeholder="Perempuan" value="{{ old('jumlah_anggota_pemuda_perempuan', $kelompokTani->jumlah_anggota_pemuda_perempuan) }}" />
</div>
</div>
</div>
<div class="mt-4 text-end">
<button type="submit" class="btn btn-success wave-effect wave-light">
<i class="ti tabler-device-floppy me-2"></i> Simpan Ringkasan
</button>
</div>
</form>
</div>
</div>
{{-- DAFTAR PENGURUS --}}
<div class="card mb-6" id="section-pengurus">
<div class="card-body pt-6">
@include('produktivitas.survey-kelompok-tani._alert', [
'section' => 'pengurus',
'errorFields' => ['pengurus.*'],
])
<h5 class="pb-4 border-bottom mb-4">Daftar Pengurus</h5>
{{-- DATA LAMA --}}
@if ($kelompokTani->pengurus->count() > 0)
@foreach ($kelompokTani->pengurus as $row)
<div class="row align-items-end border-bottom pb-3 mb-3">
<div class="col-md-4">
<label class="form-label">Nama Pengurus</label>
<input type="text" class="form-control" value="{{ $row->nama_pengurus }}" disabled>
</div>
<div class="col-md-3">
<label class="form-label">Jabatan</label>
<input type="text" class="form-control" value="{{ $row->jabatan }}" disabled>
</div>
<div class="col-md-3">
<label class="form-label">No. Kontak</label>
<input type="text" class="form-control" value="{{ $row->kontak }}" disabled>
</div>
<div class="col-md-1">
<label class="form-label d-block mb-1">Status</label>
<span class="badge {{ $row->status ? 'bg-label-success' : 'bg-label-secondary' }}">
{{ $row->status ? 'Aktif' : 'Tidak aktif' }}
</span>
</div>
<div class="col-md-1">
<form method="POST" action="{{ route('kelompok-tani.pengurus-anggota.destroy', [$kelompokTani->id, $row->id]) }}" class="delete-db-form">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-outline-danger">
<i class="icon-base ti tabler-trash icon-sm"></i>
</button>
</form>
</div>
</div>
@endforeach
@else
<p class="text-muted mb-4">Belum ada data pengurus.</p>
@endif
{{-- FORM TAMBAH DATA BARU --}}
<form method="POST" action="{{ route('kelompok-tani.pengurus-anggota.store', $kelompokTani->id) }}" class="form-repeater-pengurus">
@csrf
<div data-repeater-list="pengurus">
<div data-repeater-item>
<div class="row align-items-end">
<div class="col-md-4 mb-3">
<label class="form-label">Nama Pengurus</label>
<input type="text" class="form-control pengurus-input" name="nama_pengurus" placeholder="Cth: John Doe">
</div>
<div class="col-md-3 mb-3">
<label class="form-label">Jabatan</label>
<input type="text" class="form-control pengurus-input" name="jabatan" placeholder="Cth: Ketua">
</div>
<div class="col-md-3 mb-3">
<label class="form-label">No. Kontak</label>
<input type="text" class="form-control pengurus-input" name="kontak" placeholder="Cth: 081234567890">
</div>
<div class="col-md-1 mb-3">
<label class="form-label d-block">Status</label>
<div class="status-switch-row">
<label class="switch switch-lg">
<input type="hidden" class="pengurus-status-hidden" name="status" value="0">
<input type="checkbox" class="switch-input pengurus-status-switch">
<span class="switch-toggle-slider">
<span class="switch-on"><i class="icon-base ti tabler-check"></i></span>
<span class="switch-off"><i class="icon-base ti tabler-x"></i></span>
</span>
</label>
</div>
</div>
<div class="col-md-1 mb-3">
<button type="button" class="btn btn-outline-danger btn-delete-pengurus" data-repeater-delete disabled>
<i class="icon-base ti tabler-trash icon-sm"></i>
</button>
</div>
</div>
<hr>
</div>
</div>
<div class="mt-4 d-flex justify-content-between">
<button type="button" class="btn btn-outline-success" id="btn-tambah-pengurus" data-repeater-create disabled>
<i class="icon-base ti tabler-plus me-1_5 icon-sm"></i> Tambah Pengurus
</button>
<button type="submit" class="btn btn-success">
<i class="icon-base ti tabler-check me-1_5 icon-sm"></i> Simpan Daftar Pengurus
</button>
</div>
</form>
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
'use strict';
$(function () {
const $form = $('.form-repeater-pengurus');
const $btnTambah = $('#btn-tambah-pengurus');
function getRows() {
return $form.find('[data-repeater-item]');
}
function rowAdaIsi($row) {
return $row.find('.pengurus-input').toArray().some(function (input) {
return String($(input).val() || '').trim() !== '';
});
}
function rowLengkap($row) {
const $inputs = $row.find('.pengurus-input');
return $inputs.toArray().every(function (input) {
return String($(input).val() || '').trim() !== '';
});
}
function updateButtons() {
const $rows = getRows();
const $lastRow = $rows.last();
$rows.each(function () {
const $row = $(this);
$row.find('.btn-delete-pengurus').prop('disabled', !rowAdaIsi($row));
});
$btnTambah.prop('disabled', !rowLengkap($lastRow));
}
$form.repeater({
initEmpty: false,
show: function () {
const $row = $(this);
$row.find('.pengurus-input').val('');
$row.find('.pengurus-status-switch').prop('checked', false);
$row.find('.pengurus-status-hidden').val('0');
$row.find('.btn-delete-pengurus').prop('disabled', true);
$row.slideDown();
setTimeout(updateButtons, 50);
},
hide: function (deleteElement) {
const $row = $(this);
if (!rowAdaIsi($row)) {
return;
}
Swal.fire({
title: 'Hapus baris ini?',
text: 'Baris ini hanya akan dihapus dari form.',
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Ya, hapus',
cancelButtonText: 'Batal',
customClass: { confirmButton: 'btn btn-danger me-3', cancelButton: 'btn btn-label-secondary' },
buttonsStyling: false
}).then(function (result) {
if (result.isConfirmed) {
$row.slideUp(deleteElement);
setTimeout(updateButtons, 300);
}
});
}
});
$(document).on('input keyup change', '.form-repeater-pengurus .pengurus-input', updateButtons);
updateButtons();
// Checkbox switch tidak punya "name" (biar tidak kena auto-suffix "[]" dari plugin repeater
// untuk elemen checkbox) — nilainya disinkronkan manual ke hidden input yang benar-benar dikirim.
$(document).on('change', '.form-repeater-pengurus .pengurus-status-switch', function () {
$(this).closest('.status-switch-row').find('.pengurus-status-hidden').val(this.checked ? '1' : '0');
});
$(document).on('submit', '.delete-db-form', function (e) {
e.preventDefault();
const form = this;
Swal.fire({
title: 'Hapus data pengurus ini?',
text: 'Data yang sudah dihapus tidak bisa dikembalikan.',
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Ya, hapus',
cancelButtonText: 'Batal',
customClass: { confirmButton: 'btn btn-danger me-3', cancelButton: 'btn btn-label-secondary' },
buttonsStyling: false
}).then(function (result) {
if (result.isConfirmed) {
form.submit();
}
});
});
});
</script>
@endpush
@@ -0,0 +1,98 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
@include('produktivitas.survey-kelompok-tani.header', ['kelompokTani' => $kelompokTani])
<div class="card mb-6" id="section-sosial-konflik">
<div class="card-body pt-6">
@include('produktivitas.survey-kelompok-tani._alert', [
'section' => 'sosial-konflik',
'errorFields' => ['partisipasi_perempuan', 'konflik_kelompok', 'topik_konflik', 'penyelesaian_konflik'],
])
<form method="POST" action="{{ route('kelompok-tani.update', $kelompokTani->id) }}">
@csrf
@method('PUT')
<input type="hidden" name="section" value="sosial-konflik">
<h5 class="pb-4 border-bottom mb-4">Keterlibatan Perempuan</h5>
<div class="row">
<div class="col-md-6 mb-4 form-control-validation">
<label class="form-label" for="sk-partisipasi-perempuan">Apakah Perempuan Terlibat Aktif dalam Kegiatan & Pengambilan Keputusan?</label>
<select class="form-control @error('partisipasi_perempuan') is-invalid @enderror" id="sk-partisipasi-perempuan" name="partisipasi_perempuan">
<option value="">Pilih Status</option>
@foreach([
'Tidak terlibat',
'Hadir tapi pasif',
'Terlibat aktif dalam diskusi/keputusan',
] as $option)
<option value="{{ $option }}" {{ old('partisipasi_perempuan', $kelompokTani->partisipasi_perempuan) == $option ? 'selected' : '' }}>{{ $option }}</option>
@endforeach
</select>
@error('partisipasi_perempuan')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<h5 class="pb-4 border-bottom mb-4 mt-4">Riwayat Konflik Internal Kelompok</h5>
<p class="text-muted" style="font-size: 0.8rem; margin-top: -0.75rem;">
Topik ini cukup sensitif. Kalau responden tidak nyaman menjawab, pilih "Tidak bersedia menjawab".
</p>
<div class="row">
<div class="col-md-6 mb-4 form-control-validation">
<label class="form-label" for="sk-konflik-kelompok">Pernah Terjadi Konflik Internal?</label>
<select class="form-control @error('konflik_kelompok') is-invalid @enderror" id="sk-konflik-kelompok" name="konflik_kelompok">
<option value="">Pilih Status</option>
@foreach([
'Tidak pernah',
'Pernah, sudah selesai',
'Pernah, masih berlanjut/belum selesai',
'Tidak bersedia menjawab',
] as $option)
<option value="{{ $option }}" {{ old('konflik_kelompok', $kelompokTani->konflik_kelompok) == $option ? 'selected' : '' }}>{{ $option }}</option>
@endforeach
</select>
@error('konflik_kelompok')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="row" id="sk-detail-konflik-wrapper" style="display: none;">
<div class="col-md-6 mb-4 form-control-validation">
<label class="form-label" for="sk-topik-konflik">Jika Pernah, Soal Apa?</label>
<input type="text" class="form-control @error('topik_konflik') is-invalid @enderror" id="sk-topik-konflik" name="topik_konflik"
placeholder="Cth: Kepemimpinan, pembagian hasil" value="{{ old('topik_konflik', $kelompokTani->topik_konflik) }}" />
@error('topik_konflik')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-6 mb-4 form-control-validation">
<label class="form-label" for="sk-penyelesaian-konflik">Bagaimana Penyelesaiannya?</label>
<textarea class="form-control @error('penyelesaian_konflik') is-invalid @enderror" id="sk-penyelesaian-konflik" name="penyelesaian_konflik" rows="2">{{ old('penyelesaian_konflik', $kelompokTani->penyelesaian_konflik) }}</textarea>
@error('penyelesaian_konflik')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="mt-4 text-end">
<button type="submit" class="btn btn-success wave-effect wave-light">
<i class="ti tabler-device-floppy me-2"></i> Simpan Sosial & Konflik
</button>
</div>
</form>
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
'use strict';
$(document).ready(function () {
$('#sk-partisipasi-perempuan, #sk-konflik-kelompok').select2();
function toggleDetailKonflik() {
var val = $('#sk-konflik-kelompok').val();
$('#sk-detail-konflik-wrapper').toggle(val === 'Pernah, sudah selesai' || val === 'Pernah, masih berlanjut/belum selesai');
}
toggleDetailKonflik();
$('#sk-konflik-kelompok').on('change', toggleDetailKonflik);
});
</script>
@endpush
@@ -0,0 +1,103 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
<div class="card">
<div class="card-header border-bottom mb-4">
<h5 class="card-title mb-0">Edit Petani</h5>
</div>
<div class="card-body">
<form id="viewPetaniForm">
@if ($errors->any())
<div class="alert alert-danger">
<ul class="mb-0">
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<h6 class="mb-3">Informasi Petani</h6>
<div class="row">
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="edit-petani-nama">Nama Petani</label>
<input type="text" class="form-control" id="edit-petani-nama" name="nama"
placeholder="Cth: John Doe" value="{{ old('nama', $petani->nama) }}" readonly/>
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="edit-petani-jenis-kelamin">Jenis Kelamin</label>
<input type="text" class="form-control" id="edit-petani-jenis-kelamin" name="jenis_kelamin"
value="{{ old('jenis_kelamin', $petani->jenis_kelamin) == '1' ? 'Laki-laki' : 'Perempuan' }}" readonly/>
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="edit-petani-tempat-lahir">Tempat Lahir</label>
<input type="text" class="form-control" id="edit-petani-tempat-lahir" name="tempat_lahir" placeholder="Cth: Ngada"
value="{{ old('tempat_lahir', $petani->tempat_lahir) }}" />
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="edit-petani-tanggal-lahir">Tanggal Lahir</label>
<input type="date" class="form-control" id="edit-petani-tanggal-lahir" name="tanggal_lahir"
value="{{ old('tanggal_lahir', $petani->tanggal_lahir?->format('d-m-Y')) }}" />
</div>
</div>
<div class="row">
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="edit-petani-pendidikan-terakhir">Pendidikan Terakhir</label>
<input type="text" class="form-control" id="edit-petani-pendidikan-terakhir" name="pendidikan_terakhir"
value="{{ old('pendidikan_terakhir', $petani->pendidikan_terakhir?->label()) }}" readonly/>
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="edit-petani-status-pernikahan">Status Pernikahan<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="edit-petani-status-pernikahan" name="status_perkawinan"
value="{{ old('status_perkawinan', $petani->status_perkawinan?->label()) }}" readonly/>
</div>
</div>
<div class="row">
<div class="col-md-12 mb-4 form-control-validation">
<label class="form-label" for="edit-petani-alamat">Alamat</label>
<input type="text" class="form-control" id="edit-petani-alamat" name="alamat"
placeholder="Cth: Alamat lengkap petani" value="{{ old('alamat', $petani->alamat) }}" />
</div>
</div>
<div class="row">
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="edit-petani-provinsi">Provinsi</label>
<input type="text" class="form-control" id="edit-petani-provinsi" name="provinsi"
value="{{ old('provinsi', $petani->desaKelurahan?->kecamatan->kabupatenKota->provinsi->nama) }}" readonly/>
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="edit-petani-kabupaten">Kabupaten/Kota</label>
<input type="text" class="form-control" id="edit-petani-kabupaten" name="kabupaten"
value="{{ old('kabupaten', $petani->desaKelurahan?->kecamatan->kabupatenKota->nama) }}" readonly/>
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="edit-petani-kecamatan">Kecamatan</label>
<input type="text" class="form-control" id="edit-petani-kecamatan" name="kecamatan"
value="{{ old('kecamatan', $petani->desaKelurahan?->kecamatan->nama) }}" readonly/>
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="edit-petani-desa">Desa/Kelurahan</label>
<input type="text" class="form-control" id="edit-petani-desa" name="desa"
value="{{ old('desa', $petani->desaKelurahan->nama) }}" readonly/>
</div>
</div>
<div class="mt-4 text-end">
<a href="{{ route('petani.index') }}" class="btn btn-label-secondary me-2">Kembali</a>
</div>
</form>
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
'use strict';
$(document).ready(function () {
});
</script>
@endpush
+40 -1
View File
@@ -45,8 +45,24 @@ Route::middleware('auth')
// Dashboard
Route::get('/dashboard/petani', [App\Http\Controllers\Web\Dashboard\ProfilPetaniController::class, 'index'])->name('dashboard.petani');
Route::get('/dashboard/bumdes', [App\Http\Controllers\Web\Bumdes\PengurusBumdesController::class, 'index'])->name('dashboard.bumdes');
Route::get('/dashboard/petani/demografi', [App\Http\Controllers\Web\Dashboard\DemografiPetaniController::class, 'index'])->name('dashboard.demografi-petani');
Route::get('/dashboard/petani/demografi/table',[App\Http\Controllers\Web\Dashboard\DemografiPetaniController::class, 'data'])->name('dashboard.demografi-petani.data');
Route::get('/dashboard/petani/indikator-pertanian/data', [App\Http\Controllers\Web\Dashboard\IndikatorPertanianController::class, 'data'])->name('dashboard.indikator-pertanian.data');
Route::get('/dashboard/petani/indikator-pertanian', [App\Http\Controllers\Web\Dashboard\IndikatorPertanianController::class, 'index'])->name('dashboard.indikator-pertanian');
Route::get('/dashboard/petani/indeks', [App\Http\Controllers\Web\Dashboard\IndeksPetaniController::class, 'index'])->name('dashboard.indeks-petani');
Route::get('/dashboard/petani/indeks/summary', [App\Http\Controllers\Web\Dashboard\IndeksPetaniController::class, 'summary'])->name('dashboard.indeks-petani.summary');
Route::get('/dashboard/petani/indeks/segmen', [App\Http\Controllers\Web\Dashboard\IndeksPetaniController::class, 'segmen'])->name('dashboard.indeks-petani.segmen');
Route::get('/dashboard/petani/indeks/segmen/komoditas', [App\Http\Controllers\Web\Dashboard\IndeksPetaniController::class, 'segmenByKomoditas'])->name('dashboard.indeks-petani.segmen.komoditas');
Route::get('/dashboard/petani/indeks/dimensi', [App\Http\Controllers\Web\Dashboard\IndeksPetaniController::class, 'dimensi'])->name('dashboard.indeks-petani.dimensi');
Route::get('/dashboard/petani/indeks/komponen', [App\Http\Controllers\Web\Dashboard\IndeksPetaniController::class, 'komponen'])->name('dashboard.indeks-petani.komponen');
Route::get('/dashboard/petani/indeks/map', [App\Http\Controllers\Web\Dashboard\IndeksPetaniController::class, 'map'])->name('dashboard.indeks-petani.map');
Route::get('/dashboard/petani/indeks/desa', [App\Http\Controllers\Web\Dashboard\IndeksPetaniController::class, 'desa'])->name('dashboard.indeks-petani.desa');
Route::get('/dashboard/petani/indeks/data', [App\Http\Controllers\Web\Dashboard\IndeksPetaniController::class, 'data'])->name('dashboard.indeks-petani.data');
Route::get('/dashboard/profil/petani/{id}',[App\Http\Controllers\Web\Produktivitas\ProfilPetaniController::class, 'index'])->name('dashboard.profil-petani');
Route::get('/user-profile', [App\Http\Controllers\Web\Konfigurasi\ProfileController::class, 'index'])->name('userProfile.index');
Route::get('/user-profile/security', [App\Http\Controllers\Web\Konfigurasi\ProfileController::class, 'security'])->name('userProfile.security');
Route::get('/user-profile/activities', [App\Http\Controllers\Web\Konfigurasi\ProfileController::class, 'activities'])->name('userProfile.activities');
@@ -223,4 +239,27 @@ Route::middleware('auth')
Route::resource('petani.akses-pasar', App\Http\Controllers\Web\Produktivitas\AksesPasarController::class)->whereNumber('petani');
Route::resource('petani.skor', App\Http\Controllers\Web\Produktivitas\SkorPetaniController::class)->only(['index']);
Route::resource('survey/kelompok-tani', App\Http\Controllers\Web\Produktivitas\SurveyKelompokTaniController::class)->except(['show'])->names('kelompok-tani')->parameters(['kelompok-tani' => 'kelompokTani']);
Route::prefix('survey/kelompok-tani/{kelompokTani}')->name('kelompok-tani.')->group(function () {
Route::resource('pengurus-anggota', App\Http\Controllers\Web\Produktivitas\PengurusKelompokTaniController::class)->only(['index', 'store', 'destroy'])->parameters(['pengurus-anggota' => 'pengurus']);
Route::resource('aset-keuangan', App\Http\Controllers\Web\Produktivitas\AsetKelompokTaniController::class)->only(['index', 'store', 'destroy'])->parameters(['aset-keuangan' => 'aset']);
Route::put('/aset-keuangan', [App\Http\Controllers\Web\Produktivitas\AsetKelompokTaniController::class, 'update'])->name('aset-keuangan.update');
Route::resource('bantuan-penilaian', App\Http\Controllers\Web\Produktivitas\BantuanKelompokTaniController::class)->only(['index', 'store', 'destroy'])->parameters(['bantuan-penilaian' => 'bantuan']);
});
// BUMDES
Route::post('bumdes/{bumdes}/kelembagaan-aktor', [App\Http\Controllers\Web\Bumdes\PengurusBumdesController::class, 'storeKelembagaanAktor'])->name('bumdes.kelembagaan-aktor.store');
Route::get('bumdes/{bumdes}/kelembagaan-aktor', [App\Http\Controllers\Web\Bumdes\PengurusBumdesController::class, 'kelembagaanAktor'])->name('bumdes.kelembagaan-aktor.index');
Route::resource('bumdes', App\Http\Controllers\Web\Bumdes\PengurusBumdesController::class);
Route::delete('/koperasi/pengurus/{id}', [\App\Http\Controllers\Web\Koperasi\PengurusKoperasiController::class, 'destroy'])->name('koperasi.pengurus.destroy');
// --- KOPERASI GROUP ---
Route::prefix('koperasi')->name('koperasi.')->group(function () {
Route::resource('pengurus', App\Http\Controllers\Web\Koperasi\PengurusKoperasiController::class);
Route::get('pengurus/{id}/survey', [App\Http\Controllers\Web\Koperasi\PengurusKoperasiController::class, 'survey'])->name('pengurus.survey');
Route::post('pengurus/{id}/survey', [App\Http\Controllers\Web\Koperasi\PengurusKoperasiController::class, 'surveyStore'])->name('pengurus.survey.store');
});
});