tlconnor-xero_gateway 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.textile ADDED
@@ -0,0 +1,14 @@
1
+ h2. 1.0.1, releases 01/12/2008
2
+
3
+ # Added implementation of GET /api.xro/1.0/accounts
4
+
5
+
6
+ h2. 1.0.0, released 01/12/2008
7
+
8
+ * Initial release, including:
9
+ * PUT /api.xro/1.0/contact
10
+ * GET /api.xro/1.0/contact
11
+ * GET /api.xro/1.0/contacts
12
+ * PUT /api.xro/1.0/invoice
13
+ * GET /api.xro/1.0/invoice
14
+ * GET /api.xro/1.0/invoices
data/LICENSE ADDED
@@ -0,0 +1,14 @@
1
+ Copyright (c) 2008 Tim Connor <tlconnor@gmail.com>
2
+
3
+ Permission to use, copy, modify, and/or distribute this software for any
4
+ purpose with or without fee is hereby granted, provided that the above
5
+ copyright notice and this permission notice appear in all copies.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
+
data/README.textile ADDED
@@ -0,0 +1,119 @@
1
+ h1. Xero API wrapper
2
+
3
+ h2. Introduction
4
+
5
+ This library is designed to help ruby 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. Prerequisites
8
+
9
+ To use the Xero API you must have a Xero API Key. If you don't know what this is, and don't know how to get one, this library is probably not for you.
10
+
11
+ h2. Usage
12
+
13
+ <pre><code> require 'xero_gateway'
14
+ gateway = XeroGateway::Gateway.new(
15
+ :customer_key => "THE_CUSTOMER_KEY_GENERATED_FOR_YOUR_APP",
16
+ :api_key => "YOUR_XERO_API_KEY",
17
+ :xero_url => "THE URL FOR THE XERO API (test or live)"
18
+ )</code></pre>
19
+
20
+
21
+ h2. Implemented interface methods
22
+
23
+ h3. GET /api.xro/1.0/contact (get_contact_by_id)
24
+
25
+ Example:
26
+ <pre><code>
27
+ result = gateway.get_contact_by_id(contact_id)
28
+ contact = result.contact if result.success?
29
+ </code></pre>
30
+
31
+ h3. GET /api.xro/1.0/contact (get_contact_by_number)
32
+
33
+ Example:
34
+ <pre><code>
35
+ gateway.get_contact_by_number(contact_number)
36
+ </code></pre>
37
+
38
+ h3. GET /api.xro/1.0/contacts (get_contacts)
39
+
40
+ Example:
41
+ <pre><code>
42
+ gateway.get_contacts(:type => :all, :sort => :name, :direction => :desc)
43
+ </code></pre>
44
+
45
+ h3. PUT /api.xro/1.0/contact
46
+
47
+ Example:
48
+ <pre><code>
49
+ contact = XeroGateway::Contact.new
50
+ contact.name = "The contacts name"
51
+ contact.email = "whoever@something.com"
52
+ contact.phone.number = "555 123 4567"
53
+ contact.address.line_1 = "LINE 1 OF THE ADDRESS"
54
+ contact.address.line_2 = "LINE 2 OF THE ADDRESS"
55
+ contact.address.city = "WELLINGTON"
56
+ contact.address.region = "WELLINGTON"
57
+ contact.address.country = "NEW ZEALAND"
58
+ contact.address.post_code = "6021"
59
+
60
+ gateway.create_contact(contact)
61
+ </code></pre>
62
+
63
+ h3. GET /api.xro/1.0/invoice (get_invoice_by_id)
64
+
65
+ Example:
66
+ <pre><code>
67
+ gateway.get_invoice_by_id(invoice_id)
68
+ </code></pre>
69
+
70
+ h3. GET /api.xro/1.0/invoice (get_invoice_by_number)
71
+
72
+ Example:
73
+ <pre><code>
74
+ gateway.get_invoice_by_number(invoice_number)
75
+ </code></pre>
76
+
77
+ h3. GET /api.xro/1.0/invoices (get_invoices)
78
+
79
+ Example:
80
+ <pre><code>
81
+ gateway.get_invoices(modified_since = nil)
82
+ </code></pre>
83
+
84
+ h3. PUT /api.xro/1.0/invoice
85
+
86
+ Example:
87
+ <pre><code>
88
+ invoice = XeroGateway::Invoice.new({
89
+ :invoice_type => "ACCREC",
90
+ :due_date => 1.month.from_now,
91
+ :invoice_number => "YOUR INVOICE NUMBER",
92
+ :reference => "YOUR REFERENCE (NOT NECESSARILY UNIQUE!)",
93
+ :tax_inclusive => true,
94
+ :includes_tax => false,
95
+ :sub_total => 1000,
96
+ :total_tax => 125,
97
+ :total => 1250
98
+ })
99
+ invoice.contact = XeroGateway::Contact.new(:name => "THE NAME OF THE CONTACT")
100
+ invoice.contact.phone.number = "12345"
101
+ invoice.contact.address.line_1 = "LINE 1 OF THE ADDRESS"
102
+ invoice.line_items << XeroGateway::LineItem.new(
103
+ :description => "THE DESCRIPTION OF THE LINE ITEM",
104
+ :unit_amount => 1000,
105
+ :tax_amount => 125,
106
+ :line_amount => 1000,
107
+ :tracking_category => "THE TRACKING CATEGORY FOR THE LINE ITEM",
108
+ :tracking_option => "THE TRACKING OPTION FOR THE LINE ITEM"
109
+ )
110
+
111
+ gateway.create_invoice(invoice)
112
+ </code></pre>
113
+
114
+ h3. GET /api.xro/1.0/accounts
115
+
116
+ Example:
117
+ <pre><code>
118
+ gateway.get_accounts
119
+ </code></pre>
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ desc 'Test the xero gateway.'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'lib'
11
+ t.pattern = 'test/**/*_test.rb'
12
+ t.verbose = true
13
+ end
14
+
@@ -0,0 +1,35 @@
1
+ # Copyright (c) 2008 Tim Connor <tlconnor@gmail.com>
2
+ #
3
+ # Permission to use, copy, modify, and/or distribute this software for any
4
+ # purpose with or without fee is hereby granted, provided that the above
5
+ # copyright notice and this permission notice appear in all copies.
6
+ #
7
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
+
15
+ require 'cgi'
16
+ require "uri"
17
+ require 'net/https'
18
+ require "rexml/document"
19
+ require "builder"
20
+ require "bigdecimal"
21
+
22
+ require File.dirname(__FILE__) + "/xero_gateway/http"
23
+ require File.dirname(__FILE__) + "/xero_gateway/dates"
24
+ require File.dirname(__FILE__) + "/xero_gateway/money"
25
+ require File.dirname(__FILE__) + "/xero_gateway/response"
26
+ require File.dirname(__FILE__) + "/xero_gateway/line_item"
27
+ require File.dirname(__FILE__) + "/xero_gateway/invoice"
28
+ require File.dirname(__FILE__) + "/xero_gateway/contact"
29
+ require File.dirname(__FILE__) + "/xero_gateway/address"
30
+ require File.dirname(__FILE__) + "/xero_gateway/phone"
31
+ require File.dirname(__FILE__) + "/xero_gateway/account"
32
+ require File.dirname(__FILE__) + "/xero_gateway/messages/contact_message"
33
+ require File.dirname(__FILE__) + "/xero_gateway/messages/invoice_message"
34
+ require File.dirname(__FILE__) + "/xero_gateway/messages/account_message"
35
+ require File.dirname(__FILE__) + "/xero_gateway/gateway"
@@ -0,0 +1,34 @@
1
+ # Copyright (c) 2008 Tim Connor <tlconnor@gmail.com>
2
+ #
3
+ # Permission to use, copy, modify, and/or distribute this software for any
4
+ # purpose with or without fee is hereby granted, provided that the above
5
+ # copyright notice and this permission notice appear in all copies.
6
+ #
7
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
+
15
+ module XeroGateway
16
+ class Account
17
+ attr_accessor :code, :name, :type, :tax_type, :description
18
+
19
+ def initialize(params = {})
20
+ params.each do |k,v|
21
+ self.instance_variable_set("@#{k}", v) ## create and initialize an instance variable for this key/value pair
22
+ self.send("#{k}=", v)
23
+ end
24
+ end
25
+
26
+ def ==(other)
27
+ equal = true
28
+ [:code, :name, :type, :tax_type, :description].each do |field|
29
+ equal &&= (send(field) == other.send(field))
30
+ end
31
+ return equal
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,47 @@
1
+ # Copyright (c) 2008 Tim Connor <tlconnor@gmail.com>
2
+ #
3
+ # Permission to use, copy, modify, and/or distribute this software for any
4
+ # purpose with or without fee is hereby granted, provided that the above
5
+ # copyright notice and this permission notice appear in all copies.
6
+ #
7
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
+
15
+ module XeroGateway
16
+ class Address
17
+ attr_accessor :address_type, :line_1, :line_2, :line_3, :line_4, :city, :region, :post_code, :country
18
+
19
+ def initialize(params = {})
20
+ params = {
21
+ :address_type => "DEFAULT"
22
+ }.merge(params)
23
+
24
+ params.each do |k,v|
25
+ self.instance_variable_set("@#{k}", v) ## create and initialize an instance variable for this key/value pair
26
+ self.send("#{k}=", v)
27
+ end
28
+ end
29
+
30
+ def self.parse(string)
31
+ address = Address.new
32
+
33
+ string.split("\r\n").each_with_index do |line, index|
34
+ address.instance_variable_set("@line_#{index+1}", line)
35
+ end
36
+ address
37
+ end
38
+
39
+ def ==(other)
40
+ equal = true
41
+ [:address_type, :line_1, :line_2, :line_3, :line_4, :city, :region, :post_code, :country].each do |field|
42
+ equal &&= (send(field) == other.send(field))
43
+ end
44
+ return equal
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,54 @@
1
+ # Copyright (c) 2008 Tim Connor <tlconnor@gmail.com>
2
+ #
3
+ # Permission to use, copy, modify, and/or distribute this software for any
4
+ # purpose with or without fee is hereby granted, provided that the above
5
+ # copyright notice and this permission notice appear in all copies.
6
+ #
7
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
+
15
+ module XeroGateway
16
+ class Contact
17
+ attr_accessor :id, :contact_number, :status, :name, :email, :addresses, :phones, :updated_at
18
+
19
+ def initialize(params = {})
20
+ params = {}.merge(params)
21
+ params.each do |k,v|
22
+ self.instance_variable_set("@#{k}", v) ## create and initialize an instance variable for this key/value pair
23
+ self.send("#{k}=", v)
24
+ end
25
+
26
+ @phones ||= []
27
+ @addresses ||= []
28
+ end
29
+
30
+ def address=(address)
31
+ self.addresses = [address]
32
+ end
33
+
34
+ def address
35
+ self.addresses[0] ||= Address.new
36
+ end
37
+
38
+ def phone=(phone)
39
+ self.phones = [phone]
40
+ end
41
+
42
+ def phone
43
+ self.phones[0] ||= Phone.new
44
+ end
45
+
46
+ def ==(other)
47
+ equal = true
48
+ [:contact_number, :status, :name, :email, :addresses, :phones].each do |field|
49
+ equal &&= (send(field) == other.send(field))
50
+ end
51
+ return equal
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,31 @@
1
+ # Copyright (c) 2008 Tim Connor <tlconnor@gmail.com>
2
+ #
3
+ # Permission to use, copy, modify, and/or distribute this software for any
4
+ # purpose with or without fee is hereby granted, provided that the above
5
+ # copyright notice and this permission notice appear in all copies.
6
+ #
7
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
+
15
+ module XeroGateway
16
+ module Dates
17
+ def self.included(base)
18
+ base.extend(ClassMethods)
19
+ end
20
+
21
+ module ClassMethods
22
+ def format_date_time(time)
23
+ return time.strftime("%Y-%m-%dT%H:%M:%S")
24
+ end
25
+
26
+ def parse_date_time(time)
27
+ Time.local(time[0..3].to_i, time[5..6].to_i, time[8..9].to_i, time[11..12].to_i, time[14..15].to_i, time[17..18].to_i)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,283 @@
1
+ # Copyright (c) 2008 Tim Connor <tlconnor@gmail.com>
2
+ #
3
+ # Permission to use, copy, modify, and/or distribute this software for any
4
+ # purpose with or without fee is hereby granted, provided that the above
5
+ # copyright notice and this permission notice appear in all copies.
6
+ #
7
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
+
15
+ module XeroGateway
16
+ class Gateway
17
+ include Http
18
+
19
+ attr_accessor :xero_url, :customer_key, :api_key
20
+
21
+ def initialize(params)
22
+ @xero_url = params[:xero_url] || "https://networktest.xero.com/api.xro/1.0"
23
+ @customer_key = params[:customer_key]
24
+ @api_key = params[:api_key]
25
+ end
26
+
27
+ # Retrieve all contacts from Xero
28
+ # Usage get_contacts(:type => :all, :sort => :name, :direction => :desc)
29
+ def get_contacts(options = {})
30
+ request_params = {}
31
+ request_params[:type] = options[:type] if options[:type]
32
+ request_params[:sortBy] = options[:sort] if options[:sort]
33
+ request_params[:direction] = options[:direction] if options[:direction]
34
+
35
+ response_xml = http_get("#{@xero_url}/contacts", request_params)
36
+
37
+ doc = REXML::Document.new(response_xml)
38
+
39
+ # Create the response object
40
+ response = build_response(doc)
41
+
42
+ # Add the contacts to the response
43
+ if response.success?
44
+ response.response_item = []
45
+ REXML::XPath.each(doc, "/Response/Contacts/Contact") do |contact_element|
46
+ response.response_item << XeroGateway::Messages::ContactMessage.from_xml(contact_element)
47
+ end
48
+ end
49
+
50
+ # Add the request and response XML to the response object
51
+ response.request_params = request_params
52
+ response.response_xml = response_xml
53
+ response
54
+ end
55
+
56
+ # Retrieve a contact from Xero
57
+ # Usage get_contact_by_id(contact_id)
58
+ def get_contact_by_id(contact_id)
59
+ get_contact(contact_id)
60
+ end
61
+
62
+ # Retrieve a contact from Xero
63
+ # Usage get_contact_by_id(contact_id)
64
+ def get_contact_by_number(contact_number)
65
+ get_contact(nil, contact_number)
66
+ end
67
+
68
+
69
+ # Creates a contact in Xero
70
+ #
71
+ # Usage :
72
+ #
73
+ # contact = XeroGateway::Contact.new(:name => "THE NAME OF THE CONTACT #{Time.now.to_i}")
74
+ # contact.email = "whoever@something.com"
75
+ # contact.phone.number = "12345"
76
+ # contact.address.line_1 = "LINE 1 OF THE ADDRESS"
77
+ # contact.address.line_2 = "LINE 2 OF THE ADDRESS"
78
+ # contact.address.line_3 = "LINE 3 OF THE ADDRESS"
79
+ # contact.address.line_4 = "LINE 4 OF THE ADDRESS"
80
+ # contact.address.city = "WELLINGTON"
81
+ # contact.address.region = "WELLINGTON"
82
+ # contact.address.country = "NEW ZEALAND"
83
+ # contact.address.post_code = "6021"
84
+ #
85
+ # create_contact(contact)
86
+ def create_contact(contact)
87
+ request_xml = XeroGateway::Messages::ContactMessage.build_xml(contact)
88
+ response_xml = http_put("#{@xero_url}/contact", request_xml, {})
89
+
90
+ doc = REXML::Document.new(response_xml)
91
+
92
+ # Create the response object
93
+ response = build_response(doc)
94
+
95
+ # Add the invoice to the response
96
+ if response.success?
97
+ response.response_item = XeroGateway::Messages::ContactMessage.from_xml(REXML::XPath.first(doc, "/Response/Contact"))
98
+ end
99
+
100
+ # Add the request and response XML to the response object
101
+ response.request_xml = request_xml
102
+ response.response_xml = response_xml
103
+
104
+ response
105
+ end
106
+
107
+ # Retrieves an invoice from Xero based on its GUID
108
+ #
109
+ # Usage : get_invoice_by_id("8c69117a-60ae-4d31-9eb4-7f5a76bc4947")
110
+ def get_invoice_by_id(invoice_id)
111
+ get_invoice(invoice_id)
112
+ end
113
+
114
+ # Retrieves an invoice from Xero based on its number
115
+ #
116
+ # Usage : get_invoice_by_number("OIT00526")
117
+ def get_invoice_by_number(invoice_number)
118
+ get_invoice(nil, invoice_number)
119
+ end
120
+
121
+ # Retrieves all invoices from Xero
122
+ #
123
+ # Usage : get_invoices
124
+ # get_invoices(modified_since)
125
+ def get_invoices(modified_since = nil)
126
+ request_params = modified_since ? {:modifiedSince => modified_since.strftime("%Y-%m-%d")} : {}
127
+
128
+ response_xml = http_get("#{@xero_url}/invoices", request_params)
129
+
130
+ doc = REXML::Document.new(response_xml)
131
+
132
+ # Create the response object
133
+ response = build_response(doc)
134
+
135
+ # Add the invoices to the response
136
+ if response.success?
137
+ response.response_item = []
138
+ REXML::XPath.first(doc, "/Response/Invoices").children.each do |invoice_element|
139
+ response.response_item << XeroGateway::Messages::InvoiceMessage.from_xml(invoice_element)
140
+ end
141
+ end
142
+
143
+ # Add the request and response XML to the response object
144
+ response.request_params = request_params
145
+ response.response_xml = response_xml
146
+ response
147
+ end
148
+
149
+ # Creates an invoice in Xero based on an invoice object
150
+ #
151
+ # Usage :
152
+ #
153
+ # invoice = XeroGateway::Invoice.new({
154
+ # :invoice_type => "ACCREC",
155
+ # :due_date => 1.month.from_now,
156
+ # :invoice_number => "YOUR INVOICE NUMBER",
157
+ # :reference => "YOUR REFERENCE (NOT NECESSARILY UNIQUE!)",
158
+ # :includes_tax => false,
159
+ # :sub_total => 1000,
160
+ # :total_tax => 125,
161
+ # :total => 1125
162
+ # })
163
+ # invoice.contact = XeroGateway::Contact.new(:name => "THE NAME OF THE CONTACT")
164
+ # invoice.contact.phone.number = "12345"
165
+ # invoice.contact.address.line_1 = "LINE 1 OF THE ADDRESS"
166
+ # invoice.line_items << XeroGateway::LineItem.new(
167
+ # :description => "THE DESCRIPTION OF THE LINE ITEM",
168
+ # :unit_amount => 100,
169
+ # :tax_amount => 12.5,
170
+ # :line_amount => 125,
171
+ # :tracking_category => "THE TRACKING CATEGORY FOR THE LINE ITEM",
172
+ # :tracking_option => "THE TRACKING OPTION FOR THE LINE ITEM"
173
+ # )
174
+ #
175
+ # create_invoice(invoice)
176
+ def create_invoice(invoice)
177
+ request_xml = XeroGateway::Messages::InvoiceMessage.build_xml(invoice)
178
+ response_xml = http_put("#{@xero_url}/invoice", request_xml)
179
+
180
+ doc = REXML::Document.new(response_xml)
181
+
182
+ # Create the response object
183
+ response = build_response(doc)
184
+
185
+ # Add the invoice to the response
186
+ if response.success?
187
+ response.response_item = XeroGateway::Messages::InvoiceMessage.from_xml(REXML::XPath.first(doc, "/Response/Invoice"))
188
+ end
189
+
190
+ # Add the request and response XML to the response object
191
+ response.request_xml = request_xml
192
+ response.response_xml = response_xml
193
+
194
+ response
195
+ end
196
+
197
+ #
198
+ # Gets all accounts for a specific organization in Xero.
199
+ #
200
+ def get_accounts
201
+ response_xml = http_get("#{xero_url}/accounts")
202
+
203
+ doc = REXML::Document.new(response_xml)
204
+
205
+ # Create the response object
206
+ response = build_response(doc)
207
+
208
+ # Add the accounts to the response
209
+ response.response_item = []
210
+ REXML::XPath.first(doc, "/Response/Accounts").children.each do |account_element|
211
+ response.response_item << XeroGateway::Messages::AccountMessage.from_xml(account_element)
212
+ end
213
+
214
+ # Add the request and response XML to the response object
215
+ response.response_xml = response_xml
216
+ response
217
+ end
218
+
219
+
220
+
221
+ private
222
+
223
+ def get_invoice(invoice_id = nil, invoice_number = nil)
224
+ request_params = invoice_id ? {:invoiceID => invoice_id} : {:invoiceNumber => invoice_number}
225
+ response_xml = http_get("#{@xero_url}/invoice", request_params)
226
+
227
+ doc = REXML::Document.new(response_xml)
228
+
229
+ # Create the response object
230
+ response = build_response(doc)
231
+
232
+ # Add the invoice to the response
233
+ response.response_item = XeroGateway::Messages::InvoiceMessage.from_xml(REXML::XPath.first(doc, "/Response/Invoice")) if response.success?
234
+
235
+ # Add the request and response XML to the response object
236
+ response.request_params = request_params
237
+ response.response_xml = response_xml
238
+ response
239
+ end
240
+
241
+ def get_contact(contact_id = nil, contact_number = nil)
242
+ request_params = contact_id ? {:contactID => contact_id} : {:contactNumber => contact_number}
243
+ response_xml = http_get("#{@xero_url}/contact", request_params)
244
+
245
+ doc = REXML::Document.new(response_xml)
246
+
247
+ # Create the response object
248
+ response = build_response(doc)
249
+
250
+ # Add the invoice to the response
251
+ response.response_item = XeroGateway::Messages::ContactMessage.from_xml(REXML::XPath.first(doc, "/Response/Contact")) if response.success?
252
+
253
+ # Add the request and response XML to the response object
254
+ response.request_params = request_params
255
+ response.response_xml = response_xml
256
+ response
257
+ end
258
+
259
+
260
+
261
+ def build_response(response_document)
262
+ response = XeroGateway::Response.new({
263
+ :id => REXML::XPath.first(response_document, "/Response/ID").text,
264
+ :status => REXML::XPath.first(response_document, "/Response/Status").text,
265
+ :provider => REXML::XPath.first(response_document, "/Response/ProviderName").text,
266
+ :date_time => REXML::XPath.first(response_document, "/Response/DateTimeUTC").text,
267
+ })
268
+
269
+ # Add any errors to the response object
270
+ if !response.success?
271
+ REXML::XPath.each(response_document, "/Response/Error") do |error|
272
+ response.errors << {
273
+ :date_time => REXML::XPath.first(error, "/DateTime").text,
274
+ :type => REXML::XPath.first(error, "/ExceptionType").text,
275
+ :message => REXML::XPath.first(error, "/Message").text
276
+ }
277
+ end
278
+ end
279
+
280
+ response
281
+ end
282
+ end
283
+ end