Example #1
0
    def _get_all_occurrences(self, room_ids, form, flexible_days=0, reservation_id=None):
        start_dt = form.start_dt.data
        end_dt = form.end_dt.data
        repeat_frequency = form.repeat_frequency.data
        repeat_interval = form.repeat_interval.data
        day_start_dt = datetime.combine(start_dt.date(), time())
        day_end_dt = datetime.combine(end_dt.date(), time(23, 59))
        today_start_dt = datetime.combine(date.today(), time())
        flexible_start_dt = day_start_dt - timedelta(days=flexible_days)
        if not session.user.isAdmin():
            flexible_start_dt = max(today_start_dt, flexible_start_dt)
        flexible_end_dt = day_end_dt + timedelta(days=flexible_days)

        occurrences = ReservationOccurrence.find_all(
            Reservation.room_id.in_(room_ids),
            Reservation.id != reservation_id,
            ReservationOccurrence.start_dt >= flexible_start_dt,
            ReservationOccurrence.end_dt <= flexible_end_dt,
            ReservationOccurrence.is_valid,
            _join=Reservation,
            _eager=ReservationOccurrence.reservation
        )

        candidates = {}
        for days in xrange(-flexible_days, flexible_days + 1):
            offset = timedelta(days=days)
            series_start = start_dt + offset
            series_end = end_dt + offset
            if series_start < flexible_start_dt:
                continue
            candidates[series_start, series_end] = ReservationOccurrence.create_series(series_start, series_end,
                                                                                       (repeat_frequency,
                                                                                        repeat_interval))
        return occurrences, candidates
def test_filter_overlap(create_occurrence, overlapping_combination_from_2am_to_4am):
    start_hour, end_hour, expected = overlapping_combination_from_2am_to_4am()
    occ1 = create_occurrence(start_dt=date.today() + relativedelta(hour=2),
                             end_dt=date.today() + relativedelta(hour=4))
    occ2 = ReservationOccurrence(start_dt=date.today() + relativedelta(hour=start_hour),
                                 end_dt=date.today() + relativedelta(hour=end_hour))
    overlap_filter = ReservationOccurrence.filter_overlap([occ2])
    assert (occ1 in ReservationOccurrence.find_all(overlap_filter)) == expected
def test_filter_overlap(create_occurrence, overlapping_combination_from_2am_to_4am):
    start_hour, end_hour, expected = overlapping_combination_from_2am_to_4am()
    occ1 = create_occurrence(start_dt=date.today() + relativedelta(hour=2),
                             end_dt=date.today() + relativedelta(hour=4))
    occ2 = ReservationOccurrence(start_dt=date.today() + relativedelta(hour=start_hour),
                                 end_dt=date.today() + relativedelta(hour=end_hour))
    overlap_filter = ReservationOccurrence.filter_overlap([occ2])
    assert (occ1 in ReservationOccurrence.find_all(overlap_filter)) == expected
Example #4
0
    def _process(self):
        occurrences = ReservationOccurrence.find_all(
            Reservation.room_id == self._room.id,
            ReservationOccurrence.start_dt >= self._calendar_start,
            ReservationOccurrence.end_dt <= self._calendar_end,
            ReservationOccurrence.is_valid,
            _join=Reservation,
            _eager=ReservationOccurrence.reservation
        )

        return self._get_view(room=self._room, start_dt=self._calendar_start, end_dt=self._calendar_end,
                              occurrences=occurrences).display()
Example #5
0
    def _process(self):
        occurrences = ReservationOccurrence.find_all(
            Reservation.room_id == self._room.id,
            ReservationOccurrence.start_dt >= self._calendar_start,
            ReservationOccurrence.end_dt <= self._calendar_end,
            ReservationOccurrence.is_valid,
            _join=Reservation,
            _eager=ReservationOccurrence.reservation)

        return self._get_view(room=self._room,
                              start_dt=self._calendar_start,
                              end_dt=self._calendar_end,
                              occurrences=occurrences).display()
Example #6
0
    def approve(self, notify_blocker=True):
        """Approve the room blocking, rejecting all colliding reservations/occurrences."""
        self.state = BlockedRoomState.accepted

        # Get colliding reservations
        start_dt = datetime.combine(self.blocking.start_date, time())
        end_dt = datetime.combine(self.blocking.end_date, time(23, 59, 59))

        reservation_criteria = [
            Reservation.room_id == self.room_id,
            ~Reservation.is_rejected,
            ~Reservation.is_cancelled
        ]

        # Whole reservations to reject
        reservations = Reservation.find_all(
            Reservation.start_dt >= start_dt,
            Reservation.end_dt <= end_dt,
            *reservation_criteria
        )

        # Single occurrences to reject
        occurrences = ReservationOccurrence.find_all(
            ReservationOccurrence.start_dt >= start_dt,
            ReservationOccurrence.end_dt <= end_dt,
            ReservationOccurrence.is_valid,
            ~ReservationOccurrence.reservation_id.in_(map(attrgetter('id'), reservations)) if reservations else True,
            *reservation_criteria,
            _join=Reservation
        )

        reason = f'Conflict with blocking {self.blocking.id}: {self.blocking.reason}'

        for reservation in reservations:
            if self.blocking.can_override(reservation.created_by_user, room=reservation.room):
                continue
            reservation.reject(self.blocking.created_by_user, reason)

        for occurrence in occurrences:
            reservation = occurrence.reservation
            if self.blocking.can_override(reservation.created_by_user, room=reservation.room):
                continue
            occurrence.reject(self.blocking.created_by_user, reason)

        if notify_blocker:
            # We only need to notify the blocking creator if the blocked room wasn't approved yet.
            # This is the case if it's a new blocking for a room managed by the creator
            notify_request_response(self)
Example #7
0
    def approve(self, notify_blocker=True):
        """Approve the room blocking, rejecting all colliding reservations/occurrences."""
        self.state = BlockedRoomState.accepted

        # Get colliding reservations
        start_dt = datetime.combine(self.blocking.start_date, time())
        end_dt = datetime.combine(self.blocking.end_date, time(23, 59, 59))

        reservation_criteria = [
            Reservation.room_id == self.room_id,
            ~Reservation.is_rejected,
            ~Reservation.is_cancelled
        ]

        # Whole reservations to reject
        reservations = Reservation.find_all(
            Reservation.start_dt >= start_dt,
            Reservation.end_dt <= end_dt,
            *reservation_criteria
        )

        # Single occurrences to reject
        occurrences = ReservationOccurrence.find_all(
            ReservationOccurrence.start_dt >= start_dt,
            ReservationOccurrence.end_dt <= end_dt,
            ReservationOccurrence.is_valid,
            ~ReservationOccurrence.reservation_id.in_(map(attrgetter('id'), reservations)) if reservations else True,
            *reservation_criteria,
            _join=Reservation
        )

        reason = 'Conflict with blocking {}: {}'.format(self.blocking.id, self.blocking.reason)

        for reservation in reservations:
            if self.blocking.can_be_overridden(reservation.created_by_user, reservation.room):
                continue
            reservation.reject(self.blocking.created_by_user, reason)

        for occurrence in occurrences:
            reservation = occurrence.reservation
            if self.blocking.can_be_overridden(reservation.created_by_user, reservation.room):
                continue
            occurrence.reject(self.blocking.created_by_user, reason)

        if notify_blocker:
            # We only need to notify the blocking creator if the blocked room wasn't approved yet.
            # This is the case if it's a new blocking for a room managed by the creator
            notify_request_response(self)
Example #8
0
    def _process(self):
        if self._overload:
            rooms = []
            occurrences = []
        else:
            rooms = Room.find_all(is_active=True)
            occurrences = ReservationOccurrence.find_all(
                Reservation.room_id.in_(room.id for room in rooms),
                ReservationOccurrence.start_dt >= self.start_dt,
                ReservationOccurrence.end_dt <= self.end_dt,
                ReservationOccurrence.is_valid,
                _join=Reservation,
                _eager=ReservationOccurrence.reservation
            )

        return WPRoomBookingCalendar(self, rooms=rooms, occurrences=occurrences, start_dt=self.start_dt,
                                     end_dt=self.end_dt, overload=self._overload, max_days=self.MAX_DAYS).display()
Example #9
0
    def _process(self):
        if self._overload:
            rooms = []
            occurrences = []
        else:
            rooms = Room.find_all(is_active=True)
            occurrences = ReservationOccurrence.find_all(
                Reservation.room_id.in_(room.id for room in rooms),
                ReservationOccurrence.start_dt >= self.start_dt,
                ReservationOccurrence.end_dt <= self.end_dt,
                ReservationOccurrence.is_valid,
                _join=Reservation,
                _eager=ReservationOccurrence.reservation)

        return WPRoomBookingCalendar(self,
                                     rooms=rooms,
                                     occurrences=occurrences,
                                     start_dt=self.start_dt,
                                     end_dt=self.end_dt,
                                     overload=self._overload,
                                     max_days=self.MAX_DAYS).display()
Example #10
0
    def _get_all_occurrences(self,
                             room_ids,
                             form,
                             flexible_days=0,
                             reservation_id=None):
        start_dt = form.start_dt.data
        end_dt = form.end_dt.data
        repeat_frequency = form.repeat_frequency.data
        repeat_interval = form.repeat_interval.data
        day_start_dt = datetime.combine(start_dt.date(), time())
        day_end_dt = datetime.combine(end_dt.date(), time(23, 59))
        today_start_dt = datetime.combine(date.today(), time())
        flexible_start_dt = day_start_dt - timedelta(days=flexible_days)
        if not session.user.isAdmin():
            flexible_start_dt = max(today_start_dt, flexible_start_dt)
        flexible_end_dt = day_end_dt + timedelta(days=flexible_days)

        occurrences = ReservationOccurrence.find_all(
            Reservation.room_id.in_(room_ids),
            Reservation.id != reservation_id,
            ReservationOccurrence.start_dt >= flexible_start_dt,
            ReservationOccurrence.end_dt <= flexible_end_dt,
            ReservationOccurrence.is_valid,
            _join=Reservation,
            _eager=ReservationOccurrence.reservation)

        candidates = {}
        for days in xrange(-flexible_days, flexible_days + 1):
            offset = timedelta(days=days)
            series_start = start_dt + offset
            series_end = end_dt + offset
            if series_start < flexible_start_dt:
                continue
            candidates[series_start,
                       series_end] = ReservationOccurrence.create_series(
                           series_start, series_end,
                           (repeat_frequency, repeat_interval))
        return occurrences, candidates