xero_gateway 2.0.13 → 2.0.14
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.
- data/Gemfile +2 -1
- data/README.textile +10 -7
- data/Rakefile +1 -1
- data/lib/xero_gateway.rb +2 -0
- data/lib/xero_gateway/account.rb +5 -5
- data/lib/xero_gateway/address.rb +2 -3
- data/lib/xero_gateway/bank_transaction.rb +175 -0
- data/lib/xero_gateway/contact.rb +1 -1
- data/lib/xero_gateway/credit_note.rb +1 -54
- data/lib/xero_gateway/exceptions.rb +1 -1
- data/lib/xero_gateway/gateway.rb +104 -0
- data/lib/xero_gateway/invoice.rb +8 -61
- data/lib/xero_gateway/line_item_calculations.rb +55 -0
- data/lib/xero_gateway/response.rb +13 -11
- data/test/integration/create_bank_transaction_test.rb +38 -0
- data/test/integration/get_bank_transaction_test.rb +50 -0
- data/test/integration/get_bank_transactions_test.rb +88 -0
- data/test/integration/update_bank_transaction_test.rb +31 -0
- data/test/test_helper.rb +76 -1
- data/test/unit/account_test.rb +15 -3
- data/test/unit/bank_transaction_test.rb +114 -0
- data/test/unit/invoice_test.rb +48 -29
- data/test/unit/oauth_test.rb +13 -4
- data/xero_gateway.gemspec +2 -2
- metadata +48 -75
data/Gemfile
CHANGED
data/README.textile
CHANGED
@@ -222,14 +222,17 @@ Invoice and line item totals are calculated automatically.
|
|
222
222
|
})
|
223
223
|
invoice.contact.name = "THE NAME OF THE CONTACT"
|
224
224
|
invoice.contact.phone.number = "12345"
|
225
|
-
invoice.contact.address.line_1 = "LINE 1 OF THE ADDRESS"
|
226
|
-
|
225
|
+
invoice.contact.address.line_1 = "LINE 1 OF THE ADDRESS"
|
226
|
+
|
227
|
+
line_item = XeroGateway::LineItem.new(
|
227
228
|
:description => "THE DESCRIPTION OF THE LINE ITEM",
|
228
|
-
:
|
229
|
-
:
|
230
|
-
|
231
|
-
|
232
|
-
|
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
|
233
236
|
|
234
237
|
invoice.create</code></pre>
|
235
238
|
|
data/Rakefile
CHANGED
data/lib/xero_gateway.rb
CHANGED
@@ -15,6 +15,7 @@ require File.join(File.dirname(__FILE__), 'xero_gateway', 'http_encoding_helper'
|
|
15
15
|
require File.join(File.dirname(__FILE__), 'xero_gateway', 'http')
|
16
16
|
require File.join(File.dirname(__FILE__), 'xero_gateway', 'dates')
|
17
17
|
require File.join(File.dirname(__FILE__), 'xero_gateway', 'money')
|
18
|
+
require File.join(File.dirname(__FILE__), 'xero_gateway', 'line_item_calculations')
|
18
19
|
require File.join(File.dirname(__FILE__), 'xero_gateway', 'response')
|
19
20
|
require File.join(File.dirname(__FILE__), 'xero_gateway', 'account')
|
20
21
|
require File.join(File.dirname(__FILE__), 'xero_gateway', 'accounts_list')
|
@@ -23,6 +24,7 @@ require File.join(File.dirname(__FILE__), 'xero_gateway', 'contact')
|
|
23
24
|
require File.join(File.dirname(__FILE__), 'xero_gateway', 'line_item')
|
24
25
|
require File.join(File.dirname(__FILE__), 'xero_gateway', 'payment')
|
25
26
|
require File.join(File.dirname(__FILE__), 'xero_gateway', 'invoice')
|
27
|
+
require File.join(File.dirname(__FILE__), 'xero_gateway', 'bank_transaction')
|
26
28
|
require File.join(File.dirname(__FILE__), 'xero_gateway', 'credit_note')
|
27
29
|
require File.join(File.dirname(__FILE__), 'xero_gateway', 'address')
|
28
30
|
require File.join(File.dirname(__FILE__), 'xero_gateway', 'phone')
|
data/lib/xero_gateway/account.rb
CHANGED
@@ -35,7 +35,7 @@ module XeroGateway
|
|
35
35
|
'ZERORATED' => 'Zero-rated supplies/sales from overseas (NZ Only)'
|
36
36
|
} unless defined?(TAX_TYPE)
|
37
37
|
|
38
|
-
attr_accessor :account_id, :code, :name, :type, :tax_type, :description, :system_account, :enable_payments_to_account
|
38
|
+
attr_accessor :account_id, :code, :name, :type, :tax_type, :description, :system_account, :enable_payments_to_account, :currency_code
|
39
39
|
|
40
40
|
def initialize(params = {})
|
41
41
|
params.each do |k,v|
|
@@ -50,10 +50,8 @@ module XeroGateway
|
|
50
50
|
return true
|
51
51
|
end
|
52
52
|
|
53
|
-
def to_xml
|
54
|
-
b
|
55
|
-
|
56
|
-
b.Account {
|
53
|
+
def to_xml(b = Builder::XmlMarkup.new, options={})
|
54
|
+
b.tag!(options[:name] ? options[:name] : 'Account') {
|
57
55
|
b.AccountID self.account_id
|
58
56
|
b.Code self.code
|
59
57
|
b.Name self.name
|
@@ -62,6 +60,7 @@ module XeroGateway
|
|
62
60
|
b.Description self.description
|
63
61
|
b.SystemAccount self.system_account unless self.system_account.nil?
|
64
62
|
b.EnablePaymentsToAccount self.enable_payments_to_account
|
63
|
+
b.CurrencyCode currency_code if currency_code
|
65
64
|
}
|
66
65
|
end
|
67
66
|
|
@@ -77,6 +76,7 @@ module XeroGateway
|
|
77
76
|
when "Description" then account.description = element.text
|
78
77
|
when "SystemAccount" then account.system_account = element.text
|
79
78
|
when "EnablePaymentsToAccount" then account.enable_payments_to_account = (element.text == 'true')
|
79
|
+
when "CurrencyCode" then account.currency_code = element.text
|
80
80
|
end
|
81
81
|
end
|
82
82
|
account
|
data/lib/xero_gateway/address.rb
CHANGED
@@ -3,8 +3,7 @@ module XeroGateway
|
|
3
3
|
|
4
4
|
ADDRESS_TYPE = {
|
5
5
|
'STREET' => 'Street',
|
6
|
-
'POBOX' => 'PO Box'
|
7
|
-
'DEFAULT' => 'Default address type'
|
6
|
+
'POBOX' => 'PO Box'
|
8
7
|
} unless defined?(ADDRESS_TYPE)
|
9
8
|
|
10
9
|
# Any errors that occurred when the #valid? method called.
|
@@ -16,7 +15,7 @@ module XeroGateway
|
|
16
15
|
@errors ||= []
|
17
16
|
|
18
17
|
params = {
|
19
|
-
:address_type => "
|
18
|
+
:address_type => "POBOX"
|
20
19
|
}.merge(params)
|
21
20
|
|
22
21
|
params.each do |k,v|
|
@@ -0,0 +1,175 @@
|
|
1
|
+
module XeroGateway
|
2
|
+
class BankTransaction
|
3
|
+
include Dates
|
4
|
+
include LineItemCalculations
|
5
|
+
|
6
|
+
class NoGatewayError < Error; end
|
7
|
+
|
8
|
+
GUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/ unless defined?(GUID_REGEX)
|
9
|
+
|
10
|
+
TYPES = {
|
11
|
+
'RECEIVE' => 'Receive Bank Transaction',
|
12
|
+
'SPEND' => 'Spend Bank Transaction',
|
13
|
+
} unless defined?(TYPES)
|
14
|
+
|
15
|
+
STATUSES = {
|
16
|
+
'ACTIVE' => 'Bank Transaction is active',
|
17
|
+
'DELETED' => 'Bank Transaction is deleted',
|
18
|
+
} unless defined?(STATUSES)
|
19
|
+
|
20
|
+
# Xero::Gateway associated with this invoice.
|
21
|
+
attr_accessor :gateway
|
22
|
+
|
23
|
+
# Any errors that occurred when the #valid? method called.
|
24
|
+
attr_reader :errors
|
25
|
+
|
26
|
+
# Represents whether the line_items have been downloaded when getting from GET /API.XRO/2.0/BankTransactions
|
27
|
+
attr_accessor :line_items_downloaded
|
28
|
+
|
29
|
+
# accessible fields
|
30
|
+
attr_accessor :bank_transaction_id, :type, :date, :reference, :status, :contact, :line_items, :bank_account, :url
|
31
|
+
|
32
|
+
def initialize(params = {})
|
33
|
+
@errors ||= []
|
34
|
+
@payments ||= []
|
35
|
+
|
36
|
+
# Check if the line items have been downloaded.
|
37
|
+
@line_items_downloaded = (params.delete(:line_items_downloaded) == true)
|
38
|
+
|
39
|
+
# params = {
|
40
|
+
# :line_amount_types => "Exclusive"
|
41
|
+
# }.merge(params)
|
42
|
+
params.each do |k,v|
|
43
|
+
self.send("#{k}=", v)
|
44
|
+
end
|
45
|
+
|
46
|
+
@line_items ||= []
|
47
|
+
end
|
48
|
+
|
49
|
+
def ==(other)
|
50
|
+
['type', 'reference', 'status', 'contact', 'line_items', 'bank_account'].each do |field|
|
51
|
+
return false if send(field) != other.send(field)
|
52
|
+
end
|
53
|
+
|
54
|
+
["date"].each do |field|
|
55
|
+
return false if send(field).to_s != other.send(field).to_s
|
56
|
+
end
|
57
|
+
return true
|
58
|
+
end
|
59
|
+
|
60
|
+
# Validate the BankTransaction record according to what will be valid by the gateway.
|
61
|
+
#
|
62
|
+
# Usage:
|
63
|
+
# bank_transaction.valid? # Returns true/false
|
64
|
+
#
|
65
|
+
# Additionally sets bank_transaction.errors array to an array of field/error.
|
66
|
+
def valid?
|
67
|
+
@errors = []
|
68
|
+
|
69
|
+
if !bank_transaction_id.nil? && bank_transaction_id !~ GUID_REGEX
|
70
|
+
@errors << ['bank_transaction_id', 'must be blank or a valid Xero GUID']
|
71
|
+
end
|
72
|
+
|
73
|
+
if type && !TYPES[type]
|
74
|
+
@errors << ['type', "must be one of #{TYPES.keys.join('/')}"]
|
75
|
+
end
|
76
|
+
|
77
|
+
if status && !STATUSES[status]
|
78
|
+
@errors << ['status', "must be one of #{STATUSES.keys.join('/')}"]
|
79
|
+
end
|
80
|
+
|
81
|
+
unless date
|
82
|
+
@errors << ['date', "can't be blank"]
|
83
|
+
end
|
84
|
+
|
85
|
+
# Make sure contact is valid.
|
86
|
+
unless @contact && @contact.valid?
|
87
|
+
@errors << ['contact', 'is invalid']
|
88
|
+
end
|
89
|
+
|
90
|
+
# Make sure all line_items are valid.
|
91
|
+
unless line_items.all? { | line_item | line_item.valid? }
|
92
|
+
@errors << ['line_items', "at least one line item invalid"]
|
93
|
+
end
|
94
|
+
|
95
|
+
@errors.size == 0
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
def line_items_downloaded?
|
100
|
+
@line_items_downloaded
|
101
|
+
end
|
102
|
+
|
103
|
+
# If line items are not downloaded, then attempt a download now (if this record was found to begin with).
|
104
|
+
def line_items
|
105
|
+
if line_items_downloaded?
|
106
|
+
@line_items
|
107
|
+
|
108
|
+
elsif bank_transaction_id =~ GUID_REGEX && @gateway
|
109
|
+
# There is a bank_transaction_id so we can assume this record was loaded from Xero.
|
110
|
+
# Let's attempt to download the line_item records (if there is a gateway)
|
111
|
+
|
112
|
+
response = @gateway.get_bank_transaction(bank_transaction_id)
|
113
|
+
raise BankTransactionNotFoundError, "Bank Transaction with ID #{bank_transaction_id} not found in Xero." unless response.success? && response.bank_transaction.is_a?(XeroGateway::BankTransaction)
|
114
|
+
|
115
|
+
@line_items = response.bank_transaction.line_items
|
116
|
+
@line_items_downloaded = true
|
117
|
+
|
118
|
+
@line_items
|
119
|
+
|
120
|
+
# Otherwise, this is a new bank transaction, so return the line_items reference.
|
121
|
+
else
|
122
|
+
@line_items
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def to_xml(b = Builder::XmlMarkup.new)
|
127
|
+
b.BankTransaction {
|
128
|
+
b.BankTransactionID bank_transaction_id if bank_transaction_id
|
129
|
+
b.Type type
|
130
|
+
# b.CurrencyCode self.currency_code if self.currency_code
|
131
|
+
contact.to_xml(b)
|
132
|
+
bank_account.to_xml(b, :name => 'BankAccount')
|
133
|
+
b.Date BankTransaction.format_date(date || Date.today)
|
134
|
+
b.Status status if status
|
135
|
+
b.Reference reference if reference
|
136
|
+
b.LineItems {
|
137
|
+
self.line_items.each do |line_item|
|
138
|
+
line_item.to_xml(b)
|
139
|
+
end
|
140
|
+
}
|
141
|
+
b.Url url if url
|
142
|
+
}
|
143
|
+
end
|
144
|
+
|
145
|
+
def self.from_xml(bank_transaction_element, gateway = nil, options = {})
|
146
|
+
bank_transaction = BankTransaction.new(options.merge({:gateway => gateway}))
|
147
|
+
bank_transaction_element.children.each do |element|
|
148
|
+
case(element.name)
|
149
|
+
when "BankTransactionID" then bank_transaction.bank_transaction_id = element.text
|
150
|
+
when "Type" then bank_transaction.type = element.text
|
151
|
+
# when "CurrencyCode" then invoice.currency_code = element.text
|
152
|
+
when "Contact" then bank_transaction.contact = Contact.from_xml(element)
|
153
|
+
when "BankAccount" then bank_transaction.bank_account = Account.from_xml(element)
|
154
|
+
when "Date" then bank_transaction.date = parse_date(element.text)
|
155
|
+
when "Status" then bank_transaction.status = element.text
|
156
|
+
when "Reference" then bank_transaction.reference = element.text
|
157
|
+
when "LineItems" then element.children.each {|line_item| bank_transaction.line_items_downloaded = true; bank_transaction.line_items << LineItem.from_xml(line_item) }
|
158
|
+
# when "SubTotal" then invoice.sub_total = BigDecimal.new(element.text)
|
159
|
+
# when "TotalTax" then invoice.total_tax = BigDecimal.new(element.text)
|
160
|
+
# when "Total" then invoice.total = BigDecimal.new(element.text)
|
161
|
+
# when "InvoiceID" then invoice.invoice_id = element.text
|
162
|
+
# when "InvoiceNumber" then invoice.invoice_number = element.text
|
163
|
+
# when "Payments" then element.children.each { | payment | invoice.payments << Payment.from_xml(payment) }
|
164
|
+
# when "AmountDue" then invoice.amount_due = BigDecimal.new(element.text)
|
165
|
+
# when "AmountPaid" then invoice.amount_paid = BigDecimal.new(element.text)
|
166
|
+
# when "AmountCredited" then invoice.amount_credited = BigDecimal.new(element.text)
|
167
|
+
# when "SentToContact" then invoice.sent_to_contact = (element.text.strip.downcase == "true")
|
168
|
+
when "Url" then bank_transaction.url = element.text
|
169
|
+
end
|
170
|
+
end
|
171
|
+
bank_transaction
|
172
|
+
end # from_xml
|
173
|
+
|
174
|
+
end
|
175
|
+
end
|
data/lib/xero_gateway/contact.rb
CHANGED
@@ -109,7 +109,7 @@ module XeroGateway
|
|
109
109
|
|
110
110
|
# Make sure all phone numbers are correct.
|
111
111
|
unless phones.all? { | phone | phone.valid? }
|
112
|
-
@errors << ['phones', 'at
|
112
|
+
@errors << ['phones', 'at least one phone is invalid']
|
113
113
|
end
|
114
114
|
|
115
115
|
@errors.size == 0
|
@@ -2,10 +2,9 @@ module XeroGateway
|
|
2
2
|
class CreditNote
|
3
3
|
include Dates
|
4
4
|
include Money
|
5
|
+
include LineItemCalculations
|
5
6
|
|
6
|
-
class Error < RuntimeError; end
|
7
7
|
class NoGatewayError < Error; end
|
8
|
-
class InvalidLineItemError < Error; end
|
9
8
|
|
10
9
|
CREDIT_NOTE_TYPE = {
|
11
10
|
'ACCRECCREDIT' => 'Accounts Receivable',
|
@@ -107,58 +106,6 @@ module XeroGateway
|
|
107
106
|
@contact ||= build_contact
|
108
107
|
end
|
109
108
|
|
110
|
-
# Helper method to create a new associated line_item.
|
111
|
-
# Usage:
|
112
|
-
# credit_note.add_line_item({:description => "Bob's Widgets", :quantity => 1, :unit_amount => 120})
|
113
|
-
def add_line_item(params = {})
|
114
|
-
line_item = nil
|
115
|
-
case params
|
116
|
-
when Hash then line_item = LineItem.new(params)
|
117
|
-
when LineItem then line_item = params
|
118
|
-
else raise InvalidLineItemError
|
119
|
-
end
|
120
|
-
|
121
|
-
@line_items << line_item
|
122
|
-
|
123
|
-
line_item
|
124
|
-
end
|
125
|
-
|
126
|
-
# Deprecated (but API for setter remains).
|
127
|
-
#
|
128
|
-
# As sub_total must equal SUM(line_item.line_amount) for the API call to pass, this is now
|
129
|
-
# automatically calculated in the sub_total method.
|
130
|
-
def sub_total=(value)
|
131
|
-
end
|
132
|
-
|
133
|
-
# Calculate the sub_total as the SUM(line_item.line_amount).
|
134
|
-
def sub_total
|
135
|
-
line_items.inject(BigDecimal.new('0')) { | sum, line_item | sum + BigDecimal.new(line_item.line_amount.to_s) }
|
136
|
-
end
|
137
|
-
|
138
|
-
# Deprecated (but API for setter remains).
|
139
|
-
#
|
140
|
-
# As total_tax must equal SUM(line_item.tax_amount) for the API call to pass, this is now
|
141
|
-
# automatically calculated in the total_tax method.
|
142
|
-
def total_tax=(value)
|
143
|
-
end
|
144
|
-
|
145
|
-
# Calculate the total_tax as the SUM(line_item.tax_amount).
|
146
|
-
def total_tax
|
147
|
-
line_items.inject(BigDecimal.new('0')) { | sum, line_item | sum + BigDecimal.new(line_item.tax_amount.to_s) }
|
148
|
-
end
|
149
|
-
|
150
|
-
# Deprecated (but API for setter remains).
|
151
|
-
#
|
152
|
-
# As total must equal sub_total + total_tax for the API call to pass, this is now
|
153
|
-
# automatically calculated in the total method.
|
154
|
-
def total=(value)
|
155
|
-
end
|
156
|
-
|
157
|
-
# Calculate the toal as sub_total + total_tax.
|
158
|
-
def total
|
159
|
-
sub_total + total_tax
|
160
|
-
end
|
161
|
-
|
162
109
|
# Helper method to check if the credit_note is accounts payable.
|
163
110
|
def accounts_payable?
|
164
111
|
type == 'ACCPAYCREDIT'
|
data/lib/xero_gateway/gateway.rb
CHANGED
@@ -349,6 +349,75 @@ module XeroGateway
|
|
349
349
|
response
|
350
350
|
end
|
351
351
|
|
352
|
+
# Creates a bank transaction in Xero based on a bank transaction object.
|
353
|
+
#
|
354
|
+
# Bank transaction and line item totals are calculated automatically.
|
355
|
+
#
|
356
|
+
# Usage :
|
357
|
+
#
|
358
|
+
# bank_transaction = XeroGateway::BankTransaction.new({
|
359
|
+
# :type => "RECEIVE",
|
360
|
+
# :date => 1.month.from_now,
|
361
|
+
# :reference => "YOUR INVOICE NUMBER",
|
362
|
+
# })
|
363
|
+
# bank_transaction.contact = XeroGateway::Contact.new(:name => "THE NAME OF THE CONTACT")
|
364
|
+
# bank_transaction.contact.phone.number = "12345"
|
365
|
+
# bank_transaction.contact.address.line_1 = "LINE 1 OF THE ADDRESS"
|
366
|
+
# bank_transaction.line_items << XeroGateway::LineItem.new(
|
367
|
+
# :description => "THE DESCRIPTION OF THE LINE ITEM",
|
368
|
+
# :unit_amount => 100,
|
369
|
+
# :tax_amount => 12.5,
|
370
|
+
# :tracking_category => "THE TRACKING CATEGORY FOR THE LINE ITEM",
|
371
|
+
# :tracking_option => "THE TRACKING OPTION FOR THE LINE ITEM"
|
372
|
+
# )
|
373
|
+
# bank_transaction.bank_account = XeroGateway::Account.new(:code => 'BANK-ABC)
|
374
|
+
#
|
375
|
+
# create_bank_transaction(bank_transaction)
|
376
|
+
def create_bank_transaction(bank_transaction)
|
377
|
+
save_bank_transaction(bank_transaction)
|
378
|
+
end
|
379
|
+
|
380
|
+
#
|
381
|
+
# Updates an existing Xero bank transaction
|
382
|
+
#
|
383
|
+
# Usage :
|
384
|
+
#
|
385
|
+
# bank_transaction = xero_gateway.get_bank_transaction(some_bank_transaction_id)
|
386
|
+
# bank_transaction.due_date = Date.today
|
387
|
+
#
|
388
|
+
# xero_gateway.update_bank_transaction(bank_transaction)
|
389
|
+
def update_bank_transaction(bank_transaction)
|
390
|
+
raise "bank_transaction_id is required for updating bank transactions" if bank_transaction.bank_transaction_id.nil?
|
391
|
+
save_bank_transaction(bank_transaction)
|
392
|
+
end
|
393
|
+
|
394
|
+
# Retrieves all bank transactions from Xero
|
395
|
+
#
|
396
|
+
# Usage : get_bank_transactions
|
397
|
+
# get_bank_transactions(:bank_transaction_id => " 297c2dc5-cc47-4afd-8ec8-74990b8761e9")
|
398
|
+
#
|
399
|
+
# Note : modified_since is in UTC format (i.e. Brisbane is UTC+10)
|
400
|
+
def get_bank_transactions(options = {})
|
401
|
+
request_params = {}
|
402
|
+
request_params[:BankTransactionID] = options[:bank_transaction_id] if options[:bank_transaction_id]
|
403
|
+
request_params[:ModifiedAfter] = options[:modified_since] if options[:modified_since]
|
404
|
+
|
405
|
+
response_xml = http_get(@client, "#{@xero_url}/BankTransactions", request_params)
|
406
|
+
|
407
|
+
parse_response(response_xml, {:request_params => request_params}, {:request_signature => 'GET/BankTransactions'})
|
408
|
+
end
|
409
|
+
|
410
|
+
# Retrieves a single bank transaction
|
411
|
+
#
|
412
|
+
# Usage : get_bank_transaction("297c2dc5-cc47-4afd-8ec8-74990b8761e9") # By ID
|
413
|
+
# get_bank_transaction("OIT-12345") # By number
|
414
|
+
def get_bank_transaction(bank_transaction_id)
|
415
|
+
request_params = {}
|
416
|
+
url = "#{@xero_url}/BankTransactions/#{URI.escape(bank_transaction_id)}"
|
417
|
+
response_xml = http_get(@client, url, request_params)
|
418
|
+
parse_response(response_xml, {:request_params => request_params}, {:request_signature => 'GET/BankTransaction'})
|
419
|
+
end
|
420
|
+
|
352
421
|
#
|
353
422
|
# Gets all accounts for a specific organization in Xero.
|
354
423
|
#
|
@@ -457,6 +526,35 @@ module XeroGateway
|
|
457
526
|
response
|
458
527
|
end
|
459
528
|
|
529
|
+
# Create or update a bank transaction record based on if it has an bank_transaction_id.
|
530
|
+
def save_bank_transaction(bank_transaction)
|
531
|
+
request_xml = bank_transaction.to_xml
|
532
|
+
response_xml = nil
|
533
|
+
create_or_save = nil
|
534
|
+
|
535
|
+
if bank_transaction.bank_transaction_id.nil?
|
536
|
+
# Create new bank transaction record.
|
537
|
+
response_xml = http_put(@client, "#{@xero_url}/BankTransactions", request_xml, {})
|
538
|
+
create_or_save = :create
|
539
|
+
else
|
540
|
+
# Update existing bank transaction record.
|
541
|
+
response_xml = http_post(@client, "#{@xero_url}/BankTransactions", request_xml, {})
|
542
|
+
create_or_save = :save
|
543
|
+
end
|
544
|
+
|
545
|
+
response = parse_response(response_xml, {:request_xml => request_xml}, {:request_signature => "#{create_or_save == :create ? 'PUT' : 'POST'}/BankTransactions"})
|
546
|
+
|
547
|
+
# Xero returns bank transactions inside an <BankTransactions> tag, even though there's only ever
|
548
|
+
# one for this request
|
549
|
+
response.response_item = response.bank_transactions.first
|
550
|
+
|
551
|
+
if response.success? && response.bank_transaction && response.bank_transaction.bank_transaction_id
|
552
|
+
bank_transaction.bank_transaction_id = response.bank_transaction.bank_transaction_id
|
553
|
+
end
|
554
|
+
|
555
|
+
response
|
556
|
+
end
|
557
|
+
|
460
558
|
def parse_response(raw_response, request = {}, options = {})
|
461
559
|
|
462
560
|
response = XeroGateway::Response.new
|
@@ -476,8 +574,14 @@ module XeroGateway
|
|
476
574
|
when "DateTimeUTC" then response.date_time = element.text
|
477
575
|
when "Contact" then response.response_item = Contact.from_xml(element, self)
|
478
576
|
when "Invoice" then response.response_item = Invoice.from_xml(element, self, {:line_items_downloaded => options[:request_signature] != "GET/Invoices"})
|
577
|
+
when "BankTransaction"
|
578
|
+
response.response_item = BankTransaction.from_xml(element, self, {:line_items_downloaded => options[:request_signature] != "GET/BankTransactions"})
|
479
579
|
when "Contacts" then element.children.each {|child| response.response_item << Contact.from_xml(child, self) }
|
480
580
|
when "Invoices" then element.children.each {|child| response.response_item << Invoice.from_xml(child, self, {:line_items_downloaded => options[:request_signature] != "GET/Invoices"}) }
|
581
|
+
when "BankTransactions"
|
582
|
+
element.children.each do |child|
|
583
|
+
response.response_item << BankTransaction.from_xml(child, self, {:line_items_downloaded => options[:request_signature] != "GET/BankTransactions"})
|
584
|
+
end
|
481
585
|
when "CreditNotes" then element.children.each {|child| response.response_item << CreditNote.from_xml(child, self, {:line_items_downloaded => options[:request_signature] != "GET/CreditNotes"}) }
|
482
586
|
when "Accounts" then element.children.each {|child| response.response_item << Account.from_xml(child) }
|
483
587
|
when "TaxRates" then element.children.each {|child| response.response_item << TaxRate.from_xml(child) }
|