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…
	
	Add table
		
		Reference in a new issue
	
	 Christopher Neugebauer
						Christopher Neugebauer