Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

MahmoudAdelAli's avatar

Booking with Splited Times Carbon to Period

Hi, my logic pertaining to two users, doctor and patient, is as follows: the doctor will set his schedule for February 20, 2024, working from 10:00 AM to 10:00 PM, totaling 12 hours for the day. The patient will select the doctor and also choose the planned hours, which could be 2, 4, 6, etc. I propose dividing the time slots between 10:00 AM and 10:00 PM into intervals based on the planned hours.

#just Example
$intervals = $plan->hours // 2
 return iterator_to_array($schedule->start_time
                ->toPeriod($schedule->end_time, $intervals, 'hours')
                ->map(function ($time) use ($intervals,$schedule,$reservation_start_time,$reservation)

#Doctor Schedule  
// example not the real table

date
start_time
end_time
doctor_id
 
#Reservations
// example not the real table
patient_id
doctor_id
date
start_time
end_time  // start_time + Plan Hours 
total
status

The issue here is if the patient has reserved time from 12 pm to 2 pm with a 2-hour plan, and another patient decides to reserve another slot from 3 pm to 6 pm. How can I determine if the schedule is booked or not and how can I prevent overlapping?

#my code logic example

 public function index($name)
    {
        $doctor = User::where('name',$name)->with(['schedules','doctorDetail'])->firstOrFail();
        $plans = Plan::get();
        $latest_available_schedule = $doctor->schedules
            ->where('status',false)
            ->where('date', '>=',Carbon::today());
        $plan = $plans->first();
        $intervals = 1;
        #ex
        $reservation = [
            'date' => "2024-02-21",
            "start_time" => "10:00",
            "plan_id" => 2, // just hours
        ];
        $reservation_start_time = Carbon::parse($reservation['start_time']);
    

        //remove reservations that are already booked

        Schedule::create([
            'doctor_id' => $doctor->id,
            'date' => $reservation['date'],
            'start_time' => $reservation_start_time->format('H:i'),
            'end_time' => $reservation_start_time->addHours($intervals)->format('H:i'),
            'status' => true,
        ]);
         change start date to end date

        $splited_to_time = $latest_available_schedule->map(function ($schedule) use ($intervals,$reservation_start_time,$reservation) {

            return iterator_to_array($schedule->start_time
                ->toPeriod($schedule->end_time, $intervals, 'hours')
                ->map(function ($time) use ($intervals,$schedule,$reservation_start_time,$reservation){
                    $startTime = Carbon::createFromFormat('H:i', $time->format('H:i'));
                    if ($reservation_start_time->between($startTime, $startTime->copy()->addHours($reservation['plan_id']))) {
                        return null;
                    }

                    return [

                        'date' => $schedule->date->format('Y-m-d'), // Format the date here
                        'start_time' => $startTime->format('H:i'),
                        'end_time' => $startTime->copy()->addHours($intervals)->format('H:i'),

                    ];
                }));
        })->groupBy('date')->map->flatten(1)->flatten(1);

        dd($splited_to_time);

        return view('clientside.pages.checkout',compact(['plans','doctor','latest_available_schedule']));

    }
0 likes
1 reply
MahmoudAdelAli's avatar

also i tried with

  $doctor = User::where('name', $name)->with(['schedules', 'doctorDetail'])->firstOrFail();
    $plans = Plan::get();
    $latest_available_schedule = $doctor->schedules
        ->where('status', false)
        ->where('date', '>=', Carbon::today());
    $plan = $plans->first();
    $intervals = 1;

    $reservation = [
        'date' => "2024-02-21",
        "start_time" => "10:00",
        "plan_id" => 2, // just hours
    ];
    $reservation_start_time = Carbon::parse($reservation['start_time']);

    // Check if the reservation overlaps with existing reservations
    foreach ($latest_available_schedule as $schedule) {
        $startTime = Carbon::createFromFormat('H:i', $schedule->start_time);
        $endTime = Carbon::createFromFormat('H:i', $schedule->end_time);
        
        // Check if the reservation overlaps with this schedule
        if ($reservation_start_time->between($startTime, $endTime)
            || $reservation_start_time->addHours($reservation['plan_id'])->between($startTime, $endTime)
            || $startTime->between($reservation_start_time, $reservation_start_time->addHours($reservation['plan_id']))
            || $endTime->between($reservation_start_time, $reservation_start_time->addHours($reservation['plan_id']))) {
            
            // If there is an overlap, return with an error or handle accordingly
            return "Overlap detected. Please choose another time slot.";
        }
    }

    // If no overlap, proceed with creating the reservation
    Schedule::create([
        'doctor_id' => $doctor->id,
        'date' => $reservation['date'],
        'start_time' => $reservation_start_time->format('H:i'),
        'end_time' => $reservation_start_time->addHours($reservation['plan_id'])->format('H:i'),
        'status' => true,
    ]);

but doesn't work correctly

Please or to participate in this conversation.