Changeset - 3c29e3db8c32
[Not reviewed]
! ! !
James Polley - 7 years ago 2017-09-29 14:44:14
jp@jamezpolley.com
git subrepo pull vendor/registrasion

subrepo:
subdir: "vendor/registrasion"
merged: "c1e194a"
upstream:
origin: "git@gitlab.com:tchaypo/registrasion.git"
branch: "lca2018"
commit: "c1e194a"
git-subrepo:
version: "0.3.1"
origin: "???"
commit: "???"
123 files changed with 3358 insertions and 2 deletions:
0 comments (0 inline, 0 general)
vendor/registrasion/.gitignore
Show inline comments
 
new file 100644
 
# Byte-compiled / optimized / DLL files
 
__pycache__/
 
*.py[cod]
 
*$py.class
 

	
 
# C extensions
 
*.so
 

	
 
# Distribution / packaging
 
.Python
 
env/
 
build/
 
develop-eggs/
 
dist/
 
downloads/
 
eggs/
 
.eggs/
 
lib/
 
lib64/
 
parts/
 
sdist/
 
var/
 
*.egg-info/
 
.installed.cfg
 
*.egg
 

	
 
# PyInstaller
 
#  Usually these files are written by a python script from a template
 
#  before PyInstaller builds the exe, so as to inject date/other infos into it.
 
*.manifest
 
*.spec
 

	
 
# Installer logs
 
pip-log.txt
 
pip-delete-this-directory.txt
 

	
 
# Unit test / coverage reports
 
htmlcov/
 
.tox/
 
.coverage
 
.coverage.*
 
.cache
 
nosetests.xml
 
coverage.xml
 
*,cover
 
.hypothesis/
 

	
 
# Translations
 
*.mo
 
*.pot
 

	
 
# Django stuff:
 
*.log
 

	
 
# Sphinx documentation
 
docs/_build/
 

	
 
# PyBuilder
 
target/
 

	
 
# Grumble OSX Grumble
 

	
 
.DS_Store
 
*/.DS_Store
vendor/registrasion/.gitrepo
Show inline comments
...
 
@@ -8,4 +8,4 @@
 
	branch = lca2018
 
	commit = 8851e2076c071120ffe1dcc8bf99ac009a0fb1d9
 
	parent = 7c4cde09de905a9cf10a5b6490eddd2fa1e11b2e
 
	commit = c1e194aef92e4c06a8855fad22ca819c08736dad
 
	parent = dd8a42e9f67cfebc39347cb87bacf79046bfbfec
 
	cmdver = 0.3.1
vendor/registrasion/CONTRIBUTING.rst
Show inline comments
 
new file 100644
 
Contributing to Registrasion
 
============================
 

	
 
I'm glad that you're interested in helping make Registrasion better! Thanks! This guide is meant to help make sure your contributions to the project fit in well.
 

	
 
Making a contribution
 
---------------------
 

	
 
This project makes use of GitHub issues to track pending work, so new features that need implementation can be found there. If you think a new feature needs to be added, raise an issue for discussion before submitting a Pull Request.
 

	
 

	
 
Code Style
 
----------
 

	
 
We use PEP8. Your code should pass checks by ``flake8`` with no errors or warnings before it will be merged.
 

	
 
We use `Google-style docstrings <http://sphinxcontrib-napoleon.readthedocs.org/en/latest/example_google.html>`_, primarily because they're far far more readable than ReST docstrings. New functions should have complete docstrings, so that new contributors have a chance of understanding how the API works.
 

	
 

	
 
Structure
 
---------
 

	
 
Django Models live in ``registrasion/models``; we separate our models out into separate files, because there's a lot of them. Models are grouped by logical functionality.
 

	
 
Actions that operate on Models live in ``registrasion/controllers``.
 

	
 

	
 
Testing
 
-------
 

	
 
Functionality that lives in ``regsistrasion/controllers`` was developed in a test-driven fashion, which is sensible, given it's where most of the business logic for registrasion lives. If you're changing behaviour of a controller, either submit a test with your pull request, or modify an existing test.
 

	
 

	
 
Documentation
 
-------------
 

	
 
Registrasion aims towards high-quality documentation, so that conference registration managers can understand how the system works, and so that webmasters working for conferences understand how the system fits together. Make sure that you have docstrings :)
 

	
 
The documentation is written in Australian English: *-ise* and not *-ize*, *-our* and not *-or*; *vegemite* and not *peanut butter*, etc etc etc.
vendor/registrasion/README.rst
Show inline comments
 
new file 100644
 
Registrasion
 
============
 

	
 
**Registra** (tion for Sympo) **sion**. A conference registration app for Django,
 
letting conferences big and small sell tickets from within Symposion.
 

	
 
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 ``registrasion`` 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/
vendor/registrasion/design/design.md
Show inline comments
 
new file 100644
 
# Logic
 

	
 
## Definitions
 
- User has one 'active Cart' at a time. The Cart remains active until a paid Invoice is attached to it.
 
- A 'paid Cart' is a Cart with a paid Invoice attached to it, where the Invoice has not been voided.
 
- An unpaid Cart is 'reserved' if
 
 - CURRENT_TIME - "Time last updated" <= max(reservation duration of Products in Cart),
 
 - A Voucher was added and CURRENT_TIME - "Time last updated" < VOUCHER_RESERVATION_TIME (15 minutes?)
 
- An Item is 'reserved' if:
 
  - it belongs to a reserved Cart
 
  - it belongs to a paid Cart
 
- A Cart can have any number of Items added to it, subject to limits.
 

	
 

	
 
## Entering Vouchers
 
- Vouchers are attached to Carts
 
- A user can enter codes for as many different Vouchers as they like.
 
- A Voucher is added to the Cart if the number of paid or reserved Carts containing the Voucher is less than the "total available" for the voucher.
 
- A cart is invalid if it contains a voucher that has been overused
 

	
 

	
 
## Are products available?
 

	
 
- Availability is determined by the number of items we want to add to the cart: items_to_add
 

	
 
- If items_to_add + count(Product in their active and paid Carts) > "Limit per user" for the Product, the Product is "unavailable".
 
- If the Product belongs to an exhausted Ceiling, the Product is "unavailable".
 
- Otherwise, the product is available
 

	
 

	
 
## Displaying Products:
 

	
 
- If there is at least one mandatory EnablingCondition attached to the Product, display it only if all EnablingConditions are met
 
- If there is at least one EnablingCondition attached to the Product, display it only if at least one EnablingCondition is met
 
- If there are zero EnablingConditions attached to the Product, display it
 
- If the product is not available for items_to_add=0, mark it as "unavailable"
 

	
 
- If the Product is displayed and available, its price is the price for the Product, minus the greatest Discount available to this Cart and Product
 

	
 
- The product is displayed per the rendering characteristics of the Category it belongs to
 

	
 

	
 
## Displaying Categories
 

	
 
- If the Category contains only "unavailable" Products, mark it as "unavailable"
 
- If the Category contains no displayed Products, do not display the Category
 
- If the Category contains at least one EnablingCondition, display it only if at least one EnablingCondition is met
 
- If the Category contains no EnablingConditions, display it
 

	
 

	
 
## Exhausting Ceilings
 

	
 
- Exhaustion is determined by the number of items we want to add to the cart: items_to_add
 

	
 
- A ceiling is exhausted if:
 
 - Its start date has not yet been reached
 
 - Its end date has been exceeded
 
 - items_to_add + sum(paid and reserved Items for each Product in the ceiling) > Total available
 

	
 

	
 
## Applying Discounts
 

	
 
- Discounts only apply to the current cart
 
- Discounts can be applied to multiple carts until the user has exhausted the quantity for each product attached to the discount.
 
- Only one discount discount can be applied to each single item. Discounts are applied as follows:
 
 - All non-exhausted discounts for the product or its category are ordered by value
 
 - The highest discount is applied for the lower of the quantity of the product in the cart, or the remaining quantity from this discount
 
 - If the quantity remaining is non-zero, apply the next available discount
 

	
 
- Individual discount objects should not contain more than one DiscountForProduct for the same product
 
- Individual discount objects should not contain more than one DiscountForCategory for the same category
 
- Individual discount objects should not contain a discount for both a product and its category
 

	
 

	
 
## Adding Items to the Cart
 

	
 
- Products that are not displayed may not be added to a Cart
 
- The requested number of items must be available for those items to be added to a Cart
 
- If a different price applies to a Product when it is added to a cart, add at the new price, and display an alert to the user
 
- If a discount is used when adding a Product to the cart, add the discount as well
 
- Adding an item resets the "Time last updated" for the cart
 
- Each time carts have items added or removed, the revision number is updated
 

	
 

	
 
## Generating an invoice
 

	
 
- User can ask to 'check out' the active Cart. Doing so generates an Invoice. The invoice corresponds to a revision number of the cart.
 
- Checking out the active Cart resets the "Time last updated" for the cart.
 
- The invoice represents the current state of the cart.
 
- If the revision number for the cart is different to the cart's revision number for the invoice, the invoice is void.
 
- The invoice is void if
 

	
 

	
 
## Paying an invoice
 

	
 
- A payment can only be attached to an invoice if all of the items in it are available at the time payment is processed
 

	
 
### One-Shot
 
- Update the "Time last updated" for the cart based on the expected time it takes for a payment to complete
 
- Verify that all items are available, and if so:
 
- Proceed to make payment
 
- Apply payment record from amount received
 

	
 

	
 
### Authorization-based approach:
 
- Capture an authorization on the card
 
- Verify that all items are available, and if so:
 
- Apply payment record
 
- Take payment
 

	
 

	
 
# Registration workflow:
 

	
 
## User has not taken a guided registration yet:
 

	
 
User is shown two options:
 

	
 
1. Undertake guided registration ("for current user")
 
1. Purchase vouchers
 

	
 

	
 
## User has not purchased a ticket, and wishes to:
 

	
 
This gives the user a guided registration process.
 

	
 
1. Take list of categories, sorted by display order, and display the next lowest enabled & available category
 
1. Take user to category page
 
1. User can click "back" to go to previous screen, or "next" to go the next lowest enabled & available category
 

	
 
Once all categories have been seen:
 
1. Ask for badge information -- badge information is *not* the same as the invoicee.
 
1. User is taken to the "user has purchased a ticket" workflow
 

	
 

	
 
## User is buying vouchers
 
TODO: Consider separate workflow for purchasing ticket vouchers.
 

	
 

	
 
## User has completed a guided registration or purchased vouchers
 

	
 
1. Show list of products that are pending purchase.
 
1. Show list of categories + badge information, as well as 'checkout' button if the user has items in their current cart
 

	
 

	
 
## Category page
 

	
 
- User can enter a voucher at any time
 
- User is shown the list of products that have been paid for
 
- User has the option to add/remove products that are in the current cart
 

	
 

	
 
## Checkout
 

	
 
1. Ask for invoicing details (pre-fill from previous invoice?)
 
1. Ask for payment
 

	
 

	
 
# User Models
 

	
 
- Profile:
 
 - User
 
 - Has done guided registration?
 
 - Badge
 
 -
 

	
 
## Transaction Models
 

	
 
- Cart:
 
 - User
 
 - {Items}
 
 - {Voucher}
 
 - {DiscountItems}
 
 - Time last updated
 
 - Revision Number
 
 - Active?
 

	
 
- Item
 
 - Product
 
 - Quantity
 

	
 
- DiscountItem
 
 - Product
 
 - Discount
 
 - Quantity
 

	
 
- Invoice:
 
 - Invoice number
 
 - User
 
 - Cart
 
 - Cart Revision
 
 - {Line Items}
 
 - (Invoice Details)
 
 - {Payments}
 
 - Voided?
 

	
 
- LineItem
 
 - Description
 
 - Quantity
 
 - Price
 

	
 
- Payment
 
 - Time
 
 - Amount
 
 - Reference
 

	
 

	
 
## Inventory Model
 

	
 
- Product:
 
 - Name
 
 - Description
 
 - Category
 
 - Price
 
 - Limit per user
 
 - Reservation duration
 
 - Display order
 
 - {Ceilings}
 

	
 

	
 
- Voucher
 
 - Description
 
 - Code
 
 - Total available
 

	
 

	
 
- Category?
 
 - Name
 
 - Description
 
 - Display Order
 
 - Rendering Style
 

	
 

	
 
## Product Modifiers
 

	
 
- Discount:
 
 - Description
 
 - {DiscountForProduct}
 
 - {DiscountForCategory}
 

	
 
 - Discount Types:
 
    - TimeOrStockLimitDiscount:
 
     * A discount that is available for a limited amount of time, e.g. Early Bird sales *
 
     - Start date
 
     - End date
 
     - Total available
 

	
 
    - VoucherDiscount:
 
     * A discount that is available to a specific voucher *
 
     - Voucher
 

	
 
    - RoleDiscount
 
     * A discount that is available to a specific role *
 
     - Role
 

	
 
    - IncludedProductDiscount:
 
     * A discount that is available because another product has been purchased *
 
     - {Parent Product}
 

	
 
- DiscountForProduct
 
 - Product
 
 - Amount
 
 - Percentage
 
 - Quantity
 

	
 
- DiscountForCategory
 
 - Category
 
 - Percentage
 
 - Quantity
 

	
 

	
 
- EnablingCondition:
 
 - Description
 
 - Mandatory?
 
 - {Products}
 
 - {Categories}
 

	
 
 - EnablingCondition Types:
 
   - ProductEnablingCondition:
 
    * Enabling because the user has purchased a specific product *
 
    - {Products that enable}
 

	
 
   - CategoryEnablingCondition:
 
    * Enabling because the user has purchased a product in a specific category *
 
    - {Categories that enable}
 

	
 
   - VoucherEnablingCondition:
 
    * Enabling because the user has entered a voucher code *
 
     - Voucher
 

	
 
   - RoleEnablingCondition:
 
     * Enabling because the user has a specific role *
 
     - Role
 

	
 
   - TimeOrStockLimitEnablingCondition:
 
    * Enabling because a time condition has been met, or a number of items underneath it have not been sold *
 
    - Start date
 
    - End date
 
    - Total available
vendor/registrasion/design/goals.md
Show inline comments
 
new file 100644
 
# Registrasion
 

	
 
## What
 

	
 
A registration package that sits on top of the Symposion conference management system. It aims to be able to model complex events, such as those used by [Linux Australia events](http://lca2016.linux.org.au/register/info?_code=301).
 

	
 

	
 
## Planned features
 

	
 
### KEY:
 
- _(MODEL)_: these have model/controller functionality, and tests, and needs UI
 
- _(ADMIN)_: these have admin functionality
 

	
 
### Inventory
 
- Allow conferences to manage complex inventories of products, including tickets, t-shirts, dinner tickets, and accommodation _(MODEL)_ _(ADMIN)_
 
- Reports of available inventory and progressive sales for conference staff
 
- Restrict sales of products to specific classes of users
 
- Restrict sales of products based to users who've purchased specific products _(MODEL)_ _(ADMIN)_
 
- Restrict sales of products based on time/inventory limits _(MODEL)_ _(ADMIN)_
 
- Restrict sales of products to users with a voucher _(MODEL)_ _(ADMIN)_
 

	
 
### Tickets
 
- Sell multiple types of tickets, each with different included products _(MODEL)_ _(ADMIN)_
 
- Allow for early bird-style discounts _(MODEL)_ _(ADMIN)_
 
- Allow attendees to purchase products after initial registration is complete _(MODEL)_
 
 - Offer included products if they have not yet been claimed _(MODEL)_
 
- Automatically offer free tickets to speakers and team
 
- Offer free tickets for sponsor attendees by voucher _(MODEL)_ _(ADMIN)_
 

	
 
### Vouchers
 
- Vouchers for arbitrary discounts off visible products _(MODEL)_ _(ADMIN)_
 
- Vouchers that enable secret products _(MODEL)_ _(ADMIN)_
 

	
 
### Invoicing
 
- Automatic invoicing including discount calculation _(MODEL)_
 
- Manual invoicing for arbitrary products by organisers _(MODEL)_
 
- Refunds
 

	
 
### Payments
 
- Allow multiple payment gateways (so that conferences are not locked into specific payment providers)
 
- Allow payment of registrations by unauthenticated users (allow business admins to pay for registrations)
 
- Allow payment of multiple registrations at once
 

	
 
### Attendee profiles
 
- Attendees can enter information to be shown on their badge/dietary requirements etc
 
- Profile can be changed until check-in, allowing for badge/company updates
 

	
 
### At the conference
 
- Badge generation, in batches, or on-demand during check-in
 
- Registration manifests for each attendee including purchased products
 
- Check-in process at registration desk allowing manifested items to be claimed
 

	
 
### Tooling
 
- Generate simple registration cases (ones that don't have complex inventory requirements)
 
- Generate complex registration cases from spreadsheets
vendor/registrasion/docs/Makefile
Show inline comments
 
new file 100644
 
# 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."
vendor/registrasion/docs/conf.py
Show inline comments
 
new file 100644
 
# -*- 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
vendor/registrasion/docs/django_settings.py
Show inline comments
 
new file 100644
 
"""
 
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/'
vendor/registrasion/docs/for-zookeepr-users.rst
Show inline comments
 
new file 100644
 
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.
vendor/registrasion/docs/index.rst
Show inline comments
 
new file 100644
 
.. 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
 
============
 

	
 
Registra(tion for Sympo)sion.
 

	
 
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 generous support of the Python Software Foundation.
 

	
 

	
 
Contents:
 
---------
 
.. toctree::
 
   :maxdepth: 2
 

	
 
   overview
 
   integration
 
   inventory
 
   payments
 
   for-zookeepr-users
 
   views
 
   templates
 

	
 

	
 
Indices and tables
 
==================
 

	
 
* :ref:`genindex`
 
* :ref:`search`
 

	
 
.. * :ref:`modindex`
vendor/registrasion/docs/integration.rst
Show inline comments
 
new file 100644
 
Installing and integrating Registrasion
 
=======================================
 

	
 
Registrasion is a Django app. It does not provide any templates -- you'll need to develop these yourself. You can use the `registrasion-demo <https://github.com/chrisjrn/registrasion-demo>`_ project as a starting point.
 

	
 
To use Registrasion for your own conference, you'll need to do a small amount of configuration and development work, in your own Django App.
 

	
 
The configuration that you'll need to do is minimal. The first piece of development work is to define a model and form for your attendee profile, and the second is to implement a payment app.
 

	
 

	
 
Installing Registrasion
 
-----------------------
 

	
 
Registrasion depends on an in-development version of Symposion. You'll need to add the following  line to your ``requirements.txt`` files::
 

	
 
    registrasion==0.1.0
 
    https://github.com/pinax/symposion/tarball/ad81810#egg=symposion
 

	
 
And also to enable dependency links in pip::
 

	
 
    pip install --process-dependency-links -r requirements.txt
 

	
 
Symposion currently specifies Django version 1.9.2. Note that ``pip`` version 1.6 does not support ``--process-dependency-links``, so you'll need to use an earlier, or later version of ``pip``.
 

	
 

	
 
Configuring your Django App
 
---------------------------
 

	
 
In your Django ``settings.py`` file, you'll need to add the following to your ``INSTALLED_APPS``::
 

	
 
  "registrasion",
 
  "nested_admin",
 

	
 
You will also need to configure ``symposion`` appropriately.
 

	
 

	
 
Attendee profile
 
----------------
 

	
 
.. automodule:: registrasion.models.people
 

	
 
Attendee profiles are where you ask for information such as what your attendee wants on their badge, and what the attendee's dietary and accessibility requirements are.
 

	
 
Because every conference is different, Registrasion lets you define your own attendee profile model, and your own form for requesting this information. The only requirement is that you derive your model from ``AttendeeProfileBase``.
 

	
 
.. autoclass :: AttendeeProfileBase
 
    :members: name_field, invoice_recipient
 

	
 
You specify how to find that model in your Django ``settings.py`` file::
 

	
 
    ATTENDEE_PROFILE_MODEL = "democon.models.AttendeeProfile"
 

	
 
When Registrasion asks the to edit their profile, a default form will be generated, showing all of the fields on the profile model.
 

	
 
If you want to customise the profile editing form, you need to specify the location of that form in your ``settings.py`` file as well.
 

	
 
    ATTENDEE_PROFILE_FORM = "democon.forms.AttendeeProfileForm"
 

	
 
The only contract is that this form creates an instance of ``AttendeeProfileBase`` when saved, and that it can take an instance of your subclass on creation (so that your attendees can edit their profile).
 

	
 

	
 
Payments
 
--------
 

	
 
Registrasion does not implement its own credit card processing. You'll need to do that yourself. Registrasion *does* provide a mechanism for recording cheques and direct deposits, if you do end up taking registrations that way.
 

	
 
See :ref:`payments_and_refunds` for a guide on how to correctly implement payments.
vendor/registrasion/docs/inventory.rst
Show inline comments
 
new file 100644
 

	
 
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.
 

	
 
All of the classes described herein are available through the Django Admin interface.
 

	
 
Overview
 
--------
 

	
 
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
vendor/registrasion/docs/make.bat
Show inline comments
 
new file 100644
 
@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
vendor/registrasion/docs/overview.rst
Show inline comments
 
new file 100644
 
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.
vendor/registrasion/docs/payments.rst
Show inline comments
 
new file 100644
 
.. automodule:: registrasion.models.commerce
 
.. _payments_and_refunds:
 

	
 
Payments and Refunds
 
====================
 

	
 
Registrasion aims to support whatever payment platform you have available to use. Therefore, Registrasion uses a bare minimum payments model to track money within the system. It's the role of you, as a deployer of Registrasion, to implement a payment application that communicates with your own payment platform.
 

	
 
Invoices may have multiple ``PaymentBase`` objects attached to them; each of these represent a payment against the invoice. Payments can be negative (and this represents a refund against the Invoice), however, this approach is not recommended for use by implementers.
 

	
 
Registrasion also keeps track of money that is not currently attached to invoices through `credit notes`_. Credit notes may be applied to unpaid invoices *in full*, if there is an amount left over from the credit note, a new credit note will be created from that amount. Credit notes may also be released, at which point they're the responsibility of the payment application to create a refund.
 

	
 
Finally, Registrasion provides a `manual payments`_ feature, which allows for staff members to manually report payments into the system. This is the only payment facility built into Registrasion, but it's not intended as a reference implementation.
 

	
 

	
 
Invoice and payment access control
 
----------------------------------
 

	
 
Conferences are interesting: usually you want attendees to fill in their own registration so that they get their catering options right, so that they can personally agree to codes of conduct, and so that you can make sure that you're communicating key information directly with them.
 

	
 
On the other hand, employees at companies often need for their employers to directly pay for their registration.
 

	
 
Registrasion solves this problem by having attendees complete their own registration, and then providing an access URL that allows anyone who holds that URL to view their invoice and make payment.
 

	
 
You can call ``InvoiceController.can_view`` to determine whether or not you're allowed to show the invoice. It returns true if the user is allowed to view the invoice::
 

	
 
    InvoiceController.can_view(self, user=request.user, access_code="CODE")
 

	
 
As a rule, you should call ``can_view`` before doing any operations that amend the status of an invoice. This includes taking payments or requesting refunds.
 

	
 
The access code is unique for each attendee -- this means that every invoice that an attendee generates can be viewed with the same access code. This is useful if the user amends their registration between giving the URL to their employer, and their employer making payment.
 

	
 

	
 

	
 

	
 
Making payments
 
---------------
 

	
 
Making payments is a three-step process:
 

	
 
#. Validate that the invoice is ready to be paid,
 
#. Create a payment object for the amount that you are paying towards an invoice,
 
#. Ask the invoice to calculate its status now that the payment has been made.
 

	
 
Pre-validation
 
~~~~~~~~~~~~~~
 
Registrasion's ``InvoiceController`` has a ``validate_allowed_to_pay`` method, which performs all of the pre-payment checks (is the invoice still unpaid and non-void? has the registration been amended?).
 

	
 
If the pre-payment check fails, ``InvoiceController`` will raise a Django ``ValidationError``.
 

	
 
Our the ``demopay`` view from the ``registrasion-demo`` project implements pre-validation like so::
 

	
 
    from registrasion.controllers.invoice import InvoiceController
 
    from django.core.exceptions import ValidationError
 

	
 
    invoice = InvoiceController.for_id_or_404(invoice.id)
 

	
 
    try:
 
        invoice.validate_allowed_to_pay()  # Verify that we're allowed to do this.
 
    except ValidationError as ve:
 
        messages.error(request, ve.message)
 
        return REDIRECT_TO_INVOICE  # And display the validation message.
 

	
 
In most cases, you don't engage your actual payment application until after pre-validation is finished, as this gives you an opportunity to bail out if the invoice isn't able to have funds applied to it.
 

	
 
Applying payments
 
~~~~~~~~~~~~~~~~~
 
Payments in Registrasion are represented as subclasses of the ``PaymentBase`` model. ``PaymentBase`` looks like this:
 

	
 
.. autoclass :: PaymentBase
 

	
 
When you implement your own payment application, you'll need to subclass ``PaymentBase``, as this will allow you to add metadata that lets you link the Registrasion payment object with your payment platform's object.
 

	
 
Generally, the ``reference`` field should be something that lets your end-users identify the payment on their credit card statement, and to provide to your team's tech support in case something goes wrong.
 

	
 
Once you've subclassed ``PaymentBase``, applying a payment is really quite simple. In the ``demopay`` view, we have a subclass called ``DemoPayment``::
 

	
 
    invoice = InvoiceController(some_invoice_model)
 

	
 
    # Create the payment object
 
    models.DemoPayment.objects.create(
 
        invoice=invoice.invoice,
 
        reference="Demo payment by user: " + request.user.username,
 
        amount=invoice.invoice.value,
 
    )
 

	
 
Note that multiple payments can be provided against an ``Invoice``, however, payments that exceed the total value of the invoice will have credit notes generated.
 

	
 
Updating an invoice's status
 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
``InvoiceController`` has a method called ``update_status``. You should call ``update_status`` immediately after you create a ``PaymentBase`` object, as this keeps invoice and its payments synchronised::
 

	
 
    invoice = InvoiceController(some_invoice_model)
 
    invoice.update_status()
 

	
 
Calling ``update_status`` collects the ``PaymentBase`` objects that are attached to the ``Invoice``, and will update the status of the invoice:
 

	
 
* If an invoice is ``VOID``, it will remain void.
 
* If an invoice is ``UNPAID`` and it now has ``PaymentBase`` objects whose value meets or exceed's the invoice's value, the invoice becomes ``PAID``.
 
* If an invoice is ``UNPAID`` and it now has ``PaymentBase`` objects whose values sum to zero, the invoice becomes ``VOID``.
 
* If an invoice is ``PAID`` and it now has ``PaymentBase`` objects of less than the invoice's value, the invoice becomes ``REFUNDED``.
 

	
 
When your invoice becomes ``PAID`` for the first time, if there's a cart of inventory items attached to it, that cart becomes permanently reserved -- that is, all of the items within it are no longer available for other users to purchase. If an invoice becomes ``REFUNDED``, the items in the cart are released, which means that they are available for anyone to purchase again.
 

	
 
If you overpay an invoice, or pay into an invoice that should not have funds attached, a credit note for the residual payments will also be issued.
 

	
 
In general, although this means you *can* use negative payments to take an invoice into a *REFUNDED* state, it's still much more sensible to use the credit notes facility, as this makes sure that any leftover funds remain tracked in the system.
 

	
 

	
 
Credit Notes
 
------------
 

	
 
When you refund an invoice, often you're doing so in order to make a minor amendment to items that the attendee has purchased. In order to make it easy to transfer funds from a refunded invoice to a new invoice, Registrasion provides an automatic credit note facility.
 

	
 
Credit notes are created when you mark an invoice as refunded, but they're also created if you overpay an invoice, or if you direct money into an invoice that can no longer take payment.
 

	
 
Once created, Credit Notes act as a payment that can be put towards other invoices, or that can be cashed out, back to the original payment platform. Credits can only be applied or cashed out in full.
 

	
 
This means that it's easy to track funds that aren't accounted for by invoices -- it's just the sum of the credit notes that haven't been applied to new invoices, or haven't been cashed out.
 

	
 
We recommend using credit notes to track all of your refunds for consistency; it also allows you to invoice for cancellation fees and the like.
 

	
 
Creating credit notes
 
~~~~~~~~~~~~~~~~~~~~~
 
In Registrasion, credit notes originate against invoices, and are represented as negative payments to an invoice.
 

	
 
Credit notes are usually created automatically. In most cases, Credit Notes come about from asking to refund an invoice::
 

	
 
    InvoiceController(invoice).refund()
 

	
 
Calling ``refund()`` will generate a refund of all of the payments applied to that invoice.
 

	
 
Otherwise, credit notes come about when invoices are overpaid, in this case, a credit for the overpay amount will be generated.
 

	
 
Applying credits to new invoices
 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
Credits can be applied to invoices::
 

	
 
    CreditNoteController(credit_not).apply_to_invoice(invoice)
 

	
 
This will result in an instance of ``CreditNoteApplication`` being applied as a payment to ``invoice``. ``CreditNoteApplication`` will always be a payment of the full amount of its parent credit note. If this payment overpays the invoice it's being applied to, a credit note for the residual will be generated.
 

	
 
Refunding credit notes
 
~~~~~~~~~~~~~~~~~~~~~~
 
It is possible to release a credit note back to the original payment platform. To do so, you attach an instance of ``CreditNoteRefund`` to the original ``CreditNote``:
 

	
 
.. autoclass :: CreditNoteRefund
 

	
 
You'll usually want to make a subclass of ``CreditNoteRefund`` for your own purposes, usually so that you can tie Registrasion's internal representation of the refund to a concrete refund on the side of your payment platform.
 

	
 
Note that you can only release a credit back to the payment platform for the full amount of the credit.
 

	
 

	
 
Manual payments
 
---------------
 

	
 
Registrasion provides a *manual payments* feature, which allows for staff members to manually report payments into the system. This is the only payment facility built into Registrasion, but it's not intended as a reference implementation.
 

	
 
The main use case for manual payments is to record the receipt of funds from bank transfers or cheques sent on behalf of attendees.
 

	
 
It's not intended as a reference implementation is because it does not perform validation of the cart before the payment is applied to the invoice.
 

	
 
This means that it's possible for a staff member to apply a payment with a specific invoice reference into the invoice matching that reference. Registrasion will generate a credit note if the invoice is not able to receive payment (e.g. because it has since been voided), you can use that credit note to pay into a valid invoice if necessary.
 

	
 
It is possible for staff to enter a negative amount on a manual payment. This will be treated as a refund. Generally, it's preferred to issue a credit note to an invoice rather than enter a negative amount manually.
vendor/registrasion/docs/templates.rst
Show inline comments
 
new file 100644
 
Basic Templates
 
===============
 
Registrasion provides basic templates for all of its views. This means that if new features come along, you won't need to do extra work just to enable them.
 

	
 

	
 
What is the point of this?
 
--------------------------
 

	
 
`registrasion` provides a bunch of django views that make the app tick. As new features get added, so will this package. By keeping this package up to date, you'll get a default template for each new view that gets added.
 

	
 

	
 
How does it work
 
----------------
 

	
 
For each template required by registrasion, `registrasion_templates` provides two templates. Say the template used by the view is called `view.html`. We provide:
 

	
 
* `view.html`, which is the template that is loaded directly -- this will be *very* modular, and will let you easily override things that you need to override in your own installations
 
* `view_.html`, which is the thing that lays everything out.
 

	
 
So you can either override `view_.html` if you're happy with the text and markup that `view.html` provides, or you can override `view.html` if you want to change the entire thing. Your choice!
 

	
 

	
 
Installation
 
------------
 

	
 
Ensure that `APP_DIRS` is switched on in your `settings`, like so:
 

	
 
```
 
TEMPLATES = [{
 
    'BACKEND': 'django.template.backends.django.DjangoTemplates',
 
    'APP_DIRS': True,
 
}]
 
```
 

	
 

	
 
Overriding our defaults:
 
~~~~~~~~~~~~~~~~~~~~~~~~
 

	
 
* `registrasion/form.html` is used by these templates whenever a form needs to be rendered. The default implementation of this just calls ``{form}``, however, you may want to render your forms differently.
 
* `registrasion/base.html` extends `site_base.html`. Each `view_.html` template that we provide extends `registrasion/base.html`
 

	
 

	
 
Using the templates
 
-------------------
 

	
 
* All of the default templates provide the following blocks:
 
  * `title`, which is added to the site's `<title>` tag
 
  * `heading`, which is the page's heading
 
  * `lede`, a paragraph that describes the page
 
  * `content`, the body content for the page
 
* If you want that content to appear in your pages, you must include these blocks in your `registrasion/base.html`.
 

	
 
* `content` may include other blocks, so that you can override default text. Each `view.html` template will document the blocks that you can override.
 

	
 

	
 
CSS styling
 
-----------
 

	
 
The in-built templates do a small amount of layout and styling work, using bootstrap conventions. The following CSS classes are used:
 

	
 
* `panel panel-default`
 
* `panel panel-primary`
 
* `panel panel-info`
 
* `panel-heading`
 
* `panel-title`
 
* `panel-body`
 
* `panel-footer`
 
* `form-actions`
 
* `btn btn-default`
 
* `btn btn-primary`
 
* `btn btn-xs btn-default`
 
* `alert alert-info`
 
* `alert alert-warning`
 
* `list-group`
 
* `list-group-item`
 
* `well`
 
* `table`
 
* `table table-striped`
vendor/registrasion/docs/views.rst
Show inline comments
 
new file 100644
 
User-facing views
 
=================
 

	
 

	
 
View functions
 
--------------
 

	
 
Here's all of the views that Registrasion exposes to the public.
 

	
 
.. automodule:: registrasion.views
 
    :members:
 

	
 
Data types
 
~~~~~~~~~~
 

	
 
.. automodule:: registrasion.controllers.discount
 

	
 
.. autoclass:: DiscountAndQuantity
 

	
 

	
 
Template tags
 
-------------
 

	
 
Registrasion makes template tags available:
 

	
 
.. automodule:: registrasion.templatetags.registrasion_tags
 
    :members:
 

	
 

	
 
Rendering invoices
 
------------------
 

	
 
You'll need to render the following Django models in order to view invoices.
 

	
 
.. automodule:: registrasion.models.commerce
 

	
 
.. autoclass:: Invoice
 

	
 
.. autoclass:: LineItem
 

	
 
See also: :class:`PaymentBase`
vendor/registrasion/registrasion/__init__.py
Show inline comments
 
file renamed from vendor/registrasion/__init__.py to vendor/registrasion/registrasion/__init__.py
vendor/registrasion/registrasion/admin.py
Show inline comments
 
file renamed from vendor/registrasion/admin.py to vendor/registrasion/registrasion/admin.py
vendor/registrasion/registrasion/apps.py
Show inline comments
 
file renamed from vendor/registrasion/apps.py to vendor/registrasion/registrasion/apps.py
vendor/registrasion/registrasion/contrib/__init__.py
Show inline comments
 
file renamed from vendor/registrasion/contrib/__init__.py to vendor/registrasion/registrasion/contrib/__init__.py
vendor/registrasion/registrasion/contrib/mail.py
Show inline comments
 
file renamed from vendor/registrasion/contrib/mail.py to vendor/registrasion/registrasion/contrib/mail.py
vendor/registrasion/registrasion/controllers/__init__.py
Show inline comments
 
file renamed from vendor/registrasion/controllers/__init__.py to vendor/registrasion/registrasion/controllers/__init__.py
vendor/registrasion/registrasion/controllers/batch.py
Show inline comments
 
file renamed from vendor/registrasion/controllers/batch.py to vendor/registrasion/registrasion/controllers/batch.py
vendor/registrasion/registrasion/controllers/cart.py
Show inline comments
 
file renamed from vendor/registrasion/controllers/cart.py to vendor/registrasion/registrasion/controllers/cart.py
vendor/registrasion/registrasion/controllers/category.py
Show inline comments
 
file renamed from vendor/registrasion/controllers/category.py to vendor/registrasion/registrasion/controllers/category.py
vendor/registrasion/registrasion/controllers/conditions.py
Show inline comments
 
file renamed from vendor/registrasion/controllers/conditions.py to vendor/registrasion/registrasion/controllers/conditions.py
vendor/registrasion/registrasion/controllers/credit_note.py
Show inline comments
 
file renamed from vendor/registrasion/controllers/credit_note.py to vendor/registrasion/registrasion/controllers/credit_note.py
vendor/registrasion/registrasion/controllers/discount.py
Show inline comments
 
file renamed from vendor/registrasion/controllers/discount.py to vendor/registrasion/registrasion/controllers/discount.py
vendor/registrasion/registrasion/controllers/flag.py
Show inline comments
 
file renamed from vendor/registrasion/controllers/flag.py to vendor/registrasion/registrasion/controllers/flag.py
vendor/registrasion/registrasion/controllers/for_id.py
Show inline comments
 
file renamed from vendor/registrasion/controllers/for_id.py to vendor/registrasion/registrasion/controllers/for_id.py
vendor/registrasion/registrasion/controllers/invoice.py
Show inline comments
 
file renamed from vendor/registrasion/controllers/invoice.py to vendor/registrasion/registrasion/controllers/invoice.py
vendor/registrasion/registrasion/controllers/item.py
Show inline comments
 
file renamed from vendor/registrasion/controllers/item.py to vendor/registrasion/registrasion/controllers/item.py
vendor/registrasion/registrasion/controllers/product.py
Show inline comments
 
file renamed from vendor/registrasion/controllers/product.py to vendor/registrasion/registrasion/controllers/product.py
vendor/registrasion/registrasion/exceptions.py
Show inline comments
 
file renamed from vendor/registrasion/exceptions.py to vendor/registrasion/registrasion/exceptions.py
vendor/registrasion/registrasion/forms.py
Show inline comments
 
file renamed from vendor/registrasion/forms.py to vendor/registrasion/registrasion/forms.py
vendor/registrasion/registrasion/migrations/0001_initial.py
Show inline comments
 
file renamed from vendor/registrasion/migrations/0001_initial.py to vendor/registrasion/registrasion/migrations/0001_initial.py
vendor/registrasion/registrasion/migrations/0002_auto_20160822_0034.py
Show inline comments
 
file renamed from vendor/registrasion/migrations/0002_auto_20160822_0034.py to vendor/registrasion/registrasion/migrations/0002_auto_20160822_0034.py
vendor/registrasion/registrasion/migrations/0003_auto_20160904_0235.py
Show inline comments
 
file renamed from vendor/registrasion/migrations/0003_auto_20160904_0235.py to vendor/registrasion/registrasion/migrations/0003_auto_20160904_0235.py
vendor/registrasion/registrasion/migrations/0004_groupmemberdiscount_groupmemberflag.py
Show inline comments
 
file renamed from vendor/registrasion/migrations/0004_groupmemberdiscount_groupmemberflag.py to vendor/registrasion/registrasion/migrations/0004_groupmemberdiscount_groupmemberflag.py
vendor/registrasion/registrasion/migrations/0005_auto_20160905_0945.py
Show inline comments
 
file renamed from vendor/registrasion/migrations/0005_auto_20160905_0945.py to vendor/registrasion/registrasion/migrations/0005_auto_20160905_0945.py
vendor/registrasion/registrasion/migrations/0006_auto_20170526_1624.py
Show inline comments
 
new file 100644
 
# -*- coding: utf-8 -*-
 
# Generated by Django 1.9.2 on 2017-05-26 16:24
 
from __future__ import unicode_literals
 

	
 
from django.db import migrations, models
 

	
 

	
 
class Migration(migrations.Migration):
 

	
 
    dependencies = [
 
        ('registrasion', '0005_auto_20160905_0945'),
 
    ]
 

	
 
    operations = [
 
        migrations.AlterField(
 
            model_name='category',
 
            name='render_type',
 
            field=models.IntegerField(choices=[(1, 'Radio button'), (2, 'Quantity boxes'), (3, 'Product selector and quantity box'), (4, 'Checkbox button')], help_text='The registration form will render this category in this style.', verbose_name='Render type'),
 
        ),
 
    ]
vendor/registrasion/registrasion/migrations/0006_auto_20170702_2233.py
Show inline comments
 
file renamed from vendor/registrasion/migrations/0006_auto_20170702_2233.py to vendor/registrasion/registrasion/migrations/0006_auto_20170702_2233.py
vendor/registrasion/registrasion/migrations/__init__.py
Show inline comments
 
file renamed from vendor/registrasion/migrations/__init__.py to vendor/registrasion/registrasion/migrations/__init__.py
vendor/registrasion/registrasion/models/__init__.py
Show inline comments
 
file renamed from vendor/registrasion/models/__init__.py to vendor/registrasion/registrasion/models/__init__.py
vendor/registrasion/registrasion/models/commerce.py
Show inline comments
 
file renamed from vendor/registrasion/models/commerce.py to vendor/registrasion/registrasion/models/commerce.py
vendor/registrasion/registrasion/models/conditions.py
Show inline comments
 
file renamed from vendor/registrasion/models/conditions.py to vendor/registrasion/registrasion/models/conditions.py
vendor/registrasion/registrasion/models/inventory.py
Show inline comments
 
file renamed from vendor/registrasion/models/inventory.py to vendor/registrasion/registrasion/models/inventory.py
vendor/registrasion/registrasion/models/people.py
Show inline comments
 
file renamed from vendor/registrasion/models/people.py to vendor/registrasion/registrasion/models/people.py
vendor/registrasion/registrasion/reporting/__init__.py
Show inline comments
 
file renamed from vendor/registrasion/reporting/__init__.py to vendor/registrasion/registrasion/reporting/__init__.py
vendor/registrasion/registrasion/reporting/forms.py
Show inline comments
 
file renamed from vendor/registrasion/reporting/forms.py to vendor/registrasion/registrasion/reporting/forms.py
vendor/registrasion/registrasion/reporting/reports.py
Show inline comments
 
file renamed from vendor/registrasion/reporting/reports.py to vendor/registrasion/registrasion/reporting/reports.py
vendor/registrasion/registrasion/reporting/views.py
Show inline comments
 
file renamed from vendor/registrasion/reporting/views.py to vendor/registrasion/registrasion/reporting/views.py
vendor/registrasion/registrasion/templates/registrasion/amend_registration.html
Show inline comments
 
new file 100644
 
{% extends "registrasion/amend_registration_.html" %}
 
{% comment %}
 
  Blocks that you can override:
 

	
 
{% endcomment %}
vendor/registrasion/registrasion/templates/registrasion/amend_registration_.html
Show inline comments
 
new file 100644
 
{% extends "registrasion/base.html" %}
 
{% load registrasion_tags %}
 

	
 
{% block title %}Amend registration{% endblock %}
 
{% block heading %}Amend registration{% endblock %}
 

	
 
{% block content %}
 

	
 
  <dl>
 
    <dt>Attendee name</dt>
 
    <dd>{{ user.attendee.attendeeprofilebase.attendee_name }}</dd>
 
    <dt>Attendee ID</dt>
 
    <dd>{{ user.id }}</dd>
 
  </dl>
 

	
 
  <h2>Item summary</h2>
 

	
 
  <div class="panel panel-default">
 
    <div class="panel-heading">
 
      <h3 class="panel-title">Paid Items</h3>
 
    </div>
 

	
 
    <div class="panel-body">
 
      <div class="alert alert-warning">
 
        You cannot remove paid items from someone's registration. You must first
 
        cancel the invoice that added those items. You will need to re-add the items
 
        from that invoice for the user to have them available again.
 
      </div>
 
    </div>
 

	
 
    {% include "registrasion/snippets/items_list.html" with items=paid ul_class="list-group" li_class="list-group-item" %}
 
  </div>
 

	
 
  <div class="panel panel-default">
 
    <div class="panel-heading">
 
      <h3 class="panel-title">Cancelled Items</h3>
 
    </div>
 

	
 
    {% if cancelled %}
 
      {% include "registrasion/snippets/items_list.html" with items=cancelled ul_class="list-group" li_class="list-group-item" %}
 
    {% else %}
 
      <div class="panel-body">No cancelled items.</div>
 
    {% endif %}
 
  </div>
 

	
 
  <div class="panel panel-default">
 
    <div class="panel-heading">
 
      <h3 class="panel-title">Amend pending items</h3>
 
    </div>
 

	
 
    <form method="POST">
 
      <div class="panel-body">
 
        {% csrf_token %}
 
        {% include "registrasion/form.html" with form=form %}
 
      </div>
 

	
 
      <div class="panel-footer">
 
        <input class="btn btn-primary" type="submit">
 
        <!-- todo: disable the checkout button if the form changes. -->
 
        <a class="btn btn-default" href="{% url "checkout" user.id %}">Check out cart and view invoice</a>
 
      </div>
 
    </form>
 
  </div>
 

	
 
  <div class="panel panel-default">
 
    <div class="panel-heading">
 
      <h3 class="panel-title">Apply voucher</h3>
 
    </div>
 

	
 
    <form method="POST">
 
      <div class="panel-body">
 
        {% csrf_token %}
 
        {% include "registrasion/form.html" with form=voucher_form %}
 
      </div>
 
      <div class="panel-footer">
 
        <input class="btn btn-primary" type="submit">
 
      </div>
 
    </form>
 
  </div>
 

	
 
{% endblock %}
vendor/registrasion/registrasion/templates/registrasion/badges.html
Show inline comments
 
new file 100644
 
{% extends "registrasion/badges_.html" %}
 
{% comment %}
 
  Blocks that you can override:
 

	
 
{% endcomment %}
vendor/registrasion/registrasion/templates/registrasion/badges_.html
Show inline comments
 
new file 100644
 
{% extends "registrasion/base.html" %}
 
{% load registrasion_tags %}
 

	
 
{% block title %}Generate badges zip{% endblock  %}
 
{% block heading %}Generate badges zip{% endblock %}
 

	
 
{% block content %}
 

	
 
  <form method="POST">
 
    {% csrf_token %}
 
    {% include "registrasion/form.html" with form=form %}
 
    <br/>
 
    <!-- TODO: include themed submit button -->
 
    <input type="submit">
 
  </form>
 

	
 
{% endblock %}
vendor/registrasion/registrasion/templates/registrasion/base.html
Show inline comments
 
new file 100644
 
{% extends "site_base.html" %}
 

	
 
{% block title %}{% endblock %}
 

	
 
{% block body_outer %}
 
  {% block body %}
 

	
 
    {% block heading_outer %}
 
      <h1>{% block heading %}{% endblock %}</h1>
 
    {% endblock %}
 

	
 
    {% block lede_outer %}
 
      <p class="lead">{% block lede %}{% endblock %}
 
    {% endblock %}
 

	
 
    {% block content_outer %}
 
      <div>
 
        {% block content %}
 

	
 
        {% endblock %}
 
      </div>
 
    {% endblock %}
 
  {% endblock %}
 
{% endblock %}
vendor/registrasion/registrasion/templates/registrasion/checkout_errors.html
Show inline comments
 
new file 100644
 
{% extends "registrasion/checkout_errors_.html" %}
 
{% comment %}
 
  Blocks that you can override:
 

	
 
  - fix_intro
 

	
 
{% endcomment %}
vendor/registrasion/registrasion/templates/registrasion/checkout_errors_.html
Show inline comments
 
new file 100644
 
{% extends "registrasion/base.html" %}
 
{% load registrasion_tags %}
 

	
 
{% block title %}Cannot check out{% endblock %}
 
{% block heading %}Oh No!{% endblock %}
 
{% block lede %}We can't check out your current selections because of the following errors:{% endblock %}
 

	
 
{% block content %}
 

	
 
  <div class="alert alert-danger">
 
    <ul>
 
      {% for error in error_list %}
 
        <li>{{ error.message }}</li>
 
      {% endfor %}
 
    </ul>
 
  </div>
 

	
 
  <div class="panel panel-danger">
 
    {% block fix_intro_outer %}
 
      <div class="panel-body">
 
        {% block fix_intro %}
 
          We can automatically try to remove products and vouchers that aren't
 
          available anymore, or you can return to the dashboard and try to fix
 
          it yourself.
 
        {% endblock %}
 
      </div>
 
    {% endblock %}
 

	
 
    <div class="panel-footer">
 
      <a class="btn btn-primary" href="{% url "checkout" %}?fix_errors=true">Try fixing these errors</a>
 
      <a class="btn btn-default" href="{% url "dashboard" %}">Return to dashboard</a>
 
    </div>
 
  </div>
 

	
 
{% endblock %}
vendor/registrasion/registrasion/templates/registrasion/credit_note.html
Show inline comments
 
new file 100644
 
{% extends "registrasion/credit_note_.html" %}
 
{% comment %}
 
  Blocks that you can override:
 
  - apply_to_invoice
 
  - cancellation_fee
 
  - refund_actions
 
  - manual_refund_actions
 

	
 
{% endcomment %}
vendor/registrasion/registrasion/templates/registrasion/credit_note_.html
Show inline comments
 
new file 100644
 
{% extends "registrasion/base.html" %}
 
{% load registrasion_tags %}
 

	
 
{% block title %}Credit Note{% endblock %}
 
{% block heading %}Credit Note{% endblock %}
 

	
 
{% block content %}
 

	
 
  {% block credit_note_info_outer %}
 
    <div>
 
      {% block credit_note_info %}
 
        {% with note_user=credit_note.invoice.user %}
 
          <dl>
 
            <dt>Number</dt><dd> {{ credit_note.id }}</dd>
 
            <dt>Attention</dt><dd> {{ credit_note.invoice.recipient }}</dd>
 
            <dt>User</dt>
 
            <dd> {{ credit_note.invoice.user.email }} ({{ credit_note.invoice.user.id}})</dd>
 
            <dt>Value</dt><dd> {{ credit_note.value }}</dd>
 
            <dt>Status</dt><dd> {{ credit_note.status }}</dd>
 
          </dl>
 
        {% endwith %}
 

	
 
        <p>
 
            This credit note was generated from funds excess from
 
            <a href="{% url "invoice" credit_note.invoice.id %}">
 
              invoice {{ credit_note.invoice.id }}</a>.
 
        </p>
 
      {% endblock %}
 
    </div>
 
  {% endblock %}
 

	
 
  {% if credit_note.is_unclaimed %}
 
    {% block staff_actions %}
 
      <form method="post" action="">
 
        {% csrf_token %}
 

	
 
        {% block apply_to_invoice_outer %}
 
          <div>
 
            {% block apply_to_invoice %}
 
              <h3>Apply to invoice</h3>
 
              <p>You can apply this credit note to an unpaid invoice.</p>
 

	
 
              <p>
 
                <strong>This credit note belongs to:</strong> {{ credit_note.invoice.user.email }} ({{ credit_note.invoice.user.id}}).
 
                You can apply this credit note to any user's invoice.
 
              </p>
 

	
 
              {% include "registrasion/form.html" with form=apply_form %}
 
              <!-- TODO: make this button less bootstrap-dependent -->
 
              <div class="form-actions">
 
                  <input class="btn btn-primary" type="submit" value="Apply to invoice" />
 
              </div>
 
            {% endblock %}
 
          </div>
 
        {% endblock %}
 

	
 
        {% block cancellation_fee_outer %}
 
          <div>
 
            {% block cancellation_fee %}
 
              <h3>Generate cancellation fee</h3>
 
              <p>You can generate an invoice for a cancellation fee, resulting in an invoice
 
                and a new credit note.
 
              </p>
 
            {% endblock %}
 
          </div>
 
        {% endblock %}
 

	
 
        {% include "registrasion/form.html" with form=cancellation_fee_form %}
 
        <!-- TODO: make this button less bootstrap-dependent -->
 
        <div class="form-actions">
 
            <input class="btn btn-primary" type="submit" value="Generate fee" />
 
        </div>
 

	
 
        {% block refund_actions_outer %}
 
          <div>
 
            {% block refund_actions %}
 
              {% with credit_note_id=credit_note.id %}
 
                {% include_if_exists "registrasion/stripe/link_to_refunds.html" %}
 
              {% endwith %}
 
            {% endblock %}
 
          </div>
 
        {% endblock %}
 

	
 
        {% block manual_refund_actions_outer %}
 
          <div>
 
            {% block manual_refund_actions %}
 
              <h3>Manual refund</h3>
 
              <p>You can mark this credit note as refunded, and handle the refund manually.
 
              </p>
 

	
 
              {% include "registrasion/form.html" with form=refund_form %}
 
              <!-- TODO: make this button less bootstrap-dependent -->
 
              <div class="form-actions">
 
                  <input class="btn btn-primary" type="submit" value="Mark as refunded" />
 
              </div>
 
            {% endblock %}
 
          </div>
 
        {% endblock %}
 
      </form>
 
    {% endblock %}
 
  {% endif %}
 

	
 
{% endblock %}
vendor/registrasion/registrasion/templates/registrasion/dashboard_widget.html
Show inline comments
 
new file 100644
 
{% extends "registrasion/dashboard_widget_.html" %}
 

	
 
{% comment %}
 
  Blocks that you can override:
 

	
 
  - heading_actions
 
  - heading
 
  - panel_content
 
  - credit
 

	
 
{% endcomment %}
vendor/registrasion/registrasion/templates/registrasion/dashboard_widget_.html
Show inline comments
 
new file 100644
 
{% load i18n %}
 
{% load registrasion_tags %}
 

	
 
{% sold_out_and_unregistered as sold_out %}
 

	
 
<div class="panel panel-default">
 
  <div class="panel-heading">
 
    {% block heading_actions_outer %}
 
      <div class="pull-right">
 
        {% block heading_actions %}
 
          {% if not user.attendee.completed_registration %}
 

	
 
            {% if not sold_out %}
 
              <a href="{% url "guided_registration" %}" class="btn btn-xs btn-default">
 
                  <i class="fa fa-plus-sign"></i> Register for the conference
 
              </a>
 
            {% endif %}
 

	
 
          {% else %}
 
            <a href="{% url "attendee_edit" %}" class="btn btn-xs btn-default">
 
                <i class="fa fa-pencil"></i> Edit your attendee profile
 
            </a>
 

	
 
            {% items_pending as pending %}
 
            {% if pending %}
 
              <a href="{% url "checkout" %}" class="btn btn-xs btn-default">
 
                  <i class="fa fa-credit-card"></i> Check out and pay
 
              </a>
 
            {% endif %}
 

	
 
          {% endif %}
 

	
 
          <a href="{% url "voucher_code" %}" class="btn btn-xs btn-default">
 
              <i class="fa fa-heart"></i> Enter a voucher code
 
          </a>
 

	
 
          {% if user.is_staff %}
 

	
 
            <a href="{% url "reports_list" %}" class="btn btn-xs btn-default">
 
              <i class="fa fa-dashboard"></i> View reports</a>
 

	
 
          {% endif %}
 
        {% endblock %}
 
      </div>
 
    {% endblock %}
 

	
 
    {% block heading_outer %}
 
      <h3 class="panel-title">
 
        <i class="fa fa-ticket"></i>
 
        {% block heading %}
 
          {% trans "Registration" %}
 
        {% endblock %}
 
      </h3>
 
    {% endblock %}
 

	
 
  </div>
 

	
 
  {% block panel_content_outer %}
 
    <div class="panel-body">
 
      {% block panel_content %}
 

	
 
        {% if not user.attendee.completed_registration %}
 

	
 
          {% if not sold_out %}
 
            {% block begin_registration_outer %}
 
              <p>
 
                {% block begin_registration %}
 
                  To attend the conference, you must purchase a ticket. <a href="{% url "guided_registration" %}">Use our registration form to purchase your ticket</a>.
 
                {% endblock %}
 
              </p>
 
            {% endblock %}
 
          {% else %}
 
            {% block sold_out_outer %}
 
              <p>
 
                {% block sold_out %}
 
                  There are no tickets available to the general public. If you have a voucher code, you can <a href="{% url "voucher_code" %}">enter that voucher code</a>, which may unlock tickets for you.
 
                {% endblock %}
 
              </p>
 
            {% endblock %}
 
          {% endif %}
 

	
 
        {% else %}
 

	
 
          {% items_pending as pending %}
 
          {% if pending %}
 
            <h4>Items pending payment</h4>
 
            {% include "registrasion/snippets/items_list.html" with items=pending %}
 
            <p><a href="{% url "checkout" %}" class="btn btn-xs btn-default">
 
                <i class="fa fa-credit-card"></i>
 
                Check out and pay for these items.</a></p>
 
          {% endif %}
 

	
 
          {% items_purchased as purchased %}
 
          {% if purchased %}
 
            <h4>Paid items</h4>
 
            {% include "registrasion/snippets/items_list.html" with items=purchased %}
 
          {% endif %}
 

	
 
          <h4>Add/Update items</h4>
 
          {% available_categories as categories %}
 
          {% include "registrasion/snippets/category_list.html" with categories=categories %}
 

	
 
          {% invoices as invoices %}
 
          {% if invoices %}
 
          <h4>Invoices</h4>
 
            <ul>
 
              {% for invoice in invoices %}
 
                {% if not invoice.is_void %}
 
                  <li>
 
                      <a href="{% url "invoice" invoice.id %}">Invoice {{ invoice.id }}</a>
 
                      - ${{ invoice.value }} ({{ invoice.get_status_display }})
 
                  </li>
 
                {% endif %}
 
              {% endfor %}
 
            </ul>
 
          {% endif %}
 

	
 
          {% available_credit as credit %}
 
          {% if credit %}
 
            {% block available_credit_outer %}
 
              <p>
 
                {% block available_credit %}
 
                  You have ${{ credit }} leftover from refunded invoices. This credit will be automatically applied to new invoices. Contact the conference organisers to
 
                  for a refund to your original payment source.
 
                {% endblock %}
 
              </p>
 
            {% endblock %}
 

	
 
          {% endif %}
 
        {% endif %}
 
      {% endblock %}
 

	
 
    </div>
 
  {% endblock %}
 
</div>
vendor/registrasion/registrasion/templates/registrasion/emails/invoice_created/message.html
Show inline comments
 
new file 100644
 
{% load i18n %}
 

	
 
{% if invoice.is_unpaid %}
 

	
 
  {% with "http://"|add:current_site as current_host %}
 
    {% include "registrasion/invoice/unpaid_notice.html" %}
 
  {% endwith %}
 

	
 
  <hr />
 

	
 
{% endif %}
 

	
 
{% include "registrasion/invoice/details.html" %}
vendor/registrasion/registrasion/templates/registrasion/emails/invoice_created/subject.txt
Show inline comments
 
new file 100644
 
{% load i18n %}Invoice {{ invoice.id }}
vendor/registrasion/registrasion/templates/registrasion/emails/invoice_updated/message.html
Show inline comments
 
new file 100644
 
{% include "registrasion/emails/invoice_created/message.html" %}
vendor/registrasion/registrasion/templates/registrasion/emails/invoice_updated/subject.txt
Show inline comments
 
new file 100644
 
{% load i18n %}{{ invoice.get_status_display }} -- Invoice {{ invoice.id }}
vendor/registrasion/registrasion/templates/registrasion/form.html
Show inline comments
 
new file 100644
 
{% comment %}
 
  form.html is included whenever there is a form in one of our base templates.
 

	
 
  To override how your form is rendered, just override form.html. The form is
 
  included as `form`.
 

	
 
{% endcomment %}
 

	
 
{{ form }}
vendor/registrasion/registrasion/templates/registrasion/guided_registration.html
Show inline comments
 
new file 100644
 
{% extends "registrasion/guided_registration_.html" %}
 
{% comment %}
 
  Blocks that you can override:
 

	
 
  - discounts_intro
 
  - products_intro
 

	
 
{% endcomment %}
vendor/registrasion/registrasion/templates/registrasion/guided_registration_.html
Show inline comments
 
new file 100644
 
{% extends "registrasion/base.html" %}
 

	
 
{% block title %}Conference registrasion{% endblock %}
 
{% block heading %}Conference registration{% endblock %}
 
{% block lede %}Step {{ current_step }} of {{ total_steps }} &ndash; {{ title }}{% endblock %}
 

	
 
{% block content %}
 

	
 
  <form method="post" action="">
 
    {% csrf_token %}
 

	
 
    {% for section in sections %}
 
      <div class="panel panel-default">
 
        <div class="panel-heading">
 
          <h3 class="panel-title">{{ section.title }}</h3>
 
        </div>
 

	
 
        <div class="panel-body">
 

	
 
          {% if section.description %}
 
            <div class="well">
 
              {{ section.description|safe }}
 
            </div>
 
          {% endif %}
 

	
 
          {% if section.discounts %}
 
            <div class="panel panel-info">
 
              {% include "registrasion/snippets/discounts_list.html" with discounts=section.discounts %}
 
              {% block discounts_intro_outer %}
 
                <div class="panel-footer">
 
                  {% block discounts_intro %}
 
                    The best available discounts will be automatically applied
 
                    to any selections you make.
 
                  {% endblock %}
 
                </div>
 
              {% endblock %}
 

	
 
            </div>
 
          {% endif %}
 

	
 
          {% include "registrasion/form.html" with form=section.form %}
 
        </div>
 
      </div>
 
    {% endfor %}
 

	
 
    <div class="form-actions">
 
      {% if current_step > 1 %}
 
        <a class="btn btn-default" href="{% url "guided_registration" current_step|add:"-1" %}">Back</a>
 
      {% endif %}
 
      <input class="btn btn-primary" type="submit" value="Next" />
 
    </div>
 
  </form>
 

	
 

	
 
{% endblock %}
vendor/registrasion/registrasion/templates/registrasion/invoice.html
Show inline comments
 
new file 100644
 
{% extends "registrasion/invoice_.html" %}
 
{% comment %}
 
  Blocks that you can override:
 

	
 
  - payment_actions
 
  - refund_actions
 

	
 
  This template includes two sub-templates:
 

	
 
  - registrasion/invoice/details.html
 
  - registrasion/invoice/unpaid_notice.html
 

	
 

	
 
{% endcomment %}
vendor/registrasion/registrasion/templates/registrasion/invoice/details.html
Show inline comments
 
new file 100644
 
{% extends "registrasion/invoice/details_.html" %}
 
{% comment %}
 
  Blocks that you can override:
 

	
 
  - heading
 
  - subheading
 
  - invoice_intro
 
  - extra_line_items
 
  - contact_info
 

	
 
{% endcomment %}
vendor/registrasion/registrasion/templates/registrasion/invoice/details_.html
Show inline comments
 
new file 100644
 
{% load registrasion_tags %}
 

	
 
<div class="panel panel-primary">
 
  <div class="panel-heading">
 
    {% block heading_outer %}
 
      <h2>{% block heading %}Invoice{% endblock %}</h2>
 
    {% endblock %}
 
    {% block subheading_outer %}
 
      <div>{% block subheading %}Subtitle{% endblock %}</div>
 
    {% endblock %}
 
  </div>
 

	
 
  {% with invoice_user=invoice.cart.user %}
 
    <table class="table">
 
      <tr><th>Number</th><td> {{ invoice.id }}</td></tr>
 
      <tr><th>Status</th><td> {{ invoice.get_status_display }}</td></tr>
 
      <tr><th>Issue date</th><td> {{ invoice.issue_time|date:"DATE_FORMAT" }}</td></tr>
 

	
 
      {% if not invoice.is_void %}
 
        <tr><th>Due</th><td> {{ invoice.due_time|date:"DATETIME_FORMAT"}}</td></tr>
 
      {% endif %}
 

	
 
      <tr><th>Recipient</th><td> {{ invoice.recipient|linebreaksbr}}</td></tr>
 
    </table>
 
  {% endwith %}
 

	
 
  <div class="panel-body">
 
    {% block invoice_intro_outer %}
 
      <div class="alert alert-info">
 
        {% block invoice_intro %}
 
          This invoice has been issued as a result of an application to attend (conference name).
 
        {% endblock %}
 
      </div>
 
    {% endblock %}
 

	
 
    <div class="panel panel-default">
 
      <table class="table table-striped">
 
        <tr>
 
          <th>Description</th>
 
          <th class="text-right">Quantity</th>
 
          <th class="text-right">Price/Unit</th>
 
          <th class="text-right">Total</th>
 
        </tr>
 
        {% for line_item in invoice.lineitem_set.all %}
 
          <tr>
 
            <td>{{ line_item.description }}</td>
 
            <td class="text-right">{{ line_item.quantity }}</td>
 
            <td class="text-right">${{ line_item.price }}</td>
 
            <td class="text-right">${{ line_item.total_price }}</td>
 
          </tr>
 
        {% endfor %}
 

	
 
        {% block extra_line_items %}
 

	
 
        {% endblock %}
 

	
 
        <tr>
 
          <th colspan="3">TOTAL</th>
 
          <td class="text-right">${{ invoice.value }}</td>
 
        </tr>
 
      </table>
 
    </div>
 

	
 
    <div class="panel panel-info">
 
      <div class="panel-heading">
 
        <h3 class="panel-title">Balance</h3>
 
      </div>
 
      <table class="table table-striped">
 
        <tr>
 
          <td colspan="3">Total payments:</td>
 
          <td class="text-right">${{ invoice.total_payments }}</td>
 
        </tr>
 
        <tr>
 
          <td colspan="3">Balance due:</td>
 
          <td class="text-right">${{ invoice.balance_due }}</td>
 
        </tr>
 
      </table>
 
    </div>
 

	
 
    {% if invoice.paymentbase_set.all %}
 
      <div class="panel panel-info">
 
        <div class="panel-heading">
 
          <h4 class="panel-title">Payments received</h4>
 
        </div>
 
        {% include "registrasion/snippets/payment_list.html" with payments=invoice.paymentbase_set.all %}
 
      </div>
 
    {% endif %}
 

	
 
    <div class="panel panel-default">
 
      {% block contact_info_heading_outer %}
 
        <div class="panel-heading">
 
          <h3 class="panel-title">
 
            {% block contact_info_heading %}
 
              Contact Information
 
            {% endblock %}
 
          </h3>
 
        </div>
 
      {% endblock %}
 

	
 
      {% block contact_info_outer %}
 
        <div class="panel-body">
 
          <p>
 
            {% block contact_info %}
 
              Direct inquiries to (EMAIL ADDRESS)
 
            {% endblock %}
 
          </p>
 
        </div>
 
      {% endblock %}
 
    </div>
 
  </div>
 
</div>
vendor/registrasion/registrasion/templates/registrasion/invoice/unpaid_notice.html
Show inline comments
 
new file 100644
 
<p><strong>NOTICE:</strong> The below invoice is automatically generated, and will be voided if you amend your registration before payment, or if discounts or products contained in the invoice become unavailable. The items and discounts are only reserved until the invoice due time.</p>
 

	
 
{% url "invoice_access" invoice.user.attendee.access_code as access_url %}
 
{% url "invoice" invoice.id invoice.user.attendee.access_code as invoice_url %}
 

	
 
<p>You can send the following links to your accounts department to pay for your registration:</p>
 

	
 
<ul>
 
  <li>{{ current_host|add:access_url|urlize }} &ndash; your most recent invoice</li>
 
  <li>{{ current_host|add:invoice_url|urlize }} &ndash; this invoice, even if it becomes void.</li>
 
</ul>
vendor/registrasion/registrasion/templates/registrasion/invoice_.html
Show inline comments
 
new file 100644
 
{% extends "registrasion/base.html" %}
 
{% load bootstrap %}
 
{% load registrasion_tags %}
 

	
 
{% block content %}
 

	
 
  {% if invoice.is_unpaid %}
 

	
 
    <div class="alert alert-warning">
 
    {% with scheme=request.scheme host=request.get_host %}
 
      {% with scheme|add:"://"|add:host as current_host %}
 
        {% include "registrasion/invoice/unpaid_notice.html" with current_host=current_host %}
 
      {% endwith %}
 
    {% endwith %}
 
    </div>
 

	
 
    <div class="panel panel-default">
 

	
 
      {% block payment_actions_outer %}
 
        <div class="panel-footer">
 
          {% block payment_actions %}
 

	
 
            {% with invoice_id=invoice.id access_code=invoice.user.attendee.access_code %}
 
              {% include_if_exists "registrasion/stripe/link_to_payment.html" %}
 
            {% endwith %}
 

	
 
            {% if user.is_staff %}
 
              <a class="btn btn-default" href="{% url "manual_payment" invoice.id %}">Apply manual payment</a>
 
            {% endif %}
 
          {% endblock %}
 
          <a class="btn btn-default" href="{% url "dashboard" %}">Return to dashboard</a>
 

	
 
        </div>
 
      {% endblock %}
 
    </div>
 

	
 
  {% elif invoice.is_paid %}
 

	
 
    {% if user.is_staff %}
 
      {% block refund_actions_outer %}
 
        <div class="panel-footer">
 
          {% block refund_actions %}
 
            <a class="btn btn-primary" href="{% url "refund" invoice.id %}">Refund by issuing credit note</a>
 
            <a class="btn btn-default" href="{% url "manual_payment" invoice.id %}">Apply manual payment/refund</a>
 
            <a class="btn btn-default" href="{% url "dashboard" %}">Return to dashboard</a>
 
          {% endblock %}
 
        </div>
 
      {% endblock %}
 
    {% endif %}
 

	
 
  {% endif %}
 

	
 
  {% include "registrasion/invoice/details.html" %}
 

	
 
{% endblock %}
vendor/registrasion/registrasion/templates/registrasion/invoice_mailout.html
Show inline comments
 
new file 100644
 
{% extends "registrasion/invoice_mailout_.html" %}
 
{% comment %}
 
  Blocks that you can override:
 

	
 
{% endcomment %}
vendor/registrasion/registrasion/templates/registrasion/invoice_mailout_.html
Show inline comments
 
new file 100644
 
{% extends "registrasion/base.html" %}
 
{% load registrasion_tags %}
 

	
 
{% block title %}Send reminder e-mails{% endblock %}
 
{% block heading %}Send reminder e-mails{% endblock %}
 

	
 
{% block content %}
 

	
 
<form method="POST">
 
  {% csrf_token %}
 
  {% include "registrasion/form.html" with form=form %}
 
  <br/>
 
  <!-- TODO: include themed submit button -->
 
  <input type="submit">
 
</form>
 

	
 
{% if emails %}
 
  <h3>Previews</h3>
 

	
 
  {% for email in emails %}
 
    <dl>
 
      <dt>From</dt><dd>{{ email.from_email }}</dd>
 
      <dt>To</dt><dd>{{ email.recipient_list|join:", " }}</dd>
 
      <dt>Subject</dt><dd>{{ email.subject }}</dd>
 
      <dt>Body</dt><dd><pre>{{ email.body }}</pre></dd>
 
    </dl>
 
    <hr />
 
  {% endfor %}
 

	
 
{% endif %}
 

	
 
{% endblock %}
vendor/registrasion/registrasion/templates/registrasion/manual_payment.html
Show inline comments
 
new file 100644
 
{% extends "registrasion/manual_payment_.html" %}
 
{% comment %}
 
  Blocks that you can override:
 

	
 
{% endcomment %}
vendor/registrasion/registrasion/templates/registrasion/manual_payment_.html
Show inline comments
 
new file 100644
 
{% extends "registrasion/base.html" %}
 

	
 
{% block title %}Apply manual payment{% endblock %}
 
{% block heading %}Apply manual payment{% endblock %}
 
{% block lede %}Enter a reference and the amount of the payment. A refund is a negative
 
payment.{% endblock %}
 

	
 
{% block content %}
 

	
 
  <dl>
 
    <dt>Invoice ID:</dt>
 
    <dd>{{ invoice.id }}</dd>
 
    <dt>Recipient</dt>
 
    <dd>{{ invoice.recipient }}</dd>  
 
  </dl>
 

	
 
  <form method="post" action="">
 
    {% csrf_token %}
 

	
 
    {% include "registrasion/form.html" with form=form %}
 

	
 
    <!-- TODO: make this button less bootstrap-dependent -->
 
    <div class="form-actions">
 
      <input class="btn btn-primary" type="submit" value="Apply payment" />
 
      <a class="btn btn-default" href="{% url "invoice" invoice.id %}">Return to invoice</a>
 
    </div>
 
  </form>
 

	
 
  <h2>Past payments</h2>
 

	
 
  {% include "registrasion/snippets/payment_list.html" with payments=invoice.paymentbase_set.all %}
 

	
 
{% endblock %}
vendor/registrasion/registrasion/templates/registrasion/product_category.html
Show inline comments
 
new file 100644
 
{% extends "registrasion/product_category_.html" %}
 
{% comment %}
 
  Blocks that you can override:
 

	
 
  - paid_items_intro
 
  - discounts_intro
 
  - products_intro
 

	
 
{% endcomment %}
vendor/registrasion/registrasion/templates/registrasion/product_category_.html
Show inline comments
 
new file 100644
 
{% extends "registrasion/base.html" %}
 
{% load registrasion_tags %}
 

	
 
{% block title %}Select {{ category.name }} products{% endblock %}
 
{% block heading %}Select {{ category.name }} products{% endblock %}
 

	
 
{% block content %}
 

	
 
  <form method="post" action="">
 

	
 
    {% csrf_token %}
 

	
 
    <div class="panel panel-default">
 
      <div class="panel-heading">
 
        <h3 class="panel-title">Enter voucher code</h3>
 
      </div>
 
      <div class="panel-body">
 
        {% include "registrasion/form.html" with form=voucher_form %}
 
        <!-- TODO: make this button less bootstrap-dependent -->
 
        <div class="form-actions">
 
            <input class="btn btn-primary" type="submit" value="Add voucher" />
 
        </div>
 
      </div>
 
    </div>
 

	
 
    <div class="panel panel-primary">
 
      <div class="panel-heading">
 
        <h3 class="panel-title">{{ category.name }}</h3>
 
      </div>
 

	
 
      <div class="panel-body">
 

	
 
        {% block products_intro_outer %}
 
          <div class="well">
 
            {% block products_intro %}
 
              {{ category.description }}
 
            {% endblock %}
 
          </div>
 
        {% endblock %}
 

	
 
        {% items_purchased category as items %}
 
        {% if items %}
 
          <div class="panel panel-info">
 
            {% block paid_items_intro_outer %}
 
              <div class="panel-heading">
 
                {% block paid_items_intro %}
 
                  You have already paid for the following items:
 
                {% endblock %}
 
              </div>
 
            {% endblock %}
 
            {% include "registrasion/snippets/items_list.html" with items=items ul_class="list-group" li_class="list-group-item" %}
 
          </div>
 
        {% endif %}
 

	
 
        {% if discounts %}
 
          <div class="panel panel-info">
 
            {% include "registrasion/snippets/discounts_list.html" with discounts=discounts %}
 
            {% block discounts_intro_outer %}
 
              <div class="panel-footer">
 
                {% block discounts_intro %}
 
                  The best available discounts will be automatically applied to any selections you make.
 
                {% endblock %}
 
              </div>
 
            {% endblock %}
 
          </div>
 
        {% endif %}
 

	
 
        {% include "registrasion/form.html" with form=form %}
 

	
 
      </div>
 

	
 
      <div class="panel-footer">
 
        <input class="btn btn-primary" type="submit" value="Add to cart" />
 
        <a href="{% url "dashboard" %}" class="btn btn-default">Return to dashboard</a>
 
      </div>
 
    </div>
 

	
 
  </form>
 

	
 
{% endblock %}
vendor/registrasion/registrasion/templates/registrasion/profile_form.html
Show inline comments
 
new file 100644
 
{% extends "registrasion/profile_form_.html" %}
 
{% comment %}
 
  Blocks that you can override:
 

	
 
{% endcomment %}
vendor/registrasion/registrasion/templates/registrasion/profile_form_.html
Show inline comments
 
new file 100644
 
{% extends "registrasion/base.html" %}
 

	
 
{% block title %}Your profile{% endblock %}
 
{% block heading %}Your profile{% endblock %}
 
{% block lede %}
 
  These details will appear on your badge, your invoices, and will be used
 
  to order catered food at the conference.
 
{% endblock %}
 

	
 
{% block content %}
 

	
 
  <form method="post" action="">
 
    {% csrf_token %}
 

	
 
    <div>
 
      {% include "registrasion/form.html" with form=form %}
 
    </div>
 

	
 
    <!-- TODO: make this button less bootstrap-dependent -->
 
    <div class="form-actions">
 
        <input class="btn btn-primary" type="submit" value="Save" />
 
    </div>
 
  </form>
 

	
 
{% endblock %}
vendor/registrasion/registrasion/templates/registrasion/report.html
Show inline comments
 
new file 100644
 
{% extends "registrasion/report_.html" %}
 
{% comment %}
 
  Blocks that you can override:
 

	
 
{% endcomment %}
vendor/registrasion/registrasion/templates/registrasion/report_.html
Show inline comments
 
new file 100644
 
{% extends "registrasion/base.html" %}
 
{% load registrasion_tags %}
 

	
 
{% block title %}{{ title }}{% endblock %}
 
{% block heading %}{{ title }}{% endblock %}
 

	
 
{% block content %}
 

	
 
  {% if form %}
 
    <div class="panel panel-primary">
 
      <form method="GET">
 

	
 
        <div class="panel-body">
 
            {% include "registrasion/form.html" with form=form %}
 
        </div>
 
        <div class="panel-footer">
 
          <input class="btn btn-primary" type="submit">
 
          <a class="btn btn-default" href="{% url "reports_list" %}">Back to reports list</a>
 
        </div>
 

	
 
      </form>
 
    </div>
 
  {% endif %}
 

	
 
  {% for report in reports %}
 

	
 
    <div class="panel panel-default">
 
      <div class="panel-heading">
 

	
 
        <div class="btn-group pull-right">
 
          <a class="btn btn-default btn-xs" href="{% report_as_csv forloop.counter0 %}">View as CSV</a>
 
        </div>
 

	
 
        <h3 class="panel-title">{{ report.title }}</h3>
 
      </div>
 

	
 
      <table class="table table-striped">
 
        <tr>
 
          {% for heading in report.headings %}
 
            <th>{{ heading }}</th>
 
          {% endfor %}
 
        </tr>
 
        {% for line in report.rows %}
 
          <tr>
 
            {% for item in line %}
 
              <td>
 
                {{ item|safe }}
 
              </td>
 
            {% endfor %}
 
          </tr>
 
        {% endfor %}
 
      </table>
 
    </div>
 

	
 
  {% endfor %}
 

	
 
  <div class="form-actions">
 
    <a class="btn btn-default" href="{% url "reports_list" %}">Back to reports list</a>
 
  </div>
 

	
 

	
 
{% endblock %}
vendor/registrasion/registrasion/templates/registrasion/reports_list.html
Show inline comments
 
new file 100644
 
{% extends "registrasion/reports_list_.html" %}
 
{% comment %}
 
  Blocks that you can override:
 

	
 
{% endcomment %}
vendor/registrasion/registrasion/templates/registrasion/reports_list_.html
Show inline comments
 
new file 100644
 
{% extends "registrasion/base.html" %}
 
{% load registrasion_tags %}
 

	
 
{% block title %}Registration reports{% endblock %}
 
{% block heading %}Registration reports{% endblock %}
 

	
 
{% block content %}
 

	
 
  <table class="table table-striped">
 
    {% for report in reports %}
 
      <tr>
 
        <td>
 
          <a href="{{ report.url }}">{{ report.name }}</a>
 
        </td>
 
        <td>
 
          {{ report.description }}
 
        </td>
 
      </tr>
 
    {% endfor %}
 
  </table>
 

	
 
{% endblock %}
vendor/registrasion/registrasion/templates/registrasion/review.html
Show inline comments
 
new file 100644
 
{% extends "registrasion/review_.html" %}
 
{% comment %}
 
  Blocks that you can override:
 
  - selected_items_intro
 
  - purchased_items_intro
 
  - add_to_selection_intro
 
  - missing_categories_intro
 
  - non_missing_categories_intro
 
  - what_next_intro
 
{% endcomment %}
vendor/registrasion/registrasion/templates/registrasion/review_.html
Show inline comments
 
new file 100644
 
{% extends "registrasion/base.html" %}
 
{% load registrasion_tags %}
 

	
 
{% block title %}Review your selection{% endblock %}
 
{% block heading %}Review your selection{% endblock %}
 

	
 
{% block content %}
 

	
 
  {% items_pending as pending %}
 
  {% if pending %}
 

	
 
    <div class="panel panel-default">
 
      <div class="panel-heading">
 
        <h3 class="panel-title">Current selection</h3>
 
      </div>
 

	
 
      <div class="panel-body">
 
        {% block selected_items_intro_outer %}
 
          {% block selected_items_intro %}
 
            You've selected the following items, which will be in your invoice
 
            when you check out:
 
          {% endblock %}
 
        {% endblock %}
 
      </div>
 

	
 
      {% include "registrasion/snippets/items_list.html" with items=pending ul_class="list-group" li_class="list-group-item" %}
 

	
 
    </div>
 

	
 
    {% items_purchased as purchased %}
 
    {% if purchased %}
 
      <div class="panel panel-default">
 
        <div class="panel-heading">
 
          <h3 class="panel-title">Already purchased</h3>
 
        </div>
 
        <div class="panel-body">
 
            <div>
 
              {% block purchased_items_intro_outer %}
 
                <p>
 
                  {% block purchased_items_intro %}
 
                    You've already paid for the following items:
 
                  {% endblock %}
 
                </p>
 
              {% endblock %}
 
              {% include "registrasion/snippets/items_list.html" with items=purchased suffix="(PAID)" ul_class="list-group" li_class="list-group-item" %}
 
            </div>
 
        </div>
 
      </div>
 
    {% endif %}
 

	
 
    <div class="panel panel-default">
 
      <div class="panel-heading">
 
        <h3 class="panel-title">Add to your selection</h3>
 
      </div>
 

	
 
      <div class="panel-body">
 

	
 
        {% block add_to_selection_intro_outer %}
 
          <p>{% block add_to_selection_intro %}
 
            You can add these items now, or you can come back and add them in a
 
            later purchase.
 
          {% endblock %}</p>
 
        {% endblock %}
 

	
 
        {% missing_categories as missing %}
 
        {% if missing %}
 
          <div class="alert alert-warning">
 
            {% block missing_categories_intro_outer %}
 
              <p>
 
                {% block missing_categories_intro %}
 
                  You have <em>not</em> selected any items from the following
 
                  categories. Even if your ticket includes complimentary tickets
 
                  to social events, or t-shirts, you must still add them to your
 
                  selection.
 
                {% endblock %}
 
              </p>
 
            {% endblock %}
 

	
 
            {% include "registrasion/snippets/category_list.html" with categories=missing %}
 
          </div>
 
        {% endif %}
 

	
 
        {% block non_missing_categories_intro_outer %}
 
        <p>
 
          <strong>
 
            {% block non_missing_categories_intro %}
 
              You can also change your selection from these categories:
 
            {% endblock %}
 
          </strong>
 
        </p>
 
        {% endblock %}
 

	
 
        {% available_categories as available %}
 
        {% include "registrasion/snippets/category_list.html" with categories=available exclude=missing %}
 
      </div>
 
    </div>
 

	
 
    <div class="panel panel-default">
 

	
 
      <div class="panel-heading">
 
        <h3 class="panel-title">What next?</h3>
 
      </div>
 

	
 
      <div class="panel-body">
 

	
 
        {% block what_next_intro_outer %}
 
            {% block what_next_intro %}
 
              You can either check out and pay for your selections, or return to
 
              the dashboard.
 
            {% endblock %}
 
          </p>
 
        {% endblock %}
 

	
 
        <div class="form-actions">
 
          <a class="btn btn-primary" href="{% url "checkout" %}">
 
            <i class="fa fa-credit-card"></i> Check out and pay
 
          </a>
 
          <a class="btn btn-default" href="{% url "dashboard" %}">Return to dashboard</a>
 
        </div>
 
      </div>
 
    </div>
 

	
 
  {% else %}
 

	
 
    <div>
 

	
 
      {% block nothing_to_do_intro_outer %}
 
        <p>
 
          {% block nothing_to_do_intro %}
 
            You have no items that need to be paid.
 
          {% endblock %}
 
        </p>
 
      {% endblock %}
 

	
 
      <div class="form-actions">
 
        <a class="btn btn-default" href="{% url "dashboard" %}">Return to dashboard</a>
 
      </div>
 

	
 
    </div>
 

	
 
  {% endif %}
 

	
 
{% endblock %}
vendor/registrasion/registrasion/templates/registrasion/snippets/category_list.html
Show inline comments
 
new file 100644
 
<ul class="{{ ul_class }}">
 
  {% for category in categories %}
 
    {% if not category in exclude %}
 
      <li class="{{ li_class }}"><a href="{% url "product_category" category.id %}">{{ category.name }}</a></li>
 
    {% endif %}
 
  {% endfor %}
 
</ul>
vendor/registrasion/registrasion/templates/registrasion/snippets/discounts_list.html
Show inline comments
 
new file 100644
 
{% if discounts %}
 

	
 
  {% regroup discounts by discount.description as discounts_grouped %}
 

	
 
  <table class="table">
 
    {% for discount_type in discounts_grouped %}
 
      <tr>
 
        <th rowspan="{{ discount_type.list|length }}">{{ discount_type.grouper }}</th>
 

	
 
        {% for discount in discount_type.list %}
 
          {% if not forloop.first %}
 
            </tr><tr>
 
          {% endif %}
 
          <td>
 
            {{ discount.quantity }} &times; {{ discount.clause }}
 
          </td>
 
        {% endfor %}
 
    </tr>
 
    {% endfor %}
 
  </table>
 

	
 
{% endif %}
vendor/registrasion/registrasion/templates/registrasion/snippets/items_list.html
Show inline comments
 
new file 100644
 
{% if items %}
 
  <ul class="{{ ul_class }}">
 
    {% for item in items %}
 
      <li class="{{ li_class }}">{{ item.quantity }} &times; {{ item.product }} {{ suffix }}</li>
 
    {% endfor %}
 
  </ul>
 
{% endif %}
vendor/registrasion/registrasion/templates/registrasion/snippets/payment_list.html
Show inline comments
 
new file 100644
 
{% if payments %}
 
  <table class="table table-striped">
 
    <tr>
 
      <th>Payment time</th>
 
      <th>Reference</th>
 
      <th>Amount</th>
 
    </tr>
 
    {% for payment in payments %}
 
      <tr>
 
        <td>{{payment.time}}</td>
 
        <td>{{payment.reference}}</td>
 
        <td>{{payment.amount}}</td>
 
      </tr>
 
    {% endfor %}
 
  </table>
 
{% endif %}
vendor/registrasion/registrasion/templates/registrasion/voucher_code.html
Show inline comments
 
new file 100644
 
{% extends "registrasion/voucher_code_.html" %}
 
{% comment %}
 
  Blocks that you can override:
 

	
 
{% endcomment %}
vendor/registrasion/registrasion/templates/registrasion/voucher_code_.html
Show inline comments
 
new file 100644
 
{% extends "registrasion/base.html" %}
 

	
 
{% block title %}Enter voucher code{% endblock %}
 
{% block heading %}Enter voucher code{% endblock %}
 
{% block lede %}
 
  If you have a voucher code, you can enter it here to get
 
  discounts on products, or unlock products that aren't otherwise
 
  available.
 
{% endblock %}
 

	
 
{% block content %}
 

	
 
  <form method="post" action="">
 
    {% csrf_token %}
 

	
 
    <div class="panel panel-primary">
 
      <div class="panel-body">
 
        {% include "registrasion/form.html" with form=voucher_form %}
 
      </div>
 

	
 
      <div class="panel-footer">
 
        <input class="btn btn-primary" type="submit" value="Apply voucher code" />
 
        <a href="{% url "dashboard" %}" class="btn btn-default">Back to dashboard</a>
 
      </div>
 
    </div>
 
  </form>
 

	
 
{% endblock %}
vendor/registrasion/registrasion/templatetags/__init__.py
Show inline comments
 
file renamed from vendor/registrasion/templatetags/__init__.py to vendor/registrasion/registrasion/templatetags/__init__.py
vendor/registrasion/registrasion/templatetags/registrasion_tags.py
Show inline comments
 
file renamed from vendor/registrasion/templatetags/registrasion_tags.py to vendor/registrasion/registrasion/templatetags/registrasion_tags.py
vendor/registrasion/registrasion/tests/__init__.py
Show inline comments
 
file renamed from vendor/registrasion/tests/__init__.py to vendor/registrasion/registrasion/tests/__init__.py
vendor/registrasion/registrasion/tests/controller_helpers.py
Show inline comments
 
file renamed from vendor/registrasion/tests/controller_helpers.py to vendor/registrasion/registrasion/tests/controller_helpers.py
vendor/registrasion/registrasion/tests/patches.py
Show inline comments
 
file renamed from vendor/registrasion/tests/patches.py to vendor/registrasion/registrasion/tests/patches.py
vendor/registrasion/registrasion/tests/test_batch.py
Show inline comments
 
file renamed from vendor/registrasion/tests/test_batch.py to vendor/registrasion/registrasion/tests/test_batch.py
vendor/registrasion/registrasion/tests/test_cart.py
Show inline comments
 
file renamed from vendor/registrasion/tests/test_cart.py to vendor/registrasion/registrasion/tests/test_cart.py
vendor/registrasion/registrasion/tests/test_ceilings.py
Show inline comments
 
file renamed from vendor/registrasion/tests/test_ceilings.py to vendor/registrasion/registrasion/tests/test_ceilings.py
vendor/registrasion/registrasion/tests/test_credit_note.py
Show inline comments
 
file renamed from vendor/registrasion/tests/test_credit_note.py to vendor/registrasion/registrasion/tests/test_credit_note.py
vendor/registrasion/registrasion/tests/test_discount.py
Show inline comments
 
file renamed from vendor/registrasion/tests/test_discount.py to vendor/registrasion/registrasion/tests/test_discount.py
vendor/registrasion/registrasion/tests/test_flag.py
Show inline comments
 
file renamed from vendor/registrasion/tests/test_flag.py to vendor/registrasion/registrasion/tests/test_flag.py
vendor/registrasion/registrasion/tests/test_group_member.py
Show inline comments
 
file renamed from vendor/registrasion/tests/test_group_member.py to vendor/registrasion/registrasion/tests/test_group_member.py
vendor/registrasion/registrasion/tests/test_helpers.py
Show inline comments
 
file renamed from vendor/registrasion/tests/test_helpers.py to vendor/registrasion/registrasion/tests/test_helpers.py
vendor/registrasion/registrasion/tests/test_invoice.py
Show inline comments
 
file renamed from vendor/registrasion/tests/test_invoice.py to vendor/registrasion/registrasion/tests/test_invoice.py
vendor/registrasion/registrasion/tests/test_refund.py
Show inline comments
 
file renamed from vendor/registrasion/tests/test_refund.py to vendor/registrasion/registrasion/tests/test_refund.py
vendor/registrasion/registrasion/tests/test_speaker.py
Show inline comments
 
file renamed from vendor/registrasion/tests/test_speaker.py to vendor/registrasion/registrasion/tests/test_speaker.py
vendor/registrasion/registrasion/tests/test_voucher.py
Show inline comments
 
file renamed from vendor/registrasion/tests/test_voucher.py to vendor/registrasion/registrasion/tests/test_voucher.py
vendor/registrasion/registrasion/urls.py
Show inline comments
 
file renamed from vendor/registrasion/urls.py to vendor/registrasion/registrasion/urls.py
vendor/registrasion/registrasion/util.py
Show inline comments
 
file renamed from vendor/registrasion/util.py to vendor/registrasion/registrasion/util.py
vendor/registrasion/registrasion/views.py
Show inline comments
 
file renamed from vendor/registrasion/views.py to vendor/registrasion/registrasion/views.py
vendor/registrasion/requirements/base.txt
Show inline comments
 
new file 100644
 
django-nested-admin==2.2.6
 
#symposion==1.0b2.dev3
vendor/registrasion/requirements/dependencies.txt
Show inline comments
 
new file 100644
 
https://github.com/pinax/symposion/tarball/ad81810#egg=symposion
vendor/registrasion/requirements/docs.txt
Show inline comments
 
new file 100644
 
# requirements needed to build the docs
 

	
 
Sphinx==1.4.1
 
sphinx-rtd-theme==0.1.9
vendor/registrasion/requirements/extern.txt
Show inline comments
 
new file 100644
 
# 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@ad81810#egg=SymposionMaster-1.0.0b3-dev # Symposion lives on git at the moment
vendor/registrasion/setup.cfg
Show inline comments
 
new file 100644
 
[flake8]
 
exclude = registrasion/migrations/*, build/*, docs/*, dist/*
vendor/registrasion/setup.py
Show inline comments
 
new file 100644
 
#!/usr/bin/env python
 
import os
 
from setuptools import setup, find_packages
 

	
 
import registrasion
 

	
 

	
 
def read_file(filename):
 
    """Read a file into a string."""
 
    path = os.path.abspath(os.path.dirname(__file__))
 
    filepath = os.path.join(path, filename)
 
    try:
 
        return open(filepath).read()
 
    except IOError:
 
        return ''
 

	
 

	
 
setup(
 
    name="registrasion",
 
    author="Christopher Neugebauer",
 
    author_email="_@chrisjrn.com",
 
    version=registrasion.__version__,
 
    description="A registration app for the Symposion conference management "
 
                "system.",
 
    url="http://github.com/chrisjrn/registrasion/",
 
    packages=find_packages(),
 
    include_package_data=True,
 
    classifiers=(
 
        "Development Status :: 3 - Alpha",
 
        "Programming Language :: Python",
 
        "Framework :: Django",
 
        "Intended Audience :: Developers",
 
        "Natural Language :: English",
 
        "License :: OSI Approved :: Apache Software License",
 
    ),
 
    install_requires=read_file("requirements/base.txt").splitlines(),
 
    dependency_links=read_file("requirements/dependencies.txt").splitlines(),
 
)
0 comments (0 inline, 0 general)