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>
{{ form.instance.total|currency }}
<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 %}

View file

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

View file

@ -40,7 +40,9 @@
{% 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 %}
@ -49,7 +51,9 @@
<form method="POST">
{% csrf_token %}
{% 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>
{% else %}

View file

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

View file

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