src/Controller/OrderController.php line 127

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Dto\OrderFreeOutput;
  4. use App\Dto\OrderHistoryParams;
  5. use App\Dto\VinChekInput;
  6. use App\Entity\Order;
  7. use App\Entity\Vin;
  8. use App\Message\CheckPaymentMessage;
  9. use App\Repository\OrderRepository;
  10. use App\Service\Order\OrderService;
  11. use App\Service\Report\ReportService;
  12. use App\Service\TokenService;
  13. use App\Service\Vin\VinService;
  14. use Doctrine\ORM\EntityManagerInterface;
  15. use Nelmio\ApiDocBundle\Annotation\Model;
  16. use Nelmio\ApiDocBundle\Annotation AS Operation;
  17. use OpenApi\Annotations as OA;
  18. use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
  19. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  20. use Symfony\Component\HttpFoundation\Request;
  21. use Symfony\Component\HttpFoundation\Response;
  22. use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
  23. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  24. use Symfony\Component\Messenger\MessageBusInterface;
  25. use Symfony\Component\Routing\Annotation\Route;
  26. use Symfony\Component\Serializer\SerializerInterface;
  27. use Symfony\Component\Uid\Uuid;
  28. class OrderController extends AbstractController
  29. {
  30.     public function __construct(
  31.         private OrderService $orderService,
  32.         private SerializerInterface $serializer,
  33.         private EntityManagerInterface $em,
  34.         private VinService $vinService,
  35.         private ReportService $reportService,
  36.         private TokenService $tokenService,
  37.         private MessageBusInterface $bus,
  38.     ) {
  39.     }
  40.     /**
  41.      * @OA\Response(
  42.      *     response="201",
  43.      *     description="Returns created order",
  44.      *     @Model(type=Order::class, groups={"index"})
  45.      * ),
  46.      * @OA\Response(
  47.      *     response="400",
  48.      *     description="Wrong input data"
  49.      * ),
  50.      * @OA\Parameter(
  51.      *     name="User-Id",
  52.      *     in="header",
  53.      *     required=true,
  54.      *     @OA\Schema(type="string", format="uuid")
  55.      * ),
  56.      * @OA\RequestBody(
  57.      *     required=true,
  58.      *     @OA\JsonContent(
  59.      *        type="object",
  60.      *        @OA\Property(property="vin", type="string", example="4GDDU03A8VD268007"),
  61.      *        @OA\Property(property="email", type="string", example="test@test.ru"),
  62.      *        @OA\Property(property="code", type="string", example="1a2b3c"),
  63.      *     ),
  64.      * )
  65.      */
  66.     #[Route('/api/order'name'app_make_order'methods: ['POST'], format'json')]
  67.     public function handleMakeOrder(Request $request): Response
  68.     {
  69.         try {
  70.             $payload \json_decode((string) $request->getContent(), true512JSON_THROW_ON_ERROR);
  71.         } catch (\JsonException $e) {
  72.             throw new BadRequestHttpException(\sprintf('Bad request: %s'$e->getMessage()));
  73.         }
  74.         $vin $payload['vin'] ?? null;
  75.         $email $payload['email'] ?? null;
  76.         $code $payload['code'] ?? null;
  77.         if ($vin === null || $email === null) {
  78.             throw new BadRequestHttpException('Fields: \'vin\' and \'email\' are required');
  79.         }
  80.         $vin \strtoupper($vin);
  81.         $vinInstance $this->em->getRepository(Vin::class)->findOneBy(['vin' => $vin]);
  82.         if (!$vinInstance instanceof Vin) {
  83.             throw new BadRequestHttpException(\sprintf('Vin (%s) doesn\'t exist, you need to create it firstly'$vin));
  84.         }
  85.         try {
  86.             $order $this->orderService->makeOrder($vinInstance$emailOrder::SOURCE_WEB$codefalse);
  87.             $this->orderService->addPayInfo($order);
  88.             $this->em->flush();
  89.             $this->bus->dispatch(new CheckPaymentMessage($order));
  90.         } catch (\InvalidArgumentException $e) {
  91.             throw new BadRequestHttpException($e->getMessage());
  92.         }
  93.         return new Response($this->serializer->serialize(['order' => $order], 'json', ['groups' => 'index']));
  94.     }
  95.     /**
  96.      * @OA\Response(
  97.      *     response="200",
  98.      *     description="Returns requested order",
  99.      *     @Model(type=Order::class, groups={"index"})
  100.      * ),
  101.      * @OA\Response(
  102.      *     response="400",
  103.      *     description="Returns if order is not found",
  104.      * ),
  105.      * @OA\Parameter(
  106.      *     name="orderId",
  107.      *     in="path",
  108.      *     required=true,
  109.      *     @OA\Schema(type="string", format="uuid")
  110.      * ),
  111.      * @OA\Parameter(
  112.      *     name="User-Id",
  113.      *     in="header",
  114.      *     required=true,
  115.      *     @OA\Schema(type="string", format="uuid")
  116.      * ),
  117.      */
  118.     #[Route('/api/order/{orderId}'name'app_get_order'methods: ['GET'], format'json')]
  119.     public function handleGetOrder(string $orderId): Response
  120.     {
  121.         if (!Uuid::isValid($orderId)) {
  122.             throw new BadRequestHttpException(\json_encode(\sprintf('Invalid orderId (%s) was given'$orderId)));
  123.         }
  124.         $order $this->em->find(Order::class, $orderId);
  125.         if (!$order) {
  126.             throw new NotFoundHttpException(\sprintf('Order %s not found'$orderId));
  127.         }
  128.         $this->orderService->addPayInfo($order);
  129.         $reportPath $this->reportService->makeReport($order);
  130.         return new Response($this->serializer->serialize(['order' => $order], 'json', ['groups' => 'index']));
  131.     }
  132.     /**
  133.      * @Operation\Security(
  134.      *     name="admin"
  135.      * ),
  136.      * @OA\Response(
  137.      *     response="200",
  138.      *     description="Returns requested order history",
  139.      *     @Model(type=Order::class, groups={"order-history"})
  140.      * ),
  141.      * @OA\Parameter(
  142.      *     name="orderId",
  143.      *     in="query",
  144.      *     required=false,
  145.      *     @OA\Schema(type="string")
  146.      * ),
  147.      * @OA\Parameter(
  148.      *     name="vin",
  149.      *     in="query",
  150.      *     required=false,
  151.      *     @OA\Schema(type="string")
  152.      * ),
  153.      * @OA\Parameter(
  154.      *     name="email",
  155.      *     in="query",
  156.      *     required=false,
  157.      *     @OA\Schema(type="string")
  158.      * ),
  159.      * @OA\Parameter(
  160.      *     name="fromDate",
  161.      *     in="query",
  162.      *     required=false,
  163.      *     @OA\Schema(type="date-time")
  164.      * ),
  165.      * @OA\Parameter(
  166.      *     name="toDate",
  167.      *     in="query",
  168.      *     required=false,
  169.      *     @OA\Schema(type="date-time")
  170.      * ),
  171.      */
  172.     #[Route('/api/order-history'name'app_get_order_history'methods: ['GET'], format'json')]
  173.     #[ParamConverter('orderHistory')]
  174.     public function getOrderHistory(OrderHistoryParams $orderHistoryParamsOrderRepository $orderRepository): Response
  175.     {
  176.         $orders $orderRepository->getOrderHistory($orderHistoryParams);
  177.         return new Response($this->serializer->serialize(['orders' => $orders], 'json', ['groups' => ['orderHistory']]), Response::HTTP_OK);
  178.     }
  179.     /**
  180.      * @Operation\Security(
  181.      *     name="api-token"
  182.      * ),
  183.      * @OA\Response(
  184.      *     response="201",
  185.      *     description="Returns link to report",
  186.      *     @Model(type=OrderFreeOutput::class, groups={"index"})
  187.      * ),
  188.      * @OA\Response(
  189.      *     response="400",
  190.      *     description="Wrong input data"
  191.      * ),
  192.      * @OA\RequestBody(
  193.      *     required=true,
  194.      *     @OA\JsonContent(
  195.      *        type="object",
  196.      *        @OA\Property(property="vin", type="string", example="4GDDU03A8VD268007"),
  197.      *        @OA\Property(property="email", type="string", example="test@test.ru"),
  198.      *     ),
  199.      * )
  200.      */
  201.     #[Route('/api/vin-check'name'app_make_vin_check'methods: ['POST'])]
  202.     public function handleMakeOrderFree(Request $request): Response
  203.     {
  204.         $this->tokenService->checkToken($request);
  205.         try {
  206.             $vinChekInput $this->serializer->deserialize($request->getContent(), VinChekInput::class, 'json');
  207.         } catch (\JsonException $e) {
  208.             throw new BadRequestHttpException(\sprintf('Bad request: %s'$e->getMessage()));
  209.         }
  210.         if ($vinChekInput->getVin() === null) {
  211.             throw new BadRequestHttpException('Field: \'vin\' is required');
  212.         }
  213.         $vinInstance $this->vinService->checkVin($vinChekInput->getVin());
  214.         $email $vinChekInput->getEmail();
  215.         try {
  216.             $order $this->orderService->makeOrder($vinInstance$emailOrder::SOURCE_INT);
  217.             $this->bus->dispatch(new CheckPaymentMessage($order));
  218.         } catch (\InvalidArgumentException $e) {
  219.             throw new BadRequestHttpException($e->getMessage());
  220.         }
  221.         $orderFreeOutput = new OrderFreeOutput('OK'$order->getReportLink());
  222.         return new Response($this->serializer->serialize(['order' => $orderFreeOutput], 'json', ['groups' => 'index']));
  223.     }
  224. }