diff --git a/README.md b/README.md deleted file mode 100644 index e1ab38c424dad94a61b766bfacf345d2bd30dfff..0000000000000000000000000000000000000000 --- a/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# registrasion -A conference registration app, built on top of the Symposion conference management system diff --git a/README.rst b/README.rst new file mode 100644 index 0000000000000000000000000000000000000000..be049b721bb6662b2e6bfc170b846973ece63113 --- /dev/null +++ b/README.rst @@ -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/ diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..88006e7aebcdc2f2343baebe0996078fba21c741 --- /dev/null +++ b/docs/Makefile @@ -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 ' where 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." diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000000000000000000000000000000000000..99d8902ed7b74868d8a28005c1d2ad682b6cde47 --- /dev/null +++ b/docs/conf.py @@ -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. +# " v 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 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 diff --git a/docs/django_settings.py b/docs/django_settings.py new file mode 100644 index 0000000000000000000000000000000000000000..56a07ecafa152edc540916c83f06695f485b19d8 --- /dev/null +++ b/docs/django_settings.py @@ -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/' diff --git a/docs/for-zookeepr-users.rst b/docs/for-zookeepr-users.rst new file mode 100644 index 0000000000000000000000000000000000000000..f4d39f87d97dcc5f28969f71f78e343084cf0b06 --- /dev/null +++ b/docs/for-zookeepr-users.rst @@ -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. diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..266fa4639270b91296eee613679a227659b18269 --- /dev/null +++ b/docs/index.rst @@ -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` diff --git a/docs/inventory.rst b/docs/inventory.rst new file mode 100644 index 0000000000000000000000000000000000000000..65ac9c46dc059b238912dc89185263ed50de8784 --- /dev/null +++ b/docs/inventory.rst @@ -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 diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000000000000000000000000000000000000..da9a651fce9a4e44df08333089efea69c0731eeb --- /dev/null +++ b/docs/make.bat @@ -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 ^` where ^ 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 diff --git a/docs/overview.rst b/docs/overview.rst new file mode 100644 index 0000000000000000000000000000000000000000..5f6b25faf55ad862602c2159b64c01f111ddd4e8 --- /dev/null +++ b/docs/overview.rst @@ -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. diff --git a/registrasion/models/conditions.py b/registrasion/models/conditions.py index 804f31627810916fffde8653515c90b3a7b62075..6f259d90932154716589d75512ea1b473079d7e8 100644 --- a/registrasion/models/conditions.py +++ b/registrasion/models/conditions.py @@ -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. + + condition (int): This determines the effect of this flag's condition + being met. There are two types of condition: + + ``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 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. + 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. - If both types of conditions exist on a product, both of these rules apply. + 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" diff --git a/registrasion/models/inventory.py b/registrasion/models/inventory.py index e4e27feb34a05db82fa677d9dec8175c65060bc2..84f386e19323930bcc255a207e8eab589b5a6bf2 100644 --- a/registrasion/models/inventory.py +++ b/registrasion/models/inventory.py @@ -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" diff --git a/requirements/base.txt b/requirements/base.txt index 29d5ff623c8502463c8a6ace8f5fafc113a26091..25c5df9b6e9b4fc56e3201be8f25047d24817664 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -1,2 +1 @@ django-nested-admin==2.2.6 -#-e git+https://github.com/pinax/symposion.git#egg=SymposionMaster # Needs Symposion diff --git a/requirements/docs.txt b/requirements/docs.txt new file mode 100644 index 0000000000000000000000000000000000000000..f070a205eebe05dfa3f2897b9696b1fcc493d126 --- /dev/null +++ b/requirements/docs.txt @@ -0,0 +1,4 @@ +# requirements needed to build the docs + +Sphinx==1.4.1 +sphinx-rtd-theme==0.1.9 diff --git a/requirements/extern.txt b/requirements/extern.txt new file mode 100644 index 0000000000000000000000000000000000000000..3dc3c610a8e0f09cf557cfde511279da77479494 --- /dev/null +++ b/requirements/extern.txt @@ -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