Changeset - 0d458bea068e
[Not reviewed]
0 3 1
Christopher Neugebauer - 8 years ago 2016-03-27 02:12:33
chrisjrn@gmail.com
Allows Product.limit_per_user to be blank and null. Adds Category.limit_per_user. Adds functionality and tests to verify that this is legal.
4 files changed with 132 insertions and 14 deletions:
0 comments (0 inline, 0 general)
registrasion/controllers/product.py
Show inline comments
 
import itertools
 

	
 
from django.db.models import Q
 
from django.db.models import Sum
 
from registrasion import models as rego
 

	
 
from conditions import ConditionController
...
 
@@ -42,17 +43,25 @@ class ProductController(object):
 

	
 
        carts = rego.Cart.objects.filter(user=user)
 
        items = rego.ProductItem.objects.filter(
 
            product=self.product,
 
            cart=carts)
 
            cart=carts,
 
        )
 

	
 
        count = 0
 
        for item in items:
 
            count += item.quantity
 
        prod_items = items.filter(product=self.product)
 
        cat_items = items.filter(product__category=self.product.category)
 

	
 
        if quantity + count > self.product.limit_per_user:
 
            return False
 
        else:
 
        prod_count = prod_items.aggregate(Sum("quantity"))["quantity__sum"]
 
        cat_count = cat_items.aggregate(Sum("quantity"))["quantity__sum"]
 

	
 
        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:
 
            return True
 
        else:
 
            return False
 

	
 
    def can_add_with_enabling_conditions(self, user, quantity):
 
        ''' Returns true if the user is able to add _quantity_ to their count
registrasion/migrations/0007_auto_20160326_2105.py
Show inline comments
 
new file 100644
 
# -*- coding: utf-8 -*-
 
from __future__ import unicode_literals
 

	
 
from django.db import migrations, models
 

	
 

	
 
class Migration(migrations.Migration):
 

	
 
    dependencies = [
 
        ('registrasion', '0006_category_required'),
 
    ]
 

	
 
    operations = [
 
        migrations.AddField(
 
            model_name='category',
 
            name='limit_per_user',
 
            field=models.PositiveIntegerField(null=True, verbose_name='Limit per user', blank=True),
 
        ),
 
        migrations.AlterField(
 
            model_name='product',
 
            name='limit_per_user',
 
            field=models.PositiveIntegerField(null=True, verbose_name='Limit per user', blank=True),
 
        ),
 
    ]
registrasion/models.py
Show inline comments
...
 
@@ -132,6 +132,10 @@ class Category(models.Model):
 
    name = models.CharField(max_length=65, verbose_name=_("Name"))
 
    description = models.CharField(max_length=255,
 
                                   verbose_name=_("Description"))
 
    limit_per_user = models.PositiveIntegerField(
 
        null=True,
 
        blank=True,
 
        verbose_name=_("Limit per user"))
 
    required = models.BooleanField(blank=True)
 
    order = models.PositiveIntegerField(verbose_name=("Display order"))
 
    render_type = models.IntegerField(choices=CATEGORY_RENDER_TYPES,
...
 
@@ -153,6 +157,7 @@ class Product(models.Model):
 
                                decimal_places=2,
 
                                verbose_name=_("Price"))
 
    limit_per_user = models.PositiveIntegerField(
 
        null=True,
 
        blank=True,
 
        verbose_name=_("Limit per user"))
 
    reservation_duration = models.DurationField(
registrasion/tests/test_cart.py
Show inline comments
...
 
@@ -35,7 +35,7 @@ class RegistrationCartTestCase(SetTimeMixin, TestCase):
 
        cls.RESERVATION = datetime.timedelta(hours=1)
 

	
 
        cls.categories = []
 
        for i in xrange(3):
 
        for i in xrange(2):
 
            cat = rego.Category.objects.create(
 
                name="Category " + str(i + 1),
 
                description="This is a test category",
...
 
@@ -48,13 +48,12 @@ class RegistrationCartTestCase(SetTimeMixin, TestCase):
 

	
 
        cls.CAT_1 = cls.categories[0]
 
        cls.CAT_2 = cls.categories[1]
 
        cls.CAT_3 = cls.categories[2]
 

	
 
        cls.products = []
 
        for i in xrange(6):
 
        for i in xrange(4):
 
            prod = rego.Product.objects.create(
 
                name="Product 1",
 
                description="This is a test product."
 
                description="This is a test product.",
 
                category=cls.categories[i / 2],  # 2 products per category
 
                price=Decimal("10.00"),
 
                reservation_duration=cls.RESERVATION,
...
 
@@ -68,8 +67,6 @@ class RegistrationCartTestCase(SetTimeMixin, TestCase):
 
        cls.PROD_2 = cls.products[1]
 
        cls.PROD_3 = cls.products[2]
 
        cls.PROD_4 = cls.products[3]
 
        cls.PROD_5 = cls.products[4]
 
        cls.PROD_6 = cls.products[5]
 

	
 
        cls.PROD_4.price = Decimal("5.00")
 
        cls.PROD_4.save()
...
 
@@ -208,3 +205,86 @@ class BasicCartTests(RegistrationCartTestCase):
 
        # Second user should not be affected by first user's limits
 
        second_user_cart = CartController.for_user(self.USER_2)
 
        second_user_cart.add_to_cart(self.PROD_1, 10)
 

	
 
    def set_limits(self):
 
        self.CAT_2.limit_per_user = 10
 
        self.PROD_2.limit_per_user = None
 
        self.PROD_3.limit_per_user = None
 
        self.PROD_4.limit_per_user = 6
 

	
 
        self.CAT_2.save()
 
        self.PROD_2.save()
 
        self.PROD_3.save()
 
        self.PROD_4.save()
 

	
 
    def test_per_user_product_limit_ignored_if_blank(self):
 
        self.set_limits()
 

	
 
        current_cart = CartController.for_user(self.USER_1)
 
        # There is no product limit on PROD_2, and there is no cat limit
 
        current_cart.add_to_cart(self.PROD_2, 1)
 
        # There is no product limit on PROD_3, but there is a cat limit
 
        current_cart.add_to_cart(self.PROD_3, 1)
 

	
 
    def test_per_user_category_limit_ignored_if_blank(self):
 
        self.set_limits()
 
        current_cart = CartController.for_user(self.USER_1)
 
        # There is no product limit on PROD_2, and there is no cat limit
 
        current_cart.add_to_cart(self.PROD_2, 1)
 
        # There is no cat limit on PROD_1, but there is a prod limit
 
        current_cart.add_to_cart(self.PROD_1, 1)
 

	
 
    def test_per_user_category_limit_only(self):
 
        self.set_limits()
 

	
 
        current_cart = CartController.for_user(self.USER_1)
 

	
 
        # Cannot add to cart if category limit is filled by one product.
 
        current_cart.set_quantity(self.PROD_3, 10)
 
        with self.assertRaises(ValidationError):
 
            current_cart.set_quantity(self.PROD_4, 1)
 

	
 
        # Can add to cart if category limit is not filled by one product
 
        current_cart.set_quantity(self.PROD_3, 5)
 
        current_cart.set_quantity(self.PROD_4, 5)
 
        # Cannot add to cart if category limit is filled by two products
 
        with self.assertRaises(ValidationError):
 
            current_cart.add_to_cart(self.PROD_3, 1)
 

	
 
        current_cart.cart.active = False
 
        current_cart.cart.save()
 

	
 
        current_cart = CartController.for_user(self.USER_1)
 
        # The category limit should extend across carts
 
        with self.assertRaises(ValidationError):
 
            current_cart.add_to_cart(self.PROD_3, 10)
 

	
 
    def test_per_user_category_and_product_limits(self):
 
        self.set_limits()
 

	
 
        current_cart = CartController.for_user(self.USER_1)
 

	
 
        # Hit both the product and category edges:
 
        current_cart.set_quantity(self.PROD_3, 4)
 
        current_cart.set_quantity(self.PROD_4, 6)
 
        with self.assertRaises(ValidationError):
 
            # There's unlimited PROD_3, but limited in the category
 
            current_cart.add_to_cart(self.PROD_3, 1)
 

	
 
        current_cart.set_quantity(self.PROD_3, 0)
 
        with self.assertRaises(ValidationError):
 
            # There's only 6 allowed of PROD_4
 
            current_cart.add_to_cart(self.PROD_4, 1)
 

	
 
        # The limits should extend across carts...
 
        current_cart.cart.active = False
 
        current_cart.cart.save()
 

	
 
        current_cart = CartController.for_user(self.USER_1)
 
        current_cart.set_quantity(self.PROD_3, 4)
 

	
 
        with self.assertRaises(ValidationError):
 
            current_cart.set_quantity(self.PROD_3, 5)
 

	
 
        with self.assertRaises(ValidationError):
 
            current_cart.set_quantity(self.PROD_4, 1)
0 comments (0 inline, 0 general)