I'm not sure I fully understand your requirement, but I did something
similar recently where I need to calculate the first available time slot
for a service for a given staff and create an appointment for that time
slot if the customer wants it. The staff model in this case has
the availability against it (start and end time for the working day) and
the service is a specified half hour or one hour block or whatever the
admin sets it to be. Staff also has days and hours when they're away which
people can't book in ExceptionAvailability. Appointment is what gets
created when the available slot is found.

Below is the function I used. The code may not look the best but it does
work. :) I hope you can get something out of it:



def find_slot_inside_availability(utc_start_time,
utc_availability_end_time, duration, staff):
    utc_end_time = utc_start_time + datetime.timedelta(minutes=duration)

    # When this function is called lets make sure there's enough time left
in the current availability (given the start_time we want)
    if utc_end_time > utc_availability_end_time:
        return None

    # Check we aren't in the middle of a blocked out time for the staff in
question
    try:
        block_out_time = ExceptionAvailability.objects.get(staff = staff,
start_datetime__lt=utc_start_time, end_datetime__gt=utc_start_time)
    except ExceptionAvailability.DoesNotExist:

        # Check there are no blockouts starting before end of duration
        possible_block_out_times =
ExceptionAvailability.objects.filter(staff=staff,
start_datetime__lt=utc_end_time,
start_datetime__gte=utc_start_time).order_by('-end_datetime')
        if not possible_block_out_times:
            # If we're here it means we can start checking for appointments
inside this spot
            try:
                overlapping_appointment =
Appointment.objects.get(staffProfile=staff, deletion_date__isnull=True,
start_time__lt=utc_start_time, end_time__gt=utc_end_time)
            except Appointment.DoesNotExist:
                # Check for any appointments starting within the block we
want
                possible_overlapping_appointments =
Appointment.objects.filter(staffProfile=staff, deletion_date__isnull=True,
start_time__lt=utc_end_time,
start_time__gte=utc_start_time).order_by('-end_time')
                if not possible_overlapping_appointments:
                    return utc_start_time ### HURRAH we've found an
unencumbered slot!
                else:
                    # move to end of last overlapping appointment and run
the algo again
                    new_possible_start_time =
possible_overlapping_appointments[0].end_time.replace(tzinfo=pytz.UTC)
            else:
                # Move to end of appointment and try again
                new_possible_start_time =
overlapping_appointment.end_time.replace(tzinfo=pytz.UTC)
        else:
            # there are blockages, move to the end of the last
possible_block_out_time and try it again (after comparing against
availability_end_time
            new_possible_start_time =
possible_block_out_times[0].end_datetime.replace(tzinfo=pytz.UTC)
    else:
        # Move to end of block out time and check it against
availability_end_time
        new_possible_start_time =
block_out_time.end_datetime.replace(tzinfo=pytz.UTC)
    return find_slot_inside_availability(new_possible_start_time,
utc_availability_end_time, duration, staff)


On 22 January 2013 03:16, Tijmen <tijmen.vandenbr...@gmail.com> wrote:

> Hi,
>
> I would like to calculate the availability of a service which holds zero
> or more events. The model looks like this:
>
> class Service(models.Model):
>     name = models.CharField(max_length=75)
>
> class Event(models.Model):
>     event_class = models.CharField(max_length=75)
>     service = models.ForeignKey(Service)
>     start = models.DateTimeField()
>     end = models.DateTimeField()
>
> What approach would you take to be able to supply a certain timeframe
> (e.g. start = 01-01-2013 00:00, end = 02-01-2013 00:00) and the
> availability gets calculated over that exact timeframe. I identified two
> problems here:
>
> 1. When you get the events that match a certain timeframe (with the range
> filter) events are excluded matching the following criteria:
>          - start before the timeframe but end within the timeframe -
>          or
>          - start within the timeframe but end after the timeframe -
>
> 2. If we were able to get these events we don't want to take into account
> the time that is not within the timeframe as it would mess up our
> calculation. So we need to reset the start and or endtime.
>
> Any ideas on how to accomplish this?
>
> Thanks
>
>
>
>  --
> You received this message because you are subscribed to the Google Groups
> "Django users" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/django-users/-/YA2pMVCiBWUJ.
> To post to this group, send email to django-users@googlegroups.com.
> To unsubscribe from this group, send email to
> django-users+unsubscr...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/django-users?hl=en.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com.
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en.

Reply via email to