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)