Adds user_quantity_remaining to CategoryController
This commit is contained in:
		
							parent
							
								
									39021cd3dd
								
							
						
					
					
						commit
						576dddcaad
					
				
					 3 changed files with 76 additions and 17 deletions
				
			
		|  | @ -1,14 +1,16 @@ | |||
| import collections | ||||
| import datetime | ||||
| import discount | ||||
| 
 | ||||
| from django.core.exceptions import ObjectDoesNotExist | ||||
| from django.core.exceptions import ValidationError | ||||
| from django.db import transaction | ||||
| from django.db.models import Max | ||||
| from django.db.models import Max, Sum | ||||
| from django.utils import timezone | ||||
| 
 | ||||
| from registrasion import models as rego | ||||
| 
 | ||||
| from category import CategoryController | ||||
| from conditions import ConditionController | ||||
| from product import ProductController | ||||
| 
 | ||||
|  | @ -71,12 +73,40 @@ class CartController(object): | |||
|     @transaction.atomic | ||||
|     def set_quantities(self, product_quantities): | ||||
| 
 | ||||
|         items_in_cart = rego.ProductItem.objects.filter(cart=self.cart) | ||||
| 
 | ||||
|         # Remove all items that we're updating | ||||
|         rego.ProductItem.objects.filter( | ||||
|             cart=self.cart, | ||||
|         items_in_cart.filter( | ||||
|             product__in=(i[0] for i in product_quantities), | ||||
|         ).delete() | ||||
| 
 | ||||
|         # Collect by category | ||||
|         by_cat = collections.defaultdict(list) | ||||
|         for product, quantity in product_quantities: | ||||
|             by_cat[product.category].append((product, quantity)) | ||||
| 
 | ||||
|         # Test each category limit here | ||||
|         for cat in by_cat: | ||||
|             ctrl = CategoryController(cat) | ||||
|             limit = ctrl.user_quantity_remaining(self.cart.user) | ||||
| 
 | ||||
|             # Get the amount so far in the cart | ||||
|             cat_items = items_in_cart.filter(product__category=cat) | ||||
|             so_far = cat_items.aggregate(Sum("quantity"))["quantity__sum"] or 0 | ||||
|             to_add = sum(i[1] for i in by_cat[cat]) | ||||
| 
 | ||||
|             if so_far + to_add > limit: | ||||
|                 # TODO: batch errors | ||||
|                 raise ValidationError( | ||||
|                     "You may only have %d items in category: %s" % ( | ||||
|                         limit, cat.name, | ||||
|                     ) | ||||
|                 ) | ||||
| 
 | ||||
|         # Test each product limit here | ||||
| 
 | ||||
|         # Test each enabling condition here | ||||
| 
 | ||||
|         for product, quantity in product_quantities: | ||||
|             self._set_quantity_old(product, quantity) | ||||
| 
 | ||||
|  | @ -86,7 +116,7 @@ class CartController(object): | |||
|         ''' Sets the _quantity_ of the given _product_ in the cart to the given | ||||
|         _quantity_. ''' | ||||
| 
 | ||||
|         self.set_quantities( ((product,quantity),) ) | ||||
|         self.set_quantities(((product, quantity),)) | ||||
| 
 | ||||
|     def _set_quantity_old(self, product, quantity): | ||||
|         ''' Sets the _quantity_ of the given _product_ in the cart to the given | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| from .product import ProductController | ||||
| 
 | ||||
| from registrasion import models as rego | ||||
| 
 | ||||
| from django.db.models import Sum | ||||
| 
 | ||||
| 
 | ||||
| class AllProducts(object): | ||||
|     pass | ||||
|  | @ -9,12 +9,18 @@ class AllProducts(object): | |||
| 
 | ||||
| class CategoryController(object): | ||||
| 
 | ||||
|     def __init__(self, category): | ||||
|         self.category = category | ||||
| 
 | ||||
|     @classmethod | ||||
|     def available_categories(cls, user, products=AllProducts): | ||||
|         ''' Returns the categories available to the user. Specify `products` if | ||||
|         you want to restrict to just the categories that hold the specified | ||||
|         products, otherwise it'll do all. ''' | ||||
| 
 | ||||
|         # STOPGAP -- this needs to be elsewhere tbqh | ||||
|         from product import ProductController | ||||
| 
 | ||||
|         if products is AllProducts: | ||||
|             products = rego.Product.objects.all() | ||||
| 
 | ||||
|  | @ -24,3 +30,33 @@ class CategoryController(object): | |||
|         ) | ||||
| 
 | ||||
|         return set(i.category for i in available) | ||||
| 
 | ||||
|     def user_quantity_remaining(self, user): | ||||
|         ''' Returns the number of items from this category that the user may | ||||
|         add in the current cart. ''' | ||||
| 
 | ||||
|         cat_limit = self.category.limit_per_user | ||||
| 
 | ||||
|         if cat_limit is None: | ||||
|             # We don't need to waste the following queries | ||||
|             return 99999999 | ||||
| 
 | ||||
|         carts = rego.Cart.objects.filter( | ||||
|             user=user, | ||||
|             active=False, | ||||
|             released=False, | ||||
|         ) | ||||
| 
 | ||||
|         items = rego.ProductItem.objects.filter( | ||||
|             cart__in=carts, | ||||
|             product__category=self.category, | ||||
|         ) | ||||
| 
 | ||||
|         cat_count = items.aggregate(Sum("quantity"))["quantity__sum"] or 0 | ||||
|          | ||||
|         cat_limit = self.category.limit_per_user | ||||
| 
 | ||||
|         if cat_limit is None: | ||||
|             return 999999  # We should probably work on this. | ||||
|         else: | ||||
|             return cat_limit - cat_count | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ from django.db.models import Q | |||
| from django.db.models import Sum | ||||
| from registrasion import models as rego | ||||
| 
 | ||||
| from category import CategoryController | ||||
| from conditions import ConditionController | ||||
| 
 | ||||
| 
 | ||||
|  | @ -32,6 +33,7 @@ class ProductController(object): | |||
|         out = [ | ||||
|             product | ||||
|             for product in all_products | ||||
|             if CategoryController(product.category).user_quantity_remaining(user) > 0 | ||||
|             if cls(product).user_can_add_within_limit(user, 1, past_carts=True) | ||||
|             if cls(product).can_add_with_enabling_conditions(user, 0) | ||||
|         ] | ||||
|  | @ -54,23 +56,14 @@ class ProductController(object): | |||
|         ) | ||||
| 
 | ||||
|         prod_items = items.filter(product=self.product) | ||||
|         cat_items = items.filter(product__category=self.product.category) | ||||
| 
 | ||||
|         prod_count = prod_items.aggregate(Sum("quantity"))["quantity__sum"] | ||||
|         cat_count = cat_items.aggregate(Sum("quantity"))["quantity__sum"] | ||||
| 
 | ||||
|         if prod_count is None: | ||||
|             prod_count = 0 | ||||
|         if cat_count is None: | ||||
|             cat_count = 0 | ||||
|         prod_count = prod_count or 0 | ||||
| 
 | ||||
|         prod_limit = self.product.limit_per_user | ||||
|         prod_met = prod_limit is None or quantity + prod_count <= prod_limit | ||||
| 
 | ||||
|         cat_limit = self.product.category.limit_per_user | ||||
|         cat_met = cat_limit is None or quantity + cat_count <= cat_limit | ||||
| 
 | ||||
|         if prod_met and cat_met: | ||||
|         if prod_met: | ||||
|             return True | ||||
|         else: | ||||
|             return False | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Christopher Neugebauer
						Christopher Neugebauer