tlconnor-xero_gateway 1.0.2 → 1.0.3

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.
Files changed (42) hide show
  1. data/CHANGELOG.textile +8 -2
  2. data/lib/xero_gateway/account.rb +27 -0
  3. data/lib/xero_gateway/contact.rb +88 -0
  4. data/lib/xero_gateway/error.rb +19 -0
  5. data/lib/xero_gateway/gateway.rb +54 -157
  6. data/lib/xero_gateway/invoice.rb +116 -0
  7. data/lib/xero_gateway/response.rb +1 -0
  8. data/lib/xero_gateway/tracking_category.rb +26 -0
  9. data/lib/xero_gateway.rb +1 -4
  10. data/test/integration/create_contact_test.rb +3 -1
  11. data/test/integration/create_invoice_test.rb +3 -1
  12. data/test/integration/get_accounts_test.rb +3 -2
  13. data/test/integration/get_contact_test.rb +3 -1
  14. data/test/integration/get_contacts_test.rb +3 -1
  15. data/test/integration/get_invoice_test.rb +5 -1
  16. data/test/integration/get_invoices_test.rb +5 -1
  17. data/test/integration/get_tracking_categories_test.rb +4 -1
  18. data/test/integration/update_contact_test.rb +3 -1
  19. data/test/stub_responses/accounts.xml +1 -0
  20. data/test/{integration/stub_responses → stub_responses}/contact.xml +0 -0
  21. data/test/{integration/stub_responses → stub_responses}/contacts.xml +0 -0
  22. data/test/stub_responses/invalid_api_key_error.xml +1 -0
  23. data/test/stub_responses/invalid_customer_key_error.xml +1 -0
  24. data/test/{integration/stub_responses → stub_responses}/invoice.xml +0 -0
  25. data/test/stub_responses/invoice_not_found_error.xml +1 -0
  26. data/test/{integration/stub_responses → stub_responses}/invoices.xml +0 -0
  27. data/test/{integration/stub_responses → stub_responses}/tracking_categories.xml +0 -0
  28. data/test/stub_responses/unknown_error.xml +1 -0
  29. data/test/test_helper.rb +65 -1
  30. data/test/unit/{messages/account_message_test.rb → account_test.rb} +4 -4
  31. data/test/unit/{messages/contact_message_test.rb → contact_test.rb} +6 -6
  32. data/test/unit/gateway_test.rb +66 -0
  33. data/test/unit/{messages/invoice_message_test.rb → invoice_test.rb} +6 -6
  34. data/test/unit/{messages/tracking_category_message_test.rb → tracking_category_test.rb} +4 -4
  35. data/xero_gateway.gemspec +18 -17
  36. metadata +18 -17
  37. data/lib/xero_gateway/messages/account_message.rb +0 -33
  38. data/lib/xero_gateway/messages/contact_message.rb +0 -93
  39. data/lib/xero_gateway/messages/invoice_message.rb +0 -122
  40. data/lib/xero_gateway/messages/tracking_category_message.rb +0 -32
  41. data/test/integration/integration_test_methods.rb +0 -64
  42. data/test/integration/stub_responses/accounts.xml +0 -1
data/CHANGELOG.textile CHANGED
@@ -1,9 +1,15 @@
1
- h2. 1.0.2, releases 04/12/2008
1
+ h2. 1.0.3, released 09/12/2008
2
+
3
+ * Major refactorings to DRY out gateway.rb
4
+ * Removed all messages classes in favour of invoice.to_xml and Invoice.from_xml(element)
5
+ * Added unit tests for the handing of errors from Xero
6
+
7
+ h2. 1.0.2, released 04/12/2008
2
8
 
3
9
  * Added implementation of GET /api.xro/1.0/tracking
4
10
 
5
11
 
6
- h2. 1.0.1, releases 02/12/2008
12
+ h2. 1.0.1, released 02/12/2008
7
13
 
8
14
  * Added implementation of GET /api.xro/1.0/accounts
9
15
  * Replaced Invoice.id, Contact.id etc with Invoice.invoice_id, Contact.contact_id to avoid Object.id errors
@@ -15,5 +15,32 @@ module XeroGateway
15
15
  end
16
16
  return true
17
17
  end
18
+
19
+ def to_xml
20
+ b = Builder::XmlMarkup.new
21
+
22
+ b.Account {
23
+ b.Code self.code
24
+ b.Name self.name
25
+ b.Type self.type
26
+ b.TaxType self.tax_type
27
+ b.Description self.description
28
+ }
29
+ end
30
+
31
+ def self.from_xml(account_element)
32
+ account = Account.new
33
+ account_element.children.each do |element|
34
+ case(element.name)
35
+ when "Code" then account.code = element.text
36
+ when "Name" then account.name = element.text
37
+ when "Type" then account.type = element.text
38
+ when "TaxType" then account.tax_type = element.text
39
+ when "Description" then account.description = element.text
40
+ end
41
+ end
42
+ account
43
+ end
44
+
18
45
  end
19
46
  end
@@ -1,5 +1,7 @@
1
1
  module XeroGateway
2
2
  class Contact
3
+ include Dates
4
+
3
5
  attr_accessor :contact_id, :contact_number, :status, :name, :email, :addresses, :phones, :updated_at
4
6
 
5
7
  def initialize(params = {})
@@ -39,5 +41,91 @@ module XeroGateway
39
41
  end
40
42
  return true
41
43
  end
44
+
45
+ def to_xml
46
+ b = Builder::XmlMarkup.new
47
+
48
+ b.Contact {
49
+ b.ContactID self.contact_id if self.contact_id
50
+ b.ContactNumber self.contact_number if self.contact_number
51
+ b.Name self.name
52
+ b.EmailAddress self.email if self.email
53
+ b.Addresses {
54
+ self.addresses.each do |address|
55
+ b.Address {
56
+ b.AddressType address.address_type
57
+ b.AddressLine1 address.line_1 if address.line_1
58
+ b.AddressLine2 address.line_2 if address.line_2
59
+ b.AddressLine3 address.line_3 if address.line_3
60
+ b.AddressLine4 address.line_4 if address.line_4
61
+ b.City address.city if address.city
62
+ b.Region address.region if address.region
63
+ b.PostalCode address.post_code if address.post_code
64
+ b.Country address.country if address.country
65
+ }
66
+ end
67
+ }
68
+ b.Phones {
69
+ self.phones.each do |phone|
70
+ b.Phone {
71
+ b.PhoneType phone.phone_type
72
+ b.PhoneNumber phone.number
73
+ b.PhoneAreaCode phone.area_code if phone.area_code
74
+ b.PhoneCountryCode phone.country_code if phone.country_code
75
+ }
76
+ end
77
+ }
78
+ }
79
+ end
80
+
81
+ # Take a Contact element and convert it into an Contact object
82
+ def self.from_xml(contact_element)
83
+ contact = Contact.new
84
+ contact_element.children.each do |element|
85
+ case(element.name)
86
+ when "ContactID" then contact.contact_id = element.text
87
+ when "ContactNumber" then contact.contact_number = element.text
88
+ when "ContactStatus" then contact.status = element.text
89
+ when "Name" then contact.name = element.text
90
+ when "EmailAddress" then contact.email = element.text
91
+ when "Addresses" then element.children.each {|address| contact.addresses << parse_address(address)}
92
+ when "Phones" then element.children.each {|phone| contact.phones << parse_phone(phone)}
93
+ end
94
+ end
95
+ contact
96
+ end
97
+
98
+ private
99
+
100
+ def self.parse_address(address_element)
101
+ address = Address.new
102
+ address_element.children.each do |element|
103
+ case(element.name)
104
+ when "AddressType" then address.address_type = element.text
105
+ when "AddressLine1" then address.line_1 = element.text
106
+ when "AddressLine2" then address.line_2 = element.text
107
+ when "AddressLine3" then address.line_3 = element.text
108
+ when "AddressLine4" then address.line_4 = element.text
109
+ when "City" then address.city = element.text
110
+ when "Region" then address.region = element.text
111
+ when "PostalCode" then address.post_code = element.text
112
+ when "Country" then address.country = element.text
113
+ end
114
+ end
115
+ address
116
+ end
117
+
118
+ def self.parse_phone(phone_element)
119
+ phone = Phone.new
120
+ phone_element.children.each do |element|
121
+ case(element.name)
122
+ when "PhoneType" then phone.phone_type = element.text
123
+ when "PhoneNumber" then phone.number = element.text
124
+ when "PhoneAreaCode" then phone.area_code = element.text
125
+ when "PhoneCountryCode" then phone.country_code = element.text
126
+ end
127
+ end
128
+ phone
129
+ end
42
130
  end
43
131
  end
@@ -0,0 +1,19 @@
1
+ module XeroGateway
2
+ class Error
3
+ attr_accessor :description, :date_time, :type, :message
4
+
5
+ def initialize(params = {})
6
+ params.each do |k,v|
7
+ self.instance_variable_set("@#{k}", v) ## create and initialize an instance variable for this key/value pair
8
+ self.send("#{k}=", v)
9
+ end
10
+ end
11
+
12
+ def ==(other)
13
+ [:description, :date_time, :type, :message].each do |field|
14
+ return false if send(field) != other.send(field)
15
+ end
16
+ return true
17
+ end
18
+ end
19
+ end
@@ -20,23 +20,7 @@ module XeroGateway
20
20
 
21
21
  response_xml = http_get("#{@xero_url}/contacts", request_params)
22
22
 
23
- doc = REXML::Document.new(response_xml)
24
-
25
- # Create the response object
26
- response = build_response(doc)
27
-
28
- # Add the contacts to the response
29
- if response.success?
30
- response.response_item = []
31
- REXML::XPath.each(doc, "/Response/Contacts/Contact") do |contact_element|
32
- response.response_item << XeroGateway::Messages::ContactMessage.from_xml(contact_element)
33
- end
34
- end
35
-
36
- # Add the request and response XML to the response object
37
- response.request_params = request_params
38
- response.response_xml = response_xml
39
- response
23
+ parse_response(response_xml, :request_params => request_params)
40
24
  end
41
25
 
42
26
  # Retrieve a contact from Xero
@@ -70,23 +54,10 @@ module XeroGateway
70
54
  #
71
55
  # create_contact(contact)
72
56
  def create_contact(contact)
73
- request_xml = XeroGateway::Messages::ContactMessage.build_xml(contact)
57
+ request_xml = contact.to_xml
74
58
  response_xml = http_put("#{@xero_url}/contact", request_xml, {})
75
59
 
76
- doc = REXML::Document.new(response_xml)
77
-
78
- # Create the response object
79
- response = build_response(doc)
80
-
81
- # Add the invoice to the response
82
- if response.success?
83
- response.response_item = XeroGateway::Messages::ContactMessage.from_xml(REXML::XPath.first(doc, "/Response/Contact"))
84
- end
85
-
86
- # Add the request and response XML to the response object
87
- response.request_xml = request_xml
88
- response.response_xml = response_xml
89
- response
60
+ parse_response(response_xml, :request_xml => request_xml)
90
61
  end
91
62
 
92
63
  #
@@ -101,24 +72,10 @@ module XeroGateway
101
72
  def update_contact(contact)
102
73
  raise "contact_id or contact_number is required for updating contacts" if contact.contact_id.nil? and contact.contact_number.nil?
103
74
 
104
- request_xml = XeroGateway::Messages::ContactMessage.build_xml(contact)
75
+ request_xml = contact.to_xml
105
76
  response_xml = http_post("#{@xero_url}/contact", request_xml, {})
106
77
 
107
- doc = REXML::Document.new(response_xml)
108
-
109
- # Create the response object
110
- response = build_response(doc)
111
-
112
- # Add the invoice to the response
113
- if response.success?
114
- response.response_item = XeroGateway::Messages::ContactMessage.from_xml(REXML::XPath.first(doc, "/Response/Contact"))
115
- end
116
-
117
- # Add the request and response XML to the response object
118
- response.request_xml = request_xml
119
- response.response_xml = response_xml
120
-
121
- response
78
+ parse_response(response_xml, :request_xml => request_xml)
122
79
  end
123
80
 
124
81
  # Retrieves an invoice from Xero based on its GUID
@@ -144,23 +101,7 @@ module XeroGateway
144
101
 
145
102
  response_xml = http_get("#{@xero_url}/invoices", request_params)
146
103
 
147
- doc = REXML::Document.new(response_xml)
148
-
149
- # Create the response object
150
- response = build_response(doc)
151
-
152
- # Add the invoices to the response
153
- if response.success?
154
- response.response_item = []
155
- REXML::XPath.first(doc, "/Response/Invoices").children.each do |invoice_element|
156
- response.response_item << XeroGateway::Messages::InvoiceMessage.from_xml(invoice_element)
157
- end
158
- end
159
-
160
- # Add the request and response XML to the response object
161
- response.request_params = request_params
162
- response.response_xml = response_xml
163
- response
104
+ parse_response(response_xml, :request_params => request_params)
164
105
  end
165
106
 
166
107
  # Creates an invoice in Xero based on an invoice object
@@ -191,24 +132,10 @@ module XeroGateway
191
132
  #
192
133
  # create_invoice(invoice)
193
134
  def create_invoice(invoice)
194
- request_xml = XeroGateway::Messages::InvoiceMessage.build_xml(invoice)
135
+ request_xml = invoice.to_xml
195
136
  response_xml = http_put("#{@xero_url}/invoice", request_xml)
196
137
 
197
- doc = REXML::Document.new(response_xml)
198
-
199
- # Create the response object
200
- response = build_response(doc)
201
-
202
- # Add the invoice to the response
203
- if response.success?
204
- response.response_item = XeroGateway::Messages::InvoiceMessage.from_xml(REXML::XPath.first(doc, "/Response/Invoice"))
205
- end
206
-
207
- # Add the request and response XML to the response object
208
- response.request_xml = request_xml
209
- response.response_xml = response_xml
210
-
211
- response
138
+ parse_response(response_xml, :request_xml => request_xml)
212
139
  end
213
140
 
214
141
  #
@@ -216,21 +143,7 @@ module XeroGateway
216
143
  #
217
144
  def get_accounts
218
145
  response_xml = http_get("#{xero_url}/accounts")
219
-
220
- doc = REXML::Document.new(response_xml)
221
-
222
- # Create the response object
223
- response = build_response(doc)
224
-
225
- # Add the accounts to the response
226
- response.response_item = []
227
- REXML::XPath.first(doc, "/Response/Accounts").children.each do |account_element|
228
- response.response_item << XeroGateway::Messages::AccountMessage.from_xml(account_element)
229
- end
230
-
231
- # Add the request and response XML to the response object
232
- response.response_xml = response_xml
233
- response
146
+ parse_response(response_xml)
234
147
  end
235
148
 
236
149
  #
@@ -238,21 +151,7 @@ module XeroGateway
238
151
  #
239
152
  def get_tracking_categories
240
153
  response_xml = http_get("#{xero_url}/tracking")
241
-
242
- doc = REXML::Document.new(response_xml)
243
-
244
- # Create the response object
245
- response = build_response(doc)
246
-
247
- # Add the accounts to the response
248
- response.response_item = []
249
- REXML::XPath.first(doc, "/Response/Tracking").children.each do |tracking_category_element|
250
- response.response_item << XeroGateway::Messages::TrackingCategoryMessage.from_xml(tracking_category_element)
251
- end
252
-
253
- # Add the request and response XML to the response object
254
- response.response_xml = response_xml
255
- response
154
+ parse_response(response_xml)
256
155
  end
257
156
 
258
157
 
@@ -261,61 +160,59 @@ module XeroGateway
261
160
  def get_invoice(invoice_id = nil, invoice_number = nil)
262
161
  request_params = invoice_id ? {:invoiceID => invoice_id} : {:invoiceNumber => invoice_number}
263
162
  response_xml = http_get("#{@xero_url}/invoice", request_params)
264
-
265
- doc = REXML::Document.new(response_xml)
266
-
267
- # Create the response object
268
- response = build_response(doc)
269
163
 
270
- # Add the invoice to the response
271
- response.response_item = XeroGateway::Messages::InvoiceMessage.from_xml(REXML::XPath.first(doc, "/Response/Invoice")) if response.success?
272
-
273
- # Add the request and response XML to the response object
274
- response.request_params = request_params
275
- response.response_xml = response_xml
276
- response
164
+ parse_response(response_xml, :request_params => request_params)
277
165
  end
278
166
 
279
167
  def get_contact(contact_id = nil, contact_number = nil)
280
168
  request_params = contact_id ? {:contactID => contact_id} : {:contactNumber => contact_number}
281
169
  response_xml = http_get("#{@xero_url}/contact", request_params)
282
-
283
- doc = REXML::Document.new(response_xml)
284
-
285
- # Create the response object
286
- response = build_response(doc)
287
170
 
288
- # Add the invoice to the response
289
- response.response_item = XeroGateway::Messages::ContactMessage.from_xml(REXML::XPath.first(doc, "/Response/Contact")) if response.success?
290
-
291
- # Add the request and response XML to the response object
292
- response.request_params = request_params
293
- response.response_xml = response_xml
294
- response
171
+ parse_response(response_xml, :request_params => request_params)
295
172
  end
296
-
297
-
298
-
299
- def build_response(response_document)
300
- response = XeroGateway::Response.new({
301
- :response_id => REXML::XPath.first(response_document, "/Response/ID").text,
302
- :status => REXML::XPath.first(response_document, "/Response/Status").text,
303
- :provider => REXML::XPath.first(response_document, "/Response/ProviderName").text,
304
- :date_time => REXML::XPath.first(response_document, "/Response/DateTimeUTC").text,
305
- })
306
-
307
- # Add any errors to the response object
308
- if !response.success?
309
- REXML::XPath.each(response_document, "/Response/Error") do |error|
310
- response.errors << {
311
- :date_time => REXML::XPath.first(error, "/DateTime").text,
312
- :type => REXML::XPath.first(error, "/ExceptionType").text,
313
- :message => REXML::XPath.first(error, "/Message").text
314
- }
173
+
174
+ def parse_response(response_xml, request = {})
175
+ doc = REXML::Document.new(response_xml)
176
+
177
+ response = XeroGateway::Response.new
178
+
179
+ response_element = REXML::XPath.first(doc, "/Response")
180
+
181
+ if response_element.nil?
182
+ # The Xero API documentation states that it will always return valid XML with
183
+ # a response element, unless an invalid API key is provided.
184
+ response.status = "INVALID_API_KEY"
185
+ else
186
+ response_element.children.each do |element|
187
+ case(element.name)
188
+ when "ID" then response.response_id = element.text
189
+ when "Status" then response.status = element.text
190
+ when "ProviderName" then response.provider = element.text
191
+ when "DateTimeUTC" then response.date_time = element.text
192
+ when "Contact" then response.response_item = Contact.from_xml(element)
193
+ when "Invoice" then response.response_item = Invoice.from_xml(element)
194
+ when "Contacts" then element.children.each {|child| response.response_item << Contact.from_xml(child) }
195
+ when "Invoices" then element.children.each {|child| response.response_item << Invoice.from_xml(child) }
196
+ when "Accounts" then element.children.each {|child| response.response_item << Account.from_xml(child) }
197
+ when "Tracking" then element.children.each {|child| response.response_item << TrackingCategory.from_xml(child) }
198
+ when "Errors" then element.children.each { |error| parse_error(error, response) }
199
+ end
315
200
  end
316
201
  end
317
-
318
- response
202
+
203
+ response.request_params = request[:request_params]
204
+ response.request_xml = request[:request_xml]
205
+ response.response_xml = response_xml
206
+ response
207
+ end
208
+
209
+ def parse_error(error_element, response)
210
+ response.errors << Error.new(
211
+ :description => REXML::XPath.first(error_element, "Description").text,
212
+ :date_time => REXML::XPath.first(error_element, "//DateTime").text,
213
+ :type => REXML::XPath.first(error_element, "//ExceptionType").text,
214
+ :message => REXML::XPath.first(error_element, "//Message").text
215
+ )
319
216
  end
320
- end
217
+ end
321
218
  end
@@ -1,5 +1,8 @@
1
1
  module XeroGateway
2
2
  class Invoice
3
+ include Dates
4
+ include Money
5
+
3
6
  # All accessible fields
4
7
  attr_accessor :invoice_id, :invoice_number, :invoice_type, :invoice_status, :date, :due_date, :reference, :tax_inclusive, :includes_tax, :sub_total, :total_tax, :total, :line_items, :contact
5
8
 
@@ -28,5 +31,118 @@ module XeroGateway
28
31
  end
29
32
  return true
30
33
  end
34
+
35
+ def to_xml
36
+ b = Builder::XmlMarkup.new
37
+
38
+ b.Invoice {
39
+ b.InvoiceType self.invoice_type
40
+ b.Contact {
41
+ b.ContactID self.contact.contact_id if self.contact.contact_id
42
+ b.Name self.contact.name
43
+ b.EmailAddress self.contact.email if self.contact.email
44
+ b.Addresses {
45
+ self.contact.addresses.each do |address|
46
+ b.Address {
47
+ b.AddressType address.address_type
48
+ b.AddressLine1 address.line_1 if address.line_1
49
+ b.AddressLine2 address.line_2 if address.line_2
50
+ b.AddressLine3 address.line_3 if address.line_3
51
+ b.AddressLine4 address.line_4 if address.line_4
52
+ b.City address.city if address.city
53
+ b.Region address.region if address.region
54
+ b.PostalCode address.post_code if address.post_code
55
+ b.Country address.country if address.country
56
+ }
57
+ end
58
+ }
59
+ b.Phones {
60
+ self.contact.phones.each do |phone|
61
+ b.Phone {
62
+ b.PhoneType phone.phone_type
63
+ b.PhoneNumber phone.number
64
+ b.PhoneAreaCode phone.area_code if phone.area_code
65
+ b.PhoneCountryCode phone.country_code if phone.country_code
66
+ }
67
+ end
68
+ }
69
+ }
70
+ b.InvoiceDate Invoice.format_date_time(self.date)
71
+ b.DueDate Invoice.format_date_time(self.due_date) if self.due_date
72
+ b.InvoiceNumber self.invoice_number
73
+ b.Reference self.reference if self.reference
74
+ b.TaxInclusive self.tax_inclusive if self.tax_inclusive
75
+ b.IncludesTax self.includes_tax
76
+ b.SubTotal Invoice.format_money(self.sub_total) if self.sub_total
77
+ b.TotalTax Invoice.format_money(self.total_tax) if self.total_tax
78
+ b.Total Invoice.format_money(self.total) if self.total
79
+ b.LineItems {
80
+ self.line_items.each do |line_item|
81
+ b.LineItem {
82
+ b.Description line_item.description
83
+ b.Quantity line_item.quantity if line_item.quantity
84
+ b.UnitAmount Invoice.format_money(line_item.unit_amount)
85
+ b.TaxType line_item.tax_type if line_item.tax_type
86
+ b.TaxAmount Invoice.format_money(line_item.tax_amount) if line_item.tax_amount
87
+ b.LineAmount Invoice.format_money(line_item.line_amount)
88
+ b.AccountCode line_item.account_code || 200
89
+ b.Tracking {
90
+ b.TrackingCategory {
91
+ b.Name line_item.tracking_category
92
+ b.Option line_item.tracking_option
93
+ }
94
+ }
95
+ }
96
+ end
97
+ }
98
+ }
99
+ end
100
+
101
+ def self.from_xml(invoice_element)
102
+ invoice = Invoice.new
103
+ invoice_element.children.each do |element|
104
+ case(element.name)
105
+ when "InvoiceStatus" then invoice.invoice_status = element.text
106
+ when "InvoiceID" then invoice.invoice_id = element.text
107
+ when "InvoiceNumber" then invoice.invoice_number = element.text
108
+ when "InvoiceType" then invoice.invoice_type = element.text
109
+ when "InvoiceDate" then invoice.date = parse_date_time(element.text)
110
+ when "DueDate" then invoice.due_date = parse_date_time(element.text)
111
+ when "Reference" then invoice.reference = element.text
112
+ when "TaxInclusive" then invoice.tax_inclusive = (element.text == "true")
113
+ when "IncludesTax" then invoice.includes_tax = (element.text == "true")
114
+ when "SubTotal" then invoice.sub_total = BigDecimal.new(element.text)
115
+ when "TotalTax" then invoice.total_tax = BigDecimal.new(element.text)
116
+ when "Total" then invoice.total = BigDecimal.new(element.text)
117
+ when "Contact" then invoice.contact = Contact.from_xml(element)
118
+ when "LineItems" then element.children.each {|line_item| invoice.line_items << parse_line_item(line_item)}
119
+ end
120
+ end
121
+ invoice
122
+ end
123
+
124
+ private
125
+
126
+ def self.parse_line_item(line_item_element)
127
+ line_item = LineItem.new
128
+ line_item_element.children.each do |element|
129
+ case(element.name)
130
+ when "LineItemID" then line_item.line_item_id = element.text
131
+ when "Description" then line_item.description = element.text
132
+ when "Quantity" then line_item.quantity = element.text.to_i
133
+ when "UnitAmount" then line_item.unit_amount = BigDecimal.new(element.text)
134
+ when "TaxType" then line_item.tax_type = element.text
135
+ when "TaxAmount" then line_item.tax_amount = BigDecimal.new(element.text)
136
+ when "LineAmount" then line_item.line_amount = BigDecimal.new(element.text)
137
+ when "AccountCode" then line_item.account_code = element.text
138
+ when "Tracking" then
139
+ if element.elements['TrackingCategory']
140
+ line_item.tracking_category = element.elements['TrackingCategory/Name'].text
141
+ line_item.tracking_option = element.elements['TrackingCategory/Option'].text
142
+ end
143
+ end
144
+ end
145
+ line_item
146
+ end
31
147
  end
32
148
  end
@@ -18,6 +18,7 @@ module XeroGateway
18
18
  end
19
19
 
20
20
  @errors ||= []
21
+ @response_item ||= []
21
22
  end
22
23
 
23
24
  def success?
@@ -16,5 +16,31 @@ module XeroGateway
16
16
  end
17
17
  return true
18
18
  end
19
+
20
+ def to_xml
21
+ b = Builder::XmlMarkup.new
22
+
23
+ b.TrackingCategory {
24
+ b.Name self.name
25
+ b.Options {
26
+ self.options.each do |option|
27
+ b.Option {
28
+ b.Name option
29
+ }
30
+ end
31
+ }
32
+ }
33
+ end
34
+
35
+ def self.from_xml(tracking_category_element)
36
+ tracking_category = TrackingCategory.new
37
+ tracking_category_element.children.each do |element|
38
+ case(element.name)
39
+ when "Name" then tracking_category.name = element.text
40
+ when "Options" then element.children.each {|option| tracking_category.options << option.children.first.text}
41
+ end
42
+ end
43
+ tracking_category
44
+ end
19
45
  end
20
46
  end
data/lib/xero_gateway.rb CHANGED
@@ -15,9 +15,6 @@ require File.dirname(__FILE__) + "/xero_gateway/contact"
15
15
  require File.dirname(__FILE__) + "/xero_gateway/address"
16
16
  require File.dirname(__FILE__) + "/xero_gateway/phone"
17
17
  require File.dirname(__FILE__) + "/xero_gateway/account"
18
+ require File.dirname(__FILE__) + "/xero_gateway/error"
18
19
  require File.dirname(__FILE__) + "/xero_gateway/tracking_category"
19
- require File.dirname(__FILE__) + "/xero_gateway/messages/contact_message"
20
- require File.dirname(__FILE__) + "/xero_gateway/messages/invoice_message"
21
- require File.dirname(__FILE__) + "/xero_gateway/messages/account_message"
22
- require File.dirname(__FILE__) + "/xero_gateway/messages/tracking_category_message"
23
20
  require File.dirname(__FILE__) + "/xero_gateway/gateway"
@@ -1,7 +1,7 @@
1
1
  require File.dirname(__FILE__) + '/../test_helper'
2
2
 
3
3
  class CreateContactTest < Test::Unit::TestCase
4
- include IntegrationTestMethods
4
+ include TestHelper
5
5
 
6
6
  def setup
7
7
  @gateway = XeroGateway::Gateway.new(
@@ -22,6 +22,8 @@ class CreateContactTest < Test::Unit::TestCase
22
22
  result = @gateway.create_contact(example_contact)
23
23
  assert result.success?
24
24
  assert !result.contact.contact_id.nil?
25
+ assert !result.request_xml.nil?
26
+ assert !result.response_xml.nil?
25
27
  assert_equal result.contact.name, example_contact.name
26
28
  end
27
29
  end
@@ -1,7 +1,7 @@
1
1
  require File.dirname(__FILE__) + '/../test_helper'
2
2
 
3
3
  class CreateInvoiceTest < Test::Unit::TestCase
4
- include IntegrationTestMethods
4
+ include TestHelper
5
5
 
6
6
  def setup
7
7
  @gateway = XeroGateway::Gateway.new(
@@ -21,6 +21,8 @@ class CreateInvoiceTest < Test::Unit::TestCase
21
21
 
22
22
  result = @gateway.create_invoice(example_invoice)
23
23
  assert result.success?
24
+ assert !result.request_xml.nil?
25
+ assert !result.response_xml.nil?
24
26
  assert !result.invoice.invoice_id.nil?
25
27
  assert result.invoice.invoice_number == example_invoice.invoice_number
26
28
  end