299 lines
8.6 KiB
Markdown
299 lines
8.6 KiB
Markdown
|
# 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
|