From 1b7d8a60c1197cf4648ad54de20ae34267f235c8 Mon Sep 17 00:00:00 2001 From: Christopher Neugebauer Date: Thu, 3 Mar 2016 13:40:44 -0800 Subject: [PATCH] Adds product_category form, which allows users to add products from a specific category to their cart. --- registrasion/forms.py | 13 +++++ registrasion/models.py | 4 +- registrasion/templates/product_category.html | 20 +++++++ registrasion/urls.py | 7 +++ registrasion/views.py | 57 ++++++++++++++++++++ 5 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 registrasion/forms.py create mode 100644 registrasion/templates/product_category.html create mode 100644 registrasion/urls.py create mode 100644 registrasion/views.py diff --git a/registrasion/forms.py b/registrasion/forms.py new file mode 100644 index 00000000..dc32d7b1 --- /dev/null +++ b/registrasion/forms.py @@ -0,0 +1,13 @@ +import models as rego + +from django import forms + + +class ProductItemForm(forms.Form): + product = forms.ModelChoiceField(queryset=None, empty_label=None) + quantity = forms.IntegerField() + + def __init__(self, category, *a, **k): + super(ProductItemForm, self).__init__(*a, **k) + products = rego.Product.objects.filter(category=category) + self.fields['product'].queryset = products diff --git a/registrasion/models.py b/registrasion/models.py index 4866c00b..35b44305 100644 --- a/registrasion/models.py +++ b/registrasion/models.py @@ -155,7 +155,7 @@ class DiscountForProduct(models.Model): if len(cats) != 0: raise ValidationError( _("You may only have one discount for " - "a product or its category")) + "a product or its category")) discount = models.ForeignKey(DiscountBase, on_delete=models.CASCADE) product = models.ForeignKey(Product, on_delete=models.CASCADE) @@ -184,7 +184,7 @@ class DiscountForCategory(models.Model): if len(prods) != 0: raise ValidationError( _("You may only have one discount for " - "a product or its category")) + "a product or its category")) if len(cats) > 1 or self not in cats: raise ValidationError( _("You may only have one discount line per category")) diff --git a/registrasion/templates/product_category.html b/registrasion/templates/product_category.html new file mode 100644 index 00000000..54a5bb7b --- /dev/null +++ b/registrasion/templates/product_category.html @@ -0,0 +1,20 @@ + + +{% extends "site_base.html" %} +{% block body %} + +

Product Category: {{ category.name }}

+ +

{{ category.description }}

+ +
+ {% csrf_token %} + + {{ formset }} +
+ + + +
+ +{% endblock %} diff --git a/registrasion/urls.py b/registrasion/urls.py new file mode 100644 index 00000000..257f2e2f --- /dev/null +++ b/registrasion/urls.py @@ -0,0 +1,7 @@ +from django.conf.urls import url, patterns + +urlpatterns = patterns( + "registrasion.views", + url(r"^category/([0-9]+)$", "product_category", name="product_category"), + # url(r"^category$", "product_category", name="product_category"), +) diff --git a/registrasion/views.py b/registrasion/views.py new file mode 100644 index 00000000..1b5bc254 --- /dev/null +++ b/registrasion/views.py @@ -0,0 +1,57 @@ +from registrasion import forms +from registrasion import models as rego +from registrasion.controllers.cart import CartController + +from django.contrib.auth.decorators import login_required +from django.core.exceptions import ObjectDoesNotExist +from django.db import transaction +from django.forms import formset_factory +from django.shortcuts import render +from functools import partial, wraps + + +@login_required +def product_category(request, category_id): + ''' Registration selections form for a specific category of items ''' + + category_id = int(category_id) # Routing is [0-9]+ + category = rego.Category.objects.get(pk=category_id) + + ProductItemFormForCategory = ( + wraps(forms.ProductItemForm) + (partial(forms.ProductItemForm, category=category))) + ProductItemFormSet = formset_factory(ProductItemFormForCategory, extra=0) + + if request.method == "POST": + formset = ProductItemFormSet(request.POST, request.FILES) + if formset.is_valid(): + current_cart = CartController.for_user(request.user) + with transaction.atomic(): + for form in formset.forms: + data = form.cleaned_data + # TODO set form error instead of failing completely + current_cart.set_quantity( + data["product"], data["quantity"], batched=True) + current_cart.end_batch() + else: + # Create initial data for each of products in category + initial = [] + products = rego.Product.objects.filter(category=category) + items = rego.ProductItem.objects.filter(product__category=category) + products = products.order_by("order") + for product in products: + try: + quantity = items.get(product=product).quantity + except ObjectDoesNotExist: + quantity = 0 + data = {"product": product, "quantity": quantity} + initial.append(data) + + formset = ProductItemFormSet(initial=initial) + + data = { + "category": category, + "formset": formset, + } + + return render(request, "product_category.html", data)