xeroizer 2.20.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +126 -185
- data/lib/xeroizer/connection.rb +49 -0
- data/lib/xeroizer/exceptions.rb +2 -0
- data/lib/xeroizer/generic_application.rb +8 -3
- data/lib/xeroizer/http.rb +5 -80
- data/lib/xeroizer/http_response.rb +154 -0
- data/lib/xeroizer/models/bank_transaction.rb +1 -0
- data/lib/xeroizer/models/batch_payment.rb +4 -1
- data/lib/xeroizer/models/contact.rb +10 -4
- data/lib/xeroizer/models/credit_note.rb +20 -20
- data/lib/xeroizer/models/history_record.rb +72 -0
- data/lib/xeroizer/models/invoice.rb +5 -1
- data/lib/xeroizer/models/line_item.rb +4 -2
- data/lib/xeroizer/models/manual_journal.rb +2 -1
- data/lib/xeroizer/models/option.rb +1 -1
- data/lib/xeroizer/models/payroll/address.rb +53 -0
- data/lib/xeroizer/models/payroll/bank_account.rb +18 -6
- data/lib/xeroizer/models/payroll/benefit_line.rb +26 -0
- data/lib/xeroizer/models/payroll/benefit_type.rb +45 -0
- data/lib/xeroizer/models/payroll/deduction_line.rb +32 -0
- data/lib/xeroizer/models/payroll/deduction_type.rb +49 -0
- data/lib/xeroizer/models/payroll/earnings_line.rb +39 -0
- data/lib/xeroizer/models/payroll/earnings_type.rb +53 -0
- data/lib/xeroizer/models/payroll/employee.rb +30 -8
- data/lib/xeroizer/models/payroll/leave_application.rb +27 -0
- data/lib/xeroizer/models/payroll/leave_line.rb +30 -0
- data/lib/xeroizer/models/payroll/leave_period.rb +15 -0
- data/lib/xeroizer/models/payroll/pay_items.rb +22 -0
- data/lib/xeroizer/models/payroll/pay_run.rb +33 -0
- data/lib/xeroizer/models/payroll/pay_schedule.rb +40 -0
- data/lib/xeroizer/models/payroll/pay_template.rb +24 -0
- data/lib/xeroizer/models/payroll/payment_method.rb +24 -0
- data/lib/xeroizer/models/payroll/paystub.rb +44 -0
- data/lib/xeroizer/models/payroll/reimbursement_line.rb +21 -0
- data/lib/xeroizer/models/payroll/reimbursement_type.rb +22 -0
- data/lib/xeroizer/models/payroll/salary_and_wage.rb +29 -0
- data/lib/xeroizer/models/payroll/super_line.rb +40 -0
- data/lib/xeroizer/models/payroll/tax_declaration.rb +50 -0
- data/lib/xeroizer/models/payroll/time_off_line.rb +20 -0
- data/lib/xeroizer/models/payroll/time_off_type.rb +32 -0
- data/lib/xeroizer/models/payroll/work_location.rb +25 -0
- data/lib/xeroizer/models/quote.rb +76 -0
- data/lib/xeroizer/models/tax_component.rb +1 -0
- data/lib/xeroizer/oauth.rb +12 -1
- data/lib/xeroizer/oauth2.rb +82 -0
- data/lib/xeroizer/oauth2_application.rb +49 -0
- data/lib/xeroizer/payroll_application.rb +8 -3
- data/lib/xeroizer/record/base_model.rb +1 -1
- data/lib/xeroizer/record/base_model_http_proxy.rb +1 -0
- data/lib/xeroizer/record/payroll_base.rb +4 -0
- data/lib/xeroizer/record/record_association_helper.rb +4 -4
- data/lib/xeroizer/record/validators/associated_validator.rb +1 -0
- data/lib/xeroizer/record/xml_helper.rb +16 -16
- data/lib/xeroizer/response.rb +22 -17
- data/lib/xeroizer/version.rb +1 -1
- data/lib/xeroizer.rb +31 -4
- data/test/acceptance/about_creating_bank_transactions_test.rb +80 -82
- data/test/acceptance/about_creating_prepayment_test.rb +25 -30
- data/test/acceptance/about_fetching_bank_transactions_test.rb +10 -10
- data/test/acceptance/about_online_invoice_test.rb +6 -10
- data/test/acceptance/acceptance_test.rb +28 -26
- data/test/acceptance/bank_transfer_test.rb +12 -17
- data/test/acceptance/bulk_operations_test.rb +18 -16
- data/test/acceptance/connections_test.rb +11 -0
- data/test/stub_responses/bad_request.json +6 -0
- data/test/stub_responses/connections.json +16 -0
- data/test/stub_responses/expired_oauth2_token.json +6 -0
- data/test/stub_responses/generic_response_error.json +6 -0
- data/test/stub_responses/invalid_oauth2_request_token.json +6 -0
- data/test/stub_responses/invalid_tenant_header.json +6 -0
- data/test/stub_responses/object_not_found.json +6 -0
- data/test/test_helper.rb +16 -11
- data/test/unit/generic_application_test.rb +21 -10
- data/test/unit/http_test.rb +281 -9
- data/test/unit/models/address_test.rb +2 -2
- data/test/unit/models/bank_transaction_model_parsing_test.rb +2 -2
- data/test/unit/models/bank_transaction_test.rb +1 -1
- data/test/unit/models/bank_transaction_validation_test.rb +1 -1
- data/test/unit/models/contact_test.rb +2 -2
- data/test/unit/models/credit_note_test.rb +8 -8
- data/test/unit/models/employee_test.rb +4 -4
- data/test/unit/models/invoice_test.rb +12 -12
- data/test/unit/models/journal_line_test.rb +6 -6
- data/test/unit/models/journal_test.rb +4 -4
- data/test/unit/models/line_item_sum_test.rb +1 -1
- data/test/unit/models/line_item_test.rb +19 -2
- data/test/unit/models/manual_journal_test.rb +3 -3
- data/test/unit/models/organisation_test.rb +2 -2
- data/test/unit/models/payment_service_test.rb +2 -2
- data/test/unit/models/phone_test.rb +7 -7
- data/test/unit/models/prepayment_test.rb +4 -4
- data/test/unit/models/repeating_invoice_test.rb +2 -2
- data/test/unit/models/tax_rate_test.rb +2 -2
- data/test/unit/oauth2_test.rb +171 -0
- data/test/unit/oauth_config_test.rb +1 -1
- data/test/unit/record/base_model_test.rb +13 -13
- data/test/unit/record/base_test.rb +5 -4
- data/test/unit/record/block_validator_test.rb +1 -1
- data/test/unit/record/connection_test.rb +60 -0
- data/test/unit/record/model_definition_test.rb +36 -36
- data/test/unit/record/parse_params_test.rb +2 -2
- data/test/unit/record/parse_where_hash_test.rb +13 -13
- data/test/unit/record/record_association_test.rb +14 -14
- data/test/unit/record/validators_test.rb +43 -43
- data/test/unit/record_definition_test.rb +7 -7
- data/test/unit/report_definition_test.rb +7 -7
- data/test/unit/report_test.rb +20 -20
- data/test/unit_test_helper.rb +16 -0
- metadata +106 -23
- data/lib/xeroizer/models/payroll/home_address.rb +0 -24
- data/lib/xeroizer/partner_application.rb +0 -51
- data/lib/xeroizer/private_application.rb +0 -25
- data/lib/xeroizer/public_application.rb +0 -21
- data/test/unit/http_tsl_12_upgrade_test.rb +0 -31
- data/test/unit/oauth_test.rb +0 -118
- data/test/unit/private_application_test.rb +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 1dad6570c636b1273f3569cda927b6c997a1ca6e2cf2ad629cd88c730e57935a
|
4
|
+
data.tar.gz: e4d31e8555ca3a986241f5395cc2f9bba6adaba088a48bf286c552cda7008f40
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3f8bb7c9cbbfd1792285b4c4bd3d73a24100222dc41f86eba5344e5a84b7d1ffd75ef787fbf43a130a2c17d5f8ac16204b518949872bf6107d889d0e14cb2c4c
|
7
|
+
data.tar.gz: bade0622cf61bdff9e444c9ae931c9e8c985c4185c9b0c69c88f285c3869b4df8c83f29294b2087e1b9b045bb2aaa9b171340ab5f63c23d7bae6ac860eb4a769
|
data/README.md
CHANGED
@@ -1,14 +1,21 @@
|
|
1
|
-
Xeroizer API Library
|
1
|
+
Xeroizer API Library
|
2
2
|
====================
|
3
3
|
|
4
4
|
**Homepage**: [http://waynerobinson.github.com/xeroizer](http://waynerobinson.github.com/xeroizer)
|
5
|
+
|
5
6
|
**Git**: [git://github.com/waynerobinson/xeroizer.git](git://github.com/waynerobinson/xeroizer.git)
|
7
|
+
|
6
8
|
**Github**: [https://github.com/waynerobinson/xeroizer](https://github.com/waynerobinson/xeroizer)
|
9
|
+
|
7
10
|
**Author**: Wayne Robinson [http://www.wayne-robinson.com](http://www.wayne-robinson.com)
|
11
|
+
|
8
12
|
**Contributors**: See Contributors section below
|
13
|
+
|
9
14
|
**Copyright**: 2007-2013
|
15
|
+
|
10
16
|
**License**: MIT License
|
11
17
|
|
18
|
+
|
12
19
|
Introduction
|
13
20
|
------------
|
14
21
|
|
@@ -29,7 +36,7 @@ require 'rubygems'
|
|
29
36
|
require 'xeroizer'
|
30
37
|
|
31
38
|
# Create client (used to communicate with the API).
|
32
|
-
client = Xeroizer::
|
39
|
+
client = Xeroizer::OAuth2Application.new(YOUR_OAUTH2_CLIENT_ID, YOUR_OAUTH2_CLIENT_SECRET)
|
33
40
|
|
34
41
|
# Retrieve list of contacts (note: all communication must be made through the client).
|
35
42
|
contacts = client.Contact.all(:order => 'Name')
|
@@ -38,55 +45,6 @@ contacts = client.Contact.all(:order => 'Name')
|
|
38
45
|
Authentication
|
39
46
|
--------------
|
40
47
|
|
41
|
-
Xero uses OAuth to authenticate API clients. The OAuth gem (with minor modification) by John Nunemaker ([http://github.com/jnunemaker/twitter](http://github.com/jnunemaker/twitter)) is used in this library. If you've used this before, things will all seem very familar.
|
42
|
-
|
43
|
-
There are three methods of authentication detailed below:
|
44
|
-
|
45
|
-
### All: Consumer Key/Secret
|
46
|
-
|
47
|
-
All methods of authentication require your OAuth consumer key and secret. This can be found for your application
|
48
|
-
in the API management console at [http://api.xero.com](http://api.xero.com).
|
49
|
-
|
50
|
-
### Public Applications
|
51
|
-
|
52
|
-
Public applications use a 3-legged authorisation process. A user will need to authorise your
|
53
|
-
application against each organisation that you want access to. Your application can have access
|
54
|
-
to many organisations at once by going through the authorisation process for each organisation.
|
55
|
-
|
56
|
-
The access token received will expire after 30 minutes. If you want access for longer you will need
|
57
|
-
the user to re-authorise your application.
|
58
|
-
|
59
|
-
Authentication occurs in 3 steps:
|
60
|
-
|
61
|
-
```ruby
|
62
|
-
client = Xeroizer::PublicApplication.new(YOUR_OAUTH_CONSUMER_KEY, YOUR_OAUTH_CONSUMER_SECRET)
|
63
|
-
|
64
|
-
# 1. Get a RequestToken from Xero. :oauth_callback is the URL the user will be redirected to
|
65
|
-
# after they have authenticated your application.
|
66
|
-
#
|
67
|
-
# Note: The callback URL's domain must match that listed for your application in http://api.xero.com
|
68
|
-
# otherwise the user will not be redirected and only be shown the authentication code.
|
69
|
-
request_token = client.request_token(:oauth_callback => 'http://yourapp.com/oauth/callback')
|
70
|
-
|
71
|
-
# 2. Redirect the user to the URL specified by the RequestToken.
|
72
|
-
#
|
73
|
-
# Note: example uses redirect_to method defined in Rails controllers.
|
74
|
-
redirect_to request_token.authorize_url
|
75
|
-
|
76
|
-
# 3. Exchange RequestToken for AccessToken.
|
77
|
-
# This access token will be used for all subsequent requests but it is stored within the client
|
78
|
-
# application so you don't have to record it.
|
79
|
-
#
|
80
|
-
# Note: This example assumes the callback URL is a Rails action.
|
81
|
-
client.authorize_from_request(request_token.token, request_token.secret, :oauth_verifier => params[:oauth_verifier])
|
82
|
-
```
|
83
|
-
|
84
|
-
You can now use the client to access the Xero API methods, e.g.
|
85
|
-
|
86
|
-
```ruby
|
87
|
-
contacts = client.Contact.all
|
88
|
-
```
|
89
|
-
|
90
48
|
#### Example Rails Controller
|
91
49
|
|
92
50
|
```ruby
|
@@ -97,25 +55,32 @@ class XeroSessionController < ApplicationController
|
|
97
55
|
public
|
98
56
|
|
99
57
|
def new
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
58
|
+
url = @xero_client.authorize_url(
|
59
|
+
# The URL's domain must match that listed for your application
|
60
|
+
# otherwise the user will see an invalid redirect_uri error
|
61
|
+
redirect_uri: YOUR_CALLBACK_URL,
|
62
|
+
# space separated, see all scopes at https://developer.xero.com/documentation/oauth2/scopes.
|
63
|
+
# note that `offline_access` is required to get a refresh token, otherwise the access only lasts for 30 mins and cannot be refreshed.
|
64
|
+
scope: "accounting.settings.read offline_access"
|
65
|
+
)
|
66
|
+
|
67
|
+
redirect_to url
|
105
68
|
end
|
106
69
|
|
107
70
|
def create
|
108
|
-
@xero_client.
|
109
|
-
|
110
|
-
|
111
|
-
|
71
|
+
token = @xero_client.authorize_from_code(
|
72
|
+
params[:code],
|
73
|
+
redirect_uri: YOUR_CALLBACK_URL
|
74
|
+
)
|
75
|
+
|
76
|
+
connections = @xero_client.current_connections
|
112
77
|
|
113
78
|
session[:xero_auth] = {
|
114
|
-
|
115
|
-
|
79
|
+
:access_token => token[:access_token],
|
80
|
+
:refresh_token => token[:refresh_token],
|
81
|
+
:tenant_id => connections[1][:tenant_id]
|
82
|
+
}
|
116
83
|
|
117
|
-
session.data.delete(:request_token)
|
118
|
-
session.data.delete(:request_secret)
|
119
84
|
end
|
120
85
|
|
121
86
|
def destroy
|
@@ -125,150 +90,130 @@ class XeroSessionController < ApplicationController
|
|
125
90
|
private
|
126
91
|
|
127
92
|
def get_xero_client
|
128
|
-
@xero_client = Xeroizer::
|
93
|
+
@xero_client = Xeroizer::OAuth2Application.new(
|
94
|
+
YOUR_OAUTH2_CLIENT_ID,
|
95
|
+
YOUR_OAUTH2_CLIENT_SECRET,
|
96
|
+
)
|
129
97
|
|
130
98
|
# Add AccessToken if authorised previously.
|
131
99
|
if session[:xero_auth]
|
132
|
-
@xero_client.
|
133
|
-
|
134
|
-
|
100
|
+
@xero_client.tenant_id = session[:xero_auth][:tenant_id]
|
101
|
+
|
102
|
+
@xero_client.authorize_from_access(session[:xero_auth][:acesss_token])
|
135
103
|
end
|
136
104
|
end
|
137
105
|
end
|
138
106
|
```
|
139
107
|
|
140
|
-
|
141
|
-
|
142
|
-
You can store the access token/secret pair so you can access the API again without user intervention. Currently these
|
143
|
-
tokens are only valid for 30 minutes and will raise a `Xeroizer::OAuth::TokenExpired` exception if you try to access
|
144
|
-
the API beyond the token's expiry time.
|
108
|
+
### OAuth2 Applications
|
145
109
|
|
146
|
-
|
110
|
+
For more details, checkout Xero's [documentation](https://developer.xero.com/documentation/oauth2/auth-flow)
|
147
111
|
|
112
|
+
1. Generate the authorization url and redirect the user to authenticate
|
148
113
|
```ruby
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
Private applications require a private RSA keypair which is used to sign each request to the API. You can
|
162
|
-
generate this keypair on Mac OSX or Linux with OpenSSL. For example:
|
163
|
-
|
164
|
-
openssl genrsa -out privatekey.pem 1024
|
165
|
-
openssl req -newkey rsa:1024 -x509 -key privatekey.pem -out publickey.cer -days 365
|
166
|
-
openssl pkcs12 -export -out public_privatekey.pfx -inkey privatekey.pem -in publickey.cer
|
167
|
-
|
168
|
-
You need to upload this `public_privatekey.pfx` file to your private application in [http://api.xero.com](http://api.xero.com).
|
169
|
-
|
170
|
-
Example usage:
|
114
|
+
client = Xeroizer::OAuth2Application.new(
|
115
|
+
YOUR_OAUTH2_CLIENT_ID,
|
116
|
+
YOUR_OAUTH2_CLIENT_SECRET,
|
117
|
+
)
|
118
|
+
url = client.authorize_url(
|
119
|
+
# The URL's domain must match that listed for your application
|
120
|
+
# otherwise the user will see an invalid redirect_uri error
|
121
|
+
redirect_uri: YOUR_CALLBACK_URL,
|
122
|
+
# space separated, see all scopes at https://developer.xero.com/documentation/oauth2/scopes.
|
123
|
+
# note that `offline_access` is required to get a refresh token, otherwise the access only lasts for 30 mins and cannot be refreshed.
|
124
|
+
scope: "accounting.settings.read offline_access"
|
125
|
+
)
|
171
126
|
|
172
|
-
|
173
|
-
|
174
|
-
contacts = client.Contact.all
|
127
|
+
# Rails as an example
|
128
|
+
redirect_to url
|
175
129
|
```
|
176
130
|
|
177
|
-
|
131
|
+
2. In the callback route, use the provided code to retrieve an access token.
|
178
132
|
|
179
133
|
```ruby
|
180
|
-
|
181
|
-
|
134
|
+
token = client.authorize_from_code(
|
135
|
+
params[:code],
|
136
|
+
redirect_uri: YOUR_CALLBACK_URL
|
137
|
+
)
|
138
|
+
token.to_hash
|
139
|
+
# {
|
140
|
+
# "token_type"=>"Bearer",
|
141
|
+
# "scope"=>"accounting.transactions.read accounting.settings.read",
|
142
|
+
# :access_token=>"...",
|
143
|
+
# :refresh_token=>nil,
|
144
|
+
# :expires_at=>1615220292
|
145
|
+
# }
|
182
146
|
|
183
|
-
#
|
184
|
-
client = Xeroizer::PrivateApplication.new(key, secret, nil, private_key: Rails.application.credentials.xero_private_key)
|
147
|
+
# Save the access_token, refresh_token...
|
185
148
|
```
|
186
149
|
|
187
|
-
|
188
|
-
|
189
|
-
Partner applications use a combination of 3-legged authorisation and private key message signing.
|
190
|
-
|
191
|
-
Visit the [https://developer.xero.com/partner/app-partner](Becoming an app partner) page to get permission to create a partner application.
|
192
|
-
|
193
|
-
After you have followed the instructions provided by Xero for partner applications and uploaded your certificate you can
|
194
|
-
access the partner application in a similar way to public applications.
|
195
|
-
|
196
|
-
Authentication occcurs in 3 steps:
|
197
|
-
|
150
|
+
3. Retrieve the tenant ids.
|
198
151
|
```ruby
|
199
|
-
|
200
|
-
|
201
|
-
YOUR_OAUTH_CONSUMER_SECRET,
|
202
|
-
"/path/to/privatekey.pem"
|
203
|
-
)
|
152
|
+
connections = client.current_connections
|
153
|
+
# returns Xeroizer::Connection instances
|
204
154
|
|
205
|
-
#
|
206
|
-
# after they have authenticated your application.
|
207
|
-
#
|
208
|
-
# Note: The callback URL's domain must match that listed for your application in http://api.xero.com
|
209
|
-
# otherwise the user will not be redirected and only be shown the authentication code.
|
210
|
-
request_token = client.request_token(:oauth_callback => 'http://yourapp.com/oauth/callback')
|
155
|
+
# Save the tenant ids
|
211
156
|
|
212
|
-
# 2. Redirect the user to the URL specified by the RequestToken.
|
213
|
-
#
|
214
|
-
# Note: example uses redirect_to method defined in Rails controllers.
|
215
|
-
redirect_to request_token.authorize_url
|
216
|
-
|
217
|
-
# 3. Exchange RequestToken for AccessToken.
|
218
|
-
# This access token will be used for all subsequent requests but it is stored within the client
|
219
|
-
# application so you don't have to record it.
|
220
|
-
#
|
221
|
-
# Note: This example assumes the callback URL is a Rails action.
|
222
|
-
client.authorize_from_request(request_token.token, request_token.secret, :oauth_verifier => params[:oauth_verifier])
|
223
157
|
```
|
224
158
|
|
225
|
-
|
226
|
-
renew this token. To be able to renew this token, you need to save the following data from this organisation's
|
227
|
-
AccessToken:
|
228
|
-
|
159
|
+
4. Use access token and tenant ids to retrieve data.
|
229
160
|
```ruby
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
161
|
+
client = Xeroizer::OAuth2Application.new(
|
162
|
+
YOUR_OAUTH2_CLIENT_ID,
|
163
|
+
YOUR_OAUTH2_CLIENT_SECRET,
|
164
|
+
access_token: access_token,
|
165
|
+
tenant_id: tenant_id
|
166
|
+
)
|
167
|
+
# OR
|
168
|
+
client = Xeroizer::OAuth2Application.new(
|
169
|
+
YOUR_OAUTH2_CLIENT_ID,
|
170
|
+
YOUR_OAUTH2_CLIENT_SECRET,
|
171
|
+
tenant_id: tenant_id
|
172
|
+
).authorize_from_access(access_token)
|
236
173
|
|
237
|
-
|
238
|
-
|
174
|
+
# use the client
|
175
|
+
client.Organisation.first
|
176
|
+
```
|
239
177
|
|
240
178
|
#### AccessToken Renewal
|
241
|
-
|
242
|
-
Renewal of an access token requires knowledge of the previous access token generated for this organisation. To renew:
|
179
|
+
Renewal of an access token requires the refresh token generated for this organisation. To renew:
|
243
180
|
|
244
181
|
```ruby
|
245
|
-
|
246
|
-
|
182
|
+
client = Xeroizer::OAuth2Application.new(
|
183
|
+
YOUR_OAUTH2_CLIENT_ID,
|
184
|
+
YOUR_OAUTH2_CLIENT_SECRET,
|
185
|
+
access_token: access_token,
|
186
|
+
refresh_token: refresh_token,
|
187
|
+
tenant_id: tenant_id
|
188
|
+
)
|
247
189
|
|
248
|
-
|
249
|
-
client.renew_access_token(access_token, access_secret, session_handle)
|
190
|
+
client.renew_access_token
|
250
191
|
```
|
192
|
+
If you lose these details at any stage you can always reauthorise by redirecting the user back to the Xero OAuth gateway.
|
251
193
|
|
252
|
-
|
253
|
-
|
254
|
-
session.
|
194
|
+
#### Custom Connections
|
195
|
+
Custom Connections are a paid-for option for private M2M applications. The generated token expires and needs recreating if expired.
|
255
196
|
|
256
|
-
|
197
|
+
```ruby
|
198
|
+
client = Xeroizer::OAuth2Application.new(
|
199
|
+
YOUR_OAUTH2_CLIENT_ID,
|
200
|
+
YOUR_OAUTH2_CLIENT_SECRET
|
201
|
+
)
|
257
202
|
|
258
|
-
|
203
|
+
token = client.authorize_from_client_credentials
|
204
|
+
```
|
205
|
+
You can check the status of the token with the `expires?` and `expired?` methods.
|
259
206
|
|
260
|
-
Once you are approved as a Xero Partner you can request unofficial documentation to do with customizing Payment Services and Branding Themes using the API. There is more info on that [here]( https://github.com/waynerobinson/xeroizer/pull/439).
|
261
207
|
|
262
208
|
Retrieving Data
|
263
209
|
---------------
|
264
210
|
|
265
211
|
Each of the below record types is implemented within this library. To allow for multiple access tokens to be used at the same
|
266
|
-
time in a single application, the model classes are accessed from the instance of
|
267
|
-
or PartnerApplication. All class-level operations occur on this singleton. For example:
|
212
|
+
time in a single application, the model classes are accessed from the instance of OAuth2Application. All class-level operations occur on this singleton. For example:
|
268
213
|
|
269
214
|
```ruby
|
270
|
-
xero = Xeroizer::
|
271
|
-
xero.authorize_from_access(session[:xero_auth][:access_token]
|
215
|
+
xero = Xeroizer::OAuth2Application.new(YOUR_OAUTH2_CLIENT_ID, YOUR_OAUTH2_CLIENT_SECRET, tenant_id: tenant_id)
|
216
|
+
xero.authorize_from_access(session[:xero_auth][:access_token])
|
272
217
|
|
273
218
|
contacts = xero.Contact.all(:order => 'Name')
|
274
219
|
|
@@ -648,8 +593,8 @@ You can set this option when initializing an application:
|
|
648
593
|
|
649
594
|
```ruby
|
650
595
|
# Sleep for 2 seconds every time the rate limit is exceeded.
|
651
|
-
client = Xeroizer::
|
652
|
-
|
596
|
+
client = Xeroizer::OAuth2Application.new(YOUR_OAUTH2_CLIENT_ID,
|
597
|
+
YOUR_OAUTH2_CLIENT_SECRET,
|
653
598
|
:rate_limit_sleep => 2)
|
654
599
|
```
|
655
600
|
|
@@ -666,8 +611,8 @@ You can set this option when initializing an application:
|
|
666
611
|
|
667
612
|
```ruby
|
668
613
|
# Sleep for 1 second and retry up to 3 times when Xero claims the nonce was used.
|
669
|
-
client = Xeroizer::
|
670
|
-
|
614
|
+
client = Xeroizer::OAuth2Application.new(YOUR_OAUTH2_CLIENT_ID,
|
615
|
+
YOUR_OAUTH2_CLIENT_SECRET,
|
671
616
|
:nonce_used_max_attempts => 3)
|
672
617
|
```
|
673
618
|
|
@@ -679,8 +624,8 @@ You can add an optional parameter to the Xeroizer Application initialization, to
|
|
679
624
|
|
680
625
|
```ruby
|
681
626
|
XeroLogger = Logger.new('log/xero.log', 'weekly')
|
682
|
-
client = Xeroizer::
|
683
|
-
|
627
|
+
client = Xeroizer::OAuth2Application.new(YOUR_OAUTH2_CLIENT_ID,
|
628
|
+
YOUR_OAUTH2_CLIENT_SECRET,
|
684
629
|
:logger => XeroLogger)
|
685
630
|
```
|
686
631
|
|
@@ -692,7 +637,7 @@ time Xeroizer makes an HTTP request, which is potentially useful for both
|
|
692
637
|
throttling and logging:
|
693
638
|
|
694
639
|
```ruby
|
695
|
-
Xeroizer::
|
640
|
+
Xeroizer::OAuth2Application.new(
|
696
641
|
credentials[:key], credentials[:secret],
|
697
642
|
before_request: ->(request) { puts "Hitting this URL: #{request.url}" },
|
698
643
|
after_request: ->(request, response) { puts "Got this response: #{response.code}" },
|
@@ -711,8 +656,8 @@ By default, the API accepts unit prices (UnitAmount) to two decimals places. If
|
|
711
656
|
|
712
657
|
|
713
658
|
```ruby
|
714
|
-
client = Xeroizer::
|
715
|
-
|
659
|
+
client = Xeroizer::OAuth2Application.new(YOUR_OAUTH2_CLIENT_ID,
|
660
|
+
YOUR_OAUTH2_CLIENT_SECRET,
|
716
661
|
:unitdp => 4)
|
717
662
|
```
|
718
663
|
|
@@ -721,23 +666,19 @@ This option adds the unitdp=4 query string parameter to all requests for models
|
|
721
666
|
Tests
|
722
667
|
-----
|
723
668
|
|
724
|
-
|
725
|
-
|
726
|
-
Once you have created your Private App, set these environment variables:
|
727
|
-
```
|
728
|
-
EXPORT CONSUMER_KEY="your private app's consumer key"
|
729
|
-
EXPORT CONSUMER_SECRET="your private app's consumer secret"
|
730
|
-
EXPORT PRIVATE_KEY_PATH="the path to your private app's private key"
|
731
|
-
```
|
669
|
+
OAuth2 Tests
|
732
670
|
|
733
|
-
|
671
|
+
The tests within the repository can be run by setting up a [OAuth2 App](https://developer.xero.com/documentation/guides/oauth2/auth-flow/). You can create a Private App in the [developer portal](https://developer.xero.com/myapps/), it's suggested that you create it against the [Demo Company (AU)](https://developer.xero.com/documentation/getting-started/development-accounts). Demo Company expires after 28 days, so you will need to reset it and re-connect to it if your Demo Company has expired. Make sure you create the Demo Company in Australia region.
|
734
672
|
|
735
|
-
Then run the tests
|
736
673
|
```
|
674
|
+
export XERO_CLIENT_ID="asd"
|
675
|
+
export XERO_CLIENT_SECRET="asdfg"
|
676
|
+
export XERO_ACCESS_TOKEN="sadfsdf"
|
677
|
+
export XERO_TENANT_ID="asdfasdfasdfasd"
|
678
|
+
|
737
679
|
rake test
|
738
680
|
```
|
739
681
|
|
740
|
-
|
741
682
|
### Contributors
|
742
683
|
Xeroizer was inspired by the https://github.com/tlconnor/xero_gateway gem created by Tim Connor
|
743
684
|
and Nik Wakelin and portions of the networking and authentication code are based completely off
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Xeroizer
|
2
|
+
class Connection
|
3
|
+
attr_accessor :attributes
|
4
|
+
attr_reader :parent
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def current_connections(client)
|
8
|
+
response = do_request(client)
|
9
|
+
|
10
|
+
if response.success?
|
11
|
+
JSON.parse(response.plain_body).map do |connection_json|
|
12
|
+
build(connection_json, client)
|
13
|
+
end
|
14
|
+
else
|
15
|
+
raise Xeroizer::OAuth::TokenInvalid, response.plain_body
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def build(attributes, parent)
|
20
|
+
record = new(parent)
|
21
|
+
record.attributes = attributes
|
22
|
+
record
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def do_request(client)
|
28
|
+
client.get('https://api.xero.com/connections')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize(parent)
|
33
|
+
@parent = parent
|
34
|
+
@attributes = {}
|
35
|
+
end
|
36
|
+
|
37
|
+
def method_missing(name, *_args)
|
38
|
+
@attributes.send(:[], name.to_s.camelcase(:lower))
|
39
|
+
end
|
40
|
+
|
41
|
+
def delete
|
42
|
+
parent.delete("https://api.xero.com/connections/#{id}")
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_h
|
46
|
+
attributes.transform_keys(&:underscore)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/xeroizer/exceptions.rb
CHANGED
@@ -6,9 +6,11 @@ module Xeroizer
|
|
6
6
|
include Http
|
7
7
|
extend Record::ApplicationHelper
|
8
8
|
|
9
|
-
attr_reader :client, :
|
9
|
+
attr_reader :client, :logger, :rate_limit_sleep, :rate_limit_max_attempts,
|
10
10
|
:default_headers, :unitdp, :before_request, :after_request, :around_request, :nonce_used_max_attempts
|
11
11
|
|
12
|
+
attr_accessor :xero_url
|
13
|
+
|
12
14
|
extend Forwardable
|
13
15
|
def_delegators :client, :access_token
|
14
16
|
|
@@ -26,6 +28,7 @@ module Xeroizer
|
|
26
28
|
record :ExpenseClaim
|
27
29
|
record :Invoice
|
28
30
|
record :InvoiceReminder
|
31
|
+
record :HistoryRecord
|
29
32
|
record :OnlineInvoice
|
30
33
|
record :Item
|
31
34
|
record :Journal
|
@@ -37,6 +40,7 @@ module Xeroizer
|
|
37
40
|
record :Prepayment
|
38
41
|
record :Overpayment
|
39
42
|
record :PurchaseOrder
|
43
|
+
record :Quote
|
40
44
|
record :Receipt
|
41
45
|
record :RepeatingInvoice
|
42
46
|
record :Schedule
|
@@ -63,7 +67,8 @@ module Xeroizer
|
|
63
67
|
# @see PublicApplication
|
64
68
|
# @see PrivateApplication
|
65
69
|
# @see PartnerApplication
|
66
|
-
def initialize(
|
70
|
+
def initialize(client, options = {})
|
71
|
+
raise Xeroizer::InvalidClientError.new unless [OAuth, OAuth2].member?(client.class)
|
67
72
|
@xero_url = options[:xero_url] || "https://api.xero.com/api.xro/2.0"
|
68
73
|
@rate_limit_sleep = options[:rate_limit_sleep] || false
|
69
74
|
@rate_limit_max_attempts = options[:rate_limit_max_attempts] || 5
|
@@ -72,7 +77,7 @@ module Xeroizer
|
|
72
77
|
@before_request = options.delete(:before_request)
|
73
78
|
@after_request = options.delete(:after_request)
|
74
79
|
@around_request = options.delete(:around_request)
|
75
|
-
@client =
|
80
|
+
@client = client
|
76
81
|
@logger = options[:logger] || false
|
77
82
|
@unitdp = options[:unitdp] || 2
|
78
83
|
end
|