diff --git a/app/Http/Controllers/Api/InspeksiLahanController.php b/app/Http/Controllers/Api/InspeksiLahanController.php new file mode 100644 index 0000000..e1b15f0 --- /dev/null +++ b/app/Http/Controllers/Api/InspeksiLahanController.php @@ -0,0 +1,142 @@ +integer('size', 10); + $query = InsLahan::query()->with(['lahan']); + + if ($request->filled('search')) { + $s = strtolower($request->search); + $query->where(function($q) use ($s) { + $q->whereRaw('lower(notes) like (?)', ["%{$s}%"]) + ->orWhereRaw('lower(plant_cond) like (?)', ["%{$s}%"]); + }); + } + + if ($request->filled('sort')) { + $sort = $request->sort; + $direction = str_starts_with($sort, '-') ? 'desc' : 'asc'; + $column = ltrim($sort, '-'); + $query->orderBy($column, $direction); + } else { + $query->latest(); + } + + return response()->json($query->paginate($size)); + } + + public function store(Request $request): JsonResponse + { + + Gate::authorize('petani'); + + $validated = $request->validate([ + 'petani_id' => 'required|exists:users,id', + 'lahan_id' => 'required|exists:lahan,id', + 'air' => 'nullable|string', + 'ph' => 'nullable|numeric|between:0,14', + 'humidity' => 'nullable|string', + 'temperature' => 'nullable|string', + 'plant_cond' => 'nullable|string', + 'notes' => 'nullable|string', + 'foto_url' => 'nullable|string', + 'sync_status' => 'nullable|string', + ]); + + $today = Carbon::today(); + + $inspeksi = InsLahan::updateOrCreate( + [ + 'petani_id' => $validated['petani_id'], + 'lahan_id' => $validated['lahan_id'], + + 'created_at' => InsLahan::where('lahan_id', $validated['lahan_id']) + ->whereDate('created_at', $today) + ->exists() ? InsLahan::whereDate('created_at', $today)->first()->created_at : now() + ], + $validated + ); + + return response()->json([ + 'message' => $inspeksi->wasRecentlyCreated ? 'Inspeksi baru berhasil dibuat' : 'Inspeksi hari ini berhasil diperbarui', + 'data' => $inspeksi + ], $inspeksi->wasRecentlyCreated ? 201 : 200); + } + + public function show(string $id): JsonResponse + { + $inspeksi = InsLahan::with('lahan')->findOrFail($id); + return response()->json($inspeksi); + } + + public function update(Request $request, string $id): JsonResponse + { + Gate::authorize('petani'); + $inspeksi = InsLahan::findOrFail($id); + + $validated = $request->validate([ + 'air' => 'nullable|string', + 'ph' => 'nullable|numeric|between:0,14', + 'plant_cond' => 'nullable|string', + 'notes' => 'nullable|string', + 'foto_url' => 'nullable|string', + ]); + + $inspeksi->update($validated); + return response()->json($inspeksi); + } + + public function destroy(string $id): JsonResponse + { + Gate::authorize('petani'); + InsLahan::findOrFail($id)->delete(); + return response()->json(null, 204); + } + + public function batchUpsert(Request $request): JsonResponse + { + Gate::authorize('petani'); + + $request->validate([ + 'inspections' => 'required|array', + 'inspections.*.lahan_id' => 'required', + 'inspections.*.petani_id' => 'required', + ]); + + $dataToUpsert = []; + foreach ($request->inspections as $item) { + $dataToUpsert[] = [ + "petani_id" => $item['petani_id'], + "lahan_id" => $item['lahan_id'], + "air" => $item['air'] ?? null, + "ph" => $item['ph'] ?? null, + "humidity" => $item['humidity'] ?? null, + "temperature" => $item['temperature'] ?? null, + "plant_cond" => $item['plant_cond'] ?? null, + "notes" => $item['notes'] ?? null, + "foto_url" => $item['foto_url'] ?? null, + "sync_status" => 'synced', + "created_at" => $item['created_at'] ?? now(), + "updated_at" => now(), + ]; + } + InsLahan::upsert($dataToUpsert, ['id'], [ + 'air', 'ph', 'humidity', 'temperature', 'plant_cond', 'notes', 'foto_url', 'sync_status', 'updated_at' + ]); + + return response()->json(['message' => 'Sinkronisasi batch berhasil'], 200); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Api/InspeksiController.php b/app/Http/Controllers/Api/InspeksiTanamanController.php similarity index 98% rename from app/Http/Controllers/Api/InspeksiController.php rename to app/Http/Controllers/Api/InspeksiTanamanController.php index 296781a..83e7333 100644 --- a/app/Http/Controllers/Api/InspeksiController.php +++ b/app/Http/Controllers/Api/InspeksiTanamanController.php @@ -8,7 +8,7 @@ use Illuminate\Http\JsonResponse; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Gate; -class InspeksiController extends Controller{ +class InspeksiTanamanController extends Controller{ public function index(Request $request): JsonResponse { $size = +$request->get('size') ?: 10; diff --git a/app/Models/Map/InsLahan.php b/app/Models/Map/InsLahan.php new file mode 100644 index 0000000..a615958 --- /dev/null +++ b/app/Models/Map/InsLahan.php @@ -0,0 +1,43 @@ + 'float', + 'temperatur' => 'float', + 'kelembapan' => 'float', + 'created_at' => 'datetime', + ]; + + public $timestamps = true; + + public function lahan() { + return $this->belongsTo(\App\Models\Map\Lahan::class, 'lahan_id'); + } + public function petani() { + return $this->belongsTo(\App\Models\User::class, 'petani_id'); + } +} \ No newline at end of file diff --git a/app/Models/Map/Panen.php b/app/Models/Map/Panen.php index bacb71e..df007a2 100644 --- a/app/Models/Map/Panen.php +++ b/app/Models/Map/Panen.php @@ -27,10 +27,7 @@ class Panen extends Model 'notes', 'sync_status', ]; - - /** - * Casting tipe data agar konsisten saat diakses di Frontend/JSON. - */ + protected $casts = [ 'weight_kg' => 'float', 'harvest_date' => 'date:Y-m-d', @@ -40,29 +37,16 @@ class Panen extends Model 'updated_at' => 'datetime', ]; - /** - * Relasi ke Lahan (Many-to-One) - */ public function lahan(): BelongsTo { return $this->belongsTo(Lahan::class, 'land_id'); } - - /** - * Relasi ke Tanaman (Many-to-One) - */ public function tanaman(): BelongsTo { - // Pastikan nama model Tanaman sudah sesuai (misal: Tanaman atau Plant) return $this->belongsTo(Tanaman::class, 'plant_id'); } - - /** - * Relasi ke Profile Petani (Many-to-One) - */ public function petani(): BelongsTo { - // farmer_id merujuk ke tabel profiles (profile_id) return $this->belongsTo(\App\Models\Profile::class, 'farmer_id'); } } \ No newline at end of file diff --git a/routes/api.php b/routes/api.php index d191108..957199f 100644 --- a/routes/api.php +++ b/routes/api.php @@ -32,7 +32,8 @@ Route::middleware('auth:sanctum') Route::apiResource('/lahan', \App\Http\Controllers\Api\LahanController::class)->except(['create', 'edit']); Route::apiResource('/tanaman', \App\Http\Controllers\Api\TanamanController::class)->except(['create', 'edit']); - Route::apiResource('/inspeksi', \App\Http\Controllers\Api\InspeksiController::class)->except(['create', 'edit']); + Route::apiResource('/inspeksi/tanaman', \App\Http\Controllers\Api\InspeksiTanamanController::class)->except(['create', 'edit']); + Route::apiResource('/inspeksi/lahan', \App\Http\Controllers\Api\InspeksiLahanController::class)->except(['create', 'edit']); Route::apiResource('/panen', \App\Http\Controllers\Api\PanenController::class)->except(['create', 'edit']); Route::apiResource('/offtaker', \App\Http\Controllers\Api\OfftakerController::class)->except(['create', 'edit']); });