src/Controller/Request/RequestController.php line 287

Open in your IDE?
  1. <?php
  2. namespace App\Controller\Request;
  3. use App\Converter\RequestConverter;
  4. use App\Exception\CreateRequestException;
  5. use App\Exception\RequestRelationException;
  6. use App\Manager\OrganizationManagerInterface;
  7. use App\Message\ExportMessage;
  8. use App\Service\RequestBridgeService;
  9. use App\Models\Signal\Status as SignalStatus;
  10. use App\Models\Request\Request as PceRequest;
  11. use Psr\Log\LoggerInterface;
  12. use Nelmio\ApiDocBundle\Annotation\Model as Model;
  13. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  14. use Symfony\Component\HttpFoundation\JsonResponse;
  15. use Symfony\Component\HttpFoundation\Request;
  16. use Symfony\Component\HttpFoundation\Response;
  17. use Symfony\Component\HttpFoundation\StreamedResponse;
  18. use Symfony\Component\Messenger\MessageBusInterface;
  19. use Symfony\Component\Routing\Annotation\Route;
  20. use Swagger\Annotations as SWG;
  21. use App\Manager\SignalManager;
  22. use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
  23. use App\Constants\AppConstants;
  24. use Symfony\Contracts\Cache\TagAwareCacheInterface;
  25. use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
  26. class RequestController extends AbstractController
  27. {
  28.     protected RequestBridgeService $requestBridgeService;
  29.     protected LoggerInterface $logger;
  30.     protected MessageBusInterface $bus;
  31.     protected SignalManager $signalManager;
  32.     protected NormalizerInterface $normalizer;
  33.     protected OrganizationManagerInterface $organizationManager;
  34.     protected TagAwareCacheInterface $portailCachePool;
  35.     public function __construct(
  36.         RequestBridgeService $requestBridgeService,
  37.         LoggerInterface $logger,
  38.         MessageBusInterface $bus,
  39.         SignalManager $signalManager,
  40.         NormalizerInterface $normalizer,
  41.         OrganizationManagerInterface $organizationManager,
  42.         TagAwareCacheInterface $portailCachePool
  43.     ) {
  44.         $this->requestBridgeService $requestBridgeService;
  45.         $this->logger $logger;
  46.         $this->bus $bus;
  47.         $this->signalManager $signalManager;
  48.         $this->normalizer $normalizer;
  49.         $this->organizationManager $organizationManager;
  50.         $this->portailCachePool $portailCachePool;
  51.     }
  52.     /**
  53.      * @Route("/api/request", name="get_filtered_requests_visible_user", methods={"GET"})
  54.      *
  55.      * @SWG\Get(summary="Gets all filtered requests visible to user")
  56.      *
  57.      * @SWG\Parameter(
  58.      *     in="query",
  59.      *     name="currentPage",
  60.      *     description="Index of requested Fpage",
  61.      *     type="string"
  62.      * )
  63.      * @SWG\Parameter(
  64.      *     in="query",
  65.      *     name="itemsPerPage",
  66.      *     description="Items per page",
  67.      *     type="string"
  68.      * )
  69.      * @SWG\Parameter(
  70.      *     in="query",
  71.      *     name="query",
  72.      *     description="Search by keyword",
  73.      *     type="string"
  74.      * )
  75.      * @SWG\Parameter(
  76.      *     in="query",
  77.      *     name="incrementalId",
  78.      *     description="Incremental ID",
  79.      *     type="integer"
  80.      * )
  81.      * @SWG\Parameter(
  82.      *     in="query",
  83.      *     name="dateCreationMin",
  84.      *     description="Creation date min (YYYY-MM-DD)",
  85.      *     type="string",
  86.      *     format="date"
  87.      * )
  88.      * @SWG\Parameter(
  89.      *     in="query",
  90.      *     name="dateCreationMax",
  91.      *     description="Creation date max (YYYY-MM-DD)",
  92.      *     type="string",
  93.      *     format="date"
  94.      * )
  95.      * @SWG\Parameter(
  96.      *     name="sortField",
  97.      *     description="Field to use for sorting",
  98.      *     in="query",
  99.      *     type="string"
  100.      * )
  101.      * @SWG\Parameter(
  102.      *     name="sortDirection",
  103.      *     description="Sort direction (asc, desc)",
  104.      *     in="query",
  105.      *     type="array",
  106.      *     @SWG\Items(
  107.      *         type="string",
  108.      *         enum={"asc", "desc"},
  109.      *         default="desc"
  110.      *     )
  111.      * )
  112.      * @SWG\Parameter(
  113.      *     name="format",
  114.      *     description="Response format (json: fetch; csv: download)",
  115.      *     in="query",
  116.      *     type="array",
  117.      *     @SWG\Items(
  118.      *         type="string",
  119.      *         enum={"json", "csv"},
  120.      *         default="json"
  121.      *     )
  122.      * )
  123.      * @SWG\Response(
  124.      *     response=200,
  125.      *     description="Everything is OK."
  126.      * )
  127.      * @SWG\Response(
  128.      *     response=500,
  129.      *     description="Everything is on fire."
  130.      * )
  131.      *
  132.      * @SWG\Tag(name="Request")
  133.      *
  134.      * @param Request $request
  135.      *
  136.      * @return JsonResponse
  137.      * @throws TransportExceptionInterface
  138.      */
  139.     public function getAll(Request $request): Response
  140.     {
  141.         if ($request->query->get('format') === 'csv') {
  142.             // Traitement asynchrone avec envoie du rapport par email
  143.             $exportMessage = new ExportMessage(
  144.                 $this->getUser(),
  145.                 $request->query->all(),
  146.                 $request->headers->all(),
  147.                 $request->request->all(),
  148.                 $request->attributes->all(),
  149.                 $request->cookies->all(),
  150.                 $request->files->all(),
  151.                 $request->server->all(),
  152.                 $request->getContent()
  153.             );
  154.             $this->bus->dispatch($exportMessage);
  155.             return new JsonResponse(['status' => 'OK'], Response::HTTP_OK);
  156.         }
  157.         $stream $this->requestBridgeService->getRequests($request$this->getUser());
  158.         $streamedResponse = new StreamedResponse();
  159.         $streamedResponse->headers->set('X-Accel-Buffering''no');
  160.         // The key method of a StreamResponse allow to get the Response object
  161.         // We need the Response to get the headers and status code to add them on StreamResponse
  162.         $response $stream->key();
  163.         $streamedResponse->setStatusCode($response->getStatusCode());
  164.         foreach ($response->getHeaders(false) as $name => $values) {
  165.             $streamedResponse->headers->set($name$values);
  166.         }
  167.         $streamedResponse->setCallback(function() use ($stream) {
  168.             foreach ($stream as $chunk) {
  169.                 echo $chunk->getContent();
  170.                 flush();
  171.             }
  172.         });
  173.         return $streamedResponse;
  174.     }
  175.     /**
  176.      * @Route("/api/request/{requestId}", methods={"GET"}, name="get_request")
  177.      * @SWG\Get(summary="Gets details for one request")
  178.      * @SWG\Parameter(
  179.      *     name="id",
  180.      *     description="Request id",
  181.      *     in="query",
  182.      *     type="string",
  183.      *     required=true
  184.      * )
  185.      * @SWG\Response(
  186.      *     response=200,
  187.      *     description="Everything is OK."
  188.      * )
  189.      * @SWG\Response(
  190.      *     response=403,
  191.      *     description="Access denied. You do not have permission to view this request."
  192.      * )
  193.      * @SWG\Response(
  194.      *     response=404,
  195.      *     description="Request not found."
  196.      * )
  197.      * @SWG\Tag(name="Request")
  198.      *
  199.      * @param Request $request
  200.      * @param string $requestId
  201.      * @return JsonResponse
  202.      */
  203.     public function getOne(Request $requeststring $requestId): JsonResponse
  204.     {
  205.         $request $this->requestBridgeService->getRequest($requestId$this->getUser());
  206.         return new JsonResponse(json_decode($requesttrue), Response::HTTP_OK);
  207.     }
  208.     /**
  209.      * @Route("/api/request/{id}/status", methods={"POST"}, name="post_request_status")
  210.      * @SWG\Post(
  211.      *      path="/api/request/{id}/status",
  212.      *      summary="Update request status"
  213.      * )
  214.      * @SWG\Parameter(
  215.      *     name="id",
  216.      *     in="path",
  217.      *     type="string",
  218.      *     description="Request id to update",
  219.      *     @SWG\Schema(
  220.      *         type="string",
  221.      *         required={"id"}
  222.      *     )
  223.      * )
  224.      * @SWG\Parameter(
  225.      *     name="body",
  226.      *     in="body",
  227.      *     description="update status",
  228.      *         @SWG\Schema(
  229.      *             @SWG\Property(property="status", type="string"),
  230.      *             @SWG\Property(property="comment", type="string"),
  231.      *         )
  232.      * )
  233.      * @SWG\Response(
  234.      *     response=201,
  235.      *     description="status updated."
  236.      * ),
  237.      * @SWG\Response(
  238.      *     response=400,
  239.      *     description="Form is invalid."
  240.      * )
  241.      *
  242.      * @SWG\Tag(name="Request")
  243.      */
  244.     public function updateRequestStatus(Request $request): JsonResponse
  245.     {
  246.         $requests $this->requestBridgeService->updateRequestStatusAndCloseSignal(
  247.             $request->attributes->get('id'),
  248.             json_decode($request->getContent(), true)
  249.         );
  250.         $jsonResponse = new JsonResponse($requests['content']);
  251.         $jsonResponse->headers->add($requests['headers']);
  252.         return $jsonResponse;
  253.     }
  254.     /**
  255.      * Get stats for request.
  256.      *
  257.      * @Route("/api/widget/request/stats", name="get_request_stats",  methods={"GET"})
  258.      *
  259.      * @SWG\Get (
  260.      *      path="/api/widget/request/stats",
  261.      *      tags={"Request"},
  262.      *      summary="Get statistics for request",
  263.      *     @SWG\Response(
  264.      *         response="200",
  265.      *         description="stats"
  266.      *     )
  267.      * )
  268.      */
  269.     public function getStats(Request $request): JsonResponse
  270.     {
  271.         $requests $this->requestBridgeService->getStats($request$this->getUser());
  272.         $jsonResponse = new JsonResponse($requests['content'], Response::HTTP_OK);
  273.         $jsonResponse->headers->add($requests['headers']);
  274.         return $jsonResponse;
  275.     }
  276.     /**
  277.      * Get all status available for user.
  278.      *
  279.      * @Route("/api/contract/{contractId}/request/getAllStatus", name="get_all_status",  methods={"GET"})
  280.      *
  281.      * @SWG\Get (
  282.      *      path="/api/contract/{contractId}/request/getAllStatus",
  283.      *      tags={"Request"},
  284.      *      summary="Get status for connected user",
  285.      *     @SWG\Response(
  286.      *         response="200",
  287.      *         description="status"
  288.      *     )
  289.      * )
  290.      */
  291.     public function getAllStatusByContract($contractId): JsonResponse
  292.     {
  293.         $cacheKey hash'sha256''request_contract_status'.$contractId);
  294.         $cachedItem $this->portailCachePool->getItem($cacheKey);
  295.         if (!$cachedItem->isHit()) {
  296.             //get list of organizations for a given contract
  297.             list($organizations$pagination) = $this->organizationManager->getByContract(
  298.                 $contractId,
  299.                 [
  300.                     AppConstants::DEFAULT_ALL_ITEMS_PER_PAGE,
  301.                     AppConstants::DEFAULT_CURRENT_PAGE,
  302.                 ]
  303.             );  
  304.             //get all request types for each organization
  305.             $requestTypes = [];
  306.             foreach ($organizations as $organization) {
  307.                 $organizationRt $this->organizationManager->getOrganizationsRequestType($organization->getId());
  308.                 $jsonContent $organizationRt->getContent();
  309.                 $decodedContent json_decode($jsonContenttrue);
  310.                 foreach ($decodedContent as $requestType) {
  311.                     $requestTypes[$requestType['id']] = $requestType;
  312.                 }
  313.                 $cachedItem->tag([$organization->getId()]);
  314.             }
  315.             //get all status for each request type
  316.             $allStatus = [];
  317.             foreach ($requestTypes as $requestType) {
  318.                 $statuses $this->requestBridgeService->getRequestTypeStatus($requestType['id']);
  319.                 $decodedStatuses json_decode($statuses['content'], true);
  320.                 foreach ($decodedStatuses as $status) {
  321.                     $allStatus[$status['id']] = $status;
  322.                 }
  323.             }
  324.             
  325.             $cachedItem->set($allStatus);
  326.             $cachedItem->tag([$contractId]);
  327.             $this->portailCachePool->save($cachedItem);
  328.         }
  329.         $allStatus $cachedItem->get();
  330.         return new JsonResponse($this->normalizer->normalize($allStatus'json'), Response::HTTP_OK);
  331.     }
  332. /**
  333.  * Return request values for specific field.
  334.  *
  335.  * @Route("/api/request/fields/{field}", name="get_possible_values_for_field", methods={"GET"})
  336.  *
  337.  * @SWG\Get(summary="Return request values for specific field.")
  338.  * 
  339.  * @SWG\Parameter(
  340.  *         name="field",
  341.  *         in="path",
  342.  *         description="field name",
  343.  *         required=true,
  344.  *         type="string"
  345.  * )
  346.  *
  347.  * @SWG\Response(
  348.  *         response=200,
  349.  *         description="successful operation"
  350.  * )
  351.  * 
  352.  * @SWG\Tag(name="Request")
  353.  * 
  354.  *
  355.  * @param string $field
  356.  * @return Response
  357.  */
  358.     public function getPossibleValuesAction(string $field): Response
  359.     {
  360.         $values $this->requestBridgeService->findPossibleValuesByField($field$this->getUser());
  361.         $response = new Response($values['content'], Response::HTTP_OK);
  362.         $response->headers->add($values['headers']);
  363.         return $response;
  364.     }
  365.     /**
  366.      * @Route("/api/mapping/{signalId}/request", methods={"POST"})
  367.      *
  368.      * @SWG\Parameter(
  369.      *     name="body",
  370.      *     in="body",
  371.      *     @Model(type=PceRequest::class)
  372.      * )
  373.      * @SWG\Response(
  374.      *     response=403,
  375.      *     description="Access Denied.."
  376.      * )
  377.      * @SWG\Response(
  378.      *     response=200,
  379.      *     description="Everything is OK."
  380.      * )
  381.      * @SWG\Response(
  382.      *     response=500,
  383.      *     description="Everything is on fire."
  384.      * )
  385.      *
  386.      * @SWG\Tag(name="Request")
  387.      */
  388.     public function mapRequest(Request $requeststring $signalIdRequestConverter $requestConverter): Response
  389.     {
  390.         $data $request->getContent();
  391.         $pceRequest json_decode($datatrue);
  392.         if (! $pceRequest) {
  393.             $errorMessages sprintf("Impossible to decode the request body sent with value '%s'"$data);
  394.             $this->logger->error(
  395.                 $errorMessages
  396.             );
  397.             return $this->json(
  398.                 $errorMessages,
  399.                 Response::HTTP_BAD_REQUEST
  400.             );
  401.         }
  402.         $signal $this->signalManager->getSignalById($signalId);
  403.         // ADD new request with signal Parameters
  404.         $pceRequest $requestConverter->convertSignalToPceRequest($pceRequest$signal);
  405.         try {
  406.             $newRequestDatas $this->requestBridgeService->postRequest($pceRequest);
  407.         } catch (CreateRequestException $e) {
  408.             return new Response(
  409.                 $e->getMessage(),
  410.                 Response::HTTP_BAD_REQUEST
  411.             );
  412.         }
  413.         $newRequestId $newRequestDatas["content"]["id"];
  414.         try {
  415.             $this->requestBridgeService->postRequestRelation($signalId$newRequestId$pceRequest);
  416.         } catch (RequestRelationException $e) {
  417.             return new Response(
  418.                 $e->getMessage(),
  419.                 Response::HTTP_INTERNAL_SERVER_ERROR
  420.             );
  421.         }
  422.         $this->requestBridgeService->duplicateAttachmentsFromSignalToRequest($signal$newRequestId);
  423.         // Remove attachments from signal
  424.         $signal['attachments'] = [];
  425.         $signal['hasAttachments'] = false;
  426.         $signal['currentStatus']['comment'] = null;
  427.         $this->signalManager->updateSignal($signal);
  428.         $this->signalManager->updateSignalStatus($signalIdSignalStatus::APPROVED);
  429.         // return new request Id
  430.         return $this->json(
  431.             ['id' => $newRequestId],
  432.             Response::HTTP_CREATED,
  433.             [
  434.                 "location" => "/api/request/" $newRequestId,
  435.             ]
  436.         );
  437.     }
  438. }