xero-ruby 3.1.4 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 06a855fcd373f4b83eb0de6f4ebda1eadb564bd568b85c312a23b93747d9a55c
4
- data.tar.gz: 1cf8fad6ef31ff2c413418aad2aa5faf9188868f9e2ffc110321867315fba7d0
3
+ metadata.gz: 4faab59f0f75f9a905fac48b7ee80cfbf6414d44ceb49c16db0b5ac192471198
4
+ data.tar.gz: 6bbbff00712fd9bf777671e4d13162eafbe29c49fc18c6d880207f547e2f8b06
5
5
  SHA512:
6
- metadata.gz: 2292f433cd0c52c9bd89673c16a65078a91aae0aeb7266975e256da8907746396ef097215666ae00e2adea2c59d5b0ce8852476a5bde7c1a1009301ae037df4a
7
- data.tar.gz: 850b5487a92752dd0d74e0bc2b13d78a73d66419dd38e2c8f629eb58e8c49dc665383f398846cd802c6992d1b26b76198a278d4f0fc90c50adc48adfc70fea2e
6
+ metadata.gz: efdf971ecd85feb2bbfcc2275de9152f44849be576da7ef062d05003f0888511e043b8aa0d8d83feb7c05195937dafc8d06d3de18b739a18d737ee51089bfbf9
7
+ data.tar.gz: 586107ae9a1c2593e7b729ae4624bb47adbc9d835d86245c0c32b55b0504f5e62e41dd07c0fd45479f79591e099dcd03605b355777cd3e63c34e2e356ca65e22
data/README.md CHANGED
@@ -1,222 +1,228 @@
1
1
  # xero-ruby
2
- Xero Ruby SDK for OAuth 2.0 generated from [Xero API OpenAPI Spec](https://github.com/XeroAPI/Xero-OpenAPI).
3
-
4
- [![RubyGem](https://img.shields.io/badge/xero--ruby%20gem-brightgreen)](https://rubygems.org/gems/xero-ruby)
5
-
6
- # Documentation
7
- Xero Ruby SDK supports Xero's OAuth2.0 authentication and the following Xero API sets.
8
- ### API Client Documentation
9
- * [API client methods](https://xeroapi.github.io/xero-ruby/accounting/index.html)
10
- > This describes to ~200+ accounting API endpoints and their expected params. There are also method reference docs for the Assets, Files, Projects, and Payroll endpoints sets, though we are still working on accurately generating usable parameter examples for all! (feedback welcome)
11
- ### Model Docs
12
- * [Models](/docs/)
13
- > Directory of markdown files, describing the object models for the Accounting, Asset, Projects, Files, Payroll (AU, UK, NZ) Xero API sets.
14
- ## Sample Apps
15
- We have two sample apps showing SDK usage:
16
- * https://github.com/XeroAPI/xero-ruby-oauth2-starter (**Sinatra** - bare minimum to hello world and simple session based storage)
17
- * https://github.com/XeroAPI/xero-ruby-oauth2-app (**Rails** - token management with robust usage examples)
18
-
19
- ![sample-app](https://i.imgur.com/OOEn55G.png)
20
-
21
- ## Xero Pre-Requisites
22
- * Create a [free Xero user account](https://www.xero.com/us/signup/api/)
23
- * Login to your Xero developer [/myapps](https://developer.xero.com/myapps) dashboard & create an API application
24
- * Copy the credentials from your API app and store/access them using a secure ENV variable strategy
25
- * Resaearch and include the [neccesary scopes](https://developer.xero.com/documentation/oauth2/scopes) for your app's functionality as a space-seperated list, ex. "`SCOPES="openid profile email accounting.transactions accounting.settings"`"
26
- ## Installation
27
- To install this gem to your project:
2
+ [![Gem Version](https://badge.fury.io/rb/xero-ruby.svg)](https://badge.fury.io/rb/xero-ruby)
3
+ [![Github forks](https://img.shields.io/github/forks/XeroAPI/xero-ruby.svg)](https://github.com/XeroAPI/xero-ruby/network)
4
+ [![Github stars](https://img.shields.io/github/stars/XeroAPI/xero-ruby.svg)](https://github.com/XeroAPI/xero-ruby/stargazers)
5
+ ![total downloads](https://ruby-gem-downloads-badge.herokuapp.com/xero-ruby?type=total)
6
+
7
+ The xero-ruby SDK makes it easy for developers to access Xero's APIs in their Ruby code, and build robust applications and software using small business & general ledget accounting data.
8
+ # Table of Contents
9
+ - [API Client documentation](#api-client-documentation)
10
+ - [Sample Applications](#sample-applications)
11
+ - [Xero Account Requirements](#xero-account-requirements)
12
+ - [Installation](#installation)
13
+ - [Configuration](#configuration)
14
+ - [Authentication](#authentication)
15
+ - [Custom Connections](#custom-connections)
16
+ - [API Clients](#api-clients)
17
+ - [Helper Methods](#helper-methods)
18
+ - [Usage Examples](#usage-examples)
19
+ - [SDK conventions](#sdk-conventions)
20
+ - [Contributing](#contributing)
21
+
22
+ <hr>
23
+
24
+ ## API Client documentation
25
+ This SDK supports full method coverage for the following Xero API sets:
26
+
27
+ | API Set | Description |
28
+ | --- | --- |
29
+ | [`Accounting`](https://xeroapi.github.io/xero-ruby/accounting/index.html) | The Accounting API exposes accounting functions of the main Xero application *(most commonly used)*
30
+ | [Assets](https://xeroapi.github.io/xero-ruby/assets/index.html) | The Assets API exposes fixed asset related functions of the Xero Accounting application |
31
+ | [Files](https://xeroapi.github.io/xero-ruby/files/index.html) | The Files API provides access to the files, folders, and the association of files within a Xero organisation |
32
+ | [Projects](https://xeroapi.github.io/xero-ruby/projects/index.html) | Xero Projects allows businesses to track time and costs on projects/jobs and report on profitability |
33
+ | [Payroll (AU)](https://xeroapi.github.io/xero-ruby/payroll_au/index.html) | The (AU) Payroll API exposes payroll related functions of the payroll Xero application |
34
+ | [Payroll (UK)](https://xeroapi.github.io/xero-ruby/payroll_uk/index.html) | The (UK) Payroll API exposes payroll related functions of the payroll Xero application |
35
+ | [Payroll (NZ)](https://xeroapi.github.io/xero-ruby/payroll_nz/index.html) | The (NZ) Payroll API exposes payroll related functions of the payroll Xero application |
36
+ | [`Ruby Models`](/docs/) | Directory of markdown files, describing the object models for all supported API sets |
37
+
38
+ <img src="https://i.imgur.com/0MsvkGB.png" alt="drawing" width="350"/>
39
+
40
+ <hr>
41
+
42
+ ## Sample Applications
43
+ Sample apps can get you started quickly with simple auth flows to advanced usage.
44
+ | Sample App | Description | Screenshot |
45
+ | --- | --- | --- |
46
+ | [`xero-ruby-oauth2-starter`](https://github.com/XeroAPI/Xero-ruby-oauth2-starter) | A Sinatra application showing the basic getting started code to work with the sdk | <img src="https://i.imgur.com/9H4F98M.png" alt="drawing" width="300"/>
47
+ | [`xero-ruby-oauth2-app`](https://github.com/XeroAPI/Xero-ruby-oauth2-app) | Complete rails app with +95% of api set examples, complex filters, pagination, and user/token management in postgres | <img src="https://i.imgur.com/XsAp9Ww.png" alt="drawing" width="500"/>
48
+ | [`xero-ruby-custom-connections-starter`](https://github.com/XeroAPI/xero-ruby-custom-connections-starter) | A getting started Sinatra app showing Custom Connections - a Xero [premium option](https://developer.xero.com/documentation/oauth2/custom-connections) for building M2M integrations to a single org | <img src="https://i.imgur.com/YEkScui.png" alt="drawing" width="300"/>
49
+
50
+ <hr>
51
+
52
+ ## Xero Account Requirements
53
+ - Create a [free Xero user account](https://www.xero.com/us/signup/api/)
54
+ - Login to your Xero developer [dashboard](https://developer.xero.com/app/manage) and create an API application
55
+ - Copy the credentials from your API app and store them using a secure ENV variable strategy
56
+ - Decide the [neccesary scopes](https://developer.xero.com/documentation/oauth2/scopes) for your app's functionality
57
+
58
+ # Installation
59
+ To install this gem to your project
28
60
  ```
29
61
  gem install 'xero-ruby'
30
62
  ```
31
- Or more commonly in Ruby on Rails usage add to your gemfile and run `bundle install`:
63
+ Or add to your gemfile and run `bundle install`
32
64
  ```
33
65
  gem 'xero-ruby'
34
66
  ```
35
67
 
36
68
  ---
37
- ## Usage
38
- ```
39
- require 'xero-ruby'
40
- ```
69
+ ## Configuration
41
70
  ```ruby
71
+ require 'xero-ruby'
72
+
42
73
  creds = {
43
74
  client_id: ENV['CLIENT_ID'],
44
75
  client_secret: ENV['CLIENT_SECRET'],
45
76
  redirect_uri: ENV['REDIRECT_URI'],
46
77
  scopes: ENV['SCOPES'],
47
- state: "this-can-be-a-custom-state-parameter" # optional
78
+ state: "Optional value to pass through auth flow"
48
79
  }
49
80
  xero_client ||= XeroRuby::ApiClient.new(credentials: creds)
50
81
  ```
51
82
 
52
- For additional logging or timeout, add or override any [config](/lib/xero-ruby/configuration.rb) option by passing an optional named parameter `config: {..}`.
83
+ For additional [config](/lib/xero-ruby/configuration.rb) options you can pass an optional named parameter `config: {}`
53
84
  ```ruby
54
85
  config = { timeout: 30, debugging: true }
55
86
  @xero_client ||= XeroRuby::ApiClient.new(credentials: creds, config: config)
56
87
  ```
88
+ ---
89
+ ## Authentication
90
+ All API requests go through Xero's OAuth2.0 gateway and require a valid `access_token` to be set on the `xero_client`, which autmoatically appends the `access_token` [JWT](https://jwt.io/) to the header of each request.
57
91
 
58
- ## OAuth2.0 Authorization & Callback
59
- All API requests require a valid access token to be set on the xero_client.
92
+ If you are making an API call for the first time:
60
93
 
61
- ### Step 1
62
- Send the user to the `authorization_url` after you have configured your xero_client
94
+ 1. Send the user to the Xero authorization URL
63
95
  ```ruby
64
96
  @authorization_url = xero_client.authorization_url
65
-
66
97
  redirect_to @authorization_url
67
98
  ```
68
-
69
- ### Step 2
70
- On successful authorization, Xero identity will redirect to the URI defined in your `redirect_uri` config which must match **exactly** with the variable in your /myapps dashboard.
71
- ```
72
- => /oauth/redirect_uri
73
- ```
74
- ### Step 3
75
- In your server defined callback route, exchange the temporary code for a valid `token_set` that will get set on your client.
99
+ 2. The user will authorize your API application and be sent to your `redirect_uri`
76
100
  ```ruby
77
- token_set = xero_client.get_token_set_from_callback(params)
101
+ ENV['REDIRECT_URI']
102
+ => /xero-callback?code=xyz123
78
103
  ```
79
- At this point you should save the token_set as JSON in a datastore in relation to the authenticating user or entity.
80
-
81
- The sample [Rails app](https://github.com/XeroAPI/xero-ruby-oauth2-app/blob/master/app/controllers/application_controller.rb#L11) shows a solid pattern you can tweak to fit your needs:
104
+ 3. You exchange a temporary `authorization_code` for a valid `token_set`
82
105
  ```ruby
83
- # /oauth/redirect_uri -> 'application#callback'
84
- def callback
85
- @token_set = @xero_client.get_token_set_from_callback(params)
86
-
87
- current_user.token_set = @token_set
88
- current_user.token_set['connections'] = @xero_client.connections
89
- current_user.active_tenant_id = latest_connection(current_user.token_set['connections'])
90
- current_user.save!
91
- flash.notice = "Successfully authenticated with Xero!"
92
- end
93
- ```
94
- ---
95
- ### What is a Token Set?
96
- A `token_set` is what we call the XeroAPI response that contains data about your API connection:
97
- ```json
98
- {
99
- "id_token": "xxx.yyy.zz", (if you requested `openid profile email` scope)
100
- "access_token": "xxx.yyy.zzz",
101
- "expires_in": 1800,
102
- "token_type": "Bearer",
103
- "refresh_token": "xxxxxx", (if you requested `offline_access` scope)
104
- "scope": "email profile openid accounting.transactions offline_access"
105
- }
106
+ @token_set = @xero_client.get_token_set_from_callback(params)
107
+ # save the @token_set
106
108
  ```
107
109
 
108
- Note that an `access_token` is valid for 30 minutes but a `refresh_token` can be used once in up to a 60 day window. If a refresh_token is used to refresh access you must replace the entire token_set.
110
+ It is reccomended that you store this token set JSON in a datastore in relation to the user who has authenticated the Xero API connection. Each time you want to call the Xero API, you will need to access the previously generated token set, initialize it on the SDK `xero_client`, and refresh the `access_token` prior to making API calls.
109
111
 
110
- Both the `id_token` & `access_token` are JWT's, and can be decoded to see additional metadata described in the Token Helpers section:
111
- ## Making API calls with a valid token_set
112
- After the initial user interaction you can simply setup a xero_client by passing the whole token_set to the client.
113
- ```ruby
114
- xero_client.set_token_set(user.token_set)
112
+ ### Token Set
113
+ | key | value | description |
114
+ | --- | --- | --- |
115
+ | id_token: | "xxx.yyy.zzz" | [OpenID Connect](https://openid.net/connect/) token returned if `openid profile email` scopes accepted |
116
+ | access_token: | "xxx.yyy.zzz" | [Bearer token](https://oauth.net/2/jwt/) with a 30 minute expiration required for all API calls |
117
+ | expires_in: | 1800 | Time in seconds till the token expires - 1800s is 30m |
118
+ | refresh_token: | "XXXXXXX" | Alphanumeric string used to obtain a new Token Set w/ a fresh access_token - 60 day expiry |
119
+ | scope: | "email profile openid accounting.transactions offline_access" | The Xero permissions that are embedded in the `access_token` |
115
120
 
116
- xero_client.refresh_token_set(user.token_set)
121
+ Example Token Set JSON:
117
122
  ```
118
- This sets the access_token on the client, and returns a refreshed `token_set` that you should save in your datastore for the next time you need to connect to Xero's API.
119
- ## Token Helpers
120
- ```ruby
121
- xero_client.token_set
122
- =>
123
123
  {
124
124
  "id_token": "xxx.yyy.zz",
125
125
  "access_token": "xxx.yyy.zzz",
126
126
  "expires_in": 1800,
127
127
  "token_type": "Bearer",
128
- "refresh_token": "xxxxxx",
128
+ "refresh_token": "xxxxxxxxx",
129
129
  "scope": "email profile openid accounting.transactions offline_access"
130
130
  }
131
+ ```
132
+ ---
133
+ ## Custom Connections
131
134
 
132
- xero_client.access_token
133
- => "xxx.yyy.zzz"
134
-
135
- xero_client.decoded_access_token
136
- => {
137
- "exp": 1619715843,
138
- "xero_userid": "xero-user-uuid",
139
- "scope": [
140
- "email",
141
- "profile",
142
- "openid",
143
- "accounting.transactions",
144
- "offline_access"
145
- ]
146
- }
135
+ Custom Connections are a Xero [premium option](https://developer.xero.com/documentation/oauth2/custom-connections) used for building M2M integrations to a single organisation. A custom connection uses OAuth2.0's [`client_credentis`](https://www.oauth.com/oauth2-servers/access-tokens/client-credentials/) grant which eliminates the step of exchanging the temporary code for a token set.
147
136
 
137
+ To use this SDK with a Custom Connections:
138
+ ```ruby
139
+ CREDENTIALS = {
140
+ client_id: ENV['CLIENT_ID'],
141
+ client_secret: ENV['CLIENT_SECRET'],
142
+ grant_type: 'client_credentials'
143
+ }
148
144
 
149
- xero_client.id_token
150
- => "aaa.bbb.ccc"
145
+ xero_client = XeroRuby::ApiClient.new(credentials: CREDENTIALS)
151
146
 
152
- xero_client.decoded_id_token
153
- => {
154
- "iss": "https://identity.xero.com",
155
- "email": "luca.pacioli@accounting-services.com",
156
- "given_name": "Luca",
157
- "family_name": "Pacioli"
158
- }
147
+ @token_set = xero_client.get_client_credentials_token
148
+ # save @token_set
159
149
 
160
- xero_client.set_token_set(token_set)
161
- => true
150
+ @invoices = xero_client.accounting_api.get_invoices('').invoices
151
+ ```
162
152
 
163
- xero_client.get_token_set_from_callback(callback_url_params)
164
- => new_xero_token_set
153
+ Because Custom Connections are only valid for a single organisation you don't need to pass the `xero-tenant-id` as the first parameter to every method.
165
154
 
166
- xero_client.refresh_token_set(token_set)
167
- => new_xero_token_set
155
+ However - due to the nature of how our SDK's are generated from our OpenAPI spec, the parameter remains which requires you to pass an empty string for now to use the SDK with a Custom Connection.
168
156
 
169
- # These are automatically populated with `set_token_set`
170
- # But if you need to set just an access or id token on the client
171
- xero_client.set_access_token(access_token)
172
- xero_client.set_id_token(id_token)
157
+ ---
158
+ ## API Clients
159
+ You can access the different API sets and their available methods through the following:
173
160
 
174
- # Automatically run on initial OAuth flow - can be called its own if desired
175
- # Read about why we have included this in the default library: https://auth0.com/docs/tokens/access-tokens/validate-access-tokens
176
- xero_client.validate_tokens(token_set)
177
- xero_client.decode_jwt(tkn)
161
+ ```ruby
162
+ xero_client = XeroRuby::ApiClient.new(credentials: creds)
163
+
164
+ xero_client.accounting_api
165
+ xero_client.asset_api
166
+ xero_client.project_api
167
+ xero_client.files_api
168
+ xero_client.payroll_au_api
169
+ xero_client.payroll_nz_api
170
+ xero_client.payroll_uk_api
178
171
  ```
179
- # Connection Helpers
172
+ ---
173
+ ## Helper Methods
174
+
175
+ Once you have a valid Token Set in your datastore, the next time you want to call the Xero API simply initialize a new `xero_client` and refresh the token set.
176
+
180
177
  ```ruby
181
- xero_client.authorization_url
182
- => # https://login.xero.com/identity/connect/authorize?response_type=code&client_id=<client_id>&redirect_uri=<redirect_uri>&scope=<scopes>&state=<my-state>
183
-
184
- # To completely Revoke a user's access token and all their connections
185
- xero_client.revoke_token(token_set)
186
-
187
- # In case there are > 1 tenants connected the `updatedDateUtc` will show you the most recently authorized tenant (aka organisation) - it is important to store the `tenantId` of the Org your user specified in their API authorization
188
- connections = xero_client.connections
189
- [{
190
- "id" => "xxx-yyy-zzz",
191
- "tenantId" => "xxx-yyy-zzz",
192
- "tenantType" => "ORGANISATION",
193
- "tenantName" => "Demo Company (US)",
194
- "createdDateUtc" => "2019-11-01T20:08:03.0766400",
195
- "updatedDateUtc" => "2020-04-15T22:37:10.4943410"
196
- }]
197
-
198
- # To disconnect a single org from a user's active connections pass the connection ['id'] (not ['tenantId'])
199
- # If you want to enforce only a single org connection per token do this prior to sending user through Xero authorize flow a 2nd time.
200
- remaining_connections = xero_client.disconnect(connections[0]['id'])
201
-
202
- xero_client.token_expired?
203
- => true || false
204
-
205
- # This will check against the following logic
206
- token_expiry = Time.at(decoded_access_token['exp'])
207
- token_expiry < Time.now
178
+ xero_client = XeroRuby::ApiClient.new(credentials: creds)
179
+
180
+ if xero_client.token_expired?
181
+ @token_set = xero_client.refresh_token_set(user.token_set)
182
+ else
183
+ @token_set = xero_client.set_token_set(user.token_set)
184
+ end
185
+
186
+ # example strategy
187
+ user.token_set = @token_set if !@token_set["error"]
188
+ user.xero_connections = xero_client.connections
189
+ user.active_tenant_id = xero_client.last_connection
190
+ user.save!
191
+
192
+ xero_client.accounting_api.get_invoices(xero_client.last_connection['tenantId']).invoices
208
193
  ```
209
194
 
210
- # API Usage
195
+ This will set the access_token on the client and return the refreshed `token_set` that you need to save in your datastore to keep the connection alive until you or the user disconnect.
196
+
197
+ A full list of the SDK client's methods:
198
+
199
+ | method | description |
200
+ | --- | --- |
201
+ | xero_client.`authorization_url` | returns the authorize URL string to send a new user to for API authorization |
202
+ | xero_client.`get_token_set_from_callback`(params) | returns and generates a `token_set` from a temporary code for an `authorization_code` configured client only. Params are the url params. |
203
+ | xero_client.`get_client_credentials_token` | returns and generates a `token_set` for a `client_credentials` configured client only |
204
+ | xero_client.`refresh_token_set`(token_set) | returns a refreshed token_set |
205
+ | xero_client.`revoke_token`(token_set) | removes all a user's org connections and revokes the refresh_token |
206
+ | xero_client.`disconnect`(connection_id) | disconnects an org connection from a user's token permissions |
207
+ | xero_client.`connections` | returns an array of the user's currently connected Xero orgs |
208
+ | xero_client.`last_connection` | returns the `xero-tenant-id` of the most recently connected Xero org |
209
+ | xero_client.`set_token_set`(token_set) | returns a boolean and sets a token on the client - `token_set` containing an access_token & refresh_token |
210
+ | xero_client.`set_access_token`(access_token) | How you can set an `access_token` by itself |
211
+ | xero_client.`set_id_token`(id_token) | How you can set an `id_token` by itself |
212
+ | xero_client.`token_expired?` | returns a boolean if token_set['access_token'] is expired |
213
+ | xero_client.`token_set` | returns the token set if one is set on the client |
214
+ | xero_client.`access_token` | returns the `access_token` if one is set on the client |
215
+ | xero_client.`id_token` | returns the `id_token` if one is set on the client |
216
+ | xero_client.`decoded_access_token` | Decoded JWT exposing OAuth2.`0` meta details about the token |
217
+ | xero_client.`decoded_id_token` | Decoded JWT containing the user meta details that can be used to implement SSO or SSU to Lead |
218
+ ---
219
+ ## Usage Examples
211
220
  ### Accounting API
212
- > https://xeroapi.github.io/xero-ruby/accounting/index.html
213
221
  ```ruby
214
222
  require 'xero-ruby'
215
223
 
216
- xero_client.refresh_token_set(user.token_set)
217
-
218
- tenant_id = user.active_tenant_id
219
- # Example 'active tenant' logic storage of the tenant the user specified, xero_client.connections[0] is not a safe assumption in case they authorized multiple orgs.
224
+ xero_client.refresh_token_set(user_token_set)
225
+ tenant_id = xero_client.last_connection
220
226
 
221
227
  # Get Accounts
222
228
  accounts = xero_client.accounting_api.get_accounts(tenant_id).accounts
@@ -225,7 +231,7 @@ accounts = xero_client.accounting_api.get_accounts(tenant_id).accounts
225
231
  invoices = { invoices: [{ type: XeroRuby::Accounting::Invoice::ACCREC, contact: { contact_id: contacts[0].contact_id }, line_items: [{ description: "Big Agency", quantity: BigDecimal("2.0"), unit_amount: BigDecimal("50.99"), account_code: "600", tax_type: XeroRuby::Accounting::TaxType::NONE }], date: "2019-03-11", due_date: "2018-12-10", reference: "Website Design", status: XeroRuby::Accounting::Invoice::DRAFT }]}
226
232
  invoice = xero_client.accounting_api.create_invoices(tenant_id, invoices).invoices.first
227
233
 
228
- # display out all the serialized data as a snake_case hash
234
+ # return data as a snake_case hash
229
235
  puts invoices.to_attributes
230
236
  => {type: 'ACCREC', line_items: [...]}
231
237
 
@@ -247,53 +253,9 @@ file = File.read(Rails.root.join('app/assets/images/xero-api.png'))
247
253
  attachment = xero_client.accounting_api.create_account_attachment_by_file_name(tenant_id, @account.account_id, file_name, file, opts)
248
254
  ```
249
255
 
250
- ### Assets API
251
- > https://github.com/XeroAPI/xero-ruby/blob/master/accounting/lib/xero-ruby/api/asset_api.rb
252
- ```ruby
253
- asset = {
254
- "assetName": "AssetName: #{rand(10000)}",
255
- "assetNumber": "Asset: #{rand(10000)}",
256
- "assetStatus": "DRAFT"
257
- }
258
- asset = xero_client.asset_api.create_asset(tenant_id, asset)
259
- ```
260
-
261
- ### Project API
262
- > https://github.com/XeroAPI/xero-ruby/blob/master/docs/projects/ProjectApi.md
263
- ```ruby
264
- projects = xero_client.project_api.get_projects(tenant_id).items
265
- ```
266
-
267
- ### Files API
268
- > https://github.com/XeroAPI/xero-ruby/blob/master/docs/files/FileApi.md
269
- ```ruby
270
- opts = {
271
- pagesize: 50, # Integer | pass an optional page size value
272
- page: 2, # Integer | number of records to skip for pagination
273
- sort: 'CreatedDateUTC DESC' # String | values to sort by
274
- }
275
-
276
- files = xero_client.files_api.get_files(tenant_id, opts).files
277
- ```
278
-
279
- ### Payroll API(s)
280
- ```ruby
281
- # https://github.com/XeroAPI/xero-ruby/blob/master/docs/payroll_au/PayrollAuApi.md
282
- employee_id = 'employee_uuid'
283
- employee = xero_client.payroll_au_api.get_employee(tenant_id, employee_id).employee
284
-
285
-
286
- # https://github.com/XeroAPI/xero-ruby/blob/master/docs/payroll_nz/PayrollNzApi.md
287
- timesheet_id = 'timesheeet_uuid'
288
- timesheet = xero_client.payroll_nz_api.approve_timesheet(tenant_id, timesheet_id).timesheets
289
-
290
-
291
- # https://github.com/XeroAPI/xero-ruby/blob/master/docs/payroll_uk/PayrollUkApi.md
292
- employee_id = 'employee_uuid'
293
- wages = xero_client.payroll_uk_api.get_employee_salary_and_wages(tenant_id, employee_id, opts).salary_and_wages
294
- ```
295
-
296
- ## BigDecimal
256
+ ---
257
+ ## SDK conventions
258
+ ### BigDecimal
297
259
  All monetary and fields and a couple quantity fields utilize BigDecimal
298
260
  ```ruby
299
261
  puts invoice.unit_amount
@@ -309,8 +271,8 @@ All monetary and fields and a couple quantity fields utilize BigDecimal
309
271
  number_to_currency(invoice.unit_amount, :unit => "$")
310
272
  ```
311
273
 
312
- ## Querying & Filtering
313
- Examples for the `opts` (_options_) parameters most endpoints support. This is an area of focus and improvement. If you have a complex filering/sorting/where usage that is not supported please [open an issue](https://github.com/XeroAPI/xero-ruby/issues).
274
+ ### Querying & Filtering
275
+ Examples for `opts` (aka _options_) parameters that most endpoints support. If you have a complex filering/sorting/where usage that is not supported please [open an issue](https://github.com/XeroAPI/xero-ruby/issues).
314
276
  ```ruby
315
277
  # Invoices
316
278
  opts = {
@@ -323,7 +285,7 @@ Examples for the `opts` (_options_) parameters most endpoints support. This is a
323
285
  invoice_number: ['=', "INV-0001"],
324
286
  contact_id: ['=', 'contact-uuid-xxxx-xxx-xxxxxxx'],
325
287
  contact_number: ['=', "the-contact-number"],
326
- # date: (DateTime.now - 2.year)..DateTime.now
288
+ date: (DateTime.now - 2.year)..DateTime.now
327
289
  # ▲ you can pass a range ▼ or a date & operator
328
290
  date: ['>=', DateTime.now - 2.year],
329
291
  status: ['=', XeroRuby::Accounting::Invoice::PAID]
@@ -344,9 +306,8 @@ opts = {
344
306
  }
345
307
  xero_client.accounting_api.get_contacts(tenant_id, opts).contacts
346
308
 
347
- # for more complex where filtering that requires a null check, pass those in as a string
309
+ # for more complex chained filtering that requires a null check pass those in as a string
348
310
  # see https://developer.xero.com/documentation/api/requests-and-responses for more
349
-
350
311
  opts = {
351
312
  where: {
352
313
  email_address: '!=null&&EmailAddress.StartsWith("chris.knight@")'
@@ -374,34 +335,39 @@ opts = {
374
335
  xero_client.accounting_api.get_bank_transfers(tenant_id, opts).bank_transfers
375
336
  ```
376
337
 
377
- 1) Not all `opts` parameter combinations are available for all endpoints, and there are likely some undiscovered edge cases. If you encounter a filter / sort / where clause that seems buggy open an issue and we will dig.
338
+ - Not all `opts` parameter combinations are available for all endpoints
378
339
 
379
- 2) Some opts string values may need PascalCasing to match casing defined in our [core API docs](https://developer.xero.com/documentation/api/api-overview).
380
- * `opts = { order: 'UpdatedDateUtc DESC'}`
340
+ - Some opts string values may need PascalCasing to match casing defined in our [core API docs](https://developer.xero.com/documentation/api/api-overview) like `opts = { order: 'UpdatedDateUtc DESC'}`
381
341
 
382
- 3) If you have use cases outside of these examples let us know.
383
- ## Developing locally
384
- To develop this gem locally against your project you can use the following development pattern:
342
+ ---
343
+ ## Contributing
344
+ PRs, issues, and discussion are highly appreciated and encouraged. Note that the majority of this project is generated code based on [Xero's OpenAPI specs](https://github.com/XeroAPI/Xero-OpenAPI) - PR's will be evaluated and pre-merge will be incorporated into the root generation templates.
345
+
346
+ Please add tests for net new functionality and make existing test suite succeeds.
347
+
348
+ `$ rspec spec/`
349
+ ### Versioning
350
+ We do our best to keep OS industry `semver` standards, but we can make mistakes! If something is not accurately reflected in a version's release notes please let the team know.
351
+ ### Developing locally
352
+ To develop or test this gem locally against your project we find the following development pattern easiest
385
353
 
386
- > xero-ruby
387
354
  ```bash
355
+ cd xero-ruby
388
356
  gem build
389
357
  mv xero-ruby-<vsn>.gem xero-ruby.gem
390
358
  pwd
391
359
  => /Users/your.user/code/sdks/xero-ruby/
392
- ```
393
360
 
394
- > https://github.com/XeroAPI/xero-ruby-oauth2-app
395
- Replace gem file with local path:
396
- ```bash
361
+ cd ..
362
+ cd xero-ruby-oauth2-app/
363
+
364
+ # xero-ruby-oauth2-app/Gemfile
397
365
  gem 'xero-ruby', path: '/Users/your.user/code/sdks/xero-ruby/'
398
366
  bundle install
399
367
  ```
400
368
 
401
- ## Testing
402
- * `rspec spec/`
403
-
404
369
  ## Participating in Xero’s developer community
370
+
405
371
  This SDK is one of a number of SDK’s that the Xero Developer team builds and maintains. We are grateful for all the contributions that the community makes.
406
372
 
407
373
  Here are a few things you should be aware of as a contributor:
@@ -29,7 +29,7 @@ module XeroRuby
29
29
  # Defines the headers to be used in HTTP requests of all API calls by default.
30
30
  #
31
31
  # @return [Hash]
32
- attr_accessor :default_headers
32
+ attr_accessor :default_headers, :grant_type
33
33
 
34
34
  # Initializes the ApiClient
35
35
  # @option config [Configuration] Configuration for initializing the object, default to Configuration.default
@@ -37,6 +37,7 @@ module XeroRuby
37
37
  @client_id = credentials[:client_id]
38
38
  @client_secret = credentials[:client_secret]
39
39
  @redirect_uri = credentials[:redirect_uri]
40
+ @grant_type = credentials[:grant_type] || 'authorization_code'
40
41
  @scopes = credentials[:scopes]
41
42
  @state = credentials[:state]
42
43
  default_config = Configuration.default.clone
@@ -135,9 +136,18 @@ module XeroRuby
135
136
  @config.id_token = id_token
136
137
  end
137
138
 
139
+ def get_client_credentials_token
140
+ data = {
141
+ grant_type: @grant_type
142
+ }
143
+ token_set = token_request(data, '/token')
144
+
145
+ return token_set
146
+ end
147
+
138
148
  def get_token_set_from_callback(params)
139
149
  data = {
140
- grant_type: 'authorization_code',
150
+ grant_type: @grant_type,
141
151
  code: params['code'],
142
152
  redirect_uri: @redirect_uri
143
153
  }
@@ -222,6 +232,10 @@ module XeroRuby
222
232
  response[0]
223
233
  end
224
234
 
235
+ def last_connection
236
+ connections.sort { |a,b| DateTime.parse(a['updatedDateUtc']) <=> DateTime.parse(b['updatedDateUtc'])}.first
237
+ end
238
+
225
239
  def disconnect(connection_id)
226
240
  @config.base_url = 'https://api.xero.com'
227
241
  opts = { :header_params => {'Content-Type': 'application/json'}, :auth_names => ['OAuth2'] }
@@ -11,5 +11,5 @@ The version of the XeroOpenAPI document: 2.13.2
11
11
  =end
12
12
 
13
13
  module XeroRuby
14
- VERSION = '3.1.4'
14
+ VERSION = '3.2.0'
15
15
  end
@@ -74,6 +74,29 @@ describe XeroRuby::ApiClient do
74
74
  expect{api_client.validate_state(altered_state)}.to raise_error(StandardError, 'WARNING: @config.state: custom-state and OAuth callback state: do not match!')
75
75
  end
76
76
  end
77
+
78
+ context "Creates a valid client_credentials client" do
79
+
80
+ it "But still defaults to grant_type: authorization_code" do
81
+ creds = {
82
+ client_id: 'abc',
83
+ client_secret: '123',
84
+ }
85
+ api_client = XeroRuby::ApiClient.new(credentials: creds)
86
+ expect(api_client.grant_type).to eq('authorization_code')
87
+ end
88
+
89
+ it "Sets grant_type correctly" do
90
+ creds = {
91
+ client_id: 'abc',
92
+ client_secret: '123',
93
+ grant_type: 'client_credentials'
94
+ }
95
+ api_client = XeroRuby::ApiClient.new(credentials: creds)
96
+ expect(api_client.grant_type).to eq('client_credentials')
97
+ end
98
+
99
+ end
77
100
  end
78
101
  end
79
102
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xero-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.4
4
+ version: 3.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Xero API Team