sforkowany z mtyton/comfy
added product_request mechanism
rodzic
3a8ffd73c5
commit
24f98cc3de
|
@ -225,7 +225,6 @@ class Product(ClusterableModel):
|
|||
return main_image
|
||||
return self.product_images.first()
|
||||
|
||||
|
||||
@property
|
||||
def tags(self):
|
||||
return self.template.tags.all()
|
||||
|
|
|
@ -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}")
|
|
@ -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>
|
||||
|
|
|
@ -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):
|
||||
...
|
||||
|
|
|
@ -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"
|
||||
|
|
Ładowanie…
Reference in New Issue