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);
}
}
}