def cancel_the_reservation(reservation: Reservation, user_cancelling_reservation: User, reason: Optional[str]): response = check_policy_to_cancel_reservation(reservation, user_cancelling_reservation) # Staff must provide a reason when cancelling a reservation they do not own. if reservation.user != user_cancelling_reservation and not reason: response = HttpResponseBadRequest("You must provide a reason when cancelling someone else's reservation.") if response.status_code == HTTPStatus.OK: # All policy checks passed, so cancel the reservation. reservation.cancelled = True reservation.cancellation_time = timezone.now() reservation.cancelled_by = user_cancelling_reservation if reason: ''' don't notify in this case since we are sending a specific email for the cancellation ''' reservation.save() dictionary = { 'staff_member': user_cancelling_reservation, 'reservation': reservation, 'reason': reason, 'template_color': bootstrap_primary_color('info') } email_contents = get_media_file_contents('cancellation_email.html') if email_contents: cancellation_email = Template(email_contents).render(Context(dictionary)) if getattr(reservation.user.preferences, 'attach_cancelled_reservation', False): attachment = create_ics_for_reservation(reservation, cancelled=True) reservation.user.email_user('Your reservation was cancelled', cancellation_email, user_cancelling_reservation.email, [attachment]) else: reservation.user.email_user('Your reservation was cancelled', cancellation_email, user_cancelling_reservation.email) else: ''' here the user cancelled his own reservation so notify him ''' reservation.save_and_notify() return response
def modify_reservation(request, start_delta, end_delta): """ Cancel the user's old reservation and create a new one. Reservations are cancelled and recreated so that reservation abuse can be tracked if necessary. This function should be called by other views and should not be tied directly to a URL. """ try: reservation_to_cancel = Reservation.objects.get(pk=request.POST.get('id')) except Reservation.DoesNotExist: return HttpResponseNotFound("The reservation that you wish to modify doesn't exist!") explicit_policy_override = False try: explicit_policy_override = request.POST['explicit_policy_override'] == 'true' except: pass response = check_policy_to_cancel_reservation(reservation_to_cancel, request.user) # Do not move the reservation if the user was not authorized to cancel it. if response.status_code != HTTPStatus.OK: return response # Record the current time so that the timestamp of the cancelled reservation and the new reservation match exactly. now = timezone.now() # Cancel the user's original reservation. reservation_to_cancel.cancelled = True reservation_to_cancel.cancellation_time = now reservation_to_cancel.cancelled_by = request.user # Create a new reservation for the user. new_reservation = Reservation() new_reservation.title = reservation_to_cancel.title new_reservation.creator = request.user new_reservation.additional_information = reservation_to_cancel.additional_information # A change in start time will only be provided if the reservation is being moved. new_reservation.start = reservation_to_cancel.start new_reservation.self_configuration = reservation_to_cancel.self_configuration new_reservation.short_notice = False if start_delta: new_reservation.start += start_delta if new_reservation.self_configuration: # Reservation can't be short notice since the user is configuring the tool themselves. new_reservation.short_notice = False elif new_reservation.tool: new_reservation.short_notice = determine_insufficient_notice(reservation_to_cancel.tool, new_reservation.start) # A change in end time will always be provided for reservation move and resize operations. new_reservation.end = reservation_to_cancel.end + end_delta new_reservation.reservation_item = reservation_to_cancel.reservation_item new_reservation.project = reservation_to_cancel.project new_reservation.user = reservation_to_cancel.user new_reservation.creation_time = now policy_problems, overridable = check_policy_to_save_reservation(cancelled_reservation=reservation_to_cancel, new_reservation=new_reservation, user_creating_reservation=request.user, explicit_policy_override=explicit_policy_override) if policy_problems: reservation_action = "resize" if start_delta is None else "move" return render(request, 'calendar/policy_dialog.html', {'policy_problems': policy_problems, 'overridable': overridable and request.user.is_staff, 'reservation_action': reservation_action}) else: # All policy checks passed, so save the reservation. new_reservation.save_and_notify() reservation_to_cancel.descendant = new_reservation reservation_to_cancel.save_and_notify() return reservation_success(request, new_reservation)
def cancel_reservation(request, reservation_id): """ Cancel a reservation for a user. """ reservation = get_object_or_404(Reservation, id=reservation_id) response = check_policy_to_cancel_reservation(reservation, request.user) # Staff must provide a reason when cancelling a reservation they do not own. reason = parse_parameter_string(request.POST, 'reason') if reservation.user != request.user and not reason: response = HttpResponseBadRequest( "You must provide a reason when cancelling someone else's reservation." ) if response.status_code == HTTPStatus.OK: # All policy checks passed, so cancel the reservation. reservation.cancelled = True reservation.cancellation_time = timezone.now() reservation.cancelled_by = request.user reservation.save() if reason: dictionary = { 'staff_member': request.user, 'reservation': reservation, 'reason': reason, 'template_color': bootstrap_primary_color('info') } email_contents = get_media_file_contents('cancellation_email.html') if email_contents: cancellation_email = Template(email_contents).render( Context(dictionary)) reservation.user.email_user('Your reservation was cancelled', cancellation_email, request.user.email) if request.device == 'desktop': return response if request.device == 'mobile': if response.status_code == HTTPStatus.OK: return render(request, 'mobile/cancellation_result.html', { 'event_type': 'Reservation', 'tool': reservation.tool }) else: return render(request, 'mobile/error.html', {'message': response.content})