xero_gateway 2.1.0 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +3 -11
- data/README.md +212 -0
- data/Rakefile +0 -1
- data/lib/oauth/oauth_consumer.rb +25 -9
- data/lib/xero_gateway.rb +5 -1
- data/lib/xero_gateway/address.rb +29 -27
- data/lib/xero_gateway/bank_transaction.rb +11 -3
- data/lib/xero_gateway/base_record.rb +97 -0
- data/lib/xero_gateway/contact_group.rb +87 -0
- data/lib/xero_gateway/currency.rb +8 -54
- data/lib/xero_gateway/dates.rb +4 -0
- data/lib/xero_gateway/exceptions.rb +14 -13
- data/lib/xero_gateway/gateway.rb +90 -5
- data/lib/xero_gateway/http.rb +16 -8
- data/lib/xero_gateway/invoice.rb +9 -3
- data/lib/xero_gateway/item.rb +27 -0
- data/lib/xero_gateway/line_item_calculations.rb +3 -3
- data/lib/xero_gateway/manual_journal.rb +5 -2
- data/lib/xero_gateway/organisation.rb +22 -73
- data/lib/xero_gateway/payment.rb +22 -9
- data/lib/xero_gateway/phone.rb +2 -0
- data/lib/xero_gateway/report.rb +95 -0
- data/lib/xero_gateway/response.rb +12 -7
- data/lib/xero_gateway/tax_rate.rb +13 -61
- data/lib/xero_gateway/tracking_category.rb +39 -13
- data/lib/xero_gateway/version.rb +3 -0
- data/test/integration/get_items_test.rb +25 -0
- data/test/integration/get_payments_test.rb +54 -0
- data/test/test_helper.rb +51 -16
- data/test/unit/address_test.rb +34 -0
- data/test/unit/bank_transaction_test.rb +7 -0
- data/test/unit/contact_group_test.rb +47 -0
- data/test/unit/contact_test.rb +35 -16
- data/test/unit/credit_note_test.rb +2 -2
- data/test/unit/gateway_test.rb +170 -1
- data/test/unit/invoice_test.rb +27 -7
- data/test/unit/item_test.rb +51 -0
- data/test/unit/organisation_test.rb +1 -0
- data/test/unit/payment_test.rb +18 -11
- data/test/unit/report_test.rb +78 -0
- data/xero_gateway.gemspec +29 -13
- metadata +176 -89
- data/README.textile +0 -357
- data/init.rb +0 -1
data/README.textile
DELETED
@@ -1,357 +0,0 @@
|
|
1
|
-
h1. Xero API wrapper
|
2
|
-
|
3
|
-
h2. Introduction
|
4
|
-
|
5
|
-
This library is designed to help ruby / rails based applications communicate with the publicly available API for Xero. If you are unfamiliar with the API, you should first read the documentation, located here "http://blog.xero.com/developer/":http://blog.xero.com/developer/
|
6
|
-
|
7
|
-
h2. Usage
|
8
|
-
|
9
|
-
<pre><code> require 'xero_gateway'
|
10
|
-
gateway = XeroGateway::Gateway.new(YOUR_OAUTH_CONSUMER_KEY, YOUR_OAUTH_CONSUMER_SECRET)
|
11
|
-
</code></pre>
|
12
|
-
|
13
|
-
h2. Authenticating with OAuth
|
14
|
-
|
15
|
-
OAuth is built into this library in a very similar manner to the Twitter gem by John Nunemaker ("http://github.com/jnunemaker/twitter":http://github.com/jnunemaker/twitter). So if you've used that before this will all seem familiar.
|
16
|
-
|
17
|
-
h3. Consumer Key & Secret
|
18
|
-
|
19
|
-
First off, you'll need to get a Consumer Key/Secret pair for your application from Xero.
|
20
|
-
Head to "http://api.xero.com":http://api.xero.com, log in and then click My Applications > Add Application.
|
21
|
-
|
22
|
-
If you want to create a private application (that accesses your own Xero account rather than your users), you'll need to generate an RSA keypair and an X509 certificate. This can be done with OpenSSL as below:
|
23
|
-
<pre><code> openssl genrsa –out privatekey.pem 1024
|
24
|
-
openssl req –newkey rsa:1024 –x509 –key privatekey.pem –out publickey.cer –days 365
|
25
|
-
openssl pkcs12 –export –out public_privatekey.pfx –inkey privatekey.pem –in publickey.cer
|
26
|
-
</code></pre>
|
27
|
-
|
28
|
-
On the right-hand-side of your application's page there's a box titled "OAuth Credentials". Use the Key and Secret from this box in order to set up a new Gateway instance.
|
29
|
-
|
30
|
-
(If you're unsure about the Callback URL, specify nothing - it will become clear a bit later)
|
31
|
-
|
32
|
-
h3. Xero Gateway Initialization
|
33
|
-
|
34
|
-
<pre><code> require 'xero_gateway'
|
35
|
-
gateway = XeroGateway::Gateway.new(YOUR_OAUTH_CONSUMER_KEY, YOUR_OAUTH_CONSUMER_SECRET)
|
36
|
-
</code></pre>
|
37
|
-
|
38
|
-
or for private applications
|
39
|
-
|
40
|
-
<pre><code> require 'xero_gateway'
|
41
|
-
gateway = XeroGateway::PrivateApp.new(YOUR_OAUTH_CONSUMER_KEY, YOUR_OAUTH_CONSUMER_SECRET, PATH_TO_YOUR_PRIVATE_KEY)
|
42
|
-
</code></pre>
|
43
|
-
|
44
|
-
|
45
|
-
h3. Request Token
|
46
|
-
|
47
|
-
You'll then need to get a Request Token from Xero.
|
48
|
-
|
49
|
-
<pre><code>
|
50
|
-
request_token = gateway.request_token
|
51
|
-
</code></pre>
|
52
|
-
|
53
|
-
You should keep this around - you'll need it to exchange for an Access Token later. (If you're using Rails, this means storing it in the session or something similar)
|
54
|
-
|
55
|
-
Next, you need to redirect your user to the authorisation url for this request token. In Rails, that looks something like this:
|
56
|
-
|
57
|
-
<pre><code>
|
58
|
-
redirect_to request_token.authorize_url
|
59
|
-
</code></pre>
|
60
|
-
|
61
|
-
You may also provide a callback parameter, which is the URL within your app the user will be redirected to. See next section for more information on what parameters Xero sends with this request.
|
62
|
-
|
63
|
-
<pre><code>
|
64
|
-
redirect_to request_token.authorize_url(:oauth_callback => "http://www.something.com/xero/complete")
|
65
|
-
</code></pre>
|
66
|
-
|
67
|
-
h3. Retrieving an Access Token
|
68
|
-
|
69
|
-
If you've specified a Callback URL when setting up your application or provided an oauth_callback parameter on your request token, your user will be redirected to that URL with an OAuth Verifier as a GET parameter. You can then exchange your Request Token for an Access Token like this (assuming Rails, once again):
|
70
|
-
|
71
|
-
<pre><code>
|
72
|
-
gateway.authorize_from_request(request_token.token, request_token.secret, :oauth_verifier => params[:oauth_verifier])
|
73
|
-
</code></pre>
|
74
|
-
|
75
|
-
(If you haven't specified a Callback URL, the user will be presented with a numeric verifier which they must copy+paste into your application; see examples/oauth.rb for an example)
|
76
|
-
|
77
|
-
Now you can access Xero API methods:
|
78
|
-
|
79
|
-
<pre><code>
|
80
|
-
gateway.get_contacts
|
81
|
-
</code></pre>
|
82
|
-
|
83
|
-
h3. Storing Access Tokens
|
84
|
-
|
85
|
-
You can also store the Access Token/Secret pair so that you can access the API without user intervention. Currently, these access tokens are only valid for 30 minutes, and will raise a XeroGateway::OAuth::TokenExpired exception if you attempt to access the API beyond the token's expiry time.
|
86
|
-
|
87
|
-
<pre><code>
|
88
|
-
access_token, access_secret = gateway.access_token
|
89
|
-
</code></pre>
|
90
|
-
|
91
|
-
h3. Examples
|
92
|
-
|
93
|
-
Open examples/oauth.rb and change CONSUMER_KEY and CONSUMER_SECRET to the values for a Test OAuth Application in order to see an example of OAuth at work.
|
94
|
-
|
95
|
-
If you're working with Rails, a controller similar to this might come in handy:
|
96
|
-
|
97
|
-
<pre><code>
|
98
|
-
|
99
|
-
class XeroSessionsController < ApplicationController
|
100
|
-
|
101
|
-
before_filter :get_xero_gateway
|
102
|
-
|
103
|
-
def new
|
104
|
-
session[:request_token] = @xero_gateway.request_token.token
|
105
|
-
session[:request_secret] = @xero_gateway.request_token.secret
|
106
|
-
|
107
|
-
redirect_to @xero_gateway.request_token.authorize_url
|
108
|
-
end
|
109
|
-
|
110
|
-
def create
|
111
|
-
@xero_gateway.authorize_from_request(session[:request_token], session[:request_secret],
|
112
|
-
:oauth_verifier => params[:oauth_verifier])
|
113
|
-
|
114
|
-
session[:xero_auth] = { :access_token => @xero_gateway.access_token.token,
|
115
|
-
:access_secret => @xero_gateway.access_token.secret }
|
116
|
-
|
117
|
-
session.data.delete(:request_token); session.data.delete(:request_secret)
|
118
|
-
end
|
119
|
-
|
120
|
-
def destroy
|
121
|
-
session.data.delete(:xero_auth)
|
122
|
-
end
|
123
|
-
|
124
|
-
private
|
125
|
-
|
126
|
-
def get_xero_gateway
|
127
|
-
@xero_gateway = XeroGateway::Gateway.new(YOUR_OAUTH_CONSUMER_KEY, YOUR_OAUTH_CONSUMER_SECRET)
|
128
|
-
end
|
129
|
-
|
130
|
-
end
|
131
|
-
|
132
|
-
</code></pre>
|
133
|
-
|
134
|
-
Note that I'm just storing the Access Token + Secret in the session here - you could equally store them in the database if you felt like refreshing them every 30 minutes ;)
|
135
|
-
|
136
|
-
h2. Implemented interface methods
|
137
|
-
|
138
|
-
h3. GET /api.xro/2.0/contact (get_contact_by_id)
|
139
|
-
|
140
|
-
Gets a contact record for a specific Xero organisation
|
141
|
-
<pre><code> result = gateway.get_contact_by_id(contact_id)
|
142
|
-
contact = result.contact if result.success?</code></pre>
|
143
|
-
|
144
|
-
h3. GET /api.xro/2.0/contact (get_contact_by_number)
|
145
|
-
|
146
|
-
Gets a contact record for a specific Xero organisation
|
147
|
-
<pre><code> gateway.get_contact_by_number(contact_number)</code></pre>
|
148
|
-
|
149
|
-
|
150
|
-
h3. GET /api.xro/2.0/contacts (get_contacts)
|
151
|
-
|
152
|
-
Gets all contact records for a particular Xero customer.
|
153
|
-
<pre><code> gateway.get_contacts(:type => :all, :sort => :name, :direction => :desc)
|
154
|
-
gateway.get_contacts(:type => :all, :modified_since => 1.month.ago) # modified since 1 month ago</code></pre>
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
h3. PUT /api.xro/2.0/contact
|
159
|
-
|
160
|
-
Saves a contact record for a particular Xero customer.
|
161
|
-
<pre><code> contact = gateway.build_contact
|
162
|
-
contact.name = "The contacts name"
|
163
|
-
contact.email = "whoever@something.com"
|
164
|
-
contact.phone.number = "555 123 4567"
|
165
|
-
contact.address.line_1 = "LINE 1 OF THE ADDRESS"
|
166
|
-
contact.address.line_2 = "LINE 2 OF THE ADDRESS"
|
167
|
-
contact.address.city = "WELLINGTON"
|
168
|
-
contact.address.region = "WELLINGTON"
|
169
|
-
contact.address.country = "NEW ZEALAND"
|
170
|
-
contact.address.post_code = "6021"
|
171
|
-
|
172
|
-
contact.save</code></pre>
|
173
|
-
|
174
|
-
|
175
|
-
h3. POST /api.xro/2.0/contact
|
176
|
-
|
177
|
-
Updates an existing contact record.
|
178
|
-
<pre><code> contact_retrieved_from_xero.email = "something_new@something.com"
|
179
|
-
contact_retrieved_from_xero.save</code></pre>
|
180
|
-
|
181
|
-
|
182
|
-
h3. POST /api.xro/2.0/contacts
|
183
|
-
|
184
|
-
Creates a list of contacts or updates them if they have a matching contact_id, contact_number or name.
|
185
|
-
This method uses only a single API request to create/update multiple contacts.
|
186
|
-
<pre><code> contacts = [XeroGateway::Contact.new(:name => 'Joe Bloggs'), XeroGateway::Contact.new(:name => 'Jane Doe')]
|
187
|
-
result = gateway.update_contacts(contacts)</code></pre>
|
188
|
-
|
189
|
-
|
190
|
-
h3. GET /api.xro/2.0/invoice (get_invoice_by_id)
|
191
|
-
|
192
|
-
Gets an invoice record for a specific Xero organisation
|
193
|
-
<pre><code> gateway.get_invoice_by_id(invoice_id)</code></pre>
|
194
|
-
|
195
|
-
|
196
|
-
h3. GET /api.xro/2.0/invoice (get_invoice_by_number)
|
197
|
-
|
198
|
-
Gets an invoice record for a specific Xero organisation
|
199
|
-
<pre><code> gateway.get_invoice_by_number(invoice_number)</code></pre>
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
h3. GET /api.xro/2.0/invoices (get_invoices)
|
204
|
-
|
205
|
-
Gets all invoice records for a particular Xero customer.
|
206
|
-
<pre><code> gateway.get_invoices
|
207
|
-
gateway.get_invoices(:modified_since => 1.month.ago) # modified since 1 month ago</code></pre>
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
h3. PUT /api.xro/2.0/invoice
|
212
|
-
|
213
|
-
Inserts an invoice for a specific organization in Xero (Currently only adding new invoices is allowed).
|
214
|
-
|
215
|
-
Invoice and line item totals are calculated automatically.
|
216
|
-
<pre><code> invoice = gateway.build_invoice({
|
217
|
-
:invoice_type => "ACCREC",
|
218
|
-
:due_date => 1.month.from_now,
|
219
|
-
:invoice_number => "YOUR INVOICE NUMBER",
|
220
|
-
:reference => "YOUR REFERENCE (NOT NECESSARILY UNIQUE!)",
|
221
|
-
:line_amount_types => "Inclusive" # "Inclusive", "Exclusive" or "NoTax"
|
222
|
-
})
|
223
|
-
invoice.contact.name = "THE NAME OF THE CONTACT"
|
224
|
-
invoice.contact.phone.number = "12345"
|
225
|
-
invoice.contact.address.line_1 = "LINE 1 OF THE ADDRESS"
|
226
|
-
|
227
|
-
line_item = XeroGateway::LineItem.new(
|
228
|
-
:description => "THE DESCRIPTION OF THE LINE ITEM",
|
229
|
-
:account_code => 200,
|
230
|
-
:unit_amount => 1000
|
231
|
-
)
|
232
|
-
|
233
|
-
line_item.tracking << XeroGateway::TrackingCategory.new(:name => "tracking category", :options => "tracking option")
|
234
|
-
|
235
|
-
invoice.line_items << line_item
|
236
|
-
|
237
|
-
invoice.create</code></pre>
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
h3. POST /api.xro/2.0/invoice
|
242
|
-
|
243
|
-
Updates an existing invoice record.
|
244
|
-
<pre><code> invoice_retrieved_from_xero.due_date = Date.today
|
245
|
-
invoice_retrieved_from_xero.save</code></pre>
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
h3. PUT /api.xro/2.0/invoices
|
250
|
-
|
251
|
-
Inserts multiple invoices for a specific organization in Xero (currently only adding new invoices is allowed).
|
252
|
-
This method uses only a single API request to create/update multiple contacts.
|
253
|
-
<pre><code> invoices = [XeroGateway::Invoice.new(...), XeroGateway::Invoice.new(...)]
|
254
|
-
result = gateway.create_invoices(invoices)</code></pre>
|
255
|
-
|
256
|
-
h3. GET /api.xro/2.0/credit_note (get_credit_note_by_id)
|
257
|
-
|
258
|
-
Gets an credit_note record for a specific Xero organisation
|
259
|
-
<pre><code> gateway.get_credit_note_by_id(credit_note_id)</code></pre>
|
260
|
-
|
261
|
-
|
262
|
-
h3. GET /api.xro/2.0/credit_note (get_credit_note_by_number)
|
263
|
-
|
264
|
-
Gets a credit note record for a specific Xero organisation
|
265
|
-
<pre><code> gateway.get_credit_note_by_number(credit_note_number)</code></pre>
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
h3. GET /api.xro/2.0/credit_notes (get_credit_notes)
|
270
|
-
|
271
|
-
Gets all credit note records for a particular Xero customer.
|
272
|
-
<pre><code> gateway.get_credit_notes
|
273
|
-
gateway.get_credit_notes(:modified_since => 1.month.ago) # modified since 1 month ago</code></pre>
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
h3. PUT /api.xro/2.0/credit_note
|
278
|
-
|
279
|
-
Inserts a credit note for a specific organization in Xero (Currently only adding new credit notes is allowed).
|
280
|
-
|
281
|
-
CreditNote and line item totals are calculated automatically.
|
282
|
-
<pre><code> credit_note = gateway.build_credit_note({
|
283
|
-
:credit_note_type => "ACCRECCREDIT",
|
284
|
-
:credit_note_number => "YOUR CREDIT NOTE NUMBER",
|
285
|
-
:reference => "YOUR REFERENCE (NOT NECESSARILY UNIQUE!)",
|
286
|
-
:line_amount_types => "Inclusive" # "Inclusive", "Exclusive" or "NoTax"
|
287
|
-
})
|
288
|
-
credit_note.contact.name = "THE NAME OF THE CONTACT"
|
289
|
-
credit_note.contact.phone.number = "12345"
|
290
|
-
credit_note.contact.address.line_1 = "LINE 1 OF THE ADDRESS"
|
291
|
-
credit_note.add_line_item({
|
292
|
-
:description => "THE DESCRIPTION OF THE LINE ITEM",
|
293
|
-
:unit_amount => 1000,
|
294
|
-
:tax_amount => 125,
|
295
|
-
:tracking_category => "THE TRACKING CATEGORY FOR THE LINE ITEM",
|
296
|
-
:tracking_option => "THE TRACKING OPTION FOR THE LINE ITEM"
|
297
|
-
})
|
298
|
-
|
299
|
-
credit_note.create</code></pre>
|
300
|
-
|
301
|
-
|
302
|
-
h3. PUT /api.xro/2.0/credit_notes
|
303
|
-
|
304
|
-
Inserts multiple credit notes for a specific organization in Xero (currently only adding new credit notes is allowed).
|
305
|
-
This method uses only a single API request to create/update multiple contacts.
|
306
|
-
<pre><code> credit_notes = [XeroGateway::CreditNote.new(...), XeroGateway::CreditNote.new(...)]
|
307
|
-
result = gateway.create_credit_notes(credit_notes)</code></pre>
|
308
|
-
|
309
|
-
h3. GET /api.xro/2.0/accounts
|
310
|
-
|
311
|
-
Gets all accounts for a specific organization in Xero.
|
312
|
-
<pre><code> gateway.get_accounts</code></pre>
|
313
|
-
|
314
|
-
For more advanced (and cached) access to the accounts list, use the following.
|
315
|
-
<pre><code> accounts_list = gateway.get_accounts_list</code></pre>
|
316
|
-
|
317
|
-
Finds account with code of '200'
|
318
|
-
<pre><code> sales_account = accounts_list.find_by_code(200)</code></pre>
|
319
|
-
|
320
|
-
Finds all EXPENSE accounts. For a list of valid account types see <code>XeroGateway::Account::TYPE</code>
|
321
|
-
<pre><code> all_expense_accounts = accounts_list.find_all_by_type('EXPENSE')</code></pre>
|
322
|
-
|
323
|
-
Finds all accounts with tax_type == 'OUTPUT'. For a list of valid tax types see <code>XeroGateway::Account::TAX_TYPE</code>
|
324
|
-
<pre><code> all_output_tax_accounts = accounts_list.find_all_by_tax_type('OUTPUT')</code></pre>
|
325
|
-
|
326
|
-
|
327
|
-
h3. GET /api.xro/2.0/tracking
|
328
|
-
|
329
|
-
Gets all tracking categories and their options for a specific organization in Xero.
|
330
|
-
<pre><code> gateway.get_tracking_categories</code></pre>
|
331
|
-
|
332
|
-
h3. GET /api.xero/2.0/Organisation
|
333
|
-
|
334
|
-
Retrieves organisation details for the authorised application.
|
335
|
-
<pre><code> gateway.get_organisation.organisation</code></pre>
|
336
|
-
|
337
|
-
|
338
|
-
h3. GET /api.xero/2.0/Currencies
|
339
|
-
|
340
|
-
Retrieves currencies in use for the authorised application.
|
341
|
-
<pre><code> gateway.get_currencies.currencies</code></pre>
|
342
|
-
|
343
|
-
|
344
|
-
h3. GET /api.xero/2.0/TaxRates
|
345
|
-
|
346
|
-
Retrieves Tax Rates in use for the authorised application.
|
347
|
-
<pre><code> gateway.get_tax_rates.tax_rates</code></pre>
|
348
|
-
|
349
|
-
h2. Logging
|
350
|
-
|
351
|
-
You can specify a logger to use (so you can track down those tricky exceptions) by using:
|
352
|
-
|
353
|
-
<pre>
|
354
|
-
gateway.logger = ActiveSupport::BufferedLogger.new("log_file_name.log")
|
355
|
-
</pre>
|
356
|
-
|
357
|
-
It doesn't have to be a buffered logger - anything that responds to "info" will do just fine.
|
data/init.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require 'xero_gateway'
|