Makes EnablingConditionBase a minimal reification of an abstract base model FlagBase, replaces enablingconditionbase with flagbase where possible, and fixes method names and documentation
This commit is contained in:
parent
638ec26126
commit
c24b9ee213
6 changed files with 65 additions and 33 deletions
|
@ -118,7 +118,7 @@ class CartController(object):
|
|||
|
||||
def _test_limits(self, product_quantities):
|
||||
''' Tests that the quantity changes we intend to make do not violate
|
||||
the limits and enabling conditions imposed on the products. '''
|
||||
the limits and flag conditions imposed on the products. '''
|
||||
|
||||
errors = []
|
||||
|
||||
|
@ -159,8 +159,8 @@ class CartController(object):
|
|||
)
|
||||
))
|
||||
|
||||
# Test the enabling conditions
|
||||
errs = ConditionController.test_enabling_conditions(
|
||||
# Test the flag conditions
|
||||
errs = ConditionController.test_flags(
|
||||
self.cart.user,
|
||||
product_quantities=product_quantities,
|
||||
)
|
||||
|
|
|
@ -65,16 +65,16 @@ class ConditionController(object):
|
|||
}
|
||||
|
||||
@classmethod
|
||||
def test_enabling_conditions(
|
||||
def test_flags(
|
||||
cls, user, products=None, product_quantities=None):
|
||||
''' Evaluates all of the enabling conditions on the given products.
|
||||
''' Evaluates all of the flag conditions on the given products.
|
||||
|
||||
If `product_quantities` is supplied, the condition is only met if it
|
||||
will permit the sum of the product quantities for all of the products
|
||||
it covers. Otherwise, it will be met if at least one item can be
|
||||
accepted.
|
||||
|
||||
If all enabling conditions pass, an empty list is returned, otherwise
|
||||
If all flag conditions pass, an empty list is returned, otherwise
|
||||
a list is returned containing all of the products that are *not
|
||||
enabled*. '''
|
||||
|
||||
|
@ -90,14 +90,13 @@ class ConditionController(object):
|
|||
quantities = {}
|
||||
|
||||
# Get the conditions covered by the products themselves
|
||||
|
||||
prods = (
|
||||
product.enablingconditionbase_set.select_subclasses()
|
||||
product.flagbase_set.select_subclasses()
|
||||
for product in products
|
||||
)
|
||||
# Get the conditions covered by their categories
|
||||
cats = (
|
||||
category.enablingconditionbase_set.select_subclasses()
|
||||
category.flagbase_set.select_subclasses()
|
||||
for category in set(product.category for product in products)
|
||||
)
|
||||
|
||||
|
@ -172,7 +171,7 @@ class ConditionController(object):
|
|||
return error_fields
|
||||
|
||||
def user_quantity_remaining(self, user):
|
||||
''' Returns the number of items covered by this enabling condition the
|
||||
''' Returns the number of items covered by this flag condition the
|
||||
user can add to the current cart. This default implementation returns
|
||||
a big number if is_met() is true, otherwise 0.
|
||||
|
||||
|
@ -182,7 +181,7 @@ class ConditionController(object):
|
|||
return 99999999 if self.is_met(user) else 0
|
||||
|
||||
def is_met(self, user):
|
||||
''' Returns True if this enabling condition is met, otherwise returns
|
||||
''' Returns True if this flag condition is met, otherwise returns
|
||||
False.
|
||||
|
||||
Either this method, or user_quantity_remaining() must be overridden
|
||||
|
|
|
@ -15,9 +15,9 @@ class ProductController(object):
|
|||
@classmethod
|
||||
def available_products(cls, user, category=None, products=None):
|
||||
''' Returns a list of all of the products that are available per
|
||||
enabling conditions from the given categories.
|
||||
flag conditions from the given categories.
|
||||
TODO: refactor so that all conditions are tested here and
|
||||
can_add_with_enabling_conditions calls this method. '''
|
||||
can_add_with_flags calls this method. '''
|
||||
if category is None and products is None:
|
||||
raise ValueError("You must provide products or a category")
|
||||
|
||||
|
@ -45,7 +45,7 @@ class ProductController(object):
|
|||
if cls(product).user_quantity_remaining(user) > 0
|
||||
)
|
||||
|
||||
failed_and_messages = ConditionController.test_enabling_conditions(
|
||||
failed_and_messages = ConditionController.test_flags(
|
||||
user, products=passed_limits
|
||||
)
|
||||
failed_conditions = set(i[0] for i in failed_and_messages)
|
||||
|
|
25
registrasion/migrations/0024_auto_20160411_2230.py
Normal file
25
registrasion/migrations/0024_auto_20160411_2230.py
Normal file
|
@ -0,0 +1,25 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.9.2 on 2016-04-11 22:30
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('registrasion', '0023_auto_20160411_1001_squashed_0024_auto_20160411_1002'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='enablingconditionbase',
|
||||
name='categories',
|
||||
field=models.ManyToManyField(blank=True, help_text="Categories whose products are affected by this flag's condition.", related_name='flagbase_set', to='registrasion.Category'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='enablingconditionbase',
|
||||
name='products',
|
||||
field=models.ManyToManyField(blank=True, help_text="Products affected by this flag's condition.", related_name='flagbase_set', to='registrasion.Product'),
|
||||
),
|
||||
]
|
|
@ -366,15 +366,8 @@ class RoleDiscount(object):
|
|||
pass
|
||||
|
||||
|
||||
class FlagBase(object):
|
||||
''' This will replace EnablingConditionBase once it's ready. '''
|
||||
|
||||
DISABLE_IF_FALSE = 1
|
||||
ENABLE_IF_TRUE = 2
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class EnablingConditionBase(models.Model):
|
||||
class FlagBase(models.Model):
|
||||
''' This defines a condition which allows products or categories to
|
||||
be made visible, or be prevented from being visible.
|
||||
|
||||
|
@ -387,10 +380,14 @@ class EnablingConditionBase(models.Model):
|
|||
|
||||
If both types of conditions exist on a product, both of these rules apply.
|
||||
'''
|
||||
# TODO: rename to FlagBase once
|
||||
# https://code.djangoproject.com/ticket/26488 is solved.
|
||||
|
||||
objects = InheritanceManager()
|
||||
class Meta:
|
||||
# TODO: make concrete once https://code.djangoproject.com/ticket/26488
|
||||
# is solved.
|
||||
abstract = True
|
||||
|
||||
DISABLE_IF_FALSE = 1
|
||||
ENABLE_IF_TRUE = 2
|
||||
|
||||
def __str__(self):
|
||||
return self.description
|
||||
|
@ -409,10 +406,10 @@ class EnablingConditionBase(models.Model):
|
|||
|
||||
description = models.CharField(max_length=255)
|
||||
condition = models.IntegerField(
|
||||
default=FlagBase.ENABLE_IF_TRUE,
|
||||
default=ENABLE_IF_TRUE,
|
||||
choices=(
|
||||
(FlagBase.DISABLE_IF_FALSE, _("Disable if false")),
|
||||
(FlagBase.ENABLE_IF_TRUE, _("Enable if true")),
|
||||
(DISABLE_IF_FALSE, _("Disable if false")),
|
||||
(ENABLE_IF_TRUE, _("Enable if true")),
|
||||
),
|
||||
help_text=_("If there is at least one 'disable if false' flag "
|
||||
"defined on a product or category, all such flag "
|
||||
|
@ -426,6 +423,7 @@ class EnablingConditionBase(models.Model):
|
|||
Product,
|
||||
blank=True,
|
||||
help_text=_("Products affected by this flag's condition."),
|
||||
related_name="flagbase_set",
|
||||
)
|
||||
categories = models.ManyToManyField(
|
||||
Category,
|
||||
|
@ -433,9 +431,19 @@ class EnablingConditionBase(models.Model):
|
|||
help_text=_("Categories whose products are affected by this flag's "
|
||||
"condition."
|
||||
),
|
||||
related_name="flagbase_set",
|
||||
)
|
||||
|
||||
|
||||
class EnablingConditionBase(FlagBase):
|
||||
''' Reifies the abstract FlagBase. This is necessary because django
|
||||
prevents renaming base classes in migrations. '''
|
||||
# TODO: remove this, and make subclasses subclass FlagBase once
|
||||
# https://code.djangoproject.com/ticket/26488 is solved.
|
||||
|
||||
objects = InheritanceManager()
|
||||
|
||||
|
||||
class TimeOrStockLimitFlag(EnablingConditionBase):
|
||||
''' Registration product ceilings '''
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ class FlagTestCases(RegistrationCartTestCase):
|
|||
|
||||
@classmethod
|
||||
def add_product_flag(cls, condition=rego.FlagBase.ENABLE_IF_TRUE):
|
||||
''' Adds a product enabling condition: adding PROD_1 to a cart is
|
||||
''' Adds a product flag condition: adding PROD_1 to a cart is
|
||||
predicated on adding PROD_2 beforehand. '''
|
||||
flag = rego.ProductFlag.objects.create(
|
||||
description="Product condition",
|
||||
|
@ -29,7 +29,7 @@ class FlagTestCases(RegistrationCartTestCase):
|
|||
|
||||
@classmethod
|
||||
def add_product_flag_on_category(cls, condition=rego.FlagBase.ENABLE_IF_TRUE):
|
||||
''' Adds a product enabling condition that operates on a category:
|
||||
''' Adds a product flag condition that operates on a category:
|
||||
adding an item from CAT_1 is predicated on adding PROD_3 beforehand '''
|
||||
flag = rego.ProductFlag.objects.create(
|
||||
description="Product condition",
|
||||
|
@ -41,7 +41,7 @@ class FlagTestCases(RegistrationCartTestCase):
|
|||
flag.save()
|
||||
|
||||
def add_category_flag(cls, condition=rego.FlagBase.ENABLE_IF_TRUE):
|
||||
''' Adds a category enabling condition: adding PROD_1 to a cart is
|
||||
''' Adds a category flag condition: adding PROD_1 to a cart is
|
||||
predicated on adding an item from CAT_2 beforehand.'''
|
||||
flag = rego.CategoryFlag.objects.create(
|
||||
description="Category condition",
|
||||
|
@ -114,7 +114,7 @@ class FlagTestCases(RegistrationCartTestCase):
|
|||
self.add_product_flag()
|
||||
self.add_category_flag()
|
||||
|
||||
# User 1 is testing the product enabling condition
|
||||
# User 1 is testing the product flag condition
|
||||
cart_1 = TestingCartController.for_user(self.USER_1)
|
||||
# Cannot add PROD_1 until a condition is met
|
||||
with self.assertRaises(ValidationError):
|
||||
|
@ -122,7 +122,7 @@ class FlagTestCases(RegistrationCartTestCase):
|
|||
cart_1.add_to_cart(self.PROD_2, 1)
|
||||
cart_1.add_to_cart(self.PROD_1, 1)
|
||||
|
||||
# User 2 is testing the category enabling condition
|
||||
# User 2 is testing the category flag condition
|
||||
cart_2 = TestingCartController.for_user(self.USER_2)
|
||||
# Cannot add PROD_1 until a condition is met
|
||||
with self.assertRaises(ValidationError):
|
||||
|
|
Loading…
Reference in a new issue