src/Controller/DefaultController.php line 64

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Doctrine\QueryHelper;
  4. use App\Entity\Guest;
  5. use App\Entity\Order;
  6. use App\Entity\Page;
  7. use App\Entity\Product;
  8. use App\Entity\ProductTranslation;
  9. use App\Entity\RestaurantReserve;
  10. use App\Entity\RoomReserve;
  11. use App\Entity\TableTurn;
  12. use App\Entity\Ticket;
  13. use App\Form\TicketGuestType;
  14. use App\Manager\EmailSender\CustomerEmailSender;
  15. use App\Manager\EmailSender\HotelEmailSender;
  16. use App\Manager\TicketManager;
  17. use App\Manager\WiFiPremiumManager;
  18. use App\Repository\DepartmentRepository;
  19. use App\Repository\OrderRepository;
  20. use App\Repository\PageRepository;
  21. use App\Repository\ReportRepository;
  22. use App\Repository\RestaurantRepository;
  23. use App\Repository\RestaurantReserveRepository;
  24. use App\Repository\RoomReserveRepository;
  25. use App\Repository\TicketRepository;
  26. use App\Security\User;
  27. use App\Service\LanguageSwitcher;
  28. use App\Service\RestaurantHelper;
  29. use Doctrine\ORM\EntityManagerInterface;
  30. use Doctrine\Persistence\ManagerRegistry;
  31. use Omnipay\Omnipay;
  32. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  33. use Symfony\Component\HttpFoundation\JsonResponse;
  34. use Symfony\Component\HttpFoundation\Request;
  35. use Symfony\Component\HttpFoundation\RequestStack;
  36. use Symfony\Component\HttpFoundation\Response;
  37. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  38. use Symfony\Component\Routing\Annotation\Route;
  39. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  40. use Symfony\Component\Routing\RouterInterface;
  41. use Symfony\Component\Validator\Constraints as Assert;
  42. use Symfony\Component\Validator\Validator\ValidatorInterface;
  43. use Symfony\Contracts\Translation\TranslatorInterface;
  44. /**
  45.  * Class DefaultController
  46.  * @package App\Controller
  47.  */
  48. class DefaultController extends AbstractController
  49. {
  50.     /**
  51.      * @Route({
  52.      *     "en": "/",
  53.      *     "es": "/es",
  54.      *     "fr": "/fr",
  55.      *     "de": "/de",
  56.      *     "ru": "/ru"
  57.      * }, name="app_home")
  58.      *
  59.      * @return Response
  60.      * @throws \Exception
  61.      */
  62.     public function home(): Response
  63.     {
  64.         return $this->render('home.html.twig');
  65.     }
  66.     /**
  67.      * @Route({
  68.      *     "en": "/product/{slug}",
  69.      *     "es": "/es/product/{slug}",
  70.      *     "fr": "/fr/product/{slug}",
  71.      *     "de": "/de/product/{slug}",
  72.      *     "ru": "/ru/product/{slug}"
  73.      * }, name="app_product", priority=100)
  74.      *
  75.      * @param ProductTranslation $productTranslation
  76.      * @param RoomReserveRepository $roomReserveRepository
  77.      * @param LanguageSwitcher $languageSwitcher
  78.      * @return Response
  79.      */
  80.     public function product(
  81.         ProductTranslation $productTranslation,
  82.         RoomReserveRepository $roomReserveRepository,
  83.         WiFiPremiumManager $wiFiPremiumManager,
  84.         LanguageSwitcher $languageSwitcher
  85.     ): Response
  86.     {
  87.         $user $this->getUser();
  88.         $product $productTranslation->getTranslatable();
  89.         $roomReserve $roomReserveRepository->findOneBy(['id' => $user->getRoomReserveId()]);
  90.         $isPurchasable $product->isPurchasable($roomReserve);
  91.         if (!$product || !$product->isVisible() || !$product->isRoomReserveAvailable($roomReserve)) {
  92.             throw new NotFoundHttpException('This resource does not exists');
  93.         }
  94.         $languageSwitcher->buildPaths($product);
  95.         return $this->render('product_detail.html.twig', [
  96.             'product' => $product,
  97.             'wiFiPremiumAccess' => $wiFiPremiumManager->getCurrentWiFiPremiumAccess($roomReserve),
  98.             'roomReserve' => $roomReserve,
  99.             'isPurchasable' => $isPurchasable
  100.         ]);
  101.     }
  102.     /**
  103.      * @Route("/{_locale}/{slug}", name="app_page", defaults={"_locale":"en"}, requirements={"_locale"="%available_locales_requirement%", "slug"=".+"}, priority=-100)
  104.      *
  105.      * @param string $slug
  106.      * @param Request $request
  107.      * @param PageRepository $pageRepository
  108.      * @param RoomReserveRepository $roomReserveRepository
  109.      * @param LanguageSwitcher $languageSwitcher
  110.      * @return Response
  111.      */
  112.     public function page(
  113.         string $slug,
  114.         Request $request,
  115.         PageRepository $pageRepository,
  116.         RoomReserveRepository $roomReserveRepository,
  117.         LanguageSwitcher $languageSwitcher
  118.     ): Response
  119.     {
  120.         $user $this->getUser();
  121.         $roomReserve $roomReserveRepository->findOneBy(['id' => $user->getRoomReserveId()]);
  122.         $slugs explode('/'$slug);
  123.         $pages = [];
  124.         foreach ($slugs as $key => $slugString) {
  125.             /** @var Page $section */
  126.             $page $pageRepository->findOneBySlug($slugString);
  127.             if (!$page) {
  128.                 // Try finding the page in the default locale
  129.                 $locale $request->getDefaultLocale();
  130.                 $page $pageRepository->findOneBySlugAndLocale($slugString$locale);
  131.                 if (!$page) {
  132.                     throw new NotFoundHttpException('This resource does not exists');
  133.                 }
  134.             }
  135.             if (!$page->getTourOperators()->isEmpty() && !$page->getTourOperators()->contains($roomReserve->getTourOperator())) {
  136.                 throw new NotFoundHttpException('This resource does not exists');
  137.             }
  138.             if ($key 0) {
  139.                 $parentPage $pages[$key 1];
  140.                 if (!$page->getParent()->getId()->equals($parentPage->getId())) {
  141.                     throw new NotFoundHttpException('This resource does not exists');
  142.                 }
  143.             }
  144.             $pages[$key] = $page;
  145.         }
  146.         $currentPage end($pages);
  147.         $languageSwitcher->buildPaths($currentPage);
  148.         if (!isset($locale)) {
  149.             $locale $request->getLocale();
  150.         }
  151.         $children $currentPage->getChildren()->filter(function(Page $page) use ($roomReserve$locale) {
  152.             return !$page->isDeleted() && ($page->getTourOperators()->isEmpty() || $page->getTourOperators()->contains($roomReserve->getTourOperator())) && array_key_exists($locale$page->getTranslations()->toArray());
  153.         })->toArray();
  154.         return $this->render('page.html.twig', [
  155.             'page' => $currentPage,
  156.             'children' => $children,
  157.             'roomReserve' => $roomReserve,
  158.             'slug' => $slug,
  159.         ]);
  160.     }
  161.     /**
  162.      * @Route({
  163.      *     "en": "/checkout",
  164.      *     "es": "/es/checkout",
  165.      *     "fr": "/fr/checkout",
  166.      *     "de": "/de/checkout",
  167.      *     "ru": "/ru/checkout"
  168.      * }, name="app_checkout", priority=100)
  169.      *
  170.      * @param Request $request
  171.      * @param RequestStack $requestStack
  172.      * @param QueryHelper $queryHelper
  173.      * @param RouterInterface $router
  174.      * @param OrderRepository $orderRepository
  175.      * @param TranslatorInterface $translator
  176.      * @param ValidatorInterface $validator
  177.      * @param EntityManagerInterface $entityManager
  178.      * @return Response
  179.      */
  180.     public function checkout(
  181.         Request $request,
  182.         RequestStack $requestStack,
  183.         QueryHelper $queryHelper,
  184.         RouterInterface $router,
  185.         OrderRepository $orderRepository,
  186.         TranslatorInterface $translator,
  187.         ValidatorInterface $validator,
  188.         EntityManagerInterface $entityManager,
  189.         WiFiPremiumManager $wiFiPremiumManager
  190.     ): Response
  191.     {
  192.         $currentHotel $queryHelper->getCurrentHotel();
  193.         $user $this->getUser();
  194.         $email '';
  195.         $customerNotes '';
  196.         $orderId $requestStack->getSession()->get('orderId');
  197.         $order $orderId $orderRepository->find($orderId) : null;
  198.         $defaultErrors = [];
  199.         $checkoutErrors = [];
  200.         $chargeError '';
  201.         if (!empty($order) && ($order->isDeleted() || $order->getRoomReserve()->getId()->toRfc4122() !== $user->getRoomReserveId())) {
  202.             $order null;
  203.         }
  204.         $guestEmails $user->getGuestEmails();
  205.         if (!empty($guestEmails)) {
  206.             $email array_pop($guestEmails);
  207.         }
  208.         if ($request->isMethod('POST')) {
  209.             $email $request->request->get('email');
  210.             $customerNotes $request->request->get('customer-notes');
  211.             $order->setEmail($email);
  212.             $order->setCustomerNotes($customerNotes);
  213.             $defaultErrors $validator->validate($order);
  214.             $checkoutErrors $validator->validate($ordernull, ['checkout']);
  215.             $params = [];
  216.             if ($request->query->get('mode') === 'kiosk') {
  217.                 $params['mode'] = 'kiosk';
  218.             }
  219.             if (empty($chargeError) && count($defaultErrors) === && count($checkoutErrors) === 0) {
  220.                 // Save guest email address
  221.                 $this->saveGuestEmail($order->getRoomReserve()->getRegistrant(), $email$entityManager);
  222.                 if ($order->getTotal() > && !empty($currentHotel->getStripePublishableKey()) && !empty($currentHotel->getStripeSecretKey())) {
  223.                     $gateway Omnipay::create('Stripe\PaymentIntents');
  224.                     $gateway->initialize([
  225.                         'apiKey' => $currentHotel->getStripeSecretKey(),
  226.                     ]);
  227.                     $response $gateway->purchase([
  228.                         'amount' => $order->getTotal() / 100,
  229.                         'currency' => 'USD',
  230.                         'description' => 'Order for room reserve ' $order->getRoomReserve()->getNumber() . ' in room ' $order->getRoomReserve()->getRoom()->getName(),
  231.                         'paymentMethod' => $request->get('paymentMethodId'),
  232.                         'returnUrl' => $router->generate('app_checkout_confirm'$paramsUrlGeneratorInterface::ABSOLUTE_URL),
  233.                         'confirm' => true,
  234.                         'metadata' => [
  235.                             'order_id' => $order->getId()->toRfc4122(),
  236.                         ],
  237.                     ])->send();
  238.                     $redirectUrl null;
  239.                     if ($response->isSuccessful()) {
  240.                         $order->setStripeCharge($response->getTransactionReference());
  241.                         $order->setCreatedAt(new \DateTime());
  242.                         $entityManager->persist($order);
  243.                         if ($order->hasWiFiPremium()) {
  244.                             $wiFiPremiumAccess $wiFiPremiumManager->createWiFiPremiumAccess($order);
  245.                             if (!is_null($wiFiPremiumAccess)) {
  246.                                 $orderItem $order->getOrderItemWithWiFiPremium();
  247.                                 if ($orderItem) {
  248.                                     $orderItem->setWiFiPremiumAccess($wiFiPremiumAccess);
  249.                                     $entityManager->persist($orderItem);
  250.                                 }
  251.                                 $roomReserve $order->getRoomReserve();
  252.                                 $roomReserve->addWiFiPremiumAccess($wiFiPremiumAccess);
  253.                                 $entityManager->persist($roomReserve);
  254.                             }
  255.                         }
  256.                         $entityManager->flush();
  257.                         $redirectUrl $router->generate('app_checkout_finished'$paramsUrlGeneratorInterface::ABSOLUTE_URL);
  258.                     } elseif ($response->isRedirect()) {
  259.                         $entityManager->persist($order);
  260.                         $entityManager->flush();
  261.                         $redirectUrl $response->getRedirectUrl();
  262.                     } else {
  263.                         $chargeError $response->getMessage();
  264.                     }
  265.                     if (!is_null($redirectUrl)) {
  266.                         return $this->redirect($redirectUrl);
  267.                     }
  268.                 } else {
  269.                     $entityManager->persist($order);
  270.                     $entityManager->flush();
  271.                     return $this->redirectToRoute('app_checkout_finished'$params);
  272.                 }
  273.             }
  274.         }
  275.         return $this->render('checkout.html.twig', [
  276.             'order' => $order,
  277.             'email' => $email,
  278.             'customerNotes' => $customerNotes,
  279.             'stripePublishableKey' => $currentHotel->getStripePublishableKey(),
  280.             'defaultErrors' => $defaultErrors,
  281.             'checkoutErrors' => $checkoutErrors,
  282.             'chargeError' => $chargeError
  283.         ]);
  284.     }
  285.     /**
  286.      * @Route({
  287.      *     "en": "/checkout-confirm",
  288.      *     "es": "/es/checkout-confirm",
  289.      *     "fr": "/fr/checkout-confirm",
  290.      *     "de": "/de/checkout-confirm",
  291.      *     "ru": "/ru/checkout-confirm"
  292.      * }, name="app_checkout_confirm", priority=100)
  293.      *
  294.      * @param Request $request
  295.      * @param RequestStack $requestStack
  296.      * @param QueryHelper $queryHelper
  297.      * @param RouterInterface $router
  298.      * @param OrderRepository $orderRepository
  299.      * @param EntityManagerInterface $entityManager
  300.      * @param CustomerEmailSender $customerEmailSender
  301.      * @param ValidatorInterface $validator
  302.      * @return Response
  303.      * @throws \Exception
  304.      */
  305.     public function checkoutConfirm(
  306.         Request $request,
  307.         RequestStack $requestStack,
  308.         QueryHelper $queryHelper,
  309.         RouterInterface $router,
  310.         OrderRepository $orderRepository,
  311.         EntityManagerInterface $entityManager,
  312.         WiFiPremiumManager $wiFiPremiumManager,
  313.         CustomerEmailSender $customerEmailSender,
  314.         ValidatorInterface $validator
  315.     ): Response
  316.     {
  317.         $currentHotel $queryHelper->getCurrentHotel();
  318.         $user $this->getUser();
  319.         $orderId $requestStack->getSession()->get('orderId');
  320.         $order $orderId $orderRepository->find($orderId) : null;
  321.         $params = [];
  322.         if ($request->query->get('mode') === 'kiosk') {
  323.             $params['mode'] = 'kiosk';
  324.         }
  325.         $gateway Omnipay::create('Stripe\PaymentIntents');
  326.         $gateway->initialize([
  327.             'apiKey' => $currentHotel->getStripeSecretKey(),
  328.         ]);
  329.         $response $gateway->completePurchase([
  330.             'paymentIntentReference' => $request->get('payment_intent'),
  331.             'returnUrl' => $router->generate('app_checkout_confirm'$paramsUrlGeneratorInterface::ABSOLUTE_URL),
  332.         ])->send();
  333.         if ($response->isSuccessful()) {
  334.             $order->setStripeCharge($response->getTransactionReference());
  335.             $order->setCreatedAt(new \DateTime());
  336.             $entityManager->persist($order);
  337.             if ($order->hasWiFiPremium()) {
  338.                 $wiFiPremiumAccess $wiFiPremiumManager->createWiFiPremiumAccess($order);
  339.                 if (!is_null($wiFiPremiumAccess)) {
  340.                     $orderItem $order->getOrderItemWithWiFiPremium();
  341.                     if ($orderItem) {
  342.                         $orderItem->setWiFiPremiumAccess($wiFiPremiumAccess);
  343.                         $entityManager->persist($orderItem);
  344.                     }
  345.                     $roomReserve $order->getRoomReserve();
  346.                     $roomReserve->addWiFiPremiumAccess($wiFiPremiumAccess);
  347.                     $entityManager->persist($roomReserve);
  348.                 }
  349.             }
  350.             $entityManager->flush();
  351.             return $this->redirectToRoute('app_checkout_finished'$params);
  352.         }
  353.         return $this->redirectToRoute('app_checkout'$params);
  354.     }
  355.     /**
  356.      * @Route({
  357.      *     "en": "/checkout-finished",
  358.      *     "es": "/es/checkout-finished",
  359.      *     "fr": "/fr/checkout-finished",
  360.      *     "de": "/de/checkout-finished",
  361.      *     "ru": "/ru/checkout-finished"
  362.      * }, name="app_checkout_finished", priority=100)
  363.      *
  364.      * @param RequestStack $requestStack
  365.      * @param QueryHelper $queryHelper
  366.      * @param OrderRepository $orderRepository
  367.      * @param EntityManagerInterface $entityManager
  368.      * @param CustomerEmailSender $customerEmailSender
  369.      * @param ValidatorInterface $validator
  370.      * @return Response
  371.      * @throws \Exception
  372.      */
  373.     public function checkoutFinished(
  374.         RequestStack $requestStack,
  375.         QueryHelper $queryHelper,
  376.         OrderRepository $orderRepository,
  377.         EntityManagerInterface $entityManager,
  378.         TicketManager $ticketManager,
  379.         CustomerEmailSender $customerEmailSender,
  380.         HotelEmailSender $hotelEmailSender,
  381.         ValidatorInterface $validator
  382.     ): Response
  383.     {
  384.         $user $this->getUser();
  385.         $orderId $requestStack->getSession()->get('orderId');
  386.         $order $orderId $orderRepository->find($orderId) : null;
  387.         $errors $validator->validate($ordernull, ['Default''checkout']);
  388.         $params = [];
  389.         if ($requestStack->getCurrentRequest()->query->get('mode') === 'kiosk') {
  390.             $params['mode'] = 'kiosk';
  391.         }
  392.         if (empty($order) ||
  393.             $order->isDeleted() ||
  394.             $order->getRoomReserve()->getId()->toRfc4122() !== $user->getRoomReserveId() ||
  395.             count($errors) > 0) {
  396.             return $this->redirectToRoute('app_checkout'$params);
  397.         }
  398.         foreach($order->getOrderItems() as $item) {
  399.             $item->getProduct()->discountStock($item->getAmount());
  400.         }
  401.         $order->setStatus(Order::STATUS_FINISHED);
  402.         $entityManager->persist($order);
  403.         $entityManager->flush();
  404.         $requestStack->getSession()->remove('orderId');
  405.         $sent $customerEmailSender->sendOrder($order);
  406.         $hotelEmailSender->sendOrder($order);
  407.         $ticketManager->createTicketsForOrder($order);
  408.         $ticketManager->remotePrintOrderTickets($order);
  409.         return $this->render('checkout_finished.html.twig', [
  410.             'order' => $order,
  411.             'emailError' => $sent
  412.         ]);
  413.     }
  414.     /**
  415.      * @Route({
  416.      *     "en": "/restaurant-reserve",
  417.      *     "es": "/es/restaurant-reserve",
  418.      *     "fr": "/fr/restaurant-reserve",
  419.      *     "de": "/de/restaurant-reserve",
  420.      *     "ru": "/ru/restaurant-reserve"
  421.      * }, name="app_restaurant_reserve", priority=100)
  422.      *
  423.      * @param Request $request
  424.      * @param RequestStack $requestStack
  425.      * @param RestaurantRepository $restaurantRepository
  426.      * @param RoomReserveRepository $roomReserveRepository
  427.      * @param RestaurantHelper $restaurantHelper
  428.      * @param CustomerEmailSender $customerEmailSender
  429.      * @param EntityManagerInterface $entityManager
  430.      * @return Response
  431.      */
  432.     public function restaurants(
  433.         Request $request,
  434.         RequestStack $requestStack,
  435.         RestaurantRepository $restaurantRepository,
  436.         RoomReserveRepository $roomReserveRepository,
  437.         RestaurantHelper $restaurantHelper,
  438.         CustomerEmailSender $customerEmailSender,
  439.         EntityManagerInterface $entityManager
  440.     ): Response
  441.     {
  442.         /** @var User $user */
  443.         $user $this->getUser();
  444.         $today = new \DateTime('today');
  445.         $todayKey $today->format('N');
  446.         $tomorrow = new \DateTime('tomorrow');
  447.         $tomorrowKey $tomorrow->format('N');
  448.         $params = [];
  449.         if ($request->query->get('mode') === 'kiosk') {
  450.             $params['mode'] = 'kiosk';
  451.         }
  452.         $result = [];
  453.         $roomReserve $roomReserveRepository->findOneBy(['id' => $user->getRoomReserveId()]);
  454.         $people $roomReserve->getPeople();
  455.         if ($request->isMethod('POST')) {
  456.             $restaurant $request->request->get('restaurant');
  457.             $comments $request->request->get('comments');
  458.             $pax $request->request->getInt('pax');
  459.             $day $request->request->get('day');
  460.             $turn $request->request->get('turn');
  461.             $name $request->request->get('name');
  462.             $email $request->request->get('email');
  463.             $restaurant $restaurantRepository->findOneBy(['id' => $restaurant]);
  464.             $result $restaurantHelper->makeReservation($restaurant$comments$pax$day$turn$name$email, [$roomReserve]);
  465.             if (!empty($result) && empty($result['errors']) && !empty($result['reservation'])) {
  466.                 // Save guest email address
  467.                 $this->saveGuestEmail($roomReserve->getRegistrant(), $email$entityManager);
  468.                 if (empty($email)) {
  469.                     $emails $user->getGuestEmails();
  470.                     $email array_pop($emails);
  471.                 }
  472.                 $requestStack->getSession()->set('saved_email'$email);
  473.                 /** @var RestaurantReserve $restaurantReserve */
  474.                 $restaurantReserve $result['reservation'];
  475.                 $date $todayKey === $day $today $tomorrow;
  476.                 $customerEmailSender->sendRestaurantReservation($restaurantReserve$email$date$comments);
  477.                 $requestStack->getSession()->set('restaurant_reservation'$restaurantReserve->getId()->toRfc4122());
  478.                 $requestStack->getSession()->set('restaurant_reservation_pax'$pax);
  479.                 $requestStack->getSession()->set('restaurant_reservation_comments'$comments);
  480.                 return $this->redirectToRoute('app_restaurant_reserve_details'$params);
  481.             }
  482.         }
  483.         $restaurants $restaurantRepository->findAllByCurrentHotel();
  484.         $restaurantsData $restaurantHelper->getRestaurantsData($roomReserve$people);
  485.         return $this->render('restaurants.html.twig', [
  486.             'name' => $roomReserve->getRegistrant()->getFullName(),
  487.             'email' => $roomReserve->getRegistrant()->getEmail(),
  488.             'restaurants' => $restaurants,
  489.             'restaurantsData' => $restaurantsData,
  490.             'today' => $today,
  491.             'todayKey' => $todayKey,
  492.             'tomorrow' => $tomorrow,
  493.             'tomorrowKey' => $tomorrowKey,
  494.             'result' => $result,
  495.         ]);
  496.     }
  497.     /**
  498.      * @Route({
  499.      *     "en": "/restaurant-reserve/details",
  500.      *     "es": "/es/restaurant-reserve/details",
  501.      *     "fr": "/fr/restaurant-reserve/details",
  502.      *     "de": "/de/restaurant-reserve/details",
  503.      *     "ru": "/ru/restaurant-reserve/details"
  504.      * }, name="app_restaurant_reserve_details", priority=100)
  505.      *
  506.      * @param Request $request
  507.      * @param RequestStack $requestStack
  508.      * @param RestaurantReserveRepository $restaurantReserveRepository
  509.      * @return Response
  510.      */
  511.     public function restaurantReservationDetails(
  512.         Request $request,
  513.         RequestStack $requestStack,
  514.         RestaurantReserveRepository $restaurantReserveRepository
  515.     ): Response
  516.     {
  517.         /** @var User $user */
  518.         $user $this->getUser();
  519.         $restaurantReserveId $requestStack->getSession()->get('restaurant_reservation');
  520.         $pax $requestStack->getSession()->get('restaurant_reservation_pax');
  521.         $comments $requestStack->getSession()->get('restaurant_reservation_comments');
  522.         if (empty($restaurantReserveId) || empty($pax)) {
  523.             throw new NotFoundHttpException();
  524.         }
  525.         $restaurantReserve $restaurantReserveRepository->findOneBy(['id' => $restaurantReserveId]);
  526.         $roomReserveIds array_map(static function (RoomReserve $roomReserve) {return $roomReserve->getId()->toRfc4122();}, $restaurantReserve->getRoomReserves()->toArray());
  527.         if (!in_array($user->getRoomReserveId(), $roomReserveIdstrue)) {
  528.             throw new NotFoundHttpException();
  529.         }
  530.         $restaurantName $restaurantReserve->getRestaurant()->getName();
  531.         /** @var TableTurn $tableTurn */
  532.         $tableTurn $restaurantReserve->getTableTurns()->first();
  533.         $turnName $tableTurn->getTurnDay()->getTurn()->getName();
  534.         $turnTime $tableTurn->getTurnDay()->getTurn()->getTime();
  535.         $today = new \DateTime('today');
  536.         $todayKey $today->format('N');
  537.         $tomorrow = new \DateTime('tomorrow');
  538.         $tomorrowKey $tomorrow->format('N');
  539.         $date $todayKey === $restaurantReserve->getReservedAt()->format('N') ? $today $tomorrow;
  540.         $roomReserves $restaurantReserve->getRoomReserves();
  541.         $roomNumbers array_map(static function (RoomReserve $roomReserve) {return $roomReserve->getRoom()->getName();}, $roomReserves->toArray());
  542.         $roomNumbers implode(','$roomNumbers);
  543.         $requestStack->getSession()->remove('restaurant_reservation');
  544.         $requestStack->getSession()->remove('restaurant_reservation_pax');
  545.         $requestStack->getSession()->remove('restaurant_reservation_comments');
  546.         return $this->render('restaurant_reservation_details.html.twig', [
  547.             'restaurantReserve' => $restaurantReserve,
  548.             'roomNumbers' => $roomNumbers,
  549.             'restaurantName' => $restaurantName,
  550.             'date' => $date,
  551.             'pax' => $pax,
  552.             'turnName' => $turnName,
  553.             'turnTime' => $turnTime,
  554.             'comments' => $comments,
  555.         ]);
  556.     }
  557.     /**
  558.      * @Route({
  559.      *     "en": "/create-ticket",
  560.      *     "es": "/es/create-ticket",
  561.      *     "fr": "/fr/create-ticket",
  562.      *     "de": "/de/create-ticket",
  563.      *     "ru": "/ru/create-ticket"
  564.      * }, name="app_create_ticket", priority=100)
  565.      *
  566.      * @param Request $request
  567.      * @param RoomReserveRepository $roomReserveRepository
  568.      * @param TicketManager $ticketManager
  569.      * @param CustomerEmailSender $customerEmailSender
  570.      * @param ValidatorInterface $validator
  571.      */
  572.     public function createTicket(
  573.         Request $request,
  574.         RoomReserveRepository $roomReserveRepository,
  575.         TicketManager $ticketManager,
  576.         CustomerEmailSender $customerEmailSender,
  577.         ValidatorInterface $validator,
  578.         EntityManagerInterface $entityManager
  579.     ): Response
  580.     {
  581.         $params = [];
  582.         if ($request->query->get('mode') === 'kiosk') {
  583.             $params['mode'] = 'kiosk';
  584.         }
  585.         /** @var User $user */
  586.         $user $this->getUser();
  587.         $roomReserve $roomReserveRepository->findOneBy(['id' => $user->getRoomReserveId()]);
  588.         $ticket = new Ticket();
  589.         $form $this->createForm(TicketGuestType::class, $ticket, ['room_reserve' => $roomReserve]);
  590.         $form->handleRequest($request);
  591.         if ($form->isSubmitted() && $form->isValid()) {
  592.             $ticketManager->updateTicket($ticket);
  593.             $entityManager->persist($ticket);
  594.             $entityManager->flush();
  595.             /** @var Ticket $ticket */
  596.             $ticket $form->getData();
  597.             $department $ticket->getDepartment();
  598.             $report $ticket->getReport();
  599.             $detail $ticket->getDetail();
  600.             $comments $ticket->getDescription();
  601.             $email $form->get('email')->getData();
  602.             if (!empty($email)) {
  603.                 $emailConstraint = new Assert\Email();
  604.                 $errors $validator->validate($email$emailConstraint);
  605.                 if (count($errors) > 0) {
  606.                     $email null;
  607.                 }
  608.             }
  609.             if (empty($email)) {
  610.                 $emails $user->getGuestEmails();
  611.                 $email $emails[0];
  612.             } else {
  613.                 // Save guest email address
  614.                 $this->saveGuestEmail($roomReserve->getRegistrant(), $email$entityManager);
  615.             }
  616.             $originName 'Guest Max';
  617.             $departmentName $department->getName();
  618.             $reportName $report $report->getName() : null;
  619.             $detailName $detail $detail->getName() : null;
  620.             $customerEmailSender->sendTicket($ticket$email$originName$departmentName$reportName$detailName$comments$user);
  621.             $params['id'] = $ticket->getId();
  622.             return $this->redirectToRoute('app_create_ticket_result'$params);
  623.         }
  624.         $response $this->render('create_ticket.html.twig', [
  625.             'ticket' => $ticket,
  626.             'form' => $form->createView(),
  627.         ]);
  628.         return $this->forceRevalidate($response);
  629.     }
  630.     /**
  631.      * @Route({
  632.      *     "en": "/create-ticket-reports",
  633.      *     "es": "/es/create-ticket-reports",
  634.      *     "fr": "/fr/create-ticket-reports",
  635.      *     "de": "/de/create-ticket-reports",
  636.      *     "ru": "/ru/create-ticket-reports"
  637.      * }, name="app_create_ticket_reports", priority=100)
  638.      *
  639.      * @param Request $request
  640.      * @param RoomReserveRepository $roomReserveRepository
  641.      * @param DepartmentRepository $departmentRepository,
  642.      * @return Response
  643.      */
  644.     public function createTicketReports(
  645.         Request $request,
  646.         RoomReserveRepository $roomReserveRepository,
  647.         DepartmentRepository $departmentRepository
  648.     ): Response
  649.     {
  650.         /** @var User $user */
  651.         $user $this->getUser();
  652.         $result = [];
  653.         if ($request->isMethod('POST')) {
  654.             $department $request->request->get('department');
  655.             $roomReserve $roomReserveRepository->findOneBy(['id' => $user->getRoomReserveId()]);
  656.             $hotel $roomReserve->getRoom()->getHotel();
  657.             $department $departmentRepository->findOneBy(['id' => $department]);
  658.             if ($hotel->getDepartments()->contains($department)) {
  659.                 foreach ($department->getReports() as $report) {
  660.                     $result[] = ['id' => $report->getId()->toRfc4122(), 'name' => $report->translate($request->getLocale())->getName()];
  661.                 }
  662.             }
  663.         }
  664.         return new JsonResponse($result);
  665.     }
  666.     /**
  667.      * @Route({
  668.      *     "en": "/create-ticket-details",
  669.      *     "es": "/es/create-ticket-details",
  670.      *     "fr": "/fr/create-ticket-details",
  671.      *     "de": "/de/create-ticket-details",
  672.      *     "ru": "/ru/create-ticket-details"
  673.      * }, name="app_create_ticket_details", priority=100)
  674.      *
  675.      * @param Request $request
  676.      * @param RoomReserveRepository $roomReserveRepository
  677.      * @param ReportRepository $reportRepository
  678.      * @return Response
  679.      */
  680.     public function createTicketDetails(
  681.         Request $request,
  682.         RoomReserveRepository $roomReserveRepository,
  683.         ReportRepository $reportRepository
  684.     ): Response
  685.     {
  686.         /** @var User $user */
  687.         $user $this->getUser();
  688.         $result = [];
  689.         if ($request->isMethod('POST')) {
  690.             $report $request->request->get('report');
  691.             $roomReserve $roomReserveRepository->findOneBy(['id' => $user->getRoomReserveId()]);
  692.             $hotel $roomReserve->getRoom()->getHotel();
  693.             $report $reportRepository->findOneBy(['id' => $report]);
  694.             $department $report->getDepartment();
  695.             if ($hotel->getDepartments()->contains($department)) {
  696.                 foreach ($report->getDetails() as $detail) {
  697.                     $result[] = ['id' => $detail->getId()->toRfc4122(), 'name' => $detail->translate($request->getLocale())->getName()];
  698.                 }
  699.             }
  700.         }
  701.         return new JsonResponse($result);
  702.     }
  703.     /**
  704.      * @Route({
  705.      *     "en": "/create-ticket/{id}",
  706.      *     "es": "/es/create-ticket/{id}",
  707.      *     "fr": "/fr/create-ticket/{id}",
  708.      *     "de": "/de/create-ticket/{id}",
  709.      *     "ru": "/ru/create-ticket/{id}"
  710.      * }, name="app_create_ticket_result", priority=100)
  711.      *
  712.      * @param Request $request
  713.      * @param TicketRepository $ticketRepository
  714.      * @param RoomReserveRepository $roomReserveRepository
  715.      * @param string $id
  716.      * @return Response
  717.      */
  718.     public function createTicketResult(
  719.         Request $request,
  720.         TicketRepository $ticketRepository,
  721.         RoomReserveRepository $roomReserveRepository,
  722.         string $id
  723.     ): Response
  724.     {
  725.         /** @var User $user */
  726.         $user $this->getUser();
  727.         $ticket $ticketRepository->findOneBy(['id' => $id]);
  728.         $roomReserve $roomReserveRepository->findOneBy(['id' => $user->getRoomReserveId()]);
  729.         if (empty($ticket) || empty($roomReserve) || $ticket->getRoomReserve()->getId()->toRfc4122() !== $roomReserve->getId()->toRfc4122()) {
  730.             throw new NotFoundHttpException();
  731.         }
  732.         return $this->render('create_ticket_result.html.twig', [
  733.             'ticket' => $ticket,
  734.         ]);
  735.     }
  736.     public function languageSwitcher(RequestStack $requestStackLanguageSwitcher $languageSwitcher): Response
  737.     {
  738.         return $this->render('_language_switcher.html.twig', [
  739.             'paths' => $languageSwitcher->getPaths(),
  740.             'isKiosk' => $requestStack->getCurrentRequest()->query->get('mode') === 'kiosk' || $requestStack->getSession()->get('mode') === 'kiosk',
  741.         ]);
  742.     }
  743.     private function saveGuestEmail(?Guest $guest, ?string $emailEntityManagerInterface $entityManager)
  744.     {
  745.         if ($email && $guest) {
  746.             $guest->setEmail($email);
  747.             $entityManager->persist($guest);
  748.             $entityManager->flush();
  749.         }
  750.     }
  751.     private function forceRevalidate(Response $response): Response
  752.     {
  753.         $response->setMaxAge(0);
  754.         $response->headers->addCacheControlDirective('must-revalidate'true);
  755.         $response->headers->addCacheControlDirective('no-cache'true);
  756.         $response->headers->addCacheControlDirective('no-store'true);
  757.         return $response;
  758.     }
  759. }