src/Controller/FrontCursoController.php line 367

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\Alumno;
  4. use App\Entity\SolicitudBecaAlumno;
  5. use App\Entity\TestEvaluacionAlumno;
  6. use App\Exception\CustomException;
  7. use App\Form\FrontSolicitudBecaAlumnoType;
  8. use App\Form\FrontTestEvaluacionAlumnoType;
  9. use App\Security\AlumnoVoter;
  10. use App\Security\CursoVoter;
  11. use App\Service\AlumnoService;
  12. use App\Service\CursoService;
  13. use App\Service\SolicitudService;
  14. use Mpdf\Output\Destination;
  15. use Symfony\Component\HttpFoundation\RedirectResponse;
  16. use DateTimeInterface;
  17. use App\Entity\Curso;
  18. use App\Entity\EstadoSolicitud;
  19. use App\Entity\GrupoEdadUsuario;
  20. use App\Entity\Localidad;
  21. use App\Entity\Solicitud;
  22. use App\Entity\Usuario;
  23. use App\Form\FrontFormBusquedaCursoType;
  24. use App\Form\FrontSolicitudType;
  25. use App\Service\Globales;
  26. use DateTime;
  27. use Doctrine\ORM\EntityManagerInterface;
  28. use Exception;
  29. use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
  30. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
  31. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  32. use Symfony\Component\HttpFoundation\Request;
  33. use Symfony\Component\HttpFoundation\Response;
  34. use Symfony\Component\Routing\Annotation\Route;
  35. #[Route(path: '/cursos')]
  36. class FrontCursoController extends AbstractController
  37. {
  38. public function __construct(
  39. private readonly EntityManagerInterface $em,
  40. private readonly Globales $globales,
  41. private readonly SolicitudService $solicitudService,
  42. private readonly AlumnoService $alumnoService,
  43. private readonly CursoService $cursoService)
  44. {
  45. }
  46. #[Route(path: '/ver/{curso}-{slug}', name: 'front_ver_curso', methods: 'GET|POST')]
  47. #[ParamConverter('curso', options: ['mapping' => ['curso' => 'id']])]
  48. public function ver(Curso $curso, string $slug): RedirectResponse|Response
  49. {
  50. // Redirigir si el slug no coincide con el actual (SEO)
  51. if ($slug !== $curso->getSlug()) {
  52. return $this->redirectToRoute('front_ver_curso', [
  53. 'curso' => $curso->getId(),
  54. 'slug' => $curso->getSlug()
  55. ], Response::HTTP_MOVED_PERMANENTLY);
  56. }
  57. // Obtiene y comprueba que el curso cumpla unos criterios. Ver repo.
  58. $curso = $this->em->getRepository(Curso::class)->comprobarAccesibilidadCurso($curso);
  59. if (!$curso) {
  60. return $this->redirectToRoute('front_inicio');
  61. }
  62. // Comprueba si $now esta dentro de las fechas de inicio y fin de solicitud de inscripción del curso.
  63. $fechasEnPlazo = $curso->estaInscripcionAbierta();
  64. // Comprueba si el usuario está inscrito en otro curso y su estado como alumno es != BAJA.
  65. $estaMatriculadoEnOtroCursoNoBaja = $this->isGranted('IS_AUTHENTICATED') && $this->em->getRepository(Alumno::class)->estaMatriculadoEnOtroCursoNoBaja($this->getUser());
  66. return $this->render('front-cursos/ver.html.twig', [
  67. 'curso' => $curso,
  68. 'fechasEnPlazo' => $fechasEnPlazo,
  69. 'estaMatriculadoEnOtroCursoNoBaja' => $estaMatriculadoEnOtroCursoNoBaja
  70. ]);
  71. }
  72. /**
  73. *
  74. * @throws Exception
  75. */
  76. #[Security("is_granted('IS_AUTHENTICATED')")]
  77. #[Route(path: '/solicitar-inscripcion/{curso}/{solicitud}', name: 'front_solicitar_inscripcion_curso', methods: 'GET|POST')]
  78. #[ParamConverter('curso', options: ['mapping' => ['curso' => 'id']])]
  79. #[ParamConverter('solicitud', options: ['mapping' => ['solicitud' => 'id']])]
  80. public function solicitarInscripcionCurso(Request $request, Curso $curso, Solicitud $solicitud = null): Response
  81. {
  82. $this->denyAccessUnlessGranted(CursoVoter::PUEDE_INSCRIBIRSE, $curso);
  83. /** @var Usuario $usuario */
  84. $usuario = $this->getUser();
  85. // Comprueba si $now esta dentro de las fechas de inicio y fin de solicitud de inscripción del curso.
  86. $fechasEnPlazo = $curso->estaInscripcionAbierta();
  87. // Comprueba si el usuario está inscrito en otro curso y su estado como alumno es != BAJA.
  88. $estaMatriculadoEnOtroCursoNoBaja = $this->em->getRepository(Alumno::class)->estaMatriculadoEnOtroCursoNoBaja($this->getUser());
  89. if (!$fechasEnPlazo) {
  90. $this->addFlash('error', 'No está dentro del plazo para poder realizar la solicitud.');
  91. return $this->redirectToRoute('front_ver_curso', [
  92. 'curso' => $curso->getId(),
  93. 'slug' => $curso->getSlug()
  94. ]);
  95. }
  96. if ($estaMatriculadoEnOtroCursoNoBaja) {
  97. $this->addFlash('error', 'Ya está matriculado y no puede realizar otra solicitud.');
  98. return $this->redirectToRoute('front_ver_curso', [
  99. 'curso' => $curso->getId(),
  100. 'slug' => $curso->getSlug()
  101. ]);
  102. }
  103. // Si la solicitud existe y está en estado diferente a borrador, mostramos error.
  104. $solicitudExistente = $this->globales->comprobarSolicitudCursoUsuario($curso, $usuario);
  105. if ($solicitudExistente) {
  106. // Si está en borrador...
  107. if ($solicitudExistente->getEstado()->getId() === 4) {
  108. $solicitud = $solicitudExistente;
  109. } else { // En cualquier otro estado, que muestre error.
  110. $this->addFlash('error', 'Ya ha realizado una solicitud de inscripcion en este curso.');
  111. return $this->redirectToRoute('front_ver_curso', [
  112. 'curso' => $curso->getId(),
  113. 'slug' => $curso->getSlug()
  114. ]);
  115. }
  116. }
  117. if (!$solicitud instanceof Solicitud) {
  118. $estadoSolicitudBorrador = $this->em->getRepository(EstadoSolicitud::class)->find(4);
  119. $solicitud = new Solicitud();
  120. $solicitud
  121. ->setEstado($estadoSolicitudBorrador)
  122. ->setCurso($curso)
  123. ->setUsuario($usuario)
  124. ->setNombre($usuario->getNombre())
  125. ->setApellidos($usuario->getApellidos())
  126. ->setDniNie($usuario->getDniNie())
  127. ->setDireccion($usuario->getDireccion())
  128. ->setLocalidad($usuario->getLocalidad())
  129. ->setCodigoPostal($usuario->getCodigoPostal())
  130. ->setEmail($usuario->getEmail())
  131. ->setTelefono1($usuario->getTelefono1())
  132. ->setTelefono2($usuario->getTelefono2())
  133. ->setFechaNacimiento($usuario->getFechaNacimiento())
  134. ->setSexo($usuario->getSexo());
  135. $this->em->persist($solicitud);
  136. }
  137. $form = $this->createForm(FrontSolicitudType::class, $solicitud);
  138. $form->handleRequest($request);
  139. if ($form->isSubmitted() && $form->isValid()) {
  140. try {
  141. // Si pulsamos el botón de guardar y finalizar, se cambia el estado a pendiente.
  142. $btnSubmitPulsado = $form->getClickedButton()->getConfig()->getName();
  143. // Calculamos el grupo de edad al que pertenece el usuario.
  144. if ($solicitud->getFechaNacimiento() instanceof DateTimeInterface) {
  145. $aniosUsuario = $solicitud->getFechaNacimiento()->diff(new DateTime())->y;
  146. $solicitud->setEdadSolicitud($aniosUsuario);
  147. $gruposEdadesUsuario = $this->em->getRepository(GrupoEdadUsuario::class)->findAll();
  148. $grupoEdadEncontrado = null;
  149. foreach ($gruposEdadesUsuario as $ge) {
  150. if ($aniosUsuario >= $ge->getMin() && $aniosUsuario <= $ge->getMax()) {
  151. $grupoEdadEncontrado = $ge;
  152. break;
  153. }
  154. }
  155. $solicitud->setGrupoEdad($grupoEdadEncontrado);
  156. }
  157. if ($btnSubmitPulsado === 'guardarBorrador') {
  158. $this->em->flush();
  159. $this->addFlash('success', 'Solicitud guardada como borrador.');
  160. }
  161. // Si pulsamos el botón de guardar y finalizar, lo mandamos a la vista detalle del curso.
  162. if ($btnSubmitPulsado === 'guardarFinalizar') {
  163. // Ponemos la solicitud como pendiente de revisión.
  164. $estadoSolicitudPendiente = $this->em->getRepository(EstadoSolicitud::class)->find(1);
  165. $solicitud->setEstado($estadoSolicitudPendiente);
  166. // Añadimos y evaluamos los criterios.
  167. $this->solicitudService->evaluarCriterios($solicitud);
  168. $this->em->flush();
  169. // Generamos el word
  170. $this->solicitudService->generarWordAnexos($solicitud, true);
  171. return $this->render('front-cursos/solicitud-realizada.html.twig', ['solicitud' => $solicitud]);
  172. }
  173. return $this->redirectToRoute('front_solicitar_inscripcion_curso', [
  174. 'curso' => $curso->getId(),
  175. 'solicitud' => $solicitud->getId()
  176. ]);
  177. } catch (Exception $e) {
  178. $this->addFlash('error', 'Se ha producido un error.');
  179. }
  180. }
  181. return $this->render('front-cursos/solicitar-inscripcion.html.twig', [
  182. 'curso' => $curso,
  183. 'solicitud' => $solicitud,
  184. 'form' => $form->createView()
  185. ]);
  186. }
  187. #[Route(path: '', name: 'front_listado_cursos', options: ['expose' => true], methods: 'GET|POST')]
  188. #[Route(path: '/{slugLocalidad}', name: 'front_listado_cursos_localidad', options: ['expose' => true], methods: 'GET|POST')]
  189. #[ParamConverter('slugLocalidad', options: ['mapping' => ['slugLocalidad' => 'slug']])]
  190. public function listado(Request $request, Localidad $slugLocalidad = null): Response
  191. {
  192. $ordenarPor = 'destacados';
  193. $nombre = '';
  194. $itemsPorPagina = 30;
  195. $pagina = $request->query->getInt('page', 1);
  196. if ($request->query->get('itemsPorPagina') && trim($request->query->get('itemsPorPagina')) !== '') {
  197. $itemsPorPagina = $request->query->get('itemsPorPagina');
  198. }
  199. $localidad = null;
  200. if ($slugLocalidad instanceof Localidad) {
  201. $localidad = $slugLocalidad->getSlug();
  202. }
  203. // FORM BÚSQUEDA
  204. $frontFormBusquedaCursos = $this->createForm(FrontFormBusquedaCursoType::class, [
  205. 'localidad' => $slugLocalidad
  206. ]);
  207. $frontFormBusquedaCursos->handleRequest($request);
  208. if ($frontFormBusquedaCursos->isSubmitted() && $frontFormBusquedaCursos->isValid()) {
  209. $nombre = $frontFormBusquedaCursos->get('nombre')->getData() ?? '';
  210. }
  211. // FIN FORM BÚSQUEDA
  212. $cursos = $this->em->getRepository(Curso::class)->obtenerBuscadorFront($nombre, $localidad, $pagina, $itemsPorPagina, null, $ordenarPor);
  213. return $this->render('front-cursos/listado.html.twig', [
  214. 'cursos' => $cursos,
  215. 'itemsPorPagina' => $itemsPorPagina,
  216. 'frontFormBusquedaCursos' => $frontFormBusquedaCursos->createView(),
  217. 'localidad' => $slugLocalidad,
  218. ]);
  219. }
  220. /**
  221. * @throws CustomException
  222. */
  223. #[Security("is_granted('IS_AUTHENTICATED')")]
  224. #[Route(path: '/descargar-anexo-1/{solicitud}', name: 'front_descargar_anexo_1', methods: 'GET')]
  225. public function descargarAnexo1(Solicitud $solicitud): Response
  226. {
  227. return $this->solicitudService->descargarSolicitudPdfAnexo1($solicitud);
  228. }
  229. /**
  230. * @throws CustomException
  231. */
  232. #[Security("is_granted('IS_AUTHENTICATED')")]
  233. #[Route(path: '/descargar-anexo-2/{solicitud}', name: 'front_descargar_anexo_2', methods: 'GET')]
  234. public function descargarAnexo2(Solicitud $solicitud): Response
  235. {
  236. return $this->solicitudService->descargarSolicitudPdfAnexo2($solicitud);
  237. }
  238. /**
  239. * @throws CustomException
  240. */
  241. #[Security("is_granted('IS_AUTHENTICATED')")]
  242. #[Route(path: '/descargar-anexo-3/{solicitud}', name: 'front_descargar_anexo_3', methods: 'GET')]
  243. public function descargarAnexo3(Solicitud $solicitud): Response
  244. {
  245. return $this->solicitudService->descargarSolicitudPdfAnexo3($solicitud);
  246. }
  247. /**
  248. *
  249. * @throws Exception
  250. */
  251. #[Security("is_granted('IS_AUTHENTICATED')")]
  252. #[Route(path: '/test-evaluacion/{alumno}', name: 'front_test_evaluacion_alumno', methods: 'GET|POST')]
  253. public function testEvaluacionAlumno(Request $request, Alumno $alumno): Response
  254. {
  255. $this->denyAccessUnlessGranted(AlumnoVoter::PUEDE_HACER_TEST_EVALUACION, $alumno);
  256. $testEvaluacionAlumno = new TestEvaluacionAlumno();
  257. $testEvaluacionAlumno->setAlumno($alumno);
  258. $this->em->persist($testEvaluacionAlumno);
  259. $form = $this->createForm(FrontTestEvaluacionAlumnoType::class);
  260. $form->handleRequest($request);
  261. if ($form->isSubmitted() && $form->isValid()) {
  262. try {
  263. $testEvaluacionAlumno->setRespuestas($form->getData());
  264. $this->em->flush();
  265. $this->addFlash('success', 'Operación realizada correctamente.');
  266. return $this->redirectToRoute('front_solicitudes_perfil');
  267. } catch (Exception $e) {
  268. $this->addFlash('error', 'Se ha producido un error.');
  269. }
  270. }
  271. return $this->render('front-cursos/test-evaluacion-alumno.html.twig', [
  272. 'testEvaluacionAlumno' => $testEvaluacionAlumno,
  273. 'form' => $form->createView()
  274. ]);
  275. }
  276. /**
  277. *
  278. * @throws Exception
  279. */
  280. #[Security("is_granted('IS_AUTHENTICATED')")]
  281. #[Route(path: '/solicitar-beca/{alumno}', name: 'front_solicitar_beca_alumno', methods: 'GET|POST')]
  282. public function solicitarBecaAlumno(Request $request, Alumno $alumno): Response
  283. {
  284. $this->denyAccessUnlessGranted(AlumnoVoter::PUEDE_SOLICITAR_BECA, $alumno);
  285. $solicitudBecaAlumno = new SolicitudBecaAlumno();
  286. $solicitudBecaAlumno->setAlumno($alumno);
  287. $this->em->persist($solicitudBecaAlumno);
  288. $form = $this->createForm(FrontSolicitudBecaAlumnoType::class, $solicitudBecaAlumno);
  289. $form->handleRequest($request);
  290. if ($form->isSubmitted() && $form->isValid()) {
  291. try {
  292. $this->em->flush();
  293. // Generamos y enviamos los ficheros correspondientes.
  294. $this->alumnoService->generarFicherosSolicitudBeca($solicitudBecaAlumno, true);
  295. $this->addFlash('success', 'Operación realizada correctamente.');
  296. return $this->redirectToRoute('front_solicitudes_perfil');
  297. } catch (Exception $e) {
  298. $this->addFlash('error', 'Se ha producido un error.');
  299. }
  300. }
  301. return $this->render('front-cursos/solicitar-beca-alumno.html.twig', [
  302. 'solicitudBecaAlumno' => $solicitudBecaAlumno,
  303. 'form' => $form->createView()
  304. ]);
  305. }
  306. /**
  307. * @throws Exception
  308. */
  309. #[Route(path: '/descargar-info-curso/{curso}', name: 'front_descargar_info_curso', methods: 'GET')]
  310. public function descargarInfoCurso(Curso $curso): void
  311. {
  312. $this->cursoService->generarPdfInfoCurso($curso, Destination::INLINE);
  313. }
  314. }