Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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