# Ticket Kiosk Logic Notes and design decision explanations created by **Gabor Kristof** for the Vista Group Job Application design submission. The detailed mockups can be found at https://www.behance.net/gallery/93100775/Vista-Cinema-Kiosk ![](https://i.imgur.com/LPVpqyp.jpg) # Requirements The task was given to design the interface and user flow of a ticketing system with the following set of requirements. The requirements are numbered so we can reference them later: 1. The ticket screen needs to provide patrons the choice of 5 ticket types: * Adult - $17.50 * Child - $9.00 * Student - $11.00 * Senior - $11.00 * Loyalty member - $9.00. 2. The patron can have up to 10 tickets per order. 3. The food and drink screen consists of 4 categories: * snacks * drinks * hot food * desserts. 4. Each category has 6 - 10 items for sale. 5. A deal is a special price that is applied to a *combination of items*. 6. Some deals can have items which require a decision to be made by the patron, such as a drink flavor. An example of a deal which includes items with options would be: “The Dinner Date Combo” usually $20.00 but is $15.00 on Tuesdays. 2x Hotdogs, 2x Medium Drinks (which could be a choice of Sprite, Coke, Fanta or Orange juice) and 1x Banana Split (with either strawberry, caramel or chocolate sauce). 8. When a patron is one or two items away from a deal, a suggestion will be shown for that deal that they can apply to their order. 9. Deals can apply to both tickets & candy bar items. 10. An item in the patron’s basket can only have one deal applied to it at a time. 11. Items must be removable from the order basket. 12. A promo code can be entered to add an item at a discounted price. 13. There needs to be an option to view all deals that are available to the patron. # Considerations and Concerns regarding the requirements ## Requirement 4: "each category has 6-10 items for sale" In reality, the upper limit (10 items) should not be specified. It would be bad idea to implement a list with an upper limit. So I designed all interfaces with an item list to be scrollable -- that makes it possible to add in that 11th kind of beverage, should the need arise. ## Requirement 9: "An item in the patron’s basket can only have one deal applied to it at a time." This requirement can complicate things greatly, and it forced me to take some difficult design decisions, including potentially suggesting changes in the requirements. My assumption is that the above requirement means that when a deal is applied, then it merely adds the additional items to the basket, and changes the prices of the already-added ones to match the deal price. Let me illustrate with an example what I think the rule implies: Let's assume we have one deal, the Dinner Date Combo. Dinner Date Combo: if user has * 2 burgers * 2 chips * 2 soft drinks in the basket, then apply a 10% discount on those items User has the following items in their basket: | Item Name | In Deal? | Price | | --- | --- | --- | | Burger | no | 10 | | Burger | no | 10 | | Chips | no | 5 | | Chips | no | 5 | Since the user is only 2 items away from a deal, the deal suggestion gets triggered, and the user is told that if they add 2 more soft drinks, they will get a 10% discount. The user agrees. After this, assuming that the soft drink's full price is $5, their basket then should look like this: | Item Name | In Deal? | Price | | --- | --- | --- | | Burger | yes | 9 | | Burger | yes | 9 | | Chips | yes | 4.5 | | Chips | yes | 4.5 | | Soft drink | yes | 4.5 | | Soft drink | yes | 4.5 | So my assumption, based on requirement 10 is that applying deals change existing items in place, and adds only the required additional items to the basket. ## Complexity Incoming If that assumption is true, then **it would make things complex, perhaps reaching a level of complexity would not worth implementing.** Let me explain it with an example: Let's assume we have 2 deals: 1: Dinner Date Combo: ``` if user has * 2 burgers * 2 chips * 2 soft drinks in the basket, then apply a 10% discount on those items ``` 2: ``` Mega Diabetes Combo: if user has 5 soft drinks in the basket, they get a 50% discount on them ``` Now let's assume the user have the same basket as before: | Item Name | In Deal? | Price | | --- | --- | --- | | Burger | no | 10 | | Burger | no | 10 | | Chips | no | 5 | | Chips | no | 5 | Then, as before, the user is presented with the dinner date deal that they accept, so their basket will look like this: | Item Name | In Deal? | Price | | --- | --- | --- | | Burger | yes | 9 | | Burger | yes | 9 | | Chips | yes | 4.5 | | Chips | yes | 4.5 | | Soft drink | yes | 4.5 | | Soft drink | yes | 4.5 | Then the user adds 3 more soft drinks: | Item Name | In Deal? | Price | | --- | --- | --- | | Burger | yes | 9 | | Burger | yes | 9 | | Chips | yes | 4.5 | | Chips | yes | 4.5 | | Soft drink | yes | 4.5 | | Soft drink | yes | 4.5 | | Soft drink | no | 5 | | Soft drink | no | 5 | | Soft drink | no | 5 | So now they have 5 soft drinks, 3 full price, 2 in deal **Now** the user removes a Burger. Suddenly the Dinner Date does not apply anymore, but -- assumedly -- the Mega Diabetes deal kicks in: | Item Name | In Deal? | Price | | --- | --- | --- | | Burger | no | 10 | | Chips | no | 5 | | Chips | no | 5 | | Soft drink | yes | 2.5 | | Soft drink | yes | 2.5 | | Soft drink | yes | 2.5 | | Soft drink | yes | 2.5 | | Soft drink | yes | 2.5 | Now the user adds back the burger, but the dinner date deal is not kicking in, because the Mega Diabetes Combo is holding on to the drinks. This leads to confusion. Confusion leads to anger. And anger leads to suffering. (And eventually to the dark side.) *(Note: even without the extra soft drinks, the sudden price change of several items because of a removal of another item can be confusing.)* This -- and even more complex cases would make the underlying implementation very complicated. Some of the problems are: * a single item removed can trigger a cascade of events that could get very complex, even creating race conditions, where two or more mutually exclusive deals could be applied. * not all deals are based on percentages -- so modifying prices of individual items can get very weird, or even impossible. # Simplifying With A Single Change Based on that I decided to suggest a different approach: When a deal is selected and applied by the user, then **the whole deal is added as a single item to the basket, leaving the items that are already there.** Following the original example, from this: | Item Name | Price | | --- | --- | | Burger | 10 | | Burger | 10 | | Chips | 5 | | Chips | 5 | ... after applying the Dinner Date Deal, the user's basket would look like this: | Item Name | Price | | --- | --- | | Burger | 10 | | Burger | 10 | | Chips | 5 | | Chips | 5 | | Dinner Date for 2 at 10% discount | 36 | * **YES**, the user would have to manually remove the 2 burgers and chips. But that is the only setback of this proposal. * We don't have to track if an item is in a deal or not * We don't have to change the price of already-added items. once an item is added, it stays unchanged unless removed. This also simplifies things. * No race conditions of mutually exclusive deals. * User can't remove a single item from a deal -- they can only remove the whole deal. * We don't need to check if an item has already have a deal or not -- that is not applicable anymore. ## A Combo Solution When a deal is applied, it is possible to automatically remove the "partial ingredients" from the basket, but still add the deal as one single atomic item. In this case the user's basket would change like this: | Item Name | Price | | --- | --- | | Burger | 10 | | Burger | 10 | | Chips | 5 | | Chips | 5 | ... applying the Dinner Date Deal ... | Item Name | Price | | --- | --- | | Dinner Date for 2 at 10% discount | 36 | But I am not convinced that we should take this extra step. For this decision I would recommend a focus group or A/B testing. Note: In the detailed graphics I've decided to implement this version, as is the atomic combo deal replaces the parts in the basket. # Deal Examples Following are a few types of deals that the system can handle. In most cases they can be combined -- for example a promo code can be time based or applied only over a certain number of items. 1. Item Combo Deal -- a deal that is applicable to a certain combination of items. The system should suggest appropriate deals if the user is 2 items away from it. 2. Promo Code -- An item combo deal or volume discount that is hidden, unless the user types in the promo code. 3. Volume Discount -- user needs to buy a certain amount of a single item to trigger it, 4. Time based deal -- Only applicable on certain days, times of day or between two timestamps. 5. Extended Item Combo Deal -- a combo deal that requires both beverages and tickets to be present. For Example a "Charlie and the Chocolate Factory" deal that requires a Child ticket for the specific movie title and a chocoloate bar added to the basket to give a discount. # User Flows ## Basic Flow The User Flow follows a very straightforward path, with one single multiple choice screen, that contains all the optional branches of the purchase process. ```flow st=>start: Start e=>end: Pay op=>operation: Select Movie op2=>operation: Select Tickets op3=>operation: Select Seats op4=>operation: Menu Dashboard / Deal Suggestion st->op->op2->op3->op4->e ``` Most of the complexity is in the Menu Dashboard. It can be implemented sequentially (select snacks -> select drinks -> select hot food -> select desserts) or as a dashboard / restaurant menu. Since this part's functionality is closer to a restaurant menu, I chose to implement it as a dashboard. Below is the Dashboard flow in more details. ## Menu Dashboard / Deal Suggestion Flow Below is a possible rendering of the Menu Dashboard / Deal Sugestion flow. ```flow st=>start: Start e=>end: Checkout op1=>operation: User changes basket op2=>operation: Offer Deal op3=>operation: Add deal to basket op4=>operation: Customize deal cond0=>condition: Modify basket? cond1=>condition: Deal triggered? cond2=>condition: User Accepts? cond3=>condition: Deal Customizable? st->cond0 cond0(yes)->op1 cond0(no)->e op1->cond1 cond1(yes)->cond2 cond1(no)->cond0 cond2(yes)->cond3 cond2(no)->cond0 cond3(yes)->op4 cond3(no)->op3 op4->op3 op3->cond0 ``` Note: From both flow diagrams, the "back" routes that enable the user to go back to any earlier part of the process are omitted for clarity. --- Gabor Kristof Singapore, 1 March 2020