xero_gateway 2.3.0 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +87 -82
- data/examples/partner_app.rb +0 -4
- data/examples/private_app.rb +18 -0
- data/lib/xero_gateway/account.rb +29 -12
- data/lib/xero_gateway/bank_transaction.rb +6 -11
- data/lib/xero_gateway/base_record.rb +26 -7
- data/lib/xero_gateway/contact.rb +40 -38
- data/lib/xero_gateway/contact_group.rb +12 -10
- data/lib/xero_gateway/credit_note.rb +42 -50
- data/lib/xero_gateway/gateway.rb +10 -7
- data/lib/xero_gateway/invoice.rb +53 -54
- data/lib/xero_gateway/line_item_calculations.rb +20 -22
- data/lib/xero_gateway/manual_journal.rb +2 -1
- data/lib/xero_gateway/organisation.rb +8 -1
- data/lib/xero_gateway/partner_app.rb +14 -20
- data/lib/xero_gateway/tax_rate.rb +1 -0
- data/lib/xero_gateway/version.rb +1 -1
- data/test/integration/get_invoices_test.rb +31 -22
- data/test/integration/get_organisation_test.rb +8 -7
- data/test/integration/get_tax_rates_test.rb +8 -8
- data/test/test_helper.rb +1 -1
- data/test/unit/account_test.rb +10 -6
- data/test/unit/bank_transaction_test.rb +11 -2
- data/test/unit/contact_test.rb +62 -0
- data/test/unit/credit_note_test.rb +51 -63
- data/test/unit/gateway_test.rb +16 -4
- data/test/unit/invoice_test.rb +91 -55
- data/test/unit/manual_journal_test.rb +7 -7
- data/test/unit/organisation_test.rb +52 -7
- data/test/unit/tax_rate_test.rb +8 -7
- data/xero_gateway.gemspec +7 -2
- metadata +8 -7
data/lib/xero_gateway/contact.rb
CHANGED
@@ -1,45 +1,46 @@
|
|
1
1
|
module XeroGateway
|
2
2
|
class Contact
|
3
3
|
include Dates
|
4
|
-
|
4
|
+
|
5
5
|
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
|
-
|
6
|
+
|
7
7
|
CONTACT_STATUS = {
|
8
8
|
'ACTIVE' => 'Active',
|
9
9
|
'DELETED' => 'Deleted'
|
10
10
|
} unless defined?(CONTACT_STATUS)
|
11
|
-
|
11
|
+
|
12
12
|
# Xero::Gateway associated with this contact.
|
13
13
|
attr_accessor :gateway
|
14
|
-
|
14
|
+
|
15
15
|
# Any errors that occurred when the #valid? method called.
|
16
16
|
attr_reader :errors
|
17
|
-
|
18
|
-
attr_accessor :contact_id, :contact_number, :status, :name, :first_name, :last_name, :email, :addresses, :phones, :updated_at,
|
17
|
+
|
18
|
+
attr_accessor :contact_id, :contact_number, :account_number, :status, :name, :first_name, :last_name, :email, :addresses, :phones, :updated_at,
|
19
19
|
:bank_account_details, :tax_number, :accounts_receivable_tax_type, :accounts_payable_tax_type, :is_customer, :is_supplier,
|
20
20
|
:default_currency, :contact_groups
|
21
21
|
|
22
|
-
|
22
|
+
|
23
23
|
def initialize(params = {})
|
24
24
|
@errors ||= []
|
25
25
|
|
26
|
-
params = {}.merge(params)
|
26
|
+
params = {}.merge(params)
|
27
27
|
params.each do |k,v|
|
28
28
|
self.send("#{k}=", v)
|
29
29
|
end
|
30
30
|
|
31
31
|
@phones ||= []
|
32
|
-
@addresses ||=
|
32
|
+
@addresses ||= nil
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
def address=(address)
|
36
36
|
self.addresses = [address]
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
def address
|
40
|
+
self.addresses ||= []
|
40
41
|
self.addresses[0] ||= Address.new
|
41
42
|
end
|
42
|
-
|
43
|
+
|
43
44
|
# Helper method to add a new address object to this contact.
|
44
45
|
#
|
45
46
|
# Usage:
|
@@ -54,11 +55,11 @@ module XeroGateway
|
|
54
55
|
def add_address(address_params)
|
55
56
|
self.addresses << Address.new(address_params)
|
56
57
|
end
|
57
|
-
|
58
|
+
|
58
59
|
def phone=(phone)
|
59
60
|
self.phones = [phone]
|
60
61
|
end
|
61
|
-
|
62
|
+
|
62
63
|
def phone
|
63
64
|
if @phones.size > 1
|
64
65
|
@phones.detect {|p| p.phone_type == 'DEFAULT'} || phones[0]
|
@@ -66,7 +67,7 @@ module XeroGateway
|
|
66
67
|
@phones[0] ||= Phone.new
|
67
68
|
end
|
68
69
|
end
|
69
|
-
|
70
|
+
|
70
71
|
# Helper method to add a new phone object to this contact.
|
71
72
|
#
|
72
73
|
# Usage:
|
@@ -77,41 +78,41 @@ module XeroGateway
|
|
77
78
|
def add_phone(phone_params = {})
|
78
79
|
self.phones << Phone.new(phone_params)
|
79
80
|
end
|
80
|
-
|
81
|
+
|
81
82
|
# Validate the Contact record according to what will be valid by the gateway.
|
82
83
|
#
|
83
|
-
# Usage:
|
84
|
+
# Usage:
|
84
85
|
# contact.valid? # Returns true/false
|
85
|
-
#
|
86
|
+
#
|
86
87
|
# Additionally sets contact.errors array to an array of field/error.
|
87
88
|
def valid?
|
88
89
|
@errors = []
|
89
|
-
|
90
|
+
|
90
91
|
if !contact_id.nil? && contact_id !~ GUID_REGEX
|
91
92
|
@errors << ['contact_id', 'must be blank or a valid Xero GUID']
|
92
93
|
end
|
93
|
-
|
94
|
+
|
94
95
|
if status && !CONTACT_STATUS[status]
|
95
96
|
@errors << ['status', "must be one of #{CONTACT_STATUS.keys.join('/')}"]
|
96
97
|
end
|
97
|
-
|
98
|
+
|
98
99
|
unless name
|
99
100
|
@errors << ['name', "can't be blank"]
|
100
101
|
end
|
101
|
-
|
102
|
+
|
102
103
|
# Make sure all addresses are correct.
|
103
104
|
unless addresses.all? { | address | address.valid? }
|
104
105
|
@errors << ['addresses', 'at least one address is invalid']
|
105
106
|
end
|
106
|
-
|
107
|
+
|
107
108
|
# Make sure all phone numbers are correct.
|
108
109
|
unless phones.all? { | phone | phone.valid? }
|
109
110
|
@errors << ['phones', 'at least one phone is invalid']
|
110
111
|
end
|
111
|
-
|
112
|
+
|
112
113
|
@errors.size == 0
|
113
114
|
end
|
114
|
-
|
115
|
+
|
115
116
|
# General purpose create/save method.
|
116
117
|
# If contact_id and contact_number are nil then create, otherwise, attempt to save.
|
117
118
|
def save
|
@@ -121,25 +122,26 @@ module XeroGateway
|
|
121
122
|
update
|
122
123
|
end
|
123
124
|
end
|
124
|
-
|
125
|
+
|
125
126
|
# Creates this contact record (using gateway.create_contact) with the associated gateway.
|
126
127
|
# If no gateway set, raise a NoGatewayError exception.
|
127
128
|
def create
|
128
129
|
raise NoGatewayError unless gateway
|
129
130
|
gateway.create_contact(self)
|
130
131
|
end
|
131
|
-
|
132
|
+
|
132
133
|
# Creates this contact record (using gateway.update_contact) with the associated gateway.
|
133
134
|
# If no gateway set, raise a NoGatewayError exception.
|
134
135
|
def update
|
135
136
|
raise NoGatewayError unless gateway
|
136
137
|
gateway.update_contact(self)
|
137
138
|
end
|
138
|
-
|
139
|
+
|
139
140
|
def to_xml(b = Builder::XmlMarkup.new)
|
140
141
|
b.Contact {
|
141
142
|
b.ContactID self.contact_id if self.contact_id
|
142
143
|
b.ContactNumber self.contact_number if self.contact_number
|
144
|
+
b.AccountNumber self.account_number if self.account_number
|
143
145
|
b.Name self.name if self.name
|
144
146
|
b.EmailAddress self.email if self.email
|
145
147
|
b.FirstName self.first_name if self.first_name
|
@@ -154,13 +156,13 @@ module XeroGateway
|
|
154
156
|
b.DefaultCurrency if self.default_currency
|
155
157
|
b.Addresses {
|
156
158
|
addresses.each { |address| address.to_xml(b) }
|
157
|
-
}
|
159
|
+
} unless addresses.nil?
|
158
160
|
b.Phones {
|
159
161
|
phones.each { |phone| phone.to_xml(b) }
|
160
162
|
} if self.phones.any?
|
161
163
|
}
|
162
164
|
end
|
163
|
-
|
165
|
+
|
164
166
|
# Take a Contact element and convert it into an Contact object
|
165
167
|
def self.from_xml(contact_element, gateway = nil)
|
166
168
|
contact = Contact.new(:gateway => gateway)
|
@@ -168,15 +170,14 @@ module XeroGateway
|
|
168
170
|
case(element.name)
|
169
171
|
when "ContactID" then contact.contact_id = element.text
|
170
172
|
when "ContactNumber" then contact.contact_number = element.text
|
173
|
+
when "AccountNumber" then contact.account_number = element.text
|
171
174
|
when "ContactStatus" then contact.status = element.text
|
172
175
|
when "Name" then contact.name = element.text
|
173
176
|
when "FirstName" then contact.first_name = element.text
|
174
177
|
when "LastName" then contact.last_name = element.text
|
175
178
|
when "EmailAddress" then contact.email = element.text
|
176
|
-
when "Addresses" then element.children.each {|address_element| contact.addresses << Address.from_xml(address_element)}
|
177
|
-
when "Phones" then element.children.each {|phone_element| contact.phones << Phone.from_xml(phone_element)}
|
178
|
-
when "FirstName" then contact.first_name = element.text
|
179
|
-
when "LastName" then contact.last_name = element.text
|
179
|
+
when "Addresses" then element.children.each { |address_element| contact.addresses ||= []; contact.addresses << Address.from_xml(address_element) }
|
180
|
+
when "Phones" then element.children.each { |phone_element| contact.phones << Phone.from_xml(phone_element) }
|
180
181
|
when "BankAccountDetails" then contact.bank_account_details = element.text
|
181
182
|
when "TaxNumber" then contact.tax_number = element.text
|
182
183
|
when "AccountsReceivableTaxType" then contact.accounts_receivable_tax_type = element.text
|
@@ -185,19 +186,20 @@ module XeroGateway
|
|
185
186
|
when "IsCustomer" then contact.is_customer = (element.text == "true")
|
186
187
|
when "IsSupplier" then contact.is_supplier = (element.text == "true")
|
187
188
|
when "DefaultCurrency" then contact.default_currency = element.text
|
189
|
+
when "UpdatedDateUTC" then contact.updated_at = parse_date_time(element.text)
|
188
190
|
end
|
189
191
|
end
|
190
192
|
contact
|
191
193
|
end
|
192
|
-
|
194
|
+
|
193
195
|
def ==(other)
|
194
|
-
[ :contact_id, :contact_number, :status, :name, :first_name, :last_name, :email, :addresses, :phones, :updated_at,
|
196
|
+
[ :contact_id, :contact_number, :account_number, :status, :name, :first_name, :last_name, :email, :addresses, :phones, :updated_at,
|
195
197
|
:bank_account_details, :tax_number, :accounts_receivable_tax_type, :accounts_payable_tax_type, :is_customer, :is_supplier,
|
196
198
|
:default_currency, :contact_groups ].each do |field|
|
197
199
|
return false if send(field) != other.send(field)
|
198
200
|
end
|
199
201
|
return true
|
200
|
-
end
|
201
|
-
|
202
|
+
end
|
203
|
+
|
202
204
|
end
|
203
205
|
end
|
@@ -1,20 +1,22 @@
|
|
1
1
|
module XeroGateway
|
2
2
|
class ContactGroup
|
3
|
-
|
3
|
+
|
4
4
|
# Xero::Gateway associated with this invoice.
|
5
5
|
attr_accessor :gateway
|
6
|
-
|
6
|
+
|
7
7
|
# All accessible fields
|
8
|
-
attr_accessor :contact_group_id, :name, :status
|
9
|
-
|
8
|
+
attr_accessor :contact_group_id, :name, :status
|
9
|
+
attr_writer :contacts
|
10
|
+
|
10
11
|
# Boolean representing whether the accounts list has been loaded.
|
11
12
|
attr_accessor :contacts_downloaded
|
12
|
-
|
13
|
+
|
13
14
|
def initialize(params = {})
|
14
15
|
@contacts = []
|
15
16
|
params.each do |k,v|
|
16
17
|
self.send("#{k}=", v)
|
17
18
|
end
|
19
|
+
@contacts_downloaded = (params.delete(:contacts_downloaded) == true)
|
18
20
|
end
|
19
21
|
|
20
22
|
# Return the list of Contacts. Will load the contacts if the group
|
@@ -32,11 +34,11 @@ module XeroGateway
|
|
32
34
|
@contacts
|
33
35
|
end
|
34
36
|
|
35
|
-
# Returns the array of ContactIDs.
|
37
|
+
# Returns the array of ContactIDs.
|
36
38
|
# If the contact_ids array has been assigned, will return that array.
|
37
39
|
# Otherwise, returns any loaded ContactIDs
|
38
40
|
def contact_ids
|
39
|
-
if @contact_ids
|
41
|
+
if defined?(@contact_ids)
|
40
42
|
@contact_ids
|
41
43
|
else
|
42
44
|
contacts.map(&:contact_id)
|
@@ -80,8 +82,8 @@ module XeroGateway
|
|
80
82
|
end
|
81
83
|
end
|
82
84
|
end
|
83
|
-
contact_group
|
84
|
-
end
|
85
|
+
contact_group
|
86
|
+
end
|
85
87
|
|
86
88
|
end
|
87
|
-
end
|
89
|
+
end
|
@@ -3,18 +3,18 @@ module XeroGateway
|
|
3
3
|
include Dates
|
4
4
|
include Money
|
5
5
|
include LineItemCalculations
|
6
|
-
|
6
|
+
|
7
7
|
CREDIT_NOTE_TYPE = {
|
8
8
|
'ACCRECCREDIT' => 'Accounts Receivable',
|
9
9
|
'ACCPAYCREDIT' => 'Accounts Payable'
|
10
10
|
} unless defined?(CREDIT_NOTE_TYPE)
|
11
|
-
|
11
|
+
|
12
12
|
LINE_AMOUNT_TYPES = {
|
13
13
|
"Inclusive" => 'CreditNote lines are inclusive tax',
|
14
14
|
"Exclusive" => 'CreditNote lines are exclusive of tax (default)',
|
15
15
|
"NoTax" => 'CreditNotes lines have no tax'
|
16
16
|
} unless defined?(LINE_AMOUNT_TYPES)
|
17
|
-
|
17
|
+
|
18
18
|
CREDIT_NOTE_STATUS = {
|
19
19
|
'AUTHORISED' => 'Approved credit_notes awaiting payment',
|
20
20
|
'DELETED' => 'Draft credit_notes that are deleted',
|
@@ -23,53 +23,53 @@ module XeroGateway
|
|
23
23
|
'SUBMITTED' => 'CreditNotes entered by an employee awaiting approval',
|
24
24
|
'VOID' => 'Approved credit_notes that are voided'
|
25
25
|
} unless defined?(CREDIT_NOTE_STATUS)
|
26
|
-
|
26
|
+
|
27
27
|
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)
|
28
|
-
|
28
|
+
|
29
29
|
# Xero::Gateway associated with this credit_note.
|
30
30
|
attr_accessor :gateway
|
31
|
-
|
31
|
+
|
32
32
|
# Any errors that occurred when the #valid? method called.
|
33
33
|
attr_reader :errors
|
34
34
|
|
35
35
|
# Represents whether the line_items have been downloaded when getting from GET /API.XRO/2.0/CreditNotes
|
36
36
|
attr_accessor :line_items_downloaded
|
37
|
-
|
37
|
+
|
38
38
|
# All accessible fields
|
39
|
-
attr_accessor :credit_note_id, :credit_note_number, :type, :status, :date, :reference, :line_amount_types, :currency_code, :
|
39
|
+
attr_accessor :credit_note_id, :credit_note_number, :type, :status, :date, :reference, :line_amount_types, :currency_code, :payments, :fully_paid_on, :amount_credited
|
40
|
+
attr_writer :line_items, :contact
|
40
41
|
|
41
|
-
|
42
42
|
def initialize(params = {})
|
43
43
|
@errors ||= []
|
44
44
|
@payments ||= []
|
45
|
-
|
45
|
+
|
46
46
|
# Check if the line items have been downloaded.
|
47
47
|
@line_items_downloaded = (params.delete(:line_items_downloaded) == true)
|
48
|
-
|
48
|
+
|
49
49
|
params = {
|
50
50
|
:line_amount_types => "Inclusive"
|
51
51
|
}.merge(params)
|
52
|
-
|
52
|
+
|
53
53
|
params.each do |k,v|
|
54
54
|
self.send("#{k}=", v)
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
@line_items ||= []
|
58
58
|
end
|
59
|
-
|
59
|
+
|
60
60
|
# Validate the Address record according to what will be valid by the gateway.
|
61
61
|
#
|
62
|
-
# Usage:
|
62
|
+
# Usage:
|
63
63
|
# address.valid? # Returns true/false
|
64
|
-
#
|
64
|
+
#
|
65
65
|
# Additionally sets address.errors array to an array of field/error.
|
66
66
|
def valid?
|
67
67
|
@errors = []
|
68
|
-
|
68
|
+
|
69
69
|
if !credit_note_id.nil? && credit_note_id !~ GUID_REGEX
|
70
70
|
@errors << ['credit_note_id', 'must be blank or a valid Xero GUID']
|
71
71
|
end
|
72
|
-
|
72
|
+
|
73
73
|
if status && !CREDIT_NOTE_STATUS[status]
|
74
74
|
@errors << ['status', "must be one of #{CREDIT_NOTE_STATUS.keys.join('/')}"]
|
75
75
|
end
|
@@ -77,99 +77,93 @@ module XeroGateway
|
|
77
77
|
if line_amount_types && !LINE_AMOUNT_TYPES[line_amount_types]
|
78
78
|
@errors << ['line_amount_types', "must be one of #{LINE_AMOUNT_TYPES.keys.join('/')}"]
|
79
79
|
end
|
80
|
-
|
80
|
+
|
81
81
|
unless date
|
82
82
|
@errors << ['credit_note_date', "can't be blank"]
|
83
83
|
end
|
84
|
-
|
84
|
+
|
85
85
|
# Make sure contact is valid.
|
86
86
|
unless @contact && @contact.valid?
|
87
87
|
@errors << ['contact', 'is invalid']
|
88
88
|
end
|
89
|
-
|
89
|
+
|
90
90
|
# Make sure all line_items are valid.
|
91
91
|
unless line_items.all? { | line_item | line_item.valid? }
|
92
92
|
@errors << ['line_items', "at least one line item invalid"]
|
93
93
|
end
|
94
|
-
|
94
|
+
|
95
95
|
@errors.size == 0
|
96
96
|
end
|
97
|
-
|
97
|
+
|
98
98
|
# Helper method to create the associated contact object.
|
99
99
|
def build_contact(params = {})
|
100
100
|
self.contact = gateway ? gateway.build_contact(params) : Contact.new(params)
|
101
101
|
end
|
102
|
-
|
102
|
+
|
103
103
|
def contact
|
104
104
|
@contact ||= build_contact
|
105
105
|
end
|
106
|
-
|
106
|
+
|
107
107
|
# Helper method to check if the credit_note is accounts payable.
|
108
108
|
def accounts_payable?
|
109
109
|
type == 'ACCPAYCREDIT'
|
110
110
|
end
|
111
|
-
|
111
|
+
|
112
112
|
# Helper method to check if the credit_note is accounts receivable.
|
113
113
|
def accounts_receivable?
|
114
114
|
type == 'ACCRECCREDIT'
|
115
115
|
end
|
116
|
-
|
116
|
+
|
117
117
|
# Whether or not the line_items have been downloaded (GET/credit_notes does not download line items).
|
118
118
|
def line_items_downloaded?
|
119
119
|
@line_items_downloaded
|
120
120
|
end
|
121
|
-
|
121
|
+
|
122
122
|
# If line items are not downloaded, then attempt a download now (if this record was found to begin with).
|
123
123
|
def line_items
|
124
124
|
if line_items_downloaded?
|
125
125
|
@line_items
|
126
|
-
|
126
|
+
|
127
127
|
# There is an credit_note_is so we can assume this record was loaded from Xero.
|
128
128
|
# attempt to download the line_item records.
|
129
129
|
elsif credit_note_id =~ GUID_REGEX
|
130
130
|
raise NoGatewayError unless @gateway
|
131
|
-
|
131
|
+
|
132
132
|
response = @gateway.get_credit_note(credit_note_id)
|
133
133
|
raise CreditNoteNotFoundError, "CreditNote with ID #{credit_note_id} not found in Xero." unless response.success? && response.credit_note.is_a?(XeroGateway::CreditNote)
|
134
|
-
|
134
|
+
|
135
135
|
@line_items = response.credit_note.line_items
|
136
136
|
@line_items_downloaded = true
|
137
|
-
|
137
|
+
|
138
138
|
@line_items
|
139
|
-
|
139
|
+
|
140
140
|
# Otherwise, this is a new credit_note, so return the line_items reference.
|
141
141
|
else
|
142
142
|
@line_items
|
143
143
|
end
|
144
144
|
end
|
145
|
-
|
145
|
+
|
146
146
|
def ==(other)
|
147
147
|
["credit_note_number", "type", "status", "reference", "currency_code", "line_amount_types", "contact", "line_items"].each do |field|
|
148
148
|
return false if send(field) != other.send(field)
|
149
149
|
end
|
150
|
-
|
150
|
+
|
151
151
|
["date"].each do |field|
|
152
152
|
return false if send(field).to_s != other.send(field).to_s
|
153
153
|
end
|
154
154
|
return true
|
155
155
|
end
|
156
|
-
|
157
|
-
# General purpose createsave method.
|
158
|
-
# If contact_id and contact_number are nil then create, otherwise, attempt to save.
|
159
|
-
def save
|
160
|
-
create
|
161
|
-
end
|
162
|
-
|
156
|
+
|
163
157
|
# Creates this credit_note record (using gateway.create_credit_note) with the associated gateway.
|
164
158
|
# If no gateway set, raise a NoGatewayError exception.
|
165
159
|
def create
|
166
160
|
raise NoGatewayError unless gateway
|
167
161
|
gateway.create_credit_note(self)
|
168
162
|
end
|
169
|
-
|
163
|
+
|
170
164
|
# Alias create as save as this is currently the only write action.
|
171
165
|
alias_method :save, :create
|
172
|
-
|
166
|
+
|
173
167
|
def to_xml(b = Builder::XmlMarkup.new)
|
174
168
|
b.CreditNote {
|
175
169
|
b.Type self.type
|
@@ -187,14 +181,14 @@ module XeroGateway
|
|
187
181
|
}
|
188
182
|
}
|
189
183
|
end
|
190
|
-
|
184
|
+
|
191
185
|
#TODO UpdatedDateUTC
|
192
186
|
def self.from_xml(credit_note_element, gateway = nil, options = {})
|
193
187
|
credit_note = CreditNote.new(options.merge({:gateway => gateway}))
|
194
188
|
credit_note_element.children.each do |element|
|
195
189
|
case(element.name)
|
196
190
|
when "CreditNoteID" then credit_note.credit_note_id = element.text
|
197
|
-
when "CreditNoteNumber" then credit_note.credit_note_number = element.text
|
191
|
+
when "CreditNoteNumber" then credit_note.credit_note_number = element.text
|
198
192
|
when "Type" then credit_note.type = element.text
|
199
193
|
when "CurrencyCode" then credit_note.currency_code = element.text
|
200
194
|
when "Contact" then credit_note.contact = Contact.from_xml(element)
|
@@ -206,15 +200,13 @@ module XeroGateway
|
|
206
200
|
when "SubTotal" then credit_note.sub_total = BigDecimal.new(element.text)
|
207
201
|
when "TotalTax" then credit_note.total_tax = BigDecimal.new(element.text)
|
208
202
|
when "Total" then credit_note.total = BigDecimal.new(element.text)
|
209
|
-
when "CreditNoteID" then credit_note.credit_note_id = element.text
|
210
|
-
when "CreditNoteNumber" then credit_note.credit_note_number = element.text
|
211
203
|
when "Payments" then element.children.each { | payment | credit_note.payments << Payment.from_xml(payment) }
|
212
204
|
when "AmountDue" then credit_note.amount_due = BigDecimal.new(element.text)
|
213
205
|
when "AmountPaid" then credit_note.amount_paid = BigDecimal.new(element.text)
|
214
206
|
when "AmountCredited" then credit_note.amount_credited = BigDecimal.new(element.text)
|
215
207
|
end
|
216
|
-
end
|
208
|
+
end
|
217
209
|
credit_note
|
218
|
-
end
|
210
|
+
end
|
219
211
|
end
|
220
212
|
end
|
data/lib/xero_gateway/gateway.rb
CHANGED
@@ -147,7 +147,7 @@ module XeroGateway
|
|
147
147
|
# Retreives a contact group by its id.
|
148
148
|
def get_contact_group_by_id(contact_group_id)
|
149
149
|
request_params = { :ContactGroupID => contact_group_id }
|
150
|
-
response_xml = http_get(@client, "#{@xero_url}/ContactGroups/#{
|
150
|
+
response_xml = http_get(@client, "#{@xero_url}/ContactGroups/#{CGI.escape(contact_group_id)}", request_params)
|
151
151
|
|
152
152
|
parse_response(response_xml, {:request_params => request_params}, {:request_signature => 'GET/contactgroup'})
|
153
153
|
end
|
@@ -155,7 +155,9 @@ module XeroGateway
|
|
155
155
|
# Retrieves all invoices from Xero
|
156
156
|
#
|
157
157
|
# Usage : get_invoices
|
158
|
-
# get_invoices(:invoice_id => "
|
158
|
+
# get_invoices(:invoice_id => "297c2dc5-cc47-4afd-8ec8-74990b8761e9")
|
159
|
+
# get_invoices(:invoice_number => "175")
|
160
|
+
# get_invoices(:contact_ids => ["297c2dc5-cc47-4afd-8ec8-74990b8761e9"] )
|
159
161
|
#
|
160
162
|
# Note : modified_since is in UTC format (i.e. Brisbane is UTC+10)
|
161
163
|
def get_invoices(options = {})
|
@@ -166,6 +168,7 @@ module XeroGateway
|
|
166
168
|
request_params[:InvoiceNumber] = options[:invoice_number] if options[:invoice_number]
|
167
169
|
request_params[:order] = options[:order] if options[:order]
|
168
170
|
request_params[:ModifiedAfter] = options[:modified_since] if options[:modified_since]
|
171
|
+
request_params[:ContactIDs] = Array(options[:contact_ids]).join(",") if options[:contact_ids]
|
169
172
|
|
170
173
|
request_params[:where] = options[:where] if options[:where]
|
171
174
|
|
@@ -186,7 +189,7 @@ module XeroGateway
|
|
186
189
|
|
187
190
|
headers.merge!("Accept" => "application/pdf") if format == :pdf
|
188
191
|
|
189
|
-
url = "#{@xero_url}/Invoices/#{
|
192
|
+
url = "#{@xero_url}/Invoices/#{CGI.escape(invoice_id_or_number)}"
|
190
193
|
|
191
194
|
response = http_get(@client, url, request_params, headers)
|
192
195
|
|
@@ -306,7 +309,7 @@ module XeroGateway
|
|
306
309
|
def get_credit_note(credit_note_id_or_number)
|
307
310
|
request_params = {}
|
308
311
|
|
309
|
-
url = "#{@xero_url}/CreditNotes/#{
|
312
|
+
url = "#{@xero_url}/CreditNotes/#{CGI.escape(credit_note_id_or_number)}"
|
310
313
|
|
311
314
|
response_xml = http_get(@client, url, request_params)
|
312
315
|
|
@@ -453,7 +456,7 @@ module XeroGateway
|
|
453
456
|
# get_bank_transaction("OIT-12345") # By number
|
454
457
|
def get_bank_transaction(bank_transaction_id)
|
455
458
|
request_params = {}
|
456
|
-
url = "#{@xero_url}/BankTransactions/#{
|
459
|
+
url = "#{@xero_url}/BankTransactions/#{CGI.escape(bank_transaction_id)}"
|
457
460
|
response_xml = http_get(@client, url, request_params)
|
458
461
|
parse_response(response_xml, {:request_params => request_params}, {:request_signature => 'GET/BankTransaction'})
|
459
462
|
end
|
@@ -503,7 +506,7 @@ module XeroGateway
|
|
503
506
|
# get_manual_journal("OIT-12345") # By number
|
504
507
|
def get_manual_journal(manual_journal_id)
|
505
508
|
request_params = {}
|
506
|
-
url = "#{@xero_url}/ManualJournals/#{
|
509
|
+
url = "#{@xero_url}/ManualJournals/#{CGI.escape(manual_journal_id)}"
|
507
510
|
response_xml = http_get(@client, url, request_params)
|
508
511
|
parse_response(response_xml, {:request_params => request_params}, {:request_signature => 'GET/ManualJournal'})
|
509
512
|
end
|
@@ -621,7 +624,7 @@ module XeroGateway
|
|
621
624
|
|
622
625
|
def get_contact(contact_id = nil, contact_number = nil)
|
623
626
|
request_params = contact_id ? { :contactID => contact_id } : { :contactNumber => contact_number }
|
624
|
-
response_xml = http_get(@client, "#{@xero_url}/Contacts/#{
|
627
|
+
response_xml = http_get(@client, "#{@xero_url}/Contacts/#{CGI.escape(contact_id||contact_number)}", request_params)
|
625
628
|
|
626
629
|
parse_response(response_xml, {:request_params => request_params}, {:request_signature => 'GET/contact'})
|
627
630
|
end
|