def find_with_filters(filters, avatar=None):
        from indico.modules.rb.models.rooms import Room
        from indico.modules.rb.models.reservations import Reservation

        q = ReservationOccurrence.find(Room.is_active, _join=[Reservation, Room],
                                       _eager=ReservationOccurrence.reservation)

        if 'start_dt' in filters and 'end_dt' in filters:
            start_dt = filters['start_dt']
            end_dt = filters['end_dt']
            criteria = []
            # We have to check the time range for EACH DAY
            for day_start_dt in iterdays(start_dt, end_dt):
                # Same date, but the end time
                day_end_dt = datetime.combine(day_start_dt.date(), end_dt.time())
                criteria.append(db_dates_overlap(ReservationOccurrence, 'start_dt', day_start_dt, 'end_dt', day_end_dt))
            q = q.filter(or_(*criteria))

        if filters.get('is_only_mine') and avatar:
            q = q.filter((Reservation.booked_for_id == avatar.id) | (Reservation.created_by_id == avatar.id))
        if filters.get('room_ids'):
            q = q.filter(Room.id.in_(filters['room_ids']))

        if filters.get('is_only_confirmed_bookings') and not filters.get('is_only_pending_bookings'):
            q = q.filter(Reservation.is_accepted)
        elif not filters.get('is_only_confirmed_bookings') and filters.get('is_only_pending_bookings'):
            q = q.filter(~Reservation.is_accepted)

        if filters.get('is_rejected'):
            q = q.filter(Reservation.is_rejected | ReservationOccurrence.is_rejected)
        else:
            q = q.filter(~Reservation.is_rejected & ~ReservationOccurrence.is_rejected)
        if filters.get('is_cancelled'):
            q = q.filter(Reservation.is_cancelled | ReservationOccurrence.is_cancelled)
        else:
            q = q.filter(~Reservation.is_cancelled & ~ReservationOccurrence.is_cancelled)
        if filters.get('is_archived'):
            q = q.filter(Reservation.is_archived)

        if filters.get('uses_vc'):
            q = q.filter(Reservation.uses_vc)
        if filters.get('needs_vc_assistance'):
            q = q.filter(Reservation.needs_vc_assistance)
        if filters.get('needs_assistance'):
            q = q.filter(Reservation.needs_assistance)

        if filters.get('booked_for_name'):
            qs = u'%{}%'.format(filters['booked_for_name'])
            q = q.filter(Reservation.booked_for_name.ilike(qs))
        if filters.get('reason'):
            qs = u'%{}%'.format(filters['reason'])
            q = q.filter(Reservation.booking_reason.ilike(qs))

        q = q.order_by(Room.id)
        return q
 def filter_overlap(occurrences):
     return or_(db_dates_overlap(ReservationOccurrence, 'start_dt', occ.start_dt, 'end_dt', occ.end_dt)
                for occ in occurrences)