Merge branch 'user-documentation'

This commit is contained in:
Christopher Neugebauer 2016-04-22 16:08:34 +10:00
commit 32135dbb25
15 changed files with 1387 additions and 22 deletions

View file

@ -1,2 +0,0 @@
# registrasion
A conference registration app, built on top of the Symposion conference management system

30
README.rst Normal file
View file

@ -0,0 +1,30 @@
============
Registrasion
============
Symposion
---------
``symposion`` is an Open Source conference management solution built with Pinax
apps for Django. For more information, see https://github.com/pinax/symposion.
registrasion
------------
``registrasion`` is a registration package that you use alongside Symposion. It
handles inventory management, as well as complex product inclusions, automatic
calculation of discounts, and invoicing. Payment of invoices can be faciliated
by manual filings of payments by staff, or through plugging in a payment app.
Initial development of ``registration`` was funded with the generous support of
the Python Software Foundation.
Quickstart
----------
``registrasion`` is a Django app. You will need to create a Django project to
customize and manage your Registrasion and Symposion installation. A
demonstration app project with templates is available at
https://github.com/chrisjrn/registrasion-demo
Documentation
-------------
The documentation for ``registrasion`` is available at
http://registrasion.readthedocs.org/

231
docs/Makefile Normal file
View file

@ -0,0 +1,231 @@
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
# User-friendly check for sphinx-build
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don\'t have Sphinx installed, grab it from http://sphinx-doc.org/)
endif
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " applehelp to make an Apple Help Book"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " epub3 to make an epub3"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " xml to make Docutils-native XML files"
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
@echo " coverage to run coverage check of the documentation (if enabled)"
@echo " dummy to check syntax errors of document sources"
.PHONY: clean
clean:
rm -rf $(BUILDDIR)/*
.PHONY: html
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
.PHONY: dirhtml
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
.PHONY: singlehtml
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
.PHONY: pickle
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
.PHONY: json
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
.PHONY: htmlhelp
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
.PHONY: qthelp
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Registrasion.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Registrasion.qhc"
.PHONY: applehelp
applehelp:
$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
@echo
@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
@echo "N.B. You won't be able to view it unless you put it in" \
"~/Library/Documentation/Help or install it in your application" \
"bundle."
.PHONY: devhelp
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/Registrasion"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Registrasion"
@echo "# devhelp"
.PHONY: epub
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
.PHONY: epub3
epub3:
$(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3
@echo
@echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3."
.PHONY: latex
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
.PHONY: latexpdf
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
.PHONY: latexpdfja
latexpdfja:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through platex and dvipdfmx..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
.PHONY: text
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
.PHONY: man
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
.PHONY: texinfo
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
.PHONY: info
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
.PHONY: gettext
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
.PHONY: changes
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
.PHONY: linkcheck
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
.PHONY: doctest
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
.PHONY: coverage
coverage:
$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
@echo "Testing of coverage in the sources finished, look at the " \
"results in $(BUILDDIR)/coverage/python.txt."
.PHONY: xml
xml:
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
@echo
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
.PHONY: pseudoxml
pseudoxml:
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
@echo
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
.PHONY: dummy
dummy:
$(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy
@echo
@echo "Build finished. Dummy builder generates no files."

297
docs/conf.py Normal file
View file

@ -0,0 +1,297 @@
# -*- coding: utf-8 -*-
#
# Registrasion documentation build configuration file, created by
# sphinx-quickstart on Thu Apr 21 11:29:51 2016.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys
import os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.napoleon",
]
# Autodoc requires django to be ready to go, otherwise we can't import rego's
# things...
sys.path.insert(0, ".")
os.environ["DJANGO_SETTINGS_MODULE"] = "django_settings"
import django
django.setup()
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'Registrasion'
copyright = u'2016, Christopher Neugebauer'
author = u'Christopher Neugebauer'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = u'0.1a1'
# The full version, including alpha/beta/rc tags.
release = u'0.1a1'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# The reST default role (used for this markup: `text`) to use for all
# documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# If true, keep warnings as "system message" paragraphs in the built documents.
#keep_warnings = False
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
# on_rtd is whether we are on readthedocs.org, this line of code grabbed from docs.readthedocs.org
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
if not on_rtd: # only import and set the theme if we're building docs locally
import sphinx_rtd_theme
html_theme = 'sphinx_rtd_theme'
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
# The name for this set of Sphinx documents.
# "<project> v<release> documentation" by default.
#html_title = u'Registrasion v0.1a1'
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (relative to this directory) to use as a favicon of
# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
#html_extra_path = []
# If not None, a 'Last updated on:' timestamp is inserted at every page
# bottom, using the given strftime format.
# The empty string is equivalent to '%b %d, %Y'.
#html_last_updated_fmt = None
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# Language to be used for generating the HTML full-text search index.
# Sphinx supports the following languages:
# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr', 'zh'
#html_search_language = 'en'
# A dictionary with options for the search language support, empty by default.
# 'ja' uses this config value.
# 'zh' user can custom change `jieba` dictionary path.
#html_search_options = {'type': 'default'}
# The name of a javascript file (relative to the configuration directory) that
# implements a search results scorer. If empty, the default will be used.
#html_search_scorer = 'scorer.js'
# Output file base name for HTML help builder.
htmlhelp_basename = 'Registrasiondoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#'preamble': '',
# Latex figure (float) alignment
#'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'Registrasion.tex', u'Registrasion Documentation',
u'Christopher Neugebauer', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# If true, show page references after internal links.
#latex_show_pagerefs = False
# If true, show URL addresses after external links.
#latex_show_urls = False
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'registrasion', u'Registrasion Documentation',
[author], 1)
]
# If true, show URL addresses after external links.
#man_show_urls = False
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'Registrasion', u'Registrasion Documentation',
author, 'Registrasion', 'One line description of project.',
'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
#texinfo_appendices = []
# If false, no module index is generated.
#texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'
# If true, do not generate a @detailmenu in the "Top" node's menu.
#texinfo_no_detailmenu = False

122
docs/django_settings.py Normal file
View file

@ -0,0 +1,122 @@
"""
Django settings for djangoenv project.
Generated by 'django-admin startproject' using Django 1.9.5.
For more information on this file, see
https://docs.djangoproject.com/en/1.9/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.9/ref/settings/
"""
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'z$cu8&jcnm#qa=xbrkss-4w8do+(pp16j*usmp9j&bg=)&1@-a'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'registrasion',
]
MIDDLEWARE_CLASSES = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'djangoenv.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'djangoenv.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.9/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Password validation
# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/1.9/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.9/howto/static-files/
STATIC_URL = '/static/'

View file

@ -0,0 +1,26 @@
================================
Registrasion for Zookeepr Keeprs
================================
Things that are the same
------------------------
* You have an inventory of products
* Complete registrations are made up of multiple products
* Products are split into categories
* Products can be listed under ceilings
* Products can be included for free by purchasing other items
* e.g. a Professional Ticket includes a dinner ticket
* Products can be enabled by user roles
* e.g. Speakers Dinner tickets are visible to speakers
* Vouchers can be used to discount products
Things that are different
-------------------------
* Ceilings can be used to apply discounts, so Early Bird ticket rates can be
implemented by applying a ceiling-type discount, rather than duplicating the
ticket type.
* Vouchers can be used to enable products
* e.g. Sponsor tickets do not appear until you supply a sponsor's voucher
* Items may be enabled by having other specific items present
* e.g. Extra accommodation nights do not appear until you purchase the main
week worth of accommodation.

29
docs/index.rst Normal file
View file

@ -0,0 +1,29 @@
.. Registrasion documentation master file, created by
sphinx-quickstart on Thu Apr 21 11:29:51 2016.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Registrasion
============
Registrasion is a conference registration package that goes well with the Symposion suite of conference management apps for Django. It's designed to manage the sorts of inventories that large conferences need to manage, build up complex tickets with multiple items, and handle payments using whatever payment gateway you happen to have access to
Development of registrasion was commenced by Christopher Neugebauer in 2016, with the gracious support of the Python Software Foundation.
Contents:
---------
.. toctree::
:maxdepth: 2
overview
inventory
for-zookeepr-users
Indices and tables
==================
* :ref:`genindex`
.. * :ref:`modindex`
* :ref:`search`

153
docs/inventory.rst Normal file
View file

@ -0,0 +1,153 @@
Inventory Management
====================
Registrasion uses an inventory model to keep track of tickets, and the other various products that attendees of your conference might want to have, such as t-shirts and dinner tickets.
The inventory model is split up into Categories and Products. Categories are used to group Products.
Registrasion uses conditionals to build up complex tickets, or enable/disable specific items to specific users:
Often, you will want to offer free items, such as t-shirts or dinner tickets to your attendees. Registrasion has a Discounts facility that lets you automatically offer free items to your attendees as part of their tickets. You can also automatically offer promotional discounts, such as Early Bird discounts.
Sometimes, you may want to restrict parts of the conference to specific attendees, for example, you might have a Speakers Dinner to only speakers. Or you might want to restrict certain Products to attendees who have purchased other items, for example, you might want to sell Comfy Chairs to people who've bought VIP tickets. You can control showing and hiding specific products using Flags.
.. automodule:: registrasion.models.inventory
Categories
----------
Categories are logical groups of Products. Generally, you should keep like products in the same category, and use as many categories as you need.
You will need at least one Category to be able to sell tickets to your attendees.
Each category has the following attributes:
.. autoclass :: Category
Products
--------
Products represent the different items that comprise a user's conference ticket.
Each product has the following attributes:
.. autoclass :: Product
Vouchers
--------
Vouchers are used to enable Discounts or Flags for people who enter a voucher
code.
.. autoclass :: Voucher
If an attendee enters a voucher code, they have at least an hour to finalise
their registration before the voucher becomes unreserved. Only as many people
as allowed by ``limit`` are allowed to have a voucher reserved.
.. automodule:: registrasion.models.conditions
Discounts
---------
Discounts serve multiple purposes: they can be used to build up complex tickets by automatically waiving the costs for sub-products; they can be used to offer freebie tickets to specific people, or people who hold voucher codes; or they can be used to enable short-term promotional discounts.
Registrasion has several types of discounts, which enable themselves under specific conditions. We'll explain how these work later on, but first:
Common features
~~~~~~~~~~~~~~~
Each discount type has the following common attributes:
.. autoclass :: DiscountBase
You can apply a discount to individual products, or to whole categories, or both. All of the products and categories affected by the discount are displayed on the discount's admin page.
If you choose to specify individual products, you have these options:
.. autoclass :: DiscountForProduct
If you choose to specify whole categories, you have these options:
.. autoclass :: DiscountForCategory
Note that you cannot have a discount apply to both a category, and a product within that category.
Product Inclusions
~~~~~~~~~~~~~~~~~~
Product inclusion discounts allow you to enable a discount when an attendee has selected a specific enabling Product.
For example, if you want to give everyone with a ticket a free t-shirt, you can use a product inclusion to offer a 100% discount on the t-shirt category, if the attendee has selected one of your ticket Products.
Once a discount has been enabled in one Invoice, it is available until the quantities are exhausted for that attendee.
.. autoclass :: IncludedProductDiscount
Time/stock limit discounts
~~~~~~~~~~~~~~~~~~~~~~~~~~
These discounts allow you to offer a limited promotion that is automatically offered to all attendees. You can specify a time range for when the discount should be enabled, you can also specify a stock limit.
.. autoclass :: TimeOrStockLimitDiscount
Voucher discounts
~~~~~~~~~~~~~~~~~
Vouchers can be used to enable discounts.
.. autoclass :: VoucherDiscount
How discounts get applied
~~~~~~~~~~~~~~~~~~~~~~~~~
It's possible for multiple discounts to be available on any given Product. This means there need to be rules for how discounts get applied. It works like so:
#. Take all of the Products that the user currently has selected, and sort them so that the most expensive comes first.
#. Apply the highest-value discount line for the first Product, until either all such products have a discount applied, or the discount's Quantity has been exhausted for that user for that Product.
#. Repeat until all products have been processed.
In summary, the system greedily applies the highest-value discounts for each product. This may not provide a global optimum, but it'll do.
As an example: say a user has a voucher available for a 100% discount of tickets, and there's a promotional discount for 15% off tickets. In this case, the 100% discount will apply, and the 15% discount will not be disturbed.
Flags
-----
Flags are conditions that can be used to enable or disable Products or Categories, depending on whether conditions are met. They can be used to restrict specific products to specific people, or to place time limits on availability for products.
Common Features
~~~~~~~~~~~~~~~
.. autoclass :: FlagBase
Dependencies on products from category
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Category Dependency flags have their condition met if a product from the enabling category has been selected by the attendee. For example, if there is an *Accommodation* Category, this flag could be used to enable an *Accommodation Breakfast* category, allowing only attendees with accommodation to purchase breakfast.
.. autoclass :: CategoryFlag
Dependencies on products
~~~~~~~~~~~~~~~~~~~~~~~~
Product dependency flags have their condition met if one of the enabling products have been selected by the attendee.
.. autoclass :: ProductFlag
Time/stock limit flags
~~~~~~~~~~~~~~~~~~~~~~
These flags allow the products that they cover to be made available for a limited time, or to set a global ceiling on the products covered.
These can be used to remove items from sale once a sales deadline has been met, or if a venue for a specific event has reached capacity. If there are items that fall under multiple such groupings, it makes sense to set all of these flags to be ``DISABLE_IF_FALSE``.
.. autoclass :: TimeOrStockLimitFlag
If any of the attributes are omitted, then only the remaining attributes affect the availablility of the products covered. If there's no attributes set at all, then the grouping has no effect, but it can be used to group products for reporting purposes.
Voucher flags
~~~~~~~~~~~~~
Vouchers can be used to enable flags.
.. autoclass :: VoucherFlag

281
docs/make.bat Normal file
View file

@ -0,0 +1,281 @@
@ECHO OFF
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set BUILDDIR=_build
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
set I18NSPHINXOPTS=%SPHINXOPTS% .
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
)
if "%1" == "" goto help
if "%1" == "help" (
:help
echo.Please use `make ^<target^>` where ^<target^> is one of
echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories
echo. singlehtml to make a single large HTML file
echo. pickle to make pickle files
echo. json to make JSON files
echo. htmlhelp to make HTML files and a HTML help project
echo. qthelp to make HTML files and a qthelp project
echo. devhelp to make HTML files and a Devhelp project
echo. epub to make an epub
echo. epub3 to make an epub3
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. text to make text files
echo. man to make manual pages
echo. texinfo to make Texinfo files
echo. gettext to make PO message catalogs
echo. changes to make an overview over all changed/added/deprecated items
echo. xml to make Docutils-native XML files
echo. pseudoxml to make pseudoxml-XML files for display purposes
echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled
echo. coverage to run coverage check of the documentation if enabled
echo. dummy to check syntax errors of document sources
goto end
)
if "%1" == "clean" (
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
del /q /s %BUILDDIR%\*
goto end
)
REM Check if sphinx-build is available and fallback to Python version if any
%SPHINXBUILD% 1>NUL 2>NUL
if errorlevel 9009 goto sphinx_python
goto sphinx_ok
:sphinx_python
set SPHINXBUILD=python -m sphinx.__init__
%SPHINXBUILD% 2> nul
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
:sphinx_ok
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
goto end
)
if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
goto end
)
if "%1" == "singlehtml" (
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
goto end
)
if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the pickle files.
goto end
)
if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the JSON files.
goto end
)
if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in %BUILDDIR%/htmlhelp.
goto end
)
if "%1" == "qthelp" (
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in %BUILDDIR%/qthelp, like this:
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Registrasion.qhcp
echo.To view the help file:
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Registrasion.ghc
goto end
)
if "%1" == "devhelp" (
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished.
goto end
)
if "%1" == "epub" (
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The epub file is in %BUILDDIR%/epub.
goto end
)
if "%1" == "epub3" (
%SPHINXBUILD% -b epub3 %ALLSPHINXOPTS% %BUILDDIR%/epub3
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The epub3 file is in %BUILDDIR%/epub3.
goto end
)
if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
if errorlevel 1 exit /b 1
echo.
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "latexpdf" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex
make all-pdf
cd %~dp0
echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "latexpdfja" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex
make all-pdf-ja
cd %~dp0
echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "text" (
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The text files are in %BUILDDIR%/text.
goto end
)
if "%1" == "man" (
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The manual pages are in %BUILDDIR%/man.
goto end
)
if "%1" == "texinfo" (
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
goto end
)
if "%1" == "gettext" (
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
goto end
)
if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
if errorlevel 1 exit /b 1
echo.
echo.The overview file is in %BUILDDIR%/changes.
goto end
)
if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
if errorlevel 1 exit /b 1
echo.
echo.Link check complete; look for any errors in the above output ^
or in %BUILDDIR%/linkcheck/output.txt.
goto end
)
if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
if errorlevel 1 exit /b 1
echo.
echo.Testing of doctests in the sources finished, look at the ^
results in %BUILDDIR%/doctest/output.txt.
goto end
)
if "%1" == "coverage" (
%SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage
if errorlevel 1 exit /b 1
echo.
echo.Testing of coverage in the sources finished, look at the ^
results in %BUILDDIR%/coverage/python.txt.
goto end
)
if "%1" == "xml" (
%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The XML files are in %BUILDDIR%/xml.
goto end
)
if "%1" == "pseudoxml" (
%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
goto end
)
if "%1" == "dummy" (
%SPHINXBUILD% -b dummy %ALLSPHINXOPTS% %BUILDDIR%/dummy
if errorlevel 1 exit /b 1
echo.
echo.Build finished. Dummy builder generates no files.
goto end
)
:end

51
docs/overview.rst Normal file
View file

@ -0,0 +1,51 @@
Overview
========
Registrasion's approach to handling conference registrations is to use a cart and inventory model, where the various things sold by the conference to attendees are handled as Products, which can be added to a Cart. Carts can be used to generate Invoices, and Invoices can then be paid.
Guided registration
-------------------
Unlike a generic e-commerce platform, Registrasion is designed for building up conference tickets.
When they first attempt registration, attendees start off in a process called *guided mode*. Guided mode is multi-step form that takes users through a complete registration process:
#. The attendee fills out their profile
#. The attendee selects a ticket type
#. The attendee selects additional products such as t-shirts and dinner tickets, which may be sold at a cost, or have waivers applied.
#. The attendee is offered the opportunity to check out their cart, generating an invoice; or to enter amendments mode.
For specifics on how guided mode works, see *code guide to be written*.
Amendments mode
---------------
Once attendees have reached the end of guided registration, they are permanently added to *amendments mode*. Amendments mode allows attendees to change their product selections in a given category, with one rule: once an invoice has been paid, product selections cannot be changed without voiding that invoice (and optionally releasing a Credit Note).
Users can check out their current selections at any time, and generate an Invoice for their selections. That invoice can then be paid, and the attendee will then be making selections on a new cart.
Invoices
--------
When an attendee checks out their Cart, an Invoice is generated for their cart.
An invoice is valid for as long as the items in the cart do not change, and remain generally available. If a user amends their cart after generating an invoice, the user will need to check out their cart again, and generate a new invoice.
Once an invoice is paid, it is no longer possible for an invoice to be void, instead, it needs to have a refund generated.
User-Attendee Model
-------------------
Registrasion uses a User-Attendee model. This means that Registrasion expects each user account on the system to represent a single attendee at the conference. It also expects that the attendee themselves fill out the registration form.
This means that each attendee has a confirmed e-mail address for conference-related communications. It's usually a good idea for the conference to make sure that their account sign-up page points this out, so that administrative assistants at companies don't end up being the ones getting communicated at.
How do people get their employers to pay for their tickets?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Registrasion provides a semi-private URL that allows anyone in possession of this URL to view that attendee's most recent invoice, and make payments against that invoice.
A future release will add the ability to bulk-pay multiple invoices at once.

View file

@ -13,9 +13,14 @@ from model_utils.managers import InheritanceManager
@python_2_unicode_compatible
class DiscountBase(models.Model):
''' Base class for discounts. Each subclass has controller code that
determines whether or not the given discount is available to be added to
the current cart. '''
''' Base class for discounts. This class is subclassed with special
attributes which are used to determine whether or not the given discount
is available to be added to the current cart.
Attributes:
description (str): Display text that appears on the attendee's Invoice
when the discount is applied to a Product on that invoice.
'''
class Meta:
app_label = "registrasion"
@ -43,7 +48,23 @@ class DiscountBase(models.Model):
class DiscountForProduct(models.Model):
''' Represents a discount on an individual product. Each Discount can
contain multiple products and categories. Discounts can either be a
percentage or a fixed amount, but not both. '''
percentage or a fixed amount, but not both.
Attributes:
product (inventory.Product): The product that this discount line will
apply to.
percentage (Decimal): The percentage discount that will be *taken off*
this product if this discount applies.
price (Decimal): The currency value that will be *taken off* this
product if this discount applies.
quantity (int): The number of times that each user may apply this
discount line. This applies across every valid Invoice that
the user has.
'''
class Meta:
app_label = "registrasion"
@ -88,7 +109,21 @@ class DiscountForProduct(models.Model):
@python_2_unicode_compatible
class DiscountForCategory(models.Model):
''' Represents a discount for a category of products. Each discount can
contain multiple products. Category discounts can only be a percentage. '''
contain multiple products. Category discounts can only be a percentage.
Attributes:
category (inventory.Category): The category whose products that this
discount line will apply to.
percentage (Decimal): The percentage discount that will be *taken off*
a product if this discount applies.
quantity (int): The number of times that each user may apply this
discount line. This applies across every valid Invoice that the
user has.
'''
class Meta:
app_label = "registrasion"
@ -121,7 +156,19 @@ class DiscountForCategory(models.Model):
class TimeOrStockLimitDiscount(DiscountBase):
''' 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.
Attributes:
start_time (Optional[datetime]): When the discount should start being
offered.
end_time (Optional[datetime]): When the discount should stop being
offered.
limit (Optional[int]): How many times the discount is allowed to be
applied -- to all users.
'''
class Meta:
app_label = "registrasion"
@ -150,7 +197,13 @@ class TimeOrStockLimitDiscount(DiscountBase):
class VoucherDiscount(DiscountBase):
''' Discounts that are enabled when a voucher code is in the current
cart. '''
cart. These are normally configured in the Admin page at the same time as
creating a Voucher object.
Attributes:
voucher (inventory.Voucher): The voucher that enables this discount.
'''
class Meta:
app_label = "registrasion"
@ -167,7 +220,13 @@ class VoucherDiscount(DiscountBase):
class IncludedProductDiscount(DiscountBase):
''' 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.
Attributes:
enabling_products ([inventory.Product, ...]): The products that enable
the discount.
'''
class Meta:
app_label = "registrasion"
@ -194,14 +253,30 @@ class FlagBase(models.Model):
''' This defines a condition which allows products or categories to
be made visible, or be prevented from being visible.
The various subclasses of this can define the conditions that enable
or disable products, by the following rules:
Attributes:
description (str): A human-readable description that is used to
identify the flag to staff in the admin interface. It's not seen
anywhere else in Registrasion.
If there is at least one 'disable if false' flag defined on a product or
category, all such flag conditions must be met. If there is at least one
'enable if true' flag, at least one such condition must be met.
condition (int): This determines the effect of this flag's condition
being met. There are two types of condition:
If both types of conditions exist on a product, both of these rules apply.
``ENABLE_IF_TRUE`` conditions switch on the products and
categories included under this flag if *any* such condition is met.
``DISABLE_IF_FALSE`` conditions *switch off* the products and
categories included under this flag is any such condition
*is not* met.
If you have both types of conditions attached to a Product, every
``DISABLE_IF_FALSE`` condition must be met, along with one
``ENABLE_IF_TRUE`` condition.
products ([inventory.Product, ...]):
The Products affected by this flag.
categories ([inventory.Category, ...]):
The Categories whose Products are affected by this flag.
'''
class Meta:
@ -271,7 +346,21 @@ class EnablingConditionBase(FlagBase):
class TimeOrStockLimitFlag(EnablingConditionBase):
''' Registration product ceilings '''
''' 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
sold.
Attributes:
start_time (Optional[datetime]): This condition is only met after this
time.
end_time (Optional[datetime]): This condition is only met before this
time.
limit (Optional[int]): The number of products that *all users* can
purchase under this limit, regardless of their per-user limits.
'''
class Meta:
app_label = "registrasion"
@ -300,7 +389,12 @@ class TimeOrStockLimitFlag(EnablingConditionBase):
@python_2_unicode_compatible
class ProductFlag(EnablingConditionBase):
''' The condition is met because a specific product is purchased. '''
''' The condition is met because a specific product is purchased.
Attributes:
enabling_products ([inventory.Product, ...]): The products that cause this
condition to be met.
'''
class Meta:
app_label = "registrasion"
@ -320,7 +414,12 @@ class ProductFlag(EnablingConditionBase):
@python_2_unicode_compatible
class CategoryFlag(EnablingConditionBase):
''' The condition is met because a product in a particular product is
purchased. '''
purchased.
Attributes:
enabling_category (inventory.Category): The category that causes this
condition to be met.
'''
class Meta:
app_label = "registrasion"

View file

@ -96,7 +96,35 @@ class Category(models.Model):
@python_2_unicode_compatible
class Product(models.Model):
''' Registration products '''
''' 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"
@ -144,7 +172,20 @@ class Product(models.Model):
@python_2_unicode_compatible
class Voucher(models.Model):
''' Registration vouchers '''
''' 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"

View file

@ -1,2 +1 @@
django-nested-admin==2.2.6
#-e git+https://github.com/pinax/symposion.git#egg=SymposionMaster # Needs Symposion

4
requirements/docs.txt Normal file
View file

@ -0,0 +1,4 @@
# requirements needed to build the docs
Sphinx==1.4.1
sphinx-rtd-theme==0.1.9

4
requirements/extern.txt Normal file
View file

@ -0,0 +1,4 @@
# Requirements that currently live in git land, so are necessary to make the
# project build, but can't live in setup.py
-e git+https://github.com/pinax/symposion.git#egg=SymposionMaster # Symposion lives on git at the moment