Exemplo n.º 1
0
def get_rooms_conflicts(rooms, start_dt, end_dt, repeat_frequency, repeat_interval, blocked_rooms,
                        nonbookable_periods, unbookable_hours, skip_conflicts_with=None, allow_admin=False,
                        skip_past_conflicts=False):
    rooms_conflicts = defaultdict(set)
    rooms_pre_conflicts = defaultdict(set)
    rooms_conflicting_candidates = defaultdict(set)
    skip_conflicts_with = skip_conflicts_with or []

    candidates = ReservationOccurrence.create_series(start_dt, end_dt, (repeat_frequency, repeat_interval))
    room_ids = [room.id for room in rooms]
    query = (ReservationOccurrence.query
             .filter(Reservation.room_id.in_(room_ids),
                     ReservationOccurrence.is_valid,
                     ReservationOccurrence.filter_overlap(candidates))
             .join(ReservationOccurrence.reservation)
             .options(ReservationOccurrence.NO_RESERVATION_USER_STRATEGY,
                      contains_eager(ReservationOccurrence.reservation)))

    if skip_conflicts_with:
        query = query.filter(~Reservation.id.in_(skip_conflicts_with))
    if skip_past_conflicts:
        query = query.filter(ReservationOccurrence.start_dt > datetime.now())

    overlapping_occurrences = group_list(query, key=lambda obj: obj.reservation.room.id,
                                         sort_by=lambda obj: obj.reservation.room.id)
    for room_id, occurrences in overlapping_occurrences.items():
        conflicts = get_room_bookings_conflicts(candidates, occurrences, skip_conflicts_with)
        rooms_conflicts[room_id], rooms_pre_conflicts[room_id], rooms_conflicting_candidates[room_id] = conflicts
    for room_id, occurrences in blocked_rooms.items():
        conflicts, conflicting_candidates = get_room_blockings_conflicts(room_id, candidates, occurrences,
                                                                         allow_admin=allow_admin)
        rooms_conflicts[room_id] |= conflicts
        rooms_conflicting_candidates[room_id] |= conflicting_candidates

    if not (allow_admin and rb_is_admin(session.user)):
        for room_id, occurrences in nonbookable_periods.items():
            room = Room.get_or_404(room_id)
            if not room.can_override(session.user, allow_admin=allow_admin):
                conflicts, conflicting_candidates = get_room_nonbookable_periods_conflicts(candidates, occurrences)
                rooms_conflicts[room_id] |= conflicts
                rooms_conflicting_candidates[room_id] |= conflicting_candidates

        for room_id, occurrences in unbookable_hours.items():
            room = Room.get_or_404(room_id)
            if not room.can_override(session.user, allow_admin=allow_admin):
                conflicts, conflicting_candidates = get_room_unbookable_hours_conflicts(candidates, occurrences)
                rooms_conflicts[room_id] |= conflicts
                rooms_conflicting_candidates[room_id] |= conflicting_candidates
    rooms_conflicting_candidates = defaultdict(list, ((k, list(v)) for k, v in rooms_conflicting_candidates.items()))
    return rooms_conflicts, rooms_pre_conflicts, rooms_conflicting_candidates
Exemplo n.º 2
0
def create_booking_for_event(room_id, event):
    try:
        room = Room.get_or_404(room_id)
        default_timezone = timezone(config.DEFAULT_TIMEZONE)
        start_dt = event.start_dt.astimezone(default_timezone).replace(
            tzinfo=None)
        end_dt = event.end_dt.astimezone(default_timezone).replace(tzinfo=None)
        booking_reason = f"Event '{event.title}'"
        data = dict(start_dt=start_dt,
                    end_dt=end_dt,
                    booked_for_user=event.creator,
                    booking_reason=booking_reason,
                    repeat_frequency=RepeatFrequency.NEVER,
                    event_id=event.id)
        booking = Reservation.create_from_data(room,
                                               data,
                                               session.user,
                                               ignore_admin=True)
        booking.linked_object = event
        return booking
    except NoReportError:
        flash(
            _("Booking could not be created. Probably somebody else booked the room in the meantime."
              ), 'error')
        return None
Exemplo n.º 3
0
    def _checkSplitRooms(self, room, occs):

        if room in self.splitmap:
            for ri in self.splitmap[room]:
                oroom = Room.get_or_404(ri, is_deleted=False)
                overlap = Reservation.find_overlapping_with(oroom, occs).all()
                if overlap:
                    raise ExpectedError(
                        'Overlaps with other reservations in {}.'.format(
                            oroom.name))

        else:
            for ri, splits in self.splitmap.items():
                if room in splits:
                    oroom = Room.get_or_404(ri, is_deleted=False)
                    overlap = Reservation.find_overlapping_with(oroom,
                                                                occs).all()
                    if overlap:
                        raise ExpectedError(
                            'Overlaps with other reservations in {}.'.format(
                                oroom.name))
                    break
Exemplo n.º 4
0
 def _process_args(self):
     self.room = None
     if 'room_id' in request.view_args:
         self.room = Room.get_or_404(request.view_args['room_id'],
                                     is_deleted=False)
Exemplo n.º 5
0
 def _process_args(self, args):
     self.args = args
     self.prebook = args.pop('is_prebooking')
     self.room = Room.get_or_404(self.args.pop('room_id'), is_deleted=False)