Чтобы узнать доступные даты, вам необходимо 1) диапазон дат, которые следует учитывать, и 2) недоступные даты.Затем вы сравниваете их.
Вы можете создать таблицу календаря в вашей базе данных со всеми датами на следующие x лет, сохраненные в ней, а затем просто сравнить это с вашими заказами.Или вы можете сделать это на PHP, например, так:
$availableDates['morning'] = iterator_to_array(new DatePeriod(
new DateTime('2019-01-01'),
new DateInterval('P1D'),
new DateTime('2019-12-31')
));
$availableDates['afternoon'] = $availableDates['morning'];
$unavailableDates = [];
foreach(Booking::where('category_id', $category_id)->get() as $booking) {
$unavailableDates[$booking->booking_time] += iterator_to_array(new DatePeriod(
new DateTime($booking->date_from),
new DateInterval('P1D'),
new DateTime($booking->date_to)
));
}
function compareDates(DateTime $a, DateTime $b) { return $a->getTimestamp() - $b->getTimestamp(); }
$available['morning'] = array_udiff($availableDates['morning'],$unavailableDates,'compareDates');
$available['afternoon'] = array_udiff($availableDates['afternoon'],$unavailableDates,'compareDates');
Вероятно, есть некоторая эффективность, которую вы могли бы получить, вырезав пару циклов, но это должно помочь вам начать.