Files
@ e9ebf5da03ea
Branch filter:
Location: symposion_app/registrasion/models/inventory.py
e9ebf5da03ea
7.0 KiB
text/x-python
Writes inventory and overview documentation, and updates docstrings on a LOT of modules.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | 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):
''' Products make up the conference inventory.
Attributes:
name (str): The display name for the product.
description (str): Some descriptive text that will help the user to
understand the product when they're at the registration form.
category (Category): The Category that this product will be grouped
under.
price (Decimal): The price that 1 unit of this product will sell for.
Note that this should be the full price, before any discounts are
applied.
limit_per_user (Optional[int]): This restricts the number of this
Product that each attendee may claim. This extends across multiple
Invoices.
reservation_duration (datetime): When a Product is added to the user's
tentative registration, it is marked as unavailable for a period of
time. This allows the user to build up their registration and then
pay for it. This reservation duration determines how long an item
should be allowed to be reserved whilst being unpaid.
display_order (int): An ascending order for displaying the Products
within each Category.
'''
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):
''' Vouchers are used to enable Discounts or Flags for the people who hold
the voucher code.
Attributes:
recipient (str): A display string used to identify the holder of the
voucher on the admin page.
code (str): The string that is used to prove that the attendee holds
this voucher.
limit (int): The number of attendees who are permitted to hold this
voucher.
'''
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"))
|