239 wiersze
8.3 KiB
Python
239 wiersze
8.3 KiB
Python
from typing import Any, Dict
|
|
|
|
from django.views.generic import (
|
|
TemplateView,
|
|
View
|
|
)
|
|
from django.shortcuts import (
|
|
render,
|
|
get_object_or_404
|
|
)
|
|
from django.urls import reverse
|
|
from django.http import HttpResponseRedirect
|
|
from django.contrib import messages
|
|
from rest_framework.viewsets import ViewSet
|
|
from rest_framework.decorators import action
|
|
from rest_framework.response import Response
|
|
|
|
from store.tasks import send_produt_request_email
|
|
from store.cart import (
|
|
SessionCart,
|
|
CustomerData
|
|
)
|
|
from store.serializers import (
|
|
CartSerializer,
|
|
CartProductAddSerializer
|
|
)
|
|
from store.forms import (
|
|
CustomerDataForm,
|
|
ProductTemplateConfigForm
|
|
)
|
|
from store.models import (
|
|
Order,
|
|
Product,
|
|
ProductTemplate,
|
|
ProductListPage
|
|
)
|
|
|
|
|
|
class CartView(TemplateView):
|
|
"""
|
|
This view should simply render cart with initial data, it'll do that each refresh, for
|
|
making actions on cart (using jquery) we will use CartActionView, which will
|
|
be prepared to return JsonResponse.
|
|
"""
|
|
template_name = 'store/cart.html'
|
|
|
|
|
|
def get_context_data(self, **kwargs: Any) -> Dict[str, Any]:
|
|
context = super().get_context_data(**kwargs)
|
|
context["cart"] = SessionCart(self.request)
|
|
return context
|
|
|
|
|
|
class CartActionView(ViewSet):
|
|
|
|
# NOTE - currently not in use
|
|
@action(detail=False, methods=["get"], url_path="list-products")
|
|
def list_products(self, request):
|
|
# get cart items
|
|
cart = SessionCart(self.request)
|
|
items = cart.display_items
|
|
serializer = CartSerializer(instance=items, many=True)
|
|
return Response(serializer.data)
|
|
|
|
@action(detail=False, methods=["post"])
|
|
def add_product(self, request):
|
|
cart = SessionCart(self.request)
|
|
serializer = CartProductAddSerializer(data=request.POST)
|
|
if not serializer.is_valid():
|
|
return Response(serializer.errors, status=400)
|
|
serializer.save(cart)
|
|
items = cart.display_items
|
|
serializer = CartSerializer(instance=items, many=True)
|
|
return Response(serializer.data, status=201)
|
|
|
|
@action(detail=False, methods=["post"])
|
|
def remove_product(self, request):
|
|
cart = SessionCart(self.request)
|
|
product_id = request.POST.get("product_id")
|
|
try:
|
|
cart.remove_item(product_id)
|
|
except Product.DoesNotExist:
|
|
return Response({"error": "Product does not exist"}, status=400)
|
|
|
|
items = cart.display_items
|
|
serializer = CartSerializer(instance=items, many=True)
|
|
return Response(serializer.data, status=201)
|
|
|
|
@action(detail=True, methods=["put"])
|
|
def update_product(self, request, pk):
|
|
cart = SessionCart(self.request)
|
|
try:
|
|
cart.update_item_quantity(pk, int(request.data["quantity"]))
|
|
except Product.DoesNotExist:
|
|
return Response({"error": "Product does not exist"}, status=404)
|
|
items = cart.display_items
|
|
serializer = CartSerializer(instance=items, many=True)
|
|
return Response(serializer.data, status=201)
|
|
|
|
|
|
class ConfigureProductView(View):
|
|
template_name = "store/configure_product.html"
|
|
|
|
def get_context_data(self, pk: int, **kwargs: Any) -> Dict[str, Any]:
|
|
template = get_object_or_404(ProductTemplate, pk=pk)
|
|
form = ProductTemplateConfigForm(template=template)
|
|
context = {
|
|
"template": template,
|
|
"form": form
|
|
}
|
|
return context
|
|
|
|
def get(self, request, pk: int, *args, **kwargs):
|
|
context = self.get_context_data(pk)
|
|
return render(request, self.template_name, context)
|
|
|
|
def post(self, request, pk: int, *args, **kwargs):
|
|
# first select template
|
|
template = get_object_or_404(ProductTemplate, pk=pk)
|
|
form = ProductTemplateConfigForm(template=template, data=request.POST)
|
|
if not form.is_valid():
|
|
context = self.get_context_data(pk)
|
|
context["form"] = form
|
|
return render(request, self.template_name, context)
|
|
|
|
product_variant = form.get_product()
|
|
return HttpResponseRedirect(reverse("configure-product-summary", args=[product_variant.pk]))
|
|
|
|
class ConfigureProductSummaryView(View):
|
|
template_name = "store/configure_product_summary.html"
|
|
|
|
def get_context_data(self, variant_pk):
|
|
variant = get_object_or_404(Product, pk=variant_pk)
|
|
return {
|
|
"variant": variant,
|
|
"params_values": variant.params.all(),
|
|
"store_url": ProductListPage.objects.first().get_url()
|
|
}
|
|
|
|
def get(self, request, variant_pk: int, *args, **kwargs):
|
|
context = self.get_context_data(variant_pk)
|
|
return render(request, self.template_name, context)
|
|
|
|
def post(self, request, variant_pk: int, *args, **kwargs):
|
|
# Here just send the email with product request
|
|
variant = Product.objects.get(pk=variant_pk)
|
|
send_produt_request_email.apply_async(args=[variant.pk])
|
|
messages.success(request, "Zapytanie o produkt zostało wysłane")
|
|
context = self.get_context_data(variant_pk)
|
|
return HttpResponseRedirect(context["store_url"])
|
|
|
|
|
|
class OrderView(View):
|
|
template_name = "store/order.html"
|
|
|
|
def get_context_data(self, **kwargs: Any) -> Dict[str, Any]:
|
|
context = {}
|
|
context["form"] = CustomerDataForm()
|
|
return context
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
cart = SessionCart(self.request)
|
|
if cart.is_empty():
|
|
messages.error(request, "Twój koszyk jest pusty")
|
|
return HttpResponseRedirect(reverse("cart"))
|
|
return render(request, self.template_name, self.get_context_data())
|
|
|
|
def post(self, request, *args, **kwargs):
|
|
cart = SessionCart(self.request)
|
|
if cart.is_empty():
|
|
messages.error(request, "Twój koszyk jest pusty")
|
|
return HttpResponseRedirect(reverse("cart"))
|
|
|
|
form = CustomerDataForm(request.POST)
|
|
if not form.is_valid():
|
|
context = self.get_context_data()
|
|
context["form"] = form
|
|
return render(request, self.template_name, context)
|
|
customer_data = CustomerData(data=form.serialize())
|
|
request.session["customer_data"] = customer_data.data
|
|
return HttpResponseRedirect(reverse("order-confirm"))
|
|
|
|
|
|
class OrderConfirmView(View):
|
|
template_name = "store/order_confirm.html"
|
|
|
|
def get_context_data(self, **kwargs: Any) -> Dict[str, Any]:
|
|
|
|
form = CustomerDataForm(
|
|
data=CustomerData(
|
|
encrypted_data=self.request.session["customer_data"]
|
|
).decrypted_data
|
|
)
|
|
if not form.is_valid():
|
|
raise Exception("Customer data is not valid")
|
|
|
|
customer_data = form.cleaned_data
|
|
return {
|
|
"cart": SessionCart(self.request, delivery=customer_data["delivery_method"]),
|
|
"customer_data": customer_data
|
|
}
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
cart = SessionCart(self.request)
|
|
if cart.is_empty():
|
|
messages.error(request, "Twój koszyk jest pusty")
|
|
return HttpResponseRedirect(reverse("cart"))
|
|
return render(request, self.template_name, self.get_context_data())
|
|
|
|
def post(self, request):
|
|
customer_data = CustomerData(
|
|
encrypted_data=self.request.session["customer_data"]
|
|
).decrypted_data
|
|
cart = SessionCart(self.request)
|
|
order = Order.objects.create_from_cart(
|
|
cart.display_items,
|
|
None, customer_data
|
|
)
|
|
request.session.pop("customer_data")
|
|
cart.clear()
|
|
request.session["order_uuids"] = [str(elem) for elem in order.values_list("uuid", flat=True)]
|
|
return HttpResponseRedirect(reverse("order-success"))
|
|
|
|
|
|
class OrderSuccessView(View):
|
|
template_name = "store/order_success.html"
|
|
|
|
def get_context_data(self, **kwargs: Any) -> Dict[str, Any]:
|
|
return {
|
|
"orders": Order.objects.filter(uuid__in=self.request.session.get("order_uuids")),
|
|
"store_url": ProductListPage.objects.first().get_url()
|
|
}
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
if not self.request.session.get("order_uuids"):
|
|
return HttpResponseRedirect(reverse("cart"))
|
|
|
|
return render(request, self.template_name, self.get_context_data())
|