---
# System prepended metadata

title: New booking wizard (booking checkout)

---

# 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
![](https://i.imgur.com/0vFYJAC.png)

```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
```
![](https://i.imgur.com/YY3cFss.png)

    
### 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
