Try this:
if ($request->filled('start_datetime', 'end_datetime')) {
$start_datetime = $request->date('start_datetime', 'Y-m-d H:i');
$end_datetime = $request->date('end_datetime', 'Y-m-d H:i');
$query->where(fn ($query) => $query
->whereDoesntHave('vehicle_rentals')
->orWhereHas('vehicle_rentals', fn ($q) => $q
->whereHas('vehicle_rental_time', fn ($subQ) => $subQ
->orWhere('booking_end_datetime', '<', $start_datetime)
->orWhere('booking_start_datetime', '>', $end_datetime)
)
)
);
}
The main change was to use ->orWhere(...) on the deepest subquery.
All other changes were cosmetic or simplifications.
The OR is needed because before it reads:
Give me all rentals that started and ended before
start_datetimeAND started and ended afterend_datetime
Assuming start_datetime happened before end_datetime this condition would never be true.
I simplified this part to this:
Give me all rentals that ended before
start_datetimeOR started afterend_datetime
If your database has booking_start_datetime always before booking_end_datetime, you don't need to check both start and end dates on each condition.
Hope this helps.