petani lahan tanaman update

This commit is contained in:
2026-07-01 15:38:15 +07:00
parent 839e9aa572
commit c4ff20facd
14 changed files with 656 additions and 44 deletions
+10
View File
@@ -0,0 +1,10 @@
<?php
namespace App\Enums;
enum KeparahanSerangan: string
{
case RINGAN = 'ringan';
case SEDANG = 'sedang';
case BERAT = 'berat';
}
+4 -5
View File
@@ -4,9 +4,8 @@ namespace App\Enums;
enum KondisiTanaman: string
{
case PRODUKTIF = 'productive';
case KURANG_PRODUKTIF = 'less_productive';
case TIDAK_PRODUKTIF = 'not_productive';
case SAKIT = 'sick';
case MATI = 'dead';
case BAIK = 'baik';
case SEDANG = 'sedang';
case BURUK = 'buruk';
case MATI = 'mati';
}
+11
View File
@@ -0,0 +1,11 @@
<?php
namespace App\Enums;
enum PenyakitTanaman: string
{
case BUSUK_BUAH = 'busuk_buah';
case DAUN_MENGUNING = 'daun_menguning';
case DAUN_BERCAK = 'daun_bercak';
case TANAMAN_LAYU = 'tanaman_layu';
}
+10
View File
@@ -0,0 +1,10 @@
<?php
namespace App\Enums;
enum SeranganHama: string
{
case ULAT = 'ulat';
case BELALANG = 'belalang';
case KUTU = 'kutu';
}
@@ -9,6 +9,8 @@ use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Illuminate\Validation\Rules\Enum;
use App\Models\Pertanian\Petani;
use App\Models\Pertanian\Lahan;
@@ -17,6 +19,12 @@ use App\Models\Wilayah\Provinsi;
use App\Models\Pertanian\Komoditas;
use App\Models\Pertanian\Tanaman;
use App\Enums\StatusLahan;
use App\Enums\KondisiTanaman;
use App\Enums\SeranganHama;
use App\Enums\PenyakitTanaman;
use App\Enums\KeparahanSerangan;
class PetaniLahanController extends Controller
{
public function index($petaniId, Request $request)
@@ -80,6 +88,12 @@ class PetaniLahanController extends Controller
'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 = Komoditas::where('id', $request->komoditas_id)->first();
@@ -103,6 +117,11 @@ class PetaniLahanController extends Controller
'varietas_id' => $lahan->varietas_id,
'petani_id' => $lahan->petani_id,
'nama' => 'Tanaman ' . $komoditas->nama . ' #' . $i,
'umur_tanaman' => $lahan->umur_tanaman,
'kondisi_tanaman' => $lahan->kondisi_tanaman,
'serangan_hama' => $lahan->serangan_hama,
'penyakit_tanaman' => $lahan->penyakit_tanaman,
'keparahan_serangan' => $lahan->keparahan_serangan
];
});
@@ -122,7 +141,7 @@ class PetaniLahanController extends Controller
$petani = Petani::findOrFail($petaniId);
$lahan = Lahan::where('petani_id', $petaniId)
->orderBy('created_at', 'desc')
->orderBy('id', 'asc')
->get();
$lahanSelected = Lahan::where('petani_id', $petaniId)->findOrFail($id);
@@ -140,7 +159,7 @@ class PetaniLahanController extends Controller
$petani = Petani::findOrFail($petaniId);
$lahan = Lahan::where('petani_id', $petaniId)
->orderBy('created_at', 'desc')
->orderBy('id', 'asc')
->get();
$lahanSelected = Lahan::where('petani_id', $petaniId)->findOrFail($id);
@@ -155,9 +174,67 @@ class PetaniLahanController extends Controller
/**
* Update the specified resource in storage.
*/
public function update(Request $request, string $id)
public function update(Request $request, string $petaniId, string $id)
{
//
if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) {
abort(403);
}
$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 = Komoditas::where('id', $request->komoditas_id)->first();
$lahanCount = Lahan::where('petani_id', $petaniId)
->count();
$lahan->update([...$validated,
'nama' => 'Lahan ' . $komoditas->nama . ' #' . ($lahanCount + 1),
'uid' => 'LHN-' . $petani->uid . '-' . strtoupper(Str::random(10)),
'petani_id' => $petaniId,
'updated_by' => auth()->id()]
);
if ($lahan) {
$data = collect(range($lahanCount, $lahan->jumlah_tanaman))->map(function ($i) use ($lahan, $komoditas) {
return [
'lahan_id' => $lahan->id,
'komoditas_id' => $lahan->komoditas_id,
'jenis_komoditas_id' => $lahan->jenis_komoditas_id,
'varietas_id' => $lahan->varietas_id,
'petani_id' => $lahan->petani_id,
'nama' => 'Tanaman ' . $komoditas->nama . ' #' . $i,
];
});
$data->chunk(500)->each(function ($chunk) {
Tanaman::insert($chunk->toArray());
});
return redirect()->route('petani.lahan-tanaman.index', $petaniId)->with('success', 'Lahan berhasil ditambahkan.');
}
}
/**
@@ -0,0 +1,108 @@
<?php
namespace App\Http\Controllers\Web\Produktivitas;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use Illuminate\Validation\Rules\Enum;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use App\Models\Pertanian\Petani;
use App\Models\Pertanian\Lahan;
use App\Models\Pertanian\Tanaman;
use App\Enums\KondisiTanaman;
class PetaniLahanTanamanController extends Controller
{
public function index()
{
//
}
public function create()
{
//
}
public function store(Request $request)
{
//
}
/**
* Display the specified resource.
*/
public function show(string $petaniId, string $lahanId, string $id)
{
if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) {
abort(403);
}
$petani = Petani::findOrFail($petaniId);
$lahan = Lahan::where('petani_id', $petaniId)->findOrFail($lahanId);
$lahanTanaman = Tanaman::with(['komoditas', 'jenisKomoditas', 'varietas', 'profile'])->where('lahan_id', $lahanId)->findOrFail($id);
return response()->json([
'status' => 'success',
'data' => $lahanTanaman,
]);
}
public function edit(string $id)
{
//
}
public function update(Request $request, string $petaniId, string $lahanId, string $id)
{
if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) {
abort(403);
}
$petani = Petani::findOrFail($petaniId);
$lahan = Lahan::where('petani_id', $petaniId)->findOrFail($lahanId);
$lahanTanaman = Tanaman::where('lahan_id', $lahanId)->findOrFail($id);
$validated = $request->validate([
'latitude' => ['nullable', 'numeric', 'between:-90,90', 'required_with:longitude'],
'longitude' => ['nullable', 'numeric', 'between:-180,180', 'required_with:latitude'],
'kondisi_tanaman' => ['nullable', 'string', new Enum(KondisiTanaman::class)],
]);
$lahanTanaman->update([...$validated, 'updated_by' => auth()->id()]);
return response()->json([
'status' => 'success',
'message' => 'Data tanaman berhasil diperbarui',
'data' => $lahanTanaman,
]);
}
/**
* Remove the specified resource from storage.
*/
public function destroy(string $petaniId, string $lahanId, string $id)
{
if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) {
abort(403);
}
$petani = Petani::findOrFail($petaniId);
$lahan = Lahan::where('petani_id', $petaniId)->findOrFail($lahanId);
$lahanTanaman = LahanTanaman::where('lahan_id', $lahanId)->findOrFail($id);
$lahanTanaman->updated_by = auth()->id();
$lahanTanaman->save();
$lahanTanaman->delete();
return response()->json([
'status' => 'success',
'message' => 'Data tanaman berhasil dihapus',
]);
}
}
+6
View File
@@ -36,6 +36,12 @@ class Lahan extends Model
'varietas_id',
'jumlah_tanaman',
'petani_id',
'kondisi_tanaman',
'serangan_hama',
'penyakit_tanaman',
'keparahan_serangan',
'created_by',
'updated_by',
'deleted_by',
+17
View File
@@ -10,6 +10,11 @@ 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 Tanaman extends Model
{
use SoftDeletes;
@@ -32,6 +37,18 @@ class Tanaman extends Model
'created_by',
'updated_by',
'deleted_by',
'umur_tanaman',
'serangan_hama',
'penyakit_tanaman',
'keparahan_serangan',
];
protected $casts = [
'kondisi_tanaman' => KondisiTanaman::class,
'serangan_hama' => SeranganHama::class,
'penyakit_tanaman' => PenyakitTanaman::class,
'keparahan_serangan' => KeparahanSerangan::class,
];
public function komoditas()
@@ -24,7 +24,7 @@ return new class extends Migration
$table->integer('jumlah_tanaman')->nullable();
$table->string('kondisi_tanaman')->nullable();
$table->string('hama_tanaman')->nullable();
$table->string('serangan_hama')->nullable();
$table->string('penyakit_tanaman')->nullable();
$table->string('keparahan_serangan')->nullable();
@@ -35,10 +35,6 @@ return new class extends Migration
Schema::table('petani', function (Blueprint $table) {
$table->foreignId('profile_id')->nullable()->constrained('profiles')->onDelete('set null');
});
Schema::table('map_petani', function (Blueprint $table) {
$table->foreignId('petani_id')->nullable()->constrained('petani')->onDelete('set null');
});
}
/**
@@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('map_tanaman', function (Blueprint $table) {
$table->foreignId('petani_id')->nullable()->constrained('petani')->onDelete('set null');
$table->float('umur_tanaman', 8)->nullable();
$table->string('serangan_hama')->nullable();
$table->string('penyakit_tanaman')->nullable();
$table->string('keparahan_serangan')->nullable();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
}
};
@@ -67,7 +67,7 @@
<input type="hidden" name="status_kepemilikan" value="sendiri">
<div class="row">
<div class="col-lg-6 mb-4">
<h6 class="mb-3">Data Lahan dan Komoditas</h6>
<h6 class="mb-3">Data Lahan dan Tanaman</h6>
<div class="row">
<div class="col-md-6 mb-3 form-control-validation">
@@ -75,8 +75,18 @@
<input type="number" step="0.01" id="luas_lahan" name="luas_lahan" class="form-control @error('luas_lahan') is-invalid @enderror" placeholder="Contoh: 1.5" required />
@error('luas_lahan')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-6 mb-3 form-control-validation">
<label class="form-label">Umur Lahan (tahun)</label>
<input type="number" name="umur_lahan" class="form-control @error('umur_lahan') is-invalid @enderror" placeholder="Contoh: 1" />
@error('umur_lahan')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3 form-control-validation">
<label class="form-label">Jumlah Tanaman <span class="text-danger">*</span></label>
<input type="number" name="jumlah_tanaman" class="form-control @error('jumlah_tanaman') is-invalid @enderror" placeholder="Contoh: 1" required />
@error('jumlah_tanaman')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-6 mb-3 form-control-validation">
<label class="form-label">Komoditas Utama <span class="text-danger">*</span></label>
<select id="komoditas_id" name="komoditas_id" class="form-select @error('komoditas_id') is-invalid @enderror">
@@ -87,28 +97,74 @@
</select>
@error('komoditas_id')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3 form-control-validation">
<label class="form-label">Jenis Komoditas Utama <span class="text-danger">*</span></label>
<select id="jenis_komoditas_id" name="jenis_komoditas_id" class="form-select @error('jenis_komoditas_id') is-invalid @enderror" disabled>
</select>
@error('jenis_komoditas_id')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3 form-control-validation">
<label class="form-label">Varietas Umum <span class="text-danger">*</span></label>
<select id="varietas_id" name="varietas_id" class="form-select @error('varietas_id') is-invalid @enderror" disabled></select>
@error('varietas_id')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-6 mb-3 form-control-validation">
<label class="form-label">Jumlah Tanaman <span class="text-danger">*</span></label>
<input type="number" name="jumlah_tanaman" class="form-control @error('jumlah_tanaman') is-invalid @enderror" placeholder="Contoh: 1" required />
@error('jumlah_tanaman')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="row">
<div class="col-md-6 mb-3 form-control-validation">
<label class="form-label">Umur Tanaman (rata-rata)</label>
<input type="number" name="umur_tanaman" class="form-control @error('umur_tanaman') is-invalid @enderror" placeholder="Contoh: 1" />
@error('umur_tanaman')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3 form-control-validation">
<label class="form-label">Kondisi Umum Tanaman</label>
<select id="kondisi_tanaman" name="kondisi_tanaman" class="form-select @error('kondisi_tanaman') is-invalid @enderror">
<option value="">Pilih Kondisi Tanaman</option>
<option value="{{ \App\Enums\KondisiTanaman::BAIK }}" {{ old('kondisi_tanaman') == \App\Enums\KondisiTanaman::BAIK ? 'selected' : '' }}>Baik</option>
<option value="{{ \App\Enums\KondisiTanaman::SEDANG }}" {{ old('kondisi_tanaman') == \App\Enums\KondisiTanaman::SEDANG ? 'selected' : '' }}>Sedang</option>
<option value="{{ \App\Enums\KondisiTanaman::BURUK }}" {{ old('kondisi_tanaman') == \App\Enums\KondisiTanaman::BURUK ? 'selected' : '' }}>Buruk</option>
</select>
@error('kondisi_tanaman')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-6 mb-3 form-control-validation">
<label class="form-label">Serangan Hama</label>
<select id="serangan_hama" name="serangan_hama" class="form-select @error('serangan_hama') is-invalid @enderror">
<option value="">Pilih Serangan Hama</option>
<option value="{{ \App\Enums\SeranganHama::ULAT }}" {{ old('serangan_hama') == \App\Enums\SeranganHama::ULAT ? 'selected' : '' }}>Ulat</option>
<option value="{{ \App\Enums\SeranganHama::BELALANG }}" {{ old('serangan_hama') == \App\Enums\SeranganHama::BELALANG ? 'selected' : '' }}>Belalang</option>
<option value="{{ \App\Enums\SeranganHama::KUTU }}" {{ old('serangan_hama') == \App\Enums\SeranganHama::KUTU ? 'selected' : '' }}>Kutu</option>
</select>
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3 form-control-validation">
<label class="form-label">Serangan Penyakit</label>
<select id="penyakit_tanaman" name="penyakit_tanaman" class="form-select @error('penyakit_tanaman') is-invalid @enderror">
<option value="">Pilih Penyakit</option>
<option value="{{ \App\Enums\PenyakitTanaman::BUSUK_BUAH }}" {{ old('penyakit_tanaman') == \App\Enums\PenyakitTanaman::BUSUK_BUAH ? 'selected' : '' }}>Busuk Buah</option>
<option value="{{ \App\Enums\PenyakitTanaman::DAUN_MENGUNING }}" {{ old('penyakit_tanaman') == \App\Enums\PenyakitTanaman::DAUN_MENGUNING ? 'selected' : '' }}>Daun Menguning</option>
<option value="{{ \App\Enums\PenyakitTanaman::DAUN_BERCAK }}" {{ old('penyakit_tanaman') == \App\Enums\PenyakitTanaman::DAUN_BERCAK ? 'selected' : '' }}>Daun Bercak</option>
<option value="{{ \App\Enums\PenyakitTanaman::TANAMAN_LAYU }}" {{ old('penyakit_tanaman') == \App\Enums\PenyakitTanaman::TANAMAN_LAYU ? 'selected' : '' }}>Tanaman Layu</option>
</select>
</div>
<div class="col-md-6 mb-3 form-control-validation">
<label class="form-label">Keparahan Serangan Hama/Penyakit</label>
<select id="keparahan_serangan" name="keparahan_serangan" class="form-select @error('keparahan_serangan') is-invalid @enderror">
<option value="">Pilih Keparahan Serangan</option>
<option value="{{ \App\Enums\KeparahanSerangan::RINGAN }}" {{ old('keparahan_serangan') == \App\Enums\KeparahanSerangan::RINGAN ? 'selected' : '' }}>Ringan</option>
<option value="{{ \App\Enums\KeparahanSerangan::SEDANG }}" {{ old('keparahan_serangan') == \App\Enums\KeparahanSerangan::SEDANG ? 'selected' : '' }}>Sedang</option>
<option value="{{ \App\Enums\KeparahanSerangan::BERAT }}" {{ old('keparahan_serangan') == \App\Enums\KeparahanSerangan::BERAT ? 'selected' : '' }}>Berat</option>
</select>
@error('keparahan_serangan')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<hr class="my-4">
<h6 class="mb-3 text-primary"><i class="ti tabler-map-pin me-1"></i> Lokasi Wilayah</h6>
<h6 class="mb-3">Lokasi</h6>
<div class="row">
<div class="col-md-6 mb-3 form-control-validation">
@@ -162,7 +218,7 @@
<div class="col-lg-6 mb-4">
<div class="d-flex justify-content-between align-items-center mb-3">
<h6 class="text-primary mb-0"><i class="ti tabler-map me-1"></i> Gambar Area Lahan</h6>
<h6 class="mb-0">Peta Lahan</h6>
<span class="badge bg-label-info">Gunakan tool ⬟ di kiri peta</span>
</div>
@@ -194,6 +250,11 @@
'use strict';
$(document).ready(function () {
$('#kondisi_tanaman').select2();
$('#serangan_hama').select2();
$('#penyakit_tanaman').select2();
$('#keparahan_serangan').select2();
$('#provinsi_id').select2().change(function(e) {
e.preventDefault();
var provinsiId = $(this).val();
@@ -62,8 +62,9 @@
<div class="col-12 col-lg-10 col-md-9 pt-6 pt-lg-0">
<form id="petani-lahan-tanaman" method="POST" action="{{ route('petani.lahan-tanaman.store', ['petani' => $petani->id]) }}">
<form id="petani-lahan-tanaman" method="POST" action="{{ route('petani.lahan-tanaman.update', ['petani' => $petani->id, 'lahan_tanaman' => $lahanSelected->id]) }}">
@csrf
@method('PUT')
<input type="hidden" name="status_kepemilikan" value="sendiri">
<div class="row">
<div class="col-lg-6 mb-4">
@@ -110,13 +111,14 @@
</div>
<div class="col-md-6 mb-3 form-control-validation">
<label class="form-label">Jumlah Tanaman <span class="text-danger">*</span></label>
<input type="number" name="jumlah_tanaman" class="form-control @error('jumlah_tanaman') is-invalid @enderror" placeholder="Contoh: 1" required />
<input type="number" name="jumlah_tanaman" class="form-control @error('jumlah_tanaman') is-invalid @enderror" placeholder="Contoh: 1" ]
value="{{ old('jumlah_tanaman', $lahanSelected->jumlah_tanaman) }}" required />
@error('jumlah_tanaman')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<hr class="my-4">
<h6 class="mb-3 text-primary"><i class="ti tabler-map-pin me-1"></i> Lokasi Wilayah</h6>
<h6 class="mb-3">Lokasi</h6>
<div class="row">
<div class="col-md-6 mb-3 form-control-validation">
@@ -161,8 +163,9 @@
<div class="row">
<div class="col-md-12 mb-3 form-control-validation">
<label class="form-label">Raw Data Koordinat Lahan (Auto-generated JSON) <span class="text-danger">*</span></label>
<textarea name="path" id="path" class="form-control @error('path') is-invalid @enderror" rows="4" readonly placeholder="Koordinat akan terisi otomatis setelah Anda menggambar polygon di peta..."></textarea>
<small class="text-muted">Pastikan menggambar polygon di peta dengan menyambungkan titik akhir ke titik awal.</small>
<textarea name="path" id="path" class="form-control @error('path') is-invalid @enderror" rows="4" readonly
placeholder="Koordinat akan terisi otomatis setelah Anda menggambar polygon di peta...">{{ old('path', $lahanSelected->path) }}</textarea>
<small class="text-muted">Gunakan tombol edit (pensil) atau hapus (tong sampah) di peta untuk mengubah bentuk lahan.</small>
@error('path')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
@@ -170,8 +173,8 @@
<div class="col-lg-6 mb-4">
<div class="d-flex justify-content-between align-items-center mb-3">
<h6 class="text-primary mb-0"><i class="ti tabler-map me-1"></i> Gambar Area Lahan</h6>
<span class="badge bg-label-info">Gunakan tool ⬟ di kiri peta</span>
<h6 class="mb-0">Peta Lahan</h6>
<span class="badge bg-label-warning">Gunakan tool edit di kiri peta</span>
</div>
<div id="map" class="border rounded shadow-sm"></div>
@@ -194,14 +197,16 @@
</div>
<div class="col-12 col-lg-10 col-md-9">
<div class="table-responsive">
<table class="table table-hover table-sm">
<table class="table table-hover table-sm" id="table-tanaman">
<thead class="border-top">
<tr>
<th>No</th>
<th>Nama</th>
<th>Komoditas</th>
<th>Jenis</th>
<th>Varietas</th>
<th>Lokasi</th>
<th>Kondisi</th>
<th>Hama</th>
<th>Penyakit</th>
<th>Keparahan</th>
<th>Aksi</th>
</tr>
</thead>
@@ -209,14 +214,62 @@
@forelse($lahanSelected->tanaman as $index => $item)
<tr>
<td>{{ $loop->iteration }}</td>
<td><span class="text-heading">{{ $item->nama }}</span></td>
<td><span class="text-muted">{{ $item->komoditas->nama }}</span></td>
<td><span class="text-muted">{{ $item->jenisKomoditas->nama }}</span></td>
<td><span class="text-muted">{{ $item->varietas->nama }} </span></td>
<td>
<div class="d-flex flex-column">
<span class="text-heading">{{ $item->nama }}</span>
<span class="text-muted">{{ $item->komoditas->nama }} / {{ $item->jenisKomoditas->nama }} / {{ $item->varietas->nama }} ({{ $item->umur_tanaman }} tahun)</span>
</div>
</td>
<td class="td-lat-long">
<span class="text-muted">
@if($item->latitude && $item->longitude)
{{ $item->latitude }}, {{ $item->longitude }}
@endif
</span>
</td>
<td class="td-kondisi">
@if($item->kondisi_tanaman == \App\Enums\KondisiTanaman::BAIK)
<span class="badge bg-label-success">Baik</span>
@elseif($item->kondisi_tanaman == \App\Enums\KondisiTanaman::SEDANG)
<span class="badge bg-label-warning">Sedang</span>
@elseif($item->kondisi_tanaman == \App\Enums\KondisiTanaman::BURUK)
<span class="badge bg-label-danger">Buruk</span>
@elseif($item->kondisi_tanaman == \App\Enums\KondisiTanaman::MATI)
<span class="badge bg-label-dark">Mati</span>
@endif
</td>
<td class="td-hama">
@if($item->serangan_hama == \App\Enums\SeranganHama::ULAT)
<span class="badge bg-label-success">Ulat</span>
@elseif($item->serangan_hama == \App\Enums\SeranganHama::BELALANG)
<span class="badge bg-label-danger">Belalang</span>
@elseif($item->serangan_hama == \App\Enums\SeranganHama::KUTU)
<span class="badge bg-label-warning">Kutu</span>
@endif
</td>
<td class="td-penyakit">
@if($item->penyakit_tanaman == \App\Enums\PenyakitTanaman::BUSUK_BUAH)
<span class="badge bg-label-success">Busuk Buah</span>
@elseif($item->penyakit_tanaman == \App\Enums\PenyakitTanaman::DAUN_MENGUNING)
<span class="badge bg-label-danger">Daun Menguning</span>
@elseif($item->penyakit_tanaman == \App\Enums\PenyakitTanaman::DAUN_BERCAK)
<span class="badge bg-label-warning">Daun Bercak</span>
@elseif($item->penyakit_tanaman == \App\Enums\PenyakitTanaman::TANAMAN_LAYU)
<span class="badge bg-label-danger">Tanaman Layu</span>
@endif
</td>
<td class="td-keparahan">
@if($item->keparahan_serangan == \App\Enums\KeparahanSerangan::RINGAN)
<span class="badge bg-label-success">Ringan</span>
@elseif($item->keparahan_serangan == \App\Enums\KeparahanSerangan::SEDANG)
<span class="badge bg-label-warning">Sedang</span>
@elseif($item->keparahan_serangan == \App\Enums\KeparahanSerangan::BERAT)
<span class="badge bg-label-danger">Berat</span>
@endif
</td>
<td>
<div class="d-flex align-items-center">
<a href="{{ route('petani.edit', $item->id) }}" class="btn btn-icon btn-text-secondary rounded-pill edit-record"><i class="ti tabler-edit ti-md"></i></a>
<button data-id="{{ $item->id }}" class="btn btn-icon btn-text-secondary rounded-pill edit-tanaman"><i class="ti tabler-edit ti-md"></i></button>
<a href="javascript:;" class="btn btn-icon btn-text-secondary rounded-pill delete-record" data-id="{{ $item->id }}" data-nama="{{ $item->nama }}"><i class="ti tabler-trash ti-md"></i></a>
<a href="{{ route('petani.show', $item->id) }}" class="btn btn-icon btn-text-secondary rounded-pill view-record"><i class="ti tabler-eye ti-md"></i></a>
</div>
@@ -235,6 +288,8 @@
</div>
</div>
</div>
@include('produktivitas.petani.lahan.tanaman.edit')
@endsection
@push('scripts')
@@ -245,6 +300,25 @@
'use strict';
$(document).ready(function () {
const selectedProvinsi = "{{ optional($lahanSelected->desaKelurahan->kecamatan->kabupatenKota->provinsi)->id }}";
const selectedKabupaten = "{{ optional($lahanSelected->desaKelurahan->kecamatan->kabupatenKota)->id }}";
const selectedKecamatan = "{{ optional($lahanSelected->desaKelurahan->kecamatan)->id }}";
const selectedDesa = "{{ optional($lahanSelected->desaKelurahan)->id }}";
const selectedKomoditas = "{{ optional($lahanSelected->komoditas)->id }}";
const selectedJenisKomoditas = "{{ optional($lahanSelected->jenisKomoditas)->id }}";
const selectedVarietas = "{{ optional($lahanSelected->varietas)->id }}";
$('#table-tanaman').DataTable({
"paging": true,
"lengthChange": true,
"searching": true,
"ordering": false,
"info": true,
"autoWidth": false,
"responsive": true,
});
$('#provinsi_id').select2().change(function(e) {
e.preventDefault();
var provinsiId = $(this).val();
@@ -267,6 +341,10 @@
}
$('#kabupatenkota_id').append('<option value="' + kabupaten.id + '" data-path="' + path + '">' + kabupaten.nama + '</option>');
});
if(selectedKabupaten){
$('#kabupatenkota_id').val(selectedKabupaten).trigger('change');
}
}
});
}
@@ -291,6 +369,9 @@
}
$('#kecamatan_id').append('<option value="' + kecamatan.id + '" data-path="' + path + '">' + kecamatan.nama + '</option>');
});
if (selectedKecamatan) {
$('#kecamatan_id').val(selectedKecamatan).trigger('change');
}
}
});
}
@@ -314,6 +395,9 @@
}
$('#desa_kelurahan_id').append('<option value="' + desa.id + '" data-path="' + path + '">' + desa.nama + '</option>');
});
if (selectedDesa) {
$('#desa_kelurahan_id').val(selectedDesa).trigger('change');
}
}
});
}
@@ -323,6 +407,11 @@
focusToRegionBoundary(this);
});
async function initWilayah() {
if (!selectedProvinsi) return;
$('#provinsi_id').val(selectedProvinsi).trigger('change');
}
$('#komoditas_id').select2().change(function(e) {
e.preventDefault();
var komoditasId = $(this).val();
@@ -338,6 +427,9 @@
data.data.forEach(function(jenis) {
$('#jenis_komoditas_id').append('<option value="' + jenis.id + '">' + jenis.nama + '</option>');
});
if (selectedJenisKomoditas) {
$('#jenis_komoditas_id').val(selectedJenisKomoditas).trigger('change');
}
}
});
}
@@ -356,12 +448,20 @@
data.data.forEach(function(jenis) {
$('#varietas_id').append('<option value="' + jenis.id + '">' + jenis.nama + '</option>');
});
if (selectedVarietas) {
$('#varietas_id').val(selectedVarietas).trigger('change');
}
}
});
}
});
$('#varietas_id').select2();
async function initKomoditas() {
if (!selectedKomoditas) return;
$('#komoditas_id').val(selectedKomoditas).trigger('change');
}
// MAP
let map = L.map('map').setView([-0.789275, 113.921327], 5); // Default: Tengah Indonesia
@@ -373,7 +473,7 @@
let regionBoundaryLayer = L.featureGroup().addTo(map);
function focusToRegionBoundary(selectElement) {
function focusToRegionBoundary(selectElement, shouldZoom = true) {
regionBoundaryLayer.clearLayers(); // Bersihkan garis wilayah sebelumnya
let selectedOption = selectElement.options[selectElement.selectedIndex];
@@ -406,7 +506,7 @@
});
regionBoundaryLayer.addLayer(polygon);
map.fitBounds(polygon.getBounds(), { padding: [20, 20] });
if (shouldZoom) map.fitBounds(polygon.getBounds(), { padding: [20, 20] });
}
} catch (error) {
console.error("Format JSON path wilayah tidak valid:", error);
@@ -441,6 +541,28 @@
});
map.addControl(drawControl);
let rawLahanPath = document.getElementById('path').value;
if (rawLahanPath) {
try {
let parsedPath = JSON.parse(rawLahanPath);
if (Array.isArray(parsedPath) && parsedPath.length > 0) {
let existingLatLngs = parsedPath.map(function(coord) {
return [coord[1], coord[0]];
});
let existingPolygon = L.polygon(existingLatLngs, {
color: '#28c76f', fillColor: '#28c76f', fillOpacity: 0.4, weight: 3
});
drawnItems.addLayer(existingPolygon);
setTimeout(() => { map.fitBounds(existingPolygon.getBounds(), { padding: [30, 30] }); }, 500);
}
} catch (e) {
console.error("Gagal merender polygon lahan eksisting: ", e);
}
}
map.on(L.Draw.Event.CREATED, function (e) {
let layer = e.layer;
@@ -483,7 +605,7 @@
jenis_komoditas_id: { required: true },
varietas_id: { required: true },
desa_kelurahan_id: { required: true },
jumlah_tanaman: { required: true },
jumlah_tanaman: { required: true, min: @json($lahanSelected->jumlah_tanaman) },
},
messages: {
luas_lahan: { required: "Luas lahan wajib diisi" },
@@ -491,7 +613,7 @@
jenis_komoditas_id: { required: "Jenis komoditas wajib diisi" },
varietas_id: { required: "Varietas wajib diisi" },
desa_kelurahan_id: { required: "Desa/Kelurahan wajib diisi" },
jumlah_tanaman: { required: "Jumlah tanaman wajib diisi" },
jumlah_tanaman: { required: "Jumlah tanaman wajib diisi", min: "Jumlah tanaman tidak boleh kurang dari @json($lahanSelected->jumlah_tanaman), hapus pada tanaman yang dimaksud" },
},
errorElement: 'div',
errorPlacement: function (error, element) {
@@ -505,6 +627,9 @@
$(element).removeClass('is-invalid');
}
});
initWilayah();
initKomoditas();
});
</script>
@endpush
@@ -0,0 +1,158 @@
<div class="modal fade" id="tanamanModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="tanamanModalLabel">Ubah Data Tanaman</h5>
<button
type="button"
class="btn-close"
data-bs-dismiss="modal"
aria-label="Close"></button>
</div>
<div class="modal-body">
<form id="editTanamanForm" method="POST" action="{{ route('petani.lahan-tanaman.tanaman.update', ['petani' => $petani->id, 'lahan_tanaman' => $lahanSelected->id, 'tanaman' => ':id']) }}">
@csrf
@method('PUT')
<input type="hidden" name="id" id="editTanamanFormId">
<div class="row mb-3">
<div class="col-md-6">
<label for="komoditas" class="form-label">Komoditas</label>
<input type="text" class="form-control" id="komoditas" name="komoditas" disabled>
</div>
<div class="col-md-6">
<label for="jenis_komoditas" class="form-label">Jenis Komoditas</label>
<input type="text" class="form-control" id="jenis_komoditas" name="jenis_komoditas" disabled>
</div>
</div>
<div class="row mb-3">
<div class="col-md-6">
<label for="varietas" class="form-label">Varietas</label>
<input type="text" class="form-control" id="varietas" name="varietas" disabled>
</div>
</div>
<div class="row mb-3">
<div class="col-md-6">
<label for="latitude" class="form-label">Latitude</label>
<input type="number" class="form-control" id="latitude" name="latitude">
</div>
<div class="col-md-6">
<label for="longitude" class="form-label">Longitude</label>
<input type="number" class="form-control" id="longitude" name="longitude">
</div>
</div>
<div class="row mb-3">
<div class="col-md-6">
<label for="kondisi" class="form-label">Kondisi Tanaman</label>
<select class="form-select" id="kondisi" name="kondisi_tanaman" required>
@foreach (\App\Enums\KondisiTanaman::cases() as $kondisi)
<option value="{{ $kondisi->value }}">{{ $kondisi->name }}</option>
@endforeach
</select>
</div>
</div>
<div class="mb-3">
<button type="submit" class="btn btn-primary">Simpan Perubahan</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@push('scripts')
<script>
$(document).ready(function() {
let currentRow = null;
$('.edit-tanaman').on('click', function(e) {
e.preventDefault();
currentRow = $(this).closest('tr');
var url = "{{ route('petani.lahan-tanaman.tanaman.show', ['petani' => $petani->id, 'lahan_tanaman' => $lahanSelected->id, 'tanaman' => ':id']) }}".replace(':id', $(this).data('id'));
$.ajax({
url: url,
type: 'GET',
success: function(response) {
console.log(response);
$('#komoditas').val(response.data.komoditas.nama);
$('#jenis_komoditas').val(response.data.jenis_komoditas.nama);
$('#varietas').val(response.data.varietas.nama);
$('#latitude').val(response.data.latitude);
$('#longitude').val(response.data.longitude);
$('#kondisi').val(response.data.kondisi_tanaman);
$('#editTanamanFormId').val(response.data.id);
$('#tanamanModal').modal('show');
},
error: function(xhr) {
console.log(xhr.responseText);
}
});
});
$('#editTanamanForm').validate({
rules: {
latitude: {
number: true,
min: -90,
max: 90,
required: function(element) {
return $('#longitude').val() !== '';
}
},
longitude: {
number: true,
min: -180,
max: 180,
required: function(element) {
return $('#latitude').val() !== '';
}
}
},
submitHandler: function(form) {
var url = form.action.replace(':id', $('#editTanamanFormId').val());
console.log(url);
$.ajax({
url: url,
type: 'POST',
data: $(form).serialize(),
success: function(response) {
$('#tanamanModal').modal('hide');
if (response.status === 'success') {
console.log(response.data);
if (response.data.latitude && response.data.longitude) {
currentRow.find('.td-lat-long').html('<span class="text-muted">' + response.data.latitude + ', ' + response.data.longitude + '</span>');
} else {
currentRow.find('.td-lat-long').html('<span class="text-muted">-</span>');
}
if (response.data.kondisi_tanaman) {
if (response.data.kondisi_tanaman === 'baik') {
currentRow.find('.td-kondisi').html('<span class="badge bg-label-success">Baik</span>');
} else if (response.data.kondisi_tanaman === 'sedang') {
currentRow.find('.td-kondisi').html('<span class="badge bg-label-warning">Sedang</span>');
} else if (response.data.kondisi_tanaman === 'buruk') {
currentRow.find('.td-kondisi').html('<span class="badge bg-label-danger">Buruk</span>');
} else if (response.data.kondisi_tanaman === 'mati') {
currentRow.find('.td-kondisi').html('<span class="badge bg-label-dark">Mati</span>');
}
}
} else {
}
currentRow = null;
$('#tanamanModal').modal('hide');
},
error: function(xhr) {
//console.log(xhr.responseText);
}
});
}
});
});
</script>
@endpush
+2
View File
@@ -188,4 +188,6 @@ Route::middleware('auth')
// Petani
Route::resource('petani', App\Http\Controllers\Web\Produktivitas\PetaniController::class);
Route::resource('petani.lahan-tanaman', App\Http\Controllers\Web\Produktivitas\PetaniLahanController::class);
Route::resource('petani.lahan-tanaman.tanaman', App\Http\Controllers\Web\Produktivitas\PetaniLahanTanamanController::class)->only(['show', 'update', 'destroy']);
});