xero_gateway-float 2.0.18 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. data/Rakefile +7 -1
  2. data/examples/partner_app.rb +2 -2
  3. data/lib/xero_gateway/accounts_list.rb +0 -4
  4. data/lib/xero_gateway/bank_transaction.rb +0 -2
  5. data/lib/xero_gateway/contact.rb +6 -9
  6. data/lib/xero_gateway/credit_note.rb +1 -3
  7. data/lib/xero_gateway/error.rb +16 -0
  8. data/lib/xero_gateway/exceptions.rb +5 -0
  9. data/lib/xero_gateway/gateway.rb +184 -82
  10. data/lib/xero_gateway/http.rb +38 -32
  11. data/lib/xero_gateway/invoice.rb +17 -9
  12. data/lib/xero_gateway/journal_line.rb +102 -0
  13. data/lib/xero_gateway/line_item_calculations.rb +0 -4
  14. data/lib/xero_gateway/manual_journal.rb +163 -0
  15. data/lib/xero_gateway/oauth.rb +29 -23
  16. data/lib/xero_gateway/partner_app.rb +6 -1
  17. data/lib/xero_gateway/response.rb +2 -0
  18. data/lib/xero_gateway/tax_rate.rb +1 -1
  19. data/lib/xero_gateway.rb +3 -0
  20. data/test/integration/accounts_list_test.rb +4 -4
  21. data/test/integration/create_invoice_test.rb +6 -0
  22. data/test/integration/create_manual_journal_test.rb +35 -0
  23. data/test/integration/create_payments_test.rb +35 -0
  24. data/test/integration/get_invoice_test.rb +27 -12
  25. data/test/integration/get_manual_journal_test.rb +50 -0
  26. data/test/integration/get_manual_journals_test.rb +88 -0
  27. data/test/integration/update_manual_journal_test.rb +31 -0
  28. data/test/test_helper.rb +39 -1
  29. data/test/unit/bank_transaction_test.rb +1 -1
  30. data/test/unit/credit_note_test.rb +1 -1
  31. data/test/unit/gateway_test.rb +15 -15
  32. data/test/unit/invoice_test.rb +3 -2
  33. data/test/unit/manual_journal_test.rb +93 -0
  34. data/test/unit/payment_test.rb +34 -0
  35. data/xero_gateway.gemspec +2 -2
  36. metadata +11 -2
@@ -1,17 +1,17 @@
1
1
  module XeroGateway
2
-
2
+
3
3
  class Gateway
4
4
  include Http
5
5
  include Dates
6
-
6
+
7
7
  attr_accessor :client, :xero_url, :logger
8
-
8
+
9
9
  extend Forwardable
10
- def_delegators :client, :request_token, :access_token, :authorize_from_request, :authorize_from_access, :authorization_expires_at
10
+ def_delegators :client, :request_token, :access_token, :authorize_from_request, :authorize_from_access, :expires_at, :authorization_expires_at
11
11
 
12
12
  #
13
13
  # The consumer key and secret here correspond to those provided
14
- # to you by Xero inside the API Previewer.
14
+ # to you by Xero inside the API Previewer.
15
15
  def initialize(consumer_key, consumer_secret, options = {})
16
16
  @xero_url = options[:xero_url] || "https://api.xero.com/api.xro/2.0"
17
17
  @client = OAuth.new(consumer_key, consumer_secret, options)
@@ -34,27 +34,27 @@ module XeroGateway
34
34
 
35
35
  request_params[:ContactID] = options[:contact_id] if options[:contact_id]
36
36
  request_params[:ContactNumber] = options[:contact_number] if options[:contact_number]
37
- request_params[:OrderBy] = options[:order] if options[:order]
37
+ request_params[:OrderBy] = options[:order] if options[:order]
38
38
  request_params[:ModifiedAfter] = options[:modified_since] if options[:modified_since]
39
39
  request_params[:where] = options[:where] if options[:where]
40
-
40
+
41
41
  response_xml = http_get(@client, "#{@xero_url}/Contacts", request_params)
42
-
42
+
43
43
  parse_response(response_xml, {:request_params => request_params}, {:request_signature => 'GET/contacts'})
44
44
  end
45
-
45
+
46
46
  # Retrieve a contact from Xero
47
- # Usage get_contact_by_id(contact_id)
47
+ # Usage get_contact_by_id(contact_id)
48
48
  def get_contact_by_id(contact_id)
49
49
  get_contact(contact_id)
50
50
  end
51
51
 
52
52
  # Retrieve a contact from Xero
53
- # Usage get_contact_by_id(contact_id)
53
+ # Usage get_contact_by_id(contact_id)
54
54
  def get_contact_by_number(contact_number)
55
55
  get_contact(nil, contact_number)
56
56
  end
57
-
57
+
58
58
  # Factory method for building new Contact objects associated with this gateway.
59
59
  def build_contact(contact = {})
60
60
  case contact
@@ -63,11 +63,11 @@ module XeroGateway
63
63
  end
64
64
  contact
65
65
  end
66
-
66
+
67
67
  #
68
68
  # Creates a contact in Xero
69
69
  #
70
- # Usage :
70
+ # Usage :
71
71
  #
72
72
  # contact = XeroGateway::Contact.new(:name => "THE NAME OF THE CONTACT #{Time.now.to_i}")
73
73
  # contact.email = "whoever@something.com"
@@ -85,24 +85,24 @@ module XeroGateway
85
85
  def create_contact(contact)
86
86
  save_contact(contact)
87
87
  end
88
-
88
+
89
89
  #
90
90
  # Updates an existing Xero contact
91
91
  #
92
- # Usage :
92
+ # Usage :
93
93
  #
94
94
  # contact = xero_gateway.get_contact(some_contact_id)
95
95
  # contact.email = "a_new_email_ddress"
96
96
  #
97
- # xero_gateway.update_contact(contact)
97
+ # xero_gateway.update_contact(contact)
98
98
  def update_contact(contact)
99
99
  raise "contact_id or contact_number is required for updating contacts" if contact.contact_id.nil? and contact.contact_number.nil?
100
100
  save_contact(contact)
101
101
  end
102
-
102
+
103
103
  #
104
104
  # Updates an array of contacts in a single API operation.
105
- #
105
+ #
106
106
  # Usage :
107
107
  # contacts = [XeroGateway::Contact.new(:name => 'Joe Bloggs'), XeroGateway::Contact.new(:name => 'Jane Doe')]
108
108
  # result = gateway.update_contacts(contacts)
@@ -116,7 +116,7 @@ module XeroGateway
116
116
  contact.to_xml(b)
117
117
  end
118
118
  }
119
-
119
+
120
120
  response_xml = http_post(@client, "#{@xero_url}/Contacts", request_xml, {})
121
121
 
122
122
  response = parse_response(response_xml, {:request_xml => request_xml}, {:request_signature => 'POST/contacts'})
@@ -125,7 +125,7 @@ module XeroGateway
125
125
  end
126
126
  response
127
127
  end
128
-
128
+
129
129
  # Retrieves all invoices from Xero
130
130
  #
131
131
  # Usage : get_invoices
@@ -133,12 +133,12 @@ module XeroGateway
133
133
  #
134
134
  # Note : modified_since is in UTC format (i.e. Brisbane is UTC+10)
135
135
  def get_invoices(options = {})
136
-
136
+
137
137
  request_params = {}
138
-
138
+
139
139
  request_params[:InvoiceID] = options[:invoice_id] if options[:invoice_id]
140
140
  request_params[:InvoiceNumber] = options[:invoice_number] if options[:invoice_number]
141
- request_params[:OrderBy] = options[:order] if options[:order]
141
+ request_params[:OrderBy] = options[:order] if options[:order]
142
142
  request_params[:ModifiedAfter] = options[:modified_since] if options[:modified_since]
143
143
 
144
144
  request_params[:where] = options[:where] if options[:where]
@@ -147,21 +147,33 @@ module XeroGateway
147
147
 
148
148
  parse_response(response_xml, {:request_params => request_params}, {:request_signature => 'GET/Invoices'})
149
149
  end
150
-
150
+
151
151
  # Retrieves a single invoice
152
152
  #
153
+ # You can get a PDF-formatted invoice by specifying :pdf as the format argument
154
+ #
153
155
  # Usage : get_invoice("297c2dc5-cc47-4afd-8ec8-74990b8761e9") # By ID
154
156
  # get_invoice("OIT-12345") # By number
155
- def get_invoice(invoice_id_or_number)
157
+ def get_invoice(invoice_id_or_number, format = :xml)
156
158
  request_params = {}
157
-
159
+ headers = {}
160
+
161
+ headers.merge!("Accept" => "application/pdf") if format == :pdf
162
+
158
163
  url = "#{@xero_url}/Invoices/#{URI.escape(invoice_id_or_number)}"
159
-
160
- response_xml = http_get(@client, url, request_params)
161
164
 
162
- parse_response(response_xml, {:request_params => request_params}, {:request_signature => 'GET/Invoice'})
165
+ response = http_get(@client, url, request_params, headers)
166
+
167
+ if format == :pdf
168
+ Tempfile.open(invoice_id_or_number) do |f|
169
+ f.write(response)
170
+ f
171
+ end
172
+ else
173
+ parse_response(response, {:request_params => request_params}, {:request_signature => 'GET/Invoice'})
174
+ end
163
175
  end
164
-
176
+
165
177
  # Factory method for building new Invoice objects associated with this gateway.
166
178
  def build_invoice(invoice = {})
167
179
  case invoice
@@ -170,12 +182,12 @@ module XeroGateway
170
182
  end
171
183
  invoice
172
184
  end
173
-
185
+
174
186
  # Creates an invoice in Xero based on an invoice object.
175
187
  #
176
188
  # Invoice and line item totals are calculated automatically.
177
189
  #
178
- # Usage :
190
+ # Usage :
179
191
  #
180
192
  # invoice = XeroGateway::Invoice.new({
181
193
  # :invoice_type => "ACCREC",
@@ -186,7 +198,7 @@ module XeroGateway
186
198
  # })
187
199
  # invoice.contact = XeroGateway::Contact.new(:name => "THE NAME OF THE CONTACT")
188
200
  # invoice.contact.phone.number = "12345"
189
- # invoice.contact.address.line_1 = "LINE 1 OF THE ADDRESS"
201
+ # invoice.contact.address.line_1 = "LINE 1 OF THE ADDRESS"
190
202
  # invoice.line_items << XeroGateway::LineItem.new(
191
203
  # :description => "THE DESCRIPTION OF THE LINE ITEM",
192
204
  # :unit_amount => 100,
@@ -203,12 +215,12 @@ module XeroGateway
203
215
  #
204
216
  # Updates an existing Xero invoice
205
217
  #
206
- # Usage :
218
+ # Usage :
207
219
  #
208
220
  # invoice = xero_gateway.get_invoice(some_invoice_id)
209
221
  # invoice.due_date = Date.today
210
222
  #
211
- # xero_gateway.update_invoice(invoice)
223
+ # xero_gateway.update_invoice(invoice)
212
224
 
213
225
  def update_invoice(invoice)
214
226
  raise "invoice_id is required for updating invoices" if invoice.invoice_id.nil?
@@ -217,7 +229,7 @@ module XeroGateway
217
229
 
218
230
  #
219
231
  # Creates an array of invoices with a single API request.
220
- #
232
+ #
221
233
  # Usage :
222
234
  # invoices = [XeroGateway::Invoice.new(...), XeroGateway::Invoice.new(...)]
223
235
  # result = gateway.create_invoices(invoices)
@@ -229,8 +241,8 @@ module XeroGateway
229
241
  invoice.to_xml(b)
230
242
  end
231
243
  }
232
-
233
- response_xml = http_put(@client, "#{@xero_url}/Invoices", request_xml, {})
244
+
245
+ response_xml = http_put(@client, "#{@xero_url}/Invoices?SummarizeErrors=false", request_xml, {})
234
246
 
235
247
  response = parse_response(response_xml, {:request_xml => request_xml}, {:request_signature => 'PUT/invoices'})
236
248
  response.invoices.each_with_index do | response_invoice, index |
@@ -246,12 +258,12 @@ module XeroGateway
246
258
  #
247
259
  # Note : modified_since is in UTC format (i.e. Brisbane is UTC+10)
248
260
  def get_credit_notes(options = {})
249
-
261
+
250
262
  request_params = {}
251
-
263
+
252
264
  request_params[:CreditNoteID] = options[:credit_note_id] if options[:credit_note_id]
253
265
  request_params[:CreditNoteNumber] = options[:credit_note_number] if options[:credit_note_number]
254
- request_params[:OrderBy] = options[:order] if options[:order]
266
+ request_params[:OrderBy] = options[:order] if options[:order]
255
267
  request_params[:ModifiedAfter] = options[:modified_since] if options[:modified_since]
256
268
 
257
269
  request_params[:where] = options[:where] if options[:where]
@@ -260,21 +272,21 @@ module XeroGateway
260
272
 
261
273
  parse_response(response_xml, {:request_params => request_params}, {:request_signature => 'GET/CreditNotes'})
262
274
  end
263
-
275
+
264
276
  # Retrieves a single credit_note
265
277
  #
266
278
  # Usage : get_credit_note("297c2dc5-cc47-4afd-8ec8-74990b8761e9") # By ID
267
279
  # get_credit_note("OIT-12345") # By number
268
280
  def get_credit_note(credit_note_id_or_number)
269
281
  request_params = {}
270
-
282
+
271
283
  url = "#{@xero_url}/CreditNotes/#{URI.escape(credit_note_id_or_number)}"
272
-
284
+
273
285
  response_xml = http_get(@client, url, request_params)
274
286
 
275
287
  parse_response(response_xml, {:request_params => request_params}, {:request_signature => 'GET/CreditNote'})
276
288
  end
277
-
289
+
278
290
  # Factory method for building new CreditNote objects associated with this gateway.
279
291
  def build_credit_note(credit_note = {})
280
292
  case credit_note
@@ -283,12 +295,12 @@ module XeroGateway
283
295
  end
284
296
  credit_note
285
297
  end
286
-
298
+
287
299
  # Creates an credit_note in Xero based on an credit_note object.
288
300
  #
289
301
  # CreditNote and line item totals are calculated automatically.
290
302
  #
291
- # Usage :
303
+ # Usage :
292
304
  #
293
305
  # credit_note = XeroGateway::CreditNote.new({
294
306
  # :credit_note_type => "ACCREC",
@@ -299,7 +311,7 @@ module XeroGateway
299
311
  # })
300
312
  # credit_note.contact = XeroGateway::Contact.new(:name => "THE NAME OF THE CONTACT")
301
313
  # credit_note.contact.phone.number = "12345"
302
- # credit_note.contact.address.line_1 = "LINE 1 OF THE ADDRESS"
314
+ # credit_note.contact.address.line_1 = "LINE 1 OF THE ADDRESS"
303
315
  # credit_note.line_items << XeroGateway::LineItem.new(
304
316
  # :description => "THE DESCRIPTION OF THE LINE ITEM",
305
317
  # :unit_amount => 100,
@@ -313,21 +325,21 @@ module XeroGateway
313
325
  request_xml = credit_note.to_xml
314
326
  response_xml = http_put(@client, "#{@xero_url}/CreditNotes", request_xml)
315
327
  response = parse_response(response_xml, {:request_xml => request_xml}, {:request_signature => 'PUT/credit_note'})
316
-
328
+
317
329
  # Xero returns credit_notes inside an <CreditNotes> tag, even though there's only ever
318
330
  # one for this request
319
331
  response.response_item = response.credit_notes.first
320
-
332
+
321
333
  if response.success? && response.credit_note && response.credit_note.credit_note_id
322
- credit_note.credit_note_id = response.credit_note.credit_note_id
334
+ credit_note.credit_note_id = response.credit_note.credit_note_id
323
335
  end
324
-
336
+
325
337
  response
326
338
  end
327
-
339
+
328
340
  #
329
341
  # Creates an array of credit_notes with a single API request.
330
- #
342
+ #
331
343
  # Usage :
332
344
  # credit_notes = [XeroGateway::CreditNote.new(...), XeroGateway::CreditNote.new(...)]
333
345
  # result = gateway.create_credit_notes(credit_notes)
@@ -339,7 +351,7 @@ module XeroGateway
339
351
  credit_note.to_xml(b)
340
352
  end
341
353
  }
342
-
354
+
343
355
  response_xml = http_put(@client, "#{@xero_url}/CreditNotes", request_xml, {})
344
356
 
345
357
  response = parse_response(response_xml, {:request_xml => request_xml}, {:request_signature => 'PUT/credit_notes'})
@@ -419,6 +431,56 @@ module XeroGateway
419
431
  parse_response(response_xml, {:request_params => request_params}, {:request_signature => 'GET/BankTransaction'})
420
432
  end
421
433
 
434
+ # Creates a manual journal in Xero based on a manual journal object.
435
+ #
436
+ # Manual journal and line item totals are calculated automatically.
437
+ #
438
+ # Usage : # TODO
439
+
440
+ def create_manual_journal(manual_journal)
441
+ save_manual_journal(manual_journal)
442
+ end
443
+
444
+ #
445
+ # Updates an existing Xero manual journal
446
+ #
447
+ # Usage :
448
+ #
449
+ # manual_journal = xero_gateway.get_manual_journal(some_manual_journal_id)
450
+ #
451
+ # xero_gateway.update_manual_journal(manual_journal)
452
+ def update_manual_journal(manual_journal)
453
+ raise "manual_journal_id is required for updating manual journals" if manual_journal.manual_journal_id.nil?
454
+ save_manual_journal(manual_journal)
455
+ end
456
+
457
+ # Retrieves all manual journals from Xero
458
+ #
459
+ # Usage : get_manual_journal
460
+ # getmanual_journal(:manual_journal_id => " 297c2dc5-cc47-4afd-8ec8-74990b8761e9")
461
+ #
462
+ # Note : modified_since is in UTC format (i.e. Brisbane is UTC+10)
463
+ def get_manual_journals(options = {})
464
+ request_params = {}
465
+ request_params[:ManualJournalID] = options[:manual_journal_id] if options[:manual_journal_id]
466
+ request_params[:ModifiedAfter] = options[:modified_since] if options[:modified_since]
467
+
468
+ response_xml = http_get(@client, "#{@xero_url}/ManualJournals", request_params)
469
+
470
+ parse_response(response_xml, {:request_params => request_params}, {:request_signature => 'GET/ManualJournals'})
471
+ end
472
+
473
+ # Retrieves a single manual journal
474
+ #
475
+ # Usage : get_manual_journal("297c2dc5-cc47-4afd-8ec8-74990b8761e9") # By ID
476
+ # get_manual_journal("OIT-12345") # By number
477
+ def get_manual_journal(manual_journal_id)
478
+ request_params = {}
479
+ url = "#{@xero_url}/ManualJournals/#{URI.escape(manual_journal_id)}"
480
+ response_xml = http_get(@client, url, request_params)
481
+ parse_response(response_xml, {:request_params => request_params}, {:request_signature => 'GET/ManualJournal'})
482
+ end
483
+
422
484
  #
423
485
  # Gets all accounts for a specific organization in Xero.
424
486
  #
@@ -426,7 +488,7 @@ module XeroGateway
426
488
  response_xml = http_get(@client, "#{xero_url}/Accounts")
427
489
  parse_response(response_xml, {}, {:request_signature => 'GET/accounts'})
428
490
  end
429
-
491
+
430
492
  #
431
493
  # Returns a XeroGateway::AccountsList object that makes working with
432
494
  # the Xero list of accounts easier and allows caching the results.
@@ -451,7 +513,7 @@ module XeroGateway
451
513
  response_xml = http_get(@client, "#{xero_url}/Organisation")
452
514
  parse_response(response_xml, {}, {:request_signature => 'GET/organisation'})
453
515
  end
454
-
516
+
455
517
  #
456
518
  # Gets all currencies for a specific organisation in Xero
457
519
  #
@@ -459,7 +521,7 @@ module XeroGateway
459
521
  response_xml = http_get(@client, "#{xero_url}/Currencies")
460
522
  parse_response(response_xml, {}, {:request_signature => 'GET/currencies'})
461
523
  end
462
-
524
+
463
525
  #
464
526
  # Gets all Tax Rates for a specific organisation in Xero
465
527
  #
@@ -468,25 +530,40 @@ module XeroGateway
468
530
  parse_response(response_xml, {}, {:request_signature => 'GET/tax_rates'})
469
531
  end
470
532
 
533
+ #
534
+ # Get report for a specific organisation in Xero
535
+ #
471
536
  def get_report(report_name, request_params = {})
472
537
  response_xml = http_get(@client, "#{@xero_url}/Reports/#{report_name}", request_params)
473
538
  end
474
539
 
540
+ #
541
+ # Create Payment record in Xero
542
+ #
543
+ def create_payment(payment)
544
+ b = Builder::XmlMarkup.new
545
+
546
+ request_xml = b.Payments do
547
+ payment.to_xml(b)
548
+ end
549
+
550
+ response_xml = http_put(@client, "#{xero_url}/Payments", request_xml)
551
+ parse_response(response_xml, {:request_xml => request_xml}, {:request_signature => 'PUT/payments'})
552
+ end
475
553
 
476
554
  private
477
555
 
478
- def get_contact(contact_id = nil, contact_number = nil)
556
+ def get_contact(contact_id = nil, contact_number = nil)
479
557
  request_params = contact_id ? { :contactID => contact_id } : { :contactNumber => contact_number }
480
558
  response_xml = http_get(@client, "#{@xero_url}/Contacts/#{URI.escape(contact_id||contact_number)}", request_params)
481
559
 
482
560
  parse_response(response_xml, {:request_params => request_params}, {:request_signature => 'GET/contact'})
483
561
  end
484
562
 
485
-
486
563
  # Create or update a contact record based on if it has a contact_id or contact_number.
487
564
  def save_contact(contact)
488
565
  request_xml = contact.to_xml
489
-
566
+
490
567
  response_xml = nil
491
568
  create_or_save = nil
492
569
  if contact.contact_id.nil? && contact.contact_number.nil?
@@ -507,7 +584,7 @@ module XeroGateway
507
584
  # Create or update an invoice record based on if it has an invoice_id.
508
585
  def save_invoice(invoice)
509
586
  request_xml = invoice.to_xml
510
-
587
+
511
588
  response_xml = nil
512
589
  create_or_save = nil
513
590
  if invoice.invoice_id.nil?
@@ -521,15 +598,15 @@ module XeroGateway
521
598
  end
522
599
 
523
600
  response = parse_response(response_xml, {:request_xml => request_xml}, {:request_signature => "#{create_or_save == :create ? 'PUT' : 'POST'}/invoice"})
524
-
601
+
525
602
  # Xero returns invoices inside an <Invoices> tag, even though there's only ever
526
603
  # one for this request
527
604
  response.response_item = response.invoices.first
528
-
605
+
529
606
  if response.success? && response.invoice && response.invoice.invoice_id
530
- invoice.invoice_id = response.invoice.invoice_id
607
+ invoice.invoice_id = response.invoice.invoice_id
531
608
  end
532
-
609
+
533
610
  response
534
611
  end
535
612
 
@@ -562,17 +639,44 @@ module XeroGateway
562
639
  response
563
640
  end
564
641
 
642
+ # Create or update a manual journal record based on if it has an manual_journal_id.
643
+ def save_manual_journal(manual_journal)
644
+ request_xml = manual_journal.to_xml
645
+ response_xml = nil
646
+ create_or_save = nil
647
+
648
+ if manual_journal.manual_journal_id.nil?
649
+ # Create new manual journal record.
650
+ response_xml = http_put(@client, "#{@xero_url}/ManualJournals", request_xml, {})
651
+ create_or_save = :create
652
+ else
653
+ # Update existing manual journal record.
654
+ response_xml = http_post(@client, "#{@xero_url}/ManualJournals", request_xml, {})
655
+ create_or_save = :save
656
+ end
657
+
658
+ response = parse_response(response_xml, {:request_xml => request_xml}, {:request_signature => "#{create_or_save == :create ? 'PUT' : 'POST'}/ManualJournals"})
659
+
660
+ # Xero returns manual journals inside an <ManualJournals> tag, even though there's only ever
661
+ # one for this request
662
+ response.response_item = response.manual_journals.first
663
+
664
+ manual_journal.manual_journal_id = response.manual_journal.manual_journal_id if response.success? && response.manual_journal && response.manual_journal.manual_journal_id
665
+
666
+ response
667
+ end
668
+
565
669
  def parse_response(raw_response, request = {}, options = {})
566
670
 
567
671
  response = XeroGateway::Response.new
568
672
 
569
673
  doc = REXML::Document.new(raw_response, :ignore_whitespace_nodes => :all)
570
-
674
+
571
675
  # check for responses we don't understand
572
676
  raise UnparseableResponse.new(doc.root.name) unless doc.root.name == "Response"
573
677
 
574
678
  response_element = REXML::XPath.first(doc, "/Response")
575
-
679
+
576
680
  response_element.children.reject { |e| e.is_a? REXML::Text }.each do |element|
577
681
  case(element.name)
578
682
  when "ID" then response.response_id = element.text
@@ -583,40 +687,38 @@ module XeroGateway
583
687
  when "Invoice" then response.response_item = Invoice.from_xml(element, self, {:line_items_downloaded => options[:request_signature] != "GET/Invoices"})
584
688
  when "BankTransaction"
585
689
  response.response_item = BankTransaction.from_xml(element, self, {:line_items_downloaded => options[:request_signature] != "GET/BankTransactions"})
690
+ when "ManualJournal"
691
+ response.response_item = ManualJournal.from_xml(element, self, {:journal_lines_downloaded => options[:request_signature] != "GET/ManualJournals"})
586
692
  when "Contacts" then element.children.each {|child| response.response_item << Contact.from_xml(child, self) }
587
693
  when "Invoices" then element.children.each {|child| response.response_item << Invoice.from_xml(child, self, {:line_items_downloaded => options[:request_signature] != "GET/Invoices"}) }
588
694
  when "BankTransactions"
589
695
  element.children.each do |child|
590
696
  response.response_item << BankTransaction.from_xml(child, self, {:line_items_downloaded => options[:request_signature] != "GET/BankTransactions"})
591
697
  end
698
+ when "ManualJournals"
699
+ element.children.each do |child|
700
+ response.response_item << ManualJournal.from_xml(child, self, {:journal_lines_downloaded => options[:request_signature] != "GET/ManualJournals"})
701
+ end
592
702
  when "CreditNotes" then element.children.each {|child| response.response_item << CreditNote.from_xml(child, self, {:line_items_downloaded => options[:request_signature] != "GET/CreditNotes"}) }
593
703
  when "Accounts" then element.children.each {|child| response.response_item << Account.from_xml(child) }
594
704
  when "TaxRates" then element.children.each {|child| response.response_item << TaxRate.from_xml(child) }
595
705
  when "Currencies" then element.children.each {|child| response.response_item << Currency.from_xml(child) }
596
706
  when "Organisations" then response.response_item = Organisation.from_xml(element.children.first) # Xero only returns the Authorized Organisation
597
707
  when "TrackingCategories" then element.children.each {|child| response.response_item << TrackingCategory.from_xml(child) }
598
- when "Errors" then element.children.each { |error| parse_error(error, response) }
708
+ when "Errors" then response.errors = element.children.map { |error| Error.parse(error) }
599
709
  end
600
710
  end if response_element
601
-
711
+
602
712
  # If a single result is returned don't put it in an array
603
713
  if response.response_item.is_a?(Array) && response.response_item.size == 1
604
714
  response.response_item = response.response_item.first
605
715
  end
606
-
716
+
607
717
  response.request_params = request[:request_params]
608
718
  response.request_xml = request[:request_xml]
609
719
  response.response_xml = raw_response
610
720
  response
611
- end
612
-
613
- def parse_error(error_element, response)
614
- response.errors << Error.new(
615
- :description => REXML::XPath.first(error_element, "Description").text,
616
- :date_time => REXML::XPath.first(error_element, "//DateTime").text,
617
- :type => REXML::XPath.first(error_element, "//ExceptionType").text,
618
- :message => REXML::XPath.first(error_element, "//Message").text
619
- )
620
721
  end
621
- end
722
+
723
+ end
622
724
  end