finished preview version of configurator

feature/product_models_refactor
mtyton 2023-07-07 23:29:42 +02:00
rodzic bf33ef4ee9
commit 540318ca48
7 zmienionych plików z 110 dodań i 69 usunięć

Wyświetl plik

@ -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>

Wyświetl plik

@ -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"})
)

Wyświetl plik

@ -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")

Wyświetl plik

@ -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>
<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}}
<form action="" method="POST" class="mt-5">
{% csrf_token %}
{% for form in forms %}
<div class="container mt-3 ">
<h3>
{{form.instance}}
</h3>
<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>
<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>
{% 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>

Wyświetl plik

@ -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):

Wyświetl plik

@ -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)

Wyświetl plik

@ -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):