# New booking wizard (booking checkout)
[TOC]
## Flow
### Step A. Bookings availability check and booking creation
```plantuml
@startuml
autonumber
actor frontend as front
control backend as back
database DB as db
group Step A. Bookings availability check
== Flow starts ==
== (User is not yet authorized) ==
front -> front : user picks a type of a service eg. **/covid-19 test/**
front -> front : user picks the date of the booking
front -> back : front queries for booking possibility for service and date
note over front
query {
availableHours(
zip: "0155",
startDate: "2021-07-09",
endDate: "2021-07-15",
startHour: "12:00",
endHour: "12:30"
) {
availableBookings {
spServices
spTypesName
spServicesNames
startsAt
endsAt
date
rebooking
lat
lng
zip
serviceProvider {
id
firstName
lastName
phoneNumber
}
}
}
}
end note
back -> db : fetches available Hours through matcher
db -> back : results
back -> front : serves results
front -> front : user picks time (hour) of the booking from available options
front -> back : new booking is created **IMPLICITLY**
note over front
mutation {
createBooking(
zip: "12345",
lat: 11.11111,
lng: 22.22222,
serviceProviderId: 99,
startHour: "12:00",
endHour: "12:30",
service: "covid-19-test") {
id
price
}
}
<b>perhaps at this stage, booking does not</b>
<b>yet have an order or lineItem attached to it (TBC)</b>
end note
== at this point we should be able \n to fetch price and display it in UI ==
front -> back : fetching price based on (service,patientCount, zip)
note over front
query {
orderPrice(
zip: "0160",
lineItemAttributes: [
{
serviceSlug: "hcl-vac-flu-or",
quantity: 3
}
]
)
}
end note
back -> back :calculates price
back -> front: returns calculated price
back -> back : new booking is validated
back -> db : new booking is persisted
back -> front : booking object returned
front -> front : **<color red>user can proceed to next form step</color>**
== (booking object is at this time already created) ==
end
@enduml
```
### Step B. Authentication

```plantuml
@startuml
autonumber
actor frontend as front
control backend as back
database DB as db
entity "Otp provider" as otp
group Step B. Authentication
== (User not yet authorized) ==
front -> front : user picks the date & time of the booking
front -> front : user inputs his phone num.
front -> back : request new OTP session
note over front, back
mutation {
newOtpSession(phoneNumber: "+4791222121") {
otpCode
}
}
end note
back -> db : backend fetches user by phone number
back -> back : if no user is found, new user obj is created
back --> db : (optional) new user persisted
back -> otp : requests OTP to send SMS with code
otp --> front: (sends user an SMS to his phone)
front -> front : user inputs OTP code he just got
front -> back : front authorizes user with OTP
note over front, back
mutation {
signInUserOtp(phoneNumber: "+4791222121", code: "4444") {
id
firstName
lastName
...
}
}
end note
back -> db : backend updates user last sign in time etc. if user exists
== or in case of user-to-be ==
front -> back : front authorizes user-to-be with OTP
note over front, back
mutation {
signInOtp(phoneNumber: "+4791222121", code: "4444") {
}
}
end note
== active session is established, \nalthough user obj may not yet be created ==
front -> front : **<color red>user can proceed to next form step</color>**
end
@enduml
```
### Step B1. (optional) Creating | Updating user
(only if a user clicks **Endre oppysninger** btn, or is a new user. Otherwise user was supposed to confirm that his info are up-to-date)
```plantuml
@startuml
autonumber
actor frontend as front
control backend as back
database DB as db
group Step B Authentication
front -> front : user fills his data form (address, email, name)
front -> back : update user details
note over front, back
mutation {
createUser | updateUser(
id: 299,
zip: "12345",
email: "jens.eriksson@example.com",
street: "SomeStreet 31") {
id
}
}
end note
back -> back : validates user params \nin interactor (service obj)
back -> db : persists updated user
@enduml
```
### Step C. Updating booking details
```plantuml
@startuml
autonumber
actor frontend as front
control backend as back
database DB as db
group Step C. Updating booking details
front -> front : user fills booking address form
note over front
i.e. (address, zip, info on parking)
info get to be saved on front for the time being (not yet sent to API)
end note
group adding Patients
note over front
i.e. (patients name, email, phone no, personnumber [is this ID number?])
info get to be saved on front for the time being (not yet sent to API)
end note
note over front #aqua
we can consider sth like typeahead API-assisted
feature to facilitate adding patients from
those previously added
end note
front -> front : user fills patients form
== after each addition of the patient price is updated ==
front -> back : fetching price based on (service,patientCount, zip)
note over front
query {
orderPrice(
zip: "0160",
lineItemAttributes: [
{
serviceSlug: "hcl-vac-flu-or",
quantity: 3
}
]
)
}
end note
back -> back :calculates price
back -> front: returns calculated price and shows in the UI
end
front -> back : update Booking **<color blue>M:updateBooking(....)</color>**
back -> back : params are passed to BookingUpdater\n interactor, validation etc.
back -> db : persists updated booking
front -> front : **<color red>user can proceed to next form step</color>**
end
@enduml
```

### Step D. Confirm booking
```plantuml
@startuml
autonumber
actor frontend as front
control backend as back
entity Stripe as stripe
group Step D. Confirm booking
== at this point we should make sure user made it possible for us\n to charge him with at least 1 payment method ==
front -> front : let user fill payment method form (business card only?)
front --> stripe : updates payment information
note over front #aqua
that happens through stripe's
own control most likely (tbc)
end note
front -> front : user clicks some button (Purchase, Confirm, whatever)
front -> back : confirms booking and thus initiates order creation
note over front, back
mutation {
createOrder | purchaseBooking :-) (
booking_id: 12345,
paymentMethodId: 7894567
) {
redirectUrl
id
}
}
end note
== at this point an order is created, along with the booking \n(order + line_item + linked booking that is) ==
note over front, back #aqua
there goes some continuation of the payment flow,
to be discussed at later stage
end note
front -> front : **<color red>user is taken to payment step (can vary depending on the method)</color>**
@enduml
```
### Step E. Payment
```plantuml
@startuml
autonumber
actor frontend as front
control backend as back
entity Stripe as stripe
@enduml
```
## Doubts to discuss