Changeset - 734592207edf
[Not reviewed]
Merge
0 2 0
Christopher Neugebauer - 8 years ago 2016-09-15 05:39:07
chrisjrn@gmail.com
Merge branch 'chrisjrn/fix_71'

Fixes #71
2 files changed with 43 insertions and 37 deletions:
0 comments (0 inline, 0 general)
registrasion/controllers/conditions.py
Show inline comments
...
 
@@ -209,131 +209,129 @@ class TimeOrStockLimitConditionController(
 

	
 
        now = timezone.now()
 

	
 
        # Keep items with no start time, or start time not yet met.
 
        queryset = queryset.filter(Q(start_time=None) | Q(start_time__lte=now))
 
        queryset = queryset.filter(Q(end_time=None) | Q(end_time__gte=now))
 

	
 
        # Filter out items that have been reserved beyond the limits
 
        quantity_or_zero = self._calculate_quantities(user)
 

	
 
        remainder = Case(
 
            When(limit=None, then=Value(_BIG_QUANTITY)),
 
            default=F("limit") - Sum(quantity_or_zero),
 
        )
 

	
 
        queryset = queryset.annotate(remainder=remainder)
 
        queryset = queryset.filter(remainder__gt=0)
 

	
 
        return queryset
 

	
 
    @classmethod
 
    def _relevant_carts(cls, user):
 
        reserved_carts = commerce.Cart.reserved_carts()
 
        reserved_carts = reserved_carts.exclude(
 
            user=user,
 
            status=commerce.Cart.STATUS_ACTIVE,
 
        )
 
        return reserved_carts
 

	
 

	
 
class TimeOrStockLimitFlagController(
 
        TimeOrStockLimitConditionController):
 

	
 
    @classmethod
 
    def _calculate_quantities(cls, user):
 
        reserved_carts = cls._relevant_carts(user)
 

	
 
        # Calculate category lines
 
        item_cats = F('categories__product__productitem__product__category')
 
        reserved_category_products = (
 
            Q(categories=item_cats) &
 
            Q(categories__product__productitem__cart__in=reserved_carts)
 
        )
 

	
 
        # Calculate product lines
 
        reserved_products = (
 
            Q(products=F('products__productitem__product')) &
 
            Q(products__productitem__cart__in=reserved_carts)
 
        )
 

	
 
        category_quantity_in_reserved_carts = When(
 
            reserved_category_products,
 
            then="categories__product__productitem__quantity",
 
        )
 

	
 
        product_quantity_in_reserved_carts = When(
 
            reserved_products,
 
            then="products__productitem__quantity",
 
        )
 

	
 
        quantity_or_zero = Case(
 
            category_quantity_in_reserved_carts,
 
            product_quantity_in_reserved_carts,
 
            default=Value(0),
 
        )
 

	
 
        return quantity_or_zero
 

	
 

	
 
class TimeOrStockLimitDiscountController(TimeOrStockLimitConditionController):
 

	
 
    @classmethod
 
    def _calculate_quantities(cls, user):
 
        reserved_carts = cls._relevant_carts(user)
 

	
 
        quantity_in_reserved_carts = When(
 
            discountitem__cart__in=reserved_carts,
 
            then="discountitem__quantity"
 
        )
 

	
 
        quantity_or_zero = Case(
 
            quantity_in_reserved_carts,
 
            default=Value(0)
 
        )
 

	
 
        return quantity_or_zero
 

	
 

	
 
class VoucherConditionController(IsMetByFilter, ConditionController):
 
    ''' Condition test for VoucherFlag and VoucherDiscount.'''
 

	
 
    @classmethod
 
    def pre_filter(self, queryset, user):
 
        ''' Returns all of the items from queryset where the user has entered
 
        a voucher that invokes that item's condition in one of their carts. '''
 

	
 
        return queryset.filter(voucher__cart__user=user)
 

	
 

	
 
class SpeakerConditionController(IsMetByFilter, ConditionController):
 

	
 
    @classmethod
 
    def pre_filter(self, queryset, user):
 
        ''' Returns all of the items from queryset which are enabled by a user
 
        being a presenter or copresenter of a proposal. '''
 

	
 
        u = user
 
        # User is a presenter
 
        user_is_presenter = Q(
 
            is_presenter=True,
 
            proposal_kind__proposalbase__presentation__speaker__user=u,
 
        )
 
        # User is a copresenter
 
        user_is_copresenter = Q(
 
            is_copresenter=True,
 
            proposal_kind__proposalbase__presentation__additional_speakers__user=u,  # NOQA
 
        )
 

	
 
        return queryset.filter(user_is_presenter | user_is_copresenter)
 

	
 

	
 
class GroupMemberConditionController(IsMetByFilter, ConditionController):
 

	
 
    @classmethod
 
    def pre_filter(self, conditions, user):
 
        ''' Returns all of the items from conditions which are enabled by a
 
        user being member of a Django Auth Group. '''
 

	
 
        return conditions.filter(
 
            group=user.groups.all(),
 
        )
 
        return conditions.filter(group__in=user.groups.all())
registrasion/tests/test_group_member.py
Show inline comments
 
import pytz
 

	
 
from django.contrib.auth.models import Group
 
from django.core.exceptions import ValidationError
 

	
 
from registrasion.models import commerce
 
from registrasion.models import conditions
 
from registrasion.controllers.category import CategoryController
 
from controller_helpers import TestingCartController
 
from controller_helpers import TestingInvoiceController
 
from registrasion.controllers.product import ProductController
 

	
 
from test_cart import RegistrationCartTestCase
 

	
 
UTC = pytz.timezone('UTC')
 

	
 

	
 
class GroupMemberTestCase(RegistrationCartTestCase):
 

	
 
    @classmethod
 
    def _create_group_and_flag(cls):
 
        ''' Creates cls.GROUP, and restricts cls.PROD_1 only to users who are
 
        members of the group. '''
 
        ''' Creates cls.GROUP_1, and restricts cls.PROD_1 only to users who are
 
        members of the group. Likewise GROUP_2 and PROD_2 '''
 

	
 
        group = Group.objects.create(
 
            name="TEST GROUP",
 
        )
 
        groups = []
 
        products = [cls.PROD_1, cls.PROD_2]
 
        for i, product in enumerate(products):
 
            group = Group.objects.create(name="TEST GROUP" + str(i))
 
            flag = conditions.GroupMemberFlag.objects.create(
 
                description="Group member flag " + str(i),
 
                condition=conditions.FlagBase.ENABLE_IF_TRUE,
 
            )
 
            flag.group.add(group)
 
            flag.products.add(product)
 

	
 
        flag = conditions.GroupMemberFlag.objects.create(
 
            description="Group member flag",
 
            condition=conditions.FlagBase.ENABLE_IF_TRUE,
 
        )
 
        flag.group.add(group)
 
        flag.products.add(cls.PROD_1)
 
            groups.append(group)
 

	
 
        cls.GROUP = group
 
        cls.GROUP_1 = groups[0]
 
        cls.GROUP_2 = groups[1]
 

	
 
    def test_product_not_enabled_until_user_joins_group(self):
 
        ''' Tests that GroupMemberFlag disables a product for a user until
 
        they are a member of a specific group. '''
 

	
 
        self._create_group_and_flag()
 

	
 
        # USER_1 cannot see PROD_1 until they're in GROUP.
 
        available = ProductController.available_products(
 
            self.USER_1,
 
            products=[self.PROD_1],
 
        )
 
        self.assertNotIn(self.PROD_1, available)
 

	
 
        self.USER_1.groups.add(self.GROUP)
 

	
 
        # USER_1 cannot see PROD_1 until they're in GROUP.
 
        available = ProductController.available_products(
 
            self.USER_1,
 
            products=[self.PROD_1],
 
        )
 
        self.assertIn(self.PROD_1, available)
 

	
 
        # USER_2 is still locked out
 
        available = ProductController.available_products(
 
            self.USER_2,
 
            products=[self.PROD_1],
 
        )
 
        self.assertNotIn(self.PROD_1, available)
 
        groups = [self.GROUP_1, self.GROUP_2]
 
        products = [self.PROD_1, self.PROD_2]
 

	
 
        for group, product in zip(groups, products):
 

	
 
            # USER_1 cannot see PROD_1 until they're in GROUP.
 
            available = ProductController.available_products(
 
                self.USER_1,
 
                products=[product],
 
            )
 
            self.assertNotIn(product, available)
 

	
 
            self.USER_1.groups.add(group)
 

	
 
            # USER_1 cannot see PROD_1 until they're in GROUP.
 
            available = ProductController.available_products(
 
                self.USER_1,
 
                products=[product],
 
            )
 
            self.assertIn(product, available)
 

	
 
            # USER_2 is still locked out
 
            available = ProductController.available_products(
 
                self.USER_2,
 
                products=[product],
 
            )
 
            self.assertNotIn(product, available)
0 comments (0 inline, 0 general)