Files @ ff281c17ee63
Branch filter:

Location: symposion_app/vendor/registrasion/design/design.md

Joel Addison
Add speaker bio to JSON API
# 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