mirror of
https://github.com/pretix/pretix.git
synced 2025-12-20 16:32:26 +00:00
144 lines
7.5 KiB
ReStructuredText
144 lines
7.5 KiB
ReStructuredText
Implementation Concepts
|
|
=======================
|
|
|
|
Basic terminology
|
|
-----------------
|
|
|
|
The components
|
|
^^^^^^^^^^^^^^
|
|
|
|
The project tixl is split into several components. The main three of them are:
|
|
|
|
**tixlbase**
|
|
Tixlbase is the foundation below all other components. It is primarily
|
|
responsible for the data structures and database communication. It also hosts
|
|
several utilities which are used by multiple other components.
|
|
|
|
**tixlcontrol**
|
|
Tixlcontrol is the web-based backend software which allows organizers to
|
|
create and manage their events, items, orders and tickets.
|
|
|
|
**tixlpresale**
|
|
Tixlpresale is the ticket-shop itself, containing all the parts visible to the
|
|
end user.
|
|
|
|
Users and events
|
|
^^^^^^^^^^^^^^^^
|
|
|
|
Tixl is all about **events**, which are defined as something happening somewhere.
|
|
Every Event is managed by the **organizer**, an abstract entity running the event.
|
|
|
|
Tixl is used by **users**. We want to enable global users who can just login into
|
|
tixl and buy tickets for as many events as they like but at the same time it
|
|
should be possible to create some kind of local user to have a temporary account
|
|
just to buy tickets for one single event.
|
|
|
|
The problem is, we cannot use usernames as primary keys for our users, as we
|
|
do not want one username to be blocked forever just because of one temporary
|
|
account using it (people would have to think of a new username for every temporary
|
|
account they create). On the other hand, we can not use e-mail addresses either,
|
|
as those are not unique (imagine one person having multiple temporary accounts)
|
|
and they should not be required for temporary account (to enable anonymity).
|
|
|
|
Therefore, we split our users into two groups and use an internal **identifier**
|
|
as our primary key:
|
|
|
|
**Local users**
|
|
Local users do only exist inside the scope of one event. They are identified by
|
|
usernames, which are only valid for exactly one event. Internally, their identifier
|
|
is "{username}@{event.id}.event.tixl"
|
|
|
|
**Global users**
|
|
Global users exist everywhere in the installation of Tixl. They can buy tickets
|
|
for multiple events and they can be managers of one or more Organizers/Events.
|
|
Global users are identified by e-mail addresses.
|
|
|
|
|
|
Items and variations
|
|
^^^^^^^^^^^^^^^^^^^^
|
|
|
|
The purpose of tixl is to sell **items** (which belong to **events**) to **users**.
|
|
An **item** is a abstract thing, popular examples being event tickets or a piece of
|
|
merchandise, like 'T-Shirt'. An **item** can have multiple **properties** with multiple
|
|
**values** each. For example, the **item** 'T-Shirt' could have the **property** 'Size'
|
|
with **values** 'S', 'M' and 'L' and the **property** 'Color' with **values** 'black'
|
|
and 'blue'.
|
|
|
|
Any combination of those **values** is called a **variation**. Using the examples from
|
|
above, a possible **variation** would be 'T-Shirt, S, blue'.
|
|
|
|
Questions
|
|
^^^^^^^^^
|
|
|
|
An item can be extended using **questions**. Questions enable items to be extended by
|
|
additional information which can be entered by the user. Examples of possible questions
|
|
include 'Name' or 'age'.
|
|
|
|
Restrictions
|
|
^^^^^^^^^^^^
|
|
|
|
The probably most powerful concepts of tixl is the very abstract concept of **restricitons**.
|
|
We already know that **items** can come in very different **variations**, but a
|
|
**restriction** decides whether an variation is available for sale and assign **prices**
|
|
to **variations**. There are **restriction types** (pieces of code implementing the
|
|
restriction logic) and **restriction instances** (the specific configurations made by the
|
|
organzier). Although **restrictions** are a very abstract concept which can be used
|
|
to do nearly anything, there are a few obvious examples:
|
|
|
|
* One easy example is a restriction by time, which allows the sale of certain item variations
|
|
only within a certain time frame. As restrictions can also assign a price to a variation,
|
|
this can also be used to implement something like 'early-bird prices' for your tickets by
|
|
using multiple time restrictions with different prices.
|
|
* The most obvious example is the restriction by number, which limits the sale of the tickets to
|
|
a maximum number. You can use this either to stop selling tickets completely when your house
|
|
is full or for creating limited 'VIP tickets'. We'll come to this again later.
|
|
* A more advanced example is a restriction by user, for example reduced ticket prices for
|
|
members who are members of a special group.
|
|
* Arbitrary sophisticated features like coupon codes are also possible to be implemented using
|
|
this feature.
|
|
|
|
Any number of **restrictions** can be applied to the whole of a **item** or even to a specific
|
|
**variation**. The processing of the restriction follows the following set of rules:
|
|
|
|
* Variation-specific rules have precedence over item-specific rules.
|
|
* The restrictions are being processed in random order (there may not be any assumptions about
|
|
the evaluation order).
|
|
* Multiple restriction instances of **different restriction types** are linked with *and*, so
|
|
if both a time frame and a restriction by number are applied to an item, the item is only avaliable
|
|
for sale during the given time frame *and* only as long as items are available.
|
|
* Multiple restriction instances of the **same restriction type** are typically linked with *or*,
|
|
although this is the decision of the restriction logic itself and not mandatory. So for example
|
|
the restriction by time would implement this default logic, because if two time frames are applied
|
|
to an item, the item should be available for sale in both of the time frames (it just does not make
|
|
sense otherwise on an one-dimensional time axis).
|
|
* If multiple restrictions apply which set the price, the *cheapest* price determines the final price.
|
|
|
|
Restrictions can be implemented using a plugin system and do not require changes to the tixl codebase.
|
|
|
|
Restriction by number
|
|
"""""""""""""""""""""
|
|
|
|
The restriction by number is a special case, as it is the only (planned) restriction type demanding
|
|
special care in the implementation to never sell more tickets than allowed, even under heavy load.
|
|
|
|
* There is a concept of **quotas**. A quota is basically a number of items combined with information
|
|
about how many of them are still available.
|
|
* Every time a user places a item in the cart, a **lock** object is created, reducing the number of
|
|
available items in the pool by one. The lock is valid for a fixed time (e.g. 30 minutes), but not
|
|
instantly deleted afther those 30 minutes (we'll get to that).
|
|
* Every time a user places a binding order, the lock object is replaced by an **order** which behaves
|
|
much the same as the lock. It reduces the number of available item and is valid for a fixed time, this
|
|
time for the configured payment term (e.g. 14 days).
|
|
* If the order is being paid, the **order** becomes permanent.
|
|
* Once there are no available tickets left and a user wants to buy a ticket, a lock which is in place
|
|
for more than the allowed time frame is being removed in favor of the new buyer. If there are no
|
|
abandoned locks available, an unpaid order being older than the configured payment term is being
|
|
removed. If there are none of them as well, this quota is sold out.
|
|
* The same quota can apply to multiple items and one item can be affected by multiple quotas, to
|
|
enable both of the following features at the same time:
|
|
|
|
* You'll want to make sure you never have more then X people at your event, so you'll create a quota
|
|
applying to all ticket items.
|
|
* You want to reduce the first Y tickets in price, so you'll create a restriction which is bound by
|
|
a quota of Y and reduces the price.
|