authorize('canReviewBasketSummary', OrderTunnelStep::class); $step = OrderTunnelStep::REVIEW; $basket = $basketService->getBasket(); return view('fo.tunnel.basket-summary', compact( 'step', 'basket' )); } public function basketSummarySubmit(ValidateSummaryRequest $request): RedirectResponse { $this->authorize('canReviewBasketSummary', OrderTunnelStep::class); $customer = $this->authService->getCustomerAsMandatory(); $basket = $this->basketService->getBasket(); $this->orderTunnelService->initializeFromBasket( $basket, $customer->getId() ); return to_route('fo.sales.pick-time-slot'); } // * -- STEP 2 -- * public function pickTimeSlot(): View { $this->authorize('canPickTimeSlot', OrderTunnelStep::class); $customer = $this->authService->getCustomerAsMandatory(); $shop = $this->orderTunnelService->getShopForCustomer($customer->getId()); $timeSlots = $this->orderTunnelService->getAvailableTimeSlots($shop); $step = OrderTunnelStep::BOOKING; $mapUrl = $this->mapUrlService->generateUrl($shop); return view('fo.tunnel.pick-time-slot', compact( 'step', 'shop', 'mapUrl', 'timeSlots' )); } public function pickTimeSlotSubmit(PickTimeSlotRequest $request): RedirectResponse { $this->authorize('canPickTimeSlot', OrderTunnelStep::class); $customer = $this->authService->getCustomerAsMandatory(); $builder = $this->orderTunnelService->getBuilderFromBasketOrFail(); $shop = $this->orderTunnelService->getShopForCustomer($customer->getId()); $timeSlots = $this->orderTunnelService->getAvailableTimeSlots($shop); $matchedSlot = $this->orderTunnelService->applyTimeSlot( $builder, $shop, $request->getTimeslot(), $timeSlots ); if ($matchedSlot === null) { return back()->withErrors([ 'timeslot' => trans('Invalid or unavailable time slot'), ])->withInput(); } return to_route('fo.sales.confirmation'); } // * -- STEP 3 -- * public function confirmation(): View { $this->authorize('canFinalizeOrder', OrderTunnelStep::class); $step = OrderTunnelStep::CONFIRMATION; $builder = $this->orderTunnelService->getBuilderCompletedOrFail(); $basket = $builder->getBasket(); $shop = $this->shopRepository->find($builder->getShopId()); if (! $shop) { abort(404, 'Shop not found'); } return view('fo.tunnel.confirmation', compact( 'step', 'basket', 'builder', 'shop' )); } public function confirmationSubmit(Request $request): RedirectResponse { $this->authorize('canFinalizeOrder', OrderTunnelStep::class); $request->validate([ 'ok_cgv' => ['accepted'], ]); $builder = $this->orderTunnelService->getBuilderCompletedOrFail(); try { $order = $this->orderTunnelService->finalizeOrder($builder); } catch (WeeklyLimitExceededException | OrderLimitExceededException $e) { return back()->with('message', $e->getMessage()); } return to_route('fo.sales.confirmation.show-confirmed', $order->reference->value); } // * -- CONFIRMATION -- * public function confirmed(Order $order): View { $this->authorize('viewOwn', $order); $step = OrderTunnelStep::CONFIRMATION; $shop = $order->shop; if (! $shop) { throw new \UnexpectedValueException('Shop not found for order ' . $order->getId()); } $mapUrl = $this->mapUrlService->generateUrl($shop); return view('fo.tunnel.confirmed', compact( 'step', 'order', 'shop', 'mapUrl' )); } }