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
|
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
|
@python_2_unicode_compatible
|
||||||
class DiscountBase(models.Model):
|
class DiscountBase(models.Model):
|
||||||
|
@ -154,7 +222,7 @@ class DiscountForCategory(models.Model):
|
||||||
quantity = models.PositiveIntegerField()
|
quantity = models.PositiveIntegerField()
|
||||||
|
|
||||||
|
|
||||||
class TimeOrStockLimitDiscount(DiscountBase):
|
class TimeOrStockLimitDiscount(TimeOrStockLimitCondition, DiscountBase):
|
||||||
''' Discounts that are generally available, but are limited by timespan or
|
''' Discounts that are generally available, but are limited by timespan or
|
||||||
usage count. This is for e.g. Early Bird discounts.
|
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 = _("discount (time/stock limit)")
|
||||||
verbose_name_plural = _("discounts (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(VoucherCondition, DiscountBase):
|
||||||
class VoucherDiscount(DiscountBase):
|
|
||||||
''' Discounts that are enabled when a voucher code is in the current
|
''' 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
|
cart. These are normally configured in the Admin page at the same time as
|
||||||
creating a Voucher object.
|
creating a Voucher object.
|
||||||
|
@ -210,15 +259,8 @@ class VoucherDiscount(DiscountBase):
|
||||||
verbose_name = _("discount (enabled by voucher)")
|
verbose_name = _("discount (enabled by voucher)")
|
||||||
verbose_name_plural = _("discounts (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(IncludedProductCondition, DiscountBase):
|
||||||
class IncludedProductDiscount(DiscountBase):
|
|
||||||
''' Discounts that are enabled because another product has been purchased.
|
''' Discounts that are enabled because another product has been purchased.
|
||||||
e.g. A conference ticket includes a free t-shirt.
|
e.g. A conference ticket includes a free t-shirt.
|
||||||
|
|
||||||
|
@ -233,13 +275,6 @@ class IncludedProductDiscount(DiscountBase):
|
||||||
verbose_name = _("discount (product inclusions)")
|
verbose_name = _("discount (product inclusions)")
|
||||||
verbose_name_plural = _("discounts (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):
|
class RoleDiscount(object):
|
||||||
''' Discounts that are enabled because the active user has a specific
|
''' 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
|
''' 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
|
specific date range, or when fewer than a limit of products have been
|
||||||
sold.
|
sold.
|
||||||
|
@ -352,28 +387,9 @@ class TimeOrStockLimitFlag(FlagBase):
|
||||||
verbose_name = _("flag (time/stock limit)")
|
verbose_name = _("flag (time/stock limit)")
|
||||||
verbose_name_plural = _("flags (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
|
@python_2_unicode_compatible
|
||||||
class ProductFlag(FlagBase):
|
class ProductFlag(IncludedProductCondition, FlagBase):
|
||||||
''' The condition is met because a specific product is purchased.
|
''' The condition is met because a specific product is purchased.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
|
@ -389,12 +405,6 @@ class ProductFlag(FlagBase):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Enabled by products: " + str(self.enabling_products.all())
|
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
|
@python_2_unicode_compatible
|
||||||
class CategoryFlag(FlagBase):
|
class CategoryFlag(FlagBase):
|
||||||
|
@ -422,7 +432,7 @@ class CategoryFlag(FlagBase):
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@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.
|
''' The condition is met because a Voucher is present. This is for e.g.
|
||||||
enabling sponsor tickets. '''
|
enabling sponsor tickets. '''
|
||||||
|
|
||||||
|
@ -434,8 +444,6 @@ class VoucherFlag(FlagBase):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Enabled by voucher: %s" % self.voucher
|
return "Enabled by voucher: %s" % self.voucher
|
||||||
|
|
||||||
voucher = models.OneToOneField(inventory.Voucher)
|
|
||||||
|
|
||||||
|
|
||||||
# @python_2_unicode_compatible
|
# @python_2_unicode_compatible
|
||||||
class RoleFlag(object):
|
class RoleFlag(object):
|
||||||
|
|
Loading…
Reference in a new issue