src/Controller/V1/OrderController.php line 39

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Controller\V1;
  4. use App\Entity\Vista\ConcessionItem;
  5. use App\Entity\Local\Response\SetTicketsOnServerResponse;
  6. use App\Entity\Local\SetConcessionsRequest;
  7. use App\Entity\Vista\DTO\TicketDTO;
  8. use App\Entity\Vista\LoyaltyMember;
  9. use App\Entity\Vista\Order;
  10. use App\Entity\Vista\OrderConcessionItem;
  11. use App\Form\OrderTicketType;
  12. use App\Helper\MPay24Helper;
  13. use App\Manager\SeatPlanManager;
  14. use App\Helper\UserHelper;
  15. use App\Repository\CinemaRepository;
  16. use App\Repository\OrderRepositoryInterface;
  17. use App\Repository\SessionRepositoryInterface;
  18. use FOS\RestBundle\Controller\Annotations\View;
  19. use InvalidArgumentException;
  20. use Nelmio\ApiDocBundle\Annotation\Model;
  21. use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
  22. use Swagger\Annotations as SWG;
  23. use Symfony\Component\Form\FormFactoryInterface;
  24. use Symfony\Component\HttpFoundation\Request;
  25. use Symfony\Component\Routing\Annotation\Route;
  26. use App\Security\Security as CoreSecurity;
  27. use App\Helper\PaymentHelper;
  28. use Symfony\Component\Yaml\Yaml;
  29. use Psr\Log\LoggerInterface;
  30. use Doctrine\Common\Persistence\ManagerRegistry;
  31. use Doctrine\Common\Persistence\ObjectRepository;
  32. /**
  33.  * @Route("/orders")
  34.  * @SWG\Tag(name="Order_v1")
  35.  */
  36. class OrderController
  37. {
  38.     /** @var ObjectRepository */
  39.     protected $concessionDbRepository;
  40.     /** @var OrderRepositoryInterface */
  41.     protected $orderRepository;
  42.     /** @var UserHelper */
  43.     protected $userHelper;
  44.     /** @var MPay24Helper */
  45.     protected $mPay24Helper;
  46.     /** @var PaymentHelper */
  47.     protected $paymentHelper;
  48.     /** @var SeatPlanManager */
  49.     protected $seatPlanManager;
  50.     /** @var CinemaRepository */
  51.     protected $cinemaRepository;
  52.     /** @var SessionRepositoryInterface */
  53.     private $sessionRepository;
  54.     /** @var FormFactoryInterface */
  55.     private $formFactory;
  56.     /** @var LoggerInterface */
  57.     private $logger;
  58.     /** @var string */
  59.     protected $rootDir;
  60.     public function __construct(
  61.         OrderRepositoryInterface $orderRepository,
  62.         UserHelper $userHelper,
  63.         MPay24Helper $mPay24Helper,
  64.         PaymentHelper $paymentHelper,
  65.         SeatPlanManager $seatPlanManager,
  66.         CinemaRepository $cinemaRepository,
  67.         SessionRepositoryInterface $sessionRepository,
  68.         FormFactoryInterface $formFactory,
  69.         LoggerInterface $logger,
  70.         string $rootDir,
  71.         ManagerRegistry $managerRegistry
  72.     ) {
  73.         $this->orderRepository $orderRepository;
  74.         $this->userHelper $userHelper;
  75.         $this->mPay24Helper $mPay24Helper;
  76.         $this->paymentHelper $paymentHelper;
  77.         $this->seatPlanManager $seatPlanManager;
  78.         $this->cinemaRepository $cinemaRepository;
  79.         $this->sessionRepository $sessionRepository;
  80.         $this->formFactory $formFactory;
  81.         $this->logger $logger;
  82.         $this->rootDir $rootDir;
  83.         $this->concessionDbRepository $managerRegistry->getRepository(ConcessionItem::class);
  84.     }
  85.     /**
  86.      * @Route("", methods={"POST"})
  87.      * @ParamConverter("order", converter="fos_rest.request_body")
  88.      * @View(statusCode=201)
  89.      *
  90.      * @SWG\Response(
  91.      *     response="201",
  92.      *     description="Order successfully created",
  93.      *     @Model(type=\App\Entity\Vista\Order::class))
  94.      * @SWG\Response(
  95.      *     response="400",
  96.      *     description="Invalid request data")
  97.      * @SWG\Parameter(
  98.      *     name="body",
  99.      *     in="body",
  100.      *     @SWG\Schema(type="object",
  101.      *         @SWG\Property(property="cinemaId", type="string")))
  102.      *
  103.      * @param Order $order
  104.      * @param CoreSecurity $security
  105.      * @return Order
  106.      */
  107.     public function createAction(Order $orderCoreSecurity $security)
  108.     {
  109.         /** @var LoyaltyMember $user */
  110.         if ($user $security->getUser()) {
  111.             $country getenv('APP_COUNTRY');
  112.             if (!$user->getValidatedFiscaliazionLaw() && $country === 'rou') {
  113.                 $response $this->userHelper->validateFiscaliazionLaw($user);
  114.                 if ($response['status']) {
  115.                     throw new InvalidArgumentException($response['message']);
  116.                 }
  117.             }
  118.             try {
  119.                 $existingOrder $this->orderRepository->findBySessionId($user->getUserSessionId());
  120.                 $this->orderRepository->cancel($existingOrder);
  121.             } catch (\Exception $ex) {
  122.             }
  123.         }
  124.         if (($cinema $this->cinemaRepository->find($order->getCinemaId())) === null) {
  125.             throw new InvalidArgumentException('Invalid cinema id');
  126.         }
  127.         $order->setCinemaName($cinema->getName());
  128.         $order $this->orderRepository->create($order);
  129.         if ($user instanceof LoyaltyMember) {
  130.             $user->setValidatedFiscaliazionLaw(true);
  131.             $order->setUser($user);
  132.             $this->userHelper->validate($user$order->getUserSessionId());
  133.         }
  134.         return $order;
  135.     }
  136.     /**
  137.      * @Route("/{orderId}/sessions/{sessionId}/tickets", methods={"POST"})
  138.      * @View(statusCode=201)
  139.      *
  140.      * @SWG\Response(
  141.      *     response="201",
  142.      *     description="Seats successfully selected",
  143.      *     @Model(type=App\Entity\Local\Response\SetTicketsOnServerResponse::class))
  144.      * @SWG\Response(
  145.      *     response="400",
  146.      *     description="Invalid request data")
  147.      * @SWG\Parameter(
  148.      *     name="body",
  149.      *     in="body",
  150.      *     @SWG\Schema(type="object",
  151.      *         @SWG\Property(property="isBonusCard", type="boolean"),
  152.      *         @SWG\Property(property="numberOfSeats", type="integer"),
  153.      *         @SWG\Property(property="numberOfChildSeats", type="integer"),
  154.      *         @SWG\Property(property="numberOfReducedSeats", type="integer"),
  155.      *         @SWG\Property(property="numberOfFilmBrunchSeats", type="integer"),
  156.      *         @SWG\Property(property="numberOfFilmBrunchChildSeats", type="integer"),
  157.      *         @SWG\Property(property="numberOfCBCCar", type="integer"),
  158.      *         @SWG\Property(property="numberOfCar", type="integer"),
  159.      *         @SWG\Property(property="numberOfAdditionalCar", type="integer"),
  160.      *         @SWG\Property(property="seats", type="array", @SWG\Items(type="object",
  161.      *             @SWG\Property(property="areaNumber", type="integer"),
  162.      *             @SWG\Property(property="rowIndex", type="integer"),
  163.      *             @SWG\Property(property="columnIndex", type="integer")))))
  164.      *
  165.      * @codeCoverageIgnore
  166.      *
  167.      * @param $orderId
  168.      * @param $sessionId
  169.      * @param Request $request
  170.      * @return Order|\Symfony\Component\Form\FormInterface
  171.      */
  172.     public function ticketsAction($orderId$sessionIdRequest $request)
  173.     {
  174.         $this->logger->info('profiling seat selection :: entering ticketsAction for order ' $orderId);
  175.         $start microtime(true);
  176.         $response $this->ticketsOnServerAction($orderId$sessionId$request);
  177.         $this->logger->info(sprintf("profiling seat selection :: ticketsOnServerAction execution time: %f"microtime(true) - $start));
  178.         $this->logger->info('profiling seat selection :: exiting ticketsAction for order ' $orderId);
  179.         return $response;
  180.     }
  181.     /**
  182.      * @Route("/{orderId}/sessions/{sessionId}/tickets-on-server", methods={"POST"})
  183.      * @View(statusCode=201)
  184.      *
  185.      * @SWG\Parameter(
  186.      *     name="body",
  187.      *     in="body",
  188.      *     @SWG\Schema(type="object",
  189.      *         @SWG\Property(property="isBonusCard", type="boolean"),
  190.      *         @SWG\Property(property="numberOfSeats", type="integer"),
  191.      *         @SWG\Property(property="numberOfChildSeats", type="integer"),
  192.      *         @SWG\Property(property="numberOfReducedSeats", type="integer"),
  193.      *         @SWG\Property(property="numberOfPackageReducedSeats", type="integer"),
  194.      *         @SWG\Property(property="numberOfPackageRegularSeats", type="integer"),
  195.      *         @SWG\Property(property="numberOfPackageClubSeats", type="integer"),
  196.      *         @SWG\Property(property="numberOfPackageChildSeats", type="integer"),
  197.      *         @SWG\Property(property="numberOfPackageWheelchairSeats", type="integer"),
  198.      *         @SWG\Property(property="numberOfFilmBrunchSeats", type="integer"),
  199.      *         @SWG\Property(property="numberOfFilmBrunchChildSeats", type="integer"),
  200.      *         @SWG\Property(property="numberOfCBCCar", type="integer"),
  201.      *         @SWG\Property(property="numberOfCar", type="integer"),
  202.      *         @SWG\Property(property="numberOfAdditionalCar", type="integer"),
  203.      *         @SWG\Property(property="seats", type="array", @SWG\Items(type="object",
  204.      *             @SWG\Property(property="areaNumber", type="integer"),
  205.      *             @SWG\Property(property="rowIndex", type="integer"),
  206.      *             @SWG\Property(property="columnIndex", type="integer")))))
  207.      * @SWG\Response(
  208.      *     response="201",
  209.      *     description="Seats successfully selected",
  210.      *     @Model(type=App\Entity\Local\Response\SetTicketsOnServerResponse::class))
  211.      * @SWG\Response(
  212.      *     response="400",
  213.      *     description="Invalid request data")
  214.      *
  215.      * @param         $orderId
  216.      * @param         $sessionId
  217.      * @param Request $request
  218.      *
  219.      * @return SetTicketsOnServerResponse|\Symfony\Component\Form\FormInterface
  220.      */
  221.     public function ticketsOnServerAction($orderId$sessionIdRequest $request)
  222.     {
  223.         $start microtime(true);
  224.         /** @var Order $order */
  225.         $order $this->getAction($orderId);
  226.         $cinemaId $order->getCinemaId();
  227.         $session $this->sessionRepository->findOneBy([
  228.             'sessionId' => $sessionId,
  229.             'cinemaId' => $cinemaId
  230.         ]);
  231.         if (!$session){
  232.             // read drive in cinema mapping config
  233.             $di_mapping Yaml::parseFile($this->rootDir.'/config/drive_in_mapping.yml');
  234.             // search session with drive-in cinema id if not found with real cinema id
  235.             foreach ($di_mapping as $map) {
  236.                 if ($cinemaId === $map['host_cinema_id']) {
  237.                     $cinemaId $map['drive_in_cinema_id'];
  238.                     break;
  239.                 }
  240.             }
  241.             $session $this->sessionRepository->findOneBy([
  242.                 'sessionId' => $sessionId,
  243.                 'cinemaId' => $cinemaId
  244.             ]);
  245.         }
  246.         if (!$session){
  247.             throw "session not available";
  248.         }
  249.         // set cinemname from session to have the correct name, even with drive-in cinemas
  250.         $order->setCinemaName($session->getCinemaName());
  251.         $ticketDTO = new TicketDTO($sessionId$order->getCinemaId());
  252.         $form $this->formFactory->create(OrderTicketType::class, $ticketDTO);
  253.         
  254.         /** @var array $data */
  255.         $data $request->request->all();
  256.         // prepare vista index to reserve seat(s);
  257.         $rowsSaved false;
  258.         //error_log(sprintf("%s %s(%s) ", date('Y-m-d H:i:s'), __METHOD__, __LINE__) . var_export($rowsSaved, true));
  259.         //error_log(sprintf("%s %s(%s) before form submit", date('Y-m-d H:i:s'), __METHOD__, __LINE__));
  260.         for($i 0$i count($data['seats']); $i++) {
  261.             if ($data['seats'][$i]['rowIndex'] == && $data['seats'][$i]['areaNumber'] == 2) {
  262.                 error_log(sprintf("%s %s(%s) i data[$i] "date('Y-m-d H:i:s'), __METHOD____LINE__) . json_encode($data));
  263.             }
  264.             if(isset($data['seats'][$i]['columnIndexVista'])) {
  265.                 $data['seats'][$i]['columnIndex'] = $data['seats'][$i]['columnIndexVista'];
  266.                 unset($data['seats'][$i]['columnIndexVista']);
  267.                 unset($data['seats'][$i]['columnIndexRender']);
  268.             } else {
  269.                 if($rowsSaved === false) {
  270.                     $start microtime(true);
  271.                     $rowsSaved $this->seatPlanManager->getSavedRows($sessionId$cinemaId$session->getScreenNumber());
  272.                     $this->logger->info(sprintf("profiling seat selection :: getSavedRows execution time: %f"microtime(true) - $start));
  273.                 }
  274.                 if($rowsSaved) {
  275.                     $found false;
  276.                     foreach($rowsSaved as $rowSaved) {
  277.                         foreach($rowSaved->getSeats() as $seatSaved) {
  278.                             if($data['seats'][$i]['columnIndex'] == $seatSaved->getPosition()->getColumnIndexRender() &&
  279.                                     $data['seats'][$i]['areaNumber'] == $seatSaved->getPosition()->getAreaNumber() &&
  280.                                     $data['seats'][$i]['rowIndex'] == $seatSaved->getPosition()->getRowIndex()) {
  281.                                $data['seats'][$i]['columnIndex'] =  $seatSaved->getPosition()->getColumnIndexVista();
  282.                                $found true;
  283.                                 // if ($data['seats'][$i]['rowIndex'] == 8 && $data['seats'][$i]['areaNumber'] == 1 && $seatSaved->getPosition()->getColumnIndexVista() == 16) {
  284.                                     // error_log(sprintf("%s %s(%s) i data[$i] ", date('Y-m-d H:i:s'), __METHOD__, __LINE__) . json_encode($data));
  285.                                 // }
  286.                                break;
  287.                             }
  288.                         }
  289.                         if($found) {
  290.                             break;
  291.                         }
  292.                     }
  293.                 }
  294.             }
  295.         }
  296.         
  297.         $form->submit($data);
  298.         if (!$form->isSubmitted() || !$form->isValid()) {
  299.             return $form;
  300.         }
  301.         $setTicketsResponse $this->seatPlanManager->setTickets($order$session$ticketDTO);
  302.         $this->logger->info(sprintf("profiling seat selection :: seatPlanManager->setTickets execution time: %f"microtime(true) - $start));
  303.         return $setTicketsResponse;
  304.     }
  305.     /**
  306.      * @Route("/{orderId}/concessions-on-server", methods={"POST"})
  307.      * @View(statusCode=201)
  308.      *
  309.      * @SWG\Parameter(
  310.      *     name="body",
  311.      *     in="body",
  312.      *     @SWG\Schema(type="object",
  313.      *         @SWG\Property(property="orderConcessionItems", type="array", @SWG\Items(type="object",
  314.      *             @SWG\Property(property="numberOfConcessionItem", type="integer"),
  315.      *             @SWG\Property(property="cinemaId", type="string"),
  316.      *             @SWG\Property(property="itemId", type="string")))))
  317.      * @SWG\Response(
  318.      *     response="201",
  319.      *     description="Concessions successfully added",
  320.      *     @Model(type=App\Entity\Local\Response\SetTicketsOnServerResponse::class))
  321.      * @SWG\Response(
  322.      *     response="400",
  323.      *     description="Invalid request data")
  324.      *
  325.      * @param         $orderId
  326.      * @param Request $request
  327.      *
  328.      * @return SetTicketsOnServerResponse|\Symfony\Component\Form\FormInterface
  329.      */
  330.     public function concessionsOnServerAction($orderIdRequest $request)
  331.     {
  332.         /** @var Order $order */
  333.         $order $this->getAction($orderId);
  334.         $requestedConcessionItems=$request->get('orderConcessionItems');
  335.         /** @var OrderConcessionItem[] $orderConcessionItems */
  336.         $orderConcessionItems = [];
  337.         foreach ($requestedConcessionItems as $concessionItem){
  338.             $orderConcessionItems[] = (new OrderConcessionItem())
  339.               ->setItemId($concessionItem['itemId'])
  340.               ->setQuantity($concessionItem['numberOfConcessionItem']);
  341.         }
  342.         $order->setOrderConcessionItem($orderConcessionItems);
  343.         $order $this->orderRepository->setConcessions($order, (new SetConcessionsRequest())->setConcessionItems($orderConcessionItems));
  344.         $this->orderRepository->save($order);
  345.         return (new SetTicketsOnServerResponse())->setOrder($order);
  346.     }
  347.     /**
  348.      * Remove all concessions from order
  349.      *
  350.      * @Route("/{orderId}/remove-concessions", methods={"DELETE"})
  351.      * @View()
  352.      *
  353.      * @SWG\Response(
  354.      *     response="200",
  355.      *     description="Concessions have been successfully removed from order",
  356.      *     @Model(type=\App\Entity\Vista\Order::class))
  357.      *
  358.      * @param $orderId
  359.      * @return bool
  360.      */
  361.     public function removeConcessions($orderId)
  362.     {
  363.         if($order $this->getAction($orderId)){
  364.             $this->orderRepository->removeConcessions($order);
  365.             $this->orderRepository->save($order);
  366.             return true;
  367.         }
  368.         return false;
  369.     }
  370.     /**
  371.      * Cancel order
  372.      *
  373.      * @Route("/{orderId}", methods={"DELETE"})
  374.      * @View()
  375.      *
  376.      * @SWG\Response(
  377.      *     response="200",
  378.      *     description="Order has been successfully canceled",
  379.      *     @Model(type=\App\Entity\Vista\Order::class))
  380.      *
  381.      * @param $orderId
  382.      * @return bool
  383.      */
  384.     public function cancelAction($orderId)
  385.     {
  386.         $order $this->orderRepository->findOneBy(['userSessionId' => $orderId]);
  387.         if (getenv('KOM_BANK_ADDRESS') || getenv('RAIFFEISEN_ADDRESS') || getenv('CPAY_ADDRESS')) {
  388.             if ($this->paymentHelper->canBeCanceled($order)) {
  389.                 $this->orderRepository->cancel($order);
  390.                 return true;
  391.             }
  392.         } else {
  393.             if ($this->mPay24Helper->canBeCanceled($order)) {
  394.                 $this->orderRepository->cancel($order);
  395.                 return true;
  396.             }
  397.         }
  398.         return false;
  399.     }
  400.     /**
  401.      * @Route("/{orderId}", methods={"GET"})
  402.      * @View()
  403.      *
  404.      * @SWG\Response(
  405.      *     response=200,
  406.      *     description="Order",
  407.      *     @Model(type=\App\Entity\Vista\Order::class))
  408.      *
  409.      * @param $orderId
  410.      * @return Order
  411.      */
  412.     public function getAction($orderId)
  413.     {
  414.         return $this->orderRepository->findBySessionId($orderId);
  415.     }
  416. }