xero_gateway 2.0.11 → 2.0.12
Sign up to get free protection for your applications and to get access to all the features.
- data/README.textile +15 -2
- data/lib/xero_gateway/account.rb +3 -1
- data/lib/xero_gateway/gateway.rb +46 -14
- data/lib/xero_gateway/invoice.rb +18 -10
- data/test/integration/update_invoice_test.rb +31 -0
- data/test/unit/invoice_test.rb +6 -1
- data/test/unit/oauth_test.rb +10 -13
- data/xero_gateway.gemspec +2 -2
- metadata +7 -6
data/README.textile
CHANGED
@@ -58,11 +58,15 @@ Next, you need to redirect your user to the authorisation url for this request t
|
|
58
58
|
redirect_to request_token.authorize_url
|
59
59
|
</code></pre>
|
60
60
|
|
61
|
-
|
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>
|
62
66
|
|
63
67
|
h3. Retrieving an Access Token
|
64
68
|
|
65
|
-
If you've specified a Callback URL when setting up your application, 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):
|
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):
|
66
70
|
|
67
71
|
<pre><code>
|
68
72
|
gateway.authorize_from_request(request_token.token, request_token.secret, :oauth_verifier => params[:oauth_verifier])
|
@@ -230,6 +234,15 @@ Invoice and line item totals are calculated automatically.
|
|
230
234
|
invoice.create</code></pre>
|
231
235
|
|
232
236
|
|
237
|
+
|
238
|
+
h3. POST /api.xro/2.0/invoice
|
239
|
+
|
240
|
+
Updates an existing invoice record.
|
241
|
+
<pre><code> invoice_retrieved_from_xero.due_date = Date.today
|
242
|
+
invoice_retrieved_from_xero.save</code></pre>
|
243
|
+
|
244
|
+
|
245
|
+
|
233
246
|
h3. PUT /api.xro/2.0/invoices
|
234
247
|
|
235
248
|
Inserts multiple invoices for a specific organization in Xero (currently only adding new invoices is allowed).
|
data/lib/xero_gateway/account.rb
CHANGED
@@ -26,7 +26,9 @@ module XeroGateway
|
|
26
26
|
'ZERORATEDINPUT' => 'Expense purchased from overseas (UK only)',
|
27
27
|
'RRINPUT' => 'Reduced rate VAT on expenses (UK Only)',
|
28
28
|
'EXEMPTOUTPUT' => 'VAT on sales exempt from VAT (UK only)',
|
29
|
-
'
|
29
|
+
'ECZROUTPUT' => 'EC Zero-rated output',
|
30
|
+
'OUTPUT' => 'OUTPUT (old rate)',
|
31
|
+
'OUTPUT2' => 'OUTPUT2',
|
30
32
|
'SROUTPUT' => 'SROUTPUT',
|
31
33
|
'ZERORATEDOUTPUT' => 'Sales made from overseas (UK only)',
|
32
34
|
'RROUTPUT' => 'Reduced rate VAT on sales (UK Only)',
|
data/lib/xero_gateway/gateway.rb
CHANGED
@@ -197,21 +197,24 @@ module XeroGateway
|
|
197
197
|
#
|
198
198
|
# create_invoice(invoice)
|
199
199
|
def create_invoice(invoice)
|
200
|
-
|
201
|
-
response_xml = http_put(@client, "#{@xero_url}/Invoices", request_xml)
|
202
|
-
response = parse_response(response_xml, {:request_xml => request_xml}, {:request_signature => 'PUT/invoice'})
|
203
|
-
|
204
|
-
# Xero returns invoices inside an <Invoices> tag, even though there's only ever
|
205
|
-
# one for this request
|
206
|
-
response.response_item = response.invoices.first
|
207
|
-
|
208
|
-
if response.success? && response.invoice && response.invoice.invoice_id
|
209
|
-
invoice.invoice_id = response.invoice.invoice_id
|
210
|
-
end
|
211
|
-
|
212
|
-
response
|
200
|
+
save_invoice(invoice)
|
213
201
|
end
|
214
|
-
|
202
|
+
|
203
|
+
#
|
204
|
+
# Updates an existing Xero invoice
|
205
|
+
#
|
206
|
+
# Usage :
|
207
|
+
#
|
208
|
+
# invoice = xero_gateway.get_invoice(some_invoice_id)
|
209
|
+
# invoice.due_date = Date.today
|
210
|
+
#
|
211
|
+
# xero_gateway.update_invoice(invoice)
|
212
|
+
|
213
|
+
def update_invoice(invoice)
|
214
|
+
raise "invoice_id is required for updating invoices" if invoice.invoice_id.nil?
|
215
|
+
save_invoice(invoice)
|
216
|
+
end
|
217
|
+
|
215
218
|
#
|
216
219
|
# Creates an array of invoices with a single API request.
|
217
220
|
#
|
@@ -425,6 +428,35 @@ module XeroGateway
|
|
425
428
|
response
|
426
429
|
end
|
427
430
|
|
431
|
+
# Create or update an invoice record based on if it has an invoice_id.
|
432
|
+
def save_invoice(invoice)
|
433
|
+
request_xml = invoice.to_xml
|
434
|
+
|
435
|
+
response_xml = nil
|
436
|
+
create_or_save = nil
|
437
|
+
if invoice.invoice_id.nil?
|
438
|
+
# Create new invoice record.
|
439
|
+
response_xml = http_put(@client, "#{@xero_url}/Invoices", request_xml, {})
|
440
|
+
create_or_save = :create
|
441
|
+
else
|
442
|
+
# Update existing invoice record.
|
443
|
+
response_xml = http_post(@client, "#{@xero_url}/Invoices", request_xml, {})
|
444
|
+
create_or_save = :save
|
445
|
+
end
|
446
|
+
|
447
|
+
response = parse_response(response_xml, {:request_xml => request_xml}, {:request_signature => "#{create_or_save == :create ? 'PUT' : 'POST'}/invoice"})
|
448
|
+
|
449
|
+
# Xero returns invoices inside an <Invoices> tag, even though there's only ever
|
450
|
+
# one for this request
|
451
|
+
response.response_item = response.invoices.first
|
452
|
+
|
453
|
+
if response.success? && response.invoice && response.invoice.invoice_id
|
454
|
+
invoice.invoice_id = response.invoice.invoice_id
|
455
|
+
end
|
456
|
+
|
457
|
+
response
|
458
|
+
end
|
459
|
+
|
428
460
|
def parse_response(raw_response, request = {}, options = {})
|
429
461
|
|
430
462
|
response = XeroGateway::Response.new
|
data/lib/xero_gateway/invoice.rb
CHANGED
@@ -50,7 +50,7 @@ module XeroGateway
|
|
50
50
|
@line_items_downloaded = (params.delete(:line_items_downloaded) == true)
|
51
51
|
|
52
52
|
params = {
|
53
|
-
:line_amount_types => "
|
53
|
+
:line_amount_types => "Exclusive"
|
54
54
|
}.merge(params)
|
55
55
|
|
56
56
|
params.each do |k,v|
|
@@ -209,10 +209,14 @@ module XeroGateway
|
|
209
209
|
return true
|
210
210
|
end
|
211
211
|
|
212
|
-
# General purpose
|
213
|
-
# If
|
212
|
+
# General purpose create/save method.
|
213
|
+
# If invoice_id is nil then create, otherwise, attempt to save.
|
214
214
|
def save
|
215
|
-
|
215
|
+
if invoice_id.nil?
|
216
|
+
create
|
217
|
+
else
|
218
|
+
update
|
219
|
+
end
|
216
220
|
end
|
217
221
|
|
218
222
|
# Creates this invoice record (using gateway.create_invoice) with the associated gateway.
|
@@ -222,19 +226,24 @@ module XeroGateway
|
|
222
226
|
gateway.create_invoice(self)
|
223
227
|
end
|
224
228
|
|
225
|
-
#
|
226
|
-
|
227
|
-
|
229
|
+
# Updates this invoice record (using gateway.update_invoice) with the associated gateway.
|
230
|
+
# If no gateway set, raise a Xero::Invoice::NoGatewayError exception.
|
231
|
+
def update
|
232
|
+
raise NoGatewayError unless gateway
|
233
|
+
gateway.update_invoice(self)
|
234
|
+
end
|
235
|
+
|
228
236
|
def to_xml(b = Builder::XmlMarkup.new)
|
229
237
|
b.Invoice {
|
238
|
+
b.InvoiceID self.invoice_id if self.invoice_id
|
239
|
+
b.InvoiceNumber self.invoice_number if invoice_number
|
230
240
|
b.Type self.invoice_type
|
241
|
+
b.CurrencyCode self.currency_code if self.currency_code
|
231
242
|
contact.to_xml(b)
|
232
243
|
b.Date Invoice.format_date(self.date || Date.today)
|
233
244
|
b.DueDate Invoice.format_date(self.due_date) if self.due_date
|
234
245
|
b.Status self.invoice_status if self.invoice_status
|
235
|
-
b.InvoiceNumber self.invoice_number if invoice_number
|
236
246
|
b.Reference self.reference if self.reference
|
237
|
-
b.CurrencyCode self.currency_code if self.currency_code
|
238
247
|
b.LineAmountTypes self.line_amount_types
|
239
248
|
b.LineItems {
|
240
249
|
self.line_items.each do |line_item|
|
@@ -253,7 +262,6 @@ module XeroGateway
|
|
253
262
|
when "InvoiceNumber" then invoice.invoice_number = element.text
|
254
263
|
when "Type" then invoice.invoice_type = element.text
|
255
264
|
when "CurrencyCode" then invoice.currency_code = element.text
|
256
|
-
when "Type" then invoice.invoice_type = element.text
|
257
265
|
when "Contact" then invoice.contact = Contact.from_xml(element)
|
258
266
|
when "Date" then invoice.date = parse_date(element.text)
|
259
267
|
when "DueDate" then invoice.due_date = parse_date(element.text)
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class UpdateInvoiceTest < Test::Unit::TestCase
|
4
|
+
include TestHelper
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@gateway = XeroGateway::Gateway.new(CONSUMER_KEY, CONSUMER_SECRET)
|
8
|
+
|
9
|
+
if STUB_XERO_CALLS
|
10
|
+
@gateway.xero_url = "DUMMY_URL"
|
11
|
+
|
12
|
+
@gateway.stubs(:http_put).with {|client, url, body, params| url =~ /Invoices$/ }.returns(get_file_as_string("create_invoice.xml"))
|
13
|
+
@gateway.stubs(:http_post).with {|client, url, body, params| url =~ /Invoices$/ }.returns(get_file_as_string("invoice.xml"))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_update_invoice
|
18
|
+
invoice = @gateway.create_invoice(dummy_invoice).invoice
|
19
|
+
|
20
|
+
today = Date.today
|
21
|
+
invoice.due_date = today
|
22
|
+
|
23
|
+
result = @gateway.update_invoice(invoice)
|
24
|
+
|
25
|
+
assert result.success?
|
26
|
+
assert !result.request_xml.nil?
|
27
|
+
assert !result.response_xml.nil?
|
28
|
+
assert_equal invoice.invoice_id, result.invoice.invoice_id
|
29
|
+
assert_equal today, result.invoice.due_date if !STUB_XERO_CALLS
|
30
|
+
end
|
31
|
+
end
|
data/test/unit/invoice_test.rb
CHANGED
@@ -236,6 +236,11 @@ class InvoiceTest < Test::Unit::TestCase
|
|
236
236
|
assert_equal(2, invoice.line_items.size)
|
237
237
|
end
|
238
238
|
end
|
239
|
+
|
240
|
+
def test_instantiate_invoice_with_default_line_amount_types
|
241
|
+
invoice = XeroGateway::Invoice.new
|
242
|
+
assert_equal(invoice.line_amount_types, 'Exclusive')
|
243
|
+
end
|
239
244
|
|
240
245
|
private
|
241
246
|
|
@@ -299,4 +304,4 @@ class InvoiceTest < Test::Unit::TestCase
|
|
299
304
|
|
300
305
|
invoice
|
301
306
|
end
|
302
|
-
end
|
307
|
+
end
|
data/test/unit/oauth_test.rb
CHANGED
@@ -65,19 +65,16 @@ class OAuthTest < Test::Unit::TestCase
|
|
65
65
|
assert_equal "asecret", xero.access_token.secret
|
66
66
|
end
|
67
67
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
#
|
79
|
-
# xero.request_token(:oauth_callback => "http://callback.com")
|
80
|
-
# end
|
68
|
+
should "be able to create request token with callback url" do
|
69
|
+
xero = XeroGateway::OAuth.new('token', 'secret')
|
70
|
+
consumer = OAuth::Consumer.new('token', 'secret')
|
71
|
+
xero.stubs(:consumer).returns(consumer)
|
72
|
+
|
73
|
+
request_token = mock('request token')
|
74
|
+
consumer.expects(:get_request_token).with(:oauth_callback => "http://callback.com").returns(request_token)
|
75
|
+
|
76
|
+
xero.request_token(:oauth_callback => "http://callback.com")
|
77
|
+
end
|
81
78
|
|
82
79
|
should "be able to create access token with oauth verifier" do
|
83
80
|
xero = XeroGateway::OAuth.new('token', 'secret')
|
data/xero_gateway.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "xero_gateway"
|
3
|
-
s.version = "2.0.
|
4
|
-
s.date = "2011-
|
3
|
+
s.version = "2.0.12"
|
4
|
+
s.date = "2011-05-25"
|
5
5
|
s.summary = "Enables ruby based applications to communicate with the Xero API"
|
6
6
|
s.email = "tim@connorsoftware.com"
|
7
7
|
s.homepage = "http://github.com/tlconnor/xero_gateway"
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xero_gateway
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 2
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 2.0.
|
9
|
+
- 12
|
10
|
+
version: 2.0.12
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Tim Connor
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2011-
|
19
|
+
date: 2011-05-25 00:00:00 +12:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
@@ -121,6 +121,7 @@ files:
|
|
121
121
|
- test/integration/get_tax_rates_test.rb
|
122
122
|
- test/integration/get_tracking_categories_test.rb
|
123
123
|
- test/integration/update_contact_test.rb
|
124
|
+
- test/integration/update_invoice_test.rb
|
124
125
|
- test/test_helper.rb
|
125
126
|
- test/unit/account_test.rb
|
126
127
|
- test/unit/contact_test.rb
|
@@ -133,7 +134,7 @@ files:
|
|
133
134
|
- test/unit/tax_rate_test.rb
|
134
135
|
- test/unit/tracking_category_test.rb
|
135
136
|
- lib/xero_gateway/ca-certificates.crt
|
136
|
-
has_rdoc:
|
137
|
+
has_rdoc: false
|
137
138
|
homepage: http://github.com/tlconnor/xero_gateway
|
138
139
|
licenses: []
|
139
140
|
|
@@ -163,7 +164,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
163
164
|
requirements: []
|
164
165
|
|
165
166
|
rubyforge_project:
|
166
|
-
rubygems_version: 1.
|
167
|
+
rubygems_version: 1.3.8
|
167
168
|
signing_key:
|
168
169
|
specification_version: 3
|
169
170
|
summary: Enables ruby based applications to communicate with the Xero API
|