Factors items_pending and items_purchased into ItemController
This commit is contained in:
parent
17fc874212
commit
68aa9b067b
2 changed files with 101 additions and 78 deletions
95
registrasion/controllers/item.py
Normal file
95
registrasion/controllers/item.py
Normal file
|
@ -0,0 +1,95 @@
|
|||
''' NEEDS TESTS '''
|
||||
|
||||
from registrasion.models import commerce
|
||||
from registrasion.models import inventory
|
||||
|
||||
from collections import namedtuple
|
||||
from django.db.models import Case
|
||||
from django.db.models import Q
|
||||
from django.db.models import Sum
|
||||
from django.db.models import When
|
||||
from django.db.models import Value
|
||||
|
||||
_ProductAndQuantity = namedtuple("ProductAndQuantity", ["product", "quantity"])
|
||||
|
||||
|
||||
class ProductAndQuantity(_ProductAndQuantity):
|
||||
''' Class that holds a product and a quantity.
|
||||
|
||||
Attributes:
|
||||
product (models.inventory.Product)
|
||||
|
||||
quantity (int)
|
||||
|
||||
'''
|
||||
pass
|
||||
|
||||
|
||||
class ItemController(object):
|
||||
|
||||
def __init__(self, user):
|
||||
self.user = user
|
||||
|
||||
def items_purchased(self, category=None):
|
||||
''' Aggregates the items that this user has purchased.
|
||||
|
||||
Arguments:
|
||||
category (Optional[models.inventory.Category]): the category
|
||||
of items to restrict to.
|
||||
|
||||
Returns:
|
||||
[ProductAndQuantity, ...]: A list of product-quantity pairs,
|
||||
aggregating like products from across multiple invoices.
|
||||
|
||||
'''
|
||||
|
||||
in_cart = (
|
||||
Q(productitem__cart__user=self.user) &
|
||||
Q(productitem__cart__status=commerce.Cart.STATUS_PAID)
|
||||
)
|
||||
|
||||
quantities_in_cart = When(
|
||||
in_cart,
|
||||
then="productitem__quantity",
|
||||
)
|
||||
|
||||
quantities_or_zero = Case(
|
||||
quantities_in_cart,
|
||||
default=Value(0),
|
||||
)
|
||||
|
||||
products = inventory.Product.objects
|
||||
|
||||
if category:
|
||||
products = products.filter(category=category)
|
||||
|
||||
products = products.select_related("category")
|
||||
products = products.annotate(quantity=Sum(quantities_or_zero))
|
||||
products = products.filter(quantity__gt=0)
|
||||
|
||||
out = []
|
||||
for prod in products:
|
||||
out.append(ProductAndQuantity(prod, prod.quantity))
|
||||
return out
|
||||
|
||||
def items_pending(self):
|
||||
''' Gets all of the items that the user has reserved, but has not yet
|
||||
paid for.
|
||||
|
||||
Returns:
|
||||
[ProductAndQuantity, ...]: A list of product-quantity pairs for the
|
||||
items that the user has not yet paid for.
|
||||
|
||||
'''
|
||||
|
||||
all_items = commerce.ProductItem.objects.filter(
|
||||
cart__user=self.user,
|
||||
cart__status=commerce.Cart.STATUS_ACTIVE,
|
||||
).select_related(
|
||||
"product",
|
||||
"product__category",
|
||||
).order_by(
|
||||
"product__category__order",
|
||||
"product__order",
|
||||
)
|
||||
return all_items
|
|
@ -1,31 +1,12 @@
|
|||
from registrasion.models import commerce
|
||||
from registrasion.models import inventory
|
||||
from registrasion.controllers.category import CategoryController
|
||||
from registrasion.controllers.item import ItemController
|
||||
|
||||
from collections import namedtuple
|
||||
from django import template
|
||||
from django.db.models import Case
|
||||
from django.db.models import Q
|
||||
from django.db.models import Sum
|
||||
from django.db.models import When
|
||||
from django.db.models import Value
|
||||
|
||||
register = template.Library()
|
||||
|
||||
_ProductAndQuantity = namedtuple("ProductAndQuantity", ["product", "quantity"])
|
||||
|
||||
|
||||
class ProductAndQuantity(_ProductAndQuantity):
|
||||
''' Class that holds a product and a quantity.
|
||||
|
||||
Attributes:
|
||||
product (models.inventory.Product)
|
||||
|
||||
quantity (int)
|
||||
|
||||
'''
|
||||
pass
|
||||
|
||||
|
||||
@register.assignment_tag(takes_context=True)
|
||||
def available_categories(context):
|
||||
|
@ -67,71 +48,18 @@ def invoices(context):
|
|||
|
||||
@register.assignment_tag(takes_context=True)
|
||||
def items_pending(context):
|
||||
''' Gets all of the items that the user has reserved, but has not yet
|
||||
paid for.
|
||||
|
||||
Returns:
|
||||
[ProductAndQuantity, ...]: A list of product-quantity pairs for the
|
||||
items that the user has not yet paid for.
|
||||
|
||||
'''
|
||||
|
||||
all_items = commerce.ProductItem.objects.filter(
|
||||
cart__user=context.request.user,
|
||||
cart__status=commerce.Cart.STATUS_ACTIVE,
|
||||
).select_related(
|
||||
"product",
|
||||
"product__category",
|
||||
).order_by(
|
||||
"product__category__order",
|
||||
"product__order",
|
||||
)
|
||||
return all_items
|
||||
''' Gets all of the items that the user from this context has reserved.'''
|
||||
return ItemController(context.request.user).items_pending()
|
||||
|
||||
|
||||
@register.assignment_tag(takes_context=True)
|
||||
def items_purchased(context, category=None):
|
||||
''' Aggregates the items that this user has purchased.
|
||||
''' Returns the items purchased for this user. '''
|
||||
|
||||
Arguments:
|
||||
category (Optional[models.inventory.Category]): the category of items
|
||||
to restrict to.
|
||||
|
||||
Returns:
|
||||
[ProductAndQuantity, ...]: A list of product-quantity pairs,
|
||||
aggregating like products from across multiple invoices.
|
||||
|
||||
'''
|
||||
|
||||
in_cart = (
|
||||
Q(productitem__cart__user=context.request.user) &
|
||||
Q(productitem__cart__status=commerce.Cart.STATUS_PAID)
|
||||
return ItemController(context.request.user).items_purchased(
|
||||
category=category
|
||||
)
|
||||
|
||||
quantities_in_cart = When(
|
||||
in_cart,
|
||||
then="productitem__quantity",
|
||||
)
|
||||
|
||||
quantities_or_zero = Case(
|
||||
quantities_in_cart,
|
||||
default=Value(0),
|
||||
)
|
||||
|
||||
products = inventory.Product.objects
|
||||
|
||||
if category:
|
||||
products = products.filter(category=category)
|
||||
|
||||
products = products.select_related("category")
|
||||
products = products.annotate(quantity=Sum(quantities_or_zero))
|
||||
products = products.filter(quantity__gt=0)
|
||||
|
||||
out = []
|
||||
for prod in products:
|
||||
out.append(ProductAndQuantity(prod, prod.quantity))
|
||||
return out
|
||||
|
||||
|
||||
@register.filter
|
||||
def multiply(value, arg):
|
||||
|
|
Loading…
Reference in a new issue