diff --git a/app/Enums/PenyakitTanaman.php b/app/Enums/PenyakitTanaman.php index efaf06c..d7ad795 100644 --- a/app/Enums/PenyakitTanaman.php +++ b/app/Enums/PenyakitTanaman.php @@ -8,4 +8,22 @@ enum PenyakitTanaman: string case DAUN_MENGUNING = 'daun_menguning'; case DAUN_BERCAK = 'daun_bercak'; case TANAMAN_LAYU = 'tanaman_layu'; + + public function label(): string + { + return match ($this) { + self::BUSUK_BUAH => 'Busuk Buah', + self::DAUN_MENGUNING => 'Daun Menguning', + self::DAUN_BERCAK => 'Daun Bercak', + self::TANAMAN_LAYU => 'Tanaman Layu', + }; + } + + public static function options(): array + { + return collect(self::cases())->map(fn ($case) => [ + 'value' => $case->value, + 'label' => $case->label(), + ])->toArray(); + } } \ No newline at end of file diff --git a/app/Enums/SeranganHama.php b/app/Enums/SeranganHama.php index 1790019..283df43 100644 --- a/app/Enums/SeranganHama.php +++ b/app/Enums/SeranganHama.php @@ -7,4 +7,21 @@ enum SeranganHama: string case ULAT = 'ulat'; case BELALANG = 'belalang'; case KUTU = 'kutu'; + + public function label(): string + { + return match ($this) { + self::ULAT => 'Ulat', + self::BELALANG => 'Belalang', + self::KUTU => 'Kutu', + }; + } + + public static function options(): array + { + return collect(self::cases())->map(fn ($case) => [ + 'value' => $case->value, + 'label' => $case->label(), + ])->toArray(); + } } diff --git a/app/Http/Controllers/Web/Produktivitas/PetaniController.php b/app/Http/Controllers/Web/Produktivitas/PetaniController.php index d3c85fb..387ba64 100644 --- a/app/Http/Controllers/Web/Produktivitas/PetaniController.php +++ b/app/Http/Controllers/Web/Produktivitas/PetaniController.php @@ -14,6 +14,7 @@ use Illuminate\Support\Facades\Storage; use App\Models\Wilayah\Provinsi; use App\Models\Pertanian\Petani; use App\Models\Wilayah\DesaKelurahan; +use App\Models\Pertanian\Komoditas; use App\Enums\Pendidikan; use App\Enums\Pekerjaan; @@ -53,19 +54,17 @@ class PetaniController extends Controller $pekerjaan = Pekerjaan::options(); $pernikahan = Pernikahan::options(); + $komoditas = Komoditas::all(); + $provinsi = Provinsi::orderBy('kode', 'asc')->get(); return view('produktivitas.petani.add', compact('pendidikan', 'pekerjaan', - 'pernikahan', 'provinsi')); + 'pernikahan', 'provinsi', 'komoditas')); } - public function store(Request $request) + private function validatePetani(Request $request) { - if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) { - abort(403); - } - - $validatedData = $request->validate([ + return $request->validate([ 'nama' => ['required','string','max:255'], 'jenis_kelamin' => ['required','boolean'], 'tempat_lahir' => ['required','string','max:255'], @@ -73,7 +72,7 @@ class PetaniController extends Controller 'pendidikan_terakhir' => ['required', Rule::enum(Pendidikan::class)], 'alamat' => ['required','string','max:500'], 'desa_kelurahan_id' => ['required','exists:master_desa_kelurahan,id'], - //'komoditas_id' => ['required','exists:master_komoditas,id'], + 'komoditas_id' => ['required','exists:master_komoditas,id'], 'status_perkawinan' => ['required', Rule::enum(Pernikahan::class)], 'ktp' => ['nullable', 'min:16', 'max:16'], 'file_ktp' => ['nullable', 'image', 'mimes:jpeg,jpg,png', 'max:2048'], @@ -82,8 +81,48 @@ class PetaniController extends Controller 'foto' => ['nullable', 'image', 'mimes:jpeg,jpg,png', 'max:2048'], 'nomor_telepon' => ['nullable', 'digits_between:11,13'], ], [ + 'nama.required' => 'Nama harus diisi.', + 'nama.string' => 'Nama harus berupa string.', + 'nama.max' => 'Nama tidak boleh lebih dari 255 karakter.', + 'jenis_kelamin.required' => 'Jenis kelamin harus dipilih.', + 'tempat_lahir.required' => 'Tempat lahir harus diisi.', + 'tempat_lahir.string' => 'Tempat lahir harus berupa string.', + 'tempat_lahir.max' => 'Tempat lahir tidak boleh lebih dari 255 karakter.', + 'tanggal_lahir.required' => 'Tanggal lahir harus diisi.', + 'tanggal_lahir.date' => 'Tanggal lahir harus berupa tanggal.', + 'pendidikan_terakhir.required' => 'Pendidikan terakhir harus dipilih.', + 'alamat.required' => 'Alamat harus diisi.', + 'alamat.string' => 'Alamat harus berupa string.', + 'alamat.max' => 'Alamat tidak boleh lebih dari 500 karakter.', + 'desa_kelurahan_id.required' => 'Desa kelurahan harus dipilih.', + 'desa_kelurahan_id.exists' => 'Desa kelurahan tidak ditemukan.', + 'komoditas_id.required' => 'Komoditas harus dipilih.', + 'komoditas_id.exists' => 'Komoditas tidak ditemukan.', + 'status_perkawinan.required' => 'Status perkawinan harus dipilih.', + 'ktp.min' => 'KTP harus berupa 16 digit.', + 'ktp.max' => 'KTP harus berupa 16 digit.', + 'kk.min' => 'KK harus berupa 16 digit.', + 'kk.max' => 'KK harus berupa 16 digit.', + 'file_ktp.image' => 'File KTP harus berupa gambar.', + 'file_ktp.mimes' => 'File KTP harus berupa jpeg, jpg, atau png.', + 'file_ktp.max' => 'File KTP tidak boleh lebih dari 2MB.', + 'file_kk.image' => 'File KK harus berupa gambar.', + 'file_kk.mimes' => 'File KK harus berupa jpeg, jpg, atau png.', + 'file_kk.max' => 'File KK tidak boleh lebih dari 2MB.', + 'foto.image' => 'Foto harus berupa gambar.', + 'foto.mimes' => 'Foto harus berupa jpeg, jpg, atau png.', + 'foto.max' => 'Foto tidak boleh lebih dari 2MB.', 'nomor_telepon.digits_between' => 'Nomor telepon harus berupa angka 11 sampai 13 digit.', ]); + } + + public function store(Request $request) + { + if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) { + abort(403); + } + + $validatedData = $this->validatePetani($request); if ($request->hasFile('file_ktp')) { $file_ktp = $request->file('file_ktp'); @@ -135,10 +174,10 @@ class PetaniController extends Controller $provinsi = Provinsi::all(); - $section = $request->section ?? 'budidaya'; + $komoditas = Komoditas::all(); return view('produktivitas.petani.edit', compact('petani', 'pendidikan', 'pekerjaan', - 'pernikahan', 'provinsi', 'section')); + 'pernikahan', 'provinsi', 'komoditas')); } @@ -150,25 +189,7 @@ class PetaniController extends Controller $petani = Petani::findOrFail($id); - $validatedData = $request->validate([ - 'nama' => ['required','string','max:255'], - 'jenis_kelamin' => ['required','boolean'], - 'tempat_lahir' => ['required','string','max:255'], - 'tanggal_lahir' => ['required','date'], - 'pendidikan_terakhir' => ['required', Rule::enum(Pendidikan::class)], - 'alamat' => ['required','string','max:500'], - 'desa_kelurahan_id' => ['required','exists:master_desa_kelurahan,id'], - //'komoditas_id' => ['required','exists:master_komoditas,id'], - 'status_perkawinan' => ['required', Rule::enum(Pernikahan::class)], - 'ktp' => ['nullable', 'min:16', 'max:16'], - 'file_ktp' => ['nullable', 'file', 'mimes:jpeg,jpg,png,pdf', 'max:2048'], - 'kk' => ['nullable', 'min:16', 'max:16'], - 'file_kk' => ['nullable', 'file', 'mimes:jpeg,jpg,png,pdf', 'max:2048'], - 'foto' => ['nullable', 'file', 'mimes:jpeg,jpg,png', 'max:2048'], - 'nomor_telepon' => ['nullable', 'digits_between:11,13'], - ], [ - 'nomor_telepon.digits_between' => 'Nomor telepon harus berupa angka 11 sampai 13 digit.', - ]); + $validatedData = $this->validatePetani($request); if ($request->hasFile('file_ktp')) { $file_ktp = $request->file('file_ktp'); diff --git a/app/Http/Controllers/Web/Produktivitas/PetaniLahanController.php b/app/Http/Controllers/Web/Produktivitas/PetaniLahanController.php index 1932d86..4386583 100644 --- a/app/Http/Controllers/Web/Produktivitas/PetaniLahanController.php +++ b/app/Http/Controllers/Web/Produktivitas/PetaniLahanController.php @@ -66,15 +66,9 @@ class PetaniLahanController extends Controller return view('produktivitas.petani.lahan.add', compact('petani', 'lahan', 'provinsi', 'komoditas')); } - public function store($petaniId, Request $request) + private function validateLahan(Request $request) { - if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) { - abort(403); - } - - $petani = Petani::findOrFail($petaniId); - - $validated = $request->validate([ + return $request->validate([ 'nama' => ['nullable', 'string', 'max:255'], 'status_kepemilikan' => ['nullable', 'string', 'max:255'], 'profile_id' => ['nullable'], @@ -82,14 +76,14 @@ class PetaniLahanController extends Controller 'keluarga_pengelola_id' => ['nullable'], 'adat_pemilik_id' => ['nullable'], 'desa_kelurahan_id' => ['nullable'], - 'luas_lahan' => ['required', 'numeric'], + 'luas_lahan' => ['required', 'numeric', 'min:0.01'], 'path' => ['nullable', 'string'], 'komoditas_id' => ['required', 'exists:master_komoditas,id'], 'jenis_komoditas_id' => ['required', 'exists:jenis_komoditas,id'], 'varietas_id' => ['nullable', 'exists:master_varietas,id'], - 'jumlah_tanaman' => ['required', 'numeric'], - 'umur_lahan' => ['required', 'numeric'], - 'umur_tanaman' => ['required', 'numeric'], + 'jumlah_tanaman' => ['required', 'numeric', 'min:1'], + 'umur_lahan' => ['required', 'numeric', 'min:1'], + 'umur_tanaman' => ['required', 'numeric', 'min:1'], 'kondisi_tanaman' => ['required', 'string', new Enum(KondisiTanaman::class)], 'serangan_hama' => ['nullable', 'string', new Enum(SeranganHama::class)], 'penyakit_tanaman' => ['nullable', 'string', new Enum(PenyakitTanaman::class)], @@ -98,8 +92,51 @@ class PetaniLahanController extends Controller 'komoditas_lain.*' => ['integer', 'exists:master_komoditas,id'], 'tanaman_penaung' => ['nullable', 'array'], 'tanaman_penaung.*' => ['integer', 'exists:master_komoditas,id'], + 'foto' => ['nullable', 'array'], + 'foto.*' => ['image', 'mimes:jpeg,jpg,png', 'max:2048'], + ], [ + 'nama.string' => 'Nama lahan diisi dengan huruf.', + 'nama.max' => 'Nama lahan maksimal 255 karakter.', + 'status_kepemilikan.string' => 'Status kepemilikan diisi dengan huruf.', + 'status_kepemilikan.max' => 'Status kepemilikan maksimal 255 karakter.', + 'luas_lahan.required' => 'Luas lahan wajib diisi.', + 'luas_lahan.numeric' => 'Luas lahan diisi dengan angka.', + 'luas_lahan.min' => 'Luas lahan minimal 0.01.', + 'jumlah_tanaman.required' => 'Jumlah tanaman wajib diisi.', + 'jumlah_tanaman.numeric' => 'Jumlah tanaman diisi dengan angka.', + 'jumlah_tanaman.min' => 'Jumlah tanaman minimal 1.', + 'umur_lahan.required' => 'Umur lahan wajib diisi.', + 'umur_lahan.numeric' => 'Umur lahan diisi dengan angka.', + 'umur_lahan.min' => 'Umur lahan minimal 1.', + 'umur_tanaman.required' => 'Umur tanaman wajib diisi.', + 'umur_tanaman.numeric' => 'Umur tanaman diisi dengan angka.', + 'umur_tanaman.min' => 'Umur tanaman minimal 1.', + 'kondisi_tanaman.required' => 'Kondisi tanaman wajib dipilih.', + 'kondisi_tanaman.string' => 'Kondisi tanaman diisi dengan huruf.', + 'serangan_hama.string' => 'Serangan hama diisi dengan huruf.', + 'penyakit_tanaman.string' => 'Penyakit tanaman diisi dengan huruf.', + 'keparahan_serangan.string' => 'Keparahan serangan diisi dengan huruf.', + 'komoditas_lain.array' => 'Komoditas lain diisi dengan array.', + 'komoditas_lain.*.exists' => 'Komoditas lain yang dipilih tidak valid.', + 'tanaman_penaung.array' => 'Tanaman penaung diisi dengan array.', + 'tanaman_penaung.*.exists' => 'Tanaman penaung yang dipilih tidak valid.', + 'foto.array' => 'Foto diisi dengan array.', + 'foto.*.image' => 'Foto harus berupa gambar.', + 'foto.*.mimes' => 'Foto harus berupa gambar dengan ekstensi jpeg, jpg, atau png.', + 'foto.*.max' => 'Foto maksimal 2MB.', ]); + } + + public function store($petaniId, Request $request) + { + if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) { + abort(403); + } + + $petani = Petani::findOrFail($petaniId); + + $validated = $this->validateLahan($request); $komoditas = Komoditas::where('id', $request->komoditas_id)->first(); $lahanCount = Lahan::where('petani_id', $petaniId) ->count(); @@ -191,40 +228,14 @@ class PetaniLahanController extends Controller $petani = Petani::findOrFail($petaniId); $lahan = Lahan::where('petani_id', $petaniId)->findOrFail($id); - $validated = $request->validate([ - 'nama' => ['nullable', 'string', 'max:255'], - 'status_kepemilikan' => ['nullable', 'string', 'max:255'], - 'profile_id' => ['nullable'], - 'petani_id' => ['nullable'], - 'keluarga_pengelola_id' => ['nullable'], - 'adat_pemilik_id' => ['nullable'], - 'desa_kelurahan_id' => ['nullable'], - 'luas_lahan' => ['required', 'numeric'], - 'path' => ['nullable', 'string'], - 'komoditas_id' => ['required', 'exists:master_komoditas,id'], - 'jenis_komoditas_id' => ['required', 'exists:jenis_komoditas,id'], - 'varietas_id' => ['nullable', 'exists:master_varietas,id'], - 'jumlah_tanaman' => ['required', 'numeric'], - 'umur_lahan' => ['required', 'numeric'], - 'umur_tanaman' => ['required', 'numeric'], - 'kondisi_tanaman' => ['required', 'string', new Enum(KondisiTanaman::class)], - 'serangan_hama' => ['nullable', 'string', new Enum(SeranganHama::class)], - 'penyakit_tanaman' => ['nullable', 'string', new Enum(PenyakitTanaman::class)], - 'keparahan_serangan' => ['nullable', 'string', new Enum(KeparahanSerangan::class)], - 'komoditas_lain' => ['nullable', 'array'], - 'komoditas_lain.*' => ['integer', 'exists:master_komoditas,id'], - 'tanaman_penaung' => ['nullable', 'array'], - 'tanaman_penaung.*' => ['integer', 'exists:master_komoditas,id'], - ]); - + $validated = $this->validateLahan($request); $komoditas = Komoditas::where('id', $request->komoditas_id)->first(); - - $lahanCount = Lahan::where('petani_id', $petaniId) - ->count(); + $tanamanCount = Tanaman::where('lahan_id', $lahan->id)->count(); + $lahanCount = Lahan::where('petani_id', $petaniId)->count(); $lahan->update([...$validated, - 'nama' => 'Lahan ' . $komoditas->nama . ' #' . ($lahanCount + 1), - 'petani_id' => $petaniId, + //'nama' => 'Lahan ' . $komoditas->nama . ' #' . ($lahanCount + 1), + //'petani_id' => $petaniId, 'updated_by' => auth()->id()] ); @@ -232,8 +243,8 @@ class PetaniLahanController extends Controller $lahanUidParts = explode('LHN-', $lahanUid); $lahanUid = end($lahanUidParts); - if ($lahan) { - $data = collect(range($lahanCount, $lahan->jumlah_tanaman))->map(function ($i) use ($lahan, $komoditas, $lahanUid) { + if ($lahan && $lahan->jumlah_tanaman > $tanamanCount) { + $data = collect(range($tanamanCount + 1, $lahan->jumlah_tanaman))->map(function ($i) use ($lahan, $komoditas, $lahanUid) { return [ 'lahan_id' => $lahan->id, 'komoditas_id' => $lahan->komoditas_id, @@ -257,9 +268,9 @@ class PetaniLahanController extends Controller $data->chunk(500)->each(function ($chunk) { Tanaman::insert($chunk->toArray()); }); - - return redirect()->route('petani.lahan-tanaman.index', $petaniId)->with('success', 'Lahan berhasil ditambahkan.'); } + + return redirect()->route('petani.lahan-tanaman.index', $petaniId)->with('success', 'Lahan berhasil ditambahkan.'); } public function destroy(string $id) diff --git a/app/Models/Pertanian/Lahan.php b/app/Models/Pertanian/Lahan.php index c876134..c8c57de 100644 --- a/app/Models/Pertanian/Lahan.php +++ b/app/Models/Pertanian/Lahan.php @@ -15,6 +15,9 @@ use App\Models\Pertanian\Komoditas; use App\Models\Master\JenisKomoditas; use App\Models\Master\Varietas; use App\Enums\KondisiTanaman; +use App\Enums\SeranganHama; +use App\Enums\PenyakitTanaman; +use App\Enums\KeparahanSerangan; class Lahan extends Model { @@ -52,6 +55,8 @@ class Lahan extends Model 'komoditas_lain', 'tanaman_penaung', + + 'foto' ]; protected $casts = [ @@ -60,6 +65,10 @@ class Lahan extends Model 'komoditas_lain' => 'array', 'tanaman_penaung' => 'array', 'kondisi_tanaman' => KondisiTanaman::class, + 'serangan_hama' => SeranganHama::class, + 'penyakit_tanaman' => PenyakitTanaman::class, + 'keparahan_serangan' => KeparahanSerangan::class, + 'foto' => 'array' ]; public function profile(): BelongsTo diff --git a/app/Models/Pertanian/Petani.php b/app/Models/Pertanian/Petani.php index 594512b..7245538 100644 --- a/app/Models/Pertanian/Petani.php +++ b/app/Models/Pertanian/Petani.php @@ -5,6 +5,8 @@ namespace App\Models\Pertanian; use App\Enums\Pendidikan; use App\Enums\Pernikahan; use App\Models\Wilayah\DesaKelurahan; +use App\Models\Pertanian\Komoditas; + use Carbon\Carbon; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -12,6 +14,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasOne; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Support\Facades\Schema; +use Illuminate\Support\Str; class Petani extends Model { @@ -44,6 +47,8 @@ class Petani extends Model 'pendidikan_terakhir', 'status_perkawinan', + 'komoditas_id', + 'created_by', 'updated_by', 'deleted_by', @@ -93,6 +98,11 @@ class Petani extends Model }); } + public function komoditas(): BelongsTo + { + return $this->belongsTo(Komoditas::class, 'komoditas_id'); + } + public function skor(): HasOne { return $this->hasOne(SkorPetani::class, 'petani_id'); diff --git a/resources/views/produktivitas/petani/add.blade.php b/resources/views/produktivitas/petani/add.blade.php index 33c31df..7635073 100644 --- a/resources/views/produktivitas/petani/add.blade.php +++ b/resources/views/produktivitas/petani/add.blade.php @@ -22,16 +22,19 @@