symposion_app/registrasion/models/inventory.py
2016-04-22 15:06:24 +10:00

172 lines
5.5 KiB
Python

import datetime
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _
# Inventory Models
@python_2_unicode_compatible
class Category(models.Model):
''' Registration product categories, used as logical groupings for Products
in registration forms.
Attributes:
name (str): The display name for the category.
description (str): Some explanatory text for the category. This is
displayed alongside the forms where your attendees choose their
items.
required (bool): Requires a user to select an item from this category
during initial registration. You can use this, e.g., for making
sure that the user has a ticket before they select whether they
want a t-shirt.
render_type (int): This is used to determine what sort of form the
attendee will be presented with when choosing Products from this
category. These may be either of the following:
``RENDER_TYPE_RADIO`` presents the Products in the Category as a
list of radio buttons. At most one item can be chosen at a time.
This works well when setting limit_per_user to 1.
``RENDER_TYPE_QUANTITY`` shows each Product next to an input field,
where the user can specify a quantity of each Product type. This is
useful for additional extras, like Dinner Tickets.
limit_per_user (Optional[int]): This restricts the number of items
from this Category that each attendee may claim. This extends
across multiple Invoices.
display_order (int): An ascending order for displaying the Categories
available. By convention, your Category for ticket types should
have the lowest display order.
'''
class Meta:
app_label = "registrasion"
verbose_name = _("inventory - category")
verbose_name_plural = _("inventory - categories")
ordering = ("order", )
def __str__(self):
return self.name
RENDER_TYPE_RADIO = 1
RENDER_TYPE_QUANTITY = 2
CATEGORY_RENDER_TYPES = [
(RENDER_TYPE_RADIO, _("Radio button")),
(RENDER_TYPE_QUANTITY, _("Quantity boxes")),
]
name = models.CharField(
max_length=65,
verbose_name=_("Name"),
)
description = models.CharField(
max_length=255,
verbose_name=_("Description"),
)
limit_per_user = models.PositiveIntegerField(
null=True,
blank=True,
verbose_name=_("Limit per user"),
help_text=_("The total number of items from this category one "
"attendee may purchase."),
)
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"),
db_index=True,
)
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
class Product(models.Model):
''' Registration products '''
class Meta:
app_label = "registrasion"
verbose_name = _("inventory - product")
ordering = ("category__order", "order")
def __str__(self):
return "%s - %s" % (self.category.name, self.name)
name = models.CharField(
max_length=65,
verbose_name=_("Name"),
)
description = models.CharField(
max_length=255,
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(
null=True,
blank=True,
verbose_name=_("Limit per user"),
)
reservation_duration = models.DurationField(
default=datetime.timedelta(hours=1),
verbose_name=_("Reservation duration"),
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"),
db_index=True,
)
@python_2_unicode_compatible
class Voucher(models.Model):
''' Registration vouchers '''
class Meta:
app_label = "registrasion"
# Vouchers reserve a cart for a fixed amount of time, so that
# items may be added without the voucher being swiped by someone else
RESERVATION_DURATION = datetime.timedelta(hours=1)
def __str__(self):
return "Voucher for %s" % self.recipient
@classmethod
def normalise_code(cls, code):
return code.upper()
def save(self, *a, **k):
''' Normalise the voucher code to be uppercase '''
self.code = self.normalise_code(self.code)
super(Voucher, self).save(*a, **k)
recipient = models.CharField(max_length=64, verbose_name=_("Recipient"))
code = models.CharField(max_length=16,
unique=True,
verbose_name=_("Voucher code"))
limit = models.PositiveIntegerField(verbose_name=_("Voucher use limit"))