/** * GET /employee/jobs/{id}/notes * * Get notes for a job */ public function getNotes(Request $request, $id) { $employee = $request->user(); if (!$employee instanceof Employee) { $employee = Employee::where('email', $employee->email)->first(); } // Verify job ownership/existence, even if not using strictly for filtering $employee->schedules()->findOrFail($id); $notes = \App\Models\JobNote::where('job_id', $id) ->where('job_type', 'guard') // Assuming 'guard' type consistent with EmployeeJobController ->latest() ->get() ->map(function ($note) { return [ 'id' => $note->id, 'note' => $note->note, 'created_at' => $note->created_at->format('Y-m-d H:i'), 'start_time' => $note->created_at->format('H:i') // For UI compatibility if needed ]; }); return response()->json([ 'status' => 'success', 'data' => $notes ]); } /** * POST /employee/jobs/{id}/notes * * Store a new note for a job */ public function storeNote(Request $request, $id) { $request->validate([ 'note' => 'required|string', ]); $employee = $request->user(); if (!$employee instanceof Employee) { $employee = Employee::where('email', $employee->email)->first(); } // Verify job $schedule = $employee->schedules()->findOrFail($id); \App\Models\JobNote::create([ 'employee_id' => $employee->id, 'job_type' => 'guard', // Defaulting to 'guard' as per web controller usage for this context 'job_id' => $schedule->id, 'note' => $request->note, ]); return response()->json([ 'status' => 'success', 'message' => 'Note saved successfully.' ]); } /** * GET /employee/jobs/{id}/tour-progress * * Get tour progress, checkpoints, and scans for a job */ public function getTourProgress(Request $request, $id) { $employee = $request->user(); if (!$employee instanceof Employee) { $employee = Employee::where('email', $employee->email)->first(); } $schedule = $employee->schedules()->with(['tourRoutes.checkpoints', 'checkpointScans'])->findOrFail($id); $tourData = []; foreach ($schedule->tourRoutes as $tour) { $checkpoints = $tour->checkpoints->map(function ($cp) use ($schedule) { // Check if valid scan exists for this checkpoint in this schedule // A scan is valid if it belongs to this schedule and this checkpoint // For simplified "progress", we look for *any* scan or the *latest* scan? // The web UI likely shows if it's "Done" vs "Pending". // Find scans for this checkpoint in this schedule $scans = $schedule->checkpointScans->where('checkpoint_id', $cp->id); $isScanned = $scans->isNotEmpty(); $lastScan = $scans->sortByDesc('scanned_at')->first(); return [ 'id' => $cp->id, 'name' => $cp->name, 'checkpoint_id_code' => $cp->checkpoint_id_code, 'latitude' => $cp->latitude, 'longitude' => $cp->longitude, 'is_scanned' => $isScanned, 'scanned_at' => $lastScan ? \Carbon\Carbon::parse($lastScan->scanned_at)->format('H:i') : null, 'scan_image' => $lastScan && $lastScan->evidence_image ? asset('storage/' . $lastScan->evidence_image) : null, ]; }); $tourData[] = [ 'id' => $tour->id, 'name' => $tour->name, 'checkpoints' => $checkpoints->values() ]; } return response()->json([ 'status' => 'success', 'data' => [ 'tours' => $tourData, 'total_checkpoints' => $schedule->tourRoutes->sum(fn($t) => $t->checkpoints->count()), 'scanned_checkpoints' => $schedule->checkpointScans->unique('checkpoint_id')->count() ] ]); }