xero_gateway 2.1.0 → 2.3.0
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.
- checksums.yaml +7 -0
- data/Gemfile +3 -11
- data/README.md +212 -0
- data/Rakefile +0 -1
- data/lib/oauth/oauth_consumer.rb +25 -9
- data/lib/xero_gateway.rb +5 -1
- data/lib/xero_gateway/address.rb +29 -27
- data/lib/xero_gateway/bank_transaction.rb +11 -3
- data/lib/xero_gateway/base_record.rb +97 -0
- data/lib/xero_gateway/contact_group.rb +87 -0
- data/lib/xero_gateway/currency.rb +8 -54
- data/lib/xero_gateway/dates.rb +4 -0
- data/lib/xero_gateway/exceptions.rb +14 -13
- data/lib/xero_gateway/gateway.rb +90 -5
- data/lib/xero_gateway/http.rb +16 -8
- data/lib/xero_gateway/invoice.rb +9 -3
- data/lib/xero_gateway/item.rb +27 -0
- data/lib/xero_gateway/line_item_calculations.rb +3 -3
- data/lib/xero_gateway/manual_journal.rb +5 -2
- data/lib/xero_gateway/organisation.rb +22 -73
- data/lib/xero_gateway/payment.rb +22 -9
- data/lib/xero_gateway/phone.rb +2 -0
- data/lib/xero_gateway/report.rb +95 -0
- data/lib/xero_gateway/response.rb +12 -7
- data/lib/xero_gateway/tax_rate.rb +13 -61
- data/lib/xero_gateway/tracking_category.rb +39 -13
- data/lib/xero_gateway/version.rb +3 -0
- data/test/integration/get_items_test.rb +25 -0
- data/test/integration/get_payments_test.rb +54 -0
- data/test/test_helper.rb +51 -16
- data/test/unit/address_test.rb +34 -0
- data/test/unit/bank_transaction_test.rb +7 -0
- data/test/unit/contact_group_test.rb +47 -0
- data/test/unit/contact_test.rb +35 -16
- data/test/unit/credit_note_test.rb +2 -2
- data/test/unit/gateway_test.rb +170 -1
- data/test/unit/invoice_test.rb +27 -7
- data/test/unit/item_test.rb +51 -0
- data/test/unit/organisation_test.rb +1 -0
- data/test/unit/payment_test.rb +18 -11
- data/test/unit/report_test.rb +78 -0
- data/xero_gateway.gemspec +29 -13
- metadata +176 -89
- data/README.textile +0 -357
- data/init.rb +0 -1
data/lib/xero_gateway/http.rb
CHANGED
@@ -79,15 +79,20 @@ module XeroGateway
|
|
79
79
|
handle_oauth_error!(response)
|
80
80
|
when 404
|
81
81
|
handle_object_not_found!(response, url)
|
82
|
+
when 500..504
|
83
|
+
# Xero sends certain oauth errors back as 500 errors
|
84
|
+
handle_oauth_error!(response)
|
82
85
|
else
|
83
86
|
raise "Unknown response code: #{response.code.to_i}"
|
84
87
|
end
|
85
88
|
end
|
86
89
|
|
87
90
|
def handle_oauth_error!(response)
|
88
|
-
error_details = CGI.parse(response.plain_body)
|
91
|
+
error_details = CGI.parse(response.plain_body.strip)
|
89
92
|
description = error_details["oauth_problem_advice"].first
|
90
93
|
|
94
|
+
description = "No description found: #{response.plain_body}" if description.blank?
|
95
|
+
|
91
96
|
# see http://oauth.pbworks.com/ProblemReporting
|
92
97
|
# In addition to token_expired and token_rejected, Xero also returns
|
93
98
|
# 'rate limit exceeded' when more than 60 requests have been made in
|
@@ -97,7 +102,9 @@ module XeroGateway
|
|
97
102
|
when "consumer_key_unknown" then raise OAuth::TokenInvalid.new(description)
|
98
103
|
when "token_rejected" then raise OAuth::TokenInvalid.new(description)
|
99
104
|
when "rate limit exceeded" then raise OAuth::RateLimitExceeded.new(description)
|
100
|
-
else
|
105
|
+
else
|
106
|
+
message = (error_details["oauth_problem"].first || "Unknown Error") + ': ' + description
|
107
|
+
raise OAuth::UnknownError.new(message)
|
101
108
|
end
|
102
109
|
end
|
103
110
|
|
@@ -111,26 +118,27 @@ module XeroGateway
|
|
111
118
|
|
112
119
|
doc = REXML::Document.new(raw_response, :ignore_whitespace_nodes => :all)
|
113
120
|
|
114
|
-
if doc.root.name
|
121
|
+
if doc.root.nil? || doc.root.name != "ApiException"
|
122
|
+
|
123
|
+
raise "Unparseable 400 Response: #{raw_response}"
|
124
|
+
|
125
|
+
else
|
115
126
|
|
116
127
|
raise ApiException.new(doc.root.elements["Type"].text,
|
117
128
|
doc.root.elements["Message"].text,
|
118
129
|
request_xml,
|
119
130
|
raw_response)
|
120
131
|
|
121
|
-
else
|
122
|
-
|
123
|
-
raise "Unparseable 400 Response: #{raw_response}"
|
124
|
-
|
125
132
|
end
|
126
|
-
|
127
133
|
end
|
128
134
|
|
129
135
|
def handle_object_not_found!(response, request_url)
|
130
136
|
case(request_url)
|
131
137
|
when /Invoices/ then raise InvoiceNotFoundError.new("Invoice not found in Xero.")
|
132
138
|
when /BankTransactions/ then raise BankTransactionNotFoundError.new("Bank Transaction not found in Xero.")
|
139
|
+
when /Payments/ then raise PaymentNotFoundError.new("Payments not found in Xero.")
|
133
140
|
when /CreditNotes/ then raise CreditNoteNotFoundError.new("Credit Note not found in Xero.")
|
141
|
+
when /ManualJournals/ then raise ManualJournalNotFoundError.new("Manual Journal not found in Xero.")
|
134
142
|
else raise ObjectNotFound.new(request_url)
|
135
143
|
end
|
136
144
|
end
|
data/lib/xero_gateway/invoice.rb
CHANGED
@@ -37,9 +37,8 @@ module XeroGateway
|
|
37
37
|
attr_accessor :line_items_downloaded
|
38
38
|
|
39
39
|
# All accessible fields
|
40
|
-
attr_accessor :invoice_id, :invoice_number, :invoice_type, :invoice_status, :date, :due_date, :reference, :branding_theme_id, :line_amount_types, :currency_code, :line_items, :contact, :payments, :fully_paid_on, :amount_due, :amount_paid, :amount_credited, :sent_to_contact, :url
|
40
|
+
attr_accessor :invoice_id, :invoice_number, :invoice_type, :invoice_status, :date, :due_date, :reference, :branding_theme_id, :line_amount_types, :currency_code, :line_items, :contact, :payments, :fully_paid_on, :amount_due, :amount_paid, :amount_credited, :sent_to_contact, :url, :updated_date_utc
|
41
41
|
|
42
|
-
|
43
42
|
def initialize(params = {})
|
44
43
|
@errors ||= []
|
45
44
|
@payments ||= []
|
@@ -123,7 +122,13 @@ module XeroGateway
|
|
123
122
|
def line_items_downloaded?
|
124
123
|
@line_items_downloaded
|
125
124
|
end
|
126
|
-
|
125
|
+
|
126
|
+
%w(sub_total tax_total total).each do |line_item_total_type|
|
127
|
+
define_method("#{line_item_total_type}=") do |new_total|
|
128
|
+
instance_variable_set("@#{line_item_total_type}", new_total) unless line_items_downloaded?
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
127
132
|
# If line items are not downloaded, then attempt a download now (if this record was found to begin with).
|
128
133
|
def line_items
|
129
134
|
if line_items_downloaded?
|
@@ -215,6 +220,7 @@ module XeroGateway
|
|
215
220
|
when "Contact" then invoice.contact = Contact.from_xml(element)
|
216
221
|
when "Date" then invoice.date = parse_date(element.text)
|
217
222
|
when "DueDate" then invoice.due_date = parse_date(element.text)
|
223
|
+
when "UpdatedDateUTC" then invoice.updated_date_utc = parse_date(element.text)
|
218
224
|
when "Status" then invoice.invoice_status = element.text
|
219
225
|
when "Reference" then invoice.reference = element.text
|
220
226
|
when "BrandingThemeID" then invoice.branding_theme_id = element.text
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module XeroGateway
|
2
|
+
class Item < BaseRecord
|
3
|
+
attributes({
|
4
|
+
"ItemID" => :string,
|
5
|
+
"Code" => :string,
|
6
|
+
"InventoryAssetAccountCode" => :string,
|
7
|
+
"Name" => :string,
|
8
|
+
"IsSold" => :boolean,
|
9
|
+
"IsPurchased" => :boolean,
|
10
|
+
"Description" => :string,
|
11
|
+
"PurchaseDescription" => :string,
|
12
|
+
"IsTrackedAsInventory" => :boolean,
|
13
|
+
"TotalCostPool" => :float,
|
14
|
+
"QuantityOnHand" => :integer,
|
15
|
+
|
16
|
+
"SalesDetails" => {
|
17
|
+
"UnitPrice" => :float,
|
18
|
+
"AccountCode" => :string
|
19
|
+
},
|
20
|
+
|
21
|
+
"PurchaseDetails" => {
|
22
|
+
"UnitPrice" => :float,
|
23
|
+
"AccountCode" => :string
|
24
|
+
}
|
25
|
+
})
|
26
|
+
end
|
27
|
+
end
|
@@ -20,7 +20,7 @@ module XeroGateway
|
|
20
20
|
|
21
21
|
# Calculate the sub_total as the SUM(line_item.line_amount).
|
22
22
|
def sub_total
|
23
|
-
line_items.inject(BigDecimal.new('0')) { | sum, line_item | sum + BigDecimal.new(line_item.line_amount.to_s) }
|
23
|
+
!line_items_downloaded? && @sub_total || line_items.inject(BigDecimal.new('0')) { | sum, line_item | sum + BigDecimal.new(line_item.line_amount.to_s) }
|
24
24
|
end
|
25
25
|
|
26
26
|
# Deprecated (but API for setter remains).
|
@@ -32,7 +32,7 @@ module XeroGateway
|
|
32
32
|
|
33
33
|
# Calculate the total_tax as the SUM(line_item.tax_amount).
|
34
34
|
def total_tax
|
35
|
-
line_items.inject(BigDecimal.new('0')) { | sum, line_item | sum + BigDecimal.new(line_item.tax_amount.to_s) }
|
35
|
+
!line_items_downloaded? && @total_tax || line_items.inject(BigDecimal.new('0')) { | sum, line_item | sum + BigDecimal.new(line_item.tax_amount.to_s) }
|
36
36
|
end
|
37
37
|
|
38
38
|
# Deprecated (but API for setter remains).
|
@@ -44,7 +44,7 @@ module XeroGateway
|
|
44
44
|
|
45
45
|
# Calculate the toal as sub_total + total_tax.
|
46
46
|
def total
|
47
|
-
sub_total + total_tax
|
47
|
+
!line_items_downloaded? && @total || (sub_total + total_tax)
|
48
48
|
end
|
49
49
|
|
50
50
|
end
|
@@ -2,6 +2,9 @@ module XeroGateway
|
|
2
2
|
class ManualJournal
|
3
3
|
include Dates
|
4
4
|
|
5
|
+
class Error < RuntimeError; end
|
6
|
+
class NoGatewayError < Error; end
|
7
|
+
|
5
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)
|
6
9
|
|
7
10
|
STATUSES = {
|
@@ -121,7 +124,7 @@ module XeroGateway
|
|
121
124
|
def to_xml(b = Builder::XmlMarkup.new)
|
122
125
|
b.ManualJournal {
|
123
126
|
b.ManualJournalID manual_journal_id if manual_journal_id
|
124
|
-
b.Narration narration
|
127
|
+
b.Narration narration
|
125
128
|
b.JournalLines {
|
126
129
|
self.journal_lines.each do |journal_line|
|
127
130
|
journal_line.to_xml(b)
|
@@ -160,4 +163,4 @@ module XeroGateway
|
|
160
163
|
end
|
161
164
|
|
162
165
|
end
|
163
|
-
end
|
166
|
+
end
|
@@ -1,75 +1,24 @@
|
|
1
1
|
module XeroGateway
|
2
|
-
class Organisation
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
attr_accessor *ATTRS.keys.map(&:underscore)
|
25
|
-
|
26
|
-
def initialize(params = {})
|
27
|
-
params.each do |k,v|
|
28
|
-
self.send("#{k}=", v)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def ==(other)
|
33
|
-
ATTRS.keys.map(&:underscore).each do |field|
|
34
|
-
return false if send(field) != other.send(field)
|
35
|
-
end
|
36
|
-
return true
|
37
|
-
end
|
38
|
-
|
39
|
-
def to_xml
|
40
|
-
b = Builder::XmlMarkup.new
|
41
|
-
|
42
|
-
b.Organisation do
|
43
|
-
ATTRS.keys.each do |attr|
|
44
|
-
eval("b.#{attr} '#{self.send(attr.underscore.to_sym)}'")
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def self.from_xml(organisation_element)
|
50
|
-
Organisation.new.tap do |org|
|
51
|
-
organisation_element.children.each do |element|
|
52
|
-
|
53
|
-
attribute = element.name
|
54
|
-
underscored_attribute = element.name.underscore
|
55
|
-
|
56
|
-
if ATTRS.keys.include?(attribute)
|
57
|
-
|
58
|
-
case (ATTRS[attribute])
|
59
|
-
when :boolean then org.send("#{underscored_attribute}=", (element.text == "true"))
|
60
|
-
when :float then org.send("#{underscored_attribute}=", element.text.to_f)
|
61
|
-
else org.send("#{underscored_attribute}=", element.text)
|
62
|
-
end
|
63
|
-
|
64
|
-
else
|
65
|
-
|
66
|
-
warn "Ignoring unknown attribute: #{attribute}"
|
67
|
-
|
68
|
-
end
|
69
|
-
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
2
|
+
class Organisation < BaseRecord
|
3
|
+
attributes({
|
4
|
+
"Name" => :string, # Display name of organisation shown in Xero
|
5
|
+
"LegalName" => :string, # Organisation name shown on Reports
|
6
|
+
"PaysTax" => :boolean, # Boolean to describe if organisation is registered with a local tax authority i.e. true, false
|
7
|
+
"Version" => :string, # See Version Types
|
8
|
+
"BaseCurrency" => :string, # Default currency for organisation. See Currency types
|
9
|
+
"OrganisationType" => :string, # only returned for "real" (i.e non-demo) companies
|
10
|
+
"OrganisationStatus" => :string,
|
11
|
+
"IsDemoCompany" => :boolean,
|
12
|
+
"APIKey" => :string, # returned if organisations are linked via Xero Network
|
13
|
+
"CountryCode" => :string,
|
14
|
+
"TaxNumber" => :string,
|
15
|
+
"FinancialYearEndDay" => :string,
|
16
|
+
"FinancialYearEndMonth" => :string,
|
17
|
+
"PeriodLockDate" => :string,
|
18
|
+
"CreatedDateUTC" => :string,
|
19
|
+
"ShortCode" => :string,
|
20
|
+
"Timezone" => :string,
|
21
|
+
"LineOfBusiness" => :string
|
22
|
+
})
|
74
23
|
end
|
75
|
-
end
|
24
|
+
end
|
data/lib/xero_gateway/payment.rb
CHANGED
@@ -7,7 +7,8 @@ module XeroGateway
|
|
7
7
|
attr_reader :errors
|
8
8
|
|
9
9
|
# All accessible fields
|
10
|
-
attr_accessor :invoice_id, :invoice_number, :account_id, :code, :payment_id, :date, :amount, :reference, :currency_rate
|
10
|
+
attr_accessor :invoice_id, :invoice_number, :account_id, :code, :payment_id, :payment_type, :date, :amount, :reference, :currency_rate, :updated_at, :reconciled
|
11
|
+
alias_method :reconciled?, :reconciled
|
11
12
|
|
12
13
|
def initialize(params = {})
|
13
14
|
@errors ||= []
|
@@ -21,13 +22,18 @@ module XeroGateway
|
|
21
22
|
payment = Payment.new
|
22
23
|
payment_element.children.each do | element |
|
23
24
|
case element.name
|
24
|
-
when 'PaymentID'
|
25
|
-
when '
|
26
|
-
when '
|
27
|
-
when '
|
28
|
-
when '
|
29
|
-
when '
|
30
|
-
when '
|
25
|
+
when 'PaymentID' then payment.payment_id = element.text
|
26
|
+
when 'PaymentType' then payment.payment_type = element.text
|
27
|
+
when 'Date' then payment.date = parse_date_time(element.text)
|
28
|
+
when 'UpdatedDateUTC' then payment.updated_at = parse_date_time(element.text)
|
29
|
+
when 'Amount' then payment.amount = BigDecimal.new(element.text)
|
30
|
+
when 'Reference' then payment.reference = element.text
|
31
|
+
when 'CurrencyRate' then payment.currency_rate = BigDecimal.new(element.text)
|
32
|
+
when 'Invoice'
|
33
|
+
payment.invoice_id = element.elements["//InvoiceID"].text
|
34
|
+
payment.invoice_number = element.elements["//InvoiceNumber"].text
|
35
|
+
when 'IsReconciled' then payment.reconciled = (element.text == "true")
|
36
|
+
when 'Account' then payment.account_id = element.elements["//AccountID"].text
|
31
37
|
end
|
32
38
|
end
|
33
39
|
payment
|
@@ -43,6 +49,9 @@ module XeroGateway
|
|
43
49
|
def to_xml(b = Builder::XmlMarkup.new)
|
44
50
|
b.Payment do
|
45
51
|
|
52
|
+
b.PaymentID self.payment_id if self.payment_id
|
53
|
+
b.PaymentType self.payment_type if self.payment_type
|
54
|
+
|
46
55
|
if self.invoice_id || self.invoice_number
|
47
56
|
b.Invoice do |i|
|
48
57
|
i.InvoiceID self.invoice_id if self.invoice_id
|
@@ -61,10 +70,14 @@ module XeroGateway
|
|
61
70
|
b.CurrencyRate self.currency_rate if self.currency_rate
|
62
71
|
b.Reference self.reference if self.reference
|
63
72
|
|
73
|
+
if self.reconciled?
|
74
|
+
b.IsReconciled true
|
75
|
+
end
|
76
|
+
|
64
77
|
b.Date self.class.format_date(self.date || Date.today)
|
65
78
|
end
|
66
79
|
end
|
67
80
|
|
68
81
|
|
69
82
|
end
|
70
|
-
end
|
83
|
+
end
|
data/lib/xero_gateway/phone.rb
CHANGED
@@ -0,0 +1,95 @@
|
|
1
|
+
module XeroGateway
|
2
|
+
class Report
|
3
|
+
include Money
|
4
|
+
include Dates
|
5
|
+
|
6
|
+
attr_reader :errors
|
7
|
+
attr_accessor :report_id, :report_name, :report_type, :report_titles, :report_date, :updated_at,
|
8
|
+
:body, :column_names
|
9
|
+
|
10
|
+
def initialize(params={})
|
11
|
+
@errors ||= []
|
12
|
+
@report_titles ||= []
|
13
|
+
@body ||= []
|
14
|
+
|
15
|
+
params.each do |k,v|
|
16
|
+
self.send("#{k}=", v)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.from_xml(report_element)
|
21
|
+
report = Report.new
|
22
|
+
report_element.children.each do | element |
|
23
|
+
case element.name
|
24
|
+
when 'ReportID' then report.report_id = element.text
|
25
|
+
when 'ReportName' then report.report_name = element.text
|
26
|
+
when 'ReportType' then report.report_type = element.text
|
27
|
+
when 'ReportTitles'
|
28
|
+
each_title(element) do |title|
|
29
|
+
report.report_titles << title
|
30
|
+
end
|
31
|
+
when 'ReportDate' then report.report_date = Date.parse(element.text)
|
32
|
+
when 'UpdatedDateUTC' then report.updated_at = parse_date_time_utc(element.text)
|
33
|
+
when 'Rows'
|
34
|
+
report.column_names ||= find_body_column_names(element)
|
35
|
+
each_row_content(element) do |content_hash|
|
36
|
+
report.body << OpenStruct.new(content_hash)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
report
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def self.each_row_content(xml_element, &block)
|
46
|
+
column_names = find_body_column_names(xml_element).keys
|
47
|
+
xpath_body = REXML::XPath.first(xml_element, "//RowType[text()='Section']").parent
|
48
|
+
rows_contents = []
|
49
|
+
xpath_body.elements.each("Rows/Row") do |xpath_cells|
|
50
|
+
values = find_body_cell_values(xpath_cells)
|
51
|
+
content_hash = Hash[column_names.zip values]
|
52
|
+
rows_contents << content_hash
|
53
|
+
yield content_hash if block_given?
|
54
|
+
end
|
55
|
+
rows_contents
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.each_title(xml_element, &block)
|
59
|
+
xpath_titles = REXML::XPath.first(xml_element, "//ReportTitles")
|
60
|
+
xpath_titles.elements.each("//ReportTitle") do |xpath_title|
|
61
|
+
title = xpath_title.text.strip
|
62
|
+
yield title if block_given?
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.find_body_cell_values(xml_cells)
|
67
|
+
values = []
|
68
|
+
xml_cells.elements.each("Cells/Cell") do |xml_cell|
|
69
|
+
if value = xml_cell.children.first # finds <Value>...</Value>
|
70
|
+
values << value.text.try(:strip)
|
71
|
+
next
|
72
|
+
end
|
73
|
+
values << nil
|
74
|
+
end
|
75
|
+
values
|
76
|
+
end
|
77
|
+
|
78
|
+
# returns something like { column_1: "Amount", column_2: "Description", ... }
|
79
|
+
def self.find_body_column_names(body)
|
80
|
+
header = REXML::XPath.first(body, "//RowType[text()='Header']")
|
81
|
+
names_map = {}
|
82
|
+
column_count = 0
|
83
|
+
header.parent.elements.each("Cells/Cell") do |header_cell|
|
84
|
+
column_count += 1
|
85
|
+
column_key = "column_#{column_count}".to_sym
|
86
|
+
column_name = nil
|
87
|
+
name_value = header_cell.children.first
|
88
|
+
column_name = name_value.text.strip unless name_value.blank? # finds <Value>...</Value>
|
89
|
+
names_map[column_key] = column_name
|
90
|
+
end
|
91
|
+
names_map
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|
@@ -1,17 +1,20 @@
|
|
1
1
|
module XeroGateway
|
2
2
|
class Response
|
3
3
|
attr_accessor :response_id, :status, :errors, :provider, :date_time, :response_item, :request_params, :request_xml, :response_xml
|
4
|
-
|
4
|
+
|
5
5
|
def array_wrapped_response_item
|
6
6
|
Array(response_item)
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
alias_method :invoice, :response_item
|
10
10
|
alias_method :credit_note, :response_item
|
11
11
|
alias_method :bank_transaction, :response_item
|
12
12
|
alias_method :manual_journal, :response_item
|
13
13
|
alias_method :contact, :response_item
|
14
|
+
alias_method :contact_group, :response_item
|
14
15
|
alias_method :organisation, :response_item
|
16
|
+
alias_method :report, :response_item
|
17
|
+
alias_method :contact_groups, :array_wrapped_response_item
|
15
18
|
alias_method :invoices, :array_wrapped_response_item
|
16
19
|
alias_method :credit_notes, :array_wrapped_response_item
|
17
20
|
alias_method :bank_transactions, :array_wrapped_response_item
|
@@ -20,22 +23,24 @@ module XeroGateway
|
|
20
23
|
alias_method :accounts, :array_wrapped_response_item
|
21
24
|
alias_method :tracking_categories, :array_wrapped_response_item
|
22
25
|
alias_method :tax_rates, :array_wrapped_response_item
|
26
|
+
alias_method :items, :array_wrapped_response_item
|
23
27
|
alias_method :currencies, :array_wrapped_response_item
|
24
|
-
|
28
|
+
alias_method :payments, :array_wrapped_response_item
|
29
|
+
|
25
30
|
def initialize(params = {})
|
26
31
|
params.each do |k,v|
|
27
32
|
self.send("#{k}=", v)
|
28
33
|
end
|
29
|
-
|
34
|
+
|
30
35
|
@errors ||= []
|
31
36
|
@response_item ||= []
|
32
37
|
end
|
33
|
-
|
34
|
-
|
38
|
+
|
39
|
+
|
35
40
|
def success?
|
36
41
|
status == "OK"
|
37
42
|
end
|
38
|
-
|
43
|
+
|
39
44
|
def error
|
40
45
|
errors.blank? ? nil : errors[0]
|
41
46
|
end
|