Factors ProductsForm handling into its own function

This commit is contained in:
Christopher Neugebauer 2016-03-26 20:43:20 +11:00
parent 464684f13e
commit 834233cd72
2 changed files with 49 additions and 40 deletions

View file

@ -28,11 +28,13 @@ class ProductController(object):
if products is not None: if products is not None:
all_products = itertools.chain(all_products, products) all_products = itertools.chain(all_products, products)
return [ out = [
product product
for product in all_products for product in all_products
if cls(product).can_add_with_enabling_conditions(user, 0) if cls(product).can_add_with_enabling_conditions(user, 0)
] ]
out.sort(key=lambda product: product.order)
return out
def user_can_add_within_limit(self, user, quantity): def user_can_add_within_limit(self, user, quantity):
''' Return true if the user is able to add _quantity_ to their count of ''' Return true if the user is able to add _quantity_ to their count of

View file

@ -98,25 +98,49 @@ def product_category(request, category_id):
v = handle_voucher(request, VOUCHERS_FORM_PREFIX) v = handle_voucher(request, VOUCHERS_FORM_PREFIX)
voucher_form, voucher_handled = v voucher_form, voucher_handled = v
# Handle the products form
category_id = int(category_id) # Routing is [0-9]+ category_id = int(category_id) # Routing is [0-9]+
category = rego.Category.objects.get(pk=category_id) category = rego.Category.objects.get(pk=category_id)
current_cart = CartController.for_user(request.user)
attendee = rego.Attendee.get_instance(request.user)
products = rego.Product.objects.filter(category=category)
products = products.order_by("order")
products = ProductController.available_products( products = ProductController.available_products(
request.user, request.user,
products=products, category=category,
) )
p = handle_products(request, category, products, PRODUCTS_FORM_PREFIX)
products_form, discounts, products_handled = p
if request.POST and not voucher_handled and not products_form.errors:
# Only return to the dashboard if we didn't add a voucher code
# and if there's no errors in the products form
attendee = rego.Attendee.get_instance(request.user)
if category_id > attendee.highest_complete_category:
attendee.highest_complete_category = category_id
attendee.save()
return redirect("dashboard")
data = {
"category": category,
"discounts": discounts,
"form": products_form,
"voucher_form": voucher_form,
}
return render(request, "product_category.html", data)
def handle_products(request, category, products, prefix):
''' Handles a products list form in the given request. Returns the
form instance, the discounts applicable to this form, and whether the
contents were handled. '''
current_cart = CartController.for_user(request.user)
ProductsForm = forms.ProductsForm(products) ProductsForm = forms.ProductsForm(products)
# Create initial data for each of products in category # Create initial data for each of products in category
items = rego.ProductItem.objects.filter( items = rego.ProductItem.objects.filter(
product__category=category, product__in=products,
cart=current_cart.cart, cart=current_cart.cart,
) )
quantities = [] quantities = []
@ -128,65 +152,48 @@ def product_category(request, category_id):
quantity = 0 quantity = 0
quantities.append((product, quantity)) quantities.append((product, quantity))
cat_form = ProductsForm( products_form = ProductsForm(
request.POST or None, request.POST or None,
product_quantities=quantities, product_quantities=quantities,
prefix=PRODUCTS_FORM_PREFIX, prefix=prefix,
) )
if ( if request.method == "POST" and products_form.is_valid():
not voucher_handled and
request.method == "POST" and
cat_form.is_valid()):
try: try:
if cat_form.has_changed(): if products_form.has_changed():
handle_valid_cat_form(cat_form, current_cart) set_quantities_from_products_form(products_form, current_cart)
except ValidationError: except ValidationError:
# There were errors, but they've already been added to the form.
pass pass
# If category is required, the user must have at least one # If category is required, the user must have at least one
# in an active+valid cart # in an active+valid cart
if category.required: if category.required:
carts = rego.Cart.reserved_carts().filter(user=request.user) carts = rego.Cart.objects.filter(user=request.user)
items = rego.ProductItem.objects.filter( items = rego.ProductItem.objects.filter(
product__category=category, product__category=category,
cart=carts, cart=carts,
) )
if len(items) == 0: if len(items) == 0:
cat_form.add_error( products_form.add_error(
None, None,
"You must have at least one item from this category", "You must have at least one item from this category",
) )
handled = False if products_form.errors else True
if not cat_form.errors:
if category_id > attendee.highest_complete_category:
attendee.highest_complete_category = category_id
attendee.save()
return redirect("dashboard")
discounts = discount.available_discounts(request.user, [], products) discounts = discount.available_discounts(request.user, [], products)
data = { return products_form, discounts, handled
"category": category,
"discounts": discounts,
"form": cat_form,
"voucher_form": voucher_form,
}
return render(request, "product_category.html", data)
@transaction.atomic @transaction.atomic
def handle_valid_cat_form(cat_form, current_cart): def set_quantities_from_products_form(products_form, current_cart):
for product_id, quantity, field_name in cat_form.product_quantities(): for product_id, quantity, field_name in products_form.product_quantities():
product = rego.Product.objects.get(pk=product_id) product = rego.Product.objects.get(pk=product_id)
try: try:
current_cart.set_quantity(product, quantity, batched=True) current_cart.set_quantity(product, quantity, batched=True)
except ValidationError as ve: except ValidationError as ve:
cat_form.add_error(field_name, ve) products_form.add_error(field_name, ve)
if cat_form.errors: if products_form.errors:
raise ValidationError("Cannot add that stuff") raise ValidationError("Cannot add that stuff")
current_cart.end_batch() current_cart.end_batch()