xero_gateway-n8vision 2.0.20

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/Gemfile +12 -0
  2. data/LICENSE +14 -0
  3. data/README.textile +357 -0
  4. data/Rakefile +14 -0
  5. data/examples/oauth.rb +25 -0
  6. data/examples/partner_app.rb +36 -0
  7. data/init.rb +1 -0
  8. data/lib/oauth/oauth_consumer.rb +14 -0
  9. data/lib/xero_gateway.rb +41 -0
  10. data/lib/xero_gateway/account.rb +86 -0
  11. data/lib/xero_gateway/accounts_list.rb +73 -0
  12. data/lib/xero_gateway/address.rb +96 -0
  13. data/lib/xero_gateway/bank_transaction.rb +175 -0
  14. data/lib/xero_gateway/ca-certificates.crt +2560 -0
  15. data/lib/xero_gateway/contact.rb +203 -0
  16. data/lib/xero_gateway/credit_note.rb +220 -0
  17. data/lib/xero_gateway/currency.rb +56 -0
  18. data/lib/xero_gateway/dates.rb +25 -0
  19. data/lib/xero_gateway/error.rb +18 -0
  20. data/lib/xero_gateway/exceptions.rb +51 -0
  21. data/lib/xero_gateway/gateway.rb +698 -0
  22. data/lib/xero_gateway/http.rb +135 -0
  23. data/lib/xero_gateway/http_encoding_helper.rb +49 -0
  24. data/lib/xero_gateway/invoice.rb +238 -0
  25. data/lib/xero_gateway/journal_line.rb +102 -0
  26. data/lib/xero_gateway/line_item.rb +125 -0
  27. data/lib/xero_gateway/line_item_calculations.rb +51 -0
  28. data/lib/xero_gateway/manual_journal.rb +163 -0
  29. data/lib/xero_gateway/money.rb +16 -0
  30. data/lib/xero_gateway/oauth.rb +92 -0
  31. data/lib/xero_gateway/organisation.rb +75 -0
  32. data/lib/xero_gateway/partner_app.rb +30 -0
  33. data/lib/xero_gateway/payment.rb +43 -0
  34. data/lib/xero_gateway/phone.rb +77 -0
  35. data/lib/xero_gateway/private_app.rb +17 -0
  36. data/lib/xero_gateway/response.rb +43 -0
  37. data/lib/xero_gateway/tax_rate.rb +63 -0
  38. data/lib/xero_gateway/tracking_category.rb +87 -0
  39. data/test/integration/accounts_list_test.rb +109 -0
  40. data/test/integration/create_bank_transaction_test.rb +38 -0
  41. data/test/integration/create_contact_test.rb +66 -0
  42. data/test/integration/create_credit_note_test.rb +49 -0
  43. data/test/integration/create_invoice_test.rb +49 -0
  44. data/test/integration/create_manual_journal_test.rb +35 -0
  45. data/test/integration/get_accounts_test.rb +23 -0
  46. data/test/integration/get_bank_transaction_test.rb +51 -0
  47. data/test/integration/get_bank_transactions_test.rb +88 -0
  48. data/test/integration/get_contact_test.rb +28 -0
  49. data/test/integration/get_contacts_test.rb +40 -0
  50. data/test/integration/get_credit_note_test.rb +48 -0
  51. data/test/integration/get_credit_notes_test.rb +90 -0
  52. data/test/integration/get_currencies_test.rb +25 -0
  53. data/test/integration/get_invoice_test.rb +48 -0
  54. data/test/integration/get_invoices_test.rb +92 -0
  55. data/test/integration/get_manual_journal_test.rb +50 -0
  56. data/test/integration/get_manual_journals_test.rb +88 -0
  57. data/test/integration/get_organisation_test.rb +24 -0
  58. data/test/integration/get_tax_rates_test.rb +25 -0
  59. data/test/integration/get_tracking_categories_test.rb +27 -0
  60. data/test/integration/update_bank_transaction_test.rb +31 -0
  61. data/test/integration/update_contact_test.rb +31 -0
  62. data/test/integration/update_invoice_test.rb +31 -0
  63. data/test/integration/update_manual_journal_test.rb +31 -0
  64. data/test/test_helper.rb +217 -0
  65. data/test/unit/account_test.rb +47 -0
  66. data/test/unit/bank_transaction_test.rb +126 -0
  67. data/test/unit/contact_test.rb +97 -0
  68. data/test/unit/credit_note_test.rb +284 -0
  69. data/test/unit/currency_test.rb +31 -0
  70. data/test/unit/gateway_test.rb +119 -0
  71. data/test/unit/invoice_test.rb +326 -0
  72. data/test/unit/manual_journal_test.rb +93 -0
  73. data/test/unit/oauth_test.rb +116 -0
  74. data/test/unit/organisation_test.rb +38 -0
  75. data/test/unit/tax_rate_test.rb +38 -0
  76. data/test/unit/tracking_category_test.rb +52 -0
  77. data/xero_gateway-n8vision.gemspec +15 -0
  78. metadata +178 -0
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'xero_gateway'
@@ -0,0 +1,14 @@
1
+ module OAuth
2
+ class Consumer
3
+
4
+ def http_with_ssl_client_certificates(*args)
5
+ @http ||= http_without_ssl_client_certificates(*args).tap do |http|
6
+ http.cert = options[:ssl_client_cert]
7
+ http.key = options[:ssl_client_key]
8
+ end
9
+ end
10
+
11
+ alias_method_chain :http, :ssl_client_certificates
12
+
13
+ end
14
+ end
@@ -0,0 +1,41 @@
1
+ require "cgi"
2
+ require "uri"
3
+ require "net/https"
4
+ require "rexml/document"
5
+ require "builder"
6
+ require "bigdecimal"
7
+ require "oauth"
8
+ require 'oauth/signature/rsa/sha1'
9
+ require "forwardable"
10
+ require "active_support/all"
11
+
12
+ require File.join(File.dirname(__FILE__), 'oauth', 'oauth_consumer')
13
+
14
+ require File.join(File.dirname(__FILE__), 'xero_gateway', 'http_encoding_helper')
15
+ require File.join(File.dirname(__FILE__), 'xero_gateway', 'http')
16
+ require File.join(File.dirname(__FILE__), 'xero_gateway', 'dates')
17
+ require File.join(File.dirname(__FILE__), 'xero_gateway', 'money')
18
+ require File.join(File.dirname(__FILE__), 'xero_gateway', 'line_item_calculations')
19
+ require File.join(File.dirname(__FILE__), 'xero_gateway', 'response')
20
+ require File.join(File.dirname(__FILE__), 'xero_gateway', 'account')
21
+ require File.join(File.dirname(__FILE__), 'xero_gateway', 'accounts_list')
22
+ require File.join(File.dirname(__FILE__), 'xero_gateway', 'tracking_category')
23
+ require File.join(File.dirname(__FILE__), 'xero_gateway', 'contact')
24
+ require File.join(File.dirname(__FILE__), 'xero_gateway', 'line_item')
25
+ require File.join(File.dirname(__FILE__), 'xero_gateway', 'payment')
26
+ require File.join(File.dirname(__FILE__), 'xero_gateway', 'invoice')
27
+ require File.join(File.dirname(__FILE__), 'xero_gateway', 'bank_transaction')
28
+ require File.join(File.dirname(__FILE__), 'xero_gateway', 'credit_note')
29
+ require File.join(File.dirname(__FILE__), 'xero_gateway', 'journal_line')
30
+ require File.join(File.dirname(__FILE__), 'xero_gateway', 'manual_journal')
31
+ require File.join(File.dirname(__FILE__), 'xero_gateway', 'address')
32
+ require File.join(File.dirname(__FILE__), 'xero_gateway', 'phone')
33
+ require File.join(File.dirname(__FILE__), 'xero_gateway', 'organisation')
34
+ require File.join(File.dirname(__FILE__), 'xero_gateway', 'tax_rate')
35
+ require File.join(File.dirname(__FILE__), 'xero_gateway', 'currency')
36
+ require File.join(File.dirname(__FILE__), 'xero_gateway', 'error')
37
+ require File.join(File.dirname(__FILE__), 'xero_gateway', 'oauth')
38
+ require File.join(File.dirname(__FILE__), 'xero_gateway', 'exceptions')
39
+ require File.join(File.dirname(__FILE__), 'xero_gateway', 'gateway')
40
+ require File.join(File.dirname(__FILE__), 'xero_gateway', 'private_app')
41
+ require File.join(File.dirname(__FILE__), 'xero_gateway', 'partner_app')
@@ -0,0 +1,86 @@
1
+ module XeroGateway
2
+ class Account
3
+
4
+ TYPE = {
5
+ 'CURRENT' => '',
6
+ 'FIXED' => '',
7
+ 'PREPAYMENT' => '',
8
+ 'EQUITY' => '',
9
+ 'DEPRECIATN' => '',
10
+ 'DIRECTCOSTS' => '',
11
+ 'EXPENSE' => '',
12
+ 'OVERHEADS' => '',
13
+ 'CURRLIAB' => '',
14
+ 'LIABILITY' => '',
15
+ 'TERMLIAB' => '',
16
+ 'OTHERINCOME' => '',
17
+ 'REVENUE' => '',
18
+ 'SALES' => ''
19
+ } unless defined?(TYPE)
20
+
21
+ TAX_TYPE = {
22
+ 'NONE' => 'No GST',
23
+ 'EXEMPTINPUT' => 'VAT on expenses exempt from VAT (UK only)',
24
+ 'INPUT' => 'GST on expenses',
25
+ 'SRINPUT' => 'VAT on expenses',
26
+ 'ZERORATEDINPUT' => 'Expense purchased from overseas (UK only)',
27
+ 'RRINPUT' => 'Reduced rate VAT on expenses (UK Only)',
28
+ 'EXEMPTOUTPUT' => 'VAT on sales exempt from VAT (UK only)',
29
+ 'ECZROUTPUT' => 'EC Zero-rated output',
30
+ 'OUTPUT' => 'OUTPUT (old rate)',
31
+ 'OUTPUT2' => 'OUTPUT2',
32
+ 'SROUTPUT' => 'SROUTPUT',
33
+ 'ZERORATEDOUTPUT' => 'Sales made from overseas (UK only)',
34
+ 'RROUTPUT' => 'Reduced rate VAT on sales (UK Only)',
35
+ 'ZERORATED' => 'Zero-rated supplies/sales from overseas (NZ Only)'
36
+ } unless defined?(TAX_TYPE)
37
+
38
+ attr_accessor :account_id, :code, :name, :type, :tax_type, :description, :system_account, :enable_payments_to_account, :currency_code
39
+
40
+ def initialize(params = {})
41
+ params.each do |k,v|
42
+ self.send("#{k}=", v)
43
+ end
44
+ end
45
+
46
+ def ==(other)
47
+ [:account_id, :code, :name, :type, :tax_type, :description, :system_account, :enable_payments_to_account].each do |field|
48
+ return false if send(field) != other.send(field)
49
+ end
50
+ return true
51
+ end
52
+
53
+ def to_xml(b = Builder::XmlMarkup.new, options={})
54
+ b.tag!(options[:name] ? options[:name] : 'Account') {
55
+ b.AccountID self.account_id
56
+ b.Code self.code
57
+ b.Name self.name
58
+ b.Type self.type
59
+ b.TaxType self.tax_type
60
+ b.Description self.description
61
+ b.SystemAccount self.system_account unless self.system_account.nil?
62
+ b.EnablePaymentsToAccount self.enable_payments_to_account
63
+ b.CurrencyCode currency_code if currency_code
64
+ }
65
+ end
66
+
67
+ def self.from_xml(account_element)
68
+ account = Account.new
69
+ account_element.children.each do |element|
70
+ case(element.name)
71
+ when "AccountID" then account.account_id = element.text
72
+ when "Code" then account.code = element.text
73
+ when "Name" then account.name = element.text
74
+ when "Type" then account.type = element.text
75
+ when "TaxType" then account.tax_type = element.text
76
+ when "Description" then account.description = element.text
77
+ when "SystemAccount" then account.system_account = element.text
78
+ when "EnablePaymentsToAccount" then account.enable_payments_to_account = (element.text == 'true')
79
+ when "CurrencyCode" then account.currency_code = element.text
80
+ end
81
+ end
82
+ account
83
+ end
84
+
85
+ end
86
+ end
@@ -0,0 +1,73 @@
1
+ module XeroGateway
2
+ class AccountsList
3
+
4
+ # Xero::Gateway associated with this invoice.
5
+ attr_accessor :gateway
6
+
7
+ # All accessible fields
8
+ attr_accessor :accounts
9
+
10
+ # Hash of accounts with the account code as the key.
11
+ attr :accounts_by_code
12
+
13
+ # Boolean representing whether the accounts list has been loaded.
14
+ attr :loaded
15
+
16
+ public
17
+
18
+ def initialize(gateway, initial_load = true)
19
+ raise NoGatewayError unless gateway && gateway.is_a?(XeroGateway::Gateway)
20
+ @gateway = gateway
21
+ @loaded = false
22
+
23
+ load if initial_load
24
+ end
25
+
26
+ def load
27
+ @loaded = false
28
+ response = gateway.get_accounts
29
+ @accounts = response.accounts
30
+ @loaded = true
31
+
32
+ # Cache accounts by code.
33
+ @accounts_by_code = {}
34
+ @accounts.each do | account |
35
+ @accounts_by_code[account.code.to_s] = account
36
+ end
37
+ end
38
+
39
+ def loaded?
40
+ @loaded == true
41
+ end
42
+
43
+ # Lookup account by account_code.
44
+ def find_by_code(account_code)
45
+ raise AccountsListNotLoadedError unless loaded?
46
+ @accounts_by_code[account_code.to_s]
47
+ end
48
+
49
+ # Alias [] method to find_by_code.
50
+ def [](account_code)
51
+ find_by_code(account_code)
52
+ end
53
+
54
+ # Return a list of all accounts matching account_type.
55
+ def find_all_by_type(account_type)
56
+ raise AccountsListNotLoadedError unless loaded?
57
+ @accounts.inject([]) do | list, account |
58
+ list << account if account.type == account_type
59
+ list
60
+ end
61
+ end
62
+
63
+ # Return a list of all accounts matching tax_type.
64
+ def find_all_by_tax_type(tax_type)
65
+ raise AccountsListNotLoadedError unless loaded?
66
+ @accounts.inject([]) do | list, account |
67
+ list << account if account.tax_type == tax_type
68
+ list
69
+ end
70
+ end
71
+
72
+ end
73
+ end
@@ -0,0 +1,96 @@
1
+ module XeroGateway
2
+ class Address
3
+
4
+ ADDRESS_TYPE = {
5
+ 'STREET' => 'Street',
6
+ 'POBOX' => 'PO Box'
7
+ } unless defined?(ADDRESS_TYPE)
8
+
9
+ # Any errors that occurred when the #valid? method called.
10
+ attr_reader :errors
11
+
12
+ attr_accessor :address_type, :line_1, :line_2, :line_3, :line_4, :city, :region, :post_code, :country
13
+
14
+ def initialize(params = {})
15
+ @errors ||= []
16
+
17
+ params = {
18
+ :address_type => "POBOX"
19
+ }.merge(params)
20
+
21
+ params.each do |k,v|
22
+ self.send("#{k}=", v)
23
+ end
24
+ end
25
+
26
+ # Validate the Address record according to what will be valid by the gateway.
27
+ #
28
+ # Usage:
29
+ # address.valid? # Returns true/false
30
+ #
31
+ # Additionally sets address.errors array to an array of field/error.
32
+ def valid?
33
+ @errors = []
34
+
35
+ if address_type && !ADDRESS_TYPE[address_type]
36
+ @errors << ['address_type', "must be one of #{ADDRESS_TYPE.keys.join('/')} and is currently #{address_type}"]
37
+ end
38
+
39
+ @errors.size == 0
40
+ end
41
+
42
+ def to_xml(b = Builder::XmlMarkup.new)
43
+ b.Address {
44
+ b.AddressType address_type
45
+ b.AddressLine1 line_1 if line_1
46
+ b.AddressLine2 line_2 if line_2
47
+ b.AddressLine3 line_3 if line_3
48
+ b.AddressLine4 line_4 if line_4
49
+ b.City city if city
50
+ b.Region region if region
51
+ b.PostalCode post_code if post_code
52
+ b.Country country if country
53
+ }
54
+ end
55
+
56
+ def self.from_xml(address_element)
57
+ address = Address.new
58
+ address_element.children.each do |element|
59
+ case(element.name)
60
+ when "AddressType" then address.address_type = element.text
61
+ when "AddressLine1" then address.line_1 = element.text
62
+ when "AddressLine2" then address.line_2 = element.text
63
+ when "AddressLine3" then address.line_3 = element.text
64
+ when "AddressLine4" then address.line_4 = element.text
65
+ when "City" then address.city = element.text
66
+ when "Region" then address.region = element.text
67
+ when "PostalCode" then address.post_code = element.text
68
+ when "Country" then address.country = element.text
69
+ end
70
+ end
71
+ address
72
+ end
73
+
74
+ def self.parse(string)
75
+ address = Address.new
76
+
77
+ parts = string.split("\r\n")
78
+
79
+ if(parts.size > 3)
80
+ parts = [parts.shift, parts.shift, parts.shift, parts.join(", ")]
81
+ end
82
+
83
+ parts.each_with_index do |line, index|
84
+ address.send("line_#{index+1}=", line)
85
+ end
86
+ address
87
+ end
88
+
89
+ def ==(other)
90
+ [:address_type, :line_1, :line_2, :line_3, :line_4, :city, :region, :post_code, :country].each do |field|
91
+ return false if send(field) != other.send(field)
92
+ end
93
+ return true
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,175 @@
1
+ module XeroGateway
2
+ class BankTransaction
3
+ include Dates
4
+ include LineItemCalculations
5
+
6
+ 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)
7
+
8
+ TYPES = {
9
+ 'RECEIVE' => 'Receive Bank Transaction',
10
+ 'SPEND' => 'Spend Bank Transaction',
11
+ } unless defined?(TYPES)
12
+
13
+ STATUSES = {
14
+ 'ACTIVE' => 'Bank Transaction is active',
15
+ 'DELETED' => 'Bank Transaction is deleted',
16
+ } unless defined?(STATUSES)
17
+
18
+ # Xero::Gateway associated with this invoice.
19
+ attr_accessor :gateway
20
+
21
+ # Any errors that occurred when the #valid? method called.
22
+ attr_reader :errors
23
+
24
+ # Represents whether the line_items have been downloaded when getting from GET /API.XRO/2.0/BankTransactions
25
+ attr_accessor :line_items_downloaded
26
+
27
+ # accessible fields
28
+ attr_accessor :bank_transaction_id, :type, :date, :reference, :status, :contact, :line_items, :bank_account, :url, :is_reconciled
29
+
30
+ def initialize(params = {})
31
+ @errors ||= []
32
+ @payments ||= []
33
+
34
+ # Check if the line items have been downloaded.
35
+ @line_items_downloaded = (params.delete(:line_items_downloaded) == true)
36
+
37
+ # params = {
38
+ # :line_amount_types => "Exclusive"
39
+ # }.merge(params)
40
+ params.each do |k,v|
41
+ self.send("#{k}=", v)
42
+ end
43
+
44
+ @line_items ||= []
45
+ end
46
+
47
+ def ==(other)
48
+ ['type', 'reference', 'status', 'contact', 'line_items', 'bank_account'].each do |field|
49
+ return false if send(field) != other.send(field)
50
+ end
51
+
52
+ ["date"].each do |field|
53
+ return false if send(field).to_s != other.send(field).to_s
54
+ end
55
+ return true
56
+ end
57
+
58
+ # Validate the BankTransaction record according to what will be valid by the gateway.
59
+ #
60
+ # Usage:
61
+ # bank_transaction.valid? # Returns true/false
62
+ #
63
+ # Additionally sets bank_transaction.errors array to an array of field/error.
64
+ def valid?
65
+ @errors = []
66
+
67
+ if !bank_transaction_id.nil? && bank_transaction_id !~ GUID_REGEX
68
+ @errors << ['bank_transaction_id', 'must be blank or a valid Xero GUID']
69
+ end
70
+
71
+ if type && !TYPES[type]
72
+ @errors << ['type', "must be one of #{TYPES.keys.join('/')}"]
73
+ end
74
+
75
+ if status && !STATUSES[status]
76
+ @errors << ['status', "must be one of #{STATUSES.keys.join('/')}"]
77
+ end
78
+
79
+ unless date
80
+ @errors << ['date', "can't be blank"]
81
+ end
82
+
83
+ # Make sure contact is valid.
84
+ unless @contact && @contact.valid?
85
+ @errors << ['contact', 'is invalid']
86
+ end
87
+
88
+ # Make sure all line_items are valid.
89
+ unless line_items.all? { | line_item | line_item.valid? }
90
+ @errors << ['line_items', "at least one line item invalid"]
91
+ end
92
+
93
+ @errors.size == 0
94
+ end
95
+
96
+
97
+ def line_items_downloaded?
98
+ @line_items_downloaded
99
+ end
100
+
101
+ # If line items are not downloaded, then attempt a download now (if this record was found to begin with).
102
+ def line_items
103
+ if line_items_downloaded?
104
+ @line_items
105
+
106
+ elsif bank_transaction_id =~ GUID_REGEX && @gateway
107
+ # There is a bank_transaction_id so we can assume this record was loaded from Xero.
108
+ # Let's attempt to download the line_item records (if there is a gateway)
109
+
110
+ response = @gateway.get_bank_transaction(bank_transaction_id)
111
+ raise BankTransactionNotFoundError, "Bank Transaction with ID #{bank_transaction_id} not found in Xero." unless response.success? && response.bank_transaction.is_a?(XeroGateway::BankTransaction)
112
+
113
+ @line_items = response.bank_transaction.line_items
114
+ @line_items_downloaded = true
115
+
116
+ @line_items
117
+
118
+ # Otherwise, this is a new bank transaction, so return the line_items reference.
119
+ else
120
+ @line_items
121
+ end
122
+ end
123
+
124
+ def to_xml(b = Builder::XmlMarkup.new)
125
+ b.BankTransaction {
126
+ b.BankTransactionID bank_transaction_id if bank_transaction_id
127
+ b.Type type
128
+ # b.CurrencyCode self.currency_code if self.currency_code
129
+ contact.to_xml(b) if contact
130
+ bank_account.to_xml(b, :name => 'BankAccount') if bank_account
131
+ b.Date BankTransaction.format_date(date || Date.today)
132
+ b.Status status if status
133
+ b.Reference reference if reference
134
+ b.IsReconciled true if self.is_reconciled
135
+ b.LineItems {
136
+ self.line_items.each do |line_item|
137
+ line_item.to_xml(b)
138
+ end
139
+ }
140
+ b.Url url if url
141
+ }
142
+ end
143
+
144
+ def self.from_xml(bank_transaction_element, gateway = nil, options = {})
145
+ bank_transaction = BankTransaction.new(options.merge({:gateway => gateway}))
146
+ bank_transaction_element.children.each do |element|
147
+ case(element.name)
148
+ when "BankTransactionID" then bank_transaction.bank_transaction_id = element.text
149
+ when "Type" then bank_transaction.type = element.text
150
+ # when "CurrencyCode" then invoice.currency_code = element.text
151
+ when "Contact" then bank_transaction.contact = Contact.from_xml(element)
152
+ when "BankAccount" then bank_transaction.bank_account = Account.from_xml(element)
153
+ when "Date" then bank_transaction.date = parse_date(element.text)
154
+ when "Status" then bank_transaction.status = element.text
155
+ when "Reference" then bank_transaction.reference = element.text
156
+ when "LineItems" then element.children.each {|line_item| bank_transaction.line_items_downloaded = true; bank_transaction.line_items << LineItem.from_xml(line_item) }
157
+ # when "SubTotal" then invoice.sub_total = BigDecimal.new(element.text)
158
+ # when "TotalTax" then invoice.total_tax = BigDecimal.new(element.text)
159
+ # when "Total" then invoice.total = BigDecimal.new(element.text)
160
+ # when "InvoiceID" then invoice.invoice_id = element.text
161
+ # when "InvoiceNumber" then invoice.invoice_number = element.text
162
+ # when "Payments" then element.children.each { | payment | invoice.payments << Payment.from_xml(payment) }
163
+ # when "AmountDue" then invoice.amount_due = BigDecimal.new(element.text)
164
+ # when "AmountPaid" then invoice.amount_paid = BigDecimal.new(element.text)
165
+ # when "AmountCredited" then invoice.amount_credited = BigDecimal.new(element.text)
166
+ # when "SentToContact" then invoice.sent_to_contact = (element.text.strip.downcase == "true")
167
+ when "IsReconciled" then bank_transaction.is_reconciled = (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