JourneyJoker/auction/views.py

201 lines
No EOL
7.4 KiB
Python

from django.views.generic import CreateView, UpdateView, View, ListView, DetailView, FormView
from django.shortcuts import redirect, get_object_or_404
from django.contrib import messages
from django.urls import reverse, reverse_lazy
from django.contrib.gis.geos import Point
from django.contrib.gis.db.models.functions import Distance
from django.conf import settings
from django.utils import timezone
from public.mixins import InConstructionMixin
from partners.mixins import PartnerProfileRequiredMixin
from clients.mixins import ClientBaseMixin
from localauth.helpers import name_to_coords
from partners.models import Establishment
from payment.models import BillingAddress, Invoice, InvoiceItem, InvoicePayment
from clients.models import ClientProfile
from .models import Inquiry, Offer
from .forms import InquiryProcessForm, OfferSelectionForm
class InquiryCreateView(ClientBaseMixin, CreateView):
model = Inquiry
fields = ["destination_name", "budget", "arrival", "min_nights", "adults", "children"]
def get(self, request, *args, **kwargs):
return redirect("/")
def form_valid(self, form):
form.instance.destination_coords = self.clean_destination_coords()
form.instance.destination_radius = 5000
return super().form_valid(form)
def form_invalid(self, form, *args, **kwargs):
for field in form:
for error in field.errors:
messages.error(self.request, f"{field.name}: {error}")
return redirect("/")
def get_success_url(self):
return reverse("auction:process_inquiry", args=(self.object.uuid,))
def clean_destination_coords(self):
lat, lon = name_to_coords(self.request.POST.get("destination_name"))
return Point(lon, lat)
class InquiryProcessView(ClientBaseMixin, UpdateView):
form_class = InquiryProcessForm
model = Inquiry
template_name = "auction/process.html"
def get_object(self):
return Inquiry.objects.get(uuid=self.kwargs["uuid"])
def get_initial(self):
initial = super().get_initial()
try:
initial["country"] = self.request.user.clientprofile.country.code
except:
pass
return initial
def form_valid(self, form):
profile, _ = ClientProfile.objects.get_or_create(user=self.request.user)
profile.first_name = form.cleaned_data["first_name"]
profile.last_name = form.cleaned_data["last_name"]
profile.street = form.cleaned_data["street"]
profile.city = form.cleaned_data["city"]
profile.zip = form.cleaned_data["zip"]
profile.state = form.cleaned_data["state"]
profile.country = form.cleaned_data["country"]
profile.save()
form.instance.client = profile
return super().form_valid(form)
def form_invalid(self, form, *args, **kwargs):
for field in form:
for error in field.errors:
messages.error(self.request, f"{field.name}: {error}")
return redirect("/")
def get_success_url(self):
return reverse("auction:inquiry_payment", args=(self.object.uuid,))
class InquiryPaymentView(View):
def get(self, request, *args, **kwargs):
inquiry = Inquiry.objects.get(uuid=kwargs["uuid"])
try:
invoice = inquiry.invoice
except Invoice.DoesNotExist:
invoice = Invoice.from_inquiry(inquiry)
payment_url = InvoicePayment.from_invoice(invoice, inquiry.gateway)
return redirect(payment_url)
class OfferSelectionView(ClientBaseMixin, FormView, DetailView):
model = Inquiry
template_name = "auction/offer_select.html"
form_class = OfferSelectionForm
def get_object(self):
return get_object_or_404(Inquiry, uuid=self.kwargs["uuid"], client=self.request.user.clientprofile)
def form_valid(self, form):
inquiry = self.get_object()
offer = get_object_or_404(Offer, inquiry=inquiry, uuid=form.cleaned_data["offer"])
offer.accepted = timezone.now()
offer.save()
return super().form_valid(form)
def get_success_url(self):
return reverse_lazy("clients:booking_view", args=[self.kwargs["uuid"]])
class OfferSelectionTableView(ClientBaseMixin, ListView):
model = Offer
content_type = "text/javascript"
template_name = "auction/offer_table.js"
def get_queryset(self):
inquiry = get_object_or_404(Inquiry, uuid=self.kwargs["uuid"], client=self.request.user.clientprofile)
return inquiry.offer_set.all()
class OfferCreationView(InConstructionMixin, PartnerProfileRequiredMixin, CreateView):
model = Offer
template_name = "auction/offer_create.html"
fields = ["roomcategory", "departure", "comment"]
def dispatch(self, request, *args, **kwargs):
self.establishment = self.get_establishment()
self.inquiry = self.get_inquiry()
if not self.establishment:
messages.warning(request, "Um bieten zu können, muss zuerst eine Unterkunft im System hinterlegt werden!")
return redirect("partners:establishment_register")
return super().dispatch(request, *args, **kwargs)
def get_establishment(self):
establishment = self.kwargs.get("establishment", None)
kwargs = {"owner": self.request.user.partnerprofile}
if establishment:
kwargs["id"] = establishment
return get_object_or_404(Establishment, **kwargs)
else:
return Establishment.objects.filter(**kwargs).first()
def get_inquiry(self):
return get_object_or_404(Inquiry, uuid=self.kwargs.get("inquiry"))
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["establishment"] = self.establishment
context["inquiry"] = self.inquiry
return context
def form_valid(self, form):
form.instance.inquiry = self.inquiry
return super().form_valid(form)
def get_success_url(self):
messages.success(self.request, "Angebot erfolgreich erstellt! Viel Erfolg!")
return reverse_lazy("auction:bidding", args=[self.establishment.id])
class BiddingListView(InConstructionMixin, PartnerProfileRequiredMixin, ListView):
model = Inquiry
template_name = "auction/bidding_list.html"
def dispatch(self, request, *args, **kwargs):
self.establishment = self.get_establishment()
if not self.establishment:
messages.warning(request, "Um bieten zu können, muss zuerst eine Unterkunft im System hinterlegt werden!")
return redirect("partners:establishment_register")
return super().dispatch(request, *args, **kwargs)
def get_establishment(self):
establishment = self.kwargs.get("id", None)
kwargs = {"owner": self.request.user.partnerprofile}
if establishment:
kwargs["id"] = establishment
return get_object_or_404(Establishment, **kwargs)
else:
return Establishment.objects.filter(**kwargs).first()
def get_queryset(self):
establishment = self.get_establishment()
excluded = [offer.inquiry.id for offer in establishment.offer_set.all()]
return Inquiry.objects.annotate(distance=Distance("destination_coords", establishment.coords)).exclude(activated__isnull=True).exclude(id__in=excluded)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["establishment"] = self.establishment
return context