Lifetime access is $100 off. Ends this week.Join here →
Laravel

Build an Appointment Booking System With Laravel

Friend, I have already finished the appointment booking project with Laravel, which has already built its administrative panel and it is all functional, but you see, I would like to know what would be the most appropriate way to add time periods when it is time to assign the employee's schedule? I am thinking of creating a new table and making the respective relationships with the schedule table or creating new fields in the schedule table, what do you say? Could you please help me how to solve this problem to make the assignment of time periods more flexible and that the day does not matter!! thank you help me please

maykolcastro
maykolcastro
0
11
300
alex
alex
Moderator

Happy to help!

I designed the database schema around easy admin panel entry for schedules. Because we have starts_at, ends_at, monday_starts_at, monday_ends_at, tuesday_starts_at, etc, it means you're able to build a UI that has the following fields:

  • When the employee long term schedule starts (starts_at)
  • When the employee long term schedule ends (ends_at)
  • When they work Monday
  • When they work Tuesday
  • Etc

This means you just need a form to enter this once over a long period.

You could then add a separate section to the admin panel to add schedule exclusions for days/weeks/months off by adding to schedule_exclusions.

Let me know if you had something else in mind and I'm missing anything!

maykolcastro
maykolcastro

Sorry, I think I didn't explain myself well or it wasn't clear to me what you told me, sorry! Look, what I need is that once the schedules have been assigned to an employee, I also need to be able to add time slots, such as assigning a time slot for lunch time or break time. so that they are taken into account when calculating the hours of work availability, another example, if he works six days a week from nine am to five pm, he will need to add a time slot for his lunch or break for that reason. I need to see how I add one or more of a free time slot for them. So I don't know which would be the most appropriate way to create a new table, such as schedule_break, to save the time slots for your lunch or break time and take them into account when calculating your availability. Can you give me a little guide on how to achieve that, thank you.

alex
alex
Moderator

Ah, I see what you mean — so a recurring unavailability set for specific days of the week?

In this case, yes, a new table would be good. Structure it similarly to the availability table where you have the monday_starts_at columns, and then iterate over each record for the user in the ScheduleAvailability class.

Feel free to try it out in code, and if you're stuck post anything here that isn't working :)

maykolcastro
maykolcastro

I really forgive my ignorance on this subject, I tried all this week to achieve that but I couldn't, I don't know if I misunderstood you but I want you to see what I did.

look at the model:

class ScheduleSlot extends Model { use HasFactory;

protected $fillable = [
    'employee_id',
    'monday_starts_at',
    'monday_ends_at',
    'tuesday_starts_at',
    'tuesday_ends_at',
    'wednesday_starts_at',
    'wednesday_ends_at',
    'thursday_starts_at',
    'thursday_ends_at',
    'friday_starts_at',
    'friday_ends_at',
    'saturday_starts_at',
    'saturday_ends_at',
    'sunday_starts_at',
    'sunday_ends_at',
];

public function employee()
{
    return $this->belongsTo(Employee::class);
}

}

 Look at the function I built guided by subtractScheduleExclusion, look:


protected function LunchcheduleExclusion(ScheduleSlot  $exclusion)
{
      $this->periods = $this->periods->subtract(
        Period::make(
            $exclusion->starts_at,
            $exclusion->ends_at,
            Precision::MINUTE(),
            Boundaries::EXCLUDE_END()
        )
    );

}

Actually, that is one of the functions that I tried since there were many and that model is one of many that I also built, I have tried many, many forms and I couldn't achieve it. Many of them gave me an error and others simply did not exclude the hours of availability. I really tried and I am trying but I ask you, please, if you can help me, I would appreciate it very much. What I need is for employees to be able to enter their working hours. lunch whatever time it is but it applies to every day but according to the day it is added since it can vary from day to day, that is, if on Monday I add a lunch hour from 12 to 13pm, every Monday I exclude them and if Tuesday I add from 1:00 p.m. to 2:00 p.m. so that everything on Tuesdays excludes that time from availability. I don't know if you get my idea. please help me!!

maykolcastro
maykolcastro

the model

class ScheduleSlot extends Model { useHasFactory;

protected $fillable = [
    'employee_id',
    'monday_starts_at',
    'monday_ends_at',
    'tuesday_starts_at',
    'tuesday_ends_at',
    'wednesday_starts_at',
    'wednesday_ends_at',
    'thursday_starts_at',
    'thursday_ends_at',
    'friday_starts_at',
    'friday_ends_at',
    'saturday_starts_at',
    'saturday_ends_at',
    'sunday_starts_at',
    'sunday_ends_at',
];


public function employee()
{
    return $this->belongsTo(Employee::class);
}

public function getLunchHoursForDate(Carbon $date)
{
    $hours = array_filter([
        $this->{strtolower($date->format('l')) . '_starts_at'},
        $this->{strtolower($date->format('l')) . '_ends_at'},
    ]);

    return empty($hours) ? null : $hours;
}

}

maykolcastro
maykolcastro

next part of the function and called it on forPeriod

// the function

protected function subtractLunchScheduleExclusion(Carbon $date)
{
    if (!$scheduleslot = $this->employee->scheduleslots->where('starts_at', '<=', $date)->where('ends_at', '>=', $date)->first( )) {
        return;
    }

    if (![$startsAt, $endsAt] = $scheduleslot->getLunchHoursForDate($date)) {
        return;
    }

    $this->periods = $this->periods->subtract(
        Period::make(
            $date->copy()->setTimeFromTimeString($startsAt),
            $date->copy()->setTimeFromTimeString($endsAt)->subMinutes($this->service->duration),
            Precision::MINUTE(),
            Boundaries::EXCLUDE_END()
        )
    );
}

I call it in the forPeriod function and it doesn't give me an error but it doesn't exclude availability hours, can you help me? Please if you have any way to achieve this I would greatly appreciate it!

alex
alex
Moderator

Thanks for the additional details. Looking into this for you and I'll get back to you soon!

maykolcastro
maykolcastro

Friend, have you found anything on the subject? You know another way I've seen others use is this look at BusinessTime::enable(Carbon::class, [ 'monday' => ['09:00-12:00', '13:00-18:00'], 'tuesday' => ['09:00-12:00', '13:00-18:00'], 'wednesday' => ['09:00-12:00'], 'thursday' => ['09:00-12:00', '13:00-18:00'], 'friday' => ['09:00-12:00', '13:00-20:00'], 'saturday' => ['09:00-12:00', '13:00-16:00'], ]); They define their schedule but leaving a space of 12 to 13, I don't know if that is another way.

maykolcastro
maykolcastro

friend, were you able to find out something? Try to apply the ScheduleExclusion logic which instead of entering a specific date, add the time for a day as in schedules, for example monday_starts_at', monday_ends_at', thus in the function select the days Mondays to eliminate the time from the period. I tried several ways but it didn't work for me: (..

alex
alex
Moderator

Sorry, not had much time to at the moment. I’ll get around to it!

Also, do you have your repository on GitHub? It might be helpful if I’m able to directly work with the code.

maykolcastro
maykolcastro

Thanks mate! I will be careful!