src/Controller/ProjectController.php line 241

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\Project;
  4. use App\Entity\QuestionnaireResponse;
  5. use App\Entity\SignatureCharte;
  6. use App\Form\ProjectType;
  7. use App\Repository\AppelAProjetRepository;
  8. use App\Repository\ProjectRepository;
  9. use App\Repository\QuestionnaireRepository;
  10. use App\Repository\QuestionnaireResponseRepository;
  11. use App\Repository\SignatureCharteRepository;
  12. use App\Repository\UserProjectRepository;
  13. use App\Service\ProjectNumberService;
  14. use App\Service\ProjectUserService;
  15. use App\Service\QuestionnaireHandlerService;
  16. use App\Twig\QuestionnaireExtension;
  17. use DateTime;
  18. use Doctrine\ORM\NonUniqueResultException;
  19. use Doctrine\Persistence\ManagerRegistry;
  20. use Knp\Snappy\Pdf;
  21. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  22. use Symfony\Component\Form\FormInterface;
  23. use Symfony\Component\HttpFoundation\BinaryFileResponse;
  24. use Symfony\Component\HttpFoundation\HeaderUtils;
  25. use Symfony\Component\HttpFoundation\JsonResponse;
  26. use Symfony\Component\HttpFoundation\RedirectResponse;
  27. use Symfony\Component\HttpFoundation\Request;
  28. use Symfony\Component\HttpFoundation\Response;
  29. use Symfony\Component\Routing\Annotation\Route;
  30. /**
  31.  * @Route("/project")
  32.  */
  33. class ProjectController extends AbstractController
  34. {
  35.     /**
  36.      * @Route("/{id}", name="project_show", methods={"GET"})
  37.      * @param Project $project
  38.      * @param QuestionnaireResponseRepository $questionnaireResponseRepository
  39.      * @return Response
  40.      */
  41.     public function show(Project $projectQuestionnaireResponseRepository $questionnaireResponseRepositoryUserProjectRepository $userProjectRepository): Response
  42.     {
  43.         $this->denyAccessUnlessGranted('VIEW'$project);
  44.         // récupération des formulaires associés à ce projet
  45.         $questionnairesResponses $questionnaireResponseRepository->findByProject($project);
  46.         // récupération des personnes associées
  47.         $userProject $userProjectRepository->findOrderedByProject($project);
  48.         return $this->render('project/show.html.twig', [
  49.             'project' => $project,
  50.             'questionnairesResponses' => $questionnairesResponses,
  51.             'userProjects' => $userProject,
  52.         ]);
  53.     }
  54.     /**
  55.      * @Route("/{id}/export", name="project_export", methods={"GET"})
  56.      * @param Project $project
  57.      * @return void
  58.      */
  59.     public function export(Project $projectAppelAProjetRepository $appelAProjetRepositoryQuestionnaireRepository $questionnaireRepositoryProjectRepository $projectRepositoryPdf $knpSnappyQuestionnaireExtension $twig)
  60.     {
  61.         $this->denyAccessUnlessGranted('VIEW'$project);
  62.         $appelAProjet $appelAProjetRepository->find($project->getAppelAProjet());
  63.         if ($appelAProjet->getQuestionnaireRapport()) {
  64.             $arrayId[] = $appelAProjet->getQuestionnaireRapport()->getId();
  65.         }if ($appelAProjet->getQuestionnaireDocLi()) {
  66.             $arrayId[] = $appelAProjet->getQuestionnaireDocLi()->getId();
  67.         }if ($appelAProjet->getQuestionnaireEvalCoordo()) {
  68.             $arrayId[] = $appelAProjet->getQuestionnaireEvalCoordo()->getId();
  69.         }if ($appelAProjet->getQuestionnaireEvalThema()) {
  70.             $arrayId[] = $appelAProjet->getQuestionnaireEvalThema()->getId();
  71.         }if ($appelAProjet->getQuestionnaireLi()) {
  72.             $arrayId[] = $appelAProjet->getQuestionnaireLi()->getId();
  73.         }if ($appelAProjet->getQuestionnaireDc()) {
  74.             $arrayId[] = $appelAProjet->getQuestionnaireDc()->getId();
  75.         }if ($appelAProjet->getQuestionnaireExpert()) {
  76.             $arrayId[] = $appelAProjet->getQuestionnaireExpert()->getId();
  77.         }if ($appelAProjet->getQuestionnairePreeval()) {
  78.             $arrayId[] = $appelAProjet->getQuestionnairePreeval()->getId();
  79.         }
  80.         $questionnaires $questionnaireRepository->findForZip($arrayId);
  81.         $project $projectRepository->findOneForZip($project);
  82.         if (!is_dir('Export_ZIP')) {
  83.             mkdir('Export_ZIP');
  84.         }
  85.         $pathProject str_replace(' ''''Export_ZIP/' $project->getNumber());
  86.         $pathZip str_replace(' '''$project->getNumber());
  87.         $zipName str_replace(' '''$project->getNumber());
  88.         if ($project->getPorteur()) {
  89.             $pathProject .= '_' $project->getPorteur();
  90.             $zipName .= '_' $project->getPorteur();
  91.             $pathZip .= '_' $project->getPorteur();
  92.         }
  93.         if ($project->getAcronyme()) {
  94.             $pathProject .= '_' $project->getAcronyme();
  95.             $zipName .= '_' $project->getAcronyme();
  96.             $pathZip .= '_' $project->getAcronyme();
  97.         }
  98.         $zipName .= ".zip";
  99.         if (function_exists('iconv')) {
  100.             $pathProject iconv('utf-8''us-ascii//TRANSLIT'$pathProject);
  101.             $zipName iconv('utf-8''us-ascii//TRANSLIT'$zipName);
  102.             $pathZip iconv('utf-8''us-ascii//TRANSLIT'$pathZip);
  103.         }
  104.         if (!is_dir($pathProject)) {
  105.             mkdir($pathProject);
  106.         }
  107.         $zip = new \ZipArchive();
  108.         $zip->open('Export_ZIP/'.$zipName,  \ZipArchive::CREATE);
  109.         $filenamePrefix $project->getNumber();
  110.         if ($project->getPorteur()) {
  111.             $filenamePrefix .= '_' $project->getPorteur();
  112.         }
  113.         if ($project->getAcronyme()) {
  114.             $filenamePrefix .= '_' $project->getAcronyme();
  115.         }
  116.         foreach ($project->getQuestionnaireResponses() as $questionnaireResponse) {
  117.             if ($this->isGranted('VIEW'$questionnaireResponse)) {
  118.                 $filename str_replace(' '''$questionnaireResponse->getQuestionnaireType() . '_' $filenamePrefix '_' $questionnaireResponse->getId() . '.pdf');
  119.                 if (function_exists('iconv')) {
  120.                     $filename iconv('utf-8''us-ascii//TRANSLIT'$filename);
  121.                 }
  122.                 $arrayQuestionnaire = [];
  123.                 foreach ($questionnaireResponse->getAnswers() as $answer) {
  124.                     $arrayQuestionnaire[$answer->getQuestion()->getId()][] = $answer;
  125.                     if ($answer->getIdFile()) {
  126.                         //$zip->addFile('../files/responses/'.$answer->getIdFile(), $pathZip.'/'.$questionnaireResponse->getQuestionnaireType().'_'.$questionnaireResponse->getAuthor()->getUserIdentifier().'_'.$answer->getValue());
  127.                         $zip->addFile('../files/responses/' $answer->getIdFile(), $pathZip '/' $answer->getValue());
  128.                     }
  129.                 }
  130.                 // génération du pdf
  131.                 // n'utilise pas le même template que l'export individuel car les données ne sont pas récupérées de la même façon de la bdd.
  132.                 $html $knpSnappy->getOutputFromHtml(
  133.                     $this->renderView(
  134.                         'questionnaire_response/showPdfZip.html.twig',
  135.                         [
  136.                             'questionnaireResponse' => $questionnaireResponse,
  137.                             'questions' => $questionnaireResponse->getQuestionnaire()->getQuestions(),
  138.                             'arrayQuestionnaire' => $arrayQuestionnaire,
  139.                         ]
  140.                     ),
  141.                     [
  142.                         'footer-left' => $twig->dateFormat(new DateTime(), 'long'),
  143.                         'footer-center' => 'Page [page]/[topage]',
  144.                         'enable-local-file-access' => true,
  145.                     ]
  146.                 );
  147.                 file_put_contents($pathProject '/' $filename$html);
  148.             }
  149.         }
  150.         $dir opendir($pathProject);
  151.         while($file readdir($dir)) {
  152.             if(is_file($pathProject.'/'.$file)) {
  153.                 $zip->addFile($pathProject.'/'.$file$pathZip.'/'.$file);
  154.             }
  155.         }
  156.         $zip->close();
  157.         $disposition HeaderUtils::makeDisposition(
  158.             HeaderUtils::DISPOSITION_ATTACHMENT,
  159.             $zipName
  160.         );
  161.         $response = new BinaryFileResponse('Export_ZIP/'.$zipName);
  162.         $response->deleteFileAfterSend(true);
  163.         $response->headers->set('Content-Disposition'$disposition);
  164.         $dir opendir($pathProject);
  165.         while($file readdir($dir)) {
  166.             if (is_file($pathProject.'/'.$file)) {
  167.                 unlink($pathProject '/' $file);
  168.             }
  169.         }
  170.         rmdir($pathProject);
  171.         return $response;
  172.     }
  173.     /**
  174.      * @Route("/{id}/edit", name="project_edit", methods={"GET","POST"})
  175.      * @param Request $request
  176.      * @param Project $project
  177.      * @param ManagerRegistry $doctrine
  178.      * @return Response
  179.      */
  180.     public function edit(Request $requestProject $projectManagerRegistry $doctrine): Response
  181.     {
  182.         $this->denyAccessUnlessGranted('EDIT'$project);
  183.         $form $this->createForm(ProjectType::class, $project);
  184.         $form->handleRequest($request);
  185.         if ($form->isSubmitted()) {
  186.             if ($form->isValid()) {
  187.                 $em $doctrine->getManager();
  188.                 $em->flush();
  189.                 return $this->redirectToRoute('project_show', ['id' => $project->getId()], Response::HTTP_SEE_OTHER);
  190.             } else {
  191.                 $this->addFlash('error''Les données soumises sont invalides');
  192.             }
  193.         }
  194.         return $this->renderForm('project/edit.html.twig', [
  195.             'project' => $project,
  196.             'form' => $form,
  197.         ]);
  198.     }
  199.     /**
  200.      * @Route("/{id}/add-files", name="project_add_files", methods={"GET", "POST"})
  201.      * @Route("/{id}/add-files/auto", name="project_add_files_auto", methods={"POST"})
  202.      *
  203.      * @param Request $request
  204.      * @param Project $project
  205.      * @param QuestionnaireResponseRepository $questionnaireResponseRepository
  206.      * @param QuestionnaireHandlerService $questionnaireHandlerService
  207.      * @param ManagerRegistry $doctrine
  208.      * @return Response
  209.      */
  210.     public function addFiles(Request $requestProject $projectQuestionnaireResponseRepository $questionnaireResponseRepositoryQuestionnaireHandlerService $questionnaireHandlerServiceManagerRegistry $doctrine): Response
  211.     {
  212.         $this->denyAccessUnlessGranted('ADD_FILES'$project);
  213.         // vérification de l'existance d'un qr
  214.         $qr $questionnaireResponseRepository->getByTypeByProject(QuestionnaireResponse::QR_TYPE_LI_DOC$project);
  215.         if (count($qr) == 1) {
  216.             if ($qr[0]->getStatus() == QuestionnaireResponse::S_STATUS_DRAFT) {
  217.                 return $this->redirectToRoute('questionnaire_display_submission', ['questionnaireResponse' => $qr[0]->getId()]);
  218.             } else {
  219.                 $this->addFlash('warning''Vous avez déjà soumis ce formulaire, vous ne pouvez plus le modifier');
  220.                 return $this->redirectToRoute('questionnaire_response_show', ['questionnaireResponse' => $qr[0]->getId()]);
  221.             }
  222.         }
  223.         $form $questionnaireHandlerService->createForm($project->getAppelAProjet()->getQuestionnaireDocLi());
  224.         $form->handleRequest($request);
  225.         if ($form->isSubmitted()) {
  226.             $return $questionnaireHandlerService->handleSubmission();
  227.             if ($return instanceof Response) {
  228.                 // cas d'une erreur
  229.                 return $return;
  230.             }
  231.             // cas où ça c'est bien passé
  232.             $questionnaireResponse $questionnaireHandlerService->getQuestionnaireResponse();
  233.             $em $doctrine->getManager();
  234.             $questionnaireResponse->setQuestionnaireType(QuestionnaireResponse::QR_TYPE_LI_DOC);
  235.             $questionnaireResponse->setProject($project);
  236.             $em->flush();
  237.             if ($request->attributes->get('_route') == 'project_add_files') {
  238.                 $this->addFlash('success'$return);
  239.                 if ($questionnaireResponse->getStatus() == QuestionnaireResponse::S_STATUS_SUBMIT) {
  240.                     $this->addFlash('success''Vous êtes invité à soumettre le projet pour terminer le processus de dépôt.');
  241.                     return new JsonResponse(['url' => $this->generateUrl('project_submit', ['id' => $questionnaireResponse->getProject()->getId()])]);
  242.                 }
  243.                 return new JsonResponse(['url' => $this->generateUrl('project_show', ['id' => $project->getId()])]);
  244.             } else {
  245.                 return new JsonResponse(['url' => $this->generateUrl('questionnaire_display_submission', ['questionnaireResponse' => $questionnaireResponse->getId()])]);
  246.             }
  247.         }
  248.         return $questionnaireHandlerService->renderForm($request$project);
  249.     }
  250.     /**
  251.      * @Route("/{id}/submit-project", name="project_submit", methods={"GET", "POST"})
  252.      *
  253.      * @param Request $request
  254.      * @param Project $project
  255.      * @param QuestionnaireResponseRepository $questionnaireResponseRepository
  256.      * @param ProjectNumberService $projectNumberService
  257.      * @param ManagerRegistry $doctrine
  258.      * @return Response
  259.      */
  260.     public function submitProject(Request $requestProject $projectQuestionnaireResponseRepository $questionnaireResponseRepositoryProjectNumberService $projectNumberServiceManagerRegistry $doctrine): Response
  261.     {
  262.         $this->denyAccessUnlessGranted('SUBMIT'$project);
  263.         if ($project->getAppelAProjet()->getQuestionnaireLi()) {
  264.             $qrLi $questionnaireResponseRepository->getByTypeByProject(QuestionnaireResponse::QR_TYPE_LI_I$project)[0];
  265.             if ($qrLi->getStatus() == QuestionnaireResponse::S_STATUS_DRAFT) {
  266.                 $this->addFlash('warning''Vous devez soumettre la lettre d\'intention pour pouvoir soumettre le projet');
  267.                 return $this->redirectToRoute('questionnaire_display_submission', ['questionnaireResponse' => $qrLi->getId()]);
  268.             }
  269.             $qrLiDoc $questionnaireResponseRepository->getByTypeByProject(QuestionnaireResponse::QR_TYPE_LI_DOC$project);
  270.             if (count($qrLiDoc) == 0) {
  271.                 $this->addFlash('warning''Vous devez déposer les documents associés à la lettre d\'intention pour pouvoir soumettre le projet');
  272.                 return $this->redirectToRoute('project_add_files', ['id' => $project->getId()]);
  273.             }
  274.             if ($qrLiDoc[0]->getStatus() == QuestionnaireResponse::S_STATUS_DRAFT) {
  275.                 $this->addFlash('warning''Vous devez soumettre les documents associés à la lettre d\'intention pour pouvoir soumettre le projet');
  276.                 return $this->redirectToRoute('questionnaire_display_submission', ['questionnaireResponse' => $qrLiDoc[0]->getId()]);
  277.             }
  278.         } else {
  279.             $qrDc $questionnaireResponseRepository->getByTypeByProject(QuestionnaireResponse::QR_TYPE_DC$project)[0];
  280.             if ($qrDc->getStatus() == QuestionnaireResponse::S_STATUS_DRAFT) {
  281.                 $this->addFlash('warning''Vous devez soumettre le dossier complet pour pouvoir soumettre le projet');
  282.                 return $this->redirectToRoute('questionnaire_display_submission', ['questionnaireResponse' => $qrDc->getId()]);
  283.             }
  284.         }
  285.         // formulaire de validation (pour faire un deuxième clic)
  286.         if ($request->getMethod() === 'POST') {
  287.             if ($this->isCsrfTokenValid('submit'.$project->getId(), $request->request->get('_token'))) {
  288.                 $entityManager $doctrine->getManager();
  289.                 if ($project->getAppelAProjet()->getQuestionnaireLi()) {
  290.                     $project->setStatus(Project::PROJECT_STATUS_DEPOSE);
  291.                 } else {
  292.                     $project->setStatus(Project::PROJECT_STATUS_DC_DEPOSE);
  293.                 }
  294.                 $project->setNumber($projectNumberService->generateLeftNumber($project$project->getStatus()));
  295.                 $entityManager->flush();
  296.                 $this->addFlash('success''Projet soumis avec succès');
  297.                 return $this->redirectToRoute('project_show', ['id' => $project->getId()]);
  298.             }
  299.             $this->addFlash('error''Une erreur est survenue, veuillez réessayer');
  300.         }
  301.         return $this->render('project/submit.html.twig', [
  302.             'project' => $project,
  303.             'routeName' => 'project_submit',
  304.         ]);
  305.     }
  306.     /**
  307.      * @Route("/{id}/preevaluation", name="project_preeval", methods={"GET", "POST"})
  308.      * @Route("/{id}/preevaluation/auto", name="project_preeval_auto", methods={"POST"})
  309.      * @Route("/{id}/preevaluation-thema", name="project_preeval_thema", methods={"GET", "POST"})
  310.      * @Route("/{id}/preevaluation-thema/auto", name="project_preeval_thema_auto", methods={"POST"})
  311.      * @Route("/{id}/expertise", name="project_expert", methods={"GET", "POST"})
  312.      * @Route("/{id}/expertise/auto", name="project_expert_auto", methods={"POST"})
  313.      * @Route("/{id}/rapport", name="project_rapport", methods={"GET", "POST"})
  314.      * @Route("/{id}/rapport/auto", name="project_rapport_auto", methods={"POST"})
  315.      * @Route("/{id}/expert-3", name="project_expert_3", methods={"GET", "POST"})
  316.      * @Route("/{id}/expert-3/auto", name="project_expert_3_auto", methods={"POST"})
  317.      *
  318.      * @param Request $request
  319.      * @param Project $project
  320.      * @param UserProjectRepository $userProjectRepository
  321.      * @param SignatureCharteRepository $signatureCharteRepository
  322.      * @param QuestionnaireHandlerService $questionnaireHandlerService
  323.      * @param ManagerRegistry $doctrine
  324.      * @return JsonResponse|RedirectResponse|Response
  325.      * @throws NonUniqueResultException
  326.      */
  327.     public function questionnaire(Request $requestProject $projectUserProjectRepository $userProjectRepositorySignatureCharteRepository $signatureCharteRepositoryQuestionnaireHandlerService $questionnaireHandlerServiceManagerRegistry $doctrine)
  328.     {
  329.         switch ($request->attributes->get('_route')) {
  330.             case 'project_preeval':
  331.             case 'project_preeval_auto':
  332.                 $this->denyAccessUnlessGranted('PRE_EVAL'$project);
  333.                 $charte true;
  334.                 $urlCharte 'project_preeval_charte';
  335.                 $type QuestionnaireResponse::QR_TYPE_PREEVAL;
  336.                 $questionnaire $project->getAppelAProjet()->getQuestionnairePreeval();
  337.                 break;
  338.             case 'project_preeval_thema':
  339.             case 'project_preeval_thema_auto':
  340.                 $this->denyAccessUnlessGranted('THEMA'$project);
  341.                 $charte false;
  342.                 $type QuestionnaireResponse::QR_TYPE_EVAL_THEMA;
  343.                 $questionnaire $project->getAppelAProjet()->getQuestionnaireEvalThema();
  344.                 break;
  345.             case 'project_expert':
  346.             case 'project_expert_auto':
  347.                 $this->denyAccessUnlessGranted('EXPERT'$project);
  348.                 $charte true;
  349.                 $urlCharte 'project_expert_charte';
  350.                 $type QuestionnaireResponse::QR_TYPE_EXPERT;
  351.                 $questionnaire $project->getAppelAProjet()->getQuestionnaireExpert();
  352.                 break;
  353.             case 'project_rapport':
  354.             case 'project_rapport_auto':
  355.                 $this->denyAccessUnlessGranted('RAPPORT'$project);
  356.                 $charte true;
  357.                 $urlCharte 'project_rapport_charte';
  358.                 $type QuestionnaireResponse::QR_TYPE_RAPPORT;
  359.                 $questionnaire $project->getAppelAProjet()->getQuestionnaireRapport();
  360.                 break;
  361.             case 'project_expert_3':
  362.             case 'project_expert_3_auto':
  363.                 $this->denyAccessUnlessGranted('EXPERT_3'$project);
  364.                 $charte true;
  365.                 $urlCharte 'project_expert_3_charte';
  366.                 $type QuestionnaireResponse::QR_TYPE_EXPERT_3;
  367.                 $questionnaire $project->getAppelAProjet()->getQuestionnaireExpert();
  368.                 break;
  369.         }
  370.         if ($charte === true) {
  371.             // vérification de la signature de la charte
  372.             $signature $signatureCharteRepository->findOneBy(['appelAProjet' => $project->getAppelAProjet(), 'user' => $this->getUser(), 'type' => $type]);
  373.             if (!$signature) {
  374.                 return $this->redirectToRoute($urlCharte, ['id' => $project->getId()]);
  375.             }
  376.         }
  377.         // récupération du userProject
  378.         $up $userProjectRepository->getByTypeByProjectByUser($type$project$this->getUser());
  379.         if ($up->getQuestionnaireResponse()) {
  380.             if ($up->getQuestionnaireResponse()->getStatus() == QuestionnaireResponse::S_STATUS_DRAFT) {
  381.                 return $this->redirectToRoute('questionnaire_display_submission', ['questionnaireResponse' => $up->getQuestionnaireResponse()->getId()]);
  382.             } else {
  383.                 $this->addFlash('warning''Vous avez déjà soumis ce formulaire, vous ne pouvez plus le modifier');
  384.                 return $this->redirectToRoute('questionnaire_response_show', ['questionnaireResponse' => $up->getQuestionnaireResponse()->getId()]);
  385.             }
  386.         }
  387.         $form $questionnaireHandlerService->createForm($questionnaire);
  388.         $form->handleRequest($request);
  389.         if ($form->isSubmitted()) {
  390.             $return $questionnaireHandlerService->handleSubmission();
  391.             if ($return instanceof Response) {
  392.                 // cas d'une erreur
  393.                 return $return;
  394.             }
  395.             // cas où ça c'est bien passé
  396.             $questionnaireResponse $questionnaireHandlerService->getQuestionnaireResponse();
  397.             $em $doctrine->getManager();
  398.             $questionnaireResponse->setQuestionnaireType($type);
  399.             $questionnaireResponse->setProject($project);
  400.             $up->setQuestionnaireResponse($questionnaireResponse);
  401.             $em->flush();
  402.             if (in_array($request->attributes->get('_route'), ['project_preeval_auto''project_preeval_thema_auto''project_expert_auto''project_rapport_auto''project_expert_3_auto'])) {
  403.                 return new JsonResponse(['url' => $this->generateUrl('questionnaire_display_submission', ['questionnaireResponse' => $questionnaireResponse->getId()])]);
  404.             } else {
  405.                 $this->addFlash('success'$return);
  406.                 return new JsonResponse(['url' => $this->generateUrl('project_show', ['id' => $project->getId()])]);
  407.             }
  408.         }
  409.         return $questionnaireHandlerService->renderForm($request$project);
  410.     }
  411.     /**
  412.      * @Route("/{id}/preevaluation-charte", name="project_preeval_charte", methods={"GET", "POST"})
  413.      * @Route("/{id}/expert-charte", name="project_expert_charte", methods={"GET", "POST"})
  414.      * @Route("/{id}/rapport-charte", name="project_rapport_charte", methods={"GET", "POST"})
  415.      * @Route("/{id}/expert-3-charte", name="project_expert_3_charte", methods={"GET", "POST"})
  416.      */
  417.     public function charte(Request $requestProject $projectSignatureCharteRepository $signatureCharteRepositoryManagerRegistry $doctrine): RedirectResponse|Response
  418.     {
  419.         switch ($request->attributes->get('_route')) {
  420.             case 'project_preeval_charte':
  421.                 $this->denyAccessUnlessGranted('PRE_EVAL'$project);
  422.                 $type QuestionnaireResponse::QR_TYPE_PREEVAL;
  423.                 $url 'project_preeval';
  424.                 $typeCharte 'chartePreeval';
  425.                 break;
  426.             case 'project_expert_charte':
  427.                 $this->denyAccessUnlessGranted('EXPERT'$project);
  428.                 $type QuestionnaireResponse::QR_TYPE_EXPERT;
  429.                 $url 'project_expert';
  430.                 $typeCharte 'charteExpert';
  431.                 break;
  432.             case 'project_expert_3_charte':
  433.                 $this->denyAccessUnlessGranted('EXPERT_3'$project);
  434.                 $type QuestionnaireResponse::QR_TYPE_EXPERT_3;
  435.                 $url 'project_expert_3';
  436.                 $typeCharte 'charteExpert3';
  437.                 break;
  438.             case 'project_rapport_charte':
  439.                 $this->denyAccessUnlessGranted('RAPPORT'$project);
  440.                 $type QuestionnaireResponse::QR_TYPE_RAPPORT;
  441.                 $url 'project_rapport';
  442.                 $typeCharte 'charteRapport';
  443.                 break;
  444.             default:
  445.                 throw $this->createAccessDeniedException();
  446.         }
  447.         // vérification de la signature de la charte
  448.         $signature $signatureCharteRepository->findOneBy(['appelAProjet' => $project->getAppelAProjet(), 'user' => $this->getUser(), 'type' => $type]);
  449.         if ($signature) {
  450.             $this->addFlash('success''Vous avez déjà signé cette charte');
  451.             return $this->redirectToRoute($url, ['id' => $project->getId()]);
  452.         }
  453.         $form $this->createSignatureCharteForm($request->getRequestUri());
  454.         $form->handleRequest($request);
  455.         if ($form->isSubmitted() && $form->isValid()) {
  456.             // enregistrement de la signature
  457.             $signature = (new SignatureCharte())
  458.                 ->setAppelAProjet($project->getAppelAProjet())
  459.                 ->setUser($this->getUser())
  460.                 ->setType($type)
  461.             ;
  462.             $em $doctrine->getManager();
  463.             $em->persist($signature);
  464.             $em->flush();
  465.             $this->addFlash('success''Charte signée avec succès');
  466.             return $this->redirectToRoute($url, ['id' => $project->getId()]);
  467.         }
  468.         return $this->render('project/signature_charte.html.twig', [
  469.             'form' => $form->createView(),
  470.             'appelAProjet' => $project->getAppelAProjet(),
  471.             'type' => $typeCharte,
  472.         ]);
  473.     }
  474.     /**
  475.      * @Route("/{id}/preevaluation-coordo", name="project_preeval_coordo", methods={"GET", "POST"})
  476.      * @Route("/{id}/preevaluation-coordo/auto", name="project_preeval_coordo_auto", methods={"POST"})
  477.      *
  478.      * @param Request $request
  479.      * @param Project $project
  480.      * @param QuestionnaireResponseRepository $questionnaireResponseRepository
  481.      * @param QuestionnaireHandlerService $questionnaireHandlerService
  482.      * @param ManagerRegistry $doctrine
  483.      * @return JsonResponse|RedirectResponse|Response
  484.      */
  485.     public function preevaluationCoordo(Request $requestProject $projectQuestionnaireResponseRepository $questionnaireResponseRepositoryQuestionnaireHandlerService $questionnaireHandlerServiceManagerRegistry $doctrine): RedirectResponse|JsonResponse|Response
  486.     {
  487.         $this->denyAccessUnlessGranted('COORDO'$project);
  488.         // récupération du userProject
  489.         $qr $questionnaireResponseRepository->findOneBy(['questionnaireType' => QuestionnaireResponse::QR_TYPE_EVAL_COORDO'project' => $project'author' => $this->getUser()]);
  490.         if ($qr) {
  491.             if ($qr->getStatus() == QuestionnaireResponse::S_STATUS_DRAFT) {
  492.                 return $this->redirectToRoute('questionnaire_display_submission', ['questionnaireResponse' => $qr->getId()]);
  493.             } else {
  494.                 $this->addFlash('warning''Vous avez déjà soumis ce formulaire, vous ne pouvez plus le modifier');
  495.                 return $this->redirectToRoute('questionnaire_response_show', ['questionnaireResponse' => $qr->getId()]);
  496.             }
  497.         }
  498.         $form $questionnaireHandlerService->createForm($project->getAppelAProjet()->getQuestionnaireEvalCoordo());
  499.         $form->handleRequest($request);
  500.         if ($form->isSubmitted()) {
  501.             $return $questionnaireHandlerService->handleSubmission();
  502.             if ($return instanceof Response) {
  503.                 // cas d'une erreur
  504.                 return $return;
  505.             }
  506.             // cas où ça c'est bien passé
  507.             $questionnaireResponse $questionnaireHandlerService->getQuestionnaireResponse();
  508.             $em $doctrine->getManager();
  509.             $questionnaireResponse->setQuestionnaireType(QuestionnaireResponse::QR_TYPE_EVAL_COORDO);
  510.             $questionnaireResponse->setProject($project);
  511.             $em->flush();
  512.             if ($request->attributes->get('_route') == 'project_preeval_coordo') {
  513.                 $this->addFlash('success'$return);
  514.                 return new JsonResponse(['url' => $this->generateUrl('project_show', ['id' => $project->getId()])]);
  515.             } else {
  516.                 return new JsonResponse(['url' => $this->generateUrl('questionnaire_display_submission', ['questionnaireResponse' => $questionnaireResponse->getId()])]);
  517.             }
  518.         }
  519.         return $questionnaireHandlerService->renderForm($request$project);
  520.     }
  521.     /**
  522.      * @Route("/{id}/clone-li", name="project_clone_li", methods={"GET", "POST"})
  523.      * @param Project $project
  524.      * @param QuestionnaireResponseRepository $questionnaireResponseRepository
  525.      * @param ManagerRegistry $doctrine
  526.      * @return Response
  527.      */
  528.     public function cloneLi(Project $projectQuestionnaireResponseRepository $questionnaireResponseRepositoryManagerRegistry $doctrine): Response
  529.     {
  530.         $this->denyAccessUnlessGranted('CLONE_LI'$project);
  531.         // vérification de l'existance d'une LI clone
  532.         $qrs $questionnaireResponseRepository->getByTypeByProject(QuestionnaireResponse::QR_TYPE_LI_R$project);
  533.         if (count($qrs) == 1) {
  534.             if ($qrs[0]->getStatus() == QuestionnaireResponse::S_STATUS_DRAFT) {
  535.                 return $this->redirectToRoute('questionnaire_display_submission', ['questionnaireResponse' => $qrs[0]->getId()]);
  536.             } else {
  537.                 $this->addFlash('warning''Vous avez déjà soumis la LI clone, vous ne pouvez plus la modifier');
  538.                 return $this->redirectToRoute('questionnaire_response_show', ['questionnaireResponse' => $qrs[0]->getId()]);
  539.             }
  540.         }
  541.         $em $doctrine->getManager();
  542.         // récupération de la LI initiale et clonage
  543.         $qrs $questionnaireResponseRepository->getByTypeByProjectWithResponse(QuestionnaireResponse::QR_TYPE_LI_I$project);
  544.         $li2 = clone $qrs[0];
  545.         $li2->setAuthor($this->getUser());
  546.         $li2->setQuestionnaireType(QuestionnaireResponse::QR_TYPE_LI_R);
  547.         $answers2 = [];
  548.         foreach ($qrs[0]->getAnswers() as $key => $answer) {
  549.             $answers2[$key] = clone $answer;
  550.             $li2->addAnswer($answers2[$key]);
  551.         }
  552.         $em->persist($li2);
  553.         $em->flush();
  554.         $this->addFlash('success''Lettre d\'intention clonée avec succès. Vous pouvez maintenant la modifier');
  555.         return $this->redirectToRoute('questionnaire_display_submission', ['questionnaireResponse' => $li2->getId()]);
  556.     }
  557.     /**
  558.      * @Route("/{id}/dossier-complet", name="project_dossier_complet", methods={"GET", "POST"})
  559.      * @Route("/{id}/dossier-complet/auto", name="project_dossier_complet_auto", methods={"GET", "POST"})
  560.      *
  561.      * @param Request $request
  562.      * @param Project $project
  563.      * @param QuestionnaireResponseRepository $questionnaireResponseRepository
  564.      * @param ManagerRegistry $doctrine
  565.      * @param QuestionnaireHandlerService $questionnaireHandlerService
  566.      * @return Response
  567.      */
  568.     public function dossierComplet(Request $requestProject $projectQuestionnaireResponseRepository $questionnaireResponseRepositoryManagerRegistry $doctrineQuestionnaireHandlerService $questionnaireHandlerService): Response
  569.     {
  570.         $this->denyAccessUnlessGranted('ADD_DC'$project);
  571.         // récupération du questionnaire response
  572.         $qr $questionnaireResponseRepository->getByTypeByProject(QuestionnaireResponse::QR_TYPE_DC$project);
  573.         if (count($qr) > 0) {
  574.             if ($qr[0]->getStatus() == QuestionnaireResponse::S_STATUS_DRAFT) {
  575.                 return $this->redirectToRoute('questionnaire_display_submission', ['questionnaireResponse' => $qr[0]->getId()]);
  576.             } else {
  577.                 $this->addFlash('warning''Vous avez déjà soumis ce formulaire, vous ne pouvez plus le modifier');
  578.                 return $this->redirectToRoute('questionnaire_response_show', ['questionnaireResponse' => $qr[0]->getId()]);
  579.             }
  580.         }
  581.         $form $questionnaireHandlerService->createForm($project->getAppelAProjet()->getQuestionnaireDc());
  582.         $form->handleRequest($request);
  583.         if ($form->isSubmitted()) {
  584.             $return $questionnaireHandlerService->handleSubmission();
  585.             if ($return instanceof Response) {
  586.                 // cas d'une erreur
  587.                 return $return;
  588.             }
  589.             // cas où ça c'est bien passé
  590.             $questionnaireResponse $questionnaireHandlerService->getQuestionnaireResponse();
  591.             $em $doctrine->getManager();
  592.             $questionnaireResponse->setQuestionnaireType(QuestionnaireResponse::QR_TYPE_DC);
  593.             $questionnaireResponse->setProject($project);
  594.             $em->flush();
  595.             if ($request->attributes->get('_route') == 'project_dossier_complet') {
  596.                 $this->addFlash('success'$return);
  597.                 return new JsonResponse(['url' => $this->generateUrl('project_show', ['id' => $project->getId()])]);
  598.             } else {
  599.                 return new JsonResponse(['url' => $this->generateUrl('questionnaire_display_submission', ['questionnaireResponse' => $questionnaireResponse->getId()])]);
  600.             }
  601.         }
  602.         return $questionnaireHandlerService->renderForm($request$project);
  603.     }
  604.     /**
  605.      * @Route("/{id}/submit-dossier-complet", name="project_submit_dossier_complet", methods={"GET", "POST"})
  606.      *
  607.      * @param Request $request
  608.      * @param Project $project
  609.      * @param QuestionnaireResponseRepository $questionnaireResponseRepository
  610.      * @param ProjectNumberService $projectNumberService
  611.      * @param ManagerRegistry $doctrine
  612.      * @return Response
  613.      */
  614.     public function submitDossierComplet(Request $requestProject $projectQuestionnaireResponseRepository $questionnaireResponseRepositoryProjectNumberService $projectNumberServiceManagerRegistry $doctrine): Response
  615.     {
  616.         $this->denyAccessUnlessGranted('DC_SUBMIT'$project);
  617.         $qrLi2 $questionnaireResponseRepository->getByTypeByProject(QuestionnaireResponse::QR_TYPE_LI_R$project);
  618.         if (count($qrLi2) > && $qrLi2[0]->getStatus() == QuestionnaireResponse::S_STATUS_DRAFT) {
  619.             $this->addFlash('warning''Vous devez soumettre la lettre d\'intention pour pouvoir soumettre le projet');
  620.             return $this->redirectToRoute('questionnaire_display_submission', ['questionnaireResponse' => $qrLi2[0]->getId()]);
  621.         }
  622.         // todo : est-ce que le clone de la li est obligatoire ? si non, si il n'y en a pas, est-ce que je met un rappel ?
  623.         $qrDc $questionnaireResponseRepository->getByTypeByProject(QuestionnaireResponse::QR_TYPE_DC$project);
  624.         if (count($qrDc) == 0) {
  625.             $this->addFlash('warning''Vous devez déposer le dossier pour pouvoir soumettre le projet');
  626.             return $this->redirectToRoute('project_dossier_complet', ['id' => $project->getId()]);
  627.         }
  628.         if ($qrDc[0]->getStatus() == QuestionnaireResponse::S_STATUS_DRAFT) {
  629.             $this->addFlash('warning''Vous devez soumettre le dossier complet pour pouvoir soumettre le projet');
  630.             return $this->redirectToRoute('questionnaire_display_submission', ['questionnaireResponse' => $qrDc[0]->getId()]);
  631.         }
  632.         // formulaire de validation (pour faire un deuxième clic)
  633.         if ($request->getMethod() === 'POST') {
  634.             if ($this->isCsrfTokenValid('submit'.$project->getId(), $request->request->get('_token'))) {
  635.                 $entityManager $doctrine->getManager();
  636.                 $project->setStatus(Project::PROJECT_STATUS_DC_DEPOSE);
  637.                 $entityManager->flush();
  638.                 $this->addFlash('success''Dossier complet soumis avec succès');
  639.                 return $this->redirectToRoute('project_show', ['id' => $project->getId()]);
  640.             }
  641.             $this->addFlash('error''Une erreur est survenue, veuillez réessayer');
  642.         }
  643.         return $this->render('project/submit.html.twig', [
  644.             'project' => $project,
  645.             'routeName' => 'project_submit_dossier_complet',
  646.         ]);
  647.     }
  648.     /**
  649.      * @param $url
  650.      * @return FormInterface
  651.      */
  652.     private function createSignatureCharteForm($url): FormInterface
  653.     {
  654.         return $this->createFormBuilder()
  655.             ->setAction($url)
  656.             ->setMethod('POST')
  657.             ->getForm()
  658.             ;
  659.     }
  660. }