Beispiel #1
0
    def validate_python(self, field_dict, state):
        from hubspace.controllers import unavailable_for_booking
        resource = Resource.get(field_dict['resource_id'])
        resourceid = resource.id
        if not resource.time_based:
            return

        if 'start' in field_dict:
            start = field_dict['start']
            start_time = time(int(start['hour']), int(start['minute']))
            date = dateconverter.to_python(field_dict['date'])
            start = datetime.combine(date, start_time)
        elif 'start_datetime' in field_dict:
            start = datetimeconverter.to_python(field_dict['start_datetime'])
        else:
            start = now(resource.place)
            
        if 'end' in field_dict:
            end = field_dict['end']
            end_time = time(int(end['hour']), int(end['minute']))
            date = dateconverter.to_python(field_dict['date'])
            end = datetime.combine(date, end_time)
        elif 'end_datetime' in field_dict:
            end = datetimeconverter.to_python(field_dict['end_datetime'])
        else:
            end = start + timedelta(minutes=15)
       
        errors = {}
            
        rusage = None
        if 'id' in field_dict:
            rusage = field_dict['id']

        booking_conflicts = unavailable_for_booking(resourceid, start, end, rusage)
        dfp = datetimeconverter.from_python
 
        if booking_conflicts.count():
            conflict = booking_conflicts[0]
            if resource == conflict.resource:
                errors['start'] =  escape(resource.name) + " cannot be booked from " + dfp(start) + " to "+ dfp(end) + " since it is booked from " + dfp(conflict.start) + " to " + dfp(conflict.end_time)
            else:
                errors['start'] =  escape(resource.name) + " cannot be booked from " + dfp(start) + " to "+ dfp(end) + " since it requires " + escape(conflict.resource.name)+ " which is booked from " + dfp(conflict.start) + " to " + dfp(conflict.end_time)
            raise Invalid('Booking Conflicts', field_dict, state, error_dict=errors)
Beispiel #2
0
def get_week_overlaps(date, resources_order):
    """get a data structure which summarizes the overlaping if events in a resource group. This is used for rendering initially and should be returned as json in order to dynamically re-render 
    """
    week_starts = date - timedelta(days=date.weekday())
    day = week_starts
    week_ends = week_starts + timedelta(days=7)
    rusages = list(RUsage.select(AND(IN(RUsage.q.resourceID, resources_order),
                                     RUsage.q.start>=week_starts,
                                     RUsage.q.end_time<=week_ends)).orderBy('start'))
    conflicting_rusages = []
    for res_id in resources_order:
        conflicting_rusages += [AttrDict(id=str(conflict.id)+'-'+str(res_id),
                                         start = conflict.start,
                                         end_time = conflict.end_time) for conflict in unavailable_for_booking(res_id, week_starts, week_ends, ignore_current_res=True)]
        
        
    rusages += conflicting_rusages
    rusages.sort(lambda x,y:cmp(x.start, y.start))
    rusages = list(rusages)
    overlaps_and_index = {}
    current = 0
    while day<=week_ends:
        day = day + timedelta(days=1)
        position_indices = []
        while current<len(rusages) and rusages[current].start<=day:
            for rusage in position_indices:
                if rusage and rusage.end_time <= rusages[current].start:
                    position_indices[position_indices.index(rusage)] = None
            try:
                position_indices[position_indices.index(None)] = rusages[current]
            except ValueError:
                position_indices.append(rusages[current])

            index = position_indices.index(rusages[current])
            look_ahead = 0
            overlaps = 1
            current_overlaps = []
            while look_ahead<len(rusages) and rusages[look_ahead].start<rusages[current].end_time:
                if rusages[look_ahead].end_time<=rusages[current].start:
                    look_ahead += 1
                    continue
                if look_ahead==current:
                    look_ahead += 1
                    continue
                #the look_ahead  current and ends after the current starts => we must add it to the current_overlaps list
                current_overlaps.append(rusages[look_ahead])
                to_remove = []
                for overlap in current_overlaps:
                    if overlap.end_time <= rusages[look_ahead].start:
                        to_remove.append(overlap)
                for remove in to_remove:
                    current_overlaps.remove(remove)
                overlaps = max(overlaps, len(current_overlaps)+1)
                look_ahead += 1
            overlaps_and_index[rusages[current].id] = (index, overlaps)
            current += 1
    return overlaps_and_index