Merge branch 'more_admins'
This commit is contained in:
commit
4c7024c9ff
4 changed files with 365 additions and 48 deletions
|
@ -1,4 +1,5 @@
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
import nested_admin
|
import nested_admin
|
||||||
|
@ -6,21 +7,36 @@ import nested_admin
|
||||||
from registrasion import models as rego
|
from registrasion import models as rego
|
||||||
|
|
||||||
|
|
||||||
|
class EffectsDisplayMixin(object):
|
||||||
|
def effects(self, obj):
|
||||||
|
return list(obj.effects())
|
||||||
|
|
||||||
# Inventory admin
|
# Inventory admin
|
||||||
|
|
||||||
|
|
||||||
class ProductInline(admin.TabularInline):
|
class ProductInline(admin.TabularInline):
|
||||||
model = rego.Product
|
model = rego.Product
|
||||||
|
ordering = ("order", )
|
||||||
|
|
||||||
|
|
||||||
@admin.register(rego.Category)
|
@admin.register(rego.Category)
|
||||||
class CategoryAdmin(admin.ModelAdmin):
|
class CategoryAdmin(admin.ModelAdmin):
|
||||||
model = rego.Category
|
model = rego.Category
|
||||||
verbose_name_plural = _("Categories")
|
fields = ("name", "description", "required", "render_type",
|
||||||
|
"limit_per_user", "order",)
|
||||||
|
list_display = ("name", "description")
|
||||||
|
ordering = ("order", )
|
||||||
inlines = [
|
inlines = [
|
||||||
ProductInline,
|
ProductInline,
|
||||||
]
|
]
|
||||||
|
|
||||||
admin.site.register(rego.Product)
|
|
||||||
|
@admin.register(rego.Product)
|
||||||
|
class ProductAdmin(admin.ModelAdmin):
|
||||||
|
model = rego.Product
|
||||||
|
list_display = ("name", "category", "description")
|
||||||
|
list_filter = ("category", )
|
||||||
|
ordering = ("category__order", "order", )
|
||||||
|
|
||||||
|
|
||||||
# Discounts
|
# Discounts
|
||||||
|
@ -37,11 +53,34 @@ class DiscountForCategoryInline(admin.TabularInline):
|
||||||
verbose_name_plural = _("Categories included in discount")
|
verbose_name_plural = _("Categories included in discount")
|
||||||
|
|
||||||
|
|
||||||
@admin.register(
|
@admin.register(rego.TimeOrStockLimitDiscount)
|
||||||
rego.TimeOrStockLimitDiscount,
|
class TimeOrStockLimitDiscountAdmin(admin.ModelAdmin, EffectsDisplayMixin):
|
||||||
rego.IncludedProductDiscount,
|
list_display = (
|
||||||
)
|
"description",
|
||||||
class DiscountAdmin(admin.ModelAdmin):
|
"start_time",
|
||||||
|
"end_time",
|
||||||
|
"limit",
|
||||||
|
"effects",
|
||||||
|
)
|
||||||
|
ordering = ("start_time", "end_time", "limit")
|
||||||
|
|
||||||
|
inlines = [
|
||||||
|
DiscountForProductInline,
|
||||||
|
DiscountForCategoryInline,
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(rego.IncludedProductDiscount)
|
||||||
|
class IncludedProductDiscountAdmin(admin.ModelAdmin):
|
||||||
|
|
||||||
|
def enablers(self, obj):
|
||||||
|
return list(obj.enabling_products.all())
|
||||||
|
|
||||||
|
def effects(self, obj):
|
||||||
|
return list(obj.effects())
|
||||||
|
|
||||||
|
list_display = ("description", "enablers", "effects")
|
||||||
|
|
||||||
inlines = [
|
inlines = [
|
||||||
DiscountForProductInline,
|
DiscountForProductInline,
|
||||||
DiscountForCategoryInline,
|
DiscountForCategoryInline,
|
||||||
|
@ -75,7 +114,30 @@ class VoucherEnablingConditionInline(nested_admin.NestedStackedInline):
|
||||||
|
|
||||||
@admin.register(rego.Voucher)
|
@admin.register(rego.Voucher)
|
||||||
class VoucherAdmin(nested_admin.NestedAdmin):
|
class VoucherAdmin(nested_admin.NestedAdmin):
|
||||||
|
|
||||||
|
def effects(self, obj):
|
||||||
|
''' List the effects of the voucher in the admin. '''
|
||||||
|
out = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
discount_effects = obj.voucherdiscount.effects()
|
||||||
|
except ObjectDoesNotExist:
|
||||||
|
discount_effects = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
enabling_effects = obj.voucherenablingcondition.effects()
|
||||||
|
except ObjectDoesNotExist:
|
||||||
|
enabling_effects = None
|
||||||
|
|
||||||
|
if discount_effects:
|
||||||
|
out.append("Discounts: " + str(list(discount_effects)))
|
||||||
|
if enabling_effects:
|
||||||
|
out.append("Enables: " + str(list(enabling_effects)))
|
||||||
|
|
||||||
|
return "\n".join(out)
|
||||||
|
|
||||||
model = rego.Voucher
|
model = rego.Voucher
|
||||||
|
list_display = ("recipient", "code", "effects")
|
||||||
inlines = [
|
inlines = [
|
||||||
VoucherDiscountInline,
|
VoucherDiscountInline,
|
||||||
VoucherEnablingConditionInline,
|
VoucherEnablingConditionInline,
|
||||||
|
@ -84,11 +146,46 @@ class VoucherAdmin(nested_admin.NestedAdmin):
|
||||||
|
|
||||||
# Enabling conditions
|
# Enabling conditions
|
||||||
@admin.register(rego.ProductEnablingCondition)
|
@admin.register(rego.ProductEnablingCondition)
|
||||||
class ProductEnablingConditionAdmin(nested_admin.NestedAdmin):
|
class ProductEnablingConditionAdmin(
|
||||||
|
nested_admin.NestedAdmin,
|
||||||
|
EffectsDisplayMixin):
|
||||||
|
|
||||||
|
def enablers(self, obj):
|
||||||
|
return list(obj.enabling_products.all())
|
||||||
|
|
||||||
model = rego.ProductEnablingCondition
|
model = rego.ProductEnablingCondition
|
||||||
|
fields = ("description", "enabling_products", "mandatory", "products",
|
||||||
|
"categories"),
|
||||||
|
|
||||||
|
list_display = ("description", "enablers", "effects")
|
||||||
|
|
||||||
|
|
||||||
# Enabling conditions
|
# Enabling conditions
|
||||||
@admin.register(rego.CategoryEnablingCondition)
|
@admin.register(rego.CategoryEnablingCondition)
|
||||||
class CategoryEnablingConditionAdmin(nested_admin.NestedAdmin):
|
class CategoryEnablingConditionAdmin(
|
||||||
|
nested_admin.NestedAdmin,
|
||||||
|
EffectsDisplayMixin):
|
||||||
|
|
||||||
model = rego.CategoryEnablingCondition
|
model = rego.CategoryEnablingCondition
|
||||||
|
fields = ("description", "enabling_category", "mandatory", "products",
|
||||||
|
"categories"),
|
||||||
|
|
||||||
|
list_display = ("description", "enabling_category", "effects")
|
||||||
|
ordering = ("enabling_category",)
|
||||||
|
|
||||||
|
|
||||||
|
# Enabling conditions
|
||||||
|
@admin.register(rego.TimeOrStockLimitEnablingCondition)
|
||||||
|
class TimeOrStockLimitEnablingConditionAdmin(
|
||||||
|
nested_admin.NestedAdmin,
|
||||||
|
EffectsDisplayMixin):
|
||||||
|
model = rego.TimeOrStockLimitEnablingCondition
|
||||||
|
|
||||||
|
list_display = (
|
||||||
|
"description",
|
||||||
|
"start_time",
|
||||||
|
"end_time",
|
||||||
|
"limit",
|
||||||
|
"effects",
|
||||||
|
)
|
||||||
|
ordering = ("start_time", "end_time", "limit")
|
||||||
|
|
113
registrasion/migrations/0009_auto_20160330_2336.py
Normal file
113
registrasion/migrations/0009_auto_20160330_2336.py
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('registrasion', '0008_cart_released'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='category',
|
||||||
|
options={'verbose_name_plural': 'categories'},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='timeorstocklimitenablingcondition',
|
||||||
|
options={'verbose_name': 'ceiling'},
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='category',
|
||||||
|
name='limit_per_user',
|
||||||
|
field=models.PositiveIntegerField(help_text='The total number of items from this category one attendee may purchase.', null=True, verbose_name='Limit per user', blank=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='category',
|
||||||
|
name='render_type',
|
||||||
|
field=models.IntegerField(help_text='The registration form will render this category in this style.', verbose_name='Render type', choices=[(1, 'Radio button'), (2, 'Quantity boxes')]),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='category',
|
||||||
|
name='required',
|
||||||
|
field=models.BooleanField(help_text='If enabled, a user must select an item from this category.'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='categoryenablingcondition',
|
||||||
|
name='enabling_category',
|
||||||
|
field=models.ForeignKey(help_text='If a product from this category is purchased, this condition is met.', to='registrasion.Category'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='discountbase',
|
||||||
|
name='description',
|
||||||
|
field=models.CharField(help_text='A description of this discount. This will be included on invoices where this discount is applied.', max_length=255, verbose_name='Description'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='enablingconditionbase',
|
||||||
|
name='categories',
|
||||||
|
field=models.ManyToManyField(help_text='Categories whose products are enabled if this condition is met.', to='registrasion.Category', blank=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='enablingconditionbase',
|
||||||
|
name='mandatory',
|
||||||
|
field=models.BooleanField(default=False, help_text='If there is at least one mandatory condition defined on a product or category, all such conditions must be met. Otherwise, at least one non-mandatory condition must be met.'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='enablingconditionbase',
|
||||||
|
name='products',
|
||||||
|
field=models.ManyToManyField(help_text='Products that are enabled if this condition is met.', to='registrasion.Product', blank=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='includedproductdiscount',
|
||||||
|
name='enabling_products',
|
||||||
|
field=models.ManyToManyField(help_text='If one of these products are purchased, the discounts below will be enabled.', to='registrasion.Product', verbose_name='Including product'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='product',
|
||||||
|
name='description',
|
||||||
|
field=models.CharField(max_length=255, null=True, verbose_name='Description', blank=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='product',
|
||||||
|
name='reservation_duration',
|
||||||
|
field=models.DurationField(default=datetime.timedelta(0, 3600), help_text='The length of time this product will be reserved before it is released for someone else to purchase.', verbose_name='Reservation duration'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='productenablingcondition',
|
||||||
|
name='enabling_products',
|
||||||
|
field=models.ManyToManyField(help_text='If one of these products are purchased, this condition is met.', to='registrasion.Product'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='timeorstocklimitdiscount',
|
||||||
|
name='end_time',
|
||||||
|
field=models.DateTimeField(help_text='This discount will only be available before this time.', null=True, verbose_name='End time', blank=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='timeorstocklimitdiscount',
|
||||||
|
name='limit',
|
||||||
|
field=models.PositiveIntegerField(help_text='This discount may only be applied this many times.', null=True, verbose_name='Limit', blank=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='timeorstocklimitdiscount',
|
||||||
|
name='start_time',
|
||||||
|
field=models.DateTimeField(help_text='This discount will only be available after this time.', null=True, verbose_name='Start time', blank=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='timeorstocklimitenablingcondition',
|
||||||
|
name='end_time',
|
||||||
|
field=models.DateTimeField(help_text='Products included in this condition will only be available before this time.', null=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='timeorstocklimitenablingcondition',
|
||||||
|
name='limit',
|
||||||
|
field=models.PositiveIntegerField(help_text='The number of items under this grouping that can be purchased.', null=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='timeorstocklimitenablingcondition',
|
||||||
|
name='start_time',
|
||||||
|
field=models.DateTimeField(help_text='Products included in this condition will only be available after this time.', null=True),
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,6 +1,7 @@
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
|
import itertools
|
||||||
|
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
|
@ -118,6 +119,9 @@ class BadgeAndProfile(models.Model):
|
||||||
class Category(models.Model):
|
class Category(models.Model):
|
||||||
''' Registration product categories '''
|
''' Registration product categories '''
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name_plural = _("categories")
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
@ -129,17 +133,35 @@ class Category(models.Model):
|
||||||
(RENDER_TYPE_QUANTITY, _("Quantity boxes")),
|
(RENDER_TYPE_QUANTITY, _("Quantity boxes")),
|
||||||
]
|
]
|
||||||
|
|
||||||
name = models.CharField(max_length=65, verbose_name=_("Name"))
|
name = models.CharField(
|
||||||
description = models.CharField(max_length=255,
|
max_length=65,
|
||||||
verbose_name=_("Description"))
|
verbose_name=_("Name"),
|
||||||
|
)
|
||||||
|
description = models.CharField(
|
||||||
|
max_length=255,
|
||||||
|
verbose_name=_("Description"),
|
||||||
|
)
|
||||||
limit_per_user = models.PositiveIntegerField(
|
limit_per_user = models.PositiveIntegerField(
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
verbose_name=_("Limit per user"))
|
verbose_name=_("Limit per user"),
|
||||||
required = models.BooleanField(blank=True)
|
help_text=_("The total number of items from this category one "
|
||||||
order = models.PositiveIntegerField(verbose_name=("Display order"))
|
"attendee may purchase."),
|
||||||
render_type = models.IntegerField(choices=CATEGORY_RENDER_TYPES,
|
)
|
||||||
verbose_name=_("Render type"))
|
required = models.BooleanField(
|
||||||
|
blank=True,
|
||||||
|
help_text=_("If enabled, a user must select an "
|
||||||
|
"item from this category."),
|
||||||
|
)
|
||||||
|
order = models.PositiveIntegerField(
|
||||||
|
verbose_name=("Display order"),
|
||||||
|
)
|
||||||
|
render_type = models.IntegerField(
|
||||||
|
choices=CATEGORY_RENDER_TYPES,
|
||||||
|
verbose_name=_("Render type"),
|
||||||
|
help_text=_("The registration form will render this category in this "
|
||||||
|
"style."),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
|
@ -147,23 +169,41 @@ class Product(models.Model):
|
||||||
''' Registration products '''
|
''' Registration products '''
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return "%s - %s" % (self.category.name, self.name)
|
||||||
|
|
||||||
name = models.CharField(max_length=65, verbose_name=_("Name"))
|
name = models.CharField(
|
||||||
description = models.CharField(max_length=255,
|
max_length=65,
|
||||||
verbose_name=_("Description"))
|
verbose_name=_("Name"),
|
||||||
category = models.ForeignKey(Category, verbose_name=_("Product category"))
|
)
|
||||||
price = models.DecimalField(max_digits=8,
|
description = models.CharField(
|
||||||
decimal_places=2,
|
max_length=255,
|
||||||
verbose_name=_("Price"))
|
verbose_name=_("Description"),
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
)
|
||||||
|
category = models.ForeignKey(
|
||||||
|
Category,
|
||||||
|
verbose_name=_("Product category")
|
||||||
|
)
|
||||||
|
price = models.DecimalField(
|
||||||
|
max_digits=8,
|
||||||
|
decimal_places=2,
|
||||||
|
verbose_name=_("Price"),
|
||||||
|
)
|
||||||
limit_per_user = models.PositiveIntegerField(
|
limit_per_user = models.PositiveIntegerField(
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
verbose_name=_("Limit per user"))
|
verbose_name=_("Limit per user"),
|
||||||
|
)
|
||||||
reservation_duration = models.DurationField(
|
reservation_duration = models.DurationField(
|
||||||
default=datetime.timedelta(hours=1),
|
default=datetime.timedelta(hours=1),
|
||||||
verbose_name=_("Reservation duration"))
|
verbose_name=_("Reservation duration"),
|
||||||
order = models.PositiveIntegerField(verbose_name=("Display order"))
|
help_text=_("The length of time this product will be reserved before "
|
||||||
|
"it is released for someone else to purchase."),
|
||||||
|
)
|
||||||
|
order = models.PositiveIntegerField(
|
||||||
|
verbose_name=("Display order"),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
|
@ -206,8 +246,18 @@ class DiscountBase(models.Model):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Discount: " + self.description
|
return "Discount: " + self.description
|
||||||
|
|
||||||
description = models.CharField(max_length=255,
|
def effects(self):
|
||||||
verbose_name=_("Description"))
|
''' Returns all of the effects of this discount. '''
|
||||||
|
products = self.discountforproduct_set.all()
|
||||||
|
categories = self.discountforcategory_set.all()
|
||||||
|
return itertools.chain(products, categories)
|
||||||
|
|
||||||
|
description = models.CharField(
|
||||||
|
max_length=255,
|
||||||
|
verbose_name=_("Description"),
|
||||||
|
help_text=_("A description of this discount. This will be included on "
|
||||||
|
"invoices where this discount is applied."),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
|
@ -292,11 +342,23 @@ class TimeOrStockLimitDiscount(DiscountBase):
|
||||||
verbose_name = _("Promotional discount")
|
verbose_name = _("Promotional discount")
|
||||||
|
|
||||||
start_time = models.DateTimeField(
|
start_time = models.DateTimeField(
|
||||||
null=True, blank=True, verbose_name=_("Start time"))
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
verbose_name=_("Start time"),
|
||||||
|
help_text=_("This discount will only be available after this time."),
|
||||||
|
)
|
||||||
end_time = models.DateTimeField(
|
end_time = models.DateTimeField(
|
||||||
null=True, blank=True, verbose_name=_("End time"))
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
verbose_name=_("End time"),
|
||||||
|
help_text=_("This discount will only be available before this time."),
|
||||||
|
)
|
||||||
limit = models.PositiveIntegerField(
|
limit = models.PositiveIntegerField(
|
||||||
null=True, blank=True, verbose_name=_("Limit"))
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
verbose_name=_("Limit"),
|
||||||
|
help_text=_("This discount may only be applied this many times."),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class VoucherDiscount(DiscountBase):
|
class VoucherDiscount(DiscountBase):
|
||||||
|
@ -306,7 +368,8 @@ class VoucherDiscount(DiscountBase):
|
||||||
voucher = models.OneToOneField(
|
voucher = models.OneToOneField(
|
||||||
Voucher,
|
Voucher,
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
verbose_name=_("Voucher"))
|
verbose_name=_("Voucher"),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class IncludedProductDiscount(DiscountBase):
|
class IncludedProductDiscount(DiscountBase):
|
||||||
|
@ -318,7 +381,10 @@ class IncludedProductDiscount(DiscountBase):
|
||||||
|
|
||||||
enabling_products = models.ManyToManyField(
|
enabling_products = models.ManyToManyField(
|
||||||
Product,
|
Product,
|
||||||
verbose_name=_("Including 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):
|
||||||
|
@ -340,20 +406,54 @@ class EnablingConditionBase(models.Model):
|
||||||
objects = InheritanceManager()
|
objects = InheritanceManager()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.description
|
||||||
|
|
||||||
|
def effects(self):
|
||||||
|
''' Returns all of the items enabled by this condition. '''
|
||||||
|
return itertools.chain(self.products.all(), self.categories.all())
|
||||||
|
|
||||||
description = models.CharField(max_length=255)
|
description = models.CharField(max_length=255)
|
||||||
mandatory = models.BooleanField(default=False)
|
mandatory = models.BooleanField(
|
||||||
products = models.ManyToManyField(Product, blank=True)
|
default=False,
|
||||||
categories = models.ManyToManyField(Category, blank=True)
|
help_text=_("If there is at least one mandatory condition defined on "
|
||||||
|
"a product or category, all such conditions must be met. "
|
||||||
|
"Otherwise, at least one non-mandatory condition must be "
|
||||||
|
"met."),
|
||||||
|
)
|
||||||
|
products = models.ManyToManyField(
|
||||||
|
Product,
|
||||||
|
blank=True,
|
||||||
|
help_text=_("Products that are enabled if this condition is met."),
|
||||||
|
)
|
||||||
|
categories = models.ManyToManyField(
|
||||||
|
Category,
|
||||||
|
blank=True,
|
||||||
|
help_text=_("Categories whose products are enabled if this condition "
|
||||||
|
"is met."),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TimeOrStockLimitEnablingCondition(EnablingConditionBase):
|
class TimeOrStockLimitEnablingCondition(EnablingConditionBase):
|
||||||
''' Registration product ceilings '''
|
''' Registration product ceilings '''
|
||||||
|
|
||||||
start_time = models.DateTimeField(null=True, verbose_name=_("Start time"))
|
class Meta:
|
||||||
end_time = models.DateTimeField(null=True, verbose_name=_("End time"))
|
verbose_name = _("ceiling")
|
||||||
limit = models.PositiveIntegerField(null=True, verbose_name=_("Limit"))
|
|
||||||
|
start_time = models.DateTimeField(
|
||||||
|
null=True,
|
||||||
|
help_text=_("Products included in this condition will only be "
|
||||||
|
"available after this time."),
|
||||||
|
)
|
||||||
|
end_time = models.DateTimeField(
|
||||||
|
null=True,
|
||||||
|
help_text=_("Products included in this condition will only be "
|
||||||
|
"available before this time."),
|
||||||
|
)
|
||||||
|
limit = models.PositiveIntegerField(
|
||||||
|
null=True,
|
||||||
|
help_text=_("The number of items under this grouping that can be "
|
||||||
|
"purchased."),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
|
@ -361,9 +461,13 @@ class ProductEnablingCondition(EnablingConditionBase):
|
||||||
''' The condition is met because a specific product is purchased. '''
|
''' The condition is met because a specific product is purchased. '''
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Enabled by product: "
|
return "Enabled by products: " + str(self.enabling_products.all())
|
||||||
|
|
||||||
enabling_products = models.ManyToManyField(Product)
|
enabling_products = models.ManyToManyField(
|
||||||
|
Product,
|
||||||
|
help_text=_("If one of these products are purchased, this condition "
|
||||||
|
"is met."),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
|
@ -372,9 +476,13 @@ class CategoryEnablingCondition(EnablingConditionBase):
|
||||||
purchased. '''
|
purchased. '''
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Enabled by product in category: "
|
return "Enabled by product in category: " + str(self.enabling_category)
|
||||||
|
|
||||||
enabling_category = models.ForeignKey(Category)
|
enabling_category = models.ForeignKey(
|
||||||
|
Category,
|
||||||
|
help_text=_("If a product from this category is purchased, this "
|
||||||
|
"condition is met."),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
[flake8]
|
[flake8]
|
||||||
exclude = registrasion/migrations/*
|
exclude = registrasion/migrations/*, build/*
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue