= fromDate) * - toDate : date-time (filters work_date <= toDate) * Optional query param: * - projectId : integer (filters by associated project) * * @response \App\Models\WorkHour */ public function index(Request $request) { $request->validate([ 'fromDate' => 'required|date', 'toDate' => 'required|date', 'projectId' => 'nullable|integer', ]); $from = Carbon::parse($request->query('fromDate')) ->startOfDay() ->toDateTimeString(); // “2025-05-12 00:00:00” $to = Carbon::parse($request->query('toDate')) ->endOfDay() ->toDateTimeString(); // “2025-05-12 23:59:59” $q = WorkHour::with('project.departments') ->whereBetween('work_date', [$from, $to]); if ($pid = $request->query('projectId')) { // filter directly on the foreign key $q->where('project_id', $pid); } $result = $q->get()->map(function (WorkHour $w) { $deptIds = $w->project ->departments ->pluck('id') ->unique() ->values() ->all(); return [ 'WorkHourID' => $w->id, 'UserID' => $w->user_id, 'ProjectID' => $w->project_id, 'OrdinaryHours' => $w->ordinary_hours, 'Date' => $w->work_date->toDateString(), 'Comment' => $w->comment, 'DepartmentIDsProject' => $deptIds, 'Updated' => $w->updated_at->toIso8601String() . 'Z', 'Created' => $w->created_at->toIso8601String() . 'Z', ]; }); return response()->json($result); } }