input('search.value', ''); if (!empty($search)) { $data->where(function ($query) use ($search) { $query->whereHas('user', function ($q) use ($search) { $q->where('name', 'like', '%' . $search . '%') ->orWhereHas('profile', function ($p) use ($search) { $p->where('nip', 'like', '%' . $search . '%'); }); }); }); } if ($request->filled('start_date') && $request->filled('end_date')) { try { $startDate = Carbon::parse($request->start_date)->startOfDay(); $endDate = Carbon::parse($request->end_date)->endOfDay(); $data->whereBetween('date', [$startDate, $endDate]); } catch (\Exception $e) { return response()->json([ 'message' => 'Format tanggal tidak valid.', 'error' => $e->getMessage() ], 400); } } if ($request->has('status') && !empty($request->status)) { $data->where('status', $request->status); } if ($request->has('type') && !empty($request->type)) { $data->where('type', $request->type); } $total_data = $data->get()->count(); $length = intval($request->input('length', 0)); $start = intval($request->input('start', 0)); $data = $data->orderBy("date", "desc")->orderBy("time", "desc"); if (!$length && !$start) { $data = $data->get(); } else { $data = $data->skip($start)->take($length)->get(); } return response()->json([ 'message' => 'Data berhasil diambil.', 'data' => $data, 'draw' => $request->input('draw'), 'recordsTotal' => $total_data, 'recordsFiltered' => $total_data, ], 200); } public function show(string $id) { $data = Attendance::with(['user.profile', 'location'])->find($id); if (!$data) { return response()->json([ 'message' => 'Data tidak ditemukan.', 'data' => null ], 422); } return response()->json([ 'message' => 'Data berhasil diambil.', 'data' => $data ], 200); } public function approve(Request $request, string $id) { $attendance = Attendance::find($id); if (!$attendance) { return response()->json(['message'=>'Data tidak ditemukan.'], 422); } // parse check-in & check-out $in = \Carbon\Carbon::parse("{$attendance->date} {$attendance->time}"); $out = \Carbon\Carbon::parse("{$attendance->checkout_date} {$attendance->checkout_time}"); $durationMinutes = $out->diffInMinutes($in); // jam pulang 17:30 di hari yang sama $endOfWork = $in->copy()->setTime(17,00,0); // tentukan status baru if ($durationMinutes < 4*60) { $newStatus = 'jam_kerja_kurang'; } elseif ($out->gt($endOfWork)) { $newStatus = 'lembur'; } else { $newStatus = 'accepted'; } $attendance->update(['status'=>$newStatus]); return response()->json([ 'message' => "Absensi diproses: status “{$newStatus}”.", 'data' => $attendance->load(['user.profile','location']) ], 200); } public function statistics(Request $request) { $today = now()->toDateString(); $thisMonth = now()->format('Y-m'); $stats = [ 'today' => [ 'total' => Attendance::whereDate('date', $today)->count(), 'present' => Attendance::whereDate('date', $today)->where('status', 'accepted')->count(), 'pending' => Attendance::whereDate('date', $today)->where('status', 'pending')->count(), ], 'this_month' => [ 'total' => Attendance::where('date', 'like', $thisMonth . '%')->count(), 'present' => Attendance::where('date', 'like', $thisMonth . '%')->where('status', 'accepted')->count(), 'pending' => Attendance::where('date', 'like', $thisMonth . '%')->where('status', 'pending')->count(), ] ]; return response()->json([ 'message' => 'Statistik berhasil diambil.', 'data' => $stats ], 200); } public function area() { $area = Location::first(); // atau sesuai logic return response()->json([ 'center_lat' => $area->center_lat, 'center_lng' => $area->center_lng, 'radius' => $area->radius, ]); } public function destroy($id) { $attendance = Attendance::find($id); if (!$attendance) { return response()->json(['message' => 'Data tidak ditemukan.'], 404); } $attendance->delete(); return response()->json(['message' => 'Data absensi berhasil dihapus.'], 200); } }