File: /var/www/html/dashboard.orbiwheels.com/app/Http/Controllers/Api/Customer/BookingController.php
<?php
namespace App\Http\Controllers\Api\Customer;
use App\Http\Controllers\Controller;
use App\Http\Resources\BookingResource;
use App\Mail\BookingEnquiryMail;
use App\Mail\UserBookingEnquiryMail;
use App\Models\Booking;
use App\Models\BookingEnquiry;
use App\Models\RideRequest;
use App\Models\Transporter;
use App\Models\Trip;
use App\Models\VehicleType;
use App\Services\FirebaseService;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Kreait\Firebase\Factory;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Mail;
class BookingController extends Controller
{
public function oldcreateBooking(Request $request)
{
try {
$validator = Validator::make($request->all(), [
'ride_type' => 'required|in:1,2,3,4,5',
'booking_type' => 'required|in:1,2',
'dates.from_date' => 'required|date',
'dates.to_date' => 'required|date|after_or_equal:dates.from_date',
'trips' => 'required|array|min:1',
'trips.*.vehicle_type' => 'required|integer',
'trips.*.quantity' => 'required|integer|min:1',
'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',
]);
if ($validator->fails()) {
return response()->json([
'status' => false,
'errors' => $validator->errors()
], 422);
}
// dd($request->all());
$booking = Booking::create([
'customer_id' => auth()->user()->id,
'ride_type' => $request->ride_type,
'booking_type' => $request->booking_type,
'no_of_passengers' => $request->no_of_passengers ?? 1,
'dates' => $request->dates,
'times' => $request->times,
'status' => Booking::PENDING,
'total_customer_amount' => 0,
]);
$fromDate = Carbon::parse($request->dates['from_date']);
$toDate = Carbon::parse($request->dates['to_date']);
$total_customer_amount = 0;
foreach ($request->trips as $trip) {
$vehicle_type = VehicleType::findOrFail($trip['vehicle_type']);
$distance_km = getDistance(
$trip['pickup_lat'],
$trip['pickup_lng'],
$trip['drop_lat'],
$trip['drop_lng']
);
$fare = getFare($distance_km, $vehicle_type, "city");
$commission = getCommission($distance_km);
$gst = get_gst_on_commission($commission);
for ($date = $fromDate->copy(); $date->lte($toDate); $date->addDay()) {
for ($i = 1; $i <= $trip['quantity']; $i++) {
// Create onward ride
$booking->rides()->create([
'vehicle_type_id' => $vehicle_type->id,
'locations' => [
'pickup_location' => $trip['pickup_location'],
'pickup_lat' => $trip['pickup_lat'],
'pickup_lng' => $trip['pickup_lng'],
'drop_location' => $trip['drop_location'],
'drop_lat' => $trip['drop_lat'],
'drop_lng' => $trip['drop_lng'],
],
'ride_date' => $date->format('Y-m-d'),
'pickup_time' => $trip['pickup_time'],
'ride_slot' => getTimeSlot($trip['pickup_time']),
'distance_km' => $distance_km,
'fare' => $fare,
'ride_commission' => $commission,
'gst_on_commission' => $gst,
'total_customer_amount' => $fare + $commission + $gst,
]);
$total_customer_amount += ($fare + $commission + $gst);
// Create return ride if booking_type = 2
if ($request->booking_type == 2) {
$booking->rides()->create([
'vehicle_type_id' => $vehicle_type->id,
'locations' => [
'pickup_location' => $trip['drop_location'],
'pickup_lat' => $trip['drop_lat'],
'pickup_lng' => $trip['drop_lng'],
'drop_location' => $trip['pickup_location'],
'drop_lat' => $trip['pickup_lat'],
'drop_lng' => $trip['pickup_lng'],
],
'ride_date' => $date->format('Y-m-d'),
'pickup_time' => $trip['return_time'],
'ride_slot' => getTimeSlot($trip['return_time']),
'distance_km' => $distance_km,
'fare' => $fare,
'ride_commission' => $commission,
'gst_on_commission' => $gst,
'total_customer_amount' => $fare + $commission + $gst,
]);
$total_customer_amount += ($fare + $commission + $gst);
}
}
}
}
$rides = $booking->rides;
$booking->update([
'base_rate_per_km' => $rides->sum('fare'), // total base fare
'commission_per_km' => $rides->sum('ride_commission'), // total commission
'gst_on_commission' => $rides->sum('gst_on_commission'), // total gst
'total_customer_amount' => $total_customer_amount,
]);
return response()->json([
'status' => true,
'message' => 'Booking created successfully!',
'booking' => new BookingResource($booking)
]);
} catch (\Exception $e) {
return response()->json(['status' => false, 'error' => $e->getMessage()], 500);
}
}
public function createBooking(Request $request)
{
try {
$validator = Validator::make($request->all(), [
'ride_type' => 'required|in:1,2,3,4,5',
'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|array|min:1',
]);
if ($validator->fails()) {
return response()->json([
'status' => false,
'errors' => $validator->errors()
], 422);
}
// STEP 1: Create booking
$booking = Booking::create([
'customer_id' => auth()->user()->id,
'ride_type' => $request->ride_type,
'booking_type' => $request->booking_type,
'no_of_passengers' => $request->no_of_passengers ?? 1,
'status' => Booking::PENDING,
'total_customer_amount' => 0,
]);
$total_customer_amount = 0;
// STEP 2: Create trips under booking
foreach ($request->trips as $tripData) {
$vehicleType = VehicleType::findOrFail($tripData['vehicle_type']);
$distance_km = getDistance(
$tripData['pickup_lat'],
$tripData['pickup_lng'],
$tripData['drop_lat'],
$tripData['drop_lng']
);
$fare = getFare($distance_km, $vehicleType, "city");
$commission = getCommission($distance_km);
$gst = get_gst_on_commission($commission);
// Save trip
$trip = Trip::create([
'booking_id' => $booking->id,
'vehicle_type_id' => $vehicleType->id,
'ride_type' => $request->ride_type,
'booking_type' => $request->booking_type,
'dates' => $tripData['dates'],
'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_km,
'status' => '0',
]);
$totalFare = 0;
$totalCommission = 0;
$totalGst = 0;
$totalAmount = 0;
// STEP 3: Create rides for each date
foreach ($tripData['dates'] as $date) {
$onward = $booking->rides()->create([
'trip_id' => $trip->id,
'vehicle_type_id' => $vehicleType->id,
'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'],
],
'ride_date' => $date,
'pickup_time' => $tripData['pickup_time'],
'ride_slot' => getTimeSlot($tripData['pickup_time']),
'distance_km' => $distance_km,
'fare' => $fare,
'ride_commission' => $commission,
'gst_on_commission' => $gst,
'total_customer_amount' => $fare + $commission + $gst,
]);
$totalFare += $fare;
$totalCommission += $commission;
$totalGst += $gst;
$totalAmount += ($fare + $commission + $gst);
// Return ride (if booking_type = 2)
if ($request->booking_type == 2 && !empty($tripData['return_time'])) {
$return = $booking->rides()->create([
'trip_id' => $trip->id,
'vehicle_type_id' => $vehicleType->id,
'locations' => [
'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'],
],
'ride_date' => $date,
'pickup_time' => $tripData['return_time'],
'ride_slot' => getTimeSlot($tripData['return_time']),
'distance_km' => $distance_km,
'fare' => $fare,
'ride_commission' => $commission,
'gst_on_commission' => $gst,
'total_customer_amount' => $fare + $commission + $gst,
]);
$totalFare += $fare;
$totalCommission += $commission;
$totalGst += $gst;
$totalAmount += ($fare + $commission + $gst);
}
}
// rides ke totals Trip ke andar save karo
$trip->update([
'pricing_details' => [
'fare' => $totalFare,
'commission' => $totalCommission,
'gst' => $totalGst,
'total_amount' => $totalAmount,
]
]);
}
// STEP 4: Update booking totals
// $rides = $booking->rides;
// $booking->update([
// 'base_rate_per_km' => $rides->sum('fare'),
// 'commission_per_km' => $rides->sum('ride_commission'),
// 'gst_on_commission' => $rides->sum('gst_on_commission'),
// 'total_customer_amount' => $total_customer_amount,
// ]);
return response()->json([
'status' => true,
'message' => 'Booking created successfully!',
'booking' => new BookingResource($booking)
]);
} catch (\Exception $e) {
return response()->json(['status' => false, 'error' => $e->getMessage()], 500);
}
}
public function confirmBooking(Request $request, $id)
{
try {
$booking = Booking::findOrFail($id);
foreach ($booking->trips as $trip) {
$transporters = Transporter::where('status', Transporter::APPROVED)
->where('mode', 1)
->whereJsonContains('ride_permissions', $booking->ride_type)
->get();
foreach ($transporters as $transporter) {
RideRequest::create([
'booking_id' => $booking->id,
'trip_id' => $trip->id,
'transporter_id' => $transporter->id,
'status' => RideRequest::PENDING,
]);
// Optional: Push request to Firebase
// $service->pushRequest($transporter, $booking, $ride);
}
}
// Update booking status
$booking->update(['status' => Booking::REQUESTED]);
return response()->json([
'status' => true,
'message' => 'Booking requested successfully! Ride requests sent to transporters.',
'booking' => $booking
]);
} catch (ModelNotFoundException $e) {
return response()->json(['status' => false, 'error' => 'Booking not found'], 404);
} catch (\Exception $e) {
return response()->json(['status' => false, 'error' => $e->getMessage()], 500);
}
}
public function draftBooking(Request $request, $id)
{
try {
$booking = Booking::findOrFail($id);
$validator = Validator::make($request->all(), [
'is_draft' => 'required|boolean',
]);
if ($validator->fails()) {
return response()->json([
'status' => false,
'errors' => $validator->errors()
], 422);
}
$booking->update([
'is_draft' => $request->is_draft,
]);
return response()->json([
'status' => true,
'message' => $request->is_draft
? 'Booking saved as draft successfully!'
: 'Booking removed from draft!',
'booking' => $booking
]);
} catch (ModelNotFoundException $e) {
return response()->json(['status' => false, 'error' => 'Booking not found'], 404);
} catch (\Exception $e) {
return response()->json(['status' => false, 'error' => $e->getMessage()], 500);
}
}
public function booking_enquiry_store(Request $request)
{
try {
$validator = Validator::make($request->all(), [
'name' => 'required|string|max:255',
'email' => 'required|email|max:255',
'phone' => 'required|string|max:20',
'pick_up_location' => 'required|string|max:255',
'drop_up_location' => 'required|string|max:255',
'pick_up_date' => 'required|date',
'pick_up_time' => 'required',
'vehicle_preference' => 'required|string|max:255',
'details' => 'required|string|min:5',
]);
if ($validator->fails()) {
return response()->json([
'status' => 'error',
'errors' => $validator->errors()
], 422);
}
$enquiry = BookingEnquiry::create($request->all());
try {
Mail::to(config('mail.from.address'))
->send(new BookingEnquiryMail($enquiry));
Mail::to($enquiry->email)
->send(new UserBookingEnquiryMail($enquiry));
} catch (\Exception $mailException) {
Log::error('Booking enquiry mail failed', [
'error' => $mailException->getMessage(),
'enquiry' => $enquiry->id,
]);
}
return response()->json([
'status' => 'success',
'message' => 'Booking enquiry submitted successfully!',
'data' => $enquiry
]);
} catch (\Exception $e) {
Log::error('Booking enquiry store error', [
"message" => $e->getMessage()
]);
return response()->json([
'status' => 'error',
'message' => 'Something went wrong!'
], 500);
}
}
}