@startuml "Help us Class Diagram"
title "Help us Class Diagram"

' avoid problems with angled crows feet
skinparam linetype ortho

class SquareAuthController {
    + authorize(AuthorizeWithSquareCommand command)
    + getAuthLink(GetAuthLinkCommand command)
    + webhook(SetMerchantInfoWebHookCommand command)
}

class AuthorizeWithSquareCommand {
    + grant_type : string
    + refresh_token : string
    + code : string
    + square_service : SquareService
    + execute(self) : ObtainTokenResponse
}

class GetAuthLinkCommand {
    + square_service : SquareService
    + user_id : string
    + execute(self) : string
}

SquareAuthController ..> AuthorizeWithSquareCommand : uses
SquareAuthController ..> GetAuthLinkCommand : uses

class SquareService {
    + Variables : Variables
    + Constants : Constants
    + DirectusRepository : DirectusRepository
    + get_access_token(self, command) : str
    + set_merchant_information_for_user(self, SetMerchantInfoWebHookCommand command) : None
    + get_square_auth_link(self, command) : str
    + authorize_with_square(self, AuthorizeWithSquareCommand command) : ObtainTokenResponse
    + checkout_with_square(self, CheckoutWithSquareCommand command) : CheckoutResponse
    + update_with_square(self, UpdateWithSquareCommand command) : bool
    + delete_link_square(self, DeleteLinkSquareCommand command) : bool
    + get_payment_link(self, RetrieveWithSquareCommand command) : string
    + list_locations(self, ListLocationsSquareCommand command) : LocationResponse
    + update_location(self, UpdateLocationSquareCommand command) : bool
}

class ObtainTokenResponse {
    + access_token : string
    + merchant_id : string
    + refresh_token : string
    + short_lived : string
}

class ObtainTokenRequest {
    + grant_type : string
    + refresh_token : string
    + code : string
    + short_lived : string
    + client_id : string
    + client_secret : string
    + scopes : string
}

SquareService ..> ObtainTokenResponse : uses
SquareService ..> ObtainTokenRequest : uses
AuthorizeWithSquareCommand ..> SquareService : uses
GetAuthLinkCommand ..> SquareService : uses

class SquarePaymentController {
    + create(CheckoutWithSquareCommand command)
    + read(RetrieveWithSquareCommand command)
    + update(UpdateWithSquareCommand command)
    + delete(DeleteLinkSquareCommand command)
}

class CheckoutWithSquareCommand {
    + square_service : SquareService
    + execute(self) : CheckoutResponse
}

class RetrieveWithSquareCommand {
    + square_service : SquareService
    + execute(self) : CheckoutResponse
}

class UpdateWithSquareCommand {
    + square_service : SquareService
    + execute(self) : bool
}

class DeleteLinkSquareCommand {
    + square_service : SquareService
    + execute(self) : bool
}

class CheckoutResponse {
    + id : string
    + created_at : string
    + order_id : string
    + url : string
    + version : string
}

class  CheckoutRequest {
    + order : Order
    + source : string
}

class Order {
    + location_id : string
    + line_items : LineItem[]
    + payment_note : string
    + pre_populated_data : PrePopulatedData
}

class LineItem {
    + item_type : string
    + name : string
    + quantity : int
    + base_price_money : Money
}

class PrePopulatedData {
    + buyer_email : string
    + buyer_phone_number : string
}

class Money {
    + amount : int
    + currency : string
}

SquareService ..> CheckoutResponse : uses
SquareService ..> CheckoutRequest : uses
CheckoutRequest ..> Order : uses
Order ..> LineItem : uses
Order ..> PrePopulatedData : uses
LineItem ..> Money : uses



SquarePaymentController ..> CheckoutWithSquareCommand : uses
SquarePaymentController ..> RetrieveWithSquareCommand : uses
SquarePaymentController ..> UpdateWithSquareCommand : uses
SquarePaymentController ..> DeleteLinkSquareCommand : uses

CheckoutWithSquareCommand ..> SquareService : uses
RetrieveWithSquareCommand ..> SquareService : uses
UpdateWithSquareCommand ..> SquareService : uses
DeleteLinkSquareCommand ..> SquareService : uses

class SquareLocationController {
    + list_locations(ListLocationsSquareCommand command)
    + update_location(UpdateLocationSquareCommand command)
}

class ListLocationsSquareCommand {
    + square_service : SquareService
    + execute(self) : LocationResponse
}

class UpdateLocationSquareCommand {
    + square_service : SquareService
    + execute(self) : bool
}

class LocationResponse {
    + locations : Location[]
}

class Location {
    + id : string
    + name : string
    + business_email : string
    + logo_url : string
    + merchant_id : string
    + coordinates : Coordinates
}

class Coordinates {
    + latitude : float
    + longitude : float
}

SquareLocationController ..> ListLocationsSquareCommand : uses
SquareLocationController ..> UpdateLocationSquareCommand : uses
ListLocationsSquareCommand ..> SquareService : uses
UpdateLocationSquareCommand ..> SquareService : uses
SquareService ..> LocationResponse : uses
LocationResponse ..> Location : uses
Location ..> Coordinates : uses

class DirectusRepository {
    + set_merchant_information_for_user(String user_id , MerchantInfo info)
}

class MerchantInfo {
    + merchant_id : string
    + access_token : string
    + refresh_token : string
    + expires_in : string
}

class SetMerchantInfoWebHookCommand {
    + square_service : SquareService
    + user_id : string
    + merchant_id : string
    + access_token : string
    + refresh_token : string
    + expires_in : string
    + execute(self) : None
}

DirectusRepository ..> MerchantInfo : uses
SquareService ..> DirectusRepository : uses
SetMerchantInfoWebHookCommand ..> SquareService : uses
SquareAuthController ..> SetMerchantInfoWebHookCommand : uses


@enduml

