Files
@ 6956c78b0de1
Branch filter:
Location: symposion_app/registrasion/controllers/product.py - annotation
6956c78b0de1
3.1 KiB
text/x-python
Merge branch 'query-optimisation'
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | 45aa83f854cb 45aa83f854cb a79ad3520e60 a79ad3520e60 0d458bea068e a79ad3520e60 a79ad3520e60 a79ad3520e60 875f736d67c5 875f736d67c5 d9e433659d01 145fd057aca0 145fd057aca0 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 d9e433659d01 45aa83f854cb 45aa83f854cb 45aa83f854cb a79ad3520e60 45aa83f854cb 45aa83f854cb 45aa83f854cb 45aa83f854cb 875f736d67c5 53413388e016 45aa83f854cb 45aa83f854cb 45aa83f854cb 45aa83f854cb 53413388e016 53413388e016 a79ad3520e60 a79ad3520e60 b40505117f4c a79ad3520e60 a79ad3520e60 b40505117f4c 45aa83f854cb 194f98bcc4d0 45aa83f854cb 45aa83f854cb a79ad3520e60 a79ad3520e60 194f98bcc4d0 194f98bcc4d0 145fd057aca0 194f98bcc4d0 cc318dfa9ba8 cc318dfa9ba8 194f98bcc4d0 194f98bcc4d0 834233cd72a9 e3ec12814779 834233cd72a9 45aa83f854cb a79ad3520e60 a79ad3520e60 a79ad3520e60 a79ad3520e60 a79ad3520e60 a79ad3520e60 a79ad3520e60 a79ad3520e60 a79ad3520e60 a79ad3520e60 a79ad3520e60 a79ad3520e60 1c6dc1278147 a79ad3520e60 a79ad3520e60 a79ad3520e60 a79ad3520e60 a79ad3520e60 a79ad3520e60 a79ad3520e60 a79ad3520e60 a79ad3520e60 d9e433659d01 a79ad3520e60 a79ad3520e60 a79ad3520e60 8f233c79430f 8f233c79430f a79ad3520e60 a79ad3520e60 a79ad3520e60 0d458bea068e d9e433659d01 a79ad3520e60 a79ad3520e60 a79ad3520e60 a79ad3520e60 a79ad3520e60 a79ad3520e60 a79ad3520e60 a79ad3520e60 a79ad3520e60 69a65ac3ed90 a79ad3520e60 | import itertools
from django.db.models import Case
from django.db.models import F, Q
from django.db.models import Sum
from django.db.models import When
from django.db.models import Value
from registrasion.models import commerce
from registrasion.models import inventory
from .category import CategoryController
from .flag import FlagController
class ProductController(object):
def __init__(self, product):
self.product = product
@classmethod
def available_products(cls, user, category=None, products=None):
''' Returns a list of all of the products that are available per
flag conditions from the given categories. '''
if category is None and products is None:
raise ValueError("You must provide products or a category")
if category is not None:
all_products = inventory.Product.objects.filter(category=category)
all_products = all_products.select_related("category")
else:
all_products = []
if products is not None:
all_products = set(itertools.chain(all_products, products))
categories = set(product.category for product in all_products)
r = CategoryController.attach_user_remainders(user, categories)
cat_quants = dict((c, c) for c in r)
r = ProductController.attach_user_remainders(user, all_products)
prod_quants = dict((p, p) for p in r)
passed_limits = set(
product
for product in all_products
if cat_quants[product.category].remainder > 0
if prod_quants[product].remainder > 0
)
failed_and_messages = FlagController.test_flags(
user, products=passed_limits
)
failed_conditions = set(i[0] for i in failed_and_messages)
out = list(passed_limits - failed_conditions)
out.sort(key=lambda product: product.order)
return out
@classmethod
def attach_user_remainders(cls, user, products):
'''
Return:
queryset(inventory.Product): A queryset containing items from
``product``, with an extra attribute -- remainder = the amount of
this item that is remaining.
'''
ids = [product.id for product in products]
products = inventory.Product.objects.filter(id__in=ids)
cart_filter = (
Q(productitem__cart__user=user) &
Q(productitem__cart__status=commerce.Cart.STATUS_PAID)
)
quantity = When(
cart_filter,
then='productitem__quantity'
)
quantity_or_zero = Case(
quantity,
default=Value(0),
)
remainder = Case(
When(limit_per_user=None, then=Value(99999999)),
default=F('limit_per_user') - Sum(quantity_or_zero),
)
products = products.annotate(remainder=remainder)
return products
def user_quantity_remaining(self, user):
''' Returns the quantity of this product that the user add in the
current cart. '''
with_remainders = self.attach_user_remainders(user, [self.product])
return with_remainders[0].remainder
|