xeroizer 2.20.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|