File: /var/www/html/dashboard.orbiwheels.com/app/Http/Controllers/Admin/BookingController.php
<?php
namespace App\Http\Controllers\Admin;
use App\DataTables\Admin\BookingDataTable;
use App\DataTables\Admin\BookingEnquiriesDataTable;
use App\DataTables\Admin\BookingRidesDataTable;
use App\Http\Controllers\Controller;
use App\Models\Booking;
use App\Models\BookingRide;
use App\Models\Customer;
use App\Models\Transporter;
use App\Models\Trip;
use App\Models\VehicleType;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
class BookingController extends Controller
{
public function index(BookingDataTable $dataTable)
{
return $dataTable->render('admin.booking.index');
}
public function enquiries_index(BookingEnquiriesDataTable $dataTable)
{
return $dataTable->render('admin.booking.enquiries');
}
public function oldview($id)
{
$booking = Booking::with(['rides.driver', 'transporter', 'customer'])->findOrFail(decrypt($id));
return view('admin.booking.view', compact('booking'));
}
public function view($id, BookingRidesDataTable $dataTable)
{
$booking = Booking::findOrFail(decrypt($id));
return $dataTable
->with('bookingId', $id)
->render('admin.booking.view', compact('booking'));
}
public function getRides($id, BookingRidesDataTable $dataTable)
{
$bookingId = decrypt($id);
return $dataTable->with('bookingId', $bookingId)->ajax();
}
public function create()
{
$vehicleTypes = VehicleType::all();
$customers = Customer::all();
$transporters = Transporter::where('status', 1)->get();
return view('admin.booking.create', compact('vehicleTypes', 'transporters', 'customers'));
}
public function store(Request $request)
{
try {
$validator = Validator::make($request->all(), [
'customer_id' => 'required|integer|exists:customers,id',
'transporter_id' => 'nullable|integer|exists:transporters,id',
'ride_type' => 'required|in:1,2,3,4,5,6',
'booking_type' => 'required|in:1,2',
'trips' => 'required|array|min:1',
'trips.*.vehicle_type' => 'required|integer|exists:vehicle_types,id',
'trips.*.pickup_location' => 'required|string|max:255',
'trips.*.pickup_lat' => 'required|numeric',
'trips.*.pickup_lng' => 'required|numeric',
'trips.*.drop_location' => 'required|string|max:255',
'trips.*.drop_lat' => 'required|numeric',
'trips.*.drop_lng' => 'required|numeric',
'trips.*.pickup_time' => 'required|date_format:H:i',
'trips.*.return_time' => 'nullable|date_format:H:i|required_if:booking_type,2',
'trips.*.dates' => 'required|string',
]);
if ($validator->fails()) {
return back()->withErrors($validator)->withInput();
}
// Step 1: Create Booking
$booking = Booking::create([
'customer_id' => $request->customer_id,
'ride_type' => $request->ride_type,
'booking_type' => $request->booking_type,
'no_of_passengers' => 1,
'status' => $request->transporter_id ? BookingRide::ASSIGNED : BookingRide::PENDING,
'total_customer_amount'=> 0,
'transporter_id' => $request->transporter_id ?? '',
]);
$finalBookingTotal = 0;
// Step 2: Loop Trips
foreach ($request->trips as $tripData) {
// Convert dates string → array
$datesArray = explode(", ", $tripData['dates']);
$vehicleType = VehicleType::findOrFail($tripData['vehicle_type']);
$distance = getDistance(
$tripData['pickup_lat'],
$tripData['pickup_lng'],
$tripData['drop_lat'],
$tripData['drop_lng']
);
$fare = getFare($distance, $vehicleType, "city");
$commission = getCommission($distance);
$gst = get_gst_on_commission($commission);
// Create Trip (one trip = many rides)
$trip = Trip::create([
'booking_id' => $booking->id,
'transporter_id' => $request->transporter_id ?? '',
'vehicle_type_id' => $vehicleType->id,
'ride_type' => $request->ride_type,
'booking_type' => $request->booking_type,
'dates' => $datesArray,
'times' => [
'pickup_time' => $tripData['pickup_time'],
'return_time' => $tripData['return_time'] ?? null,
],
'locations' => [
'pickup_location' => $tripData['pickup_location'],
'pickup_lat' => $tripData['pickup_lat'],
'pickup_lng' => $tripData['pickup_lng'],
'drop_location' => $tripData['drop_location'],
'drop_lat' => $tripData['drop_lat'],
'drop_lng' => $tripData['drop_lng'],
],
'pricing_details' => [],
'distance_km' => $distance,
'status' => '0',
]);
// Trip totals
$tripFare = 0;
$tripCommission = 0;
$tripGst = 0;
$tripTotal = 0;
// Step 3: Create rides for each date inside Trip
foreach ($datesArray as $date) {
// ---- Onward ride ----
$onward = $booking->rides()->create([
'trip_id' => $trip->id,
'transporter_id' => $request->transporter_id ?? '',
'vehicle_type_id' => $vehicleType->id,
'locations' => $trip->locations,
'ride_date' => $date,
'pickup_time' => $tripData['pickup_time'],
'ride_slot' => getTimeSlot($tripData['pickup_time']),
'distance_km' => $distance,
'fare' => $fare,
'ride_commission' => $commission,
'gst_on_commission' => $gst,
'total_customer_amount' => $fare + $commission + $gst,
]);
$tripFare += $fare;
$tripCommission += $commission;
$tripGst += $gst;
$tripTotal += ($fare + $commission + $gst);
// ---- Return Ride (only for booking_type = 2) ----
if ($request->booking_type == 2 && !empty($tripData['return_time'])) {
$returnLocations = [
'pickup_location' => $tripData['drop_location'],
'pickup_lat' => $tripData['drop_lat'],
'pickup_lng' => $tripData['drop_lng'],
'drop_location' => $tripData['pickup_location'],
'drop_lat' => $tripData['pickup_lat'],
'drop_lng' => $tripData['pickup_lng'],
];
$return = $booking->rides()->create([
'trip_id' => $trip->id,
'transporter_id' => $request->transporter_id ?? '',
'vehicle_type_id' => $vehicleType->id,
'locations' => $returnLocations,
'ride_date' => $date,
'pickup_time' => $tripData['return_time'],
'ride_slot' => getTimeSlot($tripData['return_time']),
'distance_km' => $distance,
'fare' => $fare,
'ride_commission' => $commission,
'gst_on_commission' => $gst,
'total_customer_amount' => $fare + $commission + $gst,
]);
$tripFare += $fare;
$tripCommission += $commission;
$tripGst += $gst;
$tripTotal += ($fare + $commission + $gst);
}
}
// Save totals in Trip
$trip->update([
'pricing_details' => [
'fare' => $tripFare,
'commission' => $tripCommission,
'gst' => $tripGst,
'total_amount' => $tripTotal,
]
]);
$finalBookingTotal += $tripTotal;
}
// Step 4: Update Booking Final Total
$booking->update([
'total_customer_amount' => $finalBookingTotal
]);
return redirect()
->route('admin.booking.index')
->with('success', 'Booking created successfully!');
} catch (\Exception $e) {
return back()->with('error', $e->getMessage());
}
}
public function edit($id)
{
$booking = Booking::with(['trips','rides.driver', 'transporter', 'customer'])->findOrFail($id);
$vehicleTypes = VehicleType::all();
$customers = Customer::all();
$transporters = Transporter::where('status', 1)->get();
return view('admin.booking.edit', compact('booking', 'vehicleTypes','customers','transporters'));
}
public function update(Request $request, $id)
{
// dd($request->all());
try {
$validator = Validator::make($request->all(), [
'ride_type' => 'required|in:1,2,3,4,5,6',
'booking_type' => 'required|in:1,2',
'trips' => 'required|array|min:1',
'trips.*.vehicle_type' => 'required|integer|exists:vehicle_types,id',
'trips.*.pickup_location' => 'required|string|max:255',
'trips.*.pickup_lat' => 'required|numeric',
'trips.*.pickup_lng' => 'required|numeric',
'trips.*.drop_location' => 'required|string|max:255',
'trips.*.drop_lat' => 'required|numeric',
'trips.*.drop_lng' => 'required|numeric',
'trips.*.pickup_time' => 'required|date_format:H:i',
'trips.*.return_time' => 'nullable|date_format:H:i|required_if:booking_type,2',
'trips.*.dates' => 'required|string',
]);
if ($validator->fails()) {
return back()->withErrors($validator)->withInput();
}
$booking = Booking::findOrFail($id);
$booking->rides()->delete();
$booking->trips()->delete();
$booking->update([
'ride_type' => $request->ride_type,
'booking_type' => $request->booking_type,
'vehicle_preferred' => null,
]);
$finalBookingTotal = 0;
foreach ($request->trips as $tripData) {
$datesArray = explode(", ", $tripData['dates']);
$vehicleType = VehicleType::findOrFail($tripData['vehicle_type']);
$distance = getDistance(
$tripData['pickup_lat'],
$tripData['pickup_lng'],
$tripData['drop_lat'],
$tripData['drop_lng']
);
$fare = getFare($distance, $vehicleType, "city");
$commission = getCommission($distance);
$gst = get_gst_on_commission($commission);
$trip = Trip::create([
'booking_id' => $booking->id,
'transporter_id' => $request->transporter_id ?? '',
'vehicle_type_id' => $vehicleType->id,
'ride_type' => $request->ride_type,
'booking_type' => $request->booking_type,
'dates' => $datesArray,
'times' => [
'pickup_time' => $tripData['pickup_time'],
'return_time' => $tripData['return_time'] ?? null,
],
'locations' => [
'pickup_location' => $tripData['pickup_location'],
'pickup_lat' => $tripData['pickup_lat'],
'pickup_lng' => $tripData['pickup_lng'],
'drop_location' => $tripData['drop_location'],
'drop_lat' => $tripData['drop_lat'],
'drop_lng' => $tripData['drop_lng'],
],
'pricing_details' => [],
'distance_km' => $distance,
'status' => '0',
]);
$tripFare = 0;
$tripCommission = 0;
$tripGst = 0;
$tripTotal = 0;
foreach ($datesArray as $date) {
$booking->rides()->create([
'trip_id' => $trip->id,
'transporter_id' => $request->transporter_id ?? '',
'vehicle_type_id' => $vehicleType->id,
'locations' => $trip->locations,
'ride_date' => $date,
'pickup_time' => $tripData['pickup_time'],
'ride_slot' => getTimeSlot($tripData['pickup_time']),
'distance_km' => $distance,
'fare' => $fare,
'ride_commission' => $commission,
'gst_on_commission' => $gst,
'total_customer_amount' => $fare + $commission + $gst,
]);
$tripFare += $fare;
$tripCommission += $commission;
$tripGst += $gst;
$tripTotal += ($fare + $commission + $gst);
if ($request->booking_type == 2 && !empty($tripData['return_time'])) {
$returnLocations = [
'pickup_location' => $tripData['drop_location'],
'pickup_lat' => $tripData['drop_lat'],
'pickup_lng' => $tripData['drop_lng'],
'drop_location' => $tripData['pickup_location'],
'drop_lat' => $tripData['pickup_lat'],
'drop_lng' => $tripData['pickup_lng'],
];
$booking->rides()->create([
'trip_id' => $trip->id,
'transporter_id' => $request->transporter_id ?? '',
'vehicle_type_id' => $vehicleType->id,
'locations' => $returnLocations,
'ride_date' => $date,
'pickup_time' => $tripData['return_time'],
'ride_slot' => getTimeSlot($tripData['return_time']),
'distance_km' => $distance,
'fare' => $fare,
'ride_commission' => $commission,
'gst_on_commission' => $gst,
'total_customer_amount' => $fare + $commission + $gst,
]);
$tripFare += $fare;
$tripCommission += $commission;
$tripGst += $gst;
$tripTotal += ($fare + $commission + $gst);
}
}
$trip->update([
'pricing_details' => [
'fare' => $tripFare,
'commission' => $tripCommission,
'gst' => $tripGst,
'total_amount' => $tripTotal,
]
]);
$finalBookingTotal += $tripTotal;
}
$booking->update([
'total_customer_amount' => $finalBookingTotal
]);
return redirect()->route('admin.booking.index')->with('success', 'Booking updated successfully!');
} catch (\Exception $e) {
return back()->with('error', $e->getMessage());
}
}
public function search(Request $request)
{
$query = $request->get('q');
$transporters = Transporter::query()
->when($query, function ($q) use ($query) {
$q->where('company_name', 'like', "%{$query}%")
->orWhere('first_name', 'like', "%{$query}%")
->orWhere('last_name', 'like', "%{$query}%")
->orWhere('email', 'like', "%{$query}%")
->orWhere('phone', 'like', "%{$query}%");
})
->limit(10)
->get();
return response()->json($transporters);
}
public function assignTransporter(Request $request, $id)
{
$request->validate([
'transporter_id' => 'required|exists:transporters,id',
]);
$booking = Booking::with('trips.bookingRides')->findOrFail($id);
$booking->update([
'transporter_id' => $request->transporter_id
]);
$booking->trips()->update([
'transporter_id' => $request->transporter_id
]);
foreach ($booking->trips as $trip) {
$trip->bookingRides()->update([
'transporter_id' => $request->transporter_id
]);
}
return response()->json([
'status' => true,
'message' => 'Transporter updated for Booking, Trips, and Rides!',
]);
}
public function assignTransporterByTrip(Request $request, $id)
{
$trip = Trip::findOrFail($id);
$transporterId = $request->transporter_id;
if (!$trip->transporter_id) {
$trip->update([
'transporter_id' => $transporterId,
'status' => Trip::ACCEPTED,
]);
$trip->bookingRides()->update([
'transporter_id' => $transporterId,
]);
return response()->json([
'status' => true,
'message' => 'Transporter assigned successfully!',
]);
}
return response()->json([
'status' => false,
'message' => 'This trip already has a transporter assigned.',
]);
}
}