finished preview version of configurator
rodzic
bf33ef4ee9
commit
540318ca48
|
@ -53,7 +53,6 @@
|
|||
|
||||
{# Global javascript #}
|
||||
<script type="text/javascript" src="{% static 'js/jquery-3.6.4.min.js' %}"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.14.7/dist/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
|
||||
<script type="text/javascript" src="{% static 'bootstrap/js/bootstrap.bundle.min.js' %}"></script>
|
||||
<script type="text/javascript" src="{% static 'js/artel.js' %}"></script>
|
||||
<script src="{% static 'js/cart.js' %}"></script>
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
from django import forms
|
||||
from phonenumber_field.formfields import PhoneNumberField
|
||||
# from phonenumber_field.widgets import PhoneNumberPrefixWidget
|
||||
|
||||
from store.models import (
|
||||
ProductCategoryParamValue,
|
||||
ProductCategoryParam,
|
||||
ProductCategory
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -32,3 +38,22 @@ class CustomerDataForm(forms.Form):
|
|||
choices=(("PL", "Polska"), ), label="Kraj",
|
||||
widget=forms.Select(attrs={"class": "form-control"})
|
||||
)
|
||||
|
||||
|
||||
class ProductCategoryParamForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = ProductCategoryParam
|
||||
fields = ("key", "value", )
|
||||
readonly_fields = ("key", )
|
||||
|
||||
def __init__(self, instance, *args, **kwargs):
|
||||
super().__init__(*args, instance=instance, **kwargs)
|
||||
self.fields["key"].widget.attrs["disabled"] = True
|
||||
self.fields["value"].choices = [
|
||||
(param_value.pk, param_value.value) for param_value in instance.param_values.all()
|
||||
]
|
||||
|
||||
value = forms.ModelChoiceField(
|
||||
queryset=ProductCategoryParamValue.objects.none(),
|
||||
widget=forms.RadioSelect(attrs={"class": "form-control"})
|
||||
)
|
||||
|
|
|
@ -5,7 +5,7 @@ import builtins
|
|||
from decimal import Decimal
|
||||
from typing import (
|
||||
Any,
|
||||
Self
|
||||
Iterator
|
||||
)
|
||||
from django.db import models
|
||||
from django.core.paginator import (
|
||||
|
@ -110,6 +110,10 @@ class ProductCategoryParam(ClusterableModel):
|
|||
InlinePanel("param_values")
|
||||
]
|
||||
|
||||
def get_available_values(self) -> Iterator[any]:
|
||||
for elem in self.param_values.all():
|
||||
yield elem.get_value()
|
||||
|
||||
|
||||
class ProductCategoryParamValue(ClusterableModel):
|
||||
param = ParentalKey(ProductCategoryParam, on_delete=models.CASCADE, related_name="param_values")
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
{% block content %}
|
||||
|
||||
<div class="card">
|
||||
<div class="card mb-5">
|
||||
|
||||
<div class="card-header text-center">
|
||||
<h2>{{template.title}}</h2>
|
||||
|
@ -24,26 +24,36 @@
|
|||
|
||||
</div>
|
||||
|
||||
<h4 class="mt-3">Dostępne konfiguracje:</h4>
|
||||
<form action="" method="POST" class="mt-5">
|
||||
{% csrf_token %}
|
||||
{% for form in forms %}
|
||||
<div class="container mt-3 ">
|
||||
<h3>
|
||||
{{form.instance}}
|
||||
</h3>
|
||||
|
||||
<div class="container mt-3">
|
||||
<div class="row">
|
||||
{% for product in template.products.all %}
|
||||
<div class="col-4">
|
||||
<div class="card">
|
||||
<div class="card-header text-center">
|
||||
{{product.name}}
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<img src="{{product.main_image.image.url}}" class="img-fluid img-thumbnail" alt="Responsive image">
|
||||
</div>
|
||||
<div class="card-footer text-center">
|
||||
<input type="button" class="btn btn-primary btn-block" value="Wybierz">
|
||||
<div class="btn-group btn-group-toggle" data-toggle="buttons">
|
||||
{% for value, label in form.value.field.choices %}
|
||||
<div class="btn-group" role="group">
|
||||
<input type="radio" class="btn-check" name="btnradio+{{form.key.value}}" id="{{value}}" autocomplete="off" checked>
|
||||
<label class="btn btn-outline-success" for="{{value}}">{{label}}</label>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div class="container mt-5">
|
||||
<div class="row">
|
||||
<div class="col-2">
|
||||
<input type="number" class="form-control"
|
||||
id="quantity" name="quantity" placeholder="Ilość" min="1" max="100">
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<button class="btn btn-success">Zamów</button>
|
||||
</div>
|
||||
</div>
|
||||
{% if forloop.counter|divisibleby:3 %}</div><div class="row">{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -4,12 +4,42 @@ from django.test import TestCase
|
|||
from django.urls import reverse
|
||||
from django.core import mail
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.db import transaction
|
||||
|
||||
from store.tests import factories
|
||||
from store import models as store_models
|
||||
from mailings.tests.factories import MailTemplateFactory
|
||||
|
||||
|
||||
class ProductCategoryParamTestCase(TestCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.category = factories.ProductCategoryFactory()
|
||||
self.param = factories.ProductCategoryParamFactory(
|
||||
category=self.category,
|
||||
param_type="int",
|
||||
key="test_param"
|
||||
)
|
||||
|
||||
def test_get_available_values_no_values_success(self):
|
||||
available_values = [v for v in self.param.get_available_values()]
|
||||
self.assertEqual(available_values, [])
|
||||
|
||||
def test_get_available_values_one_value_success(self):
|
||||
factories.ProductCategoryParamValueFactory(param=self.param, value="23")
|
||||
available_values = [v for v in self.param.get_available_values()]
|
||||
self.assertEqual(available_values, [23])
|
||||
self.assertEqual(len(available_values), 1)
|
||||
|
||||
def test_get_available_values_multiple_values_success(self):
|
||||
factories.ProductCategoryParamValueFactory(param=self.param, value="23")
|
||||
factories.ProductCategoryParamValueFactory(param=self.param, value="24")
|
||||
factories.ProductCategoryParamValueFactory(param=self.param, value="25")
|
||||
available_values = [v for v in self.param.get_available_values()]
|
||||
self.assertEqual(available_values, [23, 24, 25])
|
||||
self.assertEqual(len(available_values), 3)
|
||||
|
||||
|
||||
class ProductCategoryParamValueTestCase(TestCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
@ -47,7 +77,8 @@ class ProductTestCase(TestCase):
|
|||
key="test_param"
|
||||
)
|
||||
param_value = factories.ProductCategoryParamValueFactory(param=param, value="23")
|
||||
product.params.add(param_value)
|
||||
with transaction.atomic():
|
||||
product.params.add(param_value)
|
||||
product.save()
|
||||
self.assertEqual(product.params.count(), 1)
|
||||
self.assertEqual(product.params.first().get_value(), 23)
|
||||
|
@ -62,8 +93,10 @@ class ProductTestCase(TestCase):
|
|||
param_value = factories.ProductCategoryParamValueFactory(param=param, value="23")
|
||||
sec_param_value = factories.ProductCategoryParamValueFactory(param=param, value="24")
|
||||
with self.assertRaises(ValidationError):
|
||||
product.params.add(param_value)
|
||||
product.params.add(sec_param_value)
|
||||
with transaction.atomic():
|
||||
product.params.add(param_value)
|
||||
product.params.add(sec_param_value)
|
||||
self.assertEqual(product.params.count(), 0)
|
||||
|
||||
|
||||
class OrderProductTestCase(TestCase):
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
from django.test import TestCase
|
||||
from django.core.exceptions import ValidationError
|
||||
|
||||
from store.tests import factories
|
||||
from store.validators import ProductParamDuplicateValidator
|
||||
from store.models import (
|
||||
ProductParam,
|
||||
Product
|
||||
)
|
||||
|
||||
|
||||
class CategoryParamValidationTestCase(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.product = factories.ProductFactory()
|
||||
|
||||
def test_set_single_param_success(self):
|
||||
param = factories.ProductCategoryParamFactory(
|
||||
category=self.product.template.category,
|
||||
param_type="int",
|
||||
key="test_param"
|
||||
)
|
||||
param_value = factories.ProductCategoryParamValueFactory(param=param, value="23")
|
||||
param = ProductParam(param_value=param_value)
|
||||
self.product.params.add(param_value)
|
||||
self.assertEqual(self.product.params.count(), 1)
|
||||
self.assertEqual(self.product.params.first().get_value(), 23)
|
||||
|
||||
def test_set_multuiple_same_type_param_failure(self):
|
||||
param = factories.ProductCategoryParamFactory(
|
||||
category=self.product.template.category,
|
||||
param_type="int",
|
||||
key="test_param"
|
||||
)
|
||||
param_value = factories.ProductCategoryParamValueFactory(param=param, value="23")
|
||||
sec_param_value = factories.ProductCategoryParamValueFactory(param=param, value="24")
|
||||
param = ProductParam(param_value=param_value)
|
||||
self.product.params.add(param_value)
|
||||
with self.assertRaises(ValidationError):
|
||||
self.product.params.add(sec_param_value)
|
||||
|
|
@ -17,7 +17,10 @@ from store.serializers import (
|
|||
CartSerializer,
|
||||
CartProductAddSerializer
|
||||
)
|
||||
from store.forms import CustomerDataForm
|
||||
from store.forms import (
|
||||
CustomerDataForm,
|
||||
ProductCategoryParamForm
|
||||
)
|
||||
from store.models import (
|
||||
Order,
|
||||
Product,
|
||||
|
@ -91,8 +94,17 @@ class ConfigureProductView(View):
|
|||
template_name = "store/configure_product.html"
|
||||
|
||||
def get_context_data(self, pk: int, **kwargs: Any) -> Dict[str, Any]:
|
||||
context = {}
|
||||
context["template"] = ProductTemplate.objects.get(pk=pk)
|
||||
template = ProductTemplate.objects.get(pk=pk)
|
||||
category_params = template.category.category_params.all()
|
||||
|
||||
|
||||
context = {
|
||||
"template": template,
|
||||
"available_variants": Product.objects.filter(template__pk=pk),
|
||||
"category_params": category_params,
|
||||
"forms": [ProductCategoryParamForm(instance=param) for param in category_params]
|
||||
}
|
||||
|
||||
return context
|
||||
|
||||
def get(self, request, pk: int, *args, **kwargs):
|
||||
|
|
Ładowanie…
Reference in New Issue