def CheckRoomAvailability(request, location_slug): if not request.method == 'POST': return HttpResponseRedirect('/404') location=get_location(location_slug) arrive_str = request.POST.get('arrive') depart_str = request.POST.get('depart') a_month, a_day, a_year = arrive_str.split("/") d_month, d_day, d_year = depart_str.split("/") arrive = datetime.date(int(a_year), int(a_month), int(a_day)) depart = datetime.date(int(d_year), int(d_month), int(d_day)) availability = location.availability(arrive, depart) date_list = date_range_to_list(arrive, depart) available_reservations = {} # Create some mock reservations for each available room so we can generate the bill free_rooms = location.rooms_free(arrive, depart) for room in free_rooms: reservation = Reservation(id=-1, room=room, arrive=arrive, depart=depart, location=location) bill_line_items = reservation.generate_bill(delete_old_items=False, save=False) total = 0 for item in bill_line_items: if not item.paid_by_house: total = total + item.amount nights = reservation.total_nights() available_reservations[room] = {'reservation':reservation, 'bill_line_items':bill_line_items, 'nights':nights, 'total':total} return render(request, "snippets/availability_calendar.html", {"availability_table": availability, "dates": date_list, 'available_reservations': available_reservations, })
def CheckRoomAvailability(request, location_slug): if not request.method == 'POST': return HttpResponseRedirect('/404') location=get_location(location_slug) arrive_str = request.POST.get('arrive') depart_str = request.POST.get('depart') a_month, a_day, a_year = arrive_str.split("/") d_month, d_day, d_year = depart_str.split("/") arrive = datetime.date(int(a_year), int(a_month), int(a_day)) depart = datetime.date(int(d_year), int(d_month), int(d_day)) availability_table = Room.objects.availability(arrive, depart, location) # all rooms should have an associated list of the same length that covers # all days, so just grab the dates from any one of them (they are already # sorted). per_date_avail = availability_table[availability_table.keys()[0]] dates = [tup[0] for tup in per_date_avail] available_reservations = {} # Create some mock reservations for each available room so we can generate the bill for room in Room.objects.free(arrive, depart, location): reservation = Reservation(id=-1, room=room, arrive=arrive, depart=depart, location=location) bill_line_items = reservation.generate_bill(delete_old_items=False, save=False) total = 0 for item in bill_line_items: if not item.paid_by_house: total = total + item.amount nights = reservation.total_nights() available_reservations[room] = {'reservation':reservation, 'bill_line_items':bill_line_items, 'nights':nights, 'total':total} return render(request, "snippets/availability_calendar.html", {"availability_table": availability_table, "dates": dates, 'available_reservations': available_reservations, })
def ReservationSubmit(request, location_slug): location=get_location(location_slug) if request.method == 'POST': form = ReservationForm(location, request.POST) if form.is_valid(): reservation = form.save(commit=False) reservation.user = request.user reservation.location = location reservation.save() # Resetting the rate will also generate a bill reservation.reset_rate() new_reservation_notify(reservation) messages.add_message(request, messages.INFO, 'Thanks! Your reservation was submitted. You will receive an email when it has been reviewed. Please <a href="/people/%s/edit/">update your profile</a> if your projects or other big ideas have changed since your last visit.<br><br>You can still modify your reservation.' % reservation.user.username) return HttpResponseRedirect(reverse('reservation_detail', args=(location_slug, reservation.id))) else: print form.errors # GET request else: form = ReservationForm(location) # pass the rate for each room to the template so we can update the cost of # a reservation in real time. rooms = Room.objects.all() room_list = {} for room in rooms: room_list[room.name] = room.default_rate room_list = json.dumps(room_list) return render(request, 'reservation.html', {'form': form, "room_list": room_list, 'max_days': location.max_reservation_days, 'location': location })
def view_room(request, location_slug, room_id): location = get_location(location_slug) room = get_object_or_404(Room, id=room_id) today = timezone.localtime(timezone.now()) month = request.GET.get("month") year = request.GET.get("year") start, end, next_month, prev_month, month, year = get_calendar_dates(month, year) return render(request, "room.html", {'room': room, 'location': location, "next_month": next_month, "prev_month": prev_month})
def ReservationRecalculateBill(request, location_slug, reservation_id): if not request.method == 'POST': return HttpResponseRedirect('/404') location = get_location(location_slug) reservation = Reservation.objects.get(id=reservation_id) reservation.generate_bill() messages.add_message(request, messages.INFO, "The bill has been recalculated.") return HttpResponseRedirect(reverse('reservation_manage', args=(location.slug, reservation_id)))
def ReservationEdit(request, reservation_id, location_slug): logger.debug("Entering ReservationEdit") location = get_location(location_slug) reservation = Reservation.objects.get(id=reservation_id) # need to pull these dates out before we pass the instance into # the ReservationForm, since it (apparently) updates the instance # immediately (which is weird, since it hasn't validated the form # yet!) original_arrive = reservation.arrive original_depart = reservation.depart original_room = reservation.room if request.user.is_authenticated() and request.user == reservation.user: logger.debug("ReservationEdit: Authenticated and same user") if request.user in reservation.location.house_admins.all(): is_house_admin = True else: is_house_admin = False if request.method == "POST": logger.debug("ReservationEdit: POST") # don't forget to specify the "instance" argument or a new object will get created! #form = get_reservation_form_for_perms(request, post=True, instance=reservation) form = ReservationForm(location, request.POST, instance=reservation) if form.is_valid(): logger.debug("ReservationEdit: Valid Form") # if the dates have been changed, and the reservation isn't # still pending to begin with, notify an admin and go back to # pending. logger.debug("is_pending: %s" % reservation.is_pending()) logger.debug("arrive: %s, original: %s" % (reservation.arrive, original_arrive)) logger.debug("depart: %s, original: %s" % (reservation.depart, original_depart)) logger.debug("room: %s, original: %s" % (reservation.room, original_room)) if (not reservation.is_pending() and (reservation.arrive != original_arrive or reservation.depart != original_depart or reservation.room != original_room )): logger.debug("reservation room or date was changed. updating status.") reservation.pending() # notify house_admins by email updated_reservation_notify(reservation) client_msg = 'The reservation was updated and the new information will be reviewed for availability.' else: client_msg = 'The reservation was updated.' # save the instance *after* the status has been updated as needed. form.save() messages.add_message(request, messages.INFO, client_msg) return HttpResponseRedirect(reverse("reservation_detail", args=(location.slug, reservation_id))) else: #form = get_reservation_form_for_perms(request, post=False, instance=reservation) form = ReservationForm(location, instance=reservation) return render(request, 'reservation_edit.html', {'form': form, 'reservation_id': reservation_id, 'arrive': reservation.arrive, 'depart': reservation.depart, 'is_house_admin' : is_house_admin, 'location': location }) else: return HttpResponseRedirect("/")
def ReservationSendReceipt(request, location_slug, reservation_id): if not request.method == 'POST': return HttpResponseRedirect('/404') location = get_location(location_slug) reservation = Reservation.objects.get(id=reservation_id) if reservation.is_paid(): send_receipt(reservation) messages.add_message(request, messages.INFO, "The receipt was sent.") return HttpResponseRedirect(reverse('reservation_manage', args=(location.slug, reservation_id)))
def LocationEditContent(request, location_slug): location = get_location(location_slug) if request.method == 'POST': form = LocationContentForm(request.POST, instance=location) if form.is_valid(): form.save() messages.add_message(request, messages.INFO, "Location Updated.") else: form = LocationContentForm(instance=location) return render(request, 'location_edit_content.html', {'page':'content', 'location': location, 'form':form})
def stay(request, location_slug): location = get_location(location_slug) rooms = location.rooms_with_future_reservability() today = timezone.localtime(timezone.now()) month = request.GET.get("month") year = request.GET.get("year") start, end, next_month, prev_month, month, year = get_calendar_dates(month, year) return render(request, "location_stay.html", {'location_stay_text': location.stay_page, 'rooms':rooms, "next_month": next_month, "prev_month": prev_month, 'location': location})
def unsubscribe(request, location_slug): ''' unsubscribe route ''' # fail gracefully if location does not exist try: location = get_location(location_slug) except: # XXX TODO reject and bounce back to sender? return HttpResponse(status=200) logger.debug('unsubscribe@ for location: %s' % location) logger.debug(request.POST) logger.debug(request.FILES) return HttpResponse(status=200)
def decorator(request, location_slug, *args, **kwargs): location = get_location(location_slug) user = request.user if user.is_authenticated() and location and user in location.house_admins.all(): return original_func(request, location_slug, *args, **kwargs) elif request.user.is_authenticated(): return HttpResponseRedirect("/") else: from django.contrib.auth.views import redirect_to_login path = request.get_full_path() login_url = settings.LOGIN_URL return redirect_to_login(path, login_url)
def room_cal_request(request, location_slug, room_id): location = get_location(location_slug) room = Room.objects.get(id=room_id) month = int(request.GET.get("month")) year = int(request.GET.get("year")) cal_html = room.availability_calendar_html(month=month, year=year) start, end, next_month, prev_month, month, year = get_calendar_dates(month, year) link_html = ''' <a class="room-cal-req" href="%s?month=%d&year=%d">Previous</a> | <a class="room-cal-req" href="%s?month=%d&year=%d">Next</a> ''' % (reverse(room_cal_request, args=(location.slug, room.id)), prev_month.month, prev_month.year, reverse(room_cal_request, args=(location.slug, room.id)), next_month.month, next_month.year) return HttpResponse(cal_html+link_html)
def today(request, location_slug): location = get_location(location_slug) # get all the reservations that intersect today (including those departing # and arriving today) today = timezone.now() reservations_today = Reservation.objects.filter(Q(status="confirmed") | Q(status="approved")).exclude(depart__lt=today).exclude(arrive__gt=today) guests_today = [] for r in reservations_today: guests_today.append(r.user) residents = location.residents.all() people_today = guests_today + list(residents) events_today = published_events_today_local(location) return render(request, "today.html", {'people_today': people_today, 'events_today': events_today})
def payments(request, location_slug, year, month): location = get_location(location_slug) start, end, next_month, prev_month, month, year = get_calendar_dates(month, year) payments_this_month = Payment.objects.filter(reservation__location=location, payment_date__gte=start, payment_date__lte=end).order_by('payment_date').reverse() totals = {'count':0, 'house_fees':0, 'to_house':0, 'non_house_fees':0, 'bill_amount':0, 'paid_amount':0} for p in payments_this_month: totals['count'] = totals['count'] + 1 totals['to_house'] = totals['to_house'] + p.to_house() totals['non_house_fees'] = totals['non_house_fees'] + p.non_house_fees() totals['house_fees'] = totals['house_fees'] + p.house_fees() totals['paid_amount'] = totals['paid_amount'] + p.paid_amount return render(request, "payments.html", {'payments': payments_this_month, 'totals':totals, 'location': location, 'this_month':start, 'previous_date':prev_month, 'next_date':next_month, })
def ReservationToggleComp(request, location_slug, reservation_id): if not request.method == 'POST': return HttpResponseRedirect('/404') location = get_location(location_slug) reservation = Reservation.objects.get(pk=reservation_id) if not reservation.is_comped(): # Let these nice people stay here for free reservation.comp() else: # Put the rate back to the default rate reservation.reset_rate() # if confirmed set status back to APPROVED if reservation.is_confirmed(): reservation.approve() return HttpResponseRedirect(reverse('reservation_manage', args=(location.slug, reservation_id)))
def ReservationCancel(request, reservation_id, location_slug): if not request.method == "POST": return HttpResponseRedirect("/404") location = get_location(location_slug) reservation = Reservation.objects.get(id=reservation_id) if (not (request.user.is_authenticated() and request.user == reservation.user) and not request.user in location.house_admins.all()): return HttpResponseRedirect("/404") redirect = request.POST.get("redirect") reservation.cancel() messages.add_message(request, messages.INFO, 'The reservation has been cancelled.') username = reservation.user.username return HttpResponseRedirect(redirect)
def ReservationSendMail(request, location_slug, reservation_id): if not request.method == 'POST': return HttpResponseRedirect('/404') location = get_location(location_slug) subject = request.POST.get("subject") recipient = [request.POST.get("recipient"),] body = request.POST.get("body") + "\n\n" + request.POST.get("footer") # TODO - This isn't fully implemented yet -JLS send_from_location_address(subject, body, None, recipient, location) reservation = Reservation.objects.get(id=reservation_id) reservation.mark_last_msg() messages.add_message(request, messages.INFO, "Your message was sent.") return HttpResponseRedirect(reverse('reservation_manage', args=(location.slug, reservation_id)))
def ReservationManageEdit(request, location_slug, reservation_id): logger.debug("ReservationManageEdit") location = get_location(location_slug) reservation = Reservation.objects.get(id=reservation_id) logger.debug(request.POST) if 'username' in request.POST: try: new_user = User.objects.get(username=request.POST.get("username")) reservation.user = new_user reservation.save() messages.add_message(request, messages.INFO, "User changed.") except: messages.add_message(request, messages.INFO, "Invalid user given!") elif 'arrive' in request.POST: try: arrive = datetime.datetime.strptime(request.POST.get("arrive"), "%Y-%m-%d") depart = datetime.datetime.strptime(request.POST.get("depart"), "%Y-%m-%d") if arrive >= depart: messages.add_message(request, messages.INFO, "Arrival must be at least 1 day before Departure.") else: reservation.arrive = arrive reservation.depart = depart reservation.save() reservation.generate_bill() messages.add_message(request, messages.INFO, "Dates changed.") except: messages.add_message(request, messages.INFO, "Invalid dates given!") elif 'room_id' in request.POST: try: new_room = Room.objects.get(pk=request.POST.get("room_id")) reservation.room = new_room reservation.save() reservation.reset_rate() messages.add_message(request, messages.INFO, "Room changed.") except: messages.add_message(request, messages.INFO, "Invalid room given!") elif 'rate' in request.POST: rate = request.POST.get("rate") if not rate.isdigit(): messages.add_message(request, messages.ERROR, "Invalid rate given!") else: int_rate = int(rate) if int_rate >= 0 and int_rate != reservation.get_rate(): reservation.set_rate(int_rate) messages.add_message(request, messages.INFO, "Rate changed.") return HttpResponseRedirect(reverse('reservation_manage', args=(location_slug, reservation_id)))
def announce(request, location_slug): ''' email all people signed up for event activity notifications at this location.''' # fail gracefully if location does not exist try: location = get_location(location_slug) except: # XXX TODO reject and bounce back to sender? logger.error('location not found') return HttpResponse(status=200) logger.debug('announce@ for location: %s' % location) # Make sure this person can post to our list sender = request.POST.get('from') location_event_admins = EventAdminGroup.objects.get( location=location).users.all() allowed_senders = [user.email for user in location_event_admins] # have to be careful here because the "sender" email address is likely a # substring of the entire 'from' field in the POST request, ie, "Jessy Kate # Schingler <*****@*****.**>" this_sender_allowed = False for sender_email in allowed_senders: if sender_email in sender: this_sender_allowed = True break if not this_sender_allowed: # TODO - This could send a response so they know they were blocked logger.warn("Sender (%s) not allowed. Exiting quietly." % sender) return HttpResponse(status=200) weekly_notifications_on = EventNotifications.objects.filter( location_weekly=location) remindees_for_location = [ notify.user for notify in weekly_notifications_on ] # TESTING jessy = User.objects.get(id=1) for user in [ jessy, ]: #for user in remindees_for_location: send_announce(request, user, location) return HttpResponse(status=200)
def LocationEditUsers(request, location_slug): location = get_location(location_slug) if request.method == 'POST': username = request.POST.get('username') user = User.objects.get(username=username) action = request.POST.get('action') if action == "Remove": # Remove user location.house_admins.remove(user) location.save() messages.add_message(request, messages.INFO, "User '%s' Removed." % username) elif action == "Add": # Add user location.house_admins.add(user) location.save() messages.add_message(request, messages.INFO, "User '%s' Added." % username) all_users = User.objects.all().order_by('username') return render(request, 'location_edit_users.html', {'page':'users', 'location': location, 'all_users':all_users})
def calendar(request, location_slug): location = get_location(location_slug) today = timezone.localtime(timezone.now()) month = request.GET.get("month") year = request.GET.get("year") start, end, next_month, prev_month, month, year = get_calendar_dates(month, year) report_date = datetime.date(year, month, 1) reservations = (Reservation.objects.filter(Q(status="confirmed") | Q(status="approved")) .filter(location=location).exclude(depart__lt=start).exclude(arrive__gt=end).order_by('arrive')) # create the calendar object guest_calendar = GuestCalendar(reservations, year, month, location).formatmonth(year, month) return render(request, "calendar.html", {'reservations': reservations, 'calendar': mark_safe(guest_calendar), "next_month": next_month, "prev_month": prev_month, "report_date": report_date, 'location': location })
def ReservationReceipt(request, location_slug, reservation_id): location = get_location(location_slug) reservation = get_object_or_404(Reservation, id=reservation_id) if request.user != reservation.user or location != reservation.location: if not request.user.is_staff: return HttpResponseRedirect("/404") # I want to render the receipt exactly like we do in the email htmltext = get_template('emails/receipt.html') c = Context({ 'today': timezone.localtime(timezone.now()), 'user': reservation.user, 'location': reservation.location, 'reservation': reservation, }) receipt_html = htmltext.render(c) return render(request, 'reservation_receipt.html', {'receipt_html': receipt_html, 'reservation': reservation, 'location': location })
def ReservationManage(request, location_slug, reservation_id): location = get_location(location_slug) reservation = get_object_or_404(Reservation, id=reservation_id) user = User.objects.get(username=reservation.user.username) other_reservations = Reservation.objects.filter(user=user).exclude(status='deleted').exclude(id=reservation_id) past_reservations = [] upcoming_reservations = [] for res in other_reservations: if res.arrive >= datetime.date.today(): upcoming_reservations.append(res) else: past_reservations.append(res) domain = Site.objects.get_current().domain emails = EmailTemplate.objects.filter(Q(shared=True) | Q(creator=request.user)) email_forms = [] email_templates_by_name = [] for email_template in emails: form = EmailTemplateForm(email_template, reservation, location) email_forms.append(form) email_templates_by_name.append(email_template.name) availability = Room.objects.availability(reservation.arrive, reservation.depart, location) free = Room.objects.free(reservation.arrive, reservation.depart, location) per_date_avail = availability[availability.keys()[0]] dates = [tup[0] for tup in per_date_avail] if reservation.room in free: room_has_availability = True else: room_has_availability = False edit_form = ReservationForm(location, request.POST, instance=reservation) return render(request, 'reservation_manage.html', { "r": reservation, "past_reservations":past_reservations, "upcoming_reservations": upcoming_reservations, "email_forms" : email_forms, "email_templates_by_name" : email_templates_by_name, "days_before_welcome_email" : location.welcome_email_days_ahead, "room_has_availability" : room_has_availability, "avail": availability, "dates": dates, "domain": domain, 'location': location, "edit_form": edit_form, })
def ReservationManagePayment(request, location_slug, reservation_id): if not request.method == 'POST': return HttpResponseRedirect('/404') location = get_location(location_slug) reservation = get_object_or_404(Reservation, id=reservation_id) action = request.POST.get("action") if action == "Refund": payment_id = request.POST.get("payment_id") payment = get_object_or_404(Payment, id=payment_id) payment_gateway.issue_refund(payment) elif action == "Add": payment_method = request.POST.get("payment_method").strip().title() paid_amount = request.POST.get("paid_amount").strip() Payment.objects.create(reservation=reservation, payment_method = payment_method, paid_amount = paid_amount, transaction_id = "Manual" ) return HttpResponseRedirect(reverse('reservation_manage', args=(location_slug, reservation_id)))
def ReservationDetail(request, reservation_id, location_slug): location = get_location(location_slug) try: reservation = Reservation.objects.get(id=reservation_id) if not reservation: raise Reservation.DoesNotExist except Reservation.DoesNotExist: msg = 'The reservation you requested do not exist' messages.add_message(request, messages.ERROR, msg) return HttpResponseRedirect('/404') else: if reservation.arrive >= datetime.date.today(): past = False else: past = True if reservation.is_paid(): paid = True else: paid = False return render(request, "reservation_detail.html", {"reservation": reservation, "past":past, 'location': location, "stripe_publishable_key":settings.STRIPE_PUBLISHABLE_KEY, "paid": paid, "contact" : location.from_email()})
def ReservationAddBillLineItem(request, location_slug, reservation_id): # can be used to apply a discount or a one time charge for, for example, a # cleaning fee. if not request.method == 'POST': return HttpResponseRedirect('/404') location = get_location(location_slug) reservation = Reservation.objects.get(pk=reservation_id) reason = request.POST.get("reason") try: amount = -float(request.POST.get("discount")) reason = "Discount: " + reason except: # then it's a fee amount = float(request.POST.get("extra_fee")) reason = "Fee: " + reason new_line_item = BillLineItem(reservation=reservation, description=reason, amount=amount, paid_by_house=False, custom=True) new_line_item.save() # regenerate the bill now that we've applied some new fees reservation.generate_bill() return HttpResponseRedirect(reverse('reservation_manage', args=(location.slug, reservation_id)))
def ReservationManageList(request, location_slug): if request.method == "POST": reservation_id = request.POST.get('reservation_id') reservation = get_object_or_404(Reservation, id=reservation_id) return HttpResponseRedirect(reverse('reservation_manage', args=(reservation.location.slug, reservation.id))) location = get_location(location_slug) show_all = False if 'show_all' in request.GET and request.GET.get('show_all') == "True": show_all = True pending = Reservation.objects.filter(location=location).filter(status="pending").order_by('-id') approved = Reservation.objects.filter(location=location).filter(status="approved").order_by('-id') confirmed = Reservation.objects.filter(location=location).filter(status="confirmed").order_by('-id') canceled = Reservation.objects.filter(location=location).exclude(status="confirmed").exclude(status="approved").exclude(status="pending").order_by('-id') if not show_all: today = timezone.localtime(timezone.now()) confirmed = confirmed.filter(depart__gt=today) canceled = canceled.filter(depart__gt=today) return render(request, 'reservation_list.html', {"pending": pending, "approved": approved, "confirmed": confirmed, "canceled": canceled, 'location': location})
def PeopleDaterangeQuery(request, location_slug): location = get_location(location_slug) start_str = request.POST.get('start_date') end_str = request.POST.get('end_date') s_month, s_day, s_year = start_str.split("/") e_month, e_day, e_year = end_str.split("/") start_date = datetime.date(int(s_year), int(s_month), int(s_day)) end_date = datetime.date(int(e_year), int(e_month), int(e_day)) reservations_for_daterange = Reservation.objects.filter(Q(status="confirmed")).exclude(depart__lt=start_date).exclude(arrive__gte=end_date) recipients = [] for r in reservations_for_daterange: recipients.append(r.user) residents = location.residents.all() recipients = recipients + list(residents) html = "<div class='btn btn-info disabled' id='recipient-list'>Your message will go to these people: " for person in recipients: info = "<a class='link-light-color' href='/people/" + person.username + "'>" + person.first_name + " " + person.last_name + "</a>, " html += info; html = html.strip(", ") html += "</div>" return HttpResponse(html)
def ReservationManageAction(request, location_slug, reservation_id): if not request.method == 'POST': return HttpResponseRedirect('/404') location = get_location(location_slug) reservation = Reservation.objects.get(id=reservation_id) reservation_action = request.POST.get('reservation-action') try: if reservation_action == 'set-tentative': reservation.approve() elif reservation_action == 'set-confirm': reservation.confirm() days_until_arrival = (reservation.arrive - datetime.date.today()).days if days_until_arrival <= location.welcome_email_days_ahead: guest_welcome(reservation) elif reservation_action == 'set-comp': reservation.comp() elif reservation_action == 'refund-card': try: payments = reservation.payments() if payments.count() == 0: Reservation.ResActionError("No payments to refund!") if payments.count() > 1: Reservation.ResActionError("Multiple payments found!") payment_gateway.issue_refund(payments[0]) except stripe.CardError, e: raise Reservation.ResActionError(e) elif reservation_action == 'res-charge-card': try: payment_gateway.charge_card(reservation) reservation.confirm() send_receipt(reservation) days_until_arrival = (reservation.arrive - datetime.date.today()).days if days_until_arrival <= location.welcome_email_days_ahead: guest_welcome(reservation) except stripe.CardError, e: raise Reservation.ResActionError(e)
def guest_rooms(request, location_slug): location = get_location(location_slug) rooms = location.guest_rooms() return render(request, "location_rooms.html", {'rooms': rooms, 'location': location})
def LocationEditEmails(request, location_slug): location = get_location(location_slug) form = LocationSettingsForm(instance=location) return render(request, 'location_edit_settings.html', {'page':'emails', 'location': location, 'form':form})
def residents(request, location_slug): location = get_location(location_slug) residents = location.residents.all() return render(request, "location_residents.html", {'residents': residents, 'location': location})