diff --git a/artel/artel/templates/base.html b/artel/artel/templates/base.html index 086f284..86be8f0 100644 --- a/artel/artel/templates/base.html +++ b/artel/artel/templates/base.html @@ -53,7 +53,6 @@ {# Global javascript #} - diff --git a/artel/store/forms.py b/artel/store/forms.py index 74fe4bb..08e8b09 100644 --- a/artel/store/forms.py +++ b/artel/store/forms.py @@ -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"}) + ) diff --git a/artel/store/models.py b/artel/store/models.py index 2be1ef8..a605055 100644 --- a/artel/store/models.py +++ b/artel/store/models.py @@ -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") diff --git a/artel/store/templates/store/configure_product.html b/artel/store/templates/store/configure_product.html index b46e34d..8e8f773 100644 --- a/artel/store/templates/store/configure_product.html +++ b/artel/store/templates/store/configure_product.html @@ -2,7 +2,7 @@ {% block content %} -
+

{{template.title}}

@@ -24,26 +24,36 @@
-

Dostępne konfiguracje:

- -
-
- {% for product in template.products.all %} -
-
-
- {{product.name}} +
+ {% csrf_token %} + {% for form in forms %} +
+

+ {{form.instance}} +

+ +
+ {% for value, label in form.value.field.choices %} +
+ +
-
- Responsive image -
- + {% endfor %} +
+
+ {% endfor %} +
+
+
+ +
+
+
- {% if forloop.counter|divisibleby:3 %}
{% endif %} - {% endfor %} +
+
diff --git a/artel/store/tests/test_models.py b/artel/store/tests/test_models.py index fbdc288..3b07e79 100644 --- a/artel/store/tests/test_models.py +++ b/artel/store/tests/test_models.py @@ -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): diff --git a/artel/store/tests/test_validators.py b/artel/store/tests/test_validators.py deleted file mode 100644 index 3a68554..0000000 --- a/artel/store/tests/test_validators.py +++ /dev/null @@ -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) - diff --git a/artel/store/views.py b/artel/store/views.py index 71068d1..25537b8 100644 --- a/artel/store/views.py +++ b/artel/store/views.py @@ -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):