def get_recurring_booking_suggestions(rooms, start_dt, end_dt, repeat_frequency, repeat_interval, limit=None): data = [] booking_days = end_dt - start_dt booking_length = booking_days.days + 1 candidates = ReservationOccurrence.create_series(start_dt, end_dt, (repeat_frequency, repeat_interval)) blocked_rooms = group_blocked_rooms(get_rooms_blockings(rooms, start_dt.date(), end_dt.date())) unbookable_hours = get_rooms_unbookable_hours(rooms) nonbookable_periods = get_rooms_nonbookable_periods(rooms, start_dt, end_dt) conflicts = get_rooms_conflicts(rooms, start_dt, end_dt, repeat_frequency, repeat_interval, blocked_rooms, nonbookable_periods, unbookable_hours)[0] for room in rooms: if limit and len(data) == limit: break suggestions = {} booking_limit = room.booking_limit_days or rb_settings.get('booking_limit') limit_exceeded = booking_limit is not None and booking_limit < booking_length if limit_exceeded: excess_days = booking_length - booking_limit suggestions['shorten'] = excess_days if not limit_exceeded: number_of_conflicting_days = len(group_by_occurrence_date(conflicts.get(room.id, []))) if number_of_conflicting_days and number_of_conflicting_days < len(candidates): suggestions['skip'] = number_of_conflicting_days if suggestions: data.append({'room': room, 'suggestions': suggestions}) return data
def get_room_details_availability(room, start_dt, end_dt): dates = [d.date() for d in iterdays(start_dt, end_dt)] occurrences = get_existing_room_occurrences(room, start_dt, end_dt, RepeatFrequency.DAY, 1) pre_bookings = [occ for occ in occurrences if not occ.reservation.is_accepted] bookings = [occ for occ in occurrences if occ.reservation.is_accepted] blocked_rooms = get_rooms_blockings([room], start_dt.date(), end_dt.date()) nonoverridable_blocked_rooms = group_blocked_rooms(filter_blocked_rooms(blocked_rooms, nonoverridable_only=True, explicit=True)).get(room.id, []) overridable_blocked_rooms = group_blocked_rooms(filter_blocked_rooms(blocked_rooms, overridable_only=True, explicit=True)).get(room.id, []) unbookable_hours = get_rooms_unbookable_hours([room]).get(room.id, []) nonbookable_periods = get_rooms_nonbookable_periods([room], start_dt, end_dt).get(room.id, []) availability = [] for day in dates: iso_day = day.isoformat() nb_periods = serialize_nonbookable_periods(group_nonbookable_periods(nonbookable_periods, dates)).get(iso_day) availability.append({ 'bookings': serialize_occurrences(group_by_occurrence_date(bookings)).get(iso_day), 'pre_bookings': serialize_occurrences(group_by_occurrence_date(pre_bookings)).get(iso_day), 'blockings': serialize_blockings(group_blockings(nonoverridable_blocked_rooms, dates)).get(iso_day), 'overridable_blockings': (serialize_blockings(group_blockings(overridable_blocked_rooms, dates)) .get(iso_day)), 'nonbookable_periods': nb_periods, 'unbookable_hours': serialize_unbookable_hours(unbookable_hours), 'day': iso_day, }) return sorted(availability, key=itemgetter('day'))
def get_room_calendar(start_date, end_date, room_ids, include_inactive=False, **filters): start_dt = datetime.combine(start_date, time(hour=0, minute=0)) end_dt = datetime.combine(end_date, time(hour=23, minute=59)) query = _bookings_query(dict(filters, start_dt=start_dt, end_dt=end_dt, room_ids=room_ids, include_inactive=include_inactive)) bookings = query.order_by(db.func.indico.natsort(Room.full_name)).all() rooms = set() if room_ids: rooms = set(Room.query .filter(~Room.is_deleted, Room.id.in_(room_ids)) .options(joinedload('location'))) rooms.update(b.reservation.room for b in bookings) rooms = sorted(rooms, key=lambda r: natural_sort_key(r.full_name)) occurrences_by_room = groupby(bookings, attrgetter('reservation.room_id')) unbookable_hours = get_rooms_unbookable_hours(rooms) nonbookable_periods = get_rooms_nonbookable_periods(rooms, start_dt, end_dt) blocked_rooms = get_rooms_blockings(rooms, start_dt, end_dt) nonoverridable_blocked_rooms = group_blocked_rooms(filter_blocked_rooms(blocked_rooms, nonoverridable_only=True, explicit=True)) overridable_blocked_rooms = group_blocked_rooms(filter_blocked_rooms(blocked_rooms, overridable_only=True, explicit=True)) dates = [d.date() for d in iterdays(start_dt, end_dt)] calendar = {room.id: { 'room_id': room.id, 'nonbookable_periods': group_nonbookable_periods(nonbookable_periods.get(room.id, []), dates), 'unbookable_hours': unbookable_hours.get(room.id, []), 'blockings': group_blockings(nonoverridable_blocked_rooms.get(room.id, []), dates), 'overridable_blockings': group_blockings(overridable_blocked_rooms.get(room.id, []), dates), } for room in rooms} for room_id, occurrences in occurrences_by_room: occurrences = list(occurrences) pre_bookings = [occ for occ in occurrences if occ.reservation.is_pending] existing_bookings = [occ for occ in occurrences if not occ.reservation.is_pending and occ.is_valid] concurrent_pre_bookings = get_concurrent_pre_bookings(pre_bookings) additional_data = { 'bookings': group_by_occurrence_date(existing_bookings), 'pre_bookings': group_by_occurrence_date(pre_bookings), 'concurrent_pre_bookings': group_by_occurrence_date(concurrent_pre_bookings) } if include_inactive: additional_data.update({ 'cancellations': group_by_occurrence_date(occ for occ in occurrences if occ.is_cancelled), 'rejections': group_by_occurrence_date(occ for occ in occurrences if occ.is_rejected) }) calendar[room_id].update(additional_data) return calendar
def get_rooms_availability(rooms, start_dt, end_dt, repeat_frequency, repeat_interval, skip_conflicts_with=None, admin_override_enabled=False, skip_past_conflicts=False): availability = {} candidates = ReservationOccurrence.create_series(start_dt, end_dt, (repeat_frequency, repeat_interval)) date_range = sorted({cand.start_dt.date() for cand in candidates}) occurrences = get_existing_rooms_occurrences(rooms, start_dt.replace(hour=0, minute=0), end_dt.replace(hour=23, minute=59), repeat_frequency, repeat_interval) blocked_rooms = get_rooms_blockings(rooms, start_dt.date(), end_dt.date()) nonoverridable_blocked_rooms = group_blocked_rooms(filter_blocked_rooms(blocked_rooms, nonoverridable_only=True, explicit=True)) overridable_blocked_rooms = group_blocked_rooms(filter_blocked_rooms(blocked_rooms, overridable_only=True, explicit=True)) unbookable_hours = get_rooms_unbookable_hours(rooms) nonbookable_periods = get_rooms_nonbookable_periods(rooms, start_dt, end_dt) conflicts, pre_conflicts, conflicting_candidates = get_rooms_conflicts( rooms, start_dt.replace(tzinfo=None), end_dt.replace(tzinfo=None), repeat_frequency, repeat_interval, nonoverridable_blocked_rooms, nonbookable_periods, unbookable_hours, skip_conflicts_with, allow_admin=admin_override_enabled, skip_past_conflicts=skip_past_conflicts ) dates = list(candidate.start_dt.date() for candidate in candidates) for room in rooms: room_occurrences = occurrences.get(room.id, []) room_conflicting_candidates = conflicting_candidates.get(room.id, []) room_conflicts = conflicts.get(room.id, []) pre_room_conflicts = pre_conflicts.get(room.id, []) pre_bookings = [occ for occ in room_occurrences if not occ.reservation.is_accepted] concurrent_pre_bookings = get_concurrent_pre_bookings(pre_bookings) if pre_bookings else [] existing_bookings = [occ for occ in room_occurrences if occ.reservation.is_accepted] room_nonoverridable_blocked_rooms = nonoverridable_blocked_rooms.get(room.id, []) room_overridable_blocked_rooms = overridable_blocked_rooms.get(room.id, []) room_nonbookable_periods = nonbookable_periods.get(room.id, []) room_unbookable_hours = unbookable_hours.get(room.id, []) room_candidates = get_room_candidates(candidates, room_conflicts) availability[room.id] = {'room_id': room.id, 'candidates': group_by_occurrence_date(room_candidates), 'conflicting_candidates': group_by_occurrence_date(room_conflicting_candidates), 'pre_bookings': group_by_occurrence_date(pre_bookings), 'concurrent_pre_bookings': group_by_occurrence_date(concurrent_pre_bookings), 'bookings': group_by_occurrence_date(existing_bookings), 'conflicts': group_by_occurrence_date(room_conflicts), 'pre_conflicts': group_by_occurrence_date(pre_room_conflicts), 'blockings': group_blockings(room_nonoverridable_blocked_rooms, dates), 'overridable_blockings': group_blockings(room_overridable_blocked_rooms, dates), 'nonbookable_periods': group_nonbookable_periods(room_nonbookable_periods, dates), 'unbookable_hours': room_unbookable_hours} return date_range, availability
def get_room_calendar(start_date, end_date, room_ids, include_inactive=False, **filters): start_dt = datetime.combine(start_date, time(hour=0, minute=0)) end_dt = datetime.combine(end_date, time(hour=23, minute=59)) query = _bookings_query(dict(filters, start_dt=start_dt, end_dt=end_dt, room_ids=room_ids, include_inactive=include_inactive)) query = query.order_by(db.func.indico.natsort(Room.full_name)) rooms = (Room.query .filter(~Room.is_deleted, Room.id.in_(room_ids) if room_ids else True) .options(joinedload('location')) .order_by(db.func.indico.natsort(Room.full_name)) .all()) unbookable_hours = get_rooms_unbookable_hours(rooms) nonbookable_periods = get_rooms_nonbookable_periods(rooms, start_dt, end_dt) occurrences_by_room = groupby(query, attrgetter('reservation.room_id')) blocked_rooms = get_rooms_blockings(rooms, start_dt, end_dt) nonoverridable_blocked_rooms = group_blocked_rooms(filter_blocked_rooms(blocked_rooms, nonoverridable_only=True, explicit=True)) overridable_blocked_rooms = group_blocked_rooms(filter_blocked_rooms(blocked_rooms, overridable_only=True, explicit=True)) dates = [d.date() for d in iterdays(start_dt, end_dt)] calendar = OrderedDict((room.id, { 'room_id': room.id, 'nonbookable_periods': group_nonbookable_periods(nonbookable_periods.get(room.id, []), dates), 'unbookable_hours': unbookable_hours.get(room.id, []), 'blockings': group_blockings(nonoverridable_blocked_rooms.get(room.id, []), dates), 'overridable_blockings': group_blockings(overridable_blocked_rooms.get(room.id, []), dates), }) for room in rooms) for room_id, occurrences in occurrences_by_room: occurrences = list(occurrences) pre_bookings = [occ for occ in occurrences if occ.reservation.is_pending] existing_bookings = [occ for occ in occurrences if not occ.reservation.is_pending and occ.is_valid] additional_data = { 'bookings': group_by_occurrence_date(existing_bookings), 'pre_bookings': group_by_occurrence_date(pre_bookings) } if include_inactive: additional_data.update({ 'cancellations': group_by_occurrence_date(occ for occ in occurrences if occ.is_cancelled), 'rejections': group_by_occurrence_date(occ for occ in occurrences if occ.is_rejected) }) calendar[room_id].update(additional_data) return calendar
def get_rooms_availability(rooms, start_dt, end_dt, repeat_frequency, repeat_interval, skip_conflicts_with=None, admin_override_enabled=False): availability = OrderedDict() candidates = ReservationOccurrence.create_series(start_dt, end_dt, (repeat_frequency, repeat_interval)) date_range = sorted(set(cand.start_dt.date() for cand in candidates)) occurrences = get_existing_rooms_occurrences(rooms, start_dt.replace(hour=0, minute=0), end_dt.replace(hour=23, minute=59), repeat_frequency, repeat_interval) blocked_rooms = get_rooms_blockings(rooms, start_dt.date(), end_dt.date()) nonoverridable_blocked_rooms = group_blocked_rooms(filter_blocked_rooms(blocked_rooms, nonoverridable_only=True, explicit=True)) overridable_blocked_rooms = group_blocked_rooms(filter_blocked_rooms(blocked_rooms, overridable_only=True, explicit=True)) unbookable_hours = get_rooms_unbookable_hours(rooms) nonbookable_periods = get_rooms_nonbookable_periods(rooms, start_dt, end_dt) conflicts, pre_conflicts, conflicting_candidates = get_rooms_conflicts( rooms, start_dt.replace(tzinfo=None), end_dt.replace(tzinfo=None), repeat_frequency, repeat_interval, nonoverridable_blocked_rooms, nonbookable_periods, unbookable_hours, skip_conflicts_with, allow_admin=admin_override_enabled ) dates = list(candidate.start_dt.date() for candidate in candidates) for room in rooms: room_occurrences = occurrences.get(room.id, []) room_conflicting_candidates = conflicting_candidates.get(room.id, []) room_conflicts = conflicts.get(room.id, []) pre_room_conflicts = pre_conflicts.get(room.id, []) pre_bookings = [occ for occ in room_occurrences if not occ.reservation.is_accepted] existing_bookings = [occ for occ in room_occurrences if occ.reservation.is_accepted] room_nonoverridable_blocked_rooms = nonoverridable_blocked_rooms.get(room.id, []) room_overridable_blocked_rooms = overridable_blocked_rooms.get(room.id, []) room_nonbookable_periods = nonbookable_periods.get(room.id, []) room_unbookable_hours = unbookable_hours.get(room.id, []) room_candidates = get_room_candidates(candidates, room_conflicts, pre_room_conflicts) availability[room.id] = {'room_id': room.id, 'candidates': group_by_occurrence_date(room_candidates), 'conflicting_candidates': group_by_occurrence_date(room_conflicting_candidates), 'pre_bookings': group_by_occurrence_date(pre_bookings), 'bookings': group_by_occurrence_date(existing_bookings), 'conflicts': group_by_occurrence_date(room_conflicts), 'pre_conflicts': group_by_occurrence_date(pre_room_conflicts), 'blockings': group_blockings(room_nonoverridable_blocked_rooms, dates), 'overridable_blockings': group_blockings(room_overridable_blocked_rooms, dates), 'nonbookable_periods': group_nonbookable_periods(room_nonbookable_periods, dates), 'unbookable_hours': room_unbookable_hours} return date_range, availability
def get_single_booking_suggestions(rooms, start_dt, end_dt, limit=None): data = [] new_start_dt = start_dt - timedelta(minutes=BOOKING_TIME_DIFF) new_end_dt = end_dt + timedelta(minutes=BOOKING_TIME_DIFF) nonbookable_periods = get_rooms_nonbookable_periods( rooms, start_dt, end_dt) rooms = [room for room in rooms if room.id not in nonbookable_periods] if not rooms: return data unbookable_hours = get_rooms_unbookable_hours(rooms) rooms_occurrences = get_existing_rooms_occurrences(rooms, new_start_dt, new_end_dt, RepeatFrequency.NEVER, None, allow_overlapping=True) for room in rooms: if limit and len(data) == limit: break suggestions = {} taken_periods = [(occ.start_dt, occ.end_dt) for occ in rooms_occurrences.get(room.id, [])] if room.id in unbookable_hours: taken_periods.extend((datetime.combine(start_dt, uh.start_time), datetime.combine(end_dt, uh.end_time)) for uh in unbookable_hours[room.id]) taken_periods = sorted(taken_periods) suggested_time = get_start_time_suggestion(taken_periods, start_dt, end_dt) if suggested_time: suggested_time_change = (suggested_time - start_dt).total_seconds() / 60 if suggested_time_change and abs( suggested_time_change) <= BOOKING_TIME_DIFF: suggestions['time'] = suggested_time_change duration_suggestion = get_duration_suggestion(taken_periods, start_dt, end_dt) original_duration = (end_dt - start_dt).total_seconds() / 60 if duration_suggestion and duration_suggestion <= DURATION_FACTOR * original_duration: suggestions['duration'] = duration_suggestion if suggestions: data.append({'room': room, 'suggestions': suggestions}) return data
def serialize_booking_details(booking): from indico.modules.rb.operations.blockings import filter_blocked_rooms, get_rooms_blockings, group_blocked_rooms from indico.modules.rb.operations.bookings import (get_booking_occurrences, get_existing_room_occurrences, group_blockings, group_nonbookable_periods) from indico.modules.rb.operations.misc import get_rooms_nonbookable_periods, get_rooms_unbookable_hours from indico.modules.rb.schemas import reservation_details_schema, reservation_occurrences_schema_with_permissions attributes = reservation_details_schema.dump(booking) date_range, occurrences = get_booking_occurrences(booking) booking_details = dict(attributes) occurrences_by_type = dict(bookings={}, cancellations={}, rejections={}, other={}, blockings={}, unbookable_hours={}, nonbookable_periods={}, overridable_blockings={}) booking_details['occurrences'] = occurrences_by_type booking_details['date_range'] = [dt.isoformat() for dt in date_range] for dt, [occ] in occurrences.iteritems(): serialized_occ = reservation_occurrences_schema_with_permissions.dump([occ]) if occ.is_cancelled: occurrences_by_type['cancellations'][dt.isoformat()] = serialized_occ elif occ.is_rejected: occurrences_by_type['rejections'][dt.isoformat()] = serialized_occ occurrences_by_type['bookings'][dt.isoformat()] = serialized_occ if occ.is_valid else [] start_dt = datetime.combine(booking.start_dt, time.min) end_dt = datetime.combine(booking.end_dt, time.max) unbookable_hours = get_rooms_unbookable_hours([booking.room]).get(booking.room.id, []) other_bookings = get_existing_room_occurrences(booking.room, start_dt, end_dt, booking.repeat_frequency, booking.repeat_interval, only_accepted=True, skip_booking_id=booking.id) blocked_rooms = get_rooms_blockings([booking.room], start_dt.date(), end_dt.date()) overridable_blockings = group_blocked_rooms(filter_blocked_rooms(blocked_rooms, overridable_only=True, explicit=True)).get(booking.room.id, []) nonoverridable_blockings = group_blocked_rooms(filter_blocked_rooms(blocked_rooms, nonoverridable_only=True, explicit=True)).get(booking.room.id, []) nonbookable_periods = get_rooms_nonbookable_periods([booking.room], start_dt, end_dt).get(booking.room.id, []) nonbookable_periods_grouped = group_nonbookable_periods(nonbookable_periods, date_range) occurrences_by_type['other'] = serialize_occurrences(group_by_occurrence_date(other_bookings)) occurrences_by_type['blockings'] = serialize_blockings(group_blockings(nonoverridable_blockings, date_range)) occurrences_by_type['overridable_blockings'] = serialize_blockings(group_blockings(overridable_blockings, date_range)) occurrences_by_type['unbookable_hours'] = serialize_unbookable_hours(unbookable_hours) occurrences_by_type['nonbookable_periods'] = serialize_nonbookable_periods(nonbookable_periods_grouped) return booking_details
def serialize_booking_details(booking): from indico.modules.rb.operations.blockings import filter_blocked_rooms, get_rooms_blockings, group_blocked_rooms from indico.modules.rb.operations.bookings import (get_booking_occurrences, get_existing_room_occurrences, group_blockings, group_nonbookable_periods) from indico.modules.rb.operations.misc import get_rooms_nonbookable_periods, get_rooms_unbookable_hours from indico.modules.rb.schemas import reservation_details_schema, reservation_occurrences_schema_with_permissions attributes = reservation_details_schema.dump(booking) date_range, occurrences = get_booking_occurrences(booking) booking_details = dict(attributes) occurrences_by_type = dict(bookings={}, cancellations={}, rejections={}, other={}, blockings={}, unbookable_hours={}, nonbookable_periods={}, overridable_blockings={}) booking_details['occurrences'] = occurrences_by_type booking_details['date_range'] = [dt.isoformat() for dt in date_range] for dt, [occ] in occurrences.items(): serialized_occ = reservation_occurrences_schema_with_permissions.dump([occ]) if occ.is_cancelled: occurrences_by_type['cancellations'][dt.isoformat()] = serialized_occ elif occ.is_rejected: occurrences_by_type['rejections'][dt.isoformat()] = serialized_occ occurrences_by_type['bookings'][dt.isoformat()] = serialized_occ if occ.is_valid else [] start_dt = datetime.combine(booking.start_dt, time.min) end_dt = datetime.combine(booking.end_dt, time.max) unbookable_hours = get_rooms_unbookable_hours([booking.room]).get(booking.room.id, []) other_bookings = get_existing_room_occurrences(booking.room, start_dt, end_dt, booking.repeat_frequency, booking.repeat_interval, skip_booking_id=booking.id) blocked_rooms = get_rooms_blockings([booking.room], start_dt.date(), end_dt.date()) overridable_blockings = group_blocked_rooms(filter_blocked_rooms(blocked_rooms, overridable_only=True, explicit=True)).get(booking.room.id, []) nonoverridable_blockings = group_blocked_rooms(filter_blocked_rooms(blocked_rooms, nonoverridable_only=True, explicit=True)).get(booking.room.id, []) nonbookable_periods = get_rooms_nonbookable_periods([booking.room], start_dt, end_dt).get(booking.room.id, []) nonbookable_periods_grouped = group_nonbookable_periods(nonbookable_periods, date_range) occurrences_by_type['other'] = serialize_occurrences(group_by_occurrence_date(other_bookings)) occurrences_by_type['blockings'] = serialize_blockings(group_blockings(nonoverridable_blockings, date_range)) occurrences_by_type['overridable_blockings'] = serialize_blockings(group_blockings(overridable_blockings, date_range)) occurrences_by_type['unbookable_hours'] = serialize_unbookable_hours(unbookable_hours) occurrences_by_type['nonbookable_periods'] = serialize_nonbookable_periods(nonbookable_periods_grouped) return booking_details
def get_single_booking_suggestions(rooms, start_dt, end_dt, limit=None): data = [] new_start_dt = start_dt - timedelta(minutes=BOOKING_TIME_DIFF) new_end_dt = end_dt + timedelta(minutes=BOOKING_TIME_DIFF) nonbookable_periods = get_rooms_nonbookable_periods(rooms, start_dt, end_dt) rooms = [room for room in rooms if room.id not in nonbookable_periods] if not rooms: return data unbookable_hours = get_rooms_unbookable_hours(rooms) rooms_occurrences = get_existing_rooms_occurrences(rooms, new_start_dt, new_end_dt, RepeatFrequency.NEVER, None, allow_overlapping=True) for room in rooms: if limit and len(data) == limit: break suggestions = {} taken_periods = [(occ.start_dt, occ.end_dt) for occ in rooms_occurrences.get(room.id, [])] if room.id in unbookable_hours: taken_periods.extend((datetime.combine(start_dt, uh.start_time), datetime.combine(end_dt, uh.end_time)) for uh in unbookable_hours[room.id]) taken_periods = sorted(taken_periods) suggested_time = get_start_time_suggestion(taken_periods, start_dt, end_dt) if suggested_time: suggested_time_change = (suggested_time - start_dt).total_seconds() / 60 if suggested_time_change and abs(suggested_time_change) <= BOOKING_TIME_DIFF: suggestions['time'] = suggested_time_change duration_suggestion = get_duration_suggestion(taken_periods, start_dt, end_dt) original_duration = (end_dt - start_dt).total_seconds() / 60 if duration_suggestion and duration_suggestion <= DURATION_FACTOR * original_duration: suggestions['duration'] = duration_suggestion if suggestions: data.append({'room': room, 'suggestions': suggestions}) return data
def check_room_available(room, start_dt, end_dt): occurrences = get_existing_room_occurrences(room, start_dt, end_dt, allow_overlapping=True) prebookings = [ occ for occ in occurrences if not occ.reservation.is_accepted ] bookings = [occ for occ in occurrences if occ.reservation.is_accepted] unbookable_hours = get_rooms_unbookable_hours([room]) hours_overlap = any( hours for hours in unbookable_hours if overlaps((start_dt.time(), end_dt.time()), (hours.start_time, hours.end_time))) nonbookable_periods = any( get_rooms_nonbookable_periods([room], start_dt, end_dt)) blocked_rooms = get_rooms_blockings([room], start_dt, end_dt) nonoverridable_blocked_rooms = filter_blocked_rooms( blocked_rooms, nonoverridable_only=True, explicit=True) blocked_for_user = any(nonoverridable_blocked_rooms) user_booking = any(booking for booking in bookings if booking.reservation.booked_for_id == session.user.id) user_prebooking = any( prebooking for prebooking in prebookings if prebooking.reservation.booked_for_id == session.user.id) return { 'can_book': room.can_book(session.user, allow_admin=False), 'can_prebook': room.can_prebook(session.user, allow_admin=False), 'conflict_booking': any(bookings), 'conflict_prebooking': any(prebookings), 'unbookable': (hours_overlap or nonbookable_periods or blocked_for_user), 'user_booking': user_booking, 'user_prebooking': user_prebooking, }
def check_room_available(room, start_dt, end_dt): occurrences = get_existing_room_occurrences(room, start_dt, end_dt, allow_overlapping=True) prebookings = [occ for occ in occurrences if not occ.reservation.is_accepted] bookings = [occ for occ in occurrences if occ.reservation.is_accepted] unbookable_hours = get_rooms_unbookable_hours([room]) hours_overlap = any(hours for hours in unbookable_hours if overlaps((start_dt.time(), end_dt.time()), (hours.start_time, hours.end_time))) nonbookable_periods = any(get_rooms_nonbookable_periods([room], start_dt, end_dt)) blocked_rooms = get_rooms_blockings([room], start_dt, end_dt) nonoverridable_blocked_rooms = filter_blocked_rooms(blocked_rooms, nonoverridable_only=True, explicit=True) blocked_for_user = any(nonoverridable_blocked_rooms) user_booking = any(booking for booking in bookings if booking.reservation.booked_for_id == session.user.id) user_prebooking = any(prebooking for prebooking in prebookings if prebooking.reservation.booked_for_id == session.user.id) return { 'can_book': room.can_book(session.user, allow_admin=False), 'can_prebook': room.can_prebook(session.user, allow_admin=False), 'conflict_booking': any(bookings), 'conflict_prebooking': any(prebookings), 'unbookable': (hours_overlap or nonbookable_periods or blocked_for_user), 'user_booking': user_booking, 'user_prebooking': user_prebooking, }