*/ private const EAGER_LOADS = ['route', 'timeSlot', 'vehicleOptions']; public function __construct( private CreateBookingAction $createBookingAction, private CancelBookingAction $cancelBookingAction, ) {} public function index(Request $request): AnonymousResourceCollection { Gate::authorize('viewAny', Booking::class); $bookings = Booking::query() ->where('user_id', $request->user()->id) ->with(self::EAGER_LOADS) ->latest() ->paginate(); return BookingResource::collection($bookings); } public function show(Booking $booking): BookingResource { Gate::authorize('view', $booking); return new BookingResource($booking->load(self::EAGER_LOADS)); } public function store(StoreBookingRequest $request): JsonResponse { $validated = $request->validated(); $selections = array_map( fn (array $selection) => new VehicleSelectionData( vehicleOption: VehicleOption::from($selection['vehicle_option']), passengerCount: $selection['passenger_count'], ), $validated['selections'], ); $booking = $this->createBookingAction->handle(new CreateBookingData( evRouteId: $validated['ev_route_id'], departureTimeSlotId: $validated['departure_time_slot_id'], travelDate: $validated['travel_date'], selections: $selections, passengerName: $validated['passenger_name'], passengerPhone: $validated['passenger_phone'], pickupAddress: $validated['pickup_address'], dropoffAddress: $validated['dropoff_address'], createdByChannel: isset($validated['created_by_channel']) ? BookingChannel::from($validated['created_by_channel']) : BookingChannel::MiniApp, userId: $request->user()?->id, openid: $validated['openid'] ?? null, pickupLat: $validated['pickup_lat'] ?? null, pickupLng: $validated['pickup_lng'] ?? null, dropoffLat: $validated['dropoff_lat'] ?? null, dropoffLng: $validated['dropoff_lng'] ?? null, isRoundTrip: $validated['is_round_trip'] ?? false, returnTravelDate: $validated['return_travel_date'] ?? null, )); return (new BookingResource($booking->load(self::EAGER_LOADS))) ->response() ->setStatusCode(201); } public function cancel(Request $request, Booking $booking): BookingResource { Gate::authorize('cancel', $booking); $this->cancelBookingAction->handle($booking, $request->user()?->id); return new BookingResource($booking->load(self::EAGER_LOADS)); } }