Refactors flags and discount classes to be DRYer.
This commit is contained in:
		
							parent
							
								
									7e39339ed9
								
							
						
					
					
						commit
						1333fcdea1
					
				
					 1 changed files with 75 additions and 67 deletions
				
			
		|  | @ -9,7 +9,75 @@ from django.utils.translation import ugettext_lazy as _ | |||
| from model_utils.managers import InheritanceManager | ||||
| 
 | ||||
| 
 | ||||
| # Product Modifiers | ||||
| # Condition Types | ||||
| 
 | ||||
| class TimeOrStockLimitCondition(models.Model): | ||||
|     ''' Attributes for a condition that is limited by timespan or a count of | ||||
|     purchased or reserved items. | ||||
| 
 | ||||
|     Attributes: | ||||
|         start_time (Optional[datetime]): When the condition should start being | ||||
|             true. | ||||
| 
 | ||||
|         end_time (Optional[datetime]): When the condition should stop being | ||||
|             true. | ||||
| 
 | ||||
|         limit (Optional[int]): How many items may fall under the condition | ||||
|             the condition until it stops being false -- for all users. | ||||
|     ''' | ||||
| 
 | ||||
|     class Meta: | ||||
|         abstract = True | ||||
| 
 | ||||
|     start_time = models.DateTimeField( | ||||
|         null=True, | ||||
|         blank=True, | ||||
|         verbose_name=_("Start time"), | ||||
|         help_text=_("When the condition should start being true"), | ||||
|     ) | ||||
|     end_time = models.DateTimeField( | ||||
|         null=True, | ||||
|         blank=True, | ||||
|         verbose_name=_("End time"), | ||||
|         help_text=_("When the condition should stop being true."), | ||||
|     ) | ||||
|     limit = models.PositiveIntegerField( | ||||
|         null=True, | ||||
|         blank=True, | ||||
|         verbose_name=_("Limit"), | ||||
|         help_text=_( | ||||
|             "How many times this condition may be applied for all users." | ||||
|         ), | ||||
|     ) | ||||
| 
 | ||||
| 
 | ||||
| class VoucherCondition(models.Model): | ||||
|     ''' A condition is met when a voucher code is in the current cart. ''' | ||||
| 
 | ||||
|     class Meta: | ||||
|         abstract = True | ||||
| 
 | ||||
|     voucher = models.OneToOneField( | ||||
|         inventory.Voucher, | ||||
|         on_delete=models.CASCADE, | ||||
|         verbose_name=_("Voucher"), | ||||
|         db_index=True, | ||||
|     ) | ||||
| 
 | ||||
| 
 | ||||
| class IncludedProductCondition(models.Model): | ||||
|     class Meta: | ||||
|         abstract = True | ||||
| 
 | ||||
|     enabling_products = models.ManyToManyField( | ||||
|         inventory.Product, | ||||
|         verbose_name=_("Including product"), | ||||
|         help_text=_("If one of these products are purchased, this condition " | ||||
|                     "is met."), | ||||
|     ) | ||||
| 
 | ||||
| 
 | ||||
| # Discounts | ||||
| 
 | ||||
| @python_2_unicode_compatible | ||||
| class DiscountBase(models.Model): | ||||
|  | @ -154,7 +222,7 @@ class DiscountForCategory(models.Model): | |||
|     quantity = models.PositiveIntegerField() | ||||
| 
 | ||||
| 
 | ||||
| class TimeOrStockLimitDiscount(DiscountBase): | ||||
| class TimeOrStockLimitDiscount(TimeOrStockLimitCondition, DiscountBase): | ||||
|     ''' Discounts that are generally available, but are limited by timespan or | ||||
|     usage count. This is for e.g. Early Bird discounts. | ||||
| 
 | ||||
|  | @ -175,27 +243,8 @@ class TimeOrStockLimitDiscount(DiscountBase): | |||
|         verbose_name = _("discount (time/stock limit)") | ||||
|         verbose_name_plural = _("discounts (time/stock limit)") | ||||
| 
 | ||||
|     start_time = models.DateTimeField( | ||||
|         null=True, | ||||
|         blank=True, | ||||
|         verbose_name=_("Start time"), | ||||
|         help_text=_("This discount will only be available after this time."), | ||||
|     ) | ||||
|     end_time = models.DateTimeField( | ||||
|         null=True, | ||||
|         blank=True, | ||||
|         verbose_name=_("End time"), | ||||
|         help_text=_("This discount will only be available before this time."), | ||||
|     ) | ||||
|     limit = models.PositiveIntegerField( | ||||
|         null=True, | ||||
|         blank=True, | ||||
|         verbose_name=_("Limit"), | ||||
|         help_text=_("This discount may only be applied this many times."), | ||||
|     ) | ||||
| 
 | ||||
| 
 | ||||
| class VoucherDiscount(DiscountBase): | ||||
| class VoucherDiscount(VoucherCondition, DiscountBase): | ||||
|     ''' Discounts that are enabled when a voucher code is in the current | ||||
|     cart. These are normally configured in the Admin page at the same time as | ||||
|     creating a Voucher object. | ||||
|  | @ -210,15 +259,8 @@ class VoucherDiscount(DiscountBase): | |||
|         verbose_name = _("discount (enabled by voucher)") | ||||
|         verbose_name_plural = _("discounts (enabled by voucher)") | ||||
| 
 | ||||
|     voucher = models.OneToOneField( | ||||
|         inventory.Voucher, | ||||
|         on_delete=models.CASCADE, | ||||
|         verbose_name=_("Voucher"), | ||||
|         db_index=True, | ||||
|     ) | ||||
| 
 | ||||
| 
 | ||||
| class IncludedProductDiscount(DiscountBase): | ||||
| class IncludedProductDiscount(IncludedProductCondition, DiscountBase): | ||||
|     ''' Discounts that are enabled because another product has been purchased. | ||||
|     e.g. A conference ticket includes a free t-shirt. | ||||
| 
 | ||||
|  | @ -233,13 +275,6 @@ class IncludedProductDiscount(DiscountBase): | |||
|         verbose_name = _("discount (product inclusions)") | ||||
|         verbose_name_plural = _("discounts (product inclusions)") | ||||
| 
 | ||||
|     enabling_products = models.ManyToManyField( | ||||
|         inventory.Product, | ||||
|         verbose_name=_("Including product"), | ||||
|         help_text=_("If one of these products are purchased, the discounts " | ||||
|                     "below will be enabled."), | ||||
|     ) | ||||
| 
 | ||||
| 
 | ||||
| class RoleDiscount(object): | ||||
|     ''' Discounts that are enabled because the active user has a specific | ||||
|  | @ -330,7 +365,7 @@ class FlagBase(models.Model): | |||
|     ) | ||||
| 
 | ||||
| 
 | ||||
| class TimeOrStockLimitFlag(FlagBase): | ||||
| class TimeOrStockLimitFlag(TimeOrStockLimitCondition, FlagBase): | ||||
|     ''' Product groupings that can be used to enable a product during a | ||||
|     specific date range, or when fewer than a limit of products have been | ||||
|     sold. | ||||
|  | @ -352,28 +387,9 @@ class TimeOrStockLimitFlag(FlagBase): | |||
|         verbose_name = _("flag (time/stock limit)") | ||||
|         verbose_name_plural = _("flags (time/stock limit)") | ||||
| 
 | ||||
|     start_time = models.DateTimeField( | ||||
|         null=True, | ||||
|         blank=True, | ||||
|         help_text=_("Products included in this condition will only be " | ||||
|                     "available after this time."), | ||||
|     ) | ||||
|     end_time = models.DateTimeField( | ||||
|         null=True, | ||||
|         blank=True, | ||||
|         help_text=_("Products included in this condition will only be " | ||||
|                     "available before this time."), | ||||
|     ) | ||||
|     limit = models.PositiveIntegerField( | ||||
|         null=True, | ||||
|         blank=True, | ||||
|         help_text=_("The number of items under this grouping that can be " | ||||
|                     "purchased."), | ||||
|     ) | ||||
| 
 | ||||
| 
 | ||||
| @python_2_unicode_compatible | ||||
| class ProductFlag(FlagBase): | ||||
| class ProductFlag(IncludedProductCondition, FlagBase): | ||||
|     ''' The condition is met because a specific product is purchased. | ||||
| 
 | ||||
|     Attributes: | ||||
|  | @ -389,12 +405,6 @@ class ProductFlag(FlagBase): | |||
|     def __str__(self): | ||||
|         return "Enabled by products: " + str(self.enabling_products.all()) | ||||
| 
 | ||||
|     enabling_products = models.ManyToManyField( | ||||
|         inventory.Product, | ||||
|         help_text=_("If one of these products are purchased, this condition " | ||||
|                     "is met."), | ||||
|     ) | ||||
| 
 | ||||
| 
 | ||||
| @python_2_unicode_compatible | ||||
| class CategoryFlag(FlagBase): | ||||
|  | @ -422,7 +432,7 @@ class CategoryFlag(FlagBase): | |||
| 
 | ||||
| 
 | ||||
| @python_2_unicode_compatible | ||||
| class VoucherFlag(FlagBase): | ||||
| class VoucherFlag(VoucherCondition, FlagBase): | ||||
|     ''' The condition is met because a Voucher is present. This is for e.g. | ||||
|     enabling sponsor tickets. ''' | ||||
| 
 | ||||
|  | @ -434,8 +444,6 @@ class VoucherFlag(FlagBase): | |||
|     def __str__(self): | ||||
|         return "Enabled by voucher: %s" % self.voucher | ||||
| 
 | ||||
|     voucher = models.OneToOneField(inventory.Voucher) | ||||
| 
 | ||||
| 
 | ||||
| # @python_2_unicode_compatible | ||||
| class RoleFlag(object): | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Christopher Neugebauer
						Christopher Neugebauer