symposion_app/design/design.md
2016-01-22 16:19:11 +11:00

8.6 KiB

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")
  2. 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
  2. Take user to category page
  3. 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.
  2. 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.
  2. 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?)
  2. 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