sellerContext = $sellerContext; $this->sellerUtil = $sellerUtil; $this->sellerMultiFetch = $sellerMultiFetch; } /** * @Route("/_focus/reservation/create/") */ public function focusReservationCreate(Request $request, ReservationUtil $reservationUtil): Response { $view = (new View()) ->setTemplate('focus/reservation/focus.reservation.tpl'); // ID produktu a varianty, ktere budu rezervovat $productId = (int) $request->get('productId'); $variationId = $request->get('variationId'); $variationId = !empty($variationId) ? (int) $variationId : null; if (!$productId) { throw new NotFoundHttpException('Missing product ID!'); } // ID vybrane prodejny $selectedSellerId = null; if (!$request->get('sellerChange')) { $selectedSellerId = $request->get('sellerId'); } // nactu si produkt $product = \Variation::createProductOrVariation($productId, $variationId); $product->createFromDB(); $selectedSeller = $this->getSelectedSeller((int) $selectedSellerId, $product); $reservationReadyDate = $this->getReservationReadyDate($selectedSeller); $vars = [ 'product' => $product, 'seller' => $selectedSeller, 'reservationReadyDate' => $reservationReadyDate, 'reservationEndDate' => $this->getReservationEndDate($selectedSeller, $reservationReadyDate), 'userData' => [], 'error' => null, ]; // formular byl odeslan if ($request->isMethod('POST')) { try { if (!($sellerId = $request->request->get('sellerId'))) { throw new \InvalidArgumentException('Missing seller id'); } // vytvorim rezervaci $vars['reservation'] = $reservationUtil->createReservation( [ 'email' => $request->get('email'), 'name' => $request->get('name'), 'surname' => $request->get('surname'), 'phone' => $request->get('phone'), ], $productId, $variationId, [ 'sellerId' => (int) $sellerId, ] ); // ulozim si vyplnene udaje do sessiony, abych to mohl u dalsich rezervaci uz predvyplnit $request->getSession()->set(self::SESSION_USER_DATA, [ 'email' => $request->get('email'), 'name' => $request->get('name'), 'surname' => $request->get('surname'), 'phone' => $request->get('phone'), ]); // musi byt setovani po session set, protože pole porovnáva session data, chci zanechat strukturu a nesetovat session // na zacatku metody $vars['userData'] = $this->getUserData($request); } catch (\Exception $e) { $vars['error'] = translate('errorGeneric', 'reservations'); if ($e instanceof ValidationException) { $vars['error'] = $e->getMessage(); } if ($e instanceof \InvalidArgumentException) { $vars['error'] = translate('errorInvalidArguments', 'reservations'); } } $vars['sent'] = true; } return $view->addBodyVariables($vars) ->getResponse(); } protected function getUserData(Request $request): array { $userContext = Contexts::get(UserContext::class); $userData = []; /** @var \User $user */ if ($user = $userContext->getActive()) { $userData = [ 'email' => $user->email, 'name' => $user->invoice['name'] ?? '', 'surname' => $user->invoice['surname'] ?? '', 'phone' => $user->invoice['phone'] ?? '', ]; } return array_merge($userData, $request->getSession()->get(self::SESSION_USER_DATA, [])); } protected function getSelectedSeller(int $sellerId, \Product $product): array { $sellers = array_filter([$this->sellerContext->getSupported()[$sellerId] ?? null]); $this->sellerMultiFetch->fetchSellersInStore($sellers, [$product->id => $product->variationId ?? null]); $seller = reset($sellers); return $seller ?: []; } protected function getReservationEndDate(array $seller, ?\DateTime $readyDate): ?\DateTime { if (empty($seller)) { return null; } if (!$readyDate) { return null; } $endDate = clone $readyDate; $dbcfg = \Settings::getDefault(); if (!($reservationLength = $dbcfg->reservations['reservation_length'] ?? null)) { return null; } $i = 0; while ($reservationLength > 0) { if ($i > 30) { break; } $endDate->add(new \DateInterval('P1D')); if (!$this->sellerUtil->isSellerClosed($seller, 0, $endDate)) { $reservationLength--; } $i++; } return $endDate; } protected function getReservationReadyDate(array $seller): ?\DateTime { if (empty($seller)) { return null; } $dbcfg = \Settings::getDefault(); $preparationTime = $dbcfg->reservations['preparation_time'] ?? 1; $date = new \DateTime(); // pokud bude prodejna brzo zavirat if ($this->sellerUtil->isSellerClosed($seller, ((int) $preparationTime) + 1)) { // nactu si oteviraci dobu dalsiho dne if ($hour = $this->sellerUtil->getClosingTime($seller, $date, 0)) { $hourData = explode(':', $hour); // aktualizuju datum $date = new \DateTime('tomorrow'); $date->setTime((int) $hourData[0], (int) ($hourData[1] ?? 0)); } } $date->add(new \DateInterval('PT'.$preparationTime.'H')); // prevedu minuty na ctvrt hodiny $minutes = $date->format('i') - ($date->format('i') % 15); $date->setTime((int) $date->format('H'), (int) $minutes); return $date; } }