HEX
Server: Apache/2.4.58 (Ubuntu)
System: Linux ip-172-26-0-120 6.17.0-1009-aws #9~24.04.2-Ubuntu SMP Fri Mar 6 23:50:29 UTC 2026 x86_64
User: ubuntu (1000)
PHP: 8.3.6
Disabled: NONE
Upload Files
File: /var/www/html/dashboard.orbiwheels.com/app/Http/Controllers/Transporter/BookingController.php
<?php

namespace App\Http\Controllers\Transporter;

use App\DataTables\Transporter\BookingDataTable;
use App\DataTables\Transporter\BookingRidesDataTable;
use App\DataTables\Transporter\TwoWayBookingDataTable;
use App\Enums\RideRequestStatus;
use App\Http\Controllers\Controller;
use App\Models\Booking;
use App\Models\BookingRide;
use App\Models\Driver;
use App\Models\RideRequest;
use App\Models\TransporterSetting;
use App\Models\Trip;
use App\Models\Vehicle;
use App\Services\FirebaseService;
use Illuminate\Http\Request;

class BookingController extends Controller
{
    public $user;
    public function __construct()
    {
        $this->user = auth()->guard('trans')->user();
    }

    public function index(BookingDataTable $dataTable)
    {
        $transporterId = auth()->guard('trans')->user()->id;
        $drivers = Driver::where('transporter_id', $transporterId)->where('status', 'active')->get();
        $vehicles = Vehicle::where('transporter_id', $transporterId)->where('status', 'active')->get();

        return $dataTable->render('transporter.booking.index', compact('drivers', 'vehicles'));
    }
    public function twoWayIndex(TwoWayBookingDataTable $dataTable)
    {
        $transporterId = auth()->guard('trans')->user()->id;
        $drivers = Driver::where('transporter_id', $transporterId)->where('status', 'active')->get();
        $vehicles = Vehicle::where('transporter_id', $transporterId)->where('status', 'active')->get();

        return $dataTable->render('transporter.booking.twoWayIndex', compact('drivers', 'vehicles'));
    }
    public function view(BookingRidesDataTable $dataTable, $id)
    {
        $transporterId = auth()->guard('trans')->id();

        $booking = Booking::with(['trips' => function ($q) use ($transporterId) {
            $q->where('transporter_id', $transporterId);
        }, 'trips.bookingRides'])
            ->findOrFail(decrypt($id));

        $drivers = Driver::where('transporter_id', $transporterId)
            ->where('status', 'active')
            ->get();

        $vehicles = Vehicle::where('transporter_id', $transporterId)
            ->where('status', 'active')
            ->get();

        $canSeeCustomer = TransporterSetting::where('transporter_id', $transporterId)
            ->where('key', 'can_see_customer')
            ->where('value', 1)
            ->exists();

        $totalTrips = $booking->trips->count(); // Only trips for this transporter

        // Total earnings for this transporter
        $totalEarnings = $booking->trips->sum(function ($trip) {
            return $trip->pricing_details['fare'] ?? 0;
        });
        $dataTable->with('bookingId', $booking->id);
         return $dataTable->render('transporter.booking.view', compact('booking', 'drivers', 'vehicles', 'canSeeCustomer', 'totalTrips', 'totalEarnings'));
    }

    public function getRides($id, BookingRidesDataTable $dataTable)
    {
        $bookingId = decrypt($id);
        //   dd('getRides called', $bookingId);
        return $dataTable->with('bookingId', $bookingId)->ajax();
    }

    public function assignBooking(Request $request, $bookingId)
    {
        try {
            $transporterId = auth()->guard('trans')->id();

            $booking = Booking::with(['rides', 'trips.bookingRides', 'rideRequests'])
                ->findOrFail(decrypt($bookingId));

            $vehicleId = $request->vehicle_id ?? null;
            $driverId  = $request->driver_id ?? null;

            if (!$vehicleId || !$driverId) {
                return response()->json(['message' => 'Driver and Vehicle are required.'], 422);
            }

            $vehicle = Vehicle::findOrFail($vehicleId);

            if (!empty($booking->vehicle_preferred) && $vehicle->vehicle_type_id != $booking->vehicle_preferred) {
                return response()->json([
                    'message' => 'Selected vehicle does not match the preferred type'
                ], 422);
            }

            $pendingRequests = $booking->rideRequests()
                ->where('status', RideRequest::PENDING)
                ->where('transporter_id', $transporterId)
                ->get();
            if ($pendingRequests->isEmpty()) {
                return response()->json(['message' => 'No pending ride request found for this booking.'], 422);
            }

            foreach ($pendingRequests as $req) {
                $req->update(['status' => RideRequest::ACCEPTED]);
            }

            RideRequest::where('booking_id', $booking->id)
                ->where('transporter_id', '!=', $transporterId)
                ->where('status', RideRequest::PENDING)
                ->update(['status' => RideRequest::EXPIRED]);
            // dd($booking->trips);

            foreach ($pendingRequests as $req) {
                $req->update(['status' => RideRequest::ACCEPTED]);

                foreach ($req->trip()->whereIn('status', [Trip::PENDING, Trip::REQUESTED])->get() as $trip) {
                    $trip->update([
                        'status'         => Trip::ACCEPTED,
                        'transporter_id' => $transporterId,
                    ]);

                    foreach ($trip->bookingRides()->where('status', BookingRide::PENDING)->get() as $ride) {
                        $ride->update([
                            'driver_id'      => $driverId,
                            'vehicle_id'     => $vehicleId,
                            'transporter_id' => $transporterId,
                            'status'         => BookingRide::ASSIGNED,
                        ]);
                    }
                }
            }


            return response()->json(['message' => 'Booking request accepted and rides assigned successfully!']);
        } catch (\Illuminate\Contracts\Encryption\DecryptException $e) {
            return response()->json(['message' => 'Invalid booking ID.'], 400);
        } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
            return response()->json(['message' => 'Booking, Vehicle, or related records not found.'], 404);
        } catch (\Exception $e) {
            return response()->json(['message' => 'Something went wrong: ' . $e->getMessage()], 500);
        }
    }


    public function acceptByBooking(Request $request, FirebaseService $service, $id)
    {
        try {
            $booking = Booking::with('rideRequests', 'trips.bookingRides')
                ->where('id', decrypt($id))
                ->firstOrFail();

            if ($booking->status !== Booking::REQUESTED) {
                return response()->json([
                    'status' => false,
                    'message' => 'This booking is already processed.'
                ]);
            }

            $transporterId = $this->user->id;

            $rideRequests = $booking->rideRequests()
                ->where('status', RideRequest::PENDING)
                ->where('transporter_id', $transporterId)
                ->get();

            if ($rideRequests->isEmpty()) {
                return response()->json([
                    'status' => false,
                    'message' => 'No pending requests found for you in this booking.'
                ]);
            }

            foreach ($rideRequests as $req) {
                $trip = $req->trip;

                $alreadyAccepted = RideRequest::where('trip_id', $trip->id)
                    ->where('status', RideRequest::ACCEPTED)
                    ->exists();

                if ($alreadyAccepted) {
                    continue;
                }

                $req->update(['status' => RideRequest::ACCEPTED]);

                BookingRide::where('trip_id', $trip->id)
                    ->where('status', BookingRide::PENDING)
                    ->update([
                        'transporter_id' => $transporterId,
                        'status'         => BookingRide::PENDING
                    ]);

                if (!$trip->transporter_id) {
                    $trip->update([
                        'transporter_id' => $transporterId,
                        'status' => Trip::ACCEPTED,
                    ]);
                }

                RideRequest::where('trip_id', $trip->id)
                    ->where('id', '!=', $req->id)
                    ->where('status', RideRequest::PENDING)
                    ->update(['status' => RideRequest::EXPIRED]);
            }

            // if (!$booking->transporter_id) {
            //     $booking->update([
            //         'transporter_id' => $transporterId,
            //     ]);
            // }

            return response()->json([
                'status' => true,
                'message' => 'All eligible requests for this booking accepted successfully.'
            ]);
        } catch (\Illuminate\Contracts\Encryption\DecryptException $e) {
            return response()->json([
                'status'  => false,
                'message' => 'Invalid booking ID.',
            ], 400);
        } catch (\Exception $e) {
            return response()->json([
                'status' => false,
                'message' => 'Something went wrong: ' . $e->getMessage(),
            ], 500);
        }
    }


    public function rejectByBooking(Request $request, FirebaseService $service, $id)
    {
        try {
            $booking = Booking::with('rideRequests')
                ->where('id', decrypt($id))
                ->firstOrFail();

            $booking->rideRequests()
                ->where('status', RideRequest::PENDING)
                ->where('transporter_id', $this->user->id)
                ->update(['status' => RideRequest::REJECTED]);

            // $booking->update([
            //     'status' => Booking::REJECTED,
            // ]);

            return response()->json([
                'status' => true,
                'message' => 'All requests for this booking rejected successfully.'
            ]);
        } catch (\Illuminate\Contracts\Encryption\DecryptException $e) {
            return response()->json([
                'status'  => false,
                'message' => 'Invalid booking ID.',
            ], 400);
        } catch (\Exception $e) {
            return response()->json([
                'status' => false,
                'message' => 'Something went wrong: ' . $e->getMessage(),
            ], 500);
        }
    }
}