From 4cbb25a537a6c3dfbb6d2d3e934bb5b5d00e000c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=AD=C3=B0ir=20Valberg=20Gu=C3=B0mundsson?= Date: Wed, 27 Mar 2019 23:34:44 +0100 Subject: [PATCH] Use OrderProductRelationForm to validate stock when adding a new product to order, also make it possible to update the quantity of a product on the product detail page if it is already in the current order. --- src/profiles/templates/shop/order_detail.html | 2 +- src/shop/forms.py | 5 +- src/shop/templates/product_detail.html | 8 ++- src/shop/templates/shop_index.html | 10 ++-- src/shop/views.py | 60 +++++++++++-------- 5 files changed, 47 insertions(+), 38 deletions(-) diff --git a/src/profiles/templates/shop/order_detail.html b/src/profiles/templates/shop/order_detail.html index 7ad6491b..ce505954 100644 --- a/src/profiles/templates/shop/order_detail.html +++ b/src/profiles/templates/shop/order_detail.html @@ -48,7 +48,7 @@ {{ form.instance.total|currency }} - {% bootstrap_button '' button_type="submit" button_class="btn-danger" name="remove_product" value=order_product.pk %} + {% bootstrap_button '' button_type="submit" button_class="btn-danger" name="remove_product" value=form.instance.pk %} {% endfor %} diff --git a/src/shop/forms.py b/src/shop/forms.py index 7ed44bcb..29910321 100644 --- a/src/shop/forms.py +++ b/src/shop/forms.py @@ -4,11 +4,8 @@ from django.forms import modelformset_factory from shop.models import OrderProductRelation -class AddToOrderForm(forms.Form): - quantity = forms.IntegerField(initial=1) - - class OrderProductRelationForm(forms.ModelForm): + class Meta: model = OrderProductRelation fields = ['quantity'] diff --git a/src/shop/templates/product_detail.html b/src/shop/templates/product_detail.html index 34fc50c2..2296fe3a 100644 --- a/src/shop/templates/product_detail.html +++ b/src/shop/templates/product_detail.html @@ -40,7 +40,9 @@ {% if product.is_stock_available %} -

Add to order

+

{% if already_in_order %}Update order{% else %}Add to order{% endif %}

+ + {% if already_in_order %}

You already have this product in your order.

{% endif %} {% if user.is_authenticated %} @@ -49,7 +51,9 @@
{% csrf_token %} {% bootstrap_form form %} - {% bootstrap_button "Add to order" button_type="submit" button_class="btn-primary" %} +
{% else %} diff --git a/src/shop/templates/shop_index.html b/src/shop/templates/shop_index.html index 1c67d61f..2ac5a0b6 100644 --- a/src/shop/templates/shop_index.html +++ b/src/shop/templates/shop_index.html @@ -59,16 +59,14 @@ Shop | {{ block.super }} {% if product.stock_amount %} - {% if product.left_in_stock <= 10 %} -
- Only {{ product.left_in_stock }} left! -
- {% endif %} - {% if product.left_in_stock == 0 %}
Sold out!
+ {% elif product.left_in_stock <= 10 %} +
+ Only {{ product.left_in_stock }} left! +
{% endif %} {% endif %} diff --git a/src/shop/views.py b/src/shop/views.py index 18fda6a3..f94378d2 100644 --- a/src/shop/views.py +++ b/src/shop/views.py @@ -41,7 +41,7 @@ from .coinify import ( process_coinify_invoice_json ) from .epay import calculate_epay_hash, validate_epay_callback -from .forms import AddToOrderForm, OrderProductRelationFormSet +from .forms import OrderProductRelationFormSet, OrderProductRelationForm logger = logging.getLogger("bornhack.%s" % __name__) @@ -219,11 +219,39 @@ class ShopIndexView(ListView): class ProductDetailView(FormView, DetailView): model = Product template_name = 'product_detail.html' - form_class = AddToOrderForm + form_class = OrderProductRelationForm context_object_name = 'product' + def get_form_kwargs(self): + kwargs = super().get_form_kwargs() + kwargs['instance'] = self.opr + return kwargs + + def get_initial(self): + return {'quantity': self.opr.quantity} + + def get_context_data(self, **kwargs): + if hasattr(self.opr, 'order'): + kwargs['already_in_order'] = True + + return super().get_context_data(**kwargs) + def dispatch(self, request, *args, **kwargs): - if not self.get_object().category.public: + self.object = self.get_object() + + try: + self.opr = OrderProductRelation.objects.get( + order__user=self.request.user, + order__open__isnull=False, + product=self.object + ) + except OrderProductRelation.DoesNotExist: + self.opr = OrderProductRelation( + product=self.get_object(), + quantity=1, + ) + + if not self.object.category.public: # this product is not publicly available raise Http404("Product not found") @@ -235,31 +263,13 @@ class ProductDetailView(FormView, DetailView): product = self.get_object() quantity = form.cleaned_data.get('quantity') - # do we have an open order? - try: - order = Order.objects.get( - user=self.request.user, - open__isnull=False - ) - except Order.DoesNotExist: - # no open order - open a new one - order = Order.objects.create( + if not hasattr(self.opr, 'order'): + self.opr.order = Order.objects.create( user=self.request.user, ) - # get product from kwargs - if product in order.products.all(): - # this product is already added to this order, - # increase count by quantity - OrderProductRelation.objects.filter( - product=product, - order=order - ).update(quantity=F('quantity') + quantity) - else: - order.orderproductrelation_set.create( - product=product, - quantity=quantity, - ) + self.opr.quantity = quantity + self.opr.save() messages.info( self.request,