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.

This commit is contained in:
Víðir Valberg Guðmundsson 2019-03-27 23:34:44 +01:00
parent 59cde9163f
commit 4cbb25a537
5 changed files with 47 additions and 38 deletions

View file

@ -48,7 +48,7 @@
<td> <td>
{{ form.instance.total|currency }} {{ form.instance.total|currency }}
<td> <td>
{% bootstrap_button '<i class="glyphicon glyphicon-remove"></i>' button_type="submit" button_class="btn-danger" name="remove_product" value=order_product.pk %} {% bootstrap_button '<i class="glyphicon glyphicon-remove"></i>' button_type="submit" button_class="btn-danger" name="remove_product" value=form.instance.pk %}
{% endfor %} {% endfor %}

View file

@ -4,11 +4,8 @@ from django.forms import modelformset_factory
from shop.models import OrderProductRelation from shop.models import OrderProductRelation
class AddToOrderForm(forms.Form):
quantity = forms.IntegerField(initial=1)
class OrderProductRelationForm(forms.ModelForm): class OrderProductRelationForm(forms.ModelForm):
class Meta: class Meta:
model = OrderProductRelation model = OrderProductRelation
fields = ['quantity'] fields = ['quantity']

View file

@ -40,7 +40,9 @@
{% if product.is_stock_available %} {% if product.is_stock_available %}
<h3>Add to order</h3> <h3>{% if already_in_order %}Update order{% else %}Add to order{% endif %}</h3>
{% if already_in_order %}<p>You already have this product in your order.</p>{% endif %}
{% if user.is_authenticated %} {% if user.is_authenticated %}
@ -49,7 +51,9 @@
<form method="POST"> <form method="POST">
{% csrf_token %} {% csrf_token %}
{% bootstrap_form form %} {% bootstrap_form form %}
{% bootstrap_button "Add to order" button_type="submit" button_class="btn-primary" %} <button type="submit" class="btn btn-primary">
{% if already_in_order %}Update{% else %}Add{% endif %}
</button>
</form> </form>
{% else %} {% else %}

View file

@ -59,16 +59,14 @@ Shop | {{ block.super }}
{% if product.stock_amount %} {% if product.stock_amount %}
{% if product.left_in_stock <= 10 %}
<div class="label label-info">
Only {{ product.left_in_stock }} left!
</div>
{% endif %}
{% if product.left_in_stock == 0 %} {% if product.left_in_stock == 0 %}
<div class="label label-danger"> <div class="label label-danger">
Sold out! Sold out!
</div> </div>
{% elif product.left_in_stock <= 10 %}
<div class="label label-info">
Only {{ product.left_in_stock }} left!
</div>
{% endif %} {% endif %}
{% endif %} {% endif %}

View file

@ -41,7 +41,7 @@ from .coinify import (
process_coinify_invoice_json process_coinify_invoice_json
) )
from .epay import calculate_epay_hash, validate_epay_callback 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__) logger = logging.getLogger("bornhack.%s" % __name__)
@ -219,11 +219,39 @@ class ShopIndexView(ListView):
class ProductDetailView(FormView, DetailView): class ProductDetailView(FormView, DetailView):
model = Product model = Product
template_name = 'product_detail.html' template_name = 'product_detail.html'
form_class = AddToOrderForm form_class = OrderProductRelationForm
context_object_name = 'product' 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): 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 # this product is not publicly available
raise Http404("Product not found") raise Http404("Product not found")
@ -235,31 +263,13 @@ class ProductDetailView(FormView, DetailView):
product = self.get_object() product = self.get_object()
quantity = form.cleaned_data.get('quantity') quantity = form.cleaned_data.get('quantity')
# do we have an open order? if not hasattr(self.opr, 'order'):
try: self.opr.order = Order.objects.create(
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(
user=self.request.user, user=self.request.user,
) )
# get product from kwargs self.opr.quantity = quantity
if product in order.products.all(): self.opr.save()
# 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,
)
messages.info( messages.info(
self.request, self.request,