Beispiel #1
0
    def _process(self, args):
        room = Room.get_one(args.pop('room_id'))
        user_id = args.pop('user_id', None)
        booked_for = User.get_one(user_id) if user_id else session.user
        is_prebooking = args.pop('is_prebooking')

        # Check that the booking is not longer than allowed
        booking_limit_days = room.booking_limit_days or rb_settings.get(
            'booking_limit')
        if not self._validate_room_booking_limit(
                args['start_dt'], args['end_dt'], booking_limit_days):
            msg = (
                _('Bookings for the room "{}" may not be longer than {} days'
                  ).format(room.name, booking_limit_days))
            return jsonify(success=False, msg=msg)

        try:
            Reservation.create_from_data(room,
                                         dict(args,
                                              booked_for_user=booked_for),
                                         session.user,
                                         prebook=is_prebooking)
            db.session.flush()
        except NoReportError as e:
            db.session.rollback()
            return jsonify(success=False, msg=unicode(e))
        return jsonify(success=True, is_prebooking=is_prebooking)
Beispiel #2
0
def create_booking_for_event(room_id, event):
    try:
        room = Room.get_one(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 = "Event '{}'".format(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
Beispiel #3
0
def split_booking(booking, new_booking_data):
    is_ongoing_booking = booking.start_dt.date() < date.today() < booking.end_dt.date()
    if not is_ongoing_booking:
        return

    room = booking.room
    occurrences = sorted(booking.occurrences, key=attrgetter('start_dt'))
    cancelled_dates = [occ.start_dt.date() for occ in occurrences if occ.is_cancelled]
    rejected_occs = {occ.start_dt.date(): occ.rejection_reason for occ in occurrences if occ.is_rejected}
    occurrences_to_cancel = [occ for occ in occurrences if occ.start_dt >= datetime.now()]
    new_start_dt = datetime.combine(occurrences_to_cancel[0].start_dt.date(), new_booking_data['start_dt'].time())
    for occurrence_to_cancel in occurrences_to_cancel:
        occurrence_to_cancel.cancel(session.user, silent=True)

    new_end_dt = [occ for occ in occurrences if occ.start_dt < datetime.now()][-1].end_dt
    old_booking_data = {
        'booking_reason': booking.booking_reason,
        'booked_for_user': booking.booked_for_user,
        'start_dt': booking.start_dt,
        'end_dt': new_end_dt,
        'repeat_frequency': booking.repeat_frequency,
        'repeat_interval': booking.repeat_interval,
    }

    booking.modify(old_booking_data, session.user)
    prebook = not room.can_book(session.user, allow_admin=False) and room.can_prebook(session.user, allow_admin=False)
    resv = Reservation.create_from_data(room, dict(new_booking_data, start_dt=new_start_dt), session.user,
                                        prebook=prebook)
    for new_occ in resv.occurrences:
        new_occ_start = new_occ.start_dt.date()
        if new_occ_start in cancelled_dates:
            new_occ.cancel(None, silent=True)
        if new_occ_start in rejected_occs:
            new_occ.reject(None, rejected_occs[new_occ_start], silent=True)
    return resv
Beispiel #4
0
    def _process(self, args):
        room = Room.get_one(args.pop('room_id'))
        user_id = args.pop('user_id', None)
        booked_for = User.get_one(user_id) if user_id else session.user
        is_prebooking = args.pop('is_prebooking')

        # Check that the booking is not longer than allowed
        booking_limit_days = room.booking_limit_days or rb_settings.get('booking_limit')
        if not self._validate_room_booking_limit(args['start_dt'], args['end_dt'], booking_limit_days):
            msg = (_('Bookings for the room "{}" may not be longer than {} days')
                   .format(room.name, booking_limit_days))
            raise ExpectedError(msg)

        try:
            resv = Reservation.create_from_data(room, dict(args, booked_for_user=booked_for), session.user,
                                                prebook=is_prebooking)
            db.session.flush()
        except NoReportError as e:
            db.session.rollback()
            raise ExpectedError(unicode(e))

        serialized_occurrences = serialize_occurrences(group_by_occurrence_date(resv.occurrences.all()))
        if is_prebooking:
            data = {'pre_bookings': serialized_occurrences}
        else:
            data = {'bookings': serialized_occurrences}
        return jsonify(room_id=room.id, booking=reservation_details_schema.dump(resv).data, calendar_data=data)
Beispiel #5
0
    def _process(self, args):
        room = Room.get_one(args.pop('room_id'))
        user_id = args.pop('user_id', None)
        booked_for = User.get_one(user_id) if user_id else session.user
        is_prebooking = args.pop('is_prebooking')

        # Check that the booking is not longer than allowed
        booking_limit_days = room.booking_limit_days or rb_settings.get('booking_limit')
        if not self._validate_room_booking_limit(args['start_dt'], args['end_dt'], booking_limit_days):
            msg = (_('Bookings for the room "{}" may not be longer than {} days')
                   .format(room.name, booking_limit_days))
            raise ExpectedError(msg)

        try:
            resv = Reservation.create_from_data(room, dict(args, booked_for_user=booked_for), session.user,
                                                prebook=is_prebooking)
            db.session.flush()
        except NoReportError as e:
            db.session.rollback()
            raise ExpectedError(unicode(e))

        serialized_occurrences = serialize_occurrences(group_by_occurrence_date(resv.occurrences.all()))
        if is_prebooking:
            data = {'pre_bookings': serialized_occurrences}
        else:
            data = {'bookings': serialized_occurrences}
        return jsonify(room_id=room.id, **data)
Beispiel #6
0
    def _process(self):
        args = self.args
        args.setdefault('booked_for_user', session.user)

        if not is_booking_start_within_grace_period(args['start_dt'], session.user, args['admin_override_enabled']):
            raise ExpectedError(_('You cannot create a booking which starts in the past'))

        # Check that the booking is not longer than allowed
        booking_limit_days = self.room.booking_limit_days or rb_settings.get('booking_limit')
        if not self._validate_room_booking_limit(args['start_dt'], args['end_dt'], booking_limit_days):
            msg = (_('Bookings for the room "{}" may not be longer than {} days')
                   .format(self.room.name, booking_limit_days))
            raise ExpectedError(msg)

        try:
            resv = Reservation.create_from_data(self.room, args, session.user, prebook=self.prebook)
            if args.get('link_type') is not None and args.get('link_id') is not None:
                self._link_booking(resv, args['link_type'], args['link_id'], args['link_back'])
            db.session.flush()
        except NoReportError as e:
            db.session.rollback()
            raise ExpectedError(unicode(e))

        serialized_occurrences = serialize_occurrences(group_by_occurrence_date(resv.occurrences.all()))
        if self.prebook:
            data = {'pre_bookings': serialized_occurrences}
        else:
            data = {'bookings': serialized_occurrences}
        return jsonify(room_id=self.room.id, booking=reservation_details_schema.dump(resv), calendar_data=data)
Beispiel #7
0
    def _process(self):
        args = self.args
        user_id = args.pop('user_id', None)
        booked_for = User.get_one(user_id, is_deleted=False) if user_id else session.user

        # Check that the booking is not longer than allowed
        booking_limit_days = self.room.booking_limit_days or rb_settings.get('booking_limit')
        if not self._validate_room_booking_limit(args['start_dt'], args['end_dt'], booking_limit_days):
            msg = (_('Bookings for the room "{}" may not be longer than {} days')
                   .format(self.room.name, booking_limit_days))
            raise ExpectedError(msg)

        try:
            resv = Reservation.create_from_data(self.room, dict(args, booked_for_user=booked_for), session.user,
                                                prebook=self.prebook)
            if args.get('link_type') is not None and args.get('link_id') is not None:
                self._link_booking(resv, args['link_type'], args['link_id'], args['link_back'])
            db.session.flush()
        except NoReportError as e:
            db.session.rollback()
            raise ExpectedError(unicode(e))

        serialized_occurrences = serialize_occurrences(group_by_occurrence_date(resv.occurrences.all()))
        if self.prebook:
            data = {'pre_bookings': serialized_occurrences}
        else:
            data = {'bookings': serialized_occurrences}
        return jsonify(room_id=self.room.id, booking=reservation_details_schema.dump(resv).data, calendar_data=data)
Beispiel #8
0
    def _process(self):
        args = self.args
        args.setdefault('booked_for_user', session.user)

        if not is_booking_start_within_grace_period(args['start_dt'], session.user, args['admin_override_enabled']):
            raise ExpectedError(_('You cannot create a booking which starts in the past'))

        # Check that the booking is not longer than allowed
        booking_limit_days = self.room.booking_limit_days or rb_settings.get('booking_limit')
        if not self._validate_room_booking_limit(args['start_dt'], args['end_dt'], booking_limit_days):
            msg = (_('Bookings for the room "{}" may not be longer than {} days')
                   .format(self.room.name, booking_limit_days))
            raise ExpectedError(msg)

        try:
            resv = Reservation.create_from_data(self.room, args, session.user, prebook=self.prebook)
            if args.get('link_type') is not None and args.get('link_id') is not None:
                self._link_booking(resv, args['link_type'], args['link_id'], args['link_back'])
            db.session.flush()
        except NoReportError as e:
            db.session.rollback()
            raise ExpectedError(unicode(e))

        serialized_occurrences = serialize_occurrences(group_by_occurrence_date(resv.occurrences.all()))
        if self.prebook:
            data = {'pre_bookings': serialized_occurrences}
        else:
            data = {'bookings': serialized_occurrences}
        return jsonify(room_id=self.room.id, booking=reservation_details_schema.dump(resv), calendar_data=data)
Beispiel #9
0
 def _create_booking(self, form, room):
     if 'submit_book' in form and 'submit_prebook' in form:
         # Admins have the choice
         prebook = form.submit_prebook.data
     else:
         # Otherwise the existence of the book submit button means the user can book
         prebook = 'submit_book' not in form
     reservation = Reservation.create_from_data(room, form.data, session.user, prebook)
     db.session.add(reservation)
     db.session.flush()
     return reservation
Beispiel #10
0
 def _create_booking(self, form, room):
     if 'submit_book' in form and 'submit_prebook' in form:
         # Admins have the choice
         prebook = form.submit_prebook.data
     else:
         # Otherwise the existence of the book submit button means the user can book
         prebook = 'submit_book' not in form
     reservation = Reservation.create_from_data(room, form.data, session.user, prebook)
     db.session.add(reservation)
     db.session.flush()
     return reservation
Beispiel #11
0
def split_booking(booking, new_booking_data):
    is_ongoing_booking = booking.start_dt.date() < date.today() < booking.end_dt.date()
    if not is_ongoing_booking:
        return

    cancelled_dates = []
    rejected_occs = {}
    room = booking.room
    occurrences = sorted(booking.occurrences, key=attrgetter('start_dt'))
    old_frequency = booking.repeat_frequency
    occurrences_to_cancel = [occ for occ in occurrences if occ.start_dt >= datetime.now() and occ.is_valid]

    if old_frequency != RepeatFrequency.NEVER and new_booking_data['repeat_frequency'] == RepeatFrequency.NEVER:
        new_start_dt = new_booking_data['start_dt']
    else:
        new_start_dt = datetime.combine(occurrences_to_cancel[0].start_dt.date(), new_booking_data['start_dt'].time())
        cancelled_dates = [occ.start_dt.date() for occ in occurrences if occ.is_cancelled]
        rejected_occs = {occ.start_dt.date(): occ.rejection_reason for occ in occurrences if occ.is_rejected}

        new_end_dt = [occ for occ in occurrences if occ.start_dt < datetime.now()][-1].end_dt
        old_booking_data = {
            'booking_reason': booking.booking_reason,
            'booked_for_user': booking.booked_for_user,
            'start_dt': booking.start_dt,
            'end_dt': new_end_dt,
            'repeat_frequency': booking.repeat_frequency,
            'repeat_interval': booking.repeat_interval,
        }

        booking.modify(old_booking_data, session.user)

    for occurrence_to_cancel in occurrences_to_cancel:
        occurrence_to_cancel.cancel(session.user, silent=True)

    prebook = not room.can_book(session.user, allow_admin=False) and room.can_prebook(session.user, allow_admin=False)
    resv = Reservation.create_from_data(room, dict(new_booking_data, start_dt=new_start_dt), session.user,
                                        prebook=prebook, ignore_admin=True)
    for new_occ in resv.occurrences:
        new_occ_start = new_occ.start_dt.date()
        if new_occ_start in cancelled_dates:
            new_occ.cancel(None, silent=True)
        if new_occ_start in rejected_occs:
            new_occ.reject(None, rejected_occs[new_occ_start], silent=True)

    booking.edit_logs.append(ReservationEditLog(user_name=session.user.full_name, info=[
        'Split into a new booking',
        f'booking_link:{resv.id}'
    ]))
    resv.edit_logs.append(ReservationEditLog(user_name=session.user.full_name, info=[
        'Split from another booking',
        f'booking_link:{booking.id}'
    ]))
    return resv
Beispiel #12
0
def create_booking_for_event(room_id, event):
    try:
        room = Room.get_one(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 = "Event '%s'" % (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)
        resv = Reservation.create_from_data(room, data, session.user, ignore_admin=True)
        return resv
    except NoReportError:
        flash(_("Booking could not be created. Probably somebody else booked the room in the meantime."), 'error')
Beispiel #13
0
def split_booking(booking, new_booking_data):
    is_ongoing_booking = booking.start_dt.date() < date.today(
    ) < booking.end_dt.date()
    if not is_ongoing_booking:
        return

    room = booking.room
    occurrences = sorted(booking.occurrences, key=attrgetter('start_dt'))
    occurrences_to_cancel = [
        occ for occ in occurrences if occ.start_dt.date() >= date.today()
    ]
    new_start_dt = datetime.combine(occurrences_to_cancel[0].start_dt.date(),
                                    new_booking_data['start_dt'].time())
    for occurrence_to_cancel in occurrences_to_cancel:
        occurrence_to_cancel.cancel(session.user, silent=True)

    new_end_dt = [
        occ for occ in occurrences if occ.start_dt.date() < date.today()
    ][-1].end_dt
    old_booking_data = {
        'booking_reason':
        booking.booking_reason,
        'room_usage':
        'current_user'
        if booking.booked_for_user == session.user else 'someone',
        'booked_for_user':
        booking.booked_for_user,
        'start_dt':
        booking.start_dt,
        'end_dt':
        new_end_dt,
        'repeat_frequency':
        booking.repeat_frequency,
        'repeat_interval':
        booking.repeat_interval,
    }

    booking.modify(old_booking_data, session.user)
    prebook = not room.can_book(session.user,
                                allow_admin=False) and room.can_prebook(
                                    session.user, allow_admin=False)
    return Reservation.create_from_data(room,
                                        dict(new_booking_data,
                                             start_dt=new_start_dt),
                                        session.user,
                                        prebook=prebook)
Beispiel #14
0
 def api_roomBooking(self, user):
     data = MultiDict({
         'start_dt': self._params['from'],
         'end_dt': self._params['to'],
         'repeat_frequency': RepeatFrequency.NEVER,
         'repeat_interval': 0,
         'room_id': self._room.id,
         'booked_for_user': self._params['booked_for'],
         'booking_reason': self._params['reason']
     })
     try:
         reservation = Reservation.create_from_data(self._room, data, user)
     except ConflictingOccurrences:
         raise HTTPAPIError('Failed to create the booking due to conflicts with other bookings')
     except IndicoError as e:
         raise HTTPAPIError('Failed to create the booking: {}'.format(e))
     db.session.add(reservation)
     db.session.flush()
     return {'reservationID': reservation.id}
Beispiel #15
0
 def api_roomBooking(self, user):
     data = MultiDict({
         'start_dt': self._params['from'],
         'end_dt': self._params['to'],
         'repeat_frequency': RepeatFrequency.NEVER,
         'repeat_interval': 0,
         'room_id': self._room.id,
         'booked_for_user': self._params['booked_for'],
         'booking_reason': self._params['reason']
     })
     try:
         reservation = Reservation.create_from_data(self._room, data, user)
     except ConflictingOccurrences:
         raise HTTPAPIError('Failed to create the booking due to conflicts with other bookings')
     except IndicoError as e:
         raise HTTPAPIError('Failed to create the booking: {}'.format(e))
     db.session.add(reservation)
     db.session.flush()
     return {'reservationID': reservation.id}