From 53913bebe940067c3e48700a744954e911eacc1e Mon Sep 17 00:00:00 2001 From: SyaharaniSalsabilla Date: Tue, 3 Nov 2026 17:53:53 +0700 Subject: [PATCH] update kelompok tani --- .../AsetKelompokTaniController.php | 81 +- .../BantuanKelompokTaniController.php | 118 ++- .../PengurusKelompokTaniController.php | 8 +- .../SurveyKelompokTaniController.php | 233 +++-- app/Models/Pertanian/KelompokTani.php | 5 + public/assets/css/demo.css | 69 ++ .../survey-kelompok-tani/_alert.blade.php | 78 +- .../survey-kelompok-tani/add.blade.php | 103 +- .../aktivitas-fungsi.blade.php | 60 +- .../aset-keuangan.blade.php | 295 +++--- .../bantuan-penilaian.blade.php | 327 +++--- .../survey-kelompok-tani/edit.blade.php | 108 +- .../survey-kelompok-tani/header.blade.php | 141 ++- .../survey-kelompok-tani/index.blade.php | 207 +++- .../kelembagaan.blade.php | 121 +-- .../pengurus-anggota.blade.php | 170 ++-- .../sosial-konflik.blade.php | 44 +- .../survey-kelompok-tani/view.blade.php | 103 -- tests/Feature/KelompokTaniIndexTest.php | 147 +++ tests/Feature/KelompokTaniProfileTest.php | 942 ++++++++++++++++++ 20 files changed, 2319 insertions(+), 1041 deletions(-) delete mode 100644 resources/views/produktivitas/survey-kelompok-tani/view.blade.php create mode 100644 tests/Feature/KelompokTaniIndexTest.php create mode 100644 tests/Feature/KelompokTaniProfileTest.php diff --git a/app/Http/Controllers/Web/Produktivitas/AsetKelompokTaniController.php b/app/Http/Controllers/Web/Produktivitas/AsetKelompokTaniController.php index 003a92d..b69b0d4 100644 --- a/app/Http/Controllers/Web/Produktivitas/AsetKelompokTaniController.php +++ b/app/Http/Controllers/Web/Produktivitas/AsetKelompokTaniController.php @@ -5,6 +5,7 @@ namespace App\Http\Controllers\Web\Produktivitas; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Illuminate\Support\Facades\Gate; +use Illuminate\Support\Facades\DB; use Illuminate\Support\Str; use Illuminate\Validation\Rule; @@ -31,21 +32,30 @@ class AsetKelompokTaniController extends Controller } } - private function redirectToSection(string $url, string $section, string $message) + private function redirectToSection(string $url, string $section, string $message, ?string $nextSection = null) { - return redirect($url . '#section-' . $section)->with([ + return redirect($url . '#section-' . ($nextSection ?? $section))->with([ 'success' => $message, 'success_section' => $section, ]); } + private function kegiatanUrl(KelompokTani $kelompokTani): string + { + return route('kelompok-tani.edit', $kelompokTani->id) . '?section=aktivitas-fungsi'; + } + + private function nextAssetSection(KelompokTani $kelompokTani): string + { + return $kelompokTani->aset()->where('jenis_aset', 'Kas/simpanan kelompok')->where('status_aset', true)->exists() + ? 'kas' : 'status-bantuan'; + } + public function index(KelompokTani $kelompokTani) { $this->authorizeAccess(); - $kelompokTani->load('aset'); - - return view('produktivitas.survey-kelompok-tani.aset-keuangan', compact('kelompokTani')); + return redirect($this->kegiatanUrl($kelompokTani) . '#section-aset-baku'); } public function update(Request $request, KelompokTani $kelompokTani) @@ -56,11 +66,26 @@ class AsetKelompokTaniController extends Controller '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'], + 'aset.*.status_pengelolaan_aset' => ['required_if_accepted:aset.*.status_aset', 'nullable', 'string', 'max:100'], + 'aset.*.kondisi_aset' => ['required_if_accepted:aset.*.status_aset', 'nullable', 'string', 'max:100'], + ...$this->asetLainnyaRules(), + ], [ + 'aset.*.status_pengelolaan_aset.required_if_accepted' => 'Status Pengelolaan wajib diisi jika aset dipilih Ada.', + 'aset.*.kondisi_aset.required_if_accepted' => 'Kondisi wajib diisi jika aset dipilih Ada.', + 'aset_lainnya.*.jenis_aset.not_in' => 'Jenis aset ini sudah ada di daftar baku di atas.', ]); - foreach ($validated['aset'] as $item) { + DB::transaction(function () use ($kelompokTani, $validated) { + $this->saveAsetBaku($kelompokTani, $validated['aset']); + $this->createAsetLainnya($kelompokTani, $validated['aset_lainnya'] ?? []); + }); + + return $this->redirectToSection($this->kegiatanUrl($kelompokTani), 'aset-baku', 'Data Operasional berhasil disimpan.', $this->nextAssetSection($kelompokTani)); + } + + private function saveAsetBaku(KelompokTani $kelompokTani, array $items): void + { + foreach ($items as $item) { $jenisAset = $item['jenis_aset']; $ada = (bool) ($item['status_aset'] ?? false); @@ -82,8 +107,8 @@ class AsetKelompokTaniController extends Controller $existing->update([ 'status_aset' => true, - 'status_pengelolaan_aset' => $item['status_pengelolaan_aset'] ?? $existing->status_pengelolaan_aset, - 'kondisi_aset' => $item['kondisi_aset'] ?? $existing->kondisi_aset, + 'status_pengelolaan_aset' => $item['status_pengelolaan_aset'], + 'kondisi_aset' => $item['kondisi_aset'], 'deleted_by' => null, 'updated_by' => auth()->id(), ]); @@ -94,30 +119,40 @@ class AsetKelompokTaniController extends Controller 'uid' => 'AKT-' . strtoupper(Str::random(10)), 'jenis_aset' => $jenisAset, 'status_aset' => true, - 'status_pengelolaan_aset' => $item['status_pengelolaan_aset'] ?? '-', - 'kondisi_aset' => $item['kondisi_aset'] ?? '-', + '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.'); + private function asetLainnyaRules(): array + { + return [ + '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'], + ]; } 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'], - ], [ + $validated = $request->validate($this->asetLainnyaRules(), [ 'aset_lainnya.*.jenis_aset.not_in' => 'Jenis aset ini sudah ada di daftar baku di atas.', ]); - foreach ($validated['aset_lainnya'] ?? [] as $item) { + DB::transaction(fn () => $this->createAsetLainnya($kelompokTani, $validated['aset_lainnya'] ?? [])); + + return $this->redirectToSection($this->kegiatanUrl($kelompokTani), 'aset-lainnya', 'Data Operasional berhasil ditambahkan.', $this->nextAssetSection($kelompokTani)); + } + + private function createAsetLainnya(KelompokTani $kelompokTani, array $items): void + { + foreach ($items as $item) { $jenisAset = trim($item['jenis_aset'] ?? ''); if ($jenisAset === '') { @@ -134,8 +169,6 @@ class AsetKelompokTaniController extends Controller '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) @@ -143,11 +176,11 @@ class AsetKelompokTaniController extends Controller $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.'); + abort_if(in_array($aset->jenis_aset, self::JENIS_ASET_BAKU), 422, 'Operasional: gunakan pilihan Ada/Tidak pada tabel untuk menghapus aset baku.'); $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.'); + return $this->redirectToSection($this->kegiatanUrl($kelompokTani), 'aset-lainnya', 'Data Operasional berhasil dihapus.'); } } diff --git a/app/Http/Controllers/Web/Produktivitas/BantuanKelompokTaniController.php b/app/Http/Controllers/Web/Produktivitas/BantuanKelompokTaniController.php index 929c680..035ecbd 100644 --- a/app/Http/Controllers/Web/Produktivitas/BantuanKelompokTaniController.php +++ b/app/Http/Controllers/Web/Produktivitas/BantuanKelompokTaniController.php @@ -5,7 +5,9 @@ namespace App\Http\Controllers\Web\Produktivitas; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Illuminate\Support\Facades\Gate; +use Illuminate\Support\Facades\DB; use Illuminate\Support\Str; +use Illuminate\Validation\Rule; use App\Models\Pertanian\KelompokTani; use App\Models\Pertanian\BantuanKelompokTani; @@ -19,9 +21,9 @@ class BantuanKelompokTaniController extends Controller } } - private function redirectToSection(string $url, string $section, string $message) + private function redirectToSection(string $url, string $section, string $message, ?string $nextSection = null) { - return redirect($url . '#section-' . $section)->with([ + return redirect($url . '#section-' . ($nextSection ?? $section))->with([ 'success' => $message, 'success_section' => $section, ]); @@ -29,7 +31,7 @@ class BantuanKelompokTaniController extends Controller private function redirectToSectionWithError(string $url, string $section, string $message) { - return redirect($url . '#section-' . $section)->with([ + return redirect($url . '#kelompok-tani-notifications')->with([ 'error' => $message, 'error_section' => $section, ]); @@ -39,9 +41,72 @@ class BantuanKelompokTaniController extends Controller { $this->authorizeAccess(); - $kelompokTani->load('bantuan'); + return redirect($this->operasionalUrl($kelompokTani) . '#section-status-bantuan'); + } - return view('produktivitas.survey-kelompok-tani.bantuan-penilaian', compact('kelompokTani')); + private function operasionalUrl(KelompokTani $kelompokTani): string + { + return route('kelompok-tani.edit', $kelompokTani->id) . '?section=aktivitas-fungsi'; + } + + private function hasRecordedAid(KelompokTani $kelompokTani): bool + { + return $kelompokTani->bantuan()->whereRaw("TRIM(nama_program) <> ''")->exists(); + } + + private function bantuanRules(bool $pernah = true, bool $requireFirstRow = false): array + { + $exclude = Rule::excludeIf(!$pernah); + + return [ + 'bantuan' => [$exclude, Rule::requiredIf($requireFirstRow), 'nullable', 'array'], + 'bantuan.*' => [$exclude, 'array'], + 'bantuan.*.nama_program' => [$exclude, 'required_with:bantuan.*.penyelenggara,bantuan.*.bentuk_bantuan,bantuan.*.tahun', 'nullable', 'string', 'max:255'], + 'bantuan.*.penyelenggara' => [$exclude, 'nullable', 'string', 'max:255'], + 'bantuan.*.bentuk_bantuan' => [$exclude, 'nullable', 'string', 'max:255'], + 'bantuan.*.tahun' => [$exclude, 'nullable', 'integer', 'min:1900', 'max:' . date('Y')], + 'bantuan.0.nama_program' => [$exclude, Rule::requiredIf($requireFirstRow), 'required_with:bantuan.0.penyelenggara,bantuan.0.bentuk_bantuan,bantuan.0.tahun', 'nullable', 'string', 'max:255'], + 'bantuan.0.penyelenggara' => [$exclude, Rule::requiredIf($requireFirstRow), 'nullable', 'string', 'max:255'], + 'bantuan.0.bentuk_bantuan' => [$exclude, Rule::requiredIf($requireFirstRow), 'nullable', 'string', 'max:255'], + 'bantuan.0.tahun' => [$exclude, Rule::requiredIf($requireFirstRow), 'nullable', 'integer', 'min:1900', 'max:' . date('Y')], + ]; + } + + private function bantuanMessages(): array + { + return [ + 'pernah_mendapatkan_bantuan.required' => 'Pengalaman Akses Bantuan/Program wajib diisi.', + 'pernah_mendapatkan_bantuan.boolean' => 'Pilih Pernah atau Belum Pernah untuk Pengalaman Akses Bantuan/Program.', + 'bantuan.required' => 'Isi minimal satu data bantuan jika memilih Pernah.', + 'bantuan.0.nama_program.required' => 'Nama Program/Bantuan pada baris pertama wajib diisi.', + 'bantuan.0.penyelenggara.required' => 'Penyelenggara pada baris pertama wajib diisi.', + 'bantuan.0.bentuk_bantuan.required' => 'Bentuk Bantuan pada baris pertama wajib diisi.', + 'bantuan.0.tahun.required' => 'Tahun pada baris pertama wajib diisi.', + 'bantuan.*.nama_program.required_with' => 'Nama Program/Bantuan wajib diisi jika baris bantuan diisi.', + ]; + } + + public function update(Request $request, KelompokTani $kelompokTani) + { + $this->authorizeAccess(); + + $validated = $request->validate([ + 'pernah_mendapatkan_bantuan' => ['required', 'boolean'], + ...$this->bantuanRules( + $request->boolean('pernah_mendapatkan_bantuan'), + $request->boolean('pernah_mendapatkan_bantuan') && !$this->hasRecordedAid($kelompokTani) + ), + ], $this->bantuanMessages()); + + DB::transaction(function () use ($kelompokTani, $validated) { + $kelompokTani->update([ + 'pernah_mendapatkan_bantuan' => $validated['pernah_mendapatkan_bantuan'], + 'updated_by' => auth()->id(), + ]); + $this->createBantuan($kelompokTani, $validated['bantuan'] ?? []); + }); + + return $this->redirectToSection($this->operasionalUrl($kelompokTani), 'status-bantuan', 'Data Operasional berhasil disimpan.'); } public function store(Request $request, KelompokTani $kelompokTani) @@ -50,37 +115,37 @@ class BantuanKelompokTaniController extends Controller if (!$kelompokTani->pernah_mendapatkan_bantuan) { return $this->redirectToSectionWithError( - route('kelompok-tani.bantuan-penilaian.index', $kelompokTani->id), + $this->operasionalUrl($kelompokTani), 'status-bantuan', - 'Set status jadi "Pernah" dulu sebelum menambahkan daftar bantuan/program.' + 'Operasional: pilih jawaban "Pernah" terlebih dahulu sebelum menambahkan data 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')], - ]); + $validated = $request->validate($this->bantuanRules(true, !$this->hasRecordedAid($kelompokTani)), $this->bantuanMessages()); - foreach ($validated['bantuan'] ?? [] as $item) { - if (empty($item['nama_program']) && empty($item['penyelenggara']) && empty($item['bentuk_bantuan'])) { + DB::transaction(fn () => $this->createBantuan($kelompokTani, $validated['bantuan'] ?? [])); + + return $this->redirectToSection($this->operasionalUrl($kelompokTani), 'status-bantuan', 'Data Operasional berhasil ditambahkan.'); + } + + private function createBantuan(KelompokTani $kelompokTani, array $items): void + { + foreach ($items as $item) { + $namaProgram = trim($item['nama_program'] ?? ''); + if ($namaProgram === '') { 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, + 'nama_program' => $namaProgram, + 'penyelenggara' => $item['penyelenggara'] ?? '', + 'bentuk_bantuan' => $item['bentuk_bantuan'] ?? '', '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) @@ -89,9 +154,18 @@ class BantuanKelompokTaniController extends Controller abort_unless($bantuan->survey_kelompok_tani_id === $kelompokTani->id, 404); + if ($kelompokTani->pernah_mendapatkan_bantuan && !$kelompokTani->bantuan() + ->where('id', '!=', $bantuan->id)->whereRaw("TRIM(nama_program) <> ''")->exists()) { + return $this->redirectToSectionWithError( + $this->operasionalUrl($kelompokTani), + 'status-bantuan', + 'Operasional: minimal satu data bantuan harus tersedia saat jawaban masih Pernah.' + ); + } + $bantuan->update(['deleted_by' => auth()->id()]); $bantuan->delete(); - return $this->redirectToSection(route('kelompok-tani.bantuan-penilaian.index', $kelompokTani->id), 'bantuan', 'Data bantuan berhasil dihapus.'); + return $this->redirectToSection($this->operasionalUrl($kelompokTani), 'status-bantuan', 'Data Operasional berhasil dihapus.'); } } diff --git a/app/Http/Controllers/Web/Produktivitas/PengurusKelompokTaniController.php b/app/Http/Controllers/Web/Produktivitas/PengurusKelompokTaniController.php index 00655e1..e89ad09 100644 --- a/app/Http/Controllers/Web/Produktivitas/PengurusKelompokTaniController.php +++ b/app/Http/Controllers/Web/Produktivitas/PengurusKelompokTaniController.php @@ -31,9 +31,7 @@ class PengurusKelompokTaniController extends Controller { $this->authorizeAccess(); - $kelompokTani->load('pengurus'); - - return view('produktivitas.survey-kelompok-tani.pengurus-anggota', compact('kelompokTani')); + return redirect(route('kelompok-tani.edit', $kelompokTani->id) . '#section-ringkasan'); } public function store(Request $request, KelompokTani $kelompokTani) @@ -64,7 +62,7 @@ class PengurusKelompokTaniController extends Controller ]); } - return $this->redirectToSection(route('kelompok-tani.pengurus-anggota.index', $kelompokTani->id), 'pengurus', 'Data pengurus berhasil ditambahkan.'); + return $this->redirectToSection(route('kelompok-tani.edit', $kelompokTani->id), 'pengurus', 'Data Profil berhasil ditambahkan.'); } public function destroy(KelompokTani $kelompokTani, PengurusKelompokTani $pengurus) @@ -76,6 +74,6 @@ class PengurusKelompokTaniController extends Controller $pengurus->update(['deleted_by' => auth()->id()]); $pengurus->delete(); - return $this->redirectToSection(route('kelompok-tani.pengurus-anggota.index', $kelompokTani->id), 'pengurus', 'Data pengurus berhasil dihapus.'); + return $this->redirectToSection(route('kelompok-tani.edit', $kelompokTani->id), 'pengurus', 'Data Profil berhasil dihapus.'); } } diff --git a/app/Http/Controllers/Web/Produktivitas/SurveyKelompokTaniController.php b/app/Http/Controllers/Web/Produktivitas/SurveyKelompokTaniController.php index b6461e1..16ba477 100644 --- a/app/Http/Controllers/Web/Produktivitas/SurveyKelompokTaniController.php +++ b/app/Http/Controllers/Web/Produktivitas/SurveyKelompokTaniController.php @@ -6,9 +6,13 @@ 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\Wilayah\Provinsi; +use App\Models\Wilayah\KabupatenKota; +use App\Models\Wilayah\Kecamatan; +use App\Models\Wilayah\DesaKelurahan; use App\Models\Pertanian\Komoditas; class SurveyKelompokTaniController extends Controller @@ -20,9 +24,9 @@ class SurveyKelompokTaniController extends Controller } } - private function redirectToSection(string $url, string $section, string $message) + private function redirectToSection(string $url, string $section, string $message, ?string $nextSection = null) { - return redirect($url . '#section-' . $section)->with([ + return redirect($url . '#section-' . ($nextSection ?? $section))->with([ 'success' => $message, 'success_section' => $section, ]); @@ -30,13 +34,90 @@ class SurveyKelompokTaniController extends Controller 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()); + $validated = $request->validate([ + 'search' => ['nullable', 'string', 'max:255'], + 'kabupaten_kota_id' => ['nullable', 'integer', 'exists:master_kabupaten_kota,id'], + 'kecamatan_id' => ['nullable', 'integer', 'exists:master_kecamatan,id'], + 'desa_kelurahan_id' => ['nullable', 'integer', 'exists:master_desa_kelurahan,id'], + 'komoditas_id' => ['nullable', 'integer', 'exists:master_komoditas,id'], + 'jenis_kelompok' => ['nullable', 'string', 'max:50'], + 'sort_by' => ['nullable', 'string'], + 'per_page' => ['nullable', 'integer', 'in:10,25'], + ]); - return view('produktivitas.survey-kelompok-tani.index', compact('kelompokTani')); + $defaultKabupaten = KabupatenKota::select('id', 'nama') + ->whereRaw('lower(nama) like ?', ['%ngada%'])->orderBy('nama')->first(); + $allowedSorts = ['nama_asc', 'nama_desc', 'anggota_desc', 'anggota_asc']; + $filters = [ + 'search' => $validated['search'] ?? null, + 'kabupaten_kota_id' => $validated['kabupaten_kota_id'] ?? $defaultKabupaten?->id, + 'kecamatan_id' => $validated['kecamatan_id'] ?? null, + 'desa_kelurahan_id' => $validated['desa_kelurahan_id'] ?? null, + 'komoditas_id' => $validated['komoditas_id'] ?? null, + 'jenis_kelompok' => $validated['jenis_kelompok'] ?? null, + 'sort_by' => in_array($validated['sort_by'] ?? null, $allowedSorts, true) + ? $validated['sort_by'] : null, + ]; + + $query = KelompokTani::query() + ->when(filled($filters['search']), function ($query) use ($filters) { + $search = '%' . Str::lower($filters['search']) . '%'; + $query->where(function ($query) use ($search) { + $query->whereRaw('lower(nama_kelompok) like ?', [$search]) + ->orWhereRaw('lower(nama_responden) like ?', [$search]); + }); + }) + ->when($filters['kabupaten_kota_id'], function ($query, $id) { + $query->whereHas('desaKelurahan.kecamatan', fn ($query) => $query->where('kabupaten_kota_id', $id)); + }) + ->when($filters['kecamatan_id'], function ($query, $id) { + $query->whereHas('desaKelurahan', fn ($query) => $query->where('kecamatan_id', $id)); + }) + ->when($filters['desa_kelurahan_id'], fn ($query, $id) => $query->where('desa_kelurahan_id', $id)) + ->when($filters['komoditas_id'], function ($query, $id) { + $query->where(function ($query) use ($id) { + $query->whereJsonContains('komoditas_id', (string) $id) + ->orWhereJsonContains('komoditas_id', (int) $id); + }); + }) + ->when($filters['jenis_kelompok'], fn ($query, $jenis) => $query->where('jenis_kelompok', $jenis)); + + $summary = (clone $query)->selectRaw(' + COUNT(*) AS total_kelompok, + COUNT(DISTINCT jenis_kelompok) AS total_jenis, + COALESCE(SUM(jumlah_pengurus), 0) AS total_pengurus, + COALESCE(SUM(jumlah_pengurus_aktif), 0) AS pengurus_aktif, + COALESCE(SUM(jumlah_anggota_terdaftar), 0) AS total_anggota, + COALESCE(SUM(jumlah_anggota_aktif), 0) AS anggota_aktif + ')->first(); + + match ($filters['sort_by']) { + 'nama_asc' => $query->orderBy('nama_kelompok'), + 'nama_desc' => $query->orderByDesc('nama_kelompok'), + 'anggota_desc' => $query->orderByRaw('COALESCE(jumlah_anggota_terdaftar, 0) DESC'), + 'anggota_asc' => $query->orderByRaw('COALESCE(jumlah_anggota_terdaftar, 0) ASC'), + default => $query->latest(), + }; + + $perPage = (int) ($validated['per_page'] ?? 10); + $kelompokTani = $query->with('desaKelurahan.kecamatan')->orderByDesc('id') + ->paginate($perPage)->appends([...$filters, 'per_page' => $perPage]); + $selectedKabupaten = $filters['kabupaten_kota_id'] + ? KabupatenKota::select('id', 'nama')->find($filters['kabupaten_kota_id']) : null; + $kecamatanOptions = $filters['kabupaten_kota_id'] + ? Kecamatan::select('id', 'nama')->where('kabupaten_kota_id', $filters['kabupaten_kota_id'])->orderBy('nama')->get() + : collect(); + $desaOptions = $filters['kecamatan_id'] + ? DesaKelurahan::select('id', 'nama')->where('kecamatan_id', $filters['kecamatan_id'])->orderBy('nama')->get() + : collect(); + $komoditasOptions = Komoditas::select('id', 'nama')->orderBy('nama')->get(); + $jenisKelompokOptions = KelompokTani::query()->whereNotNull('jenis_kelompok') + ->where('jenis_kelompok', '!=', '')->distinct()->orderBy('jenis_kelompok')->pluck('jenis_kelompok'); + + return view('produktivitas.survey-kelompok-tani.index', compact( + 'kelompokTani', 'summary', 'filters', 'selectedKabupaten', + 'kecamatanOptions', 'desaOptions', 'komoditasOptions', 'jenisKelompokOptions' + )); } public function create() @@ -46,7 +127,24 @@ class SurveyKelompokTaniController extends Controller $provinsi = Provinsi::orderBy('kode', 'asc')->get(); $komoditas = Komoditas::where('is_utama', true)->get(); - return view('produktivitas.survey-kelompok-tani.add', compact('provinsi', 'komoditas')); + return view('produktivitas.survey-kelompok-tani.add', [ + ...compact('provinsi', 'komoditas'), + ...$this->profileLocationOptions(), + ]); + } + + private function profileLocationOptions(?KelompokTani $kelompokTani = null): array + { + $locationId = static fn ($value) => is_scalar($value) && filter_var($value, FILTER_VALIDATE_INT) !== false ? (int) $value : null; + $provinsiId = $locationId(old('provinsi_id', $kelompokTani?->desaKelurahan?->kecamatan?->kabupatenKota?->provinsi_id)); + $kabupatenId = $locationId(old('kabupaten_id', $kelompokTani?->desaKelurahan?->kecamatan?->kabupaten_kota_id)); + $kecamatanId = $locationId(old('kecamatan_id', $kelompokTani?->desaKelurahan?->kecamatan_id)); + + return [ + 'kabupatenOptions' => filled($provinsiId) ? KabupatenKota::where('provinsi_id', $provinsiId)->orderBy('nama')->get() : collect(), + 'kecamatanOptions' => filled($kabupatenId) ? Kecamatan::where('kabupaten_kota_id', $kabupatenId)->orderBy('nama')->get() : collect(), + 'desaOptions' => filled($kecamatanId) ? DesaKelurahan::where('kecamatan_id', $kecamatanId)->orderBy('nama')->get() : collect(), + ]; } public function store(Request $request) @@ -67,7 +165,7 @@ class SurveyKelompokTaniController extends Controller 'updated_by' => auth()->id(), ]); - return $this->redirectToSection(route('kelompok-tani.edit', $kelompokTani->id), 'identitas', 'Data kelompok tani berhasil ditambahkan.'); + return $this->redirectToSection(route('kelompok-tani.edit', $kelompokTani->id), 'identitas', 'Data Profil berhasil ditambahkan.', 'pengurus'); } private function editUrl(KelompokTani $kelompokTani, string $section = 'identitas'): string @@ -83,12 +181,15 @@ class SurveyKelompokTaniController extends Controller 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')), + 'aktivitas-fungsi' => view('produktivitas.survey-kelompok-tani.aktivitas-fungsi', [ + 'kelompokTani' => $kelompokTani->loadMissing(['aset', 'bantuan']), + ]), 'sosial-konflik' => view('produktivitas.survey-kelompok-tani.sosial-konflik', compact('kelompokTani')), default => view('produktivitas.survey-kelompok-tani.edit', [ - 'kelompokTani' => $kelompokTani, + 'kelompokTani' => $kelompokTani->loadMissing('pengurus'), 'provinsi' => Provinsi::orderBy('kode', 'asc')->get(), 'komoditas' => Komoditas::where('is_utama', true)->get(), + ...$this->profileLocationOptions($kelompokTani), ]), }; } @@ -103,8 +204,8 @@ class SurveyKelompokTaniController extends Controller '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), + 'status-bantuan' => app(BantuanKelompokTaniController::class)->update($request, $kelompokTani), + 'penilaian' => redirect($this->editUrl($kelompokTani, 'aktivitas-fungsi') . '#section-status-bantuan'), default => $this->updateIdentitas($request, $kelompokTani), }; } @@ -122,7 +223,7 @@ class SurveyKelompokTaniController extends Controller private function validateIdentitas(Request $request) { - return $request->validate([ + $validated = $request->validate([ // Data Responden 'nama_responden' => ['required', 'string', 'max:255'], 'jabatan_responden' => ['nullable', 'string', 'max:255'], @@ -130,7 +231,10 @@ class SurveyKelompokTaniController extends Controller // Identitas Kelompok Tani 'nama_kelompok' => ['required', 'string', 'max:255'], - 'desa_kelurahan_id' => ['required', 'exists:master_desa_kelurahan,id'], + 'provinsi_id' => ['bail', 'required', 'integer', 'exists:master_provinsi,id'], + 'kabupaten_id' => ['bail', 'required', 'integer', 'exists:master_kabupaten_kota,id'], + 'kecamatan_id' => ['bail', 'required', 'integer', 'exists:master_kecamatan,id'], + 'desa_kelurahan_id' => ['bail', 'required', 'integer', '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'], @@ -138,15 +242,30 @@ class SurveyKelompokTaniController extends Controller 'nama_gapoktan' => ['nullable', 'string', 'max:255'], 'komoditas_id' => ['nullable', 'array'], 'komoditas_id.*' => ['exists:master_komoditas,id'], + ...$this->keanggotaanRules(), ], [ '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.', + 'provinsi_id.integer' => 'Pilihan Provinsi tidak valid.', + 'kabupaten_id.integer' => 'Pilihan Kabupaten/Kota tidak valid.', + 'kecamatan_id.integer' => 'Pilihan Kecamatan tidak valid.', + 'desa_kelurahan_id.integer' => 'Pilihan Desa/Kelurahan tidak valid.', + 'provinsi_id.exists' => 'Provinsi tidak ditemukan.', + 'kabupaten_id.exists' => 'Kabupaten/Kota tidak ditemukan.', + 'kecamatan_id.exists' => 'Kecamatan tidak ditemukan.', '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.', + 'jenis_kelompok.required' => 'Terdaftar/Dikenal Sebagai wajib diisi.', + 'jenis_kelompok_lainnya.required_if' => 'Sebutkan Jenis Kelompok wajib diisi.', 'tahun_berdiri.digits' => 'Tahun berdiri harus 4 digit.', ]); + + unset($validated['provinsi_id'], $validated['kabupaten_id'], $validated['kecamatan_id']); + + return $validated; } private function updateIdentitas(Request $request, KelompokTani $kelompokTani) @@ -163,12 +282,12 @@ class SurveyKelompokTaniController extends Controller 'updated_by' => auth()->id(), ]); - return $this->redirectToSection(route('kelompok-tani.edit', $kelompokTani->id), 'identitas', 'Data kelompok tani berhasil diperbarui.'); + return $this->redirectToSection(route('kelompok-tani.edit', $kelompokTani->id), 'identitas', 'Data Profil berhasil disimpan.', 'pengurus'); } - private function updateRingkasanPengurus(Request $request, KelompokTani $kelompokTani) + private function keanggotaanRules(): array { - $validated = $request->validate([ + return [ 'jumlah_pengurus' => ['nullable', 'integer', 'min:0'], 'jumlah_pengurus_aktif' => ['nullable', 'integer', 'min:0'], 'jumlah_anggota_terdaftar' => ['nullable', 'integer', 'min:0'], @@ -179,18 +298,24 @@ class SurveyKelompokTaniController extends Controller 'jumlah_anggota_perempuan' => ['nullable', 'integer', 'min:0'], 'jumlah_anggota_pemuda_laki_laki' => ['nullable', 'integer', 'min:0'], 'jumlah_anggota_pemuda_perempuan' => ['nullable', 'integer', 'min:0'], - ]); + ]; + } + + private function updateRingkasanPengurus(Request $request, KelompokTani $kelompokTani) + { + $validated = $request->validate($this->keanggotaanRules()); $kelompokTani->update([ ...$validated, 'updated_by' => auth()->id(), ]); - return $this->redirectToSection(route('kelompok-tani.pengurus-anggota.index', $kelompokTani->id), 'ringkasan', 'Ringkasan pengurus & anggota berhasil disimpan.'); + return $this->redirectToSection($this->editUrl($kelompokTani), 'identitas', 'Data Profil berhasil disimpan.', 'pengurus'); } private function updateKelembagaan(Request $request, KelompokTani $kelompokTani) { + $hasSk = in_array($request->input('status_legalitas'), KelompokTani::STATUS_LEGALITAS_DENGAN_SK, true); $validated = $request->validate([ // Cakupan Wilayah Kelompok 'cakupan_wilayah' => ['nullable', 'string', 'max:50'], @@ -198,17 +323,9 @@ class SurveyKelompokTaniController extends Controller // Status Legalitas Kelompok 'status_legalitas' => ['nullable', 'string', 'max:50'], - 'nomor_sk' => ['nullable', 'string', 'max:100'], - 'tanggal_tahun_penerbitan_sk' => ['nullable', 'string', 'max:30'], + 'nomor_sk' => [Rule::excludeIf(!$hasSk), 'nullable', 'string', 'max:100'], + 'tanggal_tahun_penerbitan_sk' => [Rule::excludeIf(!$hasSk), '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([ @@ -216,7 +333,7 @@ class SurveyKelompokTaniController extends Controller 'updated_by' => auth()->id(), ]); - return $this->redirectToSection($this->editUrl($kelompokTani, 'kelembagaan'), 'kelembagaan', 'Data kelembagaan berhasil disimpan.'); + return $this->redirectToSection($this->editUrl($kelompokTani, 'kelembagaan'), 'kelembagaan', 'Data Kelembagaan berhasil disimpan.'); } private function resolveLainnya(?array $selected, ?string $lainnyaText): ?array @@ -233,6 +350,10 @@ class SurveyKelompokTaniController extends Controller private function updateAktivitasFungsi(Request $request, KelompokTani $kelompokTani) { $validated = $request->validate([ + // Frekuensi Pertemuan Rutin + 'frekuensi_pertemuan' => ['nullable', 'string', 'max:50'], + 'tanggal_pertemuan_terakhir' => ['nullable', 'date'], + // Kegiatan Konkret yang Sudah Berjalan 'kegiatan_terlaksana' => ['nullable', 'array'], 'kegiatan_terlaksana.*' => ['string', 'max:255'], @@ -270,7 +391,7 @@ class SurveyKelompokTaniController extends Controller 'updated_by' => auth()->id(), ]); - return $this->redirectToSection($this->editUrl($kelompokTani, 'aktivitas-fungsi'), 'aktivitas-fungsi', 'Data aktivitas & fungsi kelompok berhasil disimpan.'); + return $this->redirectToSection($this->editUrl($kelompokTani, 'aktivitas-fungsi'), 'aktivitas-fungsi', 'Data Operasional berhasil disimpan.', 'aset-baku'); } private function updateKasSimpanPinjam(Request $request, KelompokTani $kelompokTani) @@ -287,22 +408,28 @@ class SurveyKelompokTaniController extends Controller 'updated_by' => auth()->id(), ]); - return $this->redirectToSection(route('kelompok-tani.aset-keuangan.index', $kelompokTani->id), 'kas', 'Data kas/simpan-pinjam berhasil disimpan.'); + return $this->redirectToSection($this->editUrl($kelompokTani, 'aktivitas-fungsi'), 'kas', 'Data Operasional berhasil disimpan.', 'status-bantuan'); } private function updateSosialKonflik(Request $request, KelompokTani $kelompokTani) { + $pernahKonflik = in_array($request->input('konflik_kelompok'), [ + 'Pernah, sudah selesai', 'Pernah, masih berlanjut/belum selesai', + ], true); + $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'], + 'topik_konflik' => [Rule::requiredIf($pernahKonflik), 'nullable', 'string', 'max:255'], 'penyelesaian_konflik' => ['nullable', 'string'], + ], [ + 'topik_konflik.required' => 'Jika Pernah, Soal Apa? wajib diisi jika pernah terjadi konflik internal.', ]); - if (!in_array($validated['konflik_kelompok'] ?? null, ['Pernah, sudah selesai', 'Pernah, masih berlanjut/belum selesai'])) { + if (!$pernahKonflik) { $validated['topik_konflik'] = null; $validated['penyelesaian_konflik'] = null; } @@ -312,35 +439,7 @@ class SurveyKelompokTaniController extends Controller 'updated_by' => auth()->id(), ]); - return $this->redirectToSection($this->editUrl($kelompokTani, 'sosial-konflik'), 'sosial-konflik', 'Data sosial & konflik berhasil disimpan.'); + return $this->redirectToSection($this->editUrl($kelompokTani, 'sosial-konflik'), 'sosial-konflik', 'Data Sosial 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.'); - } } diff --git a/app/Models/Pertanian/KelompokTani.php b/app/Models/Pertanian/KelompokTani.php index 3d813ab..76490e8 100644 --- a/app/Models/Pertanian/KelompokTani.php +++ b/app/Models/Pertanian/KelompokTani.php @@ -14,6 +14,11 @@ class KelompokTani extends Model { use HasFactory, SoftDeletes; + public const STATUS_LEGALITAS_DENGAN_SK = [ + 'Sudah ada SK dari desa/kecamatan', + 'Sudah ada SK dan terdaftar di Dinas/Kabupaten', + ]; + protected $table = 'survey_kelompok_tani'; protected $fillable = [ diff --git a/public/assets/css/demo.css b/public/assets/css/demo.css index 83f3c69..1d0ceb8 100644 --- a/public/assets/css/demo.css +++ b/public/assets/css/demo.css @@ -185,3 +185,72 @@ color: inherit; } #layout-menu .menu-sub .sidebar-icon > .ti { width: 19px; height: 19px; font-size: 19px; } + +/* Profil Kelompok Tani */ +.kelompok-tani-page { + font-family: var(--bs-body-font-family); + font-size: var(--bs-body-font-size); + font-weight: var(--bs-body-font-weight); + line-height: var(--bs-body-line-height); +} + +.kelompok-tani-page :is(.form-control, .form-select, .form-check-label, .select2-container) { + font-family: var(--bs-body-font-family); +} + +.kelompok-tani-page select.is-invalid + .select2-container .select2-selection { + border-color: var(--bs-form-invalid-border-color); +} + +.kelompok-tani-page .kelompok-tani-summary-name { + font-size: .9rem; +} + +.kelompok-tani-page .kelompok-tani-summary-note { + font-size: .75rem; + line-height: 1.3; +} + +.kelompok-tani-page .kelompok-tani-help { + margin-top: -.75rem; +} + +.kelompok-tani-page #section-kas[hidden], +.kelompok-tani-page #section-bantuan[hidden] { + display: none !important; +} + +.kelompok-tani-page #kelompok-tani-notifications, +.kelompok-tani-page [id^="section-"] { + scroll-margin-top: 7rem; +} + +.kelompok-tani-page .select2-selection { + position: relative; +} + +.kelompok-tani-page .select2-selection::after { + content: ''; + position: absolute; + top: 50%; + inset-inline-end: 1rem; + width: .5rem; + height: .5rem; + border-right: 2px solid currentColor; + border-bottom: 2px solid currentColor; + color: var(--bs-body-color); + transform: translateY(-75%) rotate(45deg); + pointer-events: none; +} + +.kelompok-tani-page .select2-selection__arrow { + display: none; +} + +.kelompok-tani-page .select2-container .select2-selection--multiple .select2-selection__rendered { + padding-inline-end: 2.5rem; +} + +.kelompok-tani-page .select2-container--disabled .select2-selection::after { + color: var(--bs-secondary-color); +} diff --git a/resources/views/produktivitas/survey-kelompok-tani/_alert.blade.php b/resources/views/produktivitas/survey-kelompok-tani/_alert.blade.php index 8f8a4b4..17be4af 100644 --- a/resources/views/produktivitas/survey-kelompok-tani/_alert.blade.php +++ b/resources/views/produktivitas/survey-kelompok-tani/_alert.blade.php @@ -1,37 +1,51 @@ -{{-- - Partial notif per-card. Dipakai di dalam tiap
supaya notif sukses/gagal - muncul tepat di atas card yang barusan disubmit, bukan di paling atas halaman. +@php + $notificationTypes = [ + 'success' => 'success', + 'error' => 'danger', + 'warning' => 'warning', + 'info' => 'info', + 'status' => 'info', + 'message' => 'info', + ]; + $hasNotifications = $errors->any() || collect(array_keys($notificationTypes))->contains(fn ($key) => session()->has($key)); +@endphp - 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) - -@endif +@if($hasNotifications) +
+ @foreach($notificationTypes as $key => $type) + @if(session()->has($key)) + + @endif + @endforeach -@if(session('error') && session('error_section') === $section) - -@endif - -@if(!empty($errorFields) && $errors->has($errorFields)) - + @endif
+ + @push('scripts') + + @endpush @endif diff --git a/resources/views/produktivitas/survey-kelompok-tani/add.blade.php b/resources/views/produktivitas/survey-kelompok-tani/add.blade.php index b046e37..20ade6c 100644 --- a/resources/views/produktivitas/survey-kelompok-tani/add.blade.php +++ b/resources/views/produktivitas/survey-kelompok-tani/add.blade.php @@ -1,31 +1,21 @@ @extends('layout.main') @section('content') -
- @if ($errors->any()) -
-
    - @foreach ($errors->all() as $error) -
  • {{ $error }}
  • - @endforeach -
-
- @endif - +
@include('produktivitas.survey-kelompok-tani.header', ['kelompokTani' => null])
-
+ @csrf
Data Responden
- @error('nama_responden')
{{ $message }}
@enderror
@@ -47,7 +37,7 @@
- @error('nama_kelompok')
{{ $message }}
@enderror
@@ -68,38 +58,50 @@
- @foreach($provinsi as $p) @endforeach + @error('provinsi_id')
{{ $message }}
@enderror
- + @foreach($kabupatenOptions ?? [] as $option) + + @endforeach + @error('kabupaten_id')
{{ $message }}
@enderror
- + @foreach($kecamatanOptions ?? [] as $option) + + @endforeach + @error('kecamatan_id')
{{ $message }}
@enderror
- + @foreach($desaOptions ?? [] as $option) + + @endforeach @error('desa_kelurahan_id')
{{ $message }}
@enderror
-
+
- @@ -111,7 +113,7 @@ @error('jenis_kelompok')
{{ $message }}
@enderror
+ @include('produktivitas.survey-kelompok-tani.pengurus-anggota', ['bagianKeanggotaan' => 'ringkasan', 'kelompokTani' => null]) +
- Kembali - +
+ + Kembali + + +
@@ -157,6 +167,7 @@ function toggleJenisKelompokFields() { var jenisKelompok = $('#add-kt-jenis-kelompok').val(); + $('#add-kt-jenis-kelompok-lainnya').prop('required', jenisKelompok === 'Lainnya').prop('disabled', jenisKelompok !== 'Lainnya'); if (jenisKelompok === 'Lainnya') { $('#add-kt-jenis-kelompok-lainnya-wrapper').show(); @@ -236,52 +247,6 @@ }); $('#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(); - } - }); }); @endpush diff --git a/resources/views/produktivitas/survey-kelompok-tani/aktivitas-fungsi.blade.php b/resources/views/produktivitas/survey-kelompok-tani/aktivitas-fungsi.blade.php index 790bea0..f529980 100644 --- a/resources/views/produktivitas/survey-kelompok-tani/aktivitas-fungsi.blade.php +++ b/resources/views/produktivitas/survey-kelompok-tani/aktivitas-fungsi.blade.php @@ -1,7 +1,7 @@ @extends('layout.main') @section('content') -
+
@include('produktivitas.survey-kelompok-tani.header', ['kelompokTani' => $kelompokTani]) @php @@ -41,18 +41,39 @@
- @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'], - ]) - -
+ @csrf @method('PUT') -
Kegiatan Konkret yang Sudah Berjalan
-

+

Frekuensi Pertemuan Rutin
+
+
+ + + @error('frekuensi_pertemuan')
{{ $message }}
@enderror +
+
+ + + @error('tanggal_pertemuan_terakhir')
{{ $message }}
@enderror +
+
+ +
Kegiatan Konkret yang Sudah Berjalan
+

Kegiatan yang sudah benar-benar dilaksanakan, bukan rencana. Boleh pilih lebih dari satu.

@@ -99,7 +120,7 @@
- @@ -123,7 +144,7 @@
Peran dan Fungsi Kelompok
-

+

Fungsi yang melekat secara struktural pada kelompok ini, terlepas dari seberapa sering kegiatannya berjalan.

@@ -153,13 +174,20 @@
- +
+ + Kembali + + +
+ @include('produktivitas.survey-kelompok-tani.aset-keuangan') + @include('produktivitas.survey-kelompok-tani.bantuan-penilaian')
@endsection @@ -167,6 +195,10 @@ @endpush diff --git a/resources/views/produktivitas/survey-kelompok-tani/header.blade.php b/resources/views/produktivitas/survey-kelompok-tani/header.blade.php index e1fc307..d6388e1 100644 --- a/resources/views/produktivitas/survey-kelompok-tani/header.blade.php +++ b/resources/views/produktivitas/survey-kelompok-tani/header.blade.php @@ -1,3 +1,5 @@ +@include('produktivitas.survey-kelompok-tani._alert') + +@endpush + @section('content') -
+
+ @include('produktivitas.survey-kelompok-tani._alert') + +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
+ +
+
+ Wilayah +
+
+ +
+ {{ preg_replace('/^(kabupaten|kota)\s+/i', '', $selectedKabupaten?->nama ?? 'Semua Kabupaten/Kota') }} +
+
+
+ +
+
+ +
+
+ +
+ +
+
+ Data +
+
+ +
+
+ +
+
+ +
+
+
+ + +
+
+ + Reset +
+
+
+
+
+
+
Data Kelompok Tani
-
+ + @foreach($filters as $field => $value) + + @endforeach
-
-
- - -
+
Tambah @@ -46,9 +196,9 @@ @forelse($kelompokTani as $index => $item) - - {{ $loop->iteration }} - {{ $item->nama_kelompok }} + + {{ $kelompokTani->firstItem() + $loop->index }} + {{ $item->nama_kelompok }} {{ $item->desaKelurahan?->nama }} {{ $item->jenis_kelompok }} {{ $item->tahun_berdiri }} @@ -67,7 +217,7 @@
@@ -79,6 +229,37 @@ const csrfToken = "{{ csrf_token() }}"; $(document).ready(function () { + const $kecamatanFilter = $('#filter-kecamatan'); + const $desaFilter = $('#filter-desa'); + const desaUrlTemplate = '{{ route("desakelurahan.bykecamatan", ":id") }}'; + let desaRequest; + + $kecamatanFilter.on('change', function () { + if (desaRequest) desaRequest.abort(); + $desaFilter.empty().append(new Option('Semua Desa', '')).prop('disabled', true); + const kecamatanId = $(this).val(); + if (!kecamatanId) return; + + desaRequest = $.get(desaUrlTemplate.replace(':id', kecamatanId), function (data) { + data.forEach(function (desa) { + $desaFilter.append(new Option(desa.nama, desa.id)); + }); + $desaFilter.prop('disabled', false); + }).fail(function (xhr, status) { + if (status !== 'abort') { + $desaFilter.empty().append(new Option('Gagal memuat desa', '')); + } + }); + }); + + $(document).on('click', '.kelompok-tani-row', function (event) { + if ($(event.target).closest('a, button, input, select, textarea, label').length) { + return; + } + + window.location.href = this.querySelector('.edit-record').href; + }); + $(document).on('click', '.delete-record', function () { const id = $(this).data('id'); const name = $(this).data('nama'); diff --git a/resources/views/produktivitas/survey-kelompok-tani/kelembagaan.blade.php b/resources/views/produktivitas/survey-kelompok-tani/kelembagaan.blade.php index b885000..a26ce18 100644 --- a/resources/views/produktivitas/survey-kelompok-tani/kelembagaan.blade.php +++ b/resources/views/produktivitas/survey-kelompok-tani/kelembagaan.blade.php @@ -1,17 +1,12 @@ @extends('layout.main') @section('content') -
+
@include('produktivitas.survey-kelompok-tani.header', ['kelompokTani' => $kelompokTani])
- @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'], - ]) - - + @csrf @method('PUT') @@ -20,7 +15,7 @@
- @foreach(['RT', 'RW', 'Desa', 'Kecamatan', 'Kabupaten'] as $option) @@ -37,11 +32,15 @@
+ @php + $statusDenganSk = \App\Models\Pertanian\KelompokTani::STATUS_LEGALITAS_DENGAN_SK; + $skAktif = in_array(old('status_legalitas', $kelompokTani->status_legalitas), $statusDenganSk, true); + @endphp
Status Legalitas Kelompok
- @foreach([ 'Belum ada SK/dokumen apa pun', @@ -56,95 +55,28 @@ @error('status_legalitas')
{{ $message }}
@enderror
- + + value="{{ old('nomor_sk', $kelompokTani->nomor_sk) }}" @disabled(!$skAktif) /> @error('nomor_sk')
{{ $message }}
@enderror
+ placeholder="Cth: 12-01-2020 atau 2020" value="{{ old('tanggal_tahun_penerbitan_sk', $kelompokTani->tanggal_tahun_penerbitan_sk) }}" @disabled(!$skAktif) /> @error('tanggal_tahun_penerbitan_sk')
{{ $message }}
@enderror
-
Kualitas Kepemimpinan
-
-
- - - @error('tingkat_keaktifan_ketua')
{{ $message }}
@enderror -
-
- - - @error('status_pembagian_peran')
{{ $message }}
@enderror -
-
- - - @error('status_dokumentasi_rapat')
{{ $message }}
@enderror -
-
- -
Frekuensi Pertemuan Rutin
-
-
- - - @error('frekuensi_pertemuan')
{{ $message }}
@enderror -
-
- - - @error('tanggal_pertemuan_terakhir')
{{ $message }}
@enderror -
-
-
- +
+ + Kembali + + +
@@ -156,12 +88,15 @@ @endpush diff --git a/resources/views/produktivitas/survey-kelompok-tani/pengurus-anggota.blade.php b/resources/views/produktivitas/survey-kelompok-tani/pengurus-anggota.blade.php index dbe459f..240026e 100644 --- a/resources/views/produktivitas/survey-kelompok-tani/pengurus-anggota.blade.php +++ b/resources/views/produktivitas/survey-kelompok-tani/pengurus-anggota.blade.php @@ -1,5 +1,65 @@ -@extends('layout.main') +@if(($bagianKeanggotaan ?? 'pengurus') === 'ringkasan') +
+
Jumlah Pengurus & Anggota
+
+
+ + + @error('jumlah_pengurus')
{{ $message }}
@enderror +
+
+ + + @error('jumlah_pengurus_aktif')
{{ $message }}
@enderror +
+
+ + + @error('jumlah_anggota_terdaftar')
{{ $message }}
@enderror +
+
+ + + @error('jumlah_anggota_aktif')
{{ $message }}
@enderror +
+
+
Komposisi Gender
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+
+@else @push('style') @endpush -@section('content') -
- @include('produktivitas.survey-kelompok-tani.header', ['kelompokTani' => $kelompokTani]) - - {{-- RINGKASAN JUMLAH & KOMPOSISI GENDER --}} -
-
- @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'], - ]) - -
- @csrf - @method('PUT') - - -
Jumlah Pengurus & Anggota
-
-
- - - @error('jumlah_pengurus')
{{ $message }}
@enderror -
-
- - - @error('jumlah_pengurus_aktif')
{{ $message }}
@enderror -
-
- - - @error('jumlah_anggota_terdaftar')
{{ $message }}
@enderror -
-
- - - @error('jumlah_anggota_aktif')
{{ $message }}
@enderror -
-
- -
Komposisi Gender
-
-
- -
- - -
-
-
- -
- - -
-
-
- -
- - -
-
-
- -
- -
-
-
-
- {{-- DAFTAR PENGURUS --}}
- @include('produktivitas.survey-kelompok-tani._alert', [ - 'section' => 'pengurus', - 'errorFields' => ['pengurus.*'], - ]) -
Daftar Pengurus
{{-- DATA LAMA --}} @@ -159,7 +129,7 @@ @endif {{-- FORM TAMBAH DATA BARU --}} -
+ @csrf
@@ -200,19 +170,22 @@
-
+
- +
+ + Kembali + + +
-
-@endsection @push('scripts') @endpush +@endif diff --git a/resources/views/produktivitas/survey-kelompok-tani/sosial-konflik.blade.php b/resources/views/produktivitas/survey-kelompok-tani/sosial-konflik.blade.php index afbdb45..49873aa 100644 --- a/resources/views/produktivitas/survey-kelompok-tani/sosial-konflik.blade.php +++ b/resources/views/produktivitas/survey-kelompok-tani/sosial-konflik.blade.php @@ -1,17 +1,18 @@ @extends('layout.main') @section('content') -
+
@include('produktivitas.survey-kelompok-tani.header', ['kelompokTani' => $kelompokTani]) + @php + $pernahKonflik = in_array(old('konflik_kelompok', $kelompokTani->konflik_kelompok), [ + 'Pernah, sudah selesai', 'Pernah, masih berlanjut/belum selesai', + ], true); + @endphp +
- @include('produktivitas.survey-kelompok-tani._alert', [ - 'section' => 'sosial-konflik', - 'errorFields' => ['partisipasi_perempuan', 'konflik_kelompok', 'topik_konflik', 'penyelesaian_konflik'], - ]) - -
+ @csrf @method('PUT') @@ -20,7 +21,7 @@
- @foreach([ 'Tidak terlibat', @@ -35,13 +36,10 @@
Riwayat Konflik Internal Kelompok
-

- Topik ini cukup sensitif. Kalau responden tidak nyaman menjawab, pilih "Tidak bersedia menjawab". -

- @foreach([ 'Tidak pernah', @@ -56,11 +54,11 @@
-