Update Kelompok Tani

This commit is contained in:
2026-11-05 21:30:38 +07:00
parent c55ff109a0
commit 291ebf919c
16 changed files with 823 additions and 413 deletions
@@ -3,6 +3,9 @@
namespace App\Http\Controllers\Web\Produktivitas;
use App\Http\Controllers\Controller;
use App\Http\Requests\Produktivitas\IndexKelompokTaniRequest;
use App\Services\Produktivitas\KelompokTaniService;
use Illuminate\View\View;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Str;
@@ -32,94 +35,10 @@ class SurveyKelompokTaniController extends Controller
]);
}
public function index(Request $request)
public function index(IndexKelompokTaniRequest $request): View
{
$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'],
]);
$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'
));
return view('produktivitas.survey-kelompok-tani.index', app(KelompokTaniService::class)->indexData($request->validated()));
}
public function create()
{
$this->authorizeAccess();
@@ -129,6 +48,7 @@ class SurveyKelompokTaniController extends Controller
return view('produktivitas.survey-kelompok-tani.add', [
...compact('provinsi', 'komoditas'),
'ringkasanProfil' => app(KelompokTaniService::class)->profileSummary(),
...$this->profileLocationOptions(),
]);
}
@@ -178,15 +98,18 @@ class SurveyKelompokTaniController extends Controller
public function edit(Request $request, KelompokTani $kelompokTani)
{
$this->authorizeAccess();
$ringkasanProfil = app(KelompokTaniService::class)->profileSummary($kelompokTani);
return match ($request->query('section', 'identitas')) {
'kelembagaan' => view('produktivitas.survey-kelompok-tani.kelembagaan', compact('kelompokTani')),
'kelembagaan' => view('produktivitas.survey-kelompok-tani.kelembagaan', compact('kelompokTani', 'ringkasanProfil')),
'aktivitas-fungsi' => view('produktivitas.survey-kelompok-tani.aktivitas-fungsi', [
'kelompokTani' => $kelompokTani->loadMissing(['aset', 'bantuan']),
'ringkasanProfil' => $ringkasanProfil,
]),
'sosial-konflik' => view('produktivitas.survey-kelompok-tani.sosial-konflik', compact('kelompokTani')),
'sosial-konflik' => view('produktivitas.survey-kelompok-tani.sosial-konflik', compact('kelompokTani', 'ringkasanProfil')),
default => view('produktivitas.survey-kelompok-tani.edit', [
'kelompokTani' => $kelompokTani->loadMissing('pengurus'),
'ringkasanProfil' => $ringkasanProfil,
'provinsi' => Provinsi::orderBy('kode', 'asc')->get(),
'komoditas' => Komoditas::where('is_utama', true)->get(),
...$this->profileLocationOptions($kelompokTani),
@@ -0,0 +1,55 @@
<?php
namespace App\Http\Requests\Produktivitas;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Gate;
class IndexKelompokTaniRequest extends FormRequest
{
public function authorize(): bool
{
return Gate::any(['super_admin', 'admin', 'enumerator']);
}
public function rules(): array
{
return [
'search' => ['nullable', 'string', 'max:255'],
'kabupaten_kota_id' => ['bail', 'nullable', 'integer', 'exists:master_kabupaten_kota,id'],
'kecamatan_id' => ['bail', 'nullable', 'integer', 'exists:master_kecamatan,id'],
'desa_kelurahan_id' => ['bail', 'nullable', 'integer', 'exists:master_desa_kelurahan,id'],
'komoditas_id' => ['bail', 'nullable', 'integer', 'exists:master_komoditas,id'],
'jenis_kelompok' => ['nullable', 'string', 'max:50'],
'status_legalitas' => ['nullable', 'string', 'max:50'],
'sort_by' => ['nullable', 'string', 'max:50'],
'per_page' => ['nullable', 'integer', 'in:10,25'],
];
}
public function messages(): array
{
return [
'integer' => ':attribute harus berupa angka bulat.',
'exists' => ':attribute tidak ditemukan.',
'string' => ':attribute harus berupa teks.',
'max' => ':attribute terlalu panjang.',
'in' => 'Pilihan :attribute tidak valid.',
];
}
public function attributes(): array
{
return [
'search' => 'Pencarian',
'kabupaten_kota_id' => 'Kabupaten/Kota',
'kecamatan_id' => 'Kecamatan',
'desa_kelurahan_id' => 'Desa/Kelurahan',
'komoditas_id' => 'Komoditas',
'jenis_kelompok' => 'Jenis kelompok',
'status_legalitas' => 'Status SK/Dokumen Pendaftaran',
'sort_by' => 'Urutan data',
'per_page' => 'Jumlah data per halaman',
];
}
}