added product_request mechanism

main
mtyton 2023-07-22 18:53:18 +02:00
rodzic 3a8ffd73c5
commit 24f98cc3de
6 zmienionych plików z 155 dodań i 24 usunięć

Wyświetl plik

@ -225,7 +225,6 @@ class Product(ClusterableModel):
return main_image
return self.product_images.first()
@property
def tags(self):
return self.template.tags.all()

Wyświetl plik

@ -0,0 +1,30 @@
import logging
from django.conf import settings
from mailings.models import OutgoingEmail
from store.models import Product
logger = logging.getLogger(__name__)
# TODO - those should be modified to be celery tasks
def send_produt_request_email(variant_pk: int):
try:
variant = Product.objects.get(pk=variant_pk)
except Product.DoesNotExist:
logger.exception(f"Product with pk={variant_pk} does not exist")
try:
send = OutgoingEmail.objects.send(
template_name="product_request",
subject="Zapytanie o produkt",
recipient=variant.template.author.email,
context={"product": variant},
sender=settings.DEFAULT_FROM_EMAIL
)
except Exception as e:
logger.exception(f"Could not send email for variant pk={variant_pk}, exception: {e} has occured")
else:
if not send:
logger.exception(f"Could not send email for variant pk={variant_pk}")

Wyświetl plik

@ -18,10 +18,6 @@
</div>
</div>
<div class="container">
<a class="btn btn-outline-primary btn-lg" href="{% url 'product-configure' variant.template.pk %}">Wróć do konfiguratora</a>
</div>
<section class="h-100">
<div class="container">
<div class="row">
@ -51,14 +47,18 @@
Jeżeli jesteś zainteresowany tą konfiguracją złóż zapytanie ofertowe.
</div>
</div>
{% else %}
<div class="row mt-3">
<div class="col-12 text-end">
<h3>Cena: {{variant.price}} zł</h3>
</div>
</div>
{% endif %}
<div class="row mt-3">
<div class="col-3 ">
{% if variant.available %}
<h3>Cena: {{variant.price}} zł</h3>
{% endif %}
<div class="col-6 ">
<a class="btn btn-outline-primary btn-lg" href="{% url 'product-configure' variant.template.pk %}">Wróć do konfiguratora</a>
</div>
<div class="col-9 text-end">
<div class="col-6 text-end">
{% if variant.available %}
<button class="btn btn-outline-success btn-lg add-to-cart-button" data-product-id="{{variant.id}}"
@ -67,7 +67,10 @@
Zamów produkt
</button>
{% else %}
<button class="btn btn-outline-success btn-lg">Złóż zapytanie ofertowe</button>
<form method="POST" action="">
{% csrf_token %}
<button class="btn btn-outline-success btn-lg" type="submit">Złóż zapytanie ofertowe</button>
</form>
{% endif %}
</div>
</div>

Wyświetl plik

@ -28,4 +28,4 @@
<a class="btn btn-outline-primary" href="{{store_url}}">Powrót do sklepu</a>
</div>
</div>
{% endblock %}
{% endblock %}

Wyświetl plik

@ -1,11 +1,98 @@
from django.test import TestCase
from django.shortcuts import reverse
from store.models import (
ProductCategoryParam,
ProductCategoryParamValue,
CategoryParamTypeChoices
)
from store.tests.factories import (
ProductTemplateFactory,
ProductCategoryFactory,
ProductFactory,
ProductCategoryParamValueFactory
)
class ConfigureProductViewTestCase(TestCase):
def setUp(self):
...
super().setUp()
self.category = ProductCategoryFactory()
self.product_template = ProductTemplateFactory(category=self.category)
# create template params and values for those params
self.param1 = ProductCategoryParam.objects.create(
key="Mocowanie", category=self.category,
param_type=CategoryParamTypeChoices.STRING
)
self.param1_value1 = ProductCategoryParamValueFactory(param=self.param1)
self.param1_value2 = ProductCategoryParamValueFactory(param=self.param1)
self.param2 = ProductCategoryParam.objects.create(
key="Format", category=self.category,
param_type=CategoryParamTypeChoices.STRING
)
self.param2_value1 = ProductCategoryParamValueFactory(param=self.param2)
self.param2_value2 = ProductCategoryParamValueFactory(param=self.param2)
# create product variant
self.variant1 = ProductFactory(
template=self.product_template
)
self.variant1.params.set([self.param1_value1, self.param2_value1])
self.variant1.save()
def test_sdkfsdf(self):
...
self.variant2 = ProductFactory(
template=self.product_template,
)
self.variant2.params.set([self.param1_value2, self.param2_value2])
self.variant2.save()
def test_get_success(self):
response = self.client.get(
reverse("product-configure", args=[self.product_template.pk]),
)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "store/configure_product.html")
def test_get_failure_wrong_pk(self):
response = self.client.get(
reverse("product-configure", args=[12312]),
)
self.assertEqual(response.status_code, 404)
def test_post_success(self):
data = {
self.param1.key: [str(self.param1_value1.pk)],
self.param2.key: [str(self.param2_value1.pk)]
}
response = self.client.post(
reverse("product-configure", args=[self.product_template.pk]),
data=data
)
self.assertEqual(response.status_code, 302)
self.assertEqual(response.url, reverse("configure-product-summary", args=[self.variant1.pk]))
def test_post_failure_not_existing_template(self):
data = {
self.param1.key: [str(self.param1_value1.pk)],
self.param2.key: [str(self.param2_value1.pk)]
}
response = self.client.post(
reverse("product-configure", args=[2137]),
data=data
)
self.assertEqual(response.status_code, 404)
def test_post_not_existing_config(self):
data = {
self.param1.key: [str(self.param1_value2.pk)],
self.param2.key: [str(self.param2_value1.pk)]
}
response = self.client.post(
reverse("product-configure", args=[self.product_template.pk]),
data=data
)
self.assertEqual(response.status_code, 302)
class ConfigureProductSummaryViewTestCase(TestCase):
...

Wyświetl plik

@ -4,7 +4,10 @@ from django.views.generic import (
TemplateView,
View
)
from django.shortcuts import render
from django.shortcuts import (
render,
get_object_or_404
)
from django.urls import reverse
from django.http import HttpResponseRedirect
from django.contrib import messages
@ -13,6 +16,7 @@ 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
from store.serializers import (
CartSerializer,
@ -96,14 +100,12 @@ class ConfigureProductView(View):
template_name = "store/configure_product.html"
def get_context_data(self, pk: int, **kwargs: Any) -> Dict[str, Any]:
template = ProductTemplate.objects.get(pk=pk)
template = get_object_or_404(ProductTemplate, pk=pk)
form = ProductTemplateConfigForm(template=template)
context = {
"template": template,
"available_variants": Product.objects.filter(template__pk=pk),
"form": form
}
return context
def get(self, request, pk: int, *args, **kwargs):
@ -112,7 +114,7 @@ class ConfigureProductView(View):
def post(self, request, pk: int, *args, **kwargs):
# first select template
template = ProductTemplate.objects.get(pk=pk)
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)
@ -125,16 +127,26 @@ class ConfigureProductView(View):
class ConfigureProductSummaryView(View):
template_name = "store/configure_product_summary.html"
def get(self, request, variant_pk: int, *args, **kwargs):
variant = Product.objects.get(pk=variant_pk)
context = {
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(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"