xero_gateway 2.3.0 → 2.4.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 +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
|