leftJoin('reglas_area_proceso as r', 'ap.id', '=', 'r.area_proceso_id') ->leftJoin('area_curso as ac', 'ap.area_id', '=', 'ac.area_id') ->leftJoin('cursos as c', 'ac.curso_id', '=', 'c.id') ->join('areas as a', 'ap.area_id', '=', 'a.id') ->join('procesos as p', 'ap.proceso_id', '=', 'p.id') ->select( 'ap.id', 'ap.area_id', 'ap.proceso_id', 'a.nombre as area_nombre', 'p.nombre as proceso_nombre', DB::raw('COUNT(DISTINCT r.id) as reglas_count'), DB::raw('COUNT(DISTINCT c.id) as cursos_count') ) ->groupBy('ap.id', 'ap.area_id', 'ap.proceso_id', 'a.nombre', 'p.nombre') ->get(); return response()->json([ 'areaProcesos' => $areasProcesos ]); } public function index($areaProcesoId) { $areaProceso = DB::table('area_proceso as ap') ->join('areas as a', 'a.id', '=', 'ap.area_id') ->join('procesos as p', 'p.id', '=', 'ap.proceso_id') ->where('ap.id', $areaProcesoId) ->select('ap.id as area_proceso_id', 'a.id as area_id', 'a.nombre as area_nombre', 'p.id as proceso_id', 'p.nombre as proceso_nombre', 'p.duracion as cantidad_total_preguntas') ->first(); if (!$areaProceso) { return response()->json(['error' => 'AreaProceso no encontrado'], 404); } $cursos = DB::table('area_curso as ac') ->join('cursos as c', 'c.id', '=', 'ac.curso_id') ->where('ac.area_id', $areaProceso->area_id) ->select('c.id as curso_id', 'c.nombre as nombre') ->get(); $reglasExistentes = DB::table('reglas_area_proceso') ->where('area_proceso_id', $areaProcesoId) ->get(); $reglas = $cursos->map(function ($curso) use ($reglasExistentes) { $regla = $reglasExistentes->firstWhere('curso_id', $curso->curso_id); return [ 'curso_id' => $curso->curso_id, 'nombre' => $curso->nombre, 'regla_id' => $regla->id ?? null, 'orden' => $regla->orden ?? null, 'cantidad_preguntas' => $regla->cantidad_preguntas ?? null, 'nivel_dificultad' => $regla->nivel_dificultad ?? 'medio', 'ponderacion' => $regla->ponderacion ?? null, ]; })->sortBy('orden')->values(); return response()->json([ 'area_proceso_id' => $areaProceso->area_proceso_id, 'proceso' => [ 'id' => $areaProceso->proceso_id, 'nombre' => $areaProceso->proceso_nombre, 'cantidad_total_preguntas' => $areaProceso->cantidad_total_preguntas, ], 'cursos' => $reglas, 'total_preguntas_asignadas' => $reglasExistentes->sum('cantidad_preguntas'), ]); } public function store(Request $request, $areaProcesoId) { $request->validate([ 'curso_id' => 'required|exists:cursos,id', 'cantidad_preguntas' => 'required|integer|min:0', 'orden' => 'required|integer|min:1', 'nivel_dificultad' => 'nullable|string|in:bajo,medio,alto', 'ponderacion' => 'nullable|numeric|min:0|max:100', ]); $areaProceso = DB::table('area_proceso as ap') ->join('procesos as p', 'ap.proceso_id', '=', 'p.id') ->where('ap.id', $areaProcesoId) ->select('p.cantidad_pregunta') ->first(); if (!$areaProceso) { return response()->json([ 'error' => 'No se encontró el proceso asociado al área' ], 404); } $totalPreguntasProceso = $areaProceso->cantidad_pregunta; $totalAsignado = DB::table('reglas_area_proceso') ->where('area_proceso_id', $areaProcesoId) ->where('curso_id', '!=', $request->curso_id) ->sum('cantidad_preguntas'); $totalNuevo = $totalAsignado + $request->cantidad_preguntas; if ($totalNuevo > $totalPreguntasProceso) { return response()->json([ 'error' => 'Excede la cantidad total de preguntas del proceso. Disponible: ' . ($totalPreguntasProceso - $totalAsignado) ], 422); } DB::table('reglas_area_proceso')->updateOrInsert( [ 'area_proceso_id' => $areaProcesoId, 'curso_id' => $request->curso_id, ], [ 'cantidad_preguntas' => $request->cantidad_preguntas, 'orden' => $request->orden, 'nivel_dificultad' => $request->nivel_dificultad ?? 'medio', 'ponderacion' => $request->ponderacion ?? 0, 'updated_at' => now(), 'created_at' => now(), ] ); $totalAsignadoFinal = DB::table('reglas_area_proceso') ->where('area_proceso_id', $areaProcesoId) ->sum('cantidad_preguntas'); return response()->json([ 'success' => true, 'message' => 'Regla guardada correctamente', 'total_preguntas_asignadas' => $totalAsignadoFinal, 'preguntas_disponibles' => $totalPreguntasProceso - $totalAsignadoFinal, ]); } public function update(Request $request, $reglaId) { $request->validate([ 'cantidad_preguntas' => 'required|integer|min:0', 'orden' => 'required|integer|min:1', 'nivel_dificultad' => 'nullable|string|in:bajo,medio,alto', 'ponderacion' => 'nullable|numeric|min:0|max:100', ]); $regla = DB::table('reglas_area_proceso') ->where('id', $reglaId) ->first(); if (!$regla) { return response()->json([ 'error' => 'La regla no existe' ], 404); } $areaProceso = DB::table('area_proceso as ap') ->join('procesos as p', 'ap.proceso_id', '=', 'p.id') ->where('ap.id', $regla->area_proceso_id) ->select('p.cantidad_pregunta') ->first(); if (!$areaProceso) { return response()->json([ 'error' => 'No se encontró el proceso asociado al área' ], 404); } $totalPreguntasProceso = $areaProceso->cantidad_pregunta; $totalAsignado = DB::table('reglas_area_proceso') ->where('area_proceso_id', $regla->area_proceso_id) ->where('id', '!=', $reglaId) ->sum('cantidad_preguntas'); $totalNuevo = $totalAsignado + $request->cantidad_preguntas; if ($totalNuevo > $totalPreguntasProceso) { return response()->json([ 'error' => 'Excede la cantidad total de preguntas del proceso. Disponible: ' . ($totalPreguntasProceso - $totalAsignado) ], 422); } DB::table('reglas_area_proceso') ->where('id', $reglaId) ->update([ 'cantidad_preguntas' => $request->cantidad_preguntas, 'orden' => $request->orden, 'nivel_dificultad' => $request->nivel_dificultad ?? 'medio', 'ponderacion' => $request->ponderacion ?? 0, 'updated_at' => now(), ]); $totalAsignadoFinal = DB::table('reglas_area_proceso') ->where('area_proceso_id', $regla->area_proceso_id) ->sum('cantidad_preguntas'); return response()->json([ 'success' => true, 'message' => 'Regla actualizada correctamente', 'total_preguntas_asignadas' => $totalAsignadoFinal, 'preguntas_disponibles' => $totalPreguntasProceso - $totalAsignadoFinal, ]); } public function destroy($reglaId) { $regla = ReglaAreaProceso::findOrFail($reglaId); $areaProcesoId = $regla->area_proceso_id; $regla->delete(); return response()->json([ 'success' => true, 'message' => 'Regla eliminada correctamente', 'total_preguntas_asignadas' => ReglaAreaProceso::where('area_proceso_id', $areaProcesoId) ->sum('cantidad_preguntas'), ]); } public function storeMultiple(Request $request, $areaProcesoId) { $request->validate([ 'reglas' => 'required|array', 'reglas.*.curso_id' => 'required|exists:cursos,id', 'reglas.*.cantidad_preguntas' => 'required|integer|min:0', 'reglas.*.orden' => 'required|integer|min:1', 'reglas.*.nivel_dificultad' => 'nullable|string|in:bajo,medio,alto', 'reglas.*.ponderacion' => 'nullable|numeric|min:0|max:100', ]); $areaProceso = DB::table('area_proceso as ap') ->join('procesos as p', 'ap.proceso_id', '=', 'p.id') ->where('ap.id', $areaProcesoId) ->select('p.cantidad_pregunta') ->first(); $totalPreguntasProceso = $areaProceso->cantidad_pregunta ?? 0; $totalNuevo = collect($request->reglas)->sum('cantidad_preguntas'); if ($totalNuevo > $totalPreguntasProceso) { return response()->json([ 'error' => 'Excede la cantidad total de preguntas del proceso. Máximo permitido: ' . $totalPreguntasProceso ], 422); } DB::table('reglas_area_proceso')->where('area_proceso_id', $areaProcesoId)->delete(); $insertData = collect($request->reglas)->map(function ($r) use ($areaProcesoId) { return [ 'area_proceso_id' => $areaProcesoId, 'curso_id' => $r['curso_id'], 'cantidad_preguntas' => $r['cantidad_preguntas'], 'orden' => $r['orden'], 'nivel_dificultad' => $r['nivel_dificultad'] ?? 'medio', 'ponderacion' => $r['ponderacion'] ?? 0, 'created_at' => now(), 'updated_at' => now(), ]; })->toArray(); if (!empty($insertData)) { DB::table('reglas_area_proceso')->insert($insertData); } return response()->json([ 'success' => true, 'message' => 'Reglas guardadas correctamente', 'total_preguntas_asignadas' => $totalNuevo, 'preguntas_disponibles' => $totalPreguntasProceso - $totalNuevo, ]); } }