id) ->where('material_id', $material->id) ->withCount([ 'entregas', 'entregas as pendientes_count' => fn($q) => $q->where('status', 'pendiente'), 'entregas as calificadas_count' => fn($q) => $q->where('status', 'calificada'), ]) ->orderByDesc('created_at') ->get(); return view('tarea.index', compact('grupo', 'material', 'tareas')); } public function create(Grupo $grupo, Material $material) { return view('tarea.create', compact('grupo', 'material')); } public function store(Request $request, Grupo $grupo, Material $material) { $request->validate([ 'titulo' => 'required|string|max:255', 'descripcion' => 'nullable|string', 'fecha_entrega' => 'nullable|date', ]); $docente = Docente::whereHas('docentes', fn($q) => $q->where('id', Auth::id()))->firstOrFail(); $tarea = Tarea::create([ 'titulo' => $request->titulo, 'descripcion' => $request->descripcion, 'fecha_entrega' => $request->fecha_entrega, 'material_id' => $material->id, 'grupo_id' => $grupo->id, 'docente_id' => $docente->id, ]); foreach ($grupo->alumnos as $alumno) { Entrega::create([ 'tarea_id' => $tarea->id, 'alumno_id' => $alumno->id, 'status' => 'sin_subir', ]); } return redirect()->route('grupo.material.tareas', [$grupo, $material]) ->with('info', 'Tarea creada correctamente.'); } public function show(Grupo $grupo, Material $material, Tarea $tarea) { $alumnos = $grupo->alumnos()->with('alumnos')->get(); $entregasExistentes = Entrega::where('tarea_id', $tarea->id)->pluck('alumno_id')->toArray(); foreach ($alumnos as $alumno) { if (!in_array($alumno->id, $entregasExistentes)) { Entrega::create([ 'tarea_id' => $tarea->id, 'alumno_id' => $alumno->id, 'status' => 'sin_subir', ]); } } $entregas = Entrega::where('tarea_id', $tarea->id) ->with('alumno.alumnos') ->get() ->keyBy('alumno_id'); return view('tarea.show', compact('grupo', 'material', 'tarea', 'alumnos', 'entregas')); } public function edit(Grupo $grupo, Material $material, Tarea $tarea) { return view('tarea.create', compact('grupo', 'material', 'tarea')); } public function update(Request $request, Grupo $grupo, Material $material, Tarea $tarea) { $request->validate([ 'titulo' => 'required|string|max:255', 'descripcion' => 'nullable|string', 'fecha_entrega' => 'nullable|date', ]); $tarea->update([ 'titulo' => $request->titulo, 'descripcion' => $request->descripcion, 'fecha_entrega' => $request->fecha_entrega, ]); return redirect()->route('grupo.material.tareas', [$grupo, $material]) ->with('info', 'Tarea actualizada correctamente.'); } public function destroy(Grupo $grupo, Material $material, Tarea $tarea) { // Borrar archivos físicos de cada entrega antes de eliminar los registros $tarea->entregas() ->whereNotNull('archivo') ->pluck('archivo') ->each(fn($path) => Storage::delete($path)); $tarea->delete(); // las entregas se eliminan en cascada por FK return redirect()->route('grupo.material.tareas', [$grupo, $material]) ->with('info', 'Tarea eliminada.'); } public function acta(Grupo $grupo, Material $material) { $tareas = Tarea::where('grupo_id', $grupo->id) ->where('material_id', $material->id) ->orderBy('created_at') ->get(); $alumnos = $grupo->alumnos()->with('alumnos')->get(); // [alumno_id][tarea_id] => Entrega $entregas = Entrega::whereIn('tarea_id', $tareas->pluck('id')) ->get() ->groupBy('alumno_id') ->map(fn($rows) => $rows->keyBy('tarea_id')); return view('tarea.acta', compact('grupo', 'material', 'tareas', 'alumnos', 'entregas')); } public function calificar(Request $request, Tarea $tarea, Alumno $alumno) { $request->validate([ 'calificacion' => 'required|numeric|min:0|max:10', 'comentario' => 'nullable|string', ]); $entrega = Entrega::where('tarea_id', $tarea->id) ->where('alumno_id', $alumno->id) ->firstOrFail(); $entrega->update([ 'calificacion' => $request->calificacion, 'comentario' => $request->comentario, 'status' => 'calificada', ]); return back()->with('info', 'Calificación guardada.'); } }