Class: LedgerSync::Xero::Client

Inherits:
Object
  • Object
show all
Includes:
Ledgers::Client::Mixin
Defined in:
lib/ledger_sync/xero/client.rb

Constant Summary collapse

ROOT_URI =
'https://api.xero.com/api.xro/2.0'
OAUTH_HEADERS =
{ 'Accept' => 'application/json', 'Content-Type' => 'application/json' }.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args = {}) ⇒ Client

Returns a new instance of Client.



23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/ledger_sync/xero/client.rb', line 23

def initialize(args = {})
  @access_token = args.fetch(:access_token)
  @client_id = args.fetch(:client_id)
  @client_secret = args.fetch(:client_secret)
  @refresh_token = args.fetch(:refresh_token)
  @tenant_id = args.fetch(:tenant_id)
  @update_dotenv = args.fetch(:update_dotenv, true)

  @previous_access_tokens = []
  @previous_refresh_tokens = []

  update_secrets_in_dotenv if update_dotenv
end

Instance Attribute Details

#access_tokenObject (readonly)

Returns the value of attribute access_token.



13
14
15
# File 'lib/ledger_sync/xero/client.rb', line 13

def access_token
  @access_token
end

#client_idObject (readonly)

Returns the value of attribute client_id.



13
14
15
# File 'lib/ledger_sync/xero/client.rb', line 13

def client_id
  @client_id
end

#client_secretObject (readonly)

Returns the value of attribute client_secret.



13
14
15
# File 'lib/ledger_sync/xero/client.rb', line 13

def client_secret
  @client_secret
end

#expires_atObject (readonly)

Returns the value of attribute expires_at.



13
14
15
# File 'lib/ledger_sync/xero/client.rb', line 13

def expires_at
  @expires_at
end

#previous_refresh_tokensObject (readonly)

Returns the value of attribute previous_refresh_tokens.



13
14
15
# File 'lib/ledger_sync/xero/client.rb', line 13

def previous_refresh_tokens
  @previous_refresh_tokens
end

#refresh_tokenObject (readonly)

Returns the value of attribute refresh_token.



13
14
15
# File 'lib/ledger_sync/xero/client.rb', line 13

def refresh_token
  @refresh_token
end

#refresh_token_expires_atObject (readonly)

Returns the value of attribute refresh_token_expires_at.



13
14
15
# File 'lib/ledger_sync/xero/client.rb', line 13

def refresh_token_expires_at
  @refresh_token_expires_at
end

#tenant_idObject (readonly)

Returns the value of attribute tenant_id.



13
14
15
# File 'lib/ledger_sync/xero/client.rb', line 13

def tenant_id
  @tenant_id
end

#update_dotenvObject (readonly)

Returns the value of attribute update_dotenv.



13
14
15
# File 'lib/ledger_sync/xero/client.rb', line 13

def update_dotenv
  @update_dotenv
end

Class Method Details

.ledger_attributes_to_saveObject



153
154
155
# File 'lib/ledger_sync/xero/client.rb', line 153

def self.ledger_attributes_to_save
  %i[access_token expires_at refresh_token refresh_token_expires_at]
end

.new_from_env(**override) ⇒ Object



111
112
113
114
115
116
117
118
119
120
121
# File 'lib/ledger_sync/xero/client.rb', line 111

def self.new_from_env(**override)
  new(
    {
      access_token: ENV.fetch('XERO_ACCESS_TOKEN'),
      client_id: ENV.fetch('XERO_CLIENT_ID'),
      client_secret: ENV.fetch('XERO_CLIENT_SECRET'),
      refresh_token: ENV.fetch('XERO_REFRESH_TOKEN'),
      tenant_id: ENV.fetch('XERO_TENANT_ID')
    }.merge(override)
  )
end

Instance Method Details

#authorization_url(redirect_uri:) ⇒ Object



37
38
39
# File 'lib/ledger_sync/xero/client.rb', line 37

def authorization_url(redirect_uri:)
  oauth_client.authorization_url(redirect_uri: redirect_uri)
end

#find(path:) ⇒ Object



41
42
43
44
45
46
47
48
49
# File 'lib/ledger_sync/xero/client.rb', line 41

def find(path:)
  url = "#{ROOT_URI}/#{path.capitalize}"

  request(
    headers: oauth_headers,
    method: :get,
    url: url
  )
end

#oauthObject



68
69
70
71
72
73
74
# File 'lib/ledger_sync/xero/client.rb', line 68

def oauth
  OAuth2::AccessToken.new(
    oauth_client.client,
    access_token,
    refresh_token: refresh_token
  )
end

#oauth_clientObject



76
77
78
79
80
81
# File 'lib/ledger_sync/xero/client.rb', line 76

def oauth_client
  @oauth_client ||= LedgerSync::Xero::OAuthClient.new(
    client_id: client_id,
    client_secret: client_secret
  )
end

#oauth_headersObject



64
65
66
# File 'lib/ledger_sync/xero/client.rb', line 64

def oauth_headers
  OAUTH_HEADERS.dup.merge('Xero-tenant-id' => @tenant_id)
end

#post(path:, payload:) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/ledger_sync/xero/client.rb', line 51

def post(path:, payload:)
  url = "#{ROOT_URI}/#{path.capitalize}"

  request(
    headers: oauth_headers,
    method: :post,
    body: {
      path.capitalize => payload
    },
    url: url
  )
end

#refresh!Object



83
84
85
86
87
88
89
90
# File 'lib/ledger_sync/xero/client.rb', line 83

def refresh!
  set_credentials_from_oauth_token(
    token: Request.new(
      client: self
    ).refresh!
  )
  self
end

#request(method:, url:, body: nil, headers: {}) ⇒ Object



101
102
103
104
105
106
107
108
109
# File 'lib/ledger_sync/xero/client.rb', line 101

def request(method:, url:, body: nil, headers: {})
  Request.new(
    client: self,
    body: body,
    headers: headers,
    method: method,
    url: url
  ).perform
end

#set_credentials_from_oauth_code(code:, redirect_uri:) ⇒ Object



123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/ledger_sync/xero/client.rb', line 123

def set_credentials_from_oauth_code(code:, redirect_uri:)
  oauth_token = oauth_client.get_token(
    code: code,
    redirect_uri: redirect_uri
  )

  set_credentials_from_oauth_token(
    token: oauth_token
  )

  oauth_token
end

#set_credentials_from_oauth_token(token:) ⇒ Object

rubocop:disable Metrics/CyclomaticComplexity,Naming/AccessorMethodName,Metrics/PerceivedComplexity



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/ledger_sync/xero/client.rb', line 136

def set_credentials_from_oauth_token(token:) # rubocop:disable Metrics/CyclomaticComplexity,Naming/AccessorMethodName,Metrics/PerceivedComplexity
  @previous_access_tokens << access_token if access_token.present?
  @access_token = token.token

  @expires_at = Time&.at(token.expires_at.to_i)&.to_datetime
  unless token.params['x_refresh_token_expires_in'].nil?
    @refresh_token_expires_at = Time&.at(
      Time.now.to_i + token.params['x_refresh_token_expires_in']
    )&.to_datetime
  end

  @previous_refresh_tokens << refresh_token if refresh_token.present?
  @refresh_token = token.refresh_token
ensure
  update_secrets_in_dotenv if update_dotenv
end

#tenantsObject



92
93
94
95
96
97
98
99
# File 'lib/ledger_sync/xero/client.rb', line 92

def tenants
  response = oauth.get(
    '/connections',
    body: nil,
    headers: LedgerSync::Xero::Client::OAUTH_HEADERS.dup
  )
  JSON.parse(response.body)
end