update kelompok tani
This commit is contained in:
@@ -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.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 = [
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -1,37 +1,51 @@
|
||||
{{--
|
||||
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.
|
||||
@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)
|
||||
<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>
|
||||
@if($hasNotifications)
|
||||
<div id="kelompok-tani-notifications">
|
||||
@foreach($notificationTypes as $key => $type)
|
||||
@if(session()->has($key))
|
||||
<div class="alert alert-{{ $type }} alert-dismissible" role="alert">
|
||||
{{ session($key) }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Tutup"></button>
|
||||
</div>
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
@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))
|
||||
@if($errors->any())
|
||||
<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
|
||||
@foreach($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Tutup"></button>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
window.addEventListener('load', function () {
|
||||
const hasErrors = @json($errors->any() || session()->has('error'));
|
||||
if (!hasErrors && window.location.hash.startsWith('#section-')) {
|
||||
const target = document.getElementById(window.location.hash.substring(1));
|
||||
if (target && target.closest('.kelompok-tani-page') && target.getClientRects().length) {
|
||||
target.scrollIntoView({ block: 'start' });
|
||||
return;
|
||||
}
|
||||
}
|
||||
document.getElementById('kelompok-tani-notifications')?.scrollIntoView({ block: 'start' });
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
@endif
|
||||
|
||||
@@ -1,31 +1,21 @@
|
||||
@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
|
||||
|
||||
<div class="container-xxl flex-grow-1 container-p-y kelompok-tani-page">
|
||||
@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">
|
||||
<form novalidate 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"
|
||||
<input type="text" class="form-control @error('nama_responden') is-invalid @enderror" id="add-kt-nama-responden" name="nama_responden" required
|
||||
placeholder="Cth: John Doe" value="{{ old('nama_responden') }}" />
|
||||
@error('nama_responden')<div class="error invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
@@ -47,7 +37,7 @@
|
||||
<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"
|
||||
<input type="text" class="form-control @error('nama_kelompok') is-invalid @enderror" id="add-kt-nama-kelompok" name="nama_kelompok" required
|
||||
placeholder="Cth: Kelompok Tani Maju Bersama" value="{{ old('nama_kelompok') }}" />
|
||||
@error('nama_kelompok')<div class="error invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
@@ -68,38 +58,50 @@
|
||||
<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">
|
||||
<select class="form-select @error('provinsi_id') is-invalid @enderror" id="add-kt-provinsi" name="provinsi_id" required>
|
||||
<option value="">Pilih Provinsi</option>
|
||||
@foreach($provinsi as $p)
|
||||
<option value="{{ $p->id }}" {{ old('provinsi_id') == $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="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>
|
||||
<select class="form-select @error('kabupaten_id') is-invalid @enderror" id="add-kt-kabupaten" name="kabupaten_id" required @disabled(!old('provinsi_id'))>
|
||||
<option value="">Pilih Kabupaten/Kota</option>
|
||||
@foreach($kabupatenOptions ?? [] as $option)
|
||||
<option value="{{ $option->id }}" @selected(old('kabupaten_id') == $option->id)>{{ $option->nama }}</option>
|
||||
@endforeach
|
||||
</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="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>
|
||||
<select class="form-select @error('kecamatan_id') is-invalid @enderror" id="add-kt-kecamatan" name="kecamatan_id" required @disabled(!old('kabupaten_id'))>
|
||||
<option value="">Pilih Kecamatan</option>
|
||||
@foreach($kecamatanOptions ?? [] as $option)
|
||||
<option value="{{ $option->id }}" @selected(old('kecamatan_id') == $option->id)>{{ $option->nama }}</option>
|
||||
@endforeach
|
||||
</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="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>
|
||||
<select class="form-select @error('desa_kelurahan_id') is-invalid @enderror" id="add-kt-desa" name="desa_kelurahan_id" required @disabled(!old('kecamatan_id'))>
|
||||
<option value="">Pilih Desa/Kelurahan</option>
|
||||
@foreach($desaOptions ?? [] as $option)
|
||||
<option value="{{ $option->id }}" @selected(old('desa_kelurahan_id') == $option->id)>{{ $option->nama }}</option>
|
||||
@endforeach
|
||||
</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">
|
||||
<div class="col-md-6 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">
|
||||
<select class="form-select @error('jenis_kelompok') is-invalid @enderror" id="add-kt-jenis-kelompok" name="jenis_kelompok" required>
|
||||
<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>
|
||||
@@ -111,7 +113,7 @@
|
||||
@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>
|
||||
<label class="form-label" for="add-kt-jenis-kelompok-lainnya">Sebutkan Jenis Kelompok<span class="text-danger">*</span></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
|
||||
@@ -136,9 +138,17 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include('produktivitas.survey-kelompok-tani.pengurus-anggota', ['bagianKeanggotaan' => 'ringkasan', 'kelompokTani' => null])
|
||||
|
||||
<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 class="d-inline-flex flex-wrap justify-content-end gap-2">
|
||||
<a href="{{ route('kelompok-tani.index') }}" class="btn btn-secondary wave-effect wave-light">
|
||||
Kembali
|
||||
</a>
|
||||
<button type="submit" class="btn btn-success data-submit wave-effect wave-light">
|
||||
<i class="icon-base ti tabler-check me-1_5 icon-sm" aria-hidden="true"></i> Simpan
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@@ -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();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@extends('layout.main')
|
||||
|
||||
@section('content')
|
||||
<div class="container-xxl flex-grow-1 container-p-y">
|
||||
<div class="container-xxl flex-grow-1 container-p-y kelompok-tani-page">
|
||||
@include('produktivitas.survey-kelompok-tani.header', ['kelompokTani' => $kelompokTani])
|
||||
|
||||
@php
|
||||
@@ -41,18 +41,39 @@
|
||||
|
||||
<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) }}">
|
||||
<form novalidate 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;">
|
||||
<h5 class="pb-4 border-bottom mb-4">Frekuensi Pertemuan Rutin</h5>
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-4 form-control-validation">
|
||||
<label class="form-label" for="af-frekuensi-pertemuan">Frekuensi Pertemuan</label>
|
||||
<select class="form-select @error('frekuensi_pertemuan') is-invalid @enderror" id="af-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="af-tanggal-pertemuan-terakhir">Tanggal Pertemuan Terakhir</label>
|
||||
<input type="text" class="form-control @error('tanggal_pertemuan_terakhir') is-invalid @enderror" id="af-tanggal-pertemuan-terakhir" name="tanggal_pertemuan_terakhir"
|
||||
value="{{ old('tanggal_pertemuan_terakhir', $kelompokTani->tanggal_pertemuan_terakhir?->format('d-m-Y')) }}" />
|
||||
@error('tanggal_pertemuan_terakhir')<div class="error invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h5 class="pb-4 border-bottom mb-4 mt-4">Kegiatan Konkret yang Sudah Berjalan</h5>
|
||||
<p class="text-muted small kelompok-tani-help">
|
||||
Kegiatan yang sudah benar-benar dilaksanakan, bukan rencana. Boleh pilih lebih dari satu.
|
||||
</p>
|
||||
<div class="row mb-2">
|
||||
@@ -99,7 +120,7 @@
|
||||
</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">
|
||||
<select class="form-select @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>
|
||||
@@ -123,7 +144,7 @@
|
||||
</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;">
|
||||
<p class="text-muted small kelompok-tani-help">
|
||||
Fungsi yang melekat secara struktural pada kelompok ini, terlepas dari seberapa sering kegiatannya berjalan.
|
||||
</p>
|
||||
<div class="row mb-2">
|
||||
@@ -153,13 +174,20 @@
|
||||
</div>
|
||||
|
||||
<div class="mt-4 text-end">
|
||||
<div class="d-inline-flex flex-wrap justify-content-end gap-2">
|
||||
<a href="{{ route('kelompok-tani.index') }}" class="btn btn-secondary wave-effect wave-light">
|
||||
Kembali
|
||||
</a>
|
||||
<button type="submit" class="btn btn-success wave-effect wave-light">
|
||||
<i class="ti tabler-device-floppy me-2"></i> Simpan Aktivitas & Fungsi
|
||||
<i class="icon-base ti tabler-check me-1_5 icon-sm" aria-hidden="true"></i> Simpan
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@include('produktivitas.survey-kelompok-tani.aset-keuangan')
|
||||
@include('produktivitas.survey-kelompok-tani.bantuan-penilaian')
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@@ -167,6 +195,10 @@
|
||||
<script>
|
||||
'use strict';
|
||||
$(document).ready(function () {
|
||||
$('#af-frekuensi-pertemuan').select2();
|
||||
$('#af-tanggal-pertemuan-terakhir').flatpickr({
|
||||
dateFormat: 'd-m-Y'
|
||||
});
|
||||
|
||||
function toggleLainnya(checkboxSelector, wrapperSelector, textInputSelector) {
|
||||
var $checkbox = $(checkboxSelector);
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
@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');
|
||||
@@ -11,19 +5,18 @@
|
||||
|
||||
$statusPengelolaanOptions = ['Swadaya', 'Hibah', 'Pinjaman', 'Sewa'];
|
||||
$kondisiOptions = ['Berfungsi', 'Perlu perbaikan/evaluasi', 'Rusak/tidak bisa dipakai', 'Mangkrak'];
|
||||
$asetLainnyaBaru = old('aset_lainnya') ?: [[]];
|
||||
$indexKas = array_search('Kas/simpanan kelompok', $jenisAsetBaku, true);
|
||||
$memilikiKas = (bool) old("aset.$indexKas.status_aset", $asetTersimpan->get('Kas/simpanan kelompok')?->status_aset ?? false);
|
||||
@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>
|
||||
<p class="text-muted small"><span class="text-danger">*</span> Wajib diisi untuk aset yang dipilih Ada.</p>
|
||||
|
||||
<form method="POST" action="{{ route('kelompok-tani.aset-keuangan.update', $kelompokTani->id) }}">
|
||||
<form novalidate id="aset-produktif-form" method="POST" action="{{ route('kelompok-tani.aset-keuangan.update', $kelompokTani->id) }}">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
|
||||
@@ -33,43 +26,56 @@
|
||||
<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>
|
||||
<th style="min-width: 180px;">Status Pengelolaan <span class="text-danger" aria-hidden="true">*</span></th>
|
||||
<th style="min-width: 200px;">Kondisi <span class="text-danger" aria-hidden="true">*</span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($jenisAsetBaku as $index => $jenis)
|
||||
@php $row = $asetTersimpan->get($jenis); @endphp
|
||||
<tr>
|
||||
@php
|
||||
$row = $asetTersimpan->get($jenis);
|
||||
$ada = (bool) old("aset.$index.status_aset", $row?->status_aset ?? false);
|
||||
$statusPengelolaan = old("aset.$index.status_pengelolaan_aset", $row?->status_pengelolaan_aset);
|
||||
$kondisi = old("aset.$index.kondisi_aset", $row?->kondisi_aset);
|
||||
@endphp
|
||||
<tr @if($index === $indexKas) data-aset-kas @endif>
|
||||
<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' : '' }}>
|
||||
<input class="form-check-input aset-status-radio" type="radio" name="aset[{{ $index }}][status_aset]" value="1" id="aset-{{ $index }}-ada" data-row="{{ $index }}" @checked($ada)>
|
||||
<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' : '' }}>
|
||||
<input class="form-check-input aset-status-radio" type="radio" name="aset[{{ $index }}][status_aset]" value="0" id="aset-{{ $index }}-tidak" data-row="{{ $index }}" @checked(!$ada)>
|
||||
<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>
|
||||
<select class="form-select aset-detail-select @error("aset.$index.status_pengelolaan_aset") is-invalid @enderror" id="aset-{{ $index }}-status-pengelolaan" name="aset[{{ $index }}][status_pengelolaan_aset]" aria-label="Status Pengelolaan {{ $jenis }}" @disabled(!$ada) @required($ada)
|
||||
@error("aset.$index.status_pengelolaan_aset") aria-invalid="true" aria-describedby="aset-{{ $index }}-status-pengelolaan-error" @enderror>
|
||||
<option value="">Pilih status pengelola</option>
|
||||
@foreach($statusPengelolaanOptions as $option)
|
||||
<option value="{{ $option }}" {{ $row?->status_pengelolaan_aset == $option ? 'selected' : '' }}>{{ $option }}</option>
|
||||
<option value="{{ $option }}" @selected($statusPengelolaan == $option)>{{ $option }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<div class="invalid-feedback" id="aset-{{ $index }}-status-pengelolaan-error" role="alert">
|
||||
@error("aset.$index.status_pengelolaan_aset") {{ $message }} @else Status Pengelolaan wajib diisi jika aset dipilih Ada. @enderror
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-select form-select-sm aset-detail-select" name="aset[{{ $index }}][kondisi_aset]" {{ !$row?->status_aset ? 'disabled' : '' }}>
|
||||
<option value="">-</option>
|
||||
<select class="form-select aset-detail-select @error("aset.$index.kondisi_aset") is-invalid @enderror" id="aset-{{ $index }}-kondisi" name="aset[{{ $index }}][kondisi_aset]" aria-label="Kondisi {{ $jenis }}" @disabled(!$ada) @required($ada)
|
||||
@error("aset.$index.kondisi_aset") aria-invalid="true" aria-describedby="aset-{{ $index }}-kondisi-error" @enderror>
|
||||
<option value="">Pilih kondisi</option>
|
||||
@foreach($kondisiOptions as $option)
|
||||
<option value="{{ $option }}" {{ $row?->kondisi_aset == $option ? 'selected' : '' }}>{{ $option }}</option>
|
||||
<option value="{{ $option }}" @selected($kondisi == $option)>{{ $option }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<div class="invalid-feedback" id="aset-{{ $index }}-kondisi-error" role="alert">
|
||||
@error("aset.$index.kondisi_aset") {{ $message }} @else Kondisi wajib diisi jika aset dipilih Ada. @enderror
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
@@ -77,24 +83,8 @@
|
||||
</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>
|
||||
<div id="section-aset-lainnya" class="mt-4">
|
||||
<h6 class="pb-3 border-bottom mb-4">Aset Lainnya</h6>
|
||||
|
||||
{{-- DATA LAMA --}}
|
||||
@if($asetLainnyaList->isNotEmpty())
|
||||
@@ -113,13 +103,9 @@
|
||||
<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">
|
||||
<button type="submit" form="delete-aset-{{ $row->id }}" class="btn btn-outline-danger" aria-label="Hapus aset {{ $row->jenis_aset }}">
|
||||
<i class="icon-base ti tabler-trash icon-sm"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
@@ -135,31 +121,30 @@
|
||||
|
||||
{{-- 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 class="form-repeater-aset-lainnya">
|
||||
<div data-repeater-list="aset_lainnya">
|
||||
@foreach($asetLainnyaBaru as $index => $item)
|
||||
<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">
|
||||
<input type="text" class="form-control aset-lainnya-input" name="jenis_aset" placeholder="Contoh: Mesin pengering" value="{{ $item['jenis_aset'] ?? '' }}">
|
||||
</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>
|
||||
<option value="">Pilih status pengelola</option>
|
||||
@foreach($statusPengelolaanOptions as $option)
|
||||
<option value="{{ $option }}">{{ $option }}</option>
|
||||
<option value="{{ $option }}" @selected(($item['status_pengelolaan_aset'] ?? '') == $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>
|
||||
<option value="">Pilih kondisi</option>
|
||||
@foreach($kondisiOptions as $option)
|
||||
<option value="{{ $option }}">{{ $option }}</option>
|
||||
<option value="{{ $option }}" @selected(($item['kondisi_aset'] ?? '') == $option)>{{ $option }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
@@ -171,35 +156,48 @@
|
||||
</div>
|
||||
<hr>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div class="mt-4 d-flex justify-content-between">
|
||||
<div class="mt-4 d-flex flex-wrap justify-content-between gap-2">
|
||||
<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
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 text-end">
|
||||
<div class="d-inline-flex flex-wrap justify-content-end gap-2">
|
||||
<a href="{{ route('kelompok-tani.index') }}" class="btn btn-secondary wave-effect wave-light">
|
||||
Kembali
|
||||
</a>
|
||||
<button type="submit" class="btn btn-success wave-effect wave-light">
|
||||
<i class="icon-base ti tabler-check me-1_5 icon-sm" aria-hidden="true"></i> Simpan
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@foreach($asetLainnyaList as $row)
|
||||
<form id="delete-aset-{{ $row->id }}" method="POST" action="{{ route('kelompok-tani.aset-keuangan.destroy', [$kelompokTani->id, $row->id]) }}" class="delete-db-form" hidden>
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
</form>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- KAS / SIMPAN-PINJAM --}}
|
||||
<div class="card mb-6" id="section-kas">
|
||||
<div class="card mb-6" id="section-kas" @if(!$memilikiKas) hidden @endif>
|
||||
<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;">
|
||||
<p class="text-muted small kelompok-tani-help">
|
||||
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) }}">
|
||||
<form novalidate method="POST" action="{{ route('kelompok-tani.update', $kelompokTani->id) }}">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
<input type="hidden" name="section" value="kas">
|
||||
@@ -207,7 +205,7 @@
|
||||
<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">
|
||||
<select class="form-select @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',
|
||||
@@ -227,7 +225,7 @@
|
||||
</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">
|
||||
<select class="form-select @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',
|
||||
@@ -250,20 +248,51 @@
|
||||
</div>
|
||||
|
||||
<div class="text-end">
|
||||
<div class="d-inline-flex flex-wrap justify-content-end gap-2">
|
||||
<a href="{{ route('kelompok-tani.index') }}" class="btn btn-secondary wave-effect wave-light">
|
||||
Kembali
|
||||
</a>
|
||||
<button type="submit" class="btn btn-success wave-effect wave-light">
|
||||
<i class="ti tabler-device-floppy me-2"></i> Simpan Kas/Simpan-Pinjam
|
||||
<i class="icon-base ti tabler-check me-1_5 icon-sm" aria-hidden="true"></i> Simpan
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
'use strict';
|
||||
$(document).ready(function () {
|
||||
var assetForm = document.getElementById('aset-produktif-form');
|
||||
assetForm.addEventListener('invalid', function (event) {
|
||||
if (!event.target.matches('.aset-detail-select')) return;
|
||||
|
||||
event.preventDefault();
|
||||
var field = event.target;
|
||||
$(field).addClass('is-invalid').attr({
|
||||
'aria-invalid': 'true',
|
||||
'aria-describedby': field.id + '-error'
|
||||
});
|
||||
if (field === assetForm.querySelector('.aset-detail-select:invalid')) {
|
||||
field.focus();
|
||||
}
|
||||
}, true);
|
||||
|
||||
$('.aset-detail-select').on('change', function () {
|
||||
if (this.validity.valid) {
|
||||
$(this).removeClass('is-invalid').removeAttr('aria-invalid aria-describedby');
|
||||
}
|
||||
});
|
||||
|
||||
function toggleKasSection() {
|
||||
var memilikiKas = $('[data-aset-kas] .aset-status-radio[value="1"]').is(':checked');
|
||||
$('#section-kas').prop('hidden', !memilikiKas);
|
||||
}
|
||||
toggleKasSection();
|
||||
$('[data-aset-kas] .aset-status-radio').on('change', toggleKasSection);
|
||||
|
||||
function toggleDeskripsiMasalah() {
|
||||
var val = $('#ak-masalah-kas').val();
|
||||
$('#ak-deskripsi-masalah-wrapper').toggle(val === 'Pernah, sudah selesai' || val === 'Pernah, masih berlanjut/belum selesai');
|
||||
@@ -277,9 +306,9 @@
|
||||
var $row = $(this).closest('tr');
|
||||
var ada = $(this).val() === '1';
|
||||
|
||||
$row.find('.aset-detail-select').prop('disabled', !ada);
|
||||
$row.find('.aset-detail-select').prop({ disabled: !ada, required: ada });
|
||||
if (!ada) {
|
||||
$row.find('.aset-detail-select').val('');
|
||||
$row.find('.aset-detail-select').val('').removeClass('is-invalid').removeAttr('aria-invalid aria-describedby');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -298,7 +327,7 @@
|
||||
}
|
||||
|
||||
function rowAdaIsi($row) {
|
||||
return String($row.find('input[name="jenis_aset"]').val() || '').trim() !== '';
|
||||
return String($row.find('.aset-lainnya-input').val() || '').trim() !== '';
|
||||
}
|
||||
|
||||
function updateButtons() {
|
||||
@@ -346,10 +375,10 @@
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('input keyup change', '.form-repeater-aset-lainnya input[name="jenis_aset"]', updateButtons);
|
||||
$(document).on('input keyup change', '.form-repeater-aset-lainnya .aset-lainnya-input', updateButtons);
|
||||
updateButtons();
|
||||
|
||||
$(document).on('submit', '.delete-db-form', function (e) {
|
||||
$(document).on('submit', '#section-aset-baku .delete-db-form', function (e) {
|
||||
e.preventDefault();
|
||||
var form = this;
|
||||
|
||||
|
||||
@@ -1,121 +1,97 @@
|
||||
@extends('layout.main')
|
||||
@php
|
||||
$pernahBantuan = old('pernah_mendapatkan_bantuan', $kelompokTani->pernah_mendapatkan_bantuan);
|
||||
$tampilkanBantuan = (bool) $pernahBantuan;
|
||||
$hasSavedAid = $kelompokTani->bantuan->contains(fn ($bantuan) => filled($bantuan->nama_program));
|
||||
$requireFirstRow = $tampilkanBantuan && !$hasSavedAid;
|
||||
$bantuanBaru = old('bantuan') ?: [[]];
|
||||
$bantuanBaru = is_array($bantuanBaru) ? $bantuanBaru : [[]];
|
||||
@endphp
|
||||
|
||||
@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) }}">
|
||||
<form novalidate id="pengalaman-bantuan-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
|
||||
<label class="form-label d-block">Apakah kelompok ini pernah mendapatkan bantuan atau akses program dari pemerintah/lembaga lain?<span class="text-danger">*</span></label>
|
||||
<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' : '' }}>
|
||||
<input class="form-check-input @error('pernah_mendapatkan_bantuan') is-invalid @enderror" type="radio" name="pernah_mendapatkan_bantuan" value="1" id="sb-pernah" @checked($tampilkanBantuan) required>
|
||||
<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' : '' }}>
|
||||
<input class="form-check-input @error('pernah_mendapatkan_bantuan') is-invalid @enderror" type="radio" name="pernah_mendapatkan_bantuan" value="0" id="sb-belum" @checked(!is_null($pernahBantuan) && !$tampilkanBantuan) required>
|
||||
<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>
|
||||
<div id="section-bantuan" @if(!$tampilkanBantuan) hidden @endif>
|
||||
<h6 class="pb-3 border-bottom mb-4">Daftar Program/Bantuan yang Pernah Diterima</h6>
|
||||
<p class="text-muted small mb-4">Minimal satu data bantuan wajib diisi.</p>
|
||||
|
||||
{{-- 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)
|
||||
@forelse($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>
|
||||
<label class="form-label">Nama Program/Bantuan @if($loop->first)<span class="text-danger bantuan-saved-required-mark" aria-hidden="true">*</span>@endif</label>
|
||||
<input type="text" class="form-control" value="{{ $row->nama_program }}" disabled>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label">Penyelenggara</label>
|
||||
<label class="form-label">Penyelenggara @if($loop->first)<span class="text-danger bantuan-saved-required-mark" aria-hidden="true">*</span>@endif</label>
|
||||
<input type="text" class="form-control" value="{{ $row->penyelenggara }}" disabled>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label">Bentuk Bantuan</label>
|
||||
<label class="form-label">Bentuk Bantuan @if($loop->first)<span class="text-danger bantuan-saved-required-mark" aria-hidden="true">*</span>@endif</label>
|
||||
<input type="text" class="form-control" value="{{ $row->bentuk_bantuan }}" disabled>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label">Tahun</label>
|
||||
<label class="form-label">Tahun @if($loop->first)<span class="text-danger bantuan-saved-required-mark" aria-hidden="true">*</span>@endif</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">
|
||||
<button type="submit" form="delete-bantuan-{{ $row->id }}" class="btn btn-outline-danger" aria-label="Hapus bantuan {{ $row->nama_program }}">
|
||||
<i class="icon-base ti tabler-trash icon-sm"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
@else
|
||||
@empty
|
||||
<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
|
||||
@endforelse
|
||||
|
||||
<fieldset id="bantuan-fields" @disabled(!$tampilkanBantuan)>
|
||||
<div class="form-repeater-bantuan" data-has-saved-bantuan="{{ $hasSavedAid ? '1' : '0' }}">
|
||||
<div data-repeater-list="bantuan">
|
||||
@foreach($bantuanBaru as $index => $item)
|
||||
@php
|
||||
$item = is_array($item) ? $item : [];
|
||||
$required = $loop->first && $requireFirstRow;
|
||||
@endphp
|
||||
<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">
|
||||
<label class="form-label">Nama Program/Bantuan <span class="text-danger bantuan-required-mark" @if(!$required) hidden @endif>*</span></label>
|
||||
<input type="text" class="form-control bantuan-input @error("bantuan.$index.nama_program") is-invalid @enderror" name="nama_program" placeholder="Contoh: Bantuan Bibit Kakao" value="{{ $item['nama_program'] ?? '' }}" @required($required)>
|
||||
@error("bantuan.$index.nama_program")<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</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">
|
||||
<label class="form-label">Penyelenggara <span class="text-danger bantuan-required-mark" @if(!$required) hidden @endif>*</span></label>
|
||||
<input type="text" class="form-control bantuan-input @error("bantuan.$index.penyelenggara") is-invalid @enderror" name="penyelenggara" placeholder="Contoh: Dinas Pertanian" value="{{ $item['penyelenggara'] ?? '' }}" @required($required)>
|
||||
@error("bantuan.$index.penyelenggara")<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</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">
|
||||
<label class="form-label">Bentuk Bantuan <span class="text-danger bantuan-required-mark" @if(!$required) hidden @endif>*</span></label>
|
||||
<input type="text" class="form-control bantuan-input @error("bantuan.$index.bentuk_bantuan") is-invalid @enderror" name="bentuk_bantuan" placeholder="Contoh: Bibit, pupuk, pelatihan" value="{{ $item['bentuk_bantuan'] ?? '' }}" @required($required)>
|
||||
@error("bantuan.$index.bentuk_bantuan")<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</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') }}">
|
||||
<label class="form-label">Tahun <span class="text-danger bantuan-required-mark" @if(!$required) hidden @endif>*</span></label>
|
||||
<input type="number" class="form-control bantuan-year-input @error("bantuan.$index.tahun") is-invalid @enderror" name="tahun" placeholder="Contoh: 2023" min="1900" max="{{ date('Y') }}" value="{{ $item['tahun'] ?? '' }}" @required($required)>
|
||||
@error("bantuan.$index.tahun")<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
<div class="col-md-1 mb-3">
|
||||
<button type="button" class="btn btn-outline-danger btn-delete-bantuan" data-repeater-delete disabled>
|
||||
@@ -125,129 +101,90 @@
|
||||
</div>
|
||||
<hr>
|
||||
</div>
|
||||
@endforeach
|
||||
</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>
|
||||
</fieldset>
|
||||
</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">
|
||||
<div class="mt-4 text-end">
|
||||
<div class="d-inline-flex flex-wrap justify-content-end gap-2">
|
||||
<a href="{{ route('kelompok-tani.index') }}" class="btn btn-secondary wave-effect wave-light">
|
||||
Kembali
|
||||
</a>
|
||||
<button type="submit" class="btn btn-success wave-effect wave-light">
|
||||
<i class="ti tabler-device-floppy me-2"></i> Simpan Penilaian
|
||||
<i class="icon-base ti tabler-check me-1_5 icon-sm" aria-hidden="true"></i> Simpan
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@foreach($kelompokTani->bantuan as $row)
|
||||
<form id="delete-bantuan-{{ $row->id }}" method="POST" action="{{ route('kelompok-tani.bantuan-penilaian.destroy', [$kelompokTani->id, $row->id]) }}" class="delete-db-form" hidden>
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
</form>
|
||||
@endforeach
|
||||
</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);
|
||||
$('#section-bantuan').prop('hidden', !pernah);
|
||||
$('#bantuan-fields').prop('disabled', !pernah);
|
||||
updateButtons();
|
||||
}
|
||||
toggleDaftarBantuan();
|
||||
$('#sb-pernah, #sb-belum').on('change', toggleDaftarBantuan);
|
||||
|
||||
var $form = $('.form-repeater-bantuan');
|
||||
var $repeater = $('.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 $row.find('.bantuan-input, .bantuan-year-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 $row.find('.bantuan-input, .bantuan-year-input[required]').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));
|
||||
var $rows = $repeater.find('[data-repeater-item]');
|
||||
var needsFirst = $('#sb-pernah').is(':checked') && $repeater.attr('data-has-saved-bantuan') !== '1';
|
||||
$rows.each(function (index) {
|
||||
var required = needsFirst && index === 0;
|
||||
$(this).find('.bantuan-input, .bantuan-year-input').prop('required', required);
|
||||
$(this).find('.bantuan-required-mark').prop('hidden', !required);
|
||||
$(this).find('.btn-delete-bantuan').prop('disabled', $rows.length === 1 && (required || !rowAdaIsi($(this))));
|
||||
});
|
||||
|
||||
$btnTambah.prop('disabled', !rowLengkap($lastRow));
|
||||
$btnTambah.prop('disabled', !rowLengkap($rows.last()));
|
||||
}
|
||||
|
||||
$form.repeater({
|
||||
$repeater.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);
|
||||
$(this).find('.bantuan-input, .bantuan-year-input').val('');
|
||||
$(this).find('.is-invalid').removeClass('is-invalid');
|
||||
$(this).find('.invalid-feedback').remove();
|
||||
$(this).slideDown();
|
||||
updateButtons();
|
||||
},
|
||||
hide: function (deleteElement) {
|
||||
var $row = $(this);
|
||||
if (!rowAdaIsi($row)) {
|
||||
deleteElement();
|
||||
updateButtons();
|
||||
return;
|
||||
}
|
||||
Swal.fire({
|
||||
@@ -261,22 +198,20 @@ $(function () {
|
||||
buttonsStyling: false
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
$row.slideUp(deleteElement);
|
||||
setTimeout(updateButtons, 300);
|
||||
$row.slideUp(function () { deleteElement(); updateButtons(); });
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
$(document).on('input change', '.form-repeater-bantuan .bantuan-input, .form-repeater-bantuan .bantuan-year-input', updateButtons);
|
||||
toggleDaftarBantuan();
|
||||
$('#sb-pernah, #sb-belum').on('change', toggleDaftarBantuan);
|
||||
|
||||
$(document).on('input keyup change', '.form-repeater-bantuan .bantuan-input', updateButtons);
|
||||
updateButtons();
|
||||
|
||||
$(document).on('submit', '.delete-db-form', function (e) {
|
||||
e.preventDefault();
|
||||
$(document).on('submit', '#section-status-bantuan .delete-db-form', function (event) {
|
||||
event.preventDefault();
|
||||
var form = this;
|
||||
|
||||
Swal.fire({
|
||||
title: 'Hapus data ini?',
|
||||
title: 'Hapus data bantuan ini?',
|
||||
text: 'Data yang sudah dihapus tidak bisa dikembalikan.',
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
@@ -285,9 +220,7 @@ $(function () {
|
||||
customClass: { confirmButton: 'btn btn-danger me-3', cancelButton: 'btn btn-label-secondary' },
|
||||
buttonsStyling: false
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
form.submit();
|
||||
}
|
||||
if (result.isConfirmed) form.submit();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,19 +1,14 @@
|
||||
@extends('layout.main')
|
||||
|
||||
@section('content')
|
||||
<div class="container-xxl flex-grow-1 container-p-y">
|
||||
<div class="container-xxl flex-grow-1 container-p-y kelompok-tani-page">
|
||||
@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">
|
||||
<form novalidate id="editKelompokTaniForm" action="{{ route('kelompok-tani.update', $kelompokTani->id) }}" method="POST">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
|
||||
@@ -21,7 +16,7 @@
|
||||
<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"
|
||||
<input type="text" class="form-control @error('nama_responden') is-invalid @enderror" id="edit-kt-nama-responden" name="nama_responden" required
|
||||
placeholder="Cth: John Doe" value="{{ old('nama_responden', $kelompokTani->nama_responden) }}" />
|
||||
@error('nama_responden')<div class="error invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
@@ -43,7 +38,7 @@
|
||||
<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"
|
||||
<input type="text" class="form-control @error('nama_kelompok') is-invalid @enderror" id="edit-kt-nama-kelompok" name="nama_kelompok" required
|
||||
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>
|
||||
@@ -64,45 +59,48 @@
|
||||
<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">
|
||||
<select class="form-select @error('provinsi_id') is-invalid @enderror" id="edit-kt-provinsi" name="provinsi_id" required>
|
||||
<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>
|
||||
@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="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">
|
||||
<select class="form-select @error('kabupaten_id') is-invalid @enderror" id="edit-kt-kabupaten" name="kabupaten_id" required>
|
||||
<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
|
||||
@foreach($kabupatenOptions ?? [] as $option)
|
||||
<option value="{{ $option->id }}" @selected(old('kabupaten_id', $kelompokTani->desaKelurahan?->kecamatan?->kabupaten_kota_id) == $option->id)>{{ $option->nama }}</option>
|
||||
@endforeach
|
||||
</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="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">
|
||||
<select class="form-select @error('kecamatan_id') is-invalid @enderror" id="edit-kt-kecamatan" name="kecamatan_id" required>
|
||||
<option value="">Pilih Kecamatan</option>
|
||||
@if($kelompokTani->desaKelurahan?->kecamatan)
|
||||
<option value="{{ $kelompokTani->desaKelurahan->kecamatan->id }}" selected>{{ $kelompokTani->desaKelurahan->kecamatan->nama }}</option>
|
||||
@endif
|
||||
@foreach($kecamatanOptions ?? [] as $option)
|
||||
<option value="{{ $option->id }}" @selected(old('kecamatan_id', $kelompokTani->desaKelurahan?->kecamatan_id) == $option->id)>{{ $option->nama }}</option>
|
||||
@endforeach
|
||||
</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="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">
|
||||
<select class="form-select @error('desa_kelurahan_id') is-invalid @enderror" id="edit-kt-desa" name="desa_kelurahan_id" required>
|
||||
<option value="">Pilih Desa/Kelurahan</option>
|
||||
@if($kelompokTani->desaKelurahan)
|
||||
<option value="{{ $kelompokTani->desaKelurahan->id }}" selected>{{ $kelompokTani->desaKelurahan->nama }}</option>
|
||||
@endif
|
||||
@foreach($desaOptions ?? [] as $option)
|
||||
<option value="{{ $option->id }}" @selected(old('desa_kelurahan_id', $kelompokTani->desa_kelurahan_id) == $option->id)>{{ $option->nama }}</option>
|
||||
@endforeach
|
||||
</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">
|
||||
<div class="col-md-6 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 = [
|
||||
@@ -115,7 +113,7 @@
|
||||
$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">
|
||||
<select class="form-select @error('jenis_kelompok') is-invalid @enderror" id="edit-kt-jenis-kelompok" name="jenis_kelompok" required>
|
||||
<option value="">Pilih Jenis Kelompok</option>
|
||||
@foreach($jenisKelompokOptions as $option)
|
||||
<option value="{{ $option }}" {{ $currentJenisKelompok == $option ? 'selected' : '' }}>{{ $option }}</option>
|
||||
@@ -125,7 +123,7 @@
|
||||
@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>
|
||||
<label class="form-label" for="edit-kt-jenis-kelompok-lainnya">Sebutkan Jenis Kelompok<span class="text-danger">*</span></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
|
||||
@@ -150,15 +148,24 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include('produktivitas.survey-kelompok-tani.pengurus-anggota', ['bagianKeanggotaan' => 'ringkasan'])
|
||||
|
||||
<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 class="d-inline-flex flex-wrap justify-content-end gap-2">
|
||||
<a href="{{ route('kelompok-tani.index') }}" class="btn btn-secondary wave-effect wave-light">
|
||||
Kembali
|
||||
</a>
|
||||
<button type="submit" class="btn btn-success data-submit wave-effect wave-light">
|
||||
<i class="icon-base ti tabler-check me-1_5 icon-sm" aria-hidden="true"></i> Simpan
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@include('produktivitas.survey-kelompok-tani.pengurus-anggota')
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@@ -171,6 +178,7 @@
|
||||
|
||||
function toggleJenisKelompokFields() {
|
||||
var jenisKelompok = $('#edit-kt-jenis-kelompok').val();
|
||||
$('#edit-kt-jenis-kelompok-lainnya').prop('required', jenisKelompok === 'Lainnya').prop('disabled', jenisKelompok !== 'Lainnya');
|
||||
|
||||
if (jenisKelompok === 'Lainnya') {
|
||||
$('#edit-kt-jenis-kelompok-lainnya-wrapper').show();
|
||||
@@ -247,52 +255,6 @@
|
||||
});
|
||||
|
||||
$('#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
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
@include('produktivitas.survey-kelompok-tani._alert')
|
||||
|
||||
<style>
|
||||
@media (min-width: 768px) {
|
||||
.nav-pills-custom-spacing {
|
||||
@@ -25,7 +27,7 @@
|
||||
padding-right: 0.5rem !important;
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
font-size: 0.9375rem !important;
|
||||
font-size: var(--bs-body-font-size) !important;
|
||||
}
|
||||
|
||||
.nav-pills-custom-spacing .nav-link i {
|
||||
@@ -45,18 +47,19 @@
|
||||
: null;
|
||||
@endphp
|
||||
|
||||
<div class="card mb-6">
|
||||
<div class="card mb-6" id="kelompok-tani-summary">
|
||||
<div class="card-body p-3">
|
||||
<div class="d-flex justify-content-start align-items-center flex-wrap row-gap-2">
|
||||
<div class="row align-items-center gy-3">
|
||||
<div class="{{ isset($kelompokTani) ? 'col-lg-8' : 'col-12' }} d-flex align-items-center">
|
||||
<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' }}
|
||||
<div class="d-flex flex-column text-break" style="min-width: 0;">
|
||||
<h6 class="mb-0 kelompok-tani-summary-name">{{ isset($kelompokTani) ? $kelompokTani->nama_kelompok : 'Tambah Kelompok Tani Baru' }}</h6>
|
||||
<span class="text-muted kelompok-tani-summary-note">
|
||||
{{ $lokasiKelompok ?: 'Lengkapi profil untuk memulai' }}
|
||||
</span>
|
||||
@if(isset($kelompokTani) && ($kelompokTani->jenis_kelompok || $namaKomoditas->isNotEmpty() || $kelompokTani->nama_gapoktan))
|
||||
<div class="d-flex flex-wrap gap-1 mt-2">
|
||||
@@ -73,6 +76,25 @@
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@if(isset($kelompokTani))
|
||||
<div class="col-lg-4">
|
||||
<p class="mb-2 fw-medium">Jumlah Pengurus & Anggota</p>
|
||||
<div class="row g-2">
|
||||
@foreach([
|
||||
'jumlah_pengurus' => 'Total Pengurus',
|
||||
'jumlah_anggota_terdaftar' => 'Total Anggota',
|
||||
] as $field => $label)
|
||||
<div class="col-6">
|
||||
<div class="border rounded p-2 h-100">
|
||||
<p class="mb-1 text-muted kelompok-tani-summary-note">{{ $label }}</p>
|
||||
<h5 class="mb-0">{{ $kelompokTani->{$field} !== null ? number_format($kelompokTani->{$field}, 0, ',', '.') : '-' }}</h5>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@if(isset($kelompokTani))
|
||||
<hr class="my-3">
|
||||
@@ -84,8 +106,8 @@
|
||||
</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>
|
||||
<p class="mb-0 text-muted kelompok-tani-summary-note">Nama Responden</p>
|
||||
<span class="fw-medium small">{{ $kelompokTani->nama_responden ?: '-' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6 col-lg-3 d-flex align-items-center">
|
||||
@@ -95,8 +117,8 @@
|
||||
</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>
|
||||
<p class="mb-0 text-muted kelompok-tani-summary-note">Jabatan Responden</p>
|
||||
<span class="fw-medium small">{{ $kelompokTani->jabatan_responden ?: '-' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6 col-lg-3 d-flex align-items-center">
|
||||
@@ -106,8 +128,8 @@
|
||||
</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>
|
||||
<p class="mb-0 text-muted kelompok-tani-summary-note">Kontak Responden</p>
|
||||
<span class="fw-medium small">{{ $kelompokTani->kontak_responden ?: '-' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6 col-lg-3 d-flex align-items-center">
|
||||
@@ -117,8 +139,8 @@
|
||||
</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>
|
||||
<p class="mb-0 text-muted kelompok-tani-summary-note">Tahun Berdiri</p>
|
||||
<span class="fw-medium small">{{ $kelompokTani->tahun_berdiri ?: '-' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -131,22 +153,9 @@
|
||||
<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
|
||||
<i class="icon-base ti tabler-user-check me-1_5 icon-sm"></i>Profil
|
||||
</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' : '' }}"
|
||||
@@ -155,7 +164,7 @@
|
||||
</a>
|
||||
@else
|
||||
<a class="nav-link" href="#" data-bs-toggle="tooltip" data-bs-placement="top"
|
||||
data-bs-original-title="Simpan Identitas & Responden terlebih dahulu">
|
||||
data-bs-original-title="Simpan Profil terlebih dahulu">
|
||||
<i class="icon-base ti tabler-building-community me-1_5 icon-sm"></i>Kelembagaan
|
||||
</a>
|
||||
@endif
|
||||
@@ -164,25 +173,12 @@
|
||||
@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
|
||||
<i class="icon-base ti tabler-clipboard-list me-1_5 icon-sm"></i>Operasional
|
||||
</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
|
||||
data-bs-original-title="Simpan Profil terlebih dahulu">
|
||||
<i class="icon-base ti tabler-clipboard-list me-1_5 icon-sm"></i>Operasional
|
||||
</a>
|
||||
@endif
|
||||
</li>
|
||||
@@ -190,25 +186,12 @@
|
||||
@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
|
||||
<i class="icon-base ti tabler-heart-handshake me-1_5 icon-sm"></i>Sosial
|
||||
</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
|
||||
data-bs-original-title="Simpan Profil terlebih dahulu">
|
||||
<i class="icon-base ti tabler-heart-handshake me-1_5 icon-sm"></i>Sosial
|
||||
</a>
|
||||
@endif
|
||||
</li>
|
||||
|
||||
@@ -1,29 +1,179 @@
|
||||
@extends('layout.main')
|
||||
|
||||
|
||||
@push('style')
|
||||
<style>
|
||||
.kelompok-tani-row { cursor: pointer; }
|
||||
.kelompok-filter-row { padding-block: 1.5rem; }
|
||||
.kelompok-filter-line { display: flex; align-items: center; flex-wrap: wrap; gap: .5rem; }
|
||||
.kelompok-filter-label { display: flex; align-items: center; font-weight: 500; margin-right: .5rem; white-space: nowrap; }
|
||||
.kelompok-filter-line .form-select,
|
||||
.kelompok-filter-line .btn { min-height: 31px; }
|
||||
.kelompok-filter-line .form-select {
|
||||
background-color: var(--bs-paper-bg);
|
||||
border-color: var(--bs-border-color);
|
||||
border-radius: var(--bs-border-radius);
|
||||
color: var(--bs-body-color);
|
||||
}
|
||||
.kelompok-filter-line .form-select:focus {
|
||||
border-color: rgba(40, 167, 69, .55);
|
||||
box-shadow: 0 0 0 .2rem rgba(40, 167, 69, .12);
|
||||
}
|
||||
.kelompok-filter-line .btn { white-space: nowrap; }
|
||||
.kelompok-filter-static {
|
||||
display: flex; align-items: center; min-height: 31px;
|
||||
padding: .25rem .75rem; font-size: .8125rem;
|
||||
background-color: var(--bs-paper-bg);
|
||||
border: 1px solid var(--bs-border-color);
|
||||
border-radius: var(--bs-border-radius);
|
||||
color: var(--bs-body-color);
|
||||
}
|
||||
.kelompok-filter-line .input-group-sm { width: 240px; }
|
||||
@media (max-width: 767.98px) {
|
||||
.kelompok-filter-line { display: grid; grid-template-columns: minmax(0, 1fr); width: 100%; }
|
||||
.kelompok-filter-label { margin-right: 0; }
|
||||
.kelompok-filter-line .btn { justify-content: center; width: 100%; }
|
||||
.kelompok-filter-line .input-group-sm { width: 100%; }
|
||||
.kelompok-filter-line .input-group .btn { width: auto; }
|
||||
}
|
||||
</style>
|
||||
@endpush
|
||||
|
||||
@section('content')
|
||||
<div class="container-xxl flex-grow-1 container-p-y">
|
||||
<div class="container-fluid flex-grow-1 container-p-y kelompok-tani-page">
|
||||
@include('produktivitas.survey-kelompok-tani._alert')
|
||||
|
||||
<div class="row g-3 mb-4">
|
||||
<div class="col-12 col-md-4">
|
||||
<x-summary-card
|
||||
title="Kelompok Tani"
|
||||
count="{{ number_format($summary->total_kelompok, 0, ',', '.') }}"
|
||||
subtitle="{{ number_format($summary->total_jenis, 0, ',', '.') }} jenis kelompok"
|
||||
icon="users-group"
|
||||
color="primary"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 col-md-4">
|
||||
<x-summary-card
|
||||
title="Total Pengurus"
|
||||
count="{{ number_format($summary->total_pengurus, 0, ',', '.') }}"
|
||||
subtitle="{{ number_format($summary->pengurus_aktif, 0, ',', '.') }} pengurus aktif"
|
||||
icon="user-star"
|
||||
color="success"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 col-md-4">
|
||||
<x-summary-card
|
||||
title="Total Anggota"
|
||||
count="{{ number_format($summary->total_anggota, 0, ',', '.') }}"
|
||||
subtitle="{{ number_format($summary->anggota_aktif, 0, ',', '.') }} anggota aktif"
|
||||
icon="users"
|
||||
color="info"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-6 kelompok-filter-row">
|
||||
<div class="col-12">
|
||||
<div class="card card-border-shadow-primary">
|
||||
<div class="card-body py-3">
|
||||
<form method="GET" action="{{ route('kelompok-tani.index') }}" id="kelompok-filter-form" aria-label="Filter data kelompok tani">
|
||||
<input type="hidden" name="per_page" value="{{ $kelompokTani->perPage() }}">
|
||||
<div class="kelompok-filter-line">
|
||||
<div class="kelompok-filter-label">
|
||||
<i class="icon-base ti tabler-map-2 me-2"></i><span>Wilayah</span>
|
||||
</div>
|
||||
<div>
|
||||
<input type="hidden" name="kabupaten_kota_id" value="{{ $filters['kabupaten_kota_id'] }}">
|
||||
<div class="kelompok-filter-static" aria-label="Kabupaten/Kota" role="text">
|
||||
{{ preg_replace('/^(kabupaten|kota)\s+/i', '', $selectedKabupaten?->nama ?? 'Semua Kabupaten/Kota') }}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<select name="kecamatan_id" id="filter-kecamatan" class="form-select form-select-sm" aria-label="Filter Kecamatan" @disabled(empty($filters['kabupaten_kota_id']))>
|
||||
<option value="">Semua Kecamatan</option>
|
||||
@foreach($kecamatanOptions as $option)
|
||||
<option value="{{ $option->id }}" @selected((string) $filters['kecamatan_id'] === (string) $option->id)>{{ $option->nama }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<select name="desa_kelurahan_id" id="filter-desa" class="form-select form-select-sm" aria-label="Filter Desa" @disabled(empty($filters['kecamatan_id']))>
|
||||
<option value="">Semua Desa</option>
|
||||
@foreach($desaOptions as $option)
|
||||
<option value="{{ $option->id }}" @selected((string) $filters['desa_kelurahan_id'] === (string) $option->id)>{{ $option->nama }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="my-3">
|
||||
|
||||
<div class="kelompok-filter-line">
|
||||
<div class="kelompok-filter-label">
|
||||
<i class="icon-base ti tabler-adjustments-horizontal me-2"></i><span>Data</span>
|
||||
</div>
|
||||
<div>
|
||||
<select name="komoditas_id" class="form-select form-select-sm" aria-label="Filter Komoditas">
|
||||
<option value="">Semua Komoditas</option>
|
||||
@foreach($komoditasOptions as $option)
|
||||
<option value="{{ $option->id }}" @selected((string) $filters['komoditas_id'] === (string) $option->id)>{{ $option->nama }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<select name="jenis_kelompok" class="form-select form-select-sm" aria-label="Filter Jenis Kelompok">
|
||||
<option value="">Semua Jenis Kelompok</option>
|
||||
@foreach($jenisKelompokOptions as $jenis)
|
||||
<option value="{{ $jenis }}" @selected($filters['jenis_kelompok'] === $jenis)>{{ $jenis }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<select name="sort_by" class="form-select form-select-sm" aria-label="Urutkan data kelompok tani">
|
||||
<option value="">Urut Terbaru</option>
|
||||
<option value="nama_asc" @selected($filters['sort_by'] === 'nama_asc')>Nama A-Z</option>
|
||||
<option value="nama_desc" @selected($filters['sort_by'] === 'nama_desc')>Nama Z-A</option>
|
||||
<option value="anggota_desc" @selected($filters['sort_by'] === 'anggota_desc')>Anggota Terbanyak</option>
|
||||
<option value="anggota_asc" @selected($filters['sort_by'] === 'anggota_asc')>Anggota Tersedikit</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<div class="input-group input-group-sm">
|
||||
<input type="text" name="search" class="form-control" placeholder="Cari kelompok / responden..." value="{{ $filters['search'] }}" aria-label="Cari nama kelompok atau responden">
|
||||
<button type="submit" class="btn btn-outline-secondary" aria-label="Cari data kelompok tani"><i class="icon-base ti tabler-search"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-outline-secondary btn-sm"><i class="icon-base ti tabler-filter me-1"></i>Filter</button>
|
||||
<a href="{{ route('kelompok-tani.index') }}" class="btn btn-outline-secondary btn-sm"><i class="icon-base ti tabler-refresh me-1"></i>Reset</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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">
|
||||
<form method="GET" action="{{ route('kelompok-tani.index') }}" class="row g-3 align-items-end">
|
||||
@foreach($filters as $field => $value)
|
||||
<input type="hidden" name="{{ $field }}" value="{{ $value }}">
|
||||
@endforeach
|
||||
<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>
|
||||
<option value="10" @selected($kelompokTani->perPage() === 10)>10</option>
|
||||
<option value="25" @selected($kelompokTani->perPage() === 25)>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>
|
||||
<div class="col-md-auto ms-md-auto">
|
||||
<a href="{{ route('kelompok-tani.create') }}" class="btn btn-sm btn-primary">
|
||||
<i class="ti tabler-plus me-1"></i> Tambah
|
||||
</a>
|
||||
@@ -46,9 +196,9 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse($kelompokTani as $index => $item)
|
||||
<tr>
|
||||
<td>{{ $loop->iteration }}</td>
|
||||
<td><span class="text-heading">{{ $item->nama_kelompok }}</span></td>
|
||||
<tr class="kelompok-tani-row">
|
||||
<td>{{ $kelompokTani->firstItem() + $loop->index }}</td>
|
||||
<td><a href="{{ route('kelompok-tani.edit', $item->id) }}" class="text-heading d-block">{{ $item->nama_kelompok }}</a></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>
|
||||
@@ -67,7 +217,7 @@
|
||||
</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') }}
|
||||
{{ $kelompokTani->links('pagination::bootstrap-5') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -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');
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
@extends('layout.main')
|
||||
|
||||
@section('content')
|
||||
<div class="container-xxl flex-grow-1 container-p-y">
|
||||
<div class="container-xxl flex-grow-1 container-p-y kelompok-tani-page">
|
||||
@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) }}">
|
||||
<form novalidate method="POST" action="{{ route('kelompok-tani.update', $kelompokTani->id) }}">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
<input type="hidden" name="section" value="kelembagaan">
|
||||
@@ -20,7 +15,7 @@
|
||||
<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">
|
||||
<select class="form-select @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>
|
||||
@@ -37,11 +32,15 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@php
|
||||
$statusDenganSk = \App\Models\Pertanian\KelompokTani::STATUS_LEGALITAS_DENGAN_SK;
|
||||
$skAktif = in_array(old('status_legalitas', $kelompokTani->status_legalitas), $statusDenganSk, true);
|
||||
@endphp
|
||||
<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">
|
||||
<select class="form-select @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',
|
||||
@@ -56,96 +55,29 @@
|
||||
@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>
|
||||
<label class="form-label" for="klb-nomor-sk">Nomor SK</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) }}" />
|
||||
value="{{ old('nomor_sk', $kelompokTani->nomor_sk) }}" @disabled(!$skAktif) />
|
||||
@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) }}" />
|
||||
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')<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">
|
||||
<div class="d-inline-flex flex-wrap justify-content-end gap-2">
|
||||
<a href="{{ route('kelompok-tani.index') }}" class="btn btn-secondary wave-effect wave-light">
|
||||
Kembali
|
||||
</a>
|
||||
<button type="submit" class="btn btn-success wave-effect wave-light">
|
||||
<i class="ti tabler-device-floppy me-2"></i> Simpan Kelembagaan
|
||||
<i class="icon-base ti tabler-check me-1_5 icon-sm" aria-hidden="true"></i> Simpan
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -156,12 +88,15 @@
|
||||
<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'
|
||||
});
|
||||
$('#klb-cakupan-wilayah, #klb-status-legalitas').select2();
|
||||
const statusDenganSk = @json($statusDenganSk);
|
||||
function toggleSkFields() {
|
||||
const skAktif = statusDenganSk.includes($('#klb-status-legalitas').val());
|
||||
$('#klb-nomor-sk, #klb-tanggal-penerbitan-sk').prop('disabled', !skAktif);
|
||||
}
|
||||
$('#klb-status-legalitas').on('change', toggleSkFields);
|
||||
toggleSkFields();
|
||||
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
|
||||
@@ -1,5 +1,65 @@
|
||||
@extends('layout.main')
|
||||
@if(($bagianKeanggotaan ?? 'pengurus') === 'ringkasan')
|
||||
<div id="section-ringkasan" class="mt-4">
|
||||
<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) (Laki-laki / Perempuan)</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>
|
||||
@else
|
||||
@push('style')
|
||||
<style>
|
||||
.status-switch-row {
|
||||
@@ -26,99 +86,9 @@
|
||||
</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 --}}
|
||||
@@ -159,7 +129,7 @@
|
||||
@endif
|
||||
|
||||
{{-- FORM TAMBAH DATA BARU --}}
|
||||
<form method="POST" action="{{ route('kelompok-tani.pengurus-anggota.store', $kelompokTani->id) }}" class="form-repeater-pengurus">
|
||||
<form novalidate method="POST" action="{{ route('kelompok-tani.pengurus-anggota.store', $kelompokTani->id) }}" class="form-repeater-pengurus">
|
||||
@csrf
|
||||
|
||||
<div data-repeater-list="pengurus">
|
||||
@@ -200,19 +170,22 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 d-flex justify-content-between">
|
||||
<div class="mt-4 d-flex flex-wrap justify-content-between gap-2">
|
||||
<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
|
||||
<div class="d-inline-flex flex-wrap justify-content-end gap-2">
|
||||
<a href="{{ route('kelompok-tani.index') }}" class="btn btn-secondary wave-effect wave-light">
|
||||
Kembali
|
||||
</a>
|
||||
<button type="submit" class="btn btn-success wave-effect wave-light">
|
||||
<i class="icon-base ti tabler-check me-1_5 icon-sm" aria-hidden="true"></i> Simpan
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
@@ -316,3 +289,4 @@ $(function () {
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
@endif
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
@extends('layout.main')
|
||||
|
||||
@section('content')
|
||||
<div class="container-xxl flex-grow-1 container-p-y">
|
||||
<div class="container-xxl flex-grow-1 container-p-y kelompok-tani-page">
|
||||
@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
|
||||
|
||||
<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) }}">
|
||||
<form novalidate method="POST" action="{{ route('kelompok-tani.update', $kelompokTani->id) }}">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
<input type="hidden" name="section" value="sosial-konflik">
|
||||
@@ -20,7 +21,7 @@
|
||||
<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">
|
||||
<select class="form-select @error('partisipasi_perempuan') is-invalid @enderror" id="sk-partisipasi-perempuan" name="partisipasi_perempuan">
|
||||
<option value="">Pilih Status</option>
|
||||
@foreach([
|
||||
'Tidak terlibat',
|
||||
@@ -35,13 +36,10 @@
|
||||
</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">
|
||||
<select class="form-select @error('konflik_kelompok') is-invalid @enderror" id="sk-konflik-kelompok" name="konflik_kelompok">
|
||||
<option value="">Pilih Status</option>
|
||||
@foreach([
|
||||
'Tidak pernah',
|
||||
@@ -56,11 +54,11 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row" id="sk-detail-konflik-wrapper" style="display: none;">
|
||||
<div class="row" id="sk-detail-konflik-wrapper" @if(!$pernahKonflik) style="display: none;" @endif>
|
||||
<div class="col-md-6 mb-4 form-control-validation">
|
||||
<label class="form-label" for="sk-topik-konflik">Jika Pernah, Soal Apa?</label>
|
||||
<label class="form-label" for="sk-topik-konflik">Jika Pernah, Soal Apa? <span class="text-danger" id="sk-topik-konflik-required" @if(!$pernahKonflik) hidden @endif>*</span></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) }}" />
|
||||
placeholder="Contoh: Kepemimpinan, pembagian hasil" value="{{ old('topik_konflik', $kelompokTani->topik_konflik) }}" @required($pernahKonflik) @disabled(!$pernahKonflik) />
|
||||
@error('topik_konflik')<div class="error invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
<div class="col-md-6 mb-4 form-control-validation">
|
||||
@@ -71,10 +69,15 @@
|
||||
</div>
|
||||
|
||||
<div class="mt-4 text-end">
|
||||
<div class="d-inline-flex flex-wrap justify-content-end gap-2">
|
||||
<a href="{{ route('kelompok-tani.index') }}" class="btn btn-secondary wave-effect wave-light">
|
||||
Kembali
|
||||
</a>
|
||||
<button type="submit" class="btn btn-success wave-effect wave-light">
|
||||
<i class="ti tabler-device-floppy me-2"></i> Simpan Sosial & Konflik
|
||||
<i class="icon-base ti tabler-check me-1_5 icon-sm" aria-hidden="true"></i> Simpan
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -89,7 +92,10 @@
|
||||
|
||||
function toggleDetailKonflik() {
|
||||
var val = $('#sk-konflik-kelompok').val();
|
||||
$('#sk-detail-konflik-wrapper').toggle(val === 'Pernah, sudah selesai' || val === 'Pernah, masih berlanjut/belum selesai');
|
||||
var pernah = val === 'Pernah, sudah selesai' || val === 'Pernah, masih berlanjut/belum selesai';
|
||||
$('#sk-detail-konflik-wrapper').toggle(pernah);
|
||||
$('#sk-topik-konflik').prop('required', pernah).prop('disabled', !pernah);
|
||||
$('#sk-topik-konflik-required').prop('hidden', !pernah);
|
||||
}
|
||||
toggleDetailKonflik();
|
||||
$('#sk-konflik-kelompok').on('change', toggleDetailKonflik);
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
@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
|
||||
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
|
||||
use App\Http\Controllers\Web\Produktivitas\SurveyKelompokTaniController;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
beforeEach(function () {
|
||||
foreach ([
|
||||
'master_kabupaten_kota' => null,
|
||||
'master_kecamatan' => 'kabupaten_kota_id',
|
||||
'master_desa_kelurahan' => 'kecamatan_id',
|
||||
'master_komoditas' => null,
|
||||
] as $name => $parent) {
|
||||
Schema::create($name, function (Blueprint $table) use ($parent) {
|
||||
$table->id();
|
||||
$table->string('nama');
|
||||
if ($parent) $table->integer($parent);
|
||||
$table->softDeletes();
|
||||
});
|
||||
}
|
||||
Schema::create('survey_kelompok_tani', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('nama_kelompok');
|
||||
$table->string('nama_responden')->nullable();
|
||||
$table->integer('desa_kelurahan_id');
|
||||
$table->string('jenis_kelompok')->nullable();
|
||||
$table->json('komoditas_id')->nullable();
|
||||
foreach (['jumlah_pengurus', 'jumlah_pengurus_aktif', 'jumlah_anggota_terdaftar', 'jumlah_anggota_aktif'] as $field) {
|
||||
$table->integer($field)->nullable();
|
||||
}
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
|
||||
DB::table('master_kabupaten_kota')->insert([
|
||||
['id' => 1, 'nama' => 'Kabupaten Ngada'], ['id' => 2, 'nama' => 'Kabupaten Lain'],
|
||||
]);
|
||||
DB::table('master_kecamatan')->insert([
|
||||
['id' => 1, 'nama' => 'Kecamatan A', 'kabupaten_kota_id' => 1],
|
||||
['id' => 2, 'nama' => 'Kecamatan B', 'kabupaten_kota_id' => 1],
|
||||
['id' => 3, 'nama' => 'Kecamatan C', 'kabupaten_kota_id' => 2],
|
||||
]);
|
||||
DB::table('master_desa_kelurahan')->insert([
|
||||
['id' => 1, 'nama' => 'Desa A', 'kecamatan_id' => 1],
|
||||
['id' => 2, 'nama' => 'Desa B', 'kecamatan_id' => 1],
|
||||
['id' => 3, 'nama' => 'Desa C', 'kecamatan_id' => 2],
|
||||
['id' => 4, 'nama' => 'Desa D', 'kecamatan_id' => 3],
|
||||
]);
|
||||
DB::table('master_komoditas')->insert([
|
||||
['id' => 1, 'nama' => 'Kakao'], ['id' => 2, 'nama' => 'Kopi'], ['id' => 11, 'nama' => 'Vanili'],
|
||||
]);
|
||||
foreach ([
|
||||
[1, 'Alpha', 'Budi', 1, 'Poktan', ['1', '2'], 3, 2, 30, 25, null],
|
||||
[2, 'Beta', 'Siti', 2, 'KWT', [1], 5, 4, 40, 35, null],
|
||||
[3, 'Citra', 'Ani', 3, 'Poktan', [2, 11], null, null, 0, 0, null],
|
||||
[4, 'Diluar', 'Toni', 4, 'Poktan', [1], 99, 99, 900, 900, null],
|
||||
[5, 'Dihapus', 'Dewi', 1, 'Poktan', [1], 99, 99, 900, 900, '2026-01-01'],
|
||||
] as [$id, $nama, $responden, $desa, $jenis, $komoditas, $pengurus, $pengurusAktif, $anggota, $anggotaAktif, $deletedAt]) {
|
||||
DB::table('survey_kelompok_tani')->insert([
|
||||
'id' => $id, 'nama_kelompok' => $nama, 'nama_responden' => $responden,
|
||||
'desa_kelurahan_id' => $desa, 'jenis_kelompok' => $jenis,
|
||||
'komoditas_id' => json_encode($komoditas), 'jumlah_pengurus' => $pengurus,
|
||||
'jumlah_pengurus_aktif' => $pengurusAktif, 'jumlah_anggota_terdaftar' => $anggota,
|
||||
'jumlah_anggota_aktif' => $anggotaAktif, 'created_at' => "2026-01-0{$id}", 'deleted_at' => $deletedAt,
|
||||
]);
|
||||
}
|
||||
|
||||
$this->listKelompok = function (array $filters = []) {
|
||||
$request = Request::create('/survey/kelompok-tani', 'GET', $filters);
|
||||
$this->app->instance('request', $request);
|
||||
|
||||
return app(SurveyKelompokTaniController::class)->index($request)->getData();
|
||||
};
|
||||
});
|
||||
|
||||
test('kelompok cards summarize the default region and exclude deleted groups', function () {
|
||||
$data = ($this->listKelompok)();
|
||||
|
||||
expect($data['kelompokTani']->pluck('id')->all())->toBe([3, 2, 1]);
|
||||
expect((int) $data['summary']->total_kelompok)->toBe(3)
|
||||
->and((int) $data['summary']->total_jenis)->toBe(2)
|
||||
->and((int) $data['summary']->total_pengurus)->toBe(8)
|
||||
->and((int) $data['summary']->pengurus_aktif)->toBe(6)
|
||||
->and((int) $data['summary']->total_anggota)->toBe(70)
|
||||
->and((int) $data['summary']->anggota_aktif)->toBe(60);
|
||||
expect($data['kecamatanOptions']->pluck('id')->all())->toBe([1, 2]);
|
||||
});
|
||||
|
||||
test('kelompok region filters constrain rows cards and dependent options', function () {
|
||||
$data = ($this->listKelompok)(['kecamatan_id' => 1, 'desa_kelurahan_id' => 2]);
|
||||
expect($data['kelompokTani']->pluck('id')->all())->toBe([2]);
|
||||
expect((int) $data['summary']->total_anggota)->toBe(40);
|
||||
expect($data['desaOptions']->pluck('id')->all())->toBe([1, 2]);
|
||||
expect(($this->listKelompok)(['kecamatan_id' => 2])['kelompokTani']->pluck('id')->all())->toBe([3]);
|
||||
expect(($this->listKelompok)(['kabupaten_kota_id' => 2])['kelompokTani']->pluck('id')->all())->toBe([4]);
|
||||
});
|
||||
|
||||
test('kelompok commodity filter matches string and numeric JSON ids exactly', function () {
|
||||
$data = ($this->listKelompok)(['komoditas_id' => '1']);
|
||||
expect($data['kelompokTani']->pluck('id')->all())->toBe([2, 1]);
|
||||
expect((int) $data['summary']->total_kelompok)->toBe(2);
|
||||
expect(($this->listKelompok)(['komoditas_id' => 2, 'jenis_kelompok' => 'Poktan'])['kelompokTani']->pluck('id')->all())->toBe([3, 1]);
|
||||
expect(($this->listKelompok)(['jenis_kelompok' => 'KWT'])['kelompokTani']->pluck('id')->all())->toBe([2]);
|
||||
});
|
||||
|
||||
test('kelompok search matches group and respondent names without escaping region filters', function () {
|
||||
expect(($this->listKelompok)(['search' => 'aLpHa'])['kelompokTani']->pluck('id')->all())->toBe([1]);
|
||||
expect(($this->listKelompok)(['search' => 'sITI'])['kelompokTani']->pluck('id')->all())->toBe([2]);
|
||||
$data = ($this->listKelompok)(['search' => 'Toni']);
|
||||
expect($data['kelompokTani']->total())->toBe(0);
|
||||
expect((int) $data['summary']->total_pengurus)->toBe(0)
|
||||
->and((int) $data['summary']->total_anggota)->toBe(0);
|
||||
});
|
||||
|
||||
test('kelompok sorting supports names membership totals and safe fallback', function () {
|
||||
foreach ([
|
||||
'nama_asc' => [1, 2, 3], 'nama_desc' => [3, 2, 1],
|
||||
'anggota_desc' => [2, 1, 3], 'anggota_asc' => [3, 1, 2], 'unknown' => [3, 2, 1],
|
||||
] as $sort => $ids) {
|
||||
expect(($this->listKelompok)(['sort_by' => $sort])['kelompokTani']->pluck('id')->all())->toBe($ids);
|
||||
}
|
||||
});
|
||||
|
||||
test('kelompok totals cover every result and pagination preserves all filters', function () {
|
||||
for ($index = 0; $index < 12; $index++) {
|
||||
DB::table('survey_kelompok_tani')->insert([
|
||||
'nama_kelompok' => 'Kelompok tambahan ' . $index, 'desa_kelurahan_id' => 1,
|
||||
'jenis_kelompok' => 'Poktan', 'komoditas_id' => '["1"]', 'jumlah_anggota_terdaftar' => 10,
|
||||
]);
|
||||
}
|
||||
$data = ($this->listKelompok)(['komoditas_id' => 1, 'sort_by' => 'nama_asc', 'page' => 2, 'per_page' => '10']);
|
||||
expect($data['kelompokTani']->count())->toBe(4);
|
||||
expect($data['kelompokTani']->perPage())->toBe(10);
|
||||
expect((int) $data['summary']->total_kelompok)->toBe(14)
|
||||
->and((int) $data['summary']->total_anggota)->toBe(190);
|
||||
parse_str(parse_url($data['kelompokTani']->url(1), PHP_URL_QUERY), $params);
|
||||
expect($params)->toMatchArray(['komoditas_id' => '1', 'sort_by' => 'nama_asc', 'per_page' => '10']);
|
||||
});
|
||||
|
||||
test('kelompok filters reject malformed ids and unsupported page sizes', function (array $filters) {
|
||||
expect(fn () => ($this->listKelompok)($filters))->toThrow(ValidationException::class);
|
||||
})->with([
|
||||
[['kecamatan_id' => 'invalid']], [['komoditas_id' => 999]], [['per_page' => 0]], [['search' => ['invalid']]],
|
||||
]);
|
||||
@@ -0,0 +1,942 @@
|
||||
<?php
|
||||
|
||||
use App\Http\Controllers\Web\Produktivitas\PengurusKelompokTaniController;
|
||||
use App\Http\Controllers\Web\Produktivitas\AsetKelompokTaniController;
|
||||
use App\Http\Controllers\Web\Produktivitas\BantuanKelompokTaniController;
|
||||
use App\Http\Controllers\Web\Produktivitas\SurveyKelompokTaniController;
|
||||
use App\Models\Pertanian\KelompokTani;
|
||||
use App\Models\Pertanian\AsetKelompokTani;
|
||||
use App\Models\Pertanian\BantuanKelompokTani;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\ViewErrorBag;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
beforeEach(function () {
|
||||
foreach ([
|
||||
'master_provinsi' => null,
|
||||
'master_kabupaten_kota' => 'provinsi_id',
|
||||
'master_kecamatan' => 'kabupaten_kota_id',
|
||||
'master_desa_kelurahan' => 'kecamatan_id',
|
||||
'master_komoditas' => null,
|
||||
] as $name => $parent) {
|
||||
Schema::create($name, function (Blueprint $table) use ($parent) {
|
||||
$table->id();
|
||||
$table->string('nama');
|
||||
$table->string('kode')->nullable();
|
||||
$table->boolean('is_utama')->default(true);
|
||||
if ($parent) $table->integer($parent);
|
||||
$table->softDeletes();
|
||||
});
|
||||
}
|
||||
Schema::create('survey_kelompok_tani', function (Blueprint $table) {
|
||||
$table->id();
|
||||
foreach ([
|
||||
'uid', 'nama_kelompok', 'nama_responden', 'jabatan_responden', 'kontak_responden',
|
||||
'dusun', 'jenis_kelompok', 'nama_gapoktan', 'cakupan_wilayah', 'nama_wilayah_cakupan',
|
||||
'status_legalitas', 'nomor_sk', 'tanggal_tahun_penerbitan_sk', 'frekuensi_pertemuan',
|
||||
'tanggal_pertemuan_terakhir',
|
||||
'pembukuan_kas', 'pengelola_kas', 'masalah_pengelolaan_kas_simpan_pinjam', 'deskripsi_masalah_pengelolaan_kas_simpan_pinjam',
|
||||
'potensi_kelompok', 'alasan_penilaian_potensi', 'konflik_kelompok', 'topik_konflik', 'penyelesaian_konflik', 'partisipasi_perempuan',
|
||||
] as $field) {
|
||||
$table->string($field)->nullable();
|
||||
}
|
||||
foreach ([
|
||||
'desa_kelurahan_id', 'tahun_berdiri', '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',
|
||||
'created_by', 'updated_by', 'deleted_by',
|
||||
] as $field) {
|
||||
$table->integer($field)->nullable();
|
||||
}
|
||||
$table->json('komoditas_id')->nullable();
|
||||
$table->json('kegiatan_terlaksana')->nullable();
|
||||
$table->json('fungsi_kelompok_bagi_anggota')->nullable();
|
||||
$table->boolean('pernah_mendapatkan_bantuan')->nullable();
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
Schema::create('survey_pengurus_kelompok_tani', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('uid');
|
||||
$table->integer('survey_kelompok_tani_id');
|
||||
$table->string('nama_pengurus');
|
||||
$table->string('jabatan');
|
||||
$table->string('kontak');
|
||||
$table->boolean('status');
|
||||
$table->integer('created_by')->nullable();
|
||||
$table->integer('updated_by')->nullable();
|
||||
$table->integer('deleted_by')->nullable();
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
Schema::create('survey_aset_kelompok_tani', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('uid');
|
||||
$table->integer('survey_kelompok_tani_id');
|
||||
$table->string('jenis_aset');
|
||||
$table->boolean('status_aset');
|
||||
$table->string('status_pengelolaan_aset');
|
||||
$table->string('kondisi_aset');
|
||||
$table->integer('created_by')->nullable();
|
||||
$table->integer('updated_by')->nullable();
|
||||
$table->integer('deleted_by')->nullable();
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
Schema::create('survey_bantuan_kelompok_tani', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('uid');
|
||||
$table->integer('survey_kelompok_tani_id');
|
||||
$table->string('nama_program');
|
||||
$table->string('penyelenggara');
|
||||
$table->string('bentuk_bantuan');
|
||||
$table->integer('tahun')->nullable();
|
||||
$table->integer('created_by')->nullable();
|
||||
$table->integer('updated_by')->nullable();
|
||||
$table->integer('deleted_by')->nullable();
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
DB::table('master_provinsi')->insert(['id' => 1, 'nama' => 'NTT']);
|
||||
DB::table('master_kabupaten_kota')->insert(['id' => 1, 'nama' => 'Ngada', 'provinsi_id' => 1]);
|
||||
DB::table('master_kecamatan')->insert(['id' => 1, 'nama' => 'Kecamatan A', 'kabupaten_kota_id' => 1]);
|
||||
DB::table('master_desa_kelurahan')->insert(['id' => 1, 'nama' => 'Desa A', 'kecamatan_id' => 1]);
|
||||
|
||||
$user = new User(['name' => 'Admin Test', 'email' => 'admin@example.test', 'role' => 'admin']);
|
||||
$user->id = 7;
|
||||
$this->be($user);
|
||||
Event::forget('composing: *');
|
||||
view()->share('errors', new ViewErrorBag());
|
||||
|
||||
$this->kelompok = fn (array $attributes = []) => KelompokTani::create([
|
||||
'nama_kelompok' => 'Kelompok A', 'nama_responden' => 'Responden A',
|
||||
'desa_kelurahan_id' => 1, 'jenis_kelompok' => 'Kelompok Tani (Poktan)', ...$attributes,
|
||||
]);
|
||||
$this->profileRequest = function (array $input = [], string $method = 'PUT') {
|
||||
$request = Request::create('/survey/kelompok-tani/1/edit', $method, $input);
|
||||
$request->setLaravelSession(app('session')->driver());
|
||||
$this->app->instance('request', $request);
|
||||
|
||||
return $request;
|
||||
};
|
||||
$this->profileDom = function ($view) {
|
||||
$dom = new DOMDocument();
|
||||
$previous = libxml_use_internal_errors(true);
|
||||
$dom->loadHTML($view->render());
|
||||
libxml_clear_errors();
|
||||
libxml_use_internal_errors($previous);
|
||||
|
||||
return new DOMXPath($dom);
|
||||
};
|
||||
});
|
||||
|
||||
test('profile saves identity and membership together on creation and update', function () {
|
||||
$controller = app(SurveyKelompokTaniController::class);
|
||||
$input = [
|
||||
'nama_kelompok' => 'Kelompok Baru', 'nama_responden' => 'Budi',
|
||||
'desa_kelurahan_id' => 1, 'jenis_kelompok' => 'Kelompok Tani (Poktan)',
|
||||
'jumlah_pengurus' => 4, 'jumlah_pengurus_aktif' => 3, 'jumlah_anggota_terdaftar' => 20,
|
||||
'jumlah_anggota_aktif' => 18, 'jumlah_pengurus_laki_laki' => 2, 'jumlah_pengurus_perempuan' => 2,
|
||||
'jumlah_anggota_laki_laki' => 12, 'jumlah_anggota_perempuan' => 8,
|
||||
'jumlah_anggota_pemuda_laki_laki' => 5, 'jumlah_anggota_pemuda_perempuan' => 3,
|
||||
];
|
||||
$locations = ['provinsi_id' => 1, 'kabupaten_id' => 1, 'kecamatan_id' => 1];
|
||||
$controller->store(($this->profileRequest)([...$input, ...$locations], 'POST'));
|
||||
$group = KelompokTani::firstOrFail();
|
||||
foreach ($input as $field => $value) expect($group->{$field})->toBe($value);
|
||||
|
||||
$response = $controller->update(($this->profileRequest)([
|
||||
...$input, ...$locations, 'nama_kelompok' => 'Kelompok Diubah', 'jumlah_anggota_terdaftar' => 25,
|
||||
]), $group);
|
||||
expect($group->refresh()->nama_kelompok)->toBe('Kelompok Diubah')
|
||||
->and($group->jumlah_anggota_terdaftar)->toBe(25);
|
||||
expect($response->getTargetUrl())->toBe(route('kelompok-tani.edit', $group->id) . '#section-pengurus');
|
||||
});
|
||||
|
||||
test('invalid membership prevents partial profile saves', function () {
|
||||
$group = ($this->kelompok)(['jumlah_anggota_terdaftar' => 20]);
|
||||
$request = ($this->profileRequest)([
|
||||
'nama_kelompok' => 'Tidak boleh tersimpan', 'nama_responden' => 'Budi',
|
||||
'provinsi_id' => 1, 'kabupaten_id' => 1, 'kecamatan_id' => 1,
|
||||
'desa_kelurahan_id' => 1, 'jenis_kelompok' => 'Kelompok Tani (Poktan)',
|
||||
'jumlah_anggota_terdaftar' => -1,
|
||||
]);
|
||||
|
||||
expect(fn () => app(SurveyKelompokTaniController::class)->update($request, $group))
|
||||
->toThrow(ValidationException::class);
|
||||
expect($group->refresh()->nama_kelompok)->toBe('Kelompok A')
|
||||
->and($group->jumlah_anggota_terdaftar)->toBe(20);
|
||||
});
|
||||
|
||||
test('membership fields belong to the profile form on create and edit', function () {
|
||||
$controller = app(SurveyKelompokTaniController::class);
|
||||
($this->profileRequest)([], 'GET');
|
||||
$create = ($this->profileDom)($controller->create());
|
||||
expect($create->query('//form[@id="addKelompokTaniForm"]//input[@name="jumlah_anggota_terdaftar"]')->length)->toBe(1);
|
||||
|
||||
$group = ($this->kelompok)(['jumlah_anggota_terdaftar' => 20]);
|
||||
$group->pengurus()->create([
|
||||
'uid' => 'PKT-TEST', 'nama_pengurus' => 'Ketua A', 'jabatan' => 'Ketua', 'kontak' => '08123456789', 'status' => true,
|
||||
]);
|
||||
$edit = ($this->profileDom)($controller->edit(($this->profileRequest)([], 'GET'), $group));
|
||||
expect($edit->query('//form[@id="editKelompokTaniForm"]//input[@name="jumlah_anggota_terdaftar" and @value="20"]')->length)->toBe(1);
|
||||
expect($edit->query('//div[@id="section-pengurus"]//input[@value="Ketua A"]')->length)->toBe(1);
|
||||
expect($edit->query('//form[contains(@class,"form-repeater-pengurus")]')->length)->toBe(1);
|
||||
expect($edit->query('//ul[contains(@class,"nav-pills")]//a[normalize-space()="Keanggotaan"]')->length)->toBe(0);
|
||||
});
|
||||
|
||||
test('SK fields render enabled only for statuses with an existing SK', function (?string $status, bool $enabled) {
|
||||
$group = ($this->kelompok)(['status_legalitas' => $status]);
|
||||
$view = app(SurveyKelompokTaniController::class)->edit(
|
||||
($this->profileRequest)(['section' => 'kelembagaan'], 'GET'), $group
|
||||
);
|
||||
$dom = ($this->profileDom)($view);
|
||||
foreach (['klb-nomor-sk', 'klb-tanggal-penerbitan-sk'] as $id) {
|
||||
expect($dom->query('//input[@id="' . $id . '"]')->item(0)->hasAttribute('disabled'))->toBe(!$enabled);
|
||||
}
|
||||
expect($dom->query('//label[@for="klb-nomor-sk"]')->item(0)->textContent)->toBe('Nomor SK');
|
||||
})->with([
|
||||
[null, false], ['Belum ada SK/dokumen apa pun', false], ['Sedang proses pengajuan', false],
|
||||
['Tidak tahu', false], ['Sudah ada SK dari desa/kecamatan', true],
|
||||
['Sudah ada SK dan terdaftar di Dinas/Kabupaten', true],
|
||||
]);
|
||||
|
||||
test('inactive SK input is ignored and existing values survive status changes', function () {
|
||||
$group = ($this->kelompok)(['nomor_sk' => 'SK-LAMA', 'tanggal_tahun_penerbitan_sk' => '2020']);
|
||||
$controller = app(SurveyKelompokTaniController::class);
|
||||
$controller->update(($this->profileRequest)([
|
||||
'section' => 'kelembagaan', 'status_legalitas' => 'Tidak tahu',
|
||||
'nomor_sk' => ['invalid'], 'tanggal_tahun_penerbitan_sk' => str_repeat('x', 100),
|
||||
]), $group);
|
||||
expect($group->refresh()->nomor_sk)->toBe('SK-LAMA')
|
||||
->and($group->tanggal_tahun_penerbitan_sk)->toBe('2020');
|
||||
|
||||
$controller->update(($this->profileRequest)([
|
||||
'section' => 'kelembagaan', 'status_legalitas' => 'Sudah ada SK dari desa/kecamatan',
|
||||
'nomor_sk' => 'SK-BARU', 'tanggal_tahun_penerbitan_sk' => '2026',
|
||||
]), $group);
|
||||
expect($group->refresh()->nomor_sk)->toBe('SK-BARU')
|
||||
->and($group->tanggal_tahun_penerbitan_sk)->toBe('2026');
|
||||
});
|
||||
|
||||
test('pengurus actions and the former membership URL return to profile', function () {
|
||||
$group = ($this->kelompok)();
|
||||
$controller = app(PengurusKelompokTaniController::class);
|
||||
$response = $controller->index($group);
|
||||
expect($response->getTargetUrl())->toBe(route('kelompok-tani.edit', $group->id) . '#section-ringkasan');
|
||||
$response = $controller->store(($this->profileRequest)(['pengurus' => [[
|
||||
'nama_pengurus' => 'Ketua A', 'jabatan' => 'Ketua', 'kontak' => '08123456789', 'status' => 1,
|
||||
]]], 'POST'), $group);
|
||||
expect($response->getTargetUrl())->toBe(route('kelompok-tani.edit', $group->id) . '#section-pengurus');
|
||||
$pengurus = $group->pengurus()->firstOrFail();
|
||||
$response = $controller->destroy($group, $pengurus);
|
||||
expect($response->getTargetUrl())->toBe(route('kelompok-tani.edit', $group->id) . '#section-pengurus');
|
||||
expect($group->pengurus()->count())->toBe(0);
|
||||
});
|
||||
|
||||
test('meeting fields are shown in Kegiatan with existing values and removed from Kelembagaan', function () {
|
||||
$group = ($this->kelompok)([
|
||||
'frekuensi_pertemuan' => '1x per bulan', 'tanggal_pertemuan_terakhir' => '2026-10-20',
|
||||
]);
|
||||
$controller = app(SurveyKelompokTaniController::class);
|
||||
$kelembagaan = ($this->profileDom)($controller->edit(
|
||||
($this->profileRequest)(['section' => 'kelembagaan'], 'GET'), $group
|
||||
));
|
||||
expect($kelembagaan->query('//select[@name="frekuensi_pertemuan"] | //input[@name="tanggal_pertemuan_terakhir"]')->length)->toBe(0);
|
||||
|
||||
$aktivitas = ($this->profileDom)($controller->edit(
|
||||
($this->profileRequest)(['section' => 'aktivitas-fungsi'], 'GET'), $group
|
||||
));
|
||||
expect($aktivitas->query('//form//select[@name="frekuensi_pertemuan"]/option[@selected]')->item(0)->getAttribute('value'))->toBe('1x per bulan');
|
||||
expect($aktivitas->query('//form//input[@name="tanggal_pertemuan_terakhir"]')->item(0)->getAttribute('value'))->toBe('20-10-2026');
|
||||
expect($aktivitas->query('//ul[contains(@class,"nav-pills")]//a[normalize-space()="Operasional"]')->length)->toBe(1);
|
||||
expect($aktivitas->query('//input[@name="tanggal_pertemuan_terakhir"]')->item(0)->hasAttribute('placeholder'))->toBeFalse();
|
||||
});
|
||||
|
||||
test('Kegiatan saves meeting details and rejects invalid dates without partial updates', function () {
|
||||
$group = ($this->kelompok)();
|
||||
$controller = app(SurveyKelompokTaniController::class);
|
||||
$response = $controller->update(($this->profileRequest)([
|
||||
'section' => 'aktivitas-fungsi', 'frekuensi_pertemuan' => '1x per bulan',
|
||||
'tanggal_pertemuan_terakhir' => '20-10-2026', 'kegiatan_terlaksana' => ['Pertemuan/diskusi rutin'],
|
||||
]), $group);
|
||||
expect($group->refresh()->frekuensi_pertemuan)->toBe('1x per bulan')
|
||||
->and($group->tanggal_pertemuan_terakhir->format('Y-m-d'))->toBe('2026-10-20')
|
||||
->and($group->kegiatan_terlaksana)->toBe(['Pertemuan/diskusi rutin']);
|
||||
expect($response->getTargetUrl())->toBe(route('kelompok-tani.edit', $group->id) . '?section=aktivitas-fungsi#section-aset-baku');
|
||||
|
||||
$invalid = ($this->profileRequest)([
|
||||
'section' => 'aktivitas-fungsi', 'frekuensi_pertemuan' => 'Tidak rutin/tidak terjadwal',
|
||||
'tanggal_pertemuan_terakhir' => 'invalid-date',
|
||||
]);
|
||||
expect(fn () => $controller->update($invalid, $group))->toThrow(ValidationException::class);
|
||||
expect($group->refresh()->frekuensi_pertemuan)->toBe('1x per bulan')
|
||||
->and($group->tanggal_pertemuan_terakhir->format('Y-m-d'))->toBe('2026-10-20');
|
||||
|
||||
$controller->update(($this->profileRequest)([
|
||||
'section' => 'kelembagaan', 'cakupan_wilayah' => 'Desa', 'frekuensi_pertemuan' => 'Diabaikan',
|
||||
'tanggal_pertemuan_terakhir' => 'invalid-date',
|
||||
]), $group);
|
||||
expect($group->refresh()->cakupan_wilayah)->toBe('Desa')
|
||||
->and($group->frekuensi_pertemuan)->toBe('1x per bulan');
|
||||
});
|
||||
|
||||
test('all group tabs show Simpan with a check and Kembali to the group list', function () {
|
||||
($this->profileRequest)([], 'GET');
|
||||
$group = ($this->kelompok)();
|
||||
foreach (['pengurus', 'aset', 'bantuan'] as $relation) $group->setRelation($relation, collect());
|
||||
|
||||
foreach (['add', 'edit', 'kelembagaan', 'aktivitas-fungsi', 'sosial-konflik'] as $template) {
|
||||
$dom = ($this->profileDom)(view('produktivitas.survey-kelompok-tani.' . $template, [
|
||||
'kelompokTani' => $template === 'add' ? null : $group,
|
||||
'provinsi' => collect(), 'komoditas' => collect(),
|
||||
]));
|
||||
$buttons = $dom->query('//div[contains(@class,"kelompok-tani-page")]//button[@type="submit" and contains(@class,"btn-success")]');
|
||||
expect($buttons->length)->toBeGreaterThan(0);
|
||||
foreach ($buttons as $button) {
|
||||
$form = $dom->query('ancestor::form', $button)->item(0);
|
||||
expect($form->hasAttribute('novalidate'))->toBeTrue();
|
||||
expect(trim($button->textContent))->toBe('Simpan');
|
||||
expect($dom->query('.//i[contains(@class,"tabler-check")]', $button)->length)->toBe(1);
|
||||
$back = $dom->query('./a[normalize-space()="Kembali"]', $button->parentNode);
|
||||
expect($back->length)->toBe(1);
|
||||
expect($back->item(0)->getAttribute('href'))->toBe(route('kelompok-tani.index'));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('flash notifications appear once above the group summary regardless of section', function (string $key) {
|
||||
($this->profileRequest)([], 'GET');
|
||||
session()->flash($key, 'Pesan pemeriksaan');
|
||||
session()->flash($key . '_section', 'kas');
|
||||
$group = ($this->kelompok)();
|
||||
$group->setRelation('pengurus', collect());
|
||||
$dom = ($this->profileDom)(view('produktivitas.survey-kelompok-tani.edit', [
|
||||
'kelompokTani' => $group, 'provinsi' => collect(), 'komoditas' => collect(),
|
||||
]));
|
||||
|
||||
expect($dom->query('//div[@id="kelompok-tani-notifications"]')->length)->toBe(1);
|
||||
expect($dom->query('//div[@id="kelompok-tani-summary"]/preceding-sibling::div[@id="kelompok-tani-notifications"]')->length)->toBe(1);
|
||||
expect($dom->query('//div[@id="kelompok-tani-notifications"]//div[@role="alert"]')->length)->toBe(1);
|
||||
expect($dom->query('//div[@id="kelompok-tani-notifications"]')->item(0)->textContent)->toContain('Pesan pemeriksaan');
|
||||
})->with(['success', 'error', 'warning', 'info', 'status', 'message']);
|
||||
|
||||
test('validation errors are summarized above the group summary', function () {
|
||||
($this->profileRequest)([], 'GET');
|
||||
$errors = new ViewErrorBag();
|
||||
$errors->put('default', new Illuminate\Support\MessageBag(['nomor_sk' => 'Nomor SK tidak valid.']));
|
||||
view()->share('errors', $errors);
|
||||
$dom = ($this->profileDom)(view('produktivitas.survey-kelompok-tani.kelembagaan', [
|
||||
'kelompokTani' => ($this->kelompok)(),
|
||||
]));
|
||||
|
||||
expect($dom->query('//div[@id="kelompok-tani-summary"]/preceding-sibling::div[@id="kelompok-tani-notifications"]')->length)->toBe(1);
|
||||
expect($dom->query('//div[@id="kelompok-tani-notifications"]//li')->item(0)->textContent)->toBe('Nomor SK tidak valid.');
|
||||
});
|
||||
|
||||
test('one asset submission saves standard and additional assets and skips empty rows', function () {
|
||||
$group = ($this->kelompok)();
|
||||
$controller = app(AsetKelompokTaniController::class);
|
||||
$response = $controller->update(($this->profileRequest)([
|
||||
'aset' => [[
|
||||
'jenis_aset' => 'Timbangan', 'status_aset' => 1,
|
||||
'status_pengelolaan_aset' => 'Hibah', 'kondisi_aset' => 'Berfungsi',
|
||||
]],
|
||||
'aset_lainnya' => [
|
||||
['jenis_aset' => 'Mesin pengering', 'status_pengelolaan_aset' => 'Swadaya', 'kondisi_aset' => 'Berfungsi'],
|
||||
['jenis_aset' => '', 'status_pengelolaan_aset' => '', 'kondisi_aset' => ''],
|
||||
],
|
||||
]), $group);
|
||||
|
||||
expect($group->aset()->count())->toBe(2);
|
||||
expect($group->aset()->where('jenis_aset', 'Timbangan')->firstOrFail()->status_pengelolaan_aset)->toBe('Hibah');
|
||||
expect($group->aset()->where('jenis_aset', 'Mesin pengering')->firstOrFail()->kondisi_aset)->toBe('Berfungsi');
|
||||
expect($response->getTargetUrl())->toBe(route('kelompok-tani.edit', $group->id) . '?section=aktivitas-fungsi#section-status-bantuan');
|
||||
});
|
||||
|
||||
test('invalid additional assets prevent standard assets from being changed', function () {
|
||||
$group = ($this->kelompok)();
|
||||
$existing = $group->aset()->create([
|
||||
'uid' => 'AKT-TEST', 'jenis_aset' => 'Timbangan', 'status_aset' => true,
|
||||
'status_pengelolaan_aset' => 'Hibah', 'kondisi_aset' => 'Berfungsi',
|
||||
]);
|
||||
$request = ($this->profileRequest)([
|
||||
'aset' => [['jenis_aset' => 'Timbangan', 'status_aset' => 0]],
|
||||
'aset_lainnya' => [['jenis_aset' => 'Timbangan']],
|
||||
]);
|
||||
expect(fn () => app(AsetKelompokTaniController::class)->update($request, $group))->toThrow(ValidationException::class);
|
||||
expect($existing->fresh()->trashed())->toBeFalse();
|
||||
expect($group->aset()->count())->toBe(1);
|
||||
});
|
||||
|
||||
test('combined asset save restores and removes standard assets while keeping additional assets', function () {
|
||||
$group = ($this->kelompok)();
|
||||
$controller = app(AsetKelompokTaniController::class);
|
||||
$existing = $group->aset()->create([
|
||||
'uid' => 'AKT-TEST', 'jenis_aset' => 'Timbangan', 'status_aset' => true,
|
||||
'status_pengelolaan_aset' => 'Hibah', 'kondisi_aset' => 'Berfungsi',
|
||||
]);
|
||||
$existing->delete();
|
||||
$controller->update(($this->profileRequest)([
|
||||
'aset' => [[
|
||||
'jenis_aset' => 'Timbangan', 'status_aset' => 1,
|
||||
'status_pengelolaan_aset' => 'Hibah', 'kondisi_aset' => 'Berfungsi',
|
||||
]],
|
||||
'aset_lainnya' => [['jenis_aset' => 'Mesin pengering']],
|
||||
]), $group);
|
||||
expect($existing->fresh()->trashed())->toBeFalse();
|
||||
expect($group->aset()->withTrashed()->where('jenis_aset', 'Timbangan')->count())->toBe(1);
|
||||
|
||||
$controller->update(($this->profileRequest)([
|
||||
'aset' => [['jenis_aset' => 'Timbangan', 'status_aset' => 0]],
|
||||
]), $group);
|
||||
expect($existing->fresh()->trashed())->toBeTrue();
|
||||
expect($group->aset()->pluck('jenis_aset')->all())->toBe(['Mesin pengering']);
|
||||
});
|
||||
|
||||
test('asset save rolls back standard changes if additional asset creation fails', function () {
|
||||
$group = ($this->kelompok)();
|
||||
$existing = $group->aset()->create([
|
||||
'uid' => 'AKT-TEST', 'jenis_aset' => 'Timbangan', 'status_aset' => true,
|
||||
'status_pengelolaan_aset' => 'Hibah', 'kondisi_aset' => 'Berfungsi',
|
||||
]);
|
||||
Event::listen('eloquent.creating: ' . AsetKelompokTani::class, function ($asset) {
|
||||
if ($asset->jenis_aset === 'Mesin gagal') throw new RuntimeException('Simulated failure');
|
||||
});
|
||||
$request = ($this->profileRequest)([
|
||||
'aset' => [['jenis_aset' => 'Timbangan', 'status_aset' => 0]],
|
||||
'aset_lainnya' => [['jenis_aset' => 'Mesin gagal']],
|
||||
]);
|
||||
expect(fn () => app(AsetKelompokTaniController::class)->update($request, $group))->toThrow(RuntimeException::class);
|
||||
expect($existing->fresh()->trashed())->toBeFalse();
|
||||
expect($group->aset()->count())->toBe(1);
|
||||
});
|
||||
|
||||
test('asset card has one shared form and preserves inputs after validation errors', function () {
|
||||
$group = ($this->kelompok)();
|
||||
$existing = $group->aset()->create([
|
||||
'uid' => 'AKT-TEST', 'jenis_aset' => 'Mesin lama', 'status_aset' => true,
|
||||
'status_pengelolaan_aset' => 'Hibah', 'kondisi_aset' => 'Berfungsi',
|
||||
]);
|
||||
($this->profileRequest)([], 'GET');
|
||||
session()->flashInput([
|
||||
'aset' => [['status_aset' => '1', 'status_pengelolaan_aset' => 'Pinjaman', 'kondisi_aset' => 'Mangkrak']],
|
||||
'aset_lainnya' => [['jenis_aset' => 'Mesin baru', 'status_pengelolaan_aset' => 'Sewa', 'kondisi_aset' => 'Berfungsi']],
|
||||
]);
|
||||
$dom = ($this->profileDom)(app(SurveyKelompokTaniController::class)->edit(($this->profileRequest)(['section' => 'aktivitas-fungsi'], 'GET'), $group));
|
||||
expect($dom->query('//div[@id="section-aset-baku"]//form[@id="aset-produktif-form"]')->length)->toBe(1);
|
||||
expect($dom->query('//form[@id="aset-produktif-form"]//div[@id="section-aset-lainnya"]')->length)->toBe(1);
|
||||
expect($dom->query('//form[@id="aset-produktif-form"]//button[contains(@class,"btn-success")]')->length)->toBe(1);
|
||||
expect($dom->query('//form[@id="aset-produktif-form"]//form')->length)->toBe(0);
|
||||
expect($dom->query('//form[@id="aset-produktif-form"]//input[@value="Mesin baru"]')->length)->toBe(1);
|
||||
expect($dom->query('//form[@id="aset-produktif-form"]//select[@name="aset[0][status_pengelolaan_aset]"]/option[@selected]')->item(0)->getAttribute('value'))->toBe('Pinjaman');
|
||||
expect($dom->query('//form[@id="aset-produktif-form"]//select[@name="status_pengelolaan_aset"]/option[@selected]')->item(0)->getAttribute('value'))->toBe('Sewa');
|
||||
expect($dom->query('//button[@form="delete-aset-' . $existing->id . '"]')->length)->toBe(1);
|
||||
expect($dom->query('//form[@id="delete-aset-' . $existing->id . '"]')->length)->toBe(1);
|
||||
});
|
||||
|
||||
test('cash management is visible only when the cash asset is present or selected in old input', function (?bool $savedStatus, bool $deleted, ?string $oldStatus, bool $visible) {
|
||||
$group = ($this->kelompok)();
|
||||
if ($savedStatus !== null) {
|
||||
$asset = $group->aset()->create([
|
||||
'uid' => 'AKT-KAS', 'jenis_aset' => 'Kas/simpanan kelompok', 'status_aset' => $savedStatus,
|
||||
'status_pengelolaan_aset' => 'Swadaya', 'kondisi_aset' => 'Berfungsi',
|
||||
]);
|
||||
if ($deleted) $asset->delete();
|
||||
}
|
||||
($this->profileRequest)([], 'GET');
|
||||
if ($oldStatus !== null) {
|
||||
$cashIndex = array_search('Kas/simpanan kelompok', AsetKelompokTaniController::JENIS_ASET_BAKU, true);
|
||||
session()->flashInput(['aset' => [$cashIndex => ['status_aset' => $oldStatus]]]);
|
||||
}
|
||||
$dom = ($this->profileDom)(app(SurveyKelompokTaniController::class)->edit(($this->profileRequest)(['section' => 'aktivitas-fungsi'], 'GET'), $group));
|
||||
expect($dom->query('//div[@id="section-kas"]')->item(0)->hasAttribute('hidden'))->toBe(!$visible);
|
||||
expect($dom->query('//tr[@data-aset-kas]//input[@value="1"]')->item(0)->hasAttribute('checked'))->toBe($visible);
|
||||
})->with([
|
||||
[null, false, null, false],
|
||||
[true, false, null, true],
|
||||
[false, false, null, false],
|
||||
[true, true, null, false],
|
||||
[true, false, '0', false],
|
||||
[null, false, '1', true],
|
||||
]);
|
||||
|
||||
test('the combined tab contains activities assets and cash management with one header', function () {
|
||||
$group = ($this->kelompok)();
|
||||
$group->aset()->create([
|
||||
'uid' => 'AKT-KAS', 'jenis_aset' => 'Kas/simpanan kelompok', 'status_aset' => true,
|
||||
'status_pengelolaan_aset' => 'Swadaya', 'kondisi_aset' => 'Berfungsi',
|
||||
]);
|
||||
$request = ($this->profileRequest)(['section' => 'aktivitas-fungsi'], 'GET');
|
||||
$route = (new Illuminate\Routing\Route('GET', '/survey/kelompok-tani/{kelompokTani}/edit', fn () => null))->name('kelompok-tani.edit');
|
||||
$request->setRouteResolver(fn () => $route);
|
||||
$dom = ($this->profileDom)(app(SurveyKelompokTaniController::class)->edit($request, $group));
|
||||
|
||||
expect($dom->query('//div[@id="kelompok-tani-summary"]')->length)->toBe(1);
|
||||
expect($dom->query('//div[@id="section-aktivitas-fungsi"]')->length)->toBe(1);
|
||||
expect($dom->query('//div[@id="section-aset-baku"]')->length)->toBe(1);
|
||||
expect($dom->query('//div[@id="section-kas"]')->item(0)->hasAttribute('hidden'))->toBeFalse();
|
||||
expect($dom->query('//div[@id="section-status-bantuan"]')->length)->toBe(1);
|
||||
expect($dom->query('//div[@id="section-penilaian"]')->length)->toBe(0);
|
||||
expect($dom->query('//ul[contains(@class,"nav-pills")]//a[normalize-space()="Bantuan & Penilaian"]')->length)->toBe(0);
|
||||
expect($dom->query('//ul[contains(@class,"nav-pills")]//a[contains(@class,"active") and normalize-space()="Operasional"]')->length)->toBe(1);
|
||||
expect($dom->query('//ul[contains(@class,"nav-pills")]//a[normalize-space()="Aset & Keuangan"]')->length)->toBe(0);
|
||||
});
|
||||
|
||||
test('asset actions and cash saves return to the combined tab', function () {
|
||||
$group = ($this->kelompok)();
|
||||
$controller = app(AsetKelompokTaniController::class);
|
||||
$url = route('kelompok-tani.edit', $group->id) . '?section=aktivitas-fungsi';
|
||||
expect($controller->index($group)->getTargetUrl())->toBe($url . '#section-aset-baku');
|
||||
|
||||
$response = $controller->store(($this->profileRequest)([
|
||||
'aset_lainnya' => [['jenis_aset' => 'Mesin pengering']],
|
||||
], 'POST'), $group);
|
||||
expect($response->getTargetUrl())->toBe($url . '#section-status-bantuan');
|
||||
$response = $controller->destroy($group, $group->aset()->firstOrFail());
|
||||
expect($response->getTargetUrl())->toBe($url . '#section-aset-lainnya');
|
||||
|
||||
$response = app(SurveyKelompokTaniController::class)->update(($this->profileRequest)([
|
||||
'section' => 'kas', 'pengelola_kas' => 'Bendahara kelompok',
|
||||
]), $group);
|
||||
expect($response->getTargetUrl())->toBe($url . '#section-status-bantuan');
|
||||
expect($group->refresh()->pengelola_kas)->toBe('Bendahara kelompok');
|
||||
});
|
||||
|
||||
test('present assets require both management status and condition before saving any assets', function ($status) {
|
||||
$group = ($this->kelompok)();
|
||||
$request = ($this->profileRequest)([
|
||||
'aset' => [['jenis_aset' => 'Timbangan', 'status_aset' => $status]],
|
||||
'aset_lainnya' => [['jenis_aset' => 'Mesin pengering']],
|
||||
]);
|
||||
try {
|
||||
app(AsetKelompokTaniController::class)->update($request, $group);
|
||||
$this->fail('An asset marked Ada must require management status and condition.');
|
||||
} catch (ValidationException $exception) {
|
||||
expect(array_keys($exception->errors()))->toBe([
|
||||
'aset.0.status_pengelolaan_aset', 'aset.0.kondisi_aset',
|
||||
]);
|
||||
expect($exception->errors()['aset.0.kondisi_aset'][0])->toBe('Kondisi wajib diisi jika aset dipilih Ada.');
|
||||
}
|
||||
expect($group->aset()->count())->toBe(0);
|
||||
})->with(['1', 1, true]);
|
||||
|
||||
test('asset requirements follow each row and reject blank values', function (array $details, string $missingField) {
|
||||
$group = ($this->kelompok)();
|
||||
$request = ($this->profileRequest)([
|
||||
'aset' => [
|
||||
['jenis_aset' => 'Timbangan', 'status_aset' => '0'],
|
||||
['jenis_aset' => 'Gudang/tempat simpan', 'status_aset' => '1', ...$details],
|
||||
],
|
||||
]);
|
||||
try {
|
||||
app(AsetKelompokTaniController::class)->update($request, $group);
|
||||
$this->fail('The selected asset has a missing detail.');
|
||||
} catch (ValidationException $exception) {
|
||||
expect(array_keys($exception->errors()))->toBe(['aset.1.' . $missingField]);
|
||||
}
|
||||
expect($group->aset()->count())->toBe(0);
|
||||
})->with([
|
||||
[['status_pengelolaan_aset' => '', 'kondisi_aset' => 'Berfungsi'], 'status_pengelolaan_aset'],
|
||||
[['status_pengelolaan_aset' => 'Hibah', 'kondisi_aset' => null], 'kondisi_aset'],
|
||||
[['status_pengelolaan_aset' => 'Hibah', 'kondisi_aset' => ' '], 'kondisi_aset'],
|
||||
]);
|
||||
|
||||
test('asset dropdowns are required only on rows selected Ada', function (bool $present) {
|
||||
$group = ($this->kelompok)();
|
||||
$group->aset()->create([
|
||||
'uid' => 'AKT-TEST', 'jenis_aset' => 'Timbangan', 'status_aset' => $present,
|
||||
'status_pengelolaan_aset' => 'Hibah', 'kondisi_aset' => 'Berfungsi',
|
||||
]);
|
||||
$request = ($this->profileRequest)(['section' => 'aktivitas-fungsi'], 'GET');
|
||||
$dom = ($this->profileDom)(app(SurveyKelompokTaniController::class)->edit($request, $group));
|
||||
$index = array_search('Timbangan', AsetKelompokTaniController::JENIS_ASET_BAKU, true);
|
||||
foreach (['status_pengelolaan_aset', 'kondisi_aset'] as $field) {
|
||||
$select = $dom->query('//select[@name="aset[' . $index . '][' . $field . ']"]')->item(0);
|
||||
expect($select->hasAttribute('required'))->toBe($present);
|
||||
expect($select->hasAttribute('disabled'))->toBe(!$present);
|
||||
}
|
||||
})->with([true, false]);
|
||||
|
||||
test('asset validation errors appear beside the marked required dropdowns', function () {
|
||||
$group = ($this->kelompok)();
|
||||
$request = ($this->profileRequest)(['section' => 'aktivitas-fungsi'], 'GET');
|
||||
session()->flashInput(['aset' => [['status_aset' => '1']]]);
|
||||
$messages = [
|
||||
'aset.0.status_pengelolaan_aset' => 'Status Pengelolaan wajib diisi jika aset dipilih Ada.',
|
||||
'aset.0.kondisi_aset' => 'Kondisi wajib diisi jika aset dipilih Ada.',
|
||||
];
|
||||
$errors = new ViewErrorBag();
|
||||
$errors->put('default', new Illuminate\Support\MessageBag($messages));
|
||||
view()->share('errors', $errors);
|
||||
$dom = ($this->profileDom)(app(SurveyKelompokTaniController::class)->edit($request, $group));
|
||||
|
||||
expect($dom->query('//form[@id="aset-produktif-form"]//th/span[contains(@class,"text-danger")]')->length)->toBe(2);
|
||||
foreach (['status_pengelolaan_aset' => 'status-pengelolaan', 'kondisi_aset' => 'kondisi'] as $field => $idPart) {
|
||||
$id = 'aset-0-' . $idPart;
|
||||
$select = $dom->query('//select[@id="' . $id . '"]')->item(0);
|
||||
expect($select->getAttribute('class'))->toContain('is-invalid');
|
||||
expect($select->getAttribute('aria-describedby'))->toBe($id . '-error');
|
||||
expect(trim($dom->query('//div[@id="' . $id . '-error"]')->item(0)->textContent))->toBe($messages['aset.0.' . $field]);
|
||||
}
|
||||
});
|
||||
|
||||
test('saving assets advances to cash only when the cash section is available', function (bool $hasCash) {
|
||||
$group = ($this->kelompok)();
|
||||
$controller = app(AsetKelompokTaniController::class);
|
||||
$input = ['aset' => [[
|
||||
'jenis_aset' => 'Kas/simpanan kelompok', 'status_aset' => $hasCash,
|
||||
'status_pengelolaan_aset' => 'Swadaya', 'kondisi_aset' => 'Berfungsi',
|
||||
]]];
|
||||
$response = $controller->update(($this->profileRequest)($input), $group);
|
||||
$url = route('kelompok-tani.edit', $group->id) . '?section=aktivitas-fungsi';
|
||||
expect($response->getTargetUrl())->toBe($url . ($hasCash ? '#section-kas' : '#section-status-bantuan'));
|
||||
|
||||
$input['aset'][0]['status_aset'] = false;
|
||||
$response = $controller->update(($this->profileRequest)($input), $group);
|
||||
expect($response->getTargetUrl())->toBe($url . '#section-status-bantuan');
|
||||
})->with([true, false]);
|
||||
|
||||
test('saving aid status stays on the combined aid card in Operasional', function (bool $hasAid) {
|
||||
$group = ($this->kelompok)();
|
||||
$response = app(SurveyKelompokTaniController::class)->update(($this->profileRequest)([
|
||||
'section' => 'status-bantuan', 'pernah_mendapatkan_bantuan' => $hasAid,
|
||||
'bantuan' => $hasAid ? [['nama_program' => 'Program A', 'penyelenggara' => 'Dinas', 'bentuk_bantuan' => 'Bibit', 'tahun' => 2026]] : [],
|
||||
]), $group);
|
||||
$url = route('kelompok-tani.edit', $group->id) . '?section=aktivitas-fungsi';
|
||||
expect($response->getTargetUrl())->toBe($url . '#section-status-bantuan');
|
||||
})->with([true, false]);
|
||||
|
||||
test('legacy aid saves return to Operasional and failed saves retain the notification target', function () {
|
||||
$group = ($this->kelompok)(['pernah_mendapatkan_bantuan' => true]);
|
||||
$controller = app(BantuanKelompokTaniController::class);
|
||||
$response = $controller->store(($this->profileRequest)(['bantuan' => [[
|
||||
'nama_program' => 'Bibit Kakao', 'penyelenggara' => 'Dinas Pertanian', 'bentuk_bantuan' => 'Bibit', 'tahun' => 2026,
|
||||
]]], 'POST'), $group);
|
||||
$url = route('kelompok-tani.edit', $group->id) . '?section=aktivitas-fungsi';
|
||||
expect($response->getTargetUrl())->toBe($url . '#section-status-bantuan');
|
||||
|
||||
$group->update(['pernah_mendapatkan_bantuan' => false]);
|
||||
$response = $controller->store(($this->profileRequest)([], 'POST'), $group);
|
||||
expect($response->getTargetUrl())->toBe($url . '#kelompok-tani-notifications');
|
||||
expect($group->bantuan()->count())->toBe(1);
|
||||
});
|
||||
|
||||
test('single and final section saves stay on their own box', function () {
|
||||
$group = ($this->kelompok)();
|
||||
$controller = app(SurveyKelompokTaniController::class);
|
||||
foreach ([
|
||||
'kelembagaan' => ['cakupan_wilayah' => 'Desa'],
|
||||
'sosial-konflik' => ['konflik_kelompok' => 'Tidak pernah'],
|
||||
] as $section => $input) {
|
||||
$response = $controller->update(($this->profileRequest)(['section' => $section, ...$input]), $group);
|
||||
expect(parse_url($response->getTargetUrl(), PHP_URL_FRAGMENT))->toBe('section-' . $section);
|
||||
}
|
||||
});
|
||||
|
||||
test('invalid required fields return Indonesian errors above the summary and beside each field', function (string $section, array $payload, array $messages) {
|
||||
$group = ($this->kelompok)();
|
||||
$url = route('kelompok-tani.edit', $group->id) . ($section === 'identitas' ? '' : '?section=' . ($section === 'status-bantuan' ? 'aktivitas-fungsi' : $section));
|
||||
$response = $this->from($url)->put(route('kelompok-tani.update', $group->id), ['section' => $section, ...$payload]);
|
||||
$response->assertRedirect($url)->assertSessionHasErrors(array_keys($messages));
|
||||
$page = $this->get($url)->assertOk();
|
||||
expect(strpos($page->getContent(), 'id="kelompok-tani-notifications"'))->toBeLessThan(strpos($page->getContent(), 'id="kelompok-tani-summary"'));
|
||||
|
||||
$dom = new DOMDocument();
|
||||
libxml_use_internal_errors(true);
|
||||
$dom->loadHTML($page->getContent());
|
||||
libxml_clear_errors();
|
||||
$xpath = new DOMXPath($dom);
|
||||
$summary = $xpath->query('//div[@id="kelompok-tani-notifications"]')->item(0)->textContent;
|
||||
$inlineMessages = collect($xpath->query('//div[contains(@class,"invalid-feedback")]'))->map(fn ($node) => trim($node->textContent))->all();
|
||||
foreach ($messages as $message) {
|
||||
expect($summary)->toContain($message);
|
||||
expect($inlineMessages)->toContain($message);
|
||||
}
|
||||
expect($xpath->query('//input[contains(@class,"is-invalid")] | //select[contains(@class,"is-invalid")]')->length)->toBeGreaterThan(0);
|
||||
expect($group->refresh()->nama_kelompok)->toBe('Kelompok A');
|
||||
})->with([
|
||||
['identitas', [], [
|
||||
'nama_responden' => 'Nama responden wajib diisi.', 'nama_kelompok' => 'Nama kelompok wajib diisi.',
|
||||
'provinsi_id' => 'Provinsi wajib diisi.', 'kabupaten_id' => 'Kabupaten/Kota wajib diisi.',
|
||||
'kecamatan_id' => 'Kecamatan wajib diisi.', 'desa_kelurahan_id' => 'Desa/Kelurahan wajib dipilih.',
|
||||
'jenis_kelompok' => 'Terdaftar/Dikenal Sebagai wajib diisi.',
|
||||
]],
|
||||
['identitas', ['jenis_kelompok' => 'Lainnya'], ['jenis_kelompok_lainnya' => 'Sebutkan Jenis Kelompok wajib diisi.']],
|
||||
['status-bantuan', [], ['pernah_mendapatkan_bantuan' => 'Pengalaman Akses Bantuan/Program wajib diisi.']],
|
||||
['status-bantuan', ['pernah_mendapatkan_bantuan' => '1', 'bantuan' => [[]]], [
|
||||
'bantuan.0.nama_program' => 'Nama Program/Bantuan pada baris pertama wajib diisi.',
|
||||
'bantuan.0.penyelenggara' => 'Penyelenggara pada baris pertama wajib diisi.',
|
||||
'bantuan.0.bentuk_bantuan' => 'Bentuk Bantuan pada baris pertama wajib diisi.',
|
||||
'bantuan.0.tahun' => 'Tahun pada baris pertama wajib diisi.',
|
||||
]],
|
||||
['sosial-konflik', ['konflik_kelompok' => 'Pernah, sudah selesai'], [
|
||||
'topik_konflik' => 'Jika Pernah, Soal Apa? wajib diisi jika pernah terjadi konflik internal.',
|
||||
]],
|
||||
]);
|
||||
|
||||
test('asset errors show together above the summary and beside both conditional dropdowns', function () {
|
||||
$group = ($this->kelompok)();
|
||||
$url = route('kelompok-tani.edit', $group->id) . '?section=aktivitas-fungsi';
|
||||
$this->from($url)->put(route('kelompok-tani.aset-keuangan.update', $group->id), [
|
||||
'aset' => [['jenis_aset' => AsetKelompokTaniController::JENIS_ASET_BAKU[0], 'status_aset' => '1']],
|
||||
])->assertRedirect($url)->assertSessionHasErrors(['aset.0.status_pengelolaan_aset', 'aset.0.kondisi_aset']);
|
||||
$page = $this->get($url)->assertOk();
|
||||
foreach (['Status Pengelolaan wajib diisi jika aset dipilih Ada.', 'Kondisi wajib diisi jika aset dipilih Ada.'] as $message) {
|
||||
expect(substr_count($page->getContent(), $message))->toBeGreaterThanOrEqual(2);
|
||||
}
|
||||
expect($group->aset()->count())->toBe(0);
|
||||
});
|
||||
|
||||
test('profile location choices survive a failed save on both create and edit', function (bool $creating) {
|
||||
$group = ($this->kelompok)();
|
||||
$url = $creating ? route('kelompok-tani.create') : route('kelompok-tani.edit', $group->id);
|
||||
$input = ['provinsi_id' => 1, 'kabupaten_id' => 1, 'kecamatan_id' => 1, 'desa_kelurahan_id' => 1, 'jenis_kelompok' => 'Kelompok Tani (Poktan)'];
|
||||
$response = $creating
|
||||
? $this->from($url)->post(route('kelompok-tani.store'), $input)
|
||||
: $this->from($url)->put(route('kelompok-tani.update', $group->id), $input);
|
||||
$response->assertRedirect($url)->assertSessionHasErrors(['nama_responden', 'nama_kelompok']);
|
||||
$page = $this->get($url)->assertOk();
|
||||
$dom = new DOMDocument();
|
||||
libxml_use_internal_errors(true);
|
||||
$dom->loadHTML($page->getContent());
|
||||
libxml_clear_errors();
|
||||
$xpath = new DOMXPath($dom);
|
||||
foreach (array_keys($input) as $field) {
|
||||
expect($xpath->query('//select[@name="' . $field . '"]/option[@selected]')->length)->toBe(1);
|
||||
}
|
||||
expect($xpath->query('//select[@name="desa_kelurahan_id" and @disabled]')->length)->toBe(0);
|
||||
})->with([true, false]);
|
||||
|
||||
test('invalid location input returns feedback without breaking the form reload', function ($invalidId) {
|
||||
$url = route('kelompok-tani.create');
|
||||
$this->from($url)->post(route('kelompok-tani.store'), [
|
||||
'provinsi_id' => $invalidId, 'kabupaten_id' => $invalidId, 'kecamatan_id' => $invalidId, 'desa_kelurahan_id' => $invalidId,
|
||||
])->assertRedirect($url)->assertSessionHasErrors(['provinsi_id', 'kabupaten_id', 'kecamatan_id', 'desa_kelurahan_id']);
|
||||
$this->get($url)->assertOk()->assertSee('Pilihan Provinsi tidak valid.');
|
||||
})->with([[['invalid']], ['1.5'], ['invalid']]);
|
||||
|
||||
test('aid experience and program entries are saved together in Operasional', function () {
|
||||
$group = ($this->kelompok)(['pernah_mendapatkan_bantuan' => false]);
|
||||
$response = app(SurveyKelompokTaniController::class)->update(($this->profileRequest)([
|
||||
'section' => 'status-bantuan', 'pernah_mendapatkan_bantuan' => '1',
|
||||
'bantuan' => [
|
||||
['nama_program' => 'Bibit Kakao', 'penyelenggara' => 'Dinas Pertanian', 'bentuk_bantuan' => 'Bibit', 'tahun' => 2026],
|
||||
['nama_program' => '', 'penyelenggara' => '', 'bentuk_bantuan' => '', 'tahun' => null],
|
||||
],
|
||||
]), $group);
|
||||
expect($group->refresh()->pernah_mendapatkan_bantuan)->toBeTrue();
|
||||
expect($group->bantuan()->pluck('nama_program')->all())->toBe(['Bibit Kakao']);
|
||||
expect($response->getTargetUrl())->toBe(route('kelompok-tani.edit', $group->id) . '?section=aktivitas-fungsi#section-status-bantuan');
|
||||
expect(session('success'))->toBe('Data Operasional berhasil disimpan.');
|
||||
});
|
||||
|
||||
test('answering Belum Pernah ignores hidden program payloads and preserves existing history', function ($payload) {
|
||||
$group = ($this->kelompok)(['pernah_mendapatkan_bantuan' => true]);
|
||||
$group->bantuan()->create([
|
||||
'uid' => 'BKT-TEST', 'nama_program' => 'Program Lama', 'penyelenggara' => 'Dinas', 'bentuk_bantuan' => 'Bibit',
|
||||
]);
|
||||
app(SurveyKelompokTaniController::class)->update(($this->profileRequest)([
|
||||
'section' => 'status-bantuan', 'pernah_mendapatkan_bantuan' => '0', 'bantuan' => $payload,
|
||||
]), $group);
|
||||
expect($group->refresh()->pernah_mendapatkan_bantuan)->toBeFalse();
|
||||
expect($group->bantuan()->pluck('nama_program')->all())->toBe(['Program Lama']);
|
||||
})->with([
|
||||
['malformed'],
|
||||
[[['nama_program' => ['invalid'], 'tahun' => 'invalid']]],
|
||||
]);
|
||||
|
||||
test('invalid aid entries cannot partially update the experience answer', function () {
|
||||
$group = ($this->kelompok)(['pernah_mendapatkan_bantuan' => false]);
|
||||
$request = ($this->profileRequest)([
|
||||
'section' => 'status-bantuan', 'pernah_mendapatkan_bantuan' => '1',
|
||||
'bantuan' => [['nama_program' => 'Program A', 'tahun' => date('Y') + 1]],
|
||||
]);
|
||||
expect(fn () => app(SurveyKelompokTaniController::class)->update($request, $group))->toThrow(ValidationException::class);
|
||||
expect($group->refresh()->pernah_mendapatkan_bantuan)->toBeFalse();
|
||||
expect($group->bantuan()->count())->toBe(0);
|
||||
});
|
||||
|
||||
test('aid creation failures roll back the experience answer', function () {
|
||||
$group = ($this->kelompok)(['pernah_mendapatkan_bantuan' => false]);
|
||||
Event::listen('eloquent.creating: ' . BantuanKelompokTani::class, function () {
|
||||
throw new RuntimeException('Simulated aid failure');
|
||||
});
|
||||
$request = ($this->profileRequest)([
|
||||
'section' => 'status-bantuan', 'pernah_mendapatkan_bantuan' => '1',
|
||||
'bantuan' => [['nama_program' => 'Program A', 'penyelenggara' => 'Dinas', 'bentuk_bantuan' => 'Bibit', 'tahun' => 2026]],
|
||||
]);
|
||||
expect(fn () => app(SurveyKelompokTaniController::class)->update($request, $group))->toThrow(RuntimeException::class);
|
||||
expect($group->refresh()->pernah_mendapatkan_bantuan)->toBeFalse();
|
||||
expect($group->bantuan()->count())->toBe(0);
|
||||
});
|
||||
|
||||
test('aid list shares the experience box and is only visible for Pernah', function (?bool $savedAnswer, ?string $oldAnswer, bool $visible) {
|
||||
$group = ($this->kelompok)(['pernah_mendapatkan_bantuan' => $savedAnswer]);
|
||||
$request = ($this->profileRequest)(['section' => 'aktivitas-fungsi'], 'GET');
|
||||
if ($oldAnswer !== null) {
|
||||
session()->flashInput([
|
||||
'pernah_mendapatkan_bantuan' => $oldAnswer,
|
||||
'bantuan' => [['nama_program' => 'Program belum disimpan', 'penyelenggara' => 'Dinas', 'bentuk_bantuan' => 'Bibit', 'tahun' => 2026]],
|
||||
]);
|
||||
}
|
||||
$dom = ($this->profileDom)(app(SurveyKelompokTaniController::class)->edit($request, $group));
|
||||
expect($dom->query('//form[@id="pengalaman-bantuan-form"]//div[@id="section-bantuan"]')->length)->toBe(1);
|
||||
expect($dom->query('//div[@id="section-bantuan"]')->item(0)->hasAttribute('hidden'))->toBe(!$visible);
|
||||
expect($dom->query('//fieldset[@id="bantuan-fields"]')->item(0)->hasAttribute('disabled'))->toBe(!$visible);
|
||||
expect($dom->query('//form[@id="pengalaman-bantuan-form"]//button[contains(@class,"btn-success")]')->length)->toBe(1);
|
||||
expect($dom->query('//form[@id="pengalaman-bantuan-form"]//form')->length)->toBe(0);
|
||||
expect($dom->query('//div[@id="section-penilaian"] | //input[@name="potensi_kelompok"] | //textarea[@name="alasan_penilaian_potensi"]')->length)->toBe(0);
|
||||
if ($oldAnswer !== null) {
|
||||
expect($dom->query('//form[@id="pengalaman-bantuan-form"]//input[@value="Program belum disimpan"]')->length)->toBe(1);
|
||||
}
|
||||
})->with([
|
||||
[null, null, false], [false, null, false], [true, null, true], [true, '0', false], [false, '1', true],
|
||||
]);
|
||||
|
||||
test('old aid URLs redirect to Operasional and removed assessment fields cannot be saved', function () {
|
||||
$group = ($this->kelompok)(['potensi_kelompok' => 'Rendah']);
|
||||
$url = route('kelompok-tani.edit', $group->id) . '?section=aktivitas-fungsi#section-status-bantuan';
|
||||
expect(app(BantuanKelompokTaniController::class)->index($group)->getTargetUrl())->toBe($url);
|
||||
$response = app(SurveyKelompokTaniController::class)->update(($this->profileRequest)([
|
||||
'section' => 'penilaian', 'potensi_kelompok' => 'Tinggi', 'alasan_penilaian_potensi' => 'Diabaikan',
|
||||
]), $group);
|
||||
expect($response->getTargetUrl())->toBe($url);
|
||||
expect($group->refresh()->potensi_kelompok)->toBe('Rendah');
|
||||
});
|
||||
|
||||
test('Pernah requires every first-row aid field before saving', function (string $missing) {
|
||||
$group = ($this->kelompok)(['pernah_mendapatkan_bantuan' => false]);
|
||||
$row = ['nama_program' => 'Program A', 'penyelenggara' => 'Dinas', 'bentuk_bantuan' => 'Bibit', 'tahun' => 2026];
|
||||
$row[$missing] = ' ';
|
||||
$request = ($this->profileRequest)(['pernah_mendapatkan_bantuan' => '1', 'bantuan' => [$row]]);
|
||||
try {
|
||||
app(BantuanKelompokTaniController::class)->update($request, $group);
|
||||
$this->fail('An incomplete first row must be rejected.');
|
||||
} catch (ValidationException $exception) {
|
||||
expect($exception->errors())->toHaveKey('bantuan.0.' . $missing);
|
||||
}
|
||||
expect($group->refresh()->pernah_mendapatkan_bantuan)->toBeFalse();
|
||||
expect($group->bantuan()->count())->toBe(0);
|
||||
})->with(['nama_program', 'penyelenggara', 'bentuk_bantuan', 'tahun']);
|
||||
|
||||
test('Pernah rejects missing first aid rows including attempts to skip the first index', function ($rows) {
|
||||
$group = ($this->kelompok)();
|
||||
$request = ($this->profileRequest)(['pernah_mendapatkan_bantuan' => '1', 'bantuan' => $rows]);
|
||||
expect(fn () => app(BantuanKelompokTaniController::class)->update($request, $group))->toThrow(ValidationException::class);
|
||||
expect($group->bantuan()->count())->toBe(0);
|
||||
})->with([
|
||||
[null], [[]], [[[]]],
|
||||
[[1 => ['nama_program' => 'Program A', 'penyelenggara' => 'Dinas', 'bentuk_bantuan' => 'Bibit', 'tahun' => 2026]]],
|
||||
]);
|
||||
|
||||
test('recorded aid meets the minimum without requiring a duplicate entry', function () {
|
||||
$group = ($this->kelompok)(['pernah_mendapatkan_bantuan' => true]);
|
||||
$group->bantuan()->create(['uid' => 'BKT-EXISTING', 'nama_program' => 'Program Lama', 'penyelenggara' => 'Dinas', 'bentuk_bantuan' => 'Bibit']);
|
||||
app(BantuanKelompokTaniController::class)->update(($this->profileRequest)(['pernah_mendapatkan_bantuan' => '1']), $group);
|
||||
expect($group->bantuan()->count())->toBe(1);
|
||||
|
||||
app(BantuanKelompokTaniController::class)->update(($this->profileRequest)([
|
||||
'pernah_mendapatkan_bantuan' => '1', 'bantuan' => [['nama_program' => 'Program Tambahan'], []],
|
||||
]), $group);
|
||||
expect($group->bantuan()->count())->toBe(2);
|
||||
});
|
||||
|
||||
test('an optional aid row with details still needs a program name', function () {
|
||||
$group = ($this->kelompok)(['pernah_mendapatkan_bantuan' => true]);
|
||||
$group->bantuan()->create(['uid' => 'BKT-EXISTING', 'nama_program' => 'Program Lama', 'penyelenggara' => 'Dinas', 'bentuk_bantuan' => 'Bibit']);
|
||||
$request = ($this->profileRequest)(['pernah_mendapatkan_bantuan' => '1', 'bantuan' => [['penyelenggara' => 'Dinas']]]);
|
||||
expect(fn () => app(BantuanKelompokTaniController::class)->update($request, $group))->toThrow(ValidationException::class);
|
||||
expect($group->bantuan()->count())->toBe(1);
|
||||
});
|
||||
|
||||
test('required aid markers only apply to the first unsaved row for Pernah', function (bool $pernah, bool $saved) {
|
||||
$group = ($this->kelompok)(['pernah_mendapatkan_bantuan' => $pernah]);
|
||||
if ($saved) {
|
||||
$group->bantuan()->create(['uid' => 'BKT-EXISTING', 'nama_program' => 'Program Lama', 'penyelenggara' => 'Dinas', 'bentuk_bantuan' => 'Bibit']);
|
||||
}
|
||||
$request = ($this->profileRequest)(['section' => 'aktivitas-fungsi'], 'GET');
|
||||
session()->flashInput(['bantuan' => [[], []]]);
|
||||
$dom = ($this->profileDom)(app(SurveyKelompokTaniController::class)->edit($request, $group));
|
||||
$expected = $pernah && !$saved ? 4 : 0;
|
||||
expect($dom->query('//fieldset[@id="bantuan-fields"]//input[@required]')->length)->toBe($expected);
|
||||
expect($dom->query('//fieldset[@id="bantuan-fields"]//span[contains(@class,"bantuan-required-mark") and not(@hidden)]')->length)->toBe($expected);
|
||||
expect($dom->query('//div[@data-repeater-list="bantuan"]/div[2]//input[@required]')->length)->toBe(0);
|
||||
expect($dom->query('//div[@id="section-bantuan"]/p[normalize-space()="Minimal satu data bantuan wajib diisi."]')->length)->toBe(1);
|
||||
$firstRow = $saved
|
||||
? '//div[@id="section-bantuan"]/div[1]'
|
||||
: '//div[@data-repeater-list="bantuan"]/div[1]';
|
||||
foreach (['Nama Program/Bantuan', 'Penyelenggara', 'Bentuk Bantuan', 'Tahun'] as $label) {
|
||||
$marks = $dom->query($firstRow . '//label[starts-with(normalize-space(),"' . $label . '")]/span[contains(@class,"text-danger") and not(@hidden)]');
|
||||
expect($marks->length)->toBe($saved || $pernah ? 1 : 0);
|
||||
}
|
||||
})->with([[true, false], [false, false], [true, true]]);
|
||||
|
||||
test('conflict topics are required for both Pernah answers without partial saves', function (string $answer, $topic) {
|
||||
$group = ($this->kelompok)(['konflik_kelompok' => 'Tidak pernah', 'partisipasi_perempuan' => 'Hadir tapi pasif']);
|
||||
$request = ($this->profileRequest)([
|
||||
'section' => 'sosial-konflik', 'konflik_kelompok' => $answer,
|
||||
'topik_konflik' => $topic, 'partisipasi_perempuan' => 'Tidak terlibat',
|
||||
]);
|
||||
try {
|
||||
app(SurveyKelompokTaniController::class)->update($request, $group);
|
||||
$this->fail('A conflict topic is required.');
|
||||
} catch (ValidationException $exception) {
|
||||
expect($exception->errors())->toHaveKey('topik_konflik');
|
||||
}
|
||||
expect($group->refresh()->konflik_kelompok)->toBe('Tidak pernah');
|
||||
expect($group->partisipasi_perempuan)->toBe('Hadir tapi pasif');
|
||||
})->with(['Pernah, sudah selesai', 'Pernah, masih berlanjut/belum selesai'])->with([null, '', ' ']);
|
||||
|
||||
test('social saves accept conflict topics and require none for other answers', function ($answer, bool $required) {
|
||||
$group = ($this->kelompok)();
|
||||
$request = ($this->profileRequest)([
|
||||
'section' => 'sosial-konflik', 'konflik_kelompok' => $answer,
|
||||
...($required ? ['topik_konflik' => 'Pembagian hasil'] : []),
|
||||
]);
|
||||
app(SurveyKelompokTaniController::class)->update($request, $group);
|
||||
expect($group->refresh()->topik_konflik)->toBe($required ? 'Pembagian hasil' : null);
|
||||
expect(session('success'))->toBe('Data Sosial berhasil disimpan.');
|
||||
|
||||
($this->profileRequest)(['section' => 'sosial-konflik'], 'GET');
|
||||
$dom = ($this->profileDom)(view('produktivitas.survey-kelompok-tani.sosial-konflik', ['kelompokTani' => $group]));
|
||||
$input = $dom->query('//input[@id="sk-topik-konflik"]')->item(0);
|
||||
expect($input->hasAttribute('required'))->toBe($required);
|
||||
expect($input->hasAttribute('disabled'))->toBe(!$required);
|
||||
expect($dom->query('//label[@for="sk-topik-konflik"]/span[not(@hidden)]')->length)->toBe($required ? 1 : 0);
|
||||
})->with([
|
||||
['Pernah, sudah selesai', true], ['Pernah, masih berlanjut/belum selesai', true],
|
||||
['Tidak pernah', false], ['Tidak bersedia menjawab', false], [null, false],
|
||||
]);
|
||||
|
||||
test('conflict topic requirements and input follow the previous submission after validation', function () {
|
||||
$group = ($this->kelompok)(['konflik_kelompok' => 'Tidak pernah']);
|
||||
($this->profileRequest)([], 'GET');
|
||||
session()->flashInput(['konflik_kelompok' => 'Pernah, sudah selesai', 'topik_konflik' => 'Pembagian hasil']);
|
||||
$dom = ($this->profileDom)(view('produktivitas.survey-kelompok-tani.sosial-konflik', ['kelompokTani' => $group]));
|
||||
$input = $dom->query('//input[@id="sk-topik-konflik"]')->item(0);
|
||||
expect($input->hasAttribute('required'))->toBeTrue();
|
||||
expect($input->getAttribute('value'))->toBe('Pembagian hasil');
|
||||
expect($dom->query('//div[@id="sk-detail-konflik-wrapper"]')->item(0)->hasAttribute('style'))->toBeFalse();
|
||||
});
|
||||
|
||||
test('the last recorded aid cannot be deleted while the answer remains Pernah', function () {
|
||||
$group = ($this->kelompok)(['pernah_mendapatkan_bantuan' => true]);
|
||||
$aid = $group->bantuan()->create(['uid' => 'BKT-EXISTING', 'nama_program' => 'Program Lama', 'penyelenggara' => 'Dinas', 'bentuk_bantuan' => 'Bibit']);
|
||||
$controller = app(BantuanKelompokTaniController::class);
|
||||
$response = $controller->destroy($group, $aid);
|
||||
expect($response->getTargetUrl())->toEndWith('#kelompok-tani-notifications');
|
||||
expect($group->bantuan()->count())->toBe(1);
|
||||
$other = $group->bantuan()->create(['uid' => 'BKT-OTHER', 'nama_program' => 'Program Lain', 'penyelenggara' => 'Dinas', 'bentuk_bantuan' => 'Bibit']);
|
||||
$controller->destroy($group, $aid);
|
||||
expect($group->bantuan()->count())->toBe(1);
|
||||
$group->update(['pernah_mendapatkan_bantuan' => false]);
|
||||
$controller->destroy($group, $other);
|
||||
expect($group->bantuan()->count())->toBe(0);
|
||||
});
|
||||
Reference in New Issue
Block a user