diff --git a/app/Enums/KeparahanSerangan.php b/app/Enums/KeparahanSerangan.php index a030eb9..3fb078a 100644 --- a/app/Enums/KeparahanSerangan.php +++ b/app/Enums/KeparahanSerangan.php @@ -11,9 +11,9 @@ enum KeparahanSerangan: string public function label(): string { return match($this) { - self::RINGAN => 'Ringan', - self::SEDANG => 'Sedang', - self::BERAT => 'Berat', + self::RINGAN => 'Ringan, hanya beberapa tanaman', + self::SEDANG => 'Sedang, sebagian tanaman terdampak', + self::BERAT => 'Parah, sebagian besar tanaman terdampak', }; } diff --git a/app/Enums/KondisiTanaman.php b/app/Enums/KondisiTanaman.php index ae73179..4193e4b 100644 --- a/app/Enums/KondisiTanaman.php +++ b/app/Enums/KondisiTanaman.php @@ -13,10 +13,10 @@ enum KondisiTanaman: string public function label(): string { return match($this) { - self::BAIK => 'Baik', - self::SEDANG => 'Sedang', - self::BURUK => 'Buruk', - self::MATI => 'Mati', + self::BAIK => 'Baik, tumbuh lebat, banyak buah', + self::SEDANG => 'Sedang, cukup tumbuh, ada masalah', + self::BURUK => 'Buruk, banyak tanaman tua dan lemah/tidak berbuah', + self::MATI => 'Mati, tanaman telah mati, tidak dapat tumbuh maupun berbuah', }; } diff --git a/app/Http/Controllers/Web/Dashboard/SurveyPetaniController.php b/app/Http/Controllers/Web/Dashboard/SurveyPetaniController.php index 3c3042e..00886c5 100644 --- a/app/Http/Controllers/Web/Dashboard/SurveyPetaniController.php +++ b/app/Http/Controllers/Web/Dashboard/SurveyPetaniController.php @@ -11,6 +11,7 @@ use App\Models\User; use App\Models\Pertanian\Petani; use App\Models\Pertanian\Komoditas; use App\Models\Pertanian\Lahan; +use App\Models\Pertanian\Tanaman; use App\Models\Pertanian\SurveyPelatihan; use App\Models\Pertanian\SurveySertifikasi; @@ -143,24 +144,29 @@ class SurveyPetaniController extends Controller // Ringkasan lahan - $totalLuasLahan = (float) Lahan::query() - ->sum('luas_lahan'); - - $totalJumlahTanaman = (int) Lahan::query() - ->sum('jumlah_tanaman'); + $totalLuasLahan = ((float) Lahan::query() + ->sum('luas_lahan')) / 10000; // Jumlah tanaman berdasarkan komoditas petani - $tanamanPerKomoditasCollection = DB::table("{$lahanTable} as l") + $tanamanTable = (new Tanaman())->getTable(); + + $tanamanPerKomoditasCollection = DB::table("{$tanamanTable} as t") + ->join("{$lahanTable} as l", 'l.id', '=', 't.lahan_id') ->join("{$petaniTable} as p", 'p.id', '=', 'l.petani_id') - ->leftJoin("{$komoditasTable} as k", 'k.id', '=', 'p.komoditas_id') + ->leftJoin("{$komoditasTable} as k", 'k.id', '=', 't.komoditas_id') ->selectRaw("COALESCE(k.nama, 'Belum ditentukan') as label") - ->selectRaw('COALESCE(SUM(l.jumlah_tanaman), 0) as total') + ->selectRaw('COUNT(t.id) as total') ->where('k.is_utama', true) + ->whereNull('t.deleted_at') + ->whereNull('l.deleted_at') + ->whereNull('p.deleted_at') ->groupBy('k.id', 'k.nama') ->orderByDesc('total') ->get(); + $totalJumlahTanaman = (int) $tanamanPerKomoditasCollection->sum('total'); + $tanamanPerKomoditas = $tanamanPerKomoditasCollection ->map(function ($item, $index) use ($colors, $totalJumlahTanaman) { $color = $colors[$index % count($colors)]; diff --git a/app/Http/Controllers/Web/Produktivitas/AksesPasarController.php b/app/Http/Controllers/Web/Produktivitas/AksesPasarController.php index 6556cfd..6c14be4 100644 --- a/app/Http/Controllers/Web/Produktivitas/AksesPasarController.php +++ b/app/Http/Controllers/Web/Produktivitas/AksesPasarController.php @@ -25,9 +25,25 @@ class AksesPasarController extends Controller $aksesPasar = AksesPasar::where('petani_id', $petaniId)->first(); $hargaJualPanen = HargaJualPanen::where('petani_id', $petaniId)->get(); + $hargaJualRows = collect([ + 'Buah segar hasil petik', + 'Biji basah', + 'Biji kering/Biji Kupas', + 'Terfermentasi (Rp/kg)', + ])->map(function (string $bentuk, int $index) use ($hargaJualPanen) { + $existingData = $hargaJualPanen->firstWhere('bentuk_produk', $bentuk); + + return [ + 'index' => $index, + 'bentuk' => $bentuk, + 'harga_panen_terakhir' => $this->currencyForDisplay($existingData?->harga_panen_terakhir), + 'harga_tahun_lalu' => $this->currencyForDisplay($existingData?->harga_tahun_lalu), + 'harga_dua_tahun_lalu' => $this->currencyForDisplay($existingData?->harga_dua_tahun_lalu), + ]; + }); return view('produktivitas.petani.akses-pasar.index', array_merge( - compact('petani', 'aksesPasar', 'hargaJualPanen'), + compact('petani', 'aksesPasar', 'hargaJualPanen', 'hargaJualRows'), $this->aksesPasarOptions() )); } @@ -251,4 +267,11 @@ class AksesPasarController extends Controller $digits = preg_replace('/\D/', '', (string) $value); return $digits === '' ? null : $digits; } -} \ No newline at end of file + + private function currencyForDisplay(mixed $value): string + { + $digits = $this->currencyDigits($value); + + return is_null($digits) ? '' : number_format((int) $digits, 0, ',', '.'); + } +} diff --git a/app/Http/Controllers/Web/Produktivitas/PendidikanPelatihanController.php b/app/Http/Controllers/Web/Produktivitas/PendidikanPelatihanController.php index 18daa53..61515d2 100644 --- a/app/Http/Controllers/Web/Produktivitas/PendidikanPelatihanController.php +++ b/app/Http/Controllers/Web/Produktivitas/PendidikanPelatihanController.php @@ -77,10 +77,11 @@ class PendidikanPelatihanController extends Controller ]); } - return back()->with('success', 'Riwayat pelatihan berhasil disimpan.'); + return $this->redirectBackToFragment($request, 'section-sertifikasi') + ->with('success', 'Riwayat pelatihan berhasil disimpan.'); } - public function destroyPelatihan(Petani $petani, SurveyPelatihan $surveyPelatihan) + public function destroyPelatihan(Request $request, Petani $petani, SurveyPelatihan $surveyPelatihan) { $this->authorizeAccess(); @@ -92,7 +93,8 @@ class PendidikanPelatihanController extends Controller $surveyPelatihan->delete(); - return back()->with('success', 'Riwayat pelatihan berhasil dihapus.'); + return $this->redirectBackToFragment($request, 'section-pelatihan') + ->with('success', 'Riwayat pelatihan berhasil dihapus.'); } public function storeSertifikasi(Request $request, Petani $petani) @@ -155,10 +157,11 @@ class PendidikanPelatihanController extends Controller ]); } - return back()->with('success', 'Sertifikasi berhasil disimpan.'); + return $this->redirectBackToFragment($request, 'section-sertifikasi') + ->with('success', 'Sertifikasi berhasil disimpan.'); } - public function destroySertifikasi(Petani $petani, SurveySertifikasi $surveySertifikasi) + public function destroySertifikasi(Request $request, Petani $petani, SurveySertifikasi $surveySertifikasi) { $this->authorizeAccess(); @@ -170,6 +173,18 @@ class PendidikanPelatihanController extends Controller $surveySertifikasi->delete(); - return back()->with('success', 'Sertifikasi berhasil dihapus.'); + return $this->redirectBackToFragment($request, 'section-sertifikasi') + ->with('success', 'Sertifikasi berhasil dihapus.'); } -} \ No newline at end of file + + private function redirectBackToFragment(Request $request, string $defaultFragment) + { + $fragment = $request->input('redirect_fragment', $defaultFragment); + + if (!is_string($fragment) || !preg_match('/^[A-Za-z0-9_-]+$/', $fragment)) { + $fragment = $defaultFragment; + } + + return redirect()->to(Str::before(url()->previous(), '#') . '#' . $fragment); + } +} diff --git a/app/Http/Controllers/Web/Produktivitas/PetaniController.php b/app/Http/Controllers/Web/Produktivitas/PetaniController.php index 336c77a..04b08a7 100644 --- a/app/Http/Controllers/Web/Produktivitas/PetaniController.php +++ b/app/Http/Controllers/Web/Produktivitas/PetaniController.php @@ -50,14 +50,14 @@ class PetaniController extends Controller $query->where('created_by', auth()->user()->id); } + $summaryPetaniIds = (clone $query)->pluck('id'); $petani = $query->paginate($request->per_page ?? 10); $komoditas = Komoditas::where('is_utama', true)->get(); - $lahan = Lahan::whereIn('petani_id', $petani->pluck('id')) + $lahan = Lahan::whereIn('petani_id', $summaryPetaniIds) ->whereIn('komoditas_id', $komoditas->pluck('id')) ->get(); $tanaman = Tanaman::whereIn('lahan_id', $lahan->pluck('id')) - ->whereIn('lahan_id', $lahan->pluck('id')) ->get(); $case = " @@ -70,7 +70,7 @@ class PetaniController extends Controller END "; $skor = SkorPetani::selectRaw("$case AS segmen, COUNT(*) AS total") - ->whereIn('petani_id', $petani->pluck('id')) + ->whereIn('petani_id', $summaryPetaniIds) ->groupByRaw($case) ->get(); @@ -178,7 +178,7 @@ class PetaniController extends Controller 'created_by' => auth()->id(), 'updated_by' => auth()->id()]); - return redirect()->route('petani.index')->with('success', 'Data petani berhasil ditambahkan.'); + return redirect()->route('petani.edit', $petani->id)->with('success', 'Data petani berhasil ditambahkan.'); } public function show(string $id) @@ -253,7 +253,7 @@ class PetaniController extends Controller $petani->update([...$validatedData, 'updated_by' => auth()->id()]); - return redirect()->route('petani.index')->with('success', 'Data petani berhasil diupdate.'); + return redirect()->route('petani.edit', $petani->id)->with('success', 'Data petani berhasil diupdate.'); } /** diff --git a/app/Http/Controllers/Web/Produktivitas/PetaniLahanController.php b/app/Http/Controllers/Web/Produktivitas/PetaniLahanController.php index 47f08ee..1a20417 100644 --- a/app/Http/Controllers/Web/Produktivitas/PetaniLahanController.php +++ b/app/Http/Controllers/Web/Produktivitas/PetaniLahanController.php @@ -7,6 +7,7 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\Gate; use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Str; use Illuminate\Validation\Rules\Enum; @@ -17,6 +18,7 @@ use App\Models\Pertanian\Lahan; use App\Models\Wilayah\DesaKelurahan; use App\Models\Wilayah\Provinsi; use App\Models\Pertanian\Komoditas; +use App\Models\Pertanian\PraktikBudidaya; use App\Models\Pertanian\Tanaman; use App\Models\Master\JenisTanaman; @@ -64,8 +66,46 @@ class PetaniLahanController extends Controller $komoditas = Komoditas::all(); $tanamanPenaung = JenisTanaman::all(); + $autoPestDiseaseData = $this->autoPestDiseaseData($petaniId); + $jenisHamaOtomatis = $autoPestDiseaseData['jenis_hama']; + $jenisPenyakitOtomatis = $autoPestDiseaseData['jenis_penyakit']; - return view('produktivitas.petani.lahan.add', compact('petani', 'lahan', 'provinsi', 'komoditas', 'tanamanPenaung')); + return view('produktivitas.petani.lahan.add', compact('petani', 'lahan', 'provinsi', 'komoditas', 'tanamanPenaung', 'jenisHamaOtomatis', 'jenisPenyakitOtomatis')); + } + + private function autoPestDiseaseData(string|int $petaniId): array + { + $praktikBudidaya = PraktikBudidaya::where('petani_id', $petaniId)->latest()->first(); + + return [ + 'jenis_hama' => $this->normalizeArrayValue($praktikBudidaya?->jenis_hama), + 'jenis_penyakit' => $this->normalizeArrayValue($praktikBudidaya?->jenis_penyakit), + ]; + } + + private function normalizeArrayValue(mixed $value): array + { + if (is_array($value)) { + return array_values(array_filter($value, fn ($item) => filled($item))); + } + + if (is_string($value) && $value !== '') { + $decoded = json_decode($value, true); + + if (is_array($decoded)) { + return array_values(array_filter($decoded, fn ($item) => filled($item))); + } + + return [$value]; + } + + return []; + } + + private function hasPestDiseaseColumns(string $table): bool + { + return Schema::hasColumn($table, 'jenis_hama') + && Schema::hasColumn($table, 'jenis_penyakit'); } private function validateLahan(Request $request) @@ -167,6 +207,14 @@ class PetaniLahanController extends Controller ]); $validated = $this->validateLahan($request); + $autoPestDiseaseData = $this->autoPestDiseaseData($petaniId); + $lahanHasPestDiseaseColumns = $this->hasPestDiseaseColumns((new Lahan)->getTable()); + $tanamanHasPestDiseaseColumns = $this->hasPestDiseaseColumns((new Tanaman)->getTable()); + + if ($lahanHasPestDiseaseColumns) { + $validated = array_merge($validated, $autoPestDiseaseData); + } + $komoditas = Komoditas::where('id', $request->komoditas_id)->first(); $lahanCount = Lahan::where('petani_id', $petaniId) ->count(); @@ -196,8 +244,8 @@ class PetaniLahanController extends Controller ); if ($lahan && $lahan->jumlah_tanaman > 0) { - $data = collect(range(1, $lahan->jumlah_tanaman))->map(function ($i) use ($lahan, $komoditas, $lahanUid) { - return [ + $data = collect(range(1, $lahan->jumlah_tanaman))->map(function ($i) use ($lahan, $komoditas, $lahanUid, $autoPestDiseaseData, $tanamanHasPestDiseaseColumns) { + $row = [ 'lahan_id' => $lahan->id, 'uid' => 'TNM-' . $lahanUid . '-' . strtoupper(Str::random(10)), 'komoditas_id' => $lahan->komoditas_id, @@ -215,6 +263,13 @@ class PetaniLahanController extends Controller 'created_at' => now(), 'updated_at' => now(), ]; + + if ($tanamanHasPestDiseaseColumns) { + $row['jenis_hama'] = json_encode($autoPestDiseaseData['jenis_hama'] ?? []); + $row['jenis_penyakit'] = json_encode($autoPestDiseaseData['jenis_penyakit'] ?? []); + } + + return $row; }); $data->chunk(500)->each(function ($chunk) { @@ -224,15 +279,15 @@ class PetaniLahanController extends Controller if ($request->ajax()) { return response()->json([ 'success' => true, - 'redirect' => route('petani.lahan-tanaman.index', $petaniId), + 'redirect' => route('petani.lahan-tanaman.edit', [$petaniId, $lahan->id]), 'message' => 'Lahan berhasil ditambahkan.' ]); } - return redirect()->route('petani.lahan-tanaman.index', $petaniId)->with('success', 'Lahan berhasil ditambahkan.'); + return redirect()->route('petani.lahan-tanaman.edit', [$petaniId, $lahan->id])->with('success', 'Lahan berhasil ditambahkan.'); } - return redirect()->route('petani.lahan-tanaman.index', $petaniId)->with('success', 'Lahan berhasil ditambahkan.'); + return redirect()->route('petani.lahan-tanaman.edit', [$petaniId, $lahan->id])->with('success', 'Lahan berhasil ditambahkan.'); } public function show(string $petaniId, string $id) @@ -269,10 +324,13 @@ class PetaniLahanController extends Controller $komoditas = Komoditas::all(); $tanamanPenaung = JenisTanaman::all(); + $autoPestDiseaseData = $this->autoPestDiseaseData($petaniId); + $jenisHamaOtomatis = $autoPestDiseaseData['jenis_hama']; + $jenisPenyakitOtomatis = $autoPestDiseaseData['jenis_penyakit']; $provinsi = Provinsi::orderBy('kode', 'asc')->get(); - return view('produktivitas.petani.lahan.edit', compact('lahan', 'lahanSelected', 'petani', 'komoditas', 'provinsi', 'tanamanPenaung')); + return view('produktivitas.petani.lahan.edit', compact('lahan', 'lahanSelected', 'petani', 'komoditas', 'provinsi', 'tanamanPenaung', 'jenisHamaOtomatis', 'jenisPenyakitOtomatis')); } public function update(Request $request, string $petaniId, string $id) @@ -290,6 +348,14 @@ class PetaniLahanController extends Controller ->toArray() ]); $validated = $this->validateLahan($request); + $autoPestDiseaseData = $this->autoPestDiseaseData($petaniId); + $lahanHasPestDiseaseColumns = $this->hasPestDiseaseColumns((new Lahan)->getTable()); + $tanamanHasPestDiseaseColumns = $this->hasPestDiseaseColumns((new Tanaman)->getTable()); + + if ($lahanHasPestDiseaseColumns) { + $validated = array_merge($validated, $autoPestDiseaseData); + } + $komoditas = Komoditas::where('id', $request->komoditas_id)->first(); $tanamanCount = Tanaman::where('lahan_id', $lahan->id)->count(); $lahanCount = Lahan::where('petani_id', $petaniId)->count(); @@ -342,8 +408,8 @@ class PetaniLahanController extends Controller $this->syncTanamanPenaung($request); if ($lahan && $lahan->jumlah_tanaman > $tanamanCount) { - $data = collect(range($tanamanCount + 1, $lahan->jumlah_tanaman))->map(function ($i) use ($lahan, $komoditas, $lahanUid) { - return [ + $data = collect(range($tanamanCount + 1, $lahan->jumlah_tanaman))->map(function ($i) use ($lahan, $komoditas, $lahanUid, $autoPestDiseaseData, $tanamanHasPestDiseaseColumns) { + $row = [ 'lahan_id' => $lahan->id, 'komoditas_id' => $lahan->komoditas_id, 'jenis_komoditas_id' => $lahan->jenis_komoditas_id, @@ -361,6 +427,13 @@ class PetaniLahanController extends Controller 'created_at' => now(), 'updated_at' => now(), ]; + + if ($tanamanHasPestDiseaseColumns) { + $row['jenis_hama'] = json_encode($autoPestDiseaseData['jenis_hama'] ?? []); + $row['jenis_penyakit'] = json_encode($autoPestDiseaseData['jenis_penyakit'] ?? []); + } + + return $row; }); $data->chunk(500)->each(function ($chunk) { @@ -368,20 +441,42 @@ class PetaniLahanController extends Controller }); } + if ($tanamanHasPestDiseaseColumns) { + $lahan->tanaman()->update([ + 'jenis_hama' => json_encode($autoPestDiseaseData['jenis_hama'] ?? []), + 'jenis_penyakit' => json_encode($autoPestDiseaseData['jenis_penyakit'] ?? []), + 'updated_by' => auth()->id(), + ]); + } + if ($request->ajax()) { return response()->json([ 'success' => true, - 'redirect' => route('petani.lahan-tanaman.index', $petaniId), + 'redirect' => route('petani.lahan-tanaman.edit', [$petaniId, $lahan->id]), 'message' => 'Lahan berhasil diupdate.' ]); } - return redirect()->route('petani.lahan-tanaman.index', $petaniId)->with('success', 'Lahan berhasil diperbarui.'); + return redirect()->route('petani.lahan-tanaman.edit', [$petaniId, $lahan->id])->with('success', 'Lahan berhasil diperbarui.'); } - public function destroy(string $id) + public function destroy(string $petaniId, string $id) { - // + if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) { + abort(403); + } + + $lahan = Lahan::findOrFail($id); + $lahan->tanaman()->update([ + 'deleted_by' => auth()->id() + ]); + $lahan->tanaman()->delete(); + $lahan->update([ + 'deleted_by' => auth()->id() + ]); + $lahan->delete(); + + return redirect()->route('petani.lahan-tanaman.index', $petaniId)->with('success', 'Lahan berhasil dihapus.'); } public function summary(string $petaniId) diff --git a/app/Http/Controllers/Web/Produktivitas/PraktikBudidayaController.php b/app/Http/Controllers/Web/Produktivitas/PraktikBudidayaController.php index a58d729..8e9aa16 100644 --- a/app/Http/Controllers/Web/Produktivitas/PraktikBudidayaController.php +++ b/app/Http/Controllers/Web/Produktivitas/PraktikBudidayaController.php @@ -178,8 +178,14 @@ class PraktikBudidayaController extends Controller $teknik_pemangkasan = array_values($teknik_pemangkasan); + if ((int) ($validatedData['frekuensi_pemangkasan_komoditas_utama'] ?? 0) === FrekuensiPemangkasanUtama::TIDAK_PERNAH->value) { + $teknik_pemangkasan = []; + } + $petani = Petani::findOrFail($petaniId); + $pemupukanTidakPernah = (int) ($validatedData['pemberian_pupuk'] ?? 0) === PemberianPupuk::TIDAK_PERNAH->value; + $praktikBudidaya = $petani->praktikBudidaya()->create([ 'petani_id' => $petani->id, 'uid' => 'PB-' . strtoupper(Str::random(10)), @@ -193,12 +199,12 @@ class PraktikBudidayaController extends Controller 'deskripsi_penyerbukan_manual' => $validatedData['alasan_tidak_penyerbukan'] ?? null, 'tingkat_keberhasilan_penyerbukan' => $validatedData['tingkat_keberhasilan_penyerbukan'] ?? null, 'pemberian_pupuk' => $validatedData['pemberian_pupuk'] ?? null, - 'jenis_pupuk' => $validatedData['jenis_pupuk'] ?? null, - 'frekuensi_pemberian_pupuk' => ($validatedData['frekuensi_pemupukan'] ?? null) === 'Lainnya' ? ($validatedData['frekuensi_pemupukan_lainnya'] ?? null) : ($validatedData['frekuensi_pemupukan'] ?? null), - 'estimasi_dosis_pupuk_organik' => $validatedData['estimasi_dosis_pupuk_organik'] ?? null, - 'estimasi_dosis_pupuk_anorganik' => $validatedData['estimasi_dosis_pupuk_anorganik'] ?? null, - 'waktu_pemberian_pupuk' => ($validatedData['waktu_pemberian_pupuk'] ?? null) === 'Lainnya' ? ($validatedData['waktu_pemberian_pupuk_lainnya'] ?? null) : ($validatedData['waktu_pemberian_pupuk'] ?? null), - 'cara_pemberian_pupuk' => ($validatedData['cara_pemberian_pupuk'] ?? null) === 'Lainnya' ? ($validatedData['cara_pemberian_pupuk_lainnya'] ?? null) : ($validatedData['cara_pemberian_pupuk'] ?? null), + 'jenis_pupuk' => $pemupukanTidakPernah ? null : ($validatedData['jenis_pupuk'] ?? null), + 'frekuensi_pemberian_pupuk' => $pemupukanTidakPernah ? null : (($validatedData['frekuensi_pemupukan'] ?? null) === 'Lainnya' ? ($validatedData['frekuensi_pemupukan_lainnya'] ?? null) : ($validatedData['frekuensi_pemupukan'] ?? null)), + 'estimasi_dosis_pupuk_organik' => $pemupukanTidakPernah ? null : ($validatedData['estimasi_dosis_pupuk_organik'] ?? null), + 'estimasi_dosis_pupuk_anorganik' => $pemupukanTidakPernah ? null : ($validatedData['estimasi_dosis_pupuk_anorganik'] ?? null), + 'waktu_pemberian_pupuk' => $pemupukanTidakPernah ? null : (($validatedData['waktu_pemberian_pupuk'] ?? null) === 'Lainnya' ? ($validatedData['waktu_pemberian_pupuk_lainnya'] ?? null) : ($validatedData['waktu_pemberian_pupuk'] ?? null)), + 'cara_pemberian_pupuk' => $pemupukanTidakPernah ? null : (($validatedData['cara_pemberian_pupuk'] ?? null) === 'Lainnya' ? ($validatedData['cara_pemberian_pupuk_lainnya'] ?? null) : ($validatedData['cara_pemberian_pupuk'] ?? null)), 'created_by' => auth()->id(), 'updated_by' => auth()->id(), ], [ @@ -554,6 +560,12 @@ class PraktikBudidayaController extends Controller } } $teknikPemangkasan = array_values($teknik_pemangkasan); + + if ((int) ($validatedData['frekuensi_pemangkasan_komoditas_utama'] ?? 0) === FrekuensiPemangkasanUtama::TIDAK_PERNAH->value) { + $teknikPemangkasan = []; + } + + $pemupukanTidakPernah = (int) ($validatedData['pemberian_pupuk'] ?? 0) === PemberianPupuk::TIDAK_PERNAH->value; $dataPraktikBudidaya = [ 'tenaga_kerja' => $validatedData['tenaga_kerja'], @@ -566,12 +578,12 @@ class PraktikBudidayaController extends Controller 'deskripsi_penyerbukan_manual' => $validatedData['alasan_tidak_penyerbukan'] ?? null, 'tingkat_keberhasilan_penyerbukan' => $validatedData['tingkat_keberhasilan_penyerbukan'] ?? null, 'pemberian_pupuk' => $validatedData['pemberian_pupuk'] ?? null, - 'jenis_pupuk' => $validatedData['jenis_pupuk'] ?? null, - 'frekuensi_pemberian_pupuk' => ($validatedData['frekuensi_pemupukan'] ?? null) === 'Lainnya' ? ($validatedData['frekuensi_pemupukan_lainnya'] ?? null) : ($validatedData['frekuensi_pemupukan'] ?? null), - 'estimasi_dosis_pupuk_organik' => $validatedData['estimasi_dosis_pupuk_organik'] ?? null, - 'estimasi_dosis_pupuk_anorganik' => $validatedData['estimasi_dosis_pupuk_anorganik'] ?? null, - 'waktu_pemberian_pupuk' => ($validatedData['waktu_pemberian_pupuk'] ?? null) === 'Lainnya' ? ($validatedData['waktu_pemberian_pupuk_lainnya'] ?? null) : ($validatedData['waktu_pemberian_pupuk'] ?? null), - 'cara_pemberian_pupuk' => ($validatedData['cara_pemberian_pupuk'] ?? null) === 'Lainnya' ? ($validatedData['cara_pemberian_pupuk_lainnya'] ?? null) : ($validatedData['cara_pemberian_pupuk'] ?? null), + 'jenis_pupuk' => $pemupukanTidakPernah ? null : ($validatedData['jenis_pupuk'] ?? null), + 'frekuensi_pemberian_pupuk' => $pemupukanTidakPernah ? null : (($validatedData['frekuensi_pemupukan'] ?? null) === 'Lainnya' ? ($validatedData['frekuensi_pemupukan_lainnya'] ?? null) : ($validatedData['frekuensi_pemupukan'] ?? null)), + 'estimasi_dosis_pupuk_organik' => $pemupukanTidakPernah ? null : ($validatedData['estimasi_dosis_pupuk_organik'] ?? null), + 'estimasi_dosis_pupuk_anorganik' => $pemupukanTidakPernah ? null : ($validatedData['estimasi_dosis_pupuk_anorganik'] ?? null), + 'waktu_pemberian_pupuk' => $pemupukanTidakPernah ? null : (($validatedData['waktu_pemberian_pupuk'] ?? null) === 'Lainnya' ? ($validatedData['waktu_pemberian_pupuk_lainnya'] ?? null) : ($validatedData['waktu_pemberian_pupuk'] ?? null)), + 'cara_pemberian_pupuk' => $pemupukanTidakPernah ? null : (($validatedData['cara_pemberian_pupuk'] ?? null) === 'Lainnya' ? ($validatedData['cara_pemberian_pupuk_lainnya'] ?? null) : ($validatedData['cara_pemberian_pupuk'] ?? null)), ]; } @@ -675,6 +687,17 @@ class PraktikBudidayaController extends Controller } } - return back()->with('success', 'Data berhasil diperbarui.'); + return $this->redirectBackToFragment($request)->with('success', 'Data berhasil diperbarui.'); + } + + private function redirectBackToFragment(Request $request) + { + $fragment = $request->input('redirect_fragment'); + + if (!is_string($fragment) || !preg_match('/^[A-Za-z0-9_-]+$/', $fragment)) { + return back(); + } + + return redirect()->to(Str::before(url()->previous(), '#') . '#' . $fragment); } } diff --git a/app/Http/Controllers/Web/Produktivitas/SosialEkonomiController.php b/app/Http/Controllers/Web/Produktivitas/SosialEkonomiController.php index 2db7af1..a54498f 100644 --- a/app/Http/Controllers/Web/Produktivitas/SosialEkonomiController.php +++ b/app/Http/Controllers/Web/Produktivitas/SosialEkonomiController.php @@ -154,8 +154,7 @@ class SosialEkonomiController extends Controller }); if (!$request->expectsJson()) { - return redirect() - ->route('petani.sosial-ekonomi.edit', [$sosialEkonomi->petani_id, $sosialEkonomi->id]) + return $this->redirectToEditSection($sosialEkonomi, $request) ->with('success', 'Data sosial ekonomi berhasil disimpan.'); } @@ -206,8 +205,7 @@ class SosialEkonomiController extends Controller }); if (!$request->expectsJson()) { - return redirect() - ->route('petani.sosial-ekonomi.edit', [$sosialEkonomi->petani_id, $sosialEkonomi->id]) + return $this->redirectToEditSection($sosialEkonomi, $request) ->with('success', 'Data sosial ekonomi berhasil diperbarui.'); } @@ -218,6 +216,18 @@ class SosialEkonomiController extends Controller ]); } + private function redirectToEditSection(SosialEkonomi $sosialEkonomi, Request $request): RedirectResponse + { + $url = route('petani.sosial-ekonomi.edit', [$sosialEkonomi->petani_id, $sosialEkonomi->id]); + $fragment = $request->input('redirect_fragment'); + + if (is_string($fragment) && preg_match('/^[A-Za-z0-9_-]+$/', $fragment)) { + $url .= '#' . $fragment; + } + + return redirect()->to($url); + } + public function destroy(string $id): JsonResponse { $sosialEkonomi = SosialEkonomi::findOrFail($id); @@ -589,6 +599,14 @@ class SosialEkonomiController extends Controller $payload = $this->normalizeSkorPayload($payload); + if (array_key_exists('ada_sengketa', $payload) && !filter_var($payload['ada_sengketa'], FILTER_VALIDATE_BOOLEAN)) { + $payload['keterangan_sengketa'] = null; + $payload['pihak_membantu_konflik'] = null; + $payload['pihak_membantu_konflik_nama'] = null; + $payload['tahun_bantuan_konflik'] = null; + $payload['status_konflik'] = null; + } + if (($payload['pihak_membantu_konflik'] ?? null) === PihakMembantuKonflik::TIDAK_ADA_SELESAIKAN_SENDIRI->value) { $payload['pihak_membantu_konflik_nama'] = null; $payload['tahun_bantuan_konflik'] = null; diff --git a/app/Http/Controllers/Web/Produktivitas/SurveyProduktivitasController.php b/app/Http/Controllers/Web/Produktivitas/SurveyProduktivitasController.php index 037a638..3c15d3a 100644 --- a/app/Http/Controllers/Web/Produktivitas/SurveyProduktivitasController.php +++ b/app/Http/Controllers/Web/Produktivitas/SurveyProduktivitasController.php @@ -32,10 +32,10 @@ class SurveyProduktivitasController extends Controller ]); } - return back()->with('success', 'Data produktivitas berhasil disimpan.'); + return $this->redirectBackToFragment($request)->with('success', 'Data produktivitas berhasil disimpan.'); } - public function destroy($petaniId, $surveyProduktivitasId) + public function destroy($petaniId, $surveyProduktivitasId, Request $request) { $surveyProduktivitas = SurveyProduktivitas::where('petani_id', $petaniId) ->where('id', $surveyProduktivitasId) @@ -44,6 +44,17 @@ class SurveyProduktivitasController extends Controller $surveyProduktivitas->save(); $surveyProduktivitas->delete(); - return back()->with('success', 'Data produktivitas berhasil dihapus.'); + return $this->redirectBackToFragment($request)->with('success', 'Data produktivitas berhasil dihapus.'); + } + + private function redirectBackToFragment(Request $request) + { + $fragment = $request->input('redirect_fragment'); + + if (!is_string($fragment) || !preg_match('/^[A-Za-z0-9_-]+$/', $fragment)) { + return back(); + } + + return redirect()->to(Str::before(url()->previous(), '#') . '#' . $fragment); } } diff --git a/app/Models/Pertanian/Lahan.php b/app/Models/Pertanian/Lahan.php index c8c57de..8021c23 100644 --- a/app/Models/Pertanian/Lahan.php +++ b/app/Models/Pertanian/Lahan.php @@ -56,7 +56,10 @@ class Lahan extends Model 'komoditas_lain', 'tanaman_penaung', - 'foto' + 'foto', + + 'jenis_hama', + 'jenis_penyakit', ]; protected $casts = [ @@ -68,7 +71,9 @@ class Lahan extends Model 'serangan_hama' => SeranganHama::class, 'penyakit_tanaman' => PenyakitTanaman::class, 'keparahan_serangan' => KeparahanSerangan::class, - 'foto' => 'array' + 'foto' => 'array', + 'jenis_hama' => 'array', + 'jenis_penyakit' => 'array' ]; public function profile(): BelongsTo diff --git a/app/Models/Pertanian/PraktikBudidaya.php b/app/Models/Pertanian/PraktikBudidaya.php index 0a3782c..bc466c7 100644 --- a/app/Models/Pertanian/PraktikBudidaya.php +++ b/app/Models/Pertanian/PraktikBudidaya.php @@ -8,10 +8,13 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasOne; +use Illuminate\Support\Facades\Schema; use Illuminate\Support\Str; use App\Models\Pertanian\Petani; use App\Models\Pertanian\SkorPetani; +use App\Models\Pertanian\Tanaman; +use App\Models\Pertanian\Lahan; class PraktikBudidaya extends Model { @@ -95,6 +98,31 @@ class PraktikBudidaya extends Model $kebiasaan = $praktikBudidaya->kebiasaan_konservasi_tanah ? count($praktikBudidaya->kebiasaan_konservasi_tanah) : 0; $pemahaman = $praktikBudidaya->pemahaman_manfaat_konservasi_tanah == 'Ya, tahu manfaatnya' ? 1 : 0; $skor_konservasi_tanah = 0; + $jenisHama = $praktikBudidaya->jenis_hama ?? []; + $jenisPenyakit = $praktikBudidaya->jenis_penyakit ?? []; + + if (Schema::hasColumn((new Lahan)->getTable(), 'jenis_hama') + && Schema::hasColumn((new Lahan)->getTable(), 'jenis_penyakit')) { + Lahan::where('petani_id', $praktikBudidaya->petani_id)->get()->each(function (Lahan $lahan) use ($jenisHama, $jenisPenyakit, $praktikBudidaya) { + $lahan->update([ + 'jenis_hama' => $jenisHama, + 'jenis_penyakit' => $jenisPenyakit, + 'updated_by' => $praktikBudidaya->updated_by, + ]); + }); + } + + if (Schema::hasColumn((new Tanaman)->getTable(), 'jenis_hama') + && Schema::hasColumn((new Tanaman)->getTable(), 'jenis_penyakit')) { + Tanaman::where('petani_id', $praktikBudidaya->petani_id)->get()->each(function (Tanaman $tanaman) use ($jenisHama, $jenisPenyakit, $praktikBudidaya) { + $tanaman->update([ + 'jenis_hama' => $jenisHama, + 'jenis_penyakit' => $jenisPenyakit, + 'updated_by' => $praktikBudidaya->updated_by, + ]); + }); + } + if ($kebiasaan == 0) { $skor_konservasi_tanah = 1; } elseif ($kebiasaan == 1 && $pemahaman == 0) { @@ -122,4 +150,4 @@ class PraktikBudidaya extends Model { return $this->belongsTo(Petani::class, 'petani_id'); } -} \ No newline at end of file +} diff --git a/app/Models/Pertanian/Tanaman.php b/app/Models/Pertanian/Tanaman.php index e31a616..72febdf 100644 --- a/app/Models/Pertanian/Tanaman.php +++ b/app/Models/Pertanian/Tanaman.php @@ -42,6 +42,9 @@ class Tanaman extends Model 'serangan_hama', 'penyakit_tanaman', 'keparahan_serangan', + + 'jenis_hama', + 'jenis_penyakit', ]; protected $casts = [ @@ -49,6 +52,8 @@ class Tanaman extends Model 'serangan_hama' => SeranganHama::class, 'penyakit_tanaman' => PenyakitTanaman::class, 'keparahan_serangan' => KeparahanSerangan::class, + 'jenis_hama' => 'array', + 'jenis_penyakit' => 'array' ]; public function komoditas() diff --git a/database/migrations/2026_07_22_110145_update_lahan_tanaman_table.php b/database/migrations/2026_07_22_110145_update_lahan_tanaman_table.php new file mode 100644 index 0000000..6fde87c --- /dev/null +++ b/database/migrations/2026_07_22_110145_update_lahan_tanaman_table.php @@ -0,0 +1,57 @@ +jsonb('jenis_hama')->nullable(); + } + + if (! Schema::hasColumn('map_lahan', 'jenis_penyakit')) { + $table->jsonb('jenis_penyakit')->nullable(); + } + }); + + Schema::table('map_tanaman', function (Blueprint $table) { + if (! Schema::hasColumn('map_tanaman', 'jenis_hama')) { + $table->jsonb('jenis_hama')->nullable(); + } + + if (! Schema::hasColumn('map_tanaman', 'jenis_penyakit')) { + $table->jsonb('jenis_penyakit')->nullable(); + } + }); + } + + public function down(): void + { + Schema::table('map_lahan', function (Blueprint $table) { + if (Schema::hasColumn('map_lahan', 'jenis_hama')) { + $table->dropColumn('jenis_hama'); + } + + if (Schema::hasColumn('map_lahan', 'jenis_penyakit')) { + $table->dropColumn('jenis_penyakit'); + } + }); + + Schema::table('map_tanaman', function (Blueprint $table) { + if (Schema::hasColumn('map_tanaman', 'jenis_hama')) { + $table->dropColumn('jenis_hama'); + } + + if (Schema::hasColumn('map_tanaman', 'jenis_penyakit')) { + $table->dropColumn('jenis_penyakit'); + } + }); + } +}; diff --git a/resources/views/dashboard/petani.blade.php b/resources/views/dashboard/petani.blade.php index d214106..ec98bc2 100644 --- a/resources/views/dashboard/petani.blade.php +++ b/resources/views/dashboard/petani.blade.php @@ -31,7 +31,7 @@ -

{{ number_format($lahanSummary->sum('luas_lahan'), 0, ',', '.') }}m2

+

{{ number_format($lahanSummary->sum('luas_lahan') / 10000, 2, ',', '.') }} ha

Lahan

@@ -701,4 +701,4 @@ radarKomponen.render(); }); -@endpush \ No newline at end of file +@endpush diff --git a/resources/views/konfigurasi/profile/index.blade.php b/resources/views/konfigurasi/profile/index.blade.php index 8fd820d..a099cde 100644 --- a/resources/views/konfigurasi/profile/index.blade.php +++ b/resources/views/konfigurasi/profile/index.blade.php @@ -88,12 +88,13 @@ @if($profile) @endif diff --git a/resources/views/produktivitas/petani/akses-pasar/index.blade.php b/resources/views/produktivitas/petani/akses-pasar/index.blade.php index 12a97a8..9894264 100644 --- a/resources/views/produktivitas/petani/akses-pasar/index.blade.php +++ b/resources/views/produktivitas/petani/akses-pasar/index.blade.php @@ -93,34 +93,30 @@ - @php($listBentukProduk = ['Buah segar hasil petik', 'Biji basah', 'Biji kering/Biji Kupas', 'Terfermentasi (Rp/kg)']) - @php($hargaJualPanen = $hargaJualPanen ?? collect()) - - @foreach ($listBentukProduk as $index => $bentuk) - @php($existingData = $hargaJualPanen->firstWhere('bentuk_produk', $bentuk)) + @foreach ($hargaJualRows as $row) - - {{ $bentuk }}: + + {{ $row['bentuk'] }}:

Rp - + /kg
Rp - + /kg
Rp - + /kg
@@ -232,6 +228,16 @@ const praktikBelumPernahValue = String(@json($praktikBelumPernahValue)); const skorPengalamanBerhentiValues = @json($skorPengalamanBerhentiValues ?? [2,3]).map(Number); + function onlyDigits(value) { + return String(value || '').replace(/\D/g, ''); + } + + function formatRupiah(value) { + const digits = onlyDigits(value); + + return digits.replace(/\B(?=(\d{3})+(?!\d))/g, '.'); + } + function syncAlasanBerhenti() { const val = Number($('input[name="skor_pengalaman"]:checked').val()); const isBerhenti = skorPengalamanBerhentiValues.includes(val); @@ -256,10 +262,21 @@ $('input[name="skor_pengalaman"]').on('change', syncAlasanBerhenti); $('input[name="saluran_terdahulu[]"]').on('change', syncSaluranLainnya); $('input[name="praktik_fermentasi"]').on('change', syncPraktikFermentasi); + $(document).on('input', '.rupiah-input', function () { + const cursorAtEnd = this.selectionStart === this.value.length; + this.value = formatRupiah(this.value); + + if (cursorAtEnd) { + this.setSelectionRange(this.value.length, this.value.length); + } + }); + $('.rupiah-input').each(function () { + this.value = formatRupiah(this.value); + }); syncAlasanBerhenti(); syncSaluranLainnya(); syncPraktikFermentasi(); }); -@endpush \ No newline at end of file +@endpush diff --git a/resources/views/produktivitas/petani/header.blade.php b/resources/views/produktivitas/petani/header.blade.php index deb6168..e3ed814 100644 --- a/resources/views/produktivitas/petani/header.blade.php +++ b/resources/views/produktivitas/petani/header.blade.php @@ -92,7 +92,13 @@ ? $petani->lahans()->get() : collect(); $totalLuasLahan = $petani ? $lahanPetani->where('komoditas_id', $petani->komoditas_id)->sum('luas_lahan') : 0; - $totalTanaman = $petani ? $lahanPetani->where('komoditas_id', $petani->komoditas_id)->sum('jumlah_tanaman') : 0; + $totalLuasLahanHa = $totalLuasLahan / 10000; + $lahanKomoditasUtamaIds = $petani + ? $lahanPetani->where('komoditas_id', $petani->komoditas_id)->pluck('id') + : collect(); + $totalTanaman = $petani && \Illuminate\Support\Facades\Schema::hasTable('map_tanaman') + ? \App\Models\Pertanian\Tanaman::whereIn('lahan_id', $lahanKomoditasUtamaIds)->count() + : 0; $pendidikanLabel = isset($petani) ? $petani->pendidikan_terakhir?->label() : null; @endphp @@ -126,7 +132,7 @@

Lahan & Tanaman

@if($lahanPetani->isNotEmpty()) - {{ number_format($totalLuasLahan, 0, ',', '.') }} m2 + {{ number_format($totalLuasLahanHa, 2, ',', '.') }} ha @else - @endif diff --git a/resources/views/produktivitas/petani/index.blade.php b/resources/views/produktivitas/petani/index.blade.php index 33ae852..2c65a89 100644 --- a/resources/views/produktivitas/petani/index.blade.php +++ b/resources/views/produktivitas/petani/index.blade.php @@ -15,7 +15,7 @@
@endpush @@ -203,8 +207,8 @@
- - + + @error('luas_lahan')
{{ $message }}
@enderror
@@ -247,17 +251,134 @@
-
+
@error('kondisi_tanaman')
{{ $message }}
@enderror
-
+
+
+
+ + +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ * Tidak diisi, terisi otomatis di Praktik Budidaya + @error('jenis_hama') +
{{ $message }}
+ @enderror +
+
+ + +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ * Tidak diisi, terisi otomatis di praktik budidaya + + @error('jenis_penyakit') +
{{ $message }}
+ @enderror +
+ +
@error('keparahan_serangan')
{{ $message }}
@enderror
@@ -657,9 +778,9 @@ let area = L.GeometryUtil.geodesicArea(latlngs); - console.log(area); + let areaHa = area / 10000; - $('#luas_lahan').val(area.toFixed(2)); + $('#luas_lahan').val(areaHa.toFixed(4)); } const previewTemplate = ` @@ -815,7 +936,7 @@ let originalText = submitBtn.html(); submitBtn.prop('disabled', true).html(' Menyimpan...'); - $.ajax({ + $.ajax({ url: $(form).attr('action'), type: "POST", data: formData, @@ -833,7 +954,7 @@ showConfirmButton: false, timer: 1500 }).then(() => { - window.location.href = "{{ route('petani.index') }}"; + window.location.href = res.redirect || window.location.href; }); }, error: function(xhr) { @@ -870,4 +991,4 @@ }); }); -@endpush \ No newline at end of file +@endpush diff --git a/resources/views/produktivitas/petani/lahan/edit.blade.php b/resources/views/produktivitas/petani/lahan/edit.blade.php index 391dd8e..8f4728c 100644 --- a/resources/views/produktivitas/petani/lahan/edit.blade.php +++ b/resources/views/produktivitas/petani/lahan/edit.blade.php @@ -34,6 +34,10 @@ .foto-lightbox img { max-width: 90vw !important; max-height: 85vh !important; object-fit: contain !important; border-radius: 8px !important; box-shadow: 0 10px 40px rgba(0,0,0,0.5) !important; } .foto-lightbox-close { position: absolute !important; top: 20px !important; right: 30px !important; color: #fff !important; font-size: 40px !important; font-weight: bold !important; cursor: pointer !important; z-index: 100000 !important; } .foto-lightbox-close:hover { color: #dc3545 !important; } + .auto-pest-disease-field .form-check-label, + .auto-pest-disease-field .text-muted { + font-size: 0.875rem; + } @endpush @@ -73,7 +77,7 @@
- + @error('luas_lahan')
{{ $message }}
@enderror @@ -129,17 +133,19 @@
-
+
@error('kondisi_tanaman')
{{ $message }}
@enderror
-
+
+
+ +
+ + +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ * Tidak diisi, terisi otomatis di praktik budidaya + @error('jenis_hama') +
{{ $message }}
+ @enderror
-
+
+ + +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ * Tidak diisi, terisi otomatis di Praktik Budidaya + + @error('jenis_penyakit') +
{{ $message }}
+ @enderror +
+
@error('keparahan_serangan')
{{ $message }}
@enderror
@@ -286,6 +407,7 @@
Kembali +
@@ -702,7 +824,8 @@ }); document.getElementById('path').value = JSON.stringify(pathData); let area = L.GeometryUtil.geodesicArea(latlngs); - $('#luas_lahan').val(area.toFixed(2)); + let areaHa = area / 10000; + $('#luas_lahan').val(areaHa.toFixed(4)); } const previewTemplate = ` @@ -900,7 +1023,7 @@ showConfirmButton: false, timer: 1500 }).then(() => { - window.location.href = "{{ route('petani.index') }}"; + window.location.href = res.redirect || window.location.href; }); }, error: function(xhr) { @@ -937,8 +1060,31 @@ } }); + $('#delete-lahan').click(function(e) { + e.preventDefault(); + $.ajax({ + url: "{{ route('petani.lahan-tanaman.destroy', ['petani' => $petani->id, 'lahan_tanaman' => $lahanSelected->id]) }}", + type: "POST", + data: { + _method: 'DELETE', + _token: $('input[name="_token"]').val() + }, + success: function(res) { + Swal.fire({ + icon: 'success', + title: 'Berhasil!', + text: 'Data lahan berhasil dihapus.', + showConfirmButton: false, + timer: 1500 + }).then(() => { + window.location.href = "{{ route('petani.lahan-tanaman.index', ['petani' => $petani->id]) }}"; + }); + } + }); + }); + initWilayah(); initKomoditas(); }); -@endpush \ No newline at end of file +@endpush diff --git a/resources/views/produktivitas/petani/pendidikan-pelatihan/index.blade.php b/resources/views/produktivitas/petani/pendidikan-pelatihan/index.blade.php index 6b2e4c5..a5e486d 100644 --- a/resources/views/produktivitas/petani/pendidikan-pelatihan/index.blade.php +++ b/resources/views/produktivitas/petani/pendidikan-pelatihan/index.blade.php @@ -29,6 +29,11 @@ white-space: nowrap !important; line-height: 1.5 !important; } + + #section-pelatihan, + #section-sertifikasi { + scroll-margin-top: 96px; + } @endpush @@ -51,7 +56,7 @@
@include('produktivitas.petani.header', ['petani' => $petani]) -
+
Riwayat Pelatihan @@ -83,6 +88,7 @@ class="delete-db-form"> @csrf @method('DELETE') + @@ -1593,6 +1598,7 @@ action="{{ route('petani.survey-produktivitas.store', $petani->id) }}" class="form-repeater"> @csrf +
@@ -1657,7 +1663,8 @@ @csrf @method('PUT') -
+ +
Kehilangan Hasil Akibat Organisme Pengganggu Tumbuhan (OPT)
@@ -1706,12 +1713,76 @@
@endsection +@push('scripts-head') + +@endpush + @push('scripts') -@endpush \ No newline at end of file +@endpush diff --git a/resources/views/produktivitas/petani/sosial-ekonomi/edit.blade.php b/resources/views/produktivitas/petani/sosial-ekonomi/edit.blade.php index 521563b..d5cb7ae 100644 --- a/resources/views/produktivitas/petani/sosial-ekonomi/edit.blade.php +++ b/resources/views/produktivitas/petani/sosial-ekonomi/edit.blade.php @@ -1,5 +1,17 @@ @extends('layout.main') +@push('scripts-head') + +@endpush + @section('content')
@if (session('success')) @@ -1062,6 +1074,20 @@ const pinjamanTokohAdatAda = @json($pinjamanTokohAdatAdaValue); const tekananJualSegeraAda = @json($tekananJualSegeraAdaValue); const kebebasanMemilihPembeliCukupBebas = Number(@json($kebebasanMemilihPembeliCukupBebasValue)); + const sectionAnchors = { + utama: 'section-utama', + sosial_budaya: 'section-sosial-budaya', + keanggotaan_kelompok: 'section-keanggotaan-kelompok', + akses_keuangan: 'section-akses-keuangan', + keterikatan_hutang: 'section-keterikatan-hutang' + }; + const nextSectionAnchors = { + utama: 'section-sosial-budaya', + sosial_budaya: 'section-keanggotaan-kelompok', + keanggotaan_kelompok: 'section-akses-keuangan', + akses_keuangan: 'section-keterikatan-hutang', + keterikatan_hutang: 'section-keterikatan-hutang' + }; const fieldExamples = { jumlah_tanggungan: 'Contoh: 4', anak_masih_sekolah: 'Contoh: 2', @@ -1399,7 +1425,8 @@ } function syncPihakMembantuFields() { - const isTidakAda = $('#pihak-membantu').val() === pihakMembantuTanpaBantuan; + const isAdaSengketa = $('input[name="ada_sengketa"]:checked').val() === '1'; + const isTidakAda = !isAdaSengketa || $('#pihak-membantu').val() === pihakMembantuTanpaBantuan; const $fields = $('#pihak-membantu-nama, #tahun-bantuan'); $fields.prop('disabled', isTidakAda); @@ -1409,6 +1436,21 @@ } } + function syncSengketaFields() { + const isAdaSengketa = $('input[name="ada_sengketa"]:checked').val() === '1'; + const $fields = $('#keterangan-sengketa, #pihak-membantu, #status-konflik'); + const $assistanceFields = $('#pihak-membantu-nama, #tahun-bantuan'); + + $fields.prop('disabled', !isAdaSengketa); + + if (!isAdaSengketa) { + $fields.add($assistanceFields).val(''); + $fields.filter('select').trigger('change.select2'); + } + + syncPihakMembantuFields(); + } + function syncPernahJualHargaLebihTinggiFields() { const isPernah = $('#pernah-jual-harga-lebih-tinggi').val() === pernahJualHargaLebihTinggiPernah; const $field = $('#penyebab-harga-lebih-tinggi'); @@ -1601,6 +1643,37 @@ clearPendapatanRowValidation($row); } + function setupSectionAnchors() { + $('input[name="form_section"]').each(function () { + const section = this.value; + const anchor = sectionAnchors[section]; + const nextAnchor = nextSectionAnchors[section] || anchor; + const $form = $(this).closest('form'); + + if (anchor) { + $form.find('> .card').first().attr('id', anchor); + } + + if (nextAnchor && !$form.find('input[name="redirect_fragment"]').length) { + $('', { + type: 'hidden', + name: 'redirect_fragment', + value: nextAnchor + }).appendTo($form); + } + }); + + if (window.location.hash) { + const target = document.getElementById(window.location.hash.substring(1)); + + if (target) { + setTimeout(function () { + target.scrollIntoView({ block: 'start' }); + }, 0); + } + } + } + $(document).on('change', '.sosial-ekonomi-komoditas-utama', syncKomoditasLainnyaOptions); $(document).on('input change', '.pendapatan-row input, .pendapatan-row select', function () { clearPendapatanRowValidation($(this).closest('.pendapatan-row')); @@ -1636,6 +1709,7 @@ }); }); $('#pihak-membantu').on('change', syncPihakMembantuFields); + $('input[name="ada_sengketa"]').on('change', syncSengketaFields); $('#pernah-jual-harga-lebih-tinggi').on('change', syncPernahJualHargaLebihTinggiFields); $('input[name="panutan_petani_sukses"]').on('change', syncPanutanFields); $('input[name="terdaftar_kelompok_tani"]').on('change', syncTerdaftarKelompokFields); @@ -1650,10 +1724,12 @@ $('#total-hutang-tidak-bersedia').on('change', syncTotalHutangFields); $('input[name="tekanan_jual_segera"]').on('change', syncTekananJualFields); $('input[name="kebebasan_memilih_pembeli"]').on('change', syncKebebasanPembeliFields); + setupSectionAnchors(); applySosialEkonomiExamples(); syncKomoditasLainnyaOptions(); setupAllPendapatanRows(); syncPihakMembantuFields(); + syncSengketaFields(); syncPernahJualHargaLebihTinggiFields(); syncPanutanFields(); syncTerdaftarKelompokFields(); diff --git a/resources/views/produktivitas/petani/sosial-ekonomi/index.blade.php b/resources/views/produktivitas/petani/sosial-ekonomi/index.blade.php index 22fc8e3..b136076 100644 --- a/resources/views/produktivitas/petani/sosial-ekonomi/index.blade.php +++ b/resources/views/produktivitas/petani/sosial-ekonomi/index.blade.php @@ -1,5 +1,17 @@ @extends('layout.main') +@push('scripts-head') + +@endpush + @section('content')
@if (session('success')) @@ -1058,6 +1070,20 @@ const pinjamanTokohAdatAda = @json($pinjamanTokohAdatAdaValue); const tekananJualSegeraAda = @json($tekananJualSegeraAdaValue); const kebebasanMemilihPembeliCukupBebas = Number(@json($kebebasanMemilihPembeliCukupBebasValue)); + const sectionAnchors = { + utama: 'section-utama', + sosial_budaya: 'section-sosial-budaya', + keanggotaan_kelompok: 'section-keanggotaan-kelompok', + akses_keuangan: 'section-akses-keuangan', + keterikatan_hutang: 'section-keterikatan-hutang' + }; + const nextSectionAnchors = { + utama: 'section-sosial-budaya', + sosial_budaya: 'section-keanggotaan-kelompok', + keanggotaan_kelompok: 'section-akses-keuangan', + akses_keuangan: 'section-keterikatan-hutang', + keterikatan_hutang: 'section-keterikatan-hutang' + }; const fieldExamples = { jumlah_tanggungan: 'Contoh: 4', anak_masih_sekolah: 'Contoh: 2', @@ -1395,7 +1421,8 @@ } function syncPihakMembantuFields() { - const isTidakAda = $('#pihak-membantu').val() === pihakMembantuTanpaBantuan; + const isAdaSengketa = $('input[name="ada_sengketa"]:checked').val() === '1'; + const isTidakAda = !isAdaSengketa || $('#pihak-membantu').val() === pihakMembantuTanpaBantuan; const $fields = $('#pihak-membantu-nama, #tahun-bantuan'); $fields.prop('disabled', isTidakAda); @@ -1405,6 +1432,21 @@ } } + function syncSengketaFields() { + const isAdaSengketa = $('input[name="ada_sengketa"]:checked').val() === '1'; + const $fields = $('#keterangan-sengketa, #pihak-membantu, #status-konflik'); + const $assistanceFields = $('#pihak-membantu-nama, #tahun-bantuan'); + + $fields.prop('disabled', !isAdaSengketa); + + if (!isAdaSengketa) { + $fields.add($assistanceFields).val(''); + $fields.filter('select').trigger('change.select2'); + } + + syncPihakMembantuFields(); + } + function syncPernahJualHargaLebihTinggiFields() { const isPernah = $('#pernah-jual-harga-lebih-tinggi').val() === pernahJualHargaLebihTinggiPernah; const $field = $('#penyebab-harga-lebih-tinggi'); @@ -1597,6 +1639,37 @@ clearPendapatanRowValidation($row); } + function setupSectionAnchors() { + $('input[name="form_section"]').each(function () { + const section = this.value; + const anchor = sectionAnchors[section]; + const nextAnchor = nextSectionAnchors[section] || anchor; + const $form = $(this).closest('form'); + + if (anchor) { + $form.find('> .card').first().attr('id', anchor); + } + + if (nextAnchor && !$form.find('input[name="redirect_fragment"]').length) { + $('', { + type: 'hidden', + name: 'redirect_fragment', + value: nextAnchor + }).appendTo($form); + } + }); + + if (window.location.hash) { + const target = document.getElementById(window.location.hash.substring(1)); + + if (target) { + setTimeout(function () { + target.scrollIntoView({ block: 'start' }); + }, 0); + } + } + } + $(document).on('change', '.sosial-ekonomi-komoditas-utama', syncKomoditasLainnyaOptions); $(document).on('input change', '.pendapatan-row input, .pendapatan-row select', function () { clearPendapatanRowValidation($(this).closest('.pendapatan-row')); @@ -1632,6 +1705,7 @@ }); }); $('#pihak-membantu').on('change', syncPihakMembantuFields); + $('input[name="ada_sengketa"]').on('change', syncSengketaFields); $('#pernah-jual-harga-lebih-tinggi').on('change', syncPernahJualHargaLebihTinggiFields); $('input[name="panutan_petani_sukses"]').on('change', syncPanutanFields); $('input[name="terdaftar_kelompok_tani"]').on('change', syncTerdaftarKelompokFields); @@ -1646,10 +1720,12 @@ $('#total-hutang-tidak-bersedia').on('change', syncTotalHutangFields); $('input[name="tekanan_jual_segera"]').on('change', syncTekananJualFields); $('input[name="kebebasan_memilih_pembeli"]').on('change', syncKebebasanPembeliFields); + setupSectionAnchors(); applySosialEkonomiExamples(); syncKomoditasLainnyaOptions(); setupAllPendapatanRows(); syncPihakMembantuFields(); + syncSengketaFields(); syncPernahJualHargaLebihTinggiFields(); syncPanutanFields(); syncTerdaftarKelompokFields();