configurator is almost done
rodzic
540318ca48
commit
c76e6fbc12
|
@ -43,7 +43,7 @@ class CustomerDataForm(forms.Form):
|
||||||
class ProductCategoryParamForm(forms.ModelForm):
|
class ProductCategoryParamForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ProductCategoryParam
|
model = ProductCategoryParam
|
||||||
fields = ("key", "value", )
|
fields = ("key", "value")
|
||||||
readonly_fields = ("key", )
|
readonly_fields = ("key", )
|
||||||
|
|
||||||
def __init__(self, instance, *args, **kwargs):
|
def __init__(self, instance, *args, **kwargs):
|
||||||
|
@ -57,3 +57,9 @@ class ProductCategoryParamForm(forms.ModelForm):
|
||||||
queryset=ProductCategoryParamValue.objects.none(),
|
queryset=ProductCategoryParamValue.objects.none(),
|
||||||
widget=forms.RadioSelect(attrs={"class": "form-control"})
|
widget=forms.RadioSelect(attrs={"class": "form-control"})
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
return ProductCategoryParamValue.objects.get(
|
||||||
|
param=self.instance,
|
||||||
|
value=str(self.cleaned_data["value"])
|
||||||
|
)
|
||||||
|
|
|
@ -168,6 +168,23 @@ class ProductTemplateImage(BaseImageModel):
|
||||||
is_main = models.BooleanField(default=False)
|
is_main = models.BooleanField(default=False)
|
||||||
|
|
||||||
|
|
||||||
|
class ProductManager(models.Manager):
|
||||||
|
|
||||||
|
def get_or_create_by_params(self, params: list[ProductCategoryParamValue], template: ProductTemplate):
|
||||||
|
product = self.filter(params__in=params).first()
|
||||||
|
if not product:
|
||||||
|
product = self.create(
|
||||||
|
name=f"{template.title} - AUTOGENERATED",
|
||||||
|
template=template,
|
||||||
|
price=...,
|
||||||
|
available=False
|
||||||
|
)
|
||||||
|
for param in params:
|
||||||
|
product.params.add(param)
|
||||||
|
|
||||||
|
return product
|
||||||
|
|
||||||
|
|
||||||
class Product(ClusterableModel):
|
class Product(ClusterableModel):
|
||||||
name = models.CharField(max_length=255, blank=True)
|
name = models.CharField(max_length=255, blank=True)
|
||||||
template = models.ForeignKey(ProductTemplate, on_delete=models.CASCADE, related_name="products")
|
template = models.ForeignKey(ProductTemplate, on_delete=models.CASCADE, related_name="products")
|
||||||
|
|
|
@ -1,16 +1,12 @@
|
||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<div class="card mb-5">
|
<div class="card mb-5">
|
||||||
|
|
||||||
<div class="card-header text-center">
|
<div class="card-header text-center">
|
||||||
<h2>{{template.title}}</h2>
|
<h2>{{template.title}}</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
@ -24,38 +20,33 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
<form action="" method="POST" class="mt-5">
|
<form action="" method="POST" class="mt-5">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
<div class="row mt-5">
|
||||||
{% for form in forms %}
|
{% for form in forms %}
|
||||||
<div class="container mt-3 ">
|
<div class="col-6 text-center">
|
||||||
<h3>
|
<h3>{{form.instance}}</h3>
|
||||||
{{form.instance}}
|
|
||||||
</h3>
|
|
||||||
|
|
||||||
<div class="btn-group btn-group-toggle" data-toggle="buttons">
|
|
||||||
{% for value, label in form.value.field.choices %}
|
{% for value, label in form.value.field.choices %}
|
||||||
<div class="btn-group" role="group">
|
<div class="btn-group btn-group-toggle" role="group">
|
||||||
<input type="radio" class="btn-check" name="btnradio+{{form.key.value}}" id="{{value}}" autocomplete="off" checked>
|
<input type="radio" class="btn-check" name="{{form.key.value}}" id="{{value}}" autocomplete="off" checked>
|
||||||
<label class="btn btn-outline-success" for="{{value}}">{{label}}</label>
|
<label class="btn btn-outline-primary" for="{{value}}">{{label}}</label>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{% if forloop.counter|divisibleby:"2" %} </div><div class="row mt-5">{% endif %}
|
||||||
{% endfor %}
|
{% 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>
|
||||||
|
<div class="row mt-5">
|
||||||
|
<div class="col-6"></div>
|
||||||
|
<div class="col-6 text-center">
|
||||||
|
<button class="btn btn-lg btn-success" type="submit">Sprawdź dostępność</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -3,26 +3,6 @@
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<div class="modal" tabindex="-1" role="dialog" id="addToCartModal" aria-labelledby="addToCartLabel" aria-hidden="true">
|
|
||||||
<div class="modal-dialog" role="document">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h5 class="modal-title">Dodano do koszyka</h5>
|
|
||||||
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close" >
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<p>Przedmiot został dodany do koszyka.</p>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Kontynuuj zakupy</button>
|
|
||||||
<a href="{% url 'cart' %}" class="btn btn-primary">Idź do koszyka</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="container mb-3 mt-5">
|
<div class="container mb-3 mt-5">
|
||||||
<div class="row row-cols-3 g-4 mt-3">
|
<div class="row row-cols-3 g-4 mt-3">
|
||||||
{% for item in items %}
|
{% for item in items %}
|
||||||
|
|
|
@ -10,6 +10,7 @@ router.register("cart-action", store_views.CartActionView, "cart-action")
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('product-configure/<int:pk>/', store_views.ConfigureProductView.as_view(), name='product-configure'),
|
path('product-configure/<int:pk>/', store_views.ConfigureProductView.as_view(), name='product-configure'),
|
||||||
|
path('product-configure/summary/<int:variant_pk>/', store_views.ConfigureProductSummaryView.as_view(), name='product-configure-summary'),
|
||||||
path('cart/', store_views.CartView.as_view(), name='cart'),
|
path('cart/', store_views.CartView.as_view(), name='cart'),
|
||||||
path("order/", store_views.OrderView.as_view(), name="order"),
|
path("order/", store_views.OrderView.as_view(), name="order"),
|
||||||
path("order/confirm/", store_views.OrderConfirmView.as_view(), name="order-confirm")
|
path("order/confirm/", store_views.OrderConfirmView.as_view(), name="order-confirm")
|
||||||
|
|
|
@ -111,6 +111,22 @@ class ConfigureProductView(View):
|
||||||
context = self.get_context_data(pk)
|
context = self.get_context_data(pk)
|
||||||
return render(request, self.template_name, context)
|
return render(request, self.template_name, context)
|
||||||
|
|
||||||
|
def post(self, request, pk: int, *args, **kwargs):
|
||||||
|
print(request.POST)
|
||||||
|
return HttpResponseRedirect(reverse("product-configure-summary", kwargs={"variant_pk": 1}))
|
||||||
|
|
||||||
|
|
||||||
|
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 = {
|
||||||
|
"variant": variant,
|
||||||
|
"category_params": variant.template.category.category_params.all()
|
||||||
|
}
|
||||||
|
return render(request, self.template_name, context)
|
||||||
|
|
||||||
|
|
||||||
class OrderView(View):
|
class OrderView(View):
|
||||||
template_name = "store/order.html"
|
template_name = "store/order.html"
|
||||||
|
|
Ładowanie…
Reference in New Issue