forked from xero-gateway/xero_gateway
/
credit_note_test.rb
284 lines (230 loc) · 12.5 KB
/
credit_note_test.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
require File.join(File.dirname(__FILE__), '../test_helper.rb')
class CreditNoteTest < Test::Unit::TestCase
# Tests that a credit note can be converted into XML that Xero can understand, and then converted back to a credit note
def test_build_and_parse_xml
credit_note = create_test_credit_note
# Generate the XML message
credit_note_as_xml = credit_note.to_xml
# Parse the XML message and retrieve the credit_note element
credit_note_element = REXML::XPath.first(REXML::Document.new(credit_note_as_xml), "/CreditNote")
# Build a new credit_note from the XML
result_credit_note = XeroGateway::CreditNote.from_xml(credit_note_element)
assert_equal(credit_note, result_credit_note)
end
# Tests the sub_total calculation and that setting it manually doesn't modify the data.
def test_credit_note_sub_total_calculation
credit_note = create_test_credit_note
line_item = credit_note.line_items.first
# Make sure that everything adds up to begin with.
expected_sub_total = credit_note.line_items.inject(BigDecimal.new('0')) { | sum, line_item | line_item.line_amount }
assert_equal(expected_sub_total, credit_note.sub_total)
# Change the sub_total and check that it doesn't modify anything.
credit_note.sub_total = expected_sub_total * 10
assert_equal(expected_sub_total, credit_note.sub_total)
# Change the amount of the first line item and make sure that
# everything still continues to add up.
line_item.unit_amount = line_item.unit_amount + 10
assert_not_equal(expected_sub_total, credit_note.sub_total)
expected_sub_total = credit_note.line_items.inject(BigDecimal.new('0')) { | sum, line_item | line_item.line_amount }
assert_equal(expected_sub_total, credit_note.sub_total)
end
# Tests the total_tax calculation and that setting it manually doesn't modify the data.
def test_credit_note_sub_total_calculation2
credit_note = create_test_credit_note
line_item = credit_note.line_items.first
# Make sure that everything adds up to begin with.
expected_total_tax = credit_note.line_items.inject(BigDecimal.new('0')) { | sum, line_item | line_item.tax_amount }
assert_equal(expected_total_tax, credit_note.total_tax)
# Change the total_tax and check that it doesn't modify anything.
credit_note.total_tax = expected_total_tax * 10
assert_equal(expected_total_tax, credit_note.total_tax)
# Change the tax_amount of the first line item and make sure that
# everything still continues to add up.
line_item.tax_amount = line_item.tax_amount + 10
assert_not_equal(expected_total_tax, credit_note.total_tax)
expected_total_tax = credit_note.line_items.inject(BigDecimal.new('0')) { | sum, line_item | line_item.tax_amount }
assert_equal(expected_total_tax, credit_note.total_tax)
end
# Tests the total calculation and that setting it manually doesn't modify the data.
def test_credit_note_sub_total_calculation3
credit_note = create_test_credit_note
line_item = credit_note.line_items.first
# Make sure that everything adds up to begin with.
expected_total = credit_note.sub_total + credit_note.total_tax
assert_equal(expected_total, credit_note.total)
# Change the total and check that it doesn't modify anything.
credit_note.total = expected_total * 10
assert_equal(expected_total, credit_note.total)
# Change the quantity of the first line item and make sure that
# everything still continues to add up.
line_item.quantity = line_item.quantity + 5
assert_not_equal(expected_total, credit_note.total)
expected_total = credit_note.sub_total + credit_note.total_tax
assert_equal(expected_total, credit_note.total)
end
# Tests that the LineItem#line_amount calculation is working correctly.
def test_line_amount_calculation
credit_note = create_test_credit_note
line_item = credit_note.line_items.first
# Make sure that everything adds up to begin with.
expected_amount = line_item.quantity * line_item.unit_amount
assert_equal(expected_amount, line_item.line_amount)
# Change the line_amount and check that it doesn't modify anything.
line_item.line_amount = expected_amount * 10
assert_equal(expected_amount, line_item.line_amount)
# Change the quantity and check that the line_amount has been updated.
quantity = line_item.quantity + 2
line_item.quantity = quantity
assert_not_equal(expected_amount, line_item.line_amount)
assert_equal(quantity * line_item.unit_amount, line_item.line_amount)
end
# Ensure that the totalling methods don't raise exceptions, even when
# credit_note.line_items is empty.
def test_totalling_methods_when_line_items_empty
credit_note = create_test_credit_note
credit_note.line_items = []
assert_nothing_raised(Exception) {
assert_equal(BigDecimal.new('0'), credit_note.sub_total)
assert_equal(BigDecimal.new('0'), credit_note.total_tax)
assert_equal(BigDecimal.new('0'), credit_note.total)
}
end
def test_type_helper_methods
# Test accounts receivable credit_notes.
credit_note = create_test_credit_note({:type => 'ACCRECCREDIT'})
assert_equal(true, credit_note.accounts_receivable?, "Accounts RECEIVABLE credit_note doesn't think it is.")
assert_equal(false, credit_note.accounts_payable?, "Accounts RECEIVABLE credit_note thinks it's payable.")
# Test accounts payable credit_notes.
credit_note = create_test_credit_note({:type => 'ACCPAYCREDIT'})
assert_equal(false, credit_note.accounts_receivable?, "Accounts PAYABLE credit_note doesn't think it is.")
assert_equal(true, credit_note.accounts_payable?, "Accounts PAYABLE credit_note thinks it's receivable.")
end
# Make sure that the create_test_credit_note method is working correctly
# with all the defaults and overrides.
def test_create_test_credit_note_defaults_working
credit_note = create_test_credit_note
# Test credit_note defaults.
assert_equal('ACCRECCREDIT', credit_note.type)
assert_kind_of(Date, credit_note.date)
assert_equal('12345', credit_note.credit_note_number)
assert_equal('MY REFERENCE FOR THIS CREDIT NOTE', credit_note.reference)
assert_equal("Exclusive", credit_note.line_amount_types)
# Test the contact defaults.
assert_equal('00000000-0000-0000-0000-000000000000', credit_note.contact.contact_id)
assert_equal('CONTACT NAME', credit_note.contact.name)
# Test address defaults.
assert_equal('DEFAULT', credit_note.contact.address.address_type)
assert_equal('LINE 1 OF THE ADDRESS', credit_note.contact.address.line_1)
# Test phone defaults.
assert_equal('DEFAULT', credit_note.contact.phone.phone_type)
assert_equal('12345678', credit_note.contact.phone.number)
# Test the line_item defaults.
assert_equal('A LINE ITEM', credit_note.line_items.first.description)
assert_equal('200', credit_note.line_items.first.account_code)
assert_equal(BigDecimal.new('100'), credit_note.line_items.first.unit_amount)
assert_equal(BigDecimal.new('12.5'), credit_note.line_items.first.tax_amount)
# Test overriding an credit_note parameter (assume works for all).
credit_note = create_test_credit_note({:type => 'ACCPAYCREDIT'})
assert_equal('ACCPAYCREDIT', credit_note.type)
# Test overriding a contact/address/phone parameter (assume works for all).
credit_note = create_test_credit_note({}, {:name => 'OVERRIDDEN NAME', :address => {:line_1 => 'OVERRIDDEN LINE 1'}, :phone => {:number => '999'}})
assert_equal('OVERRIDDEN NAME', credit_note.contact.name)
assert_equal('OVERRIDDEN LINE 1', credit_note.contact.address.line_1)
assert_equal('999', credit_note.contact.phone.number)
# Test overriding line_items with hash.
credit_note = create_test_credit_note({}, {}, {:description => 'OVERRIDDEN LINE ITEM'})
assert_equal(1, credit_note.line_items.size)
assert_equal('OVERRIDDEN LINE ITEM', credit_note.line_items.first.description)
assert_equal(BigDecimal.new('100'), credit_note.line_items.first.unit_amount)
# Test overriding line_items with array of 2 line_items.
credit_note = create_test_credit_note({}, {}, [
{:description => 'OVERRIDDEN ITEM 1'},
{:description => 'OVERRIDDEN ITEM 2', :account_code => '200', :unit_amount => BigDecimal.new('200'), :tax_amount => '25.0'}
])
assert_equal(2, credit_note.line_items.size)
assert_equal('OVERRIDDEN ITEM 1', credit_note.line_items[0].description)
assert_equal(BigDecimal.new('100'), credit_note.line_items[0].unit_amount)
assert_equal('OVERRIDDEN ITEM 2', credit_note.line_items[1].description)
assert_equal(BigDecimal.new('200'), credit_note.line_items[1].unit_amount)
end
def test_auto_creation_of_associated_contact
credit_note = create_test_credit_note({}, nil) # no contact
assert_nil(credit_note.instance_variable_get("@contact"))
new_contact = credit_note.contact
assert_kind_of(XeroGateway::Contact, new_contact)
end
def test_add_line_item
credit_note = create_test_credit_note({}, {}, nil) # no line_items
assert_equal(0, credit_note.line_items.size)
line_item_params = {:description => "Test Item 1", :unit_amount => 100}
# Test adding line item by hash
line_item = credit_note.add_line_item(line_item_params)
assert_kind_of(XeroGateway::LineItem, line_item)
assert_equal(line_item_params[:description], line_item.description)
assert_equal(line_item_params[:unit_amount], line_item.unit_amount)
assert_equal(1, credit_note.line_items.size)
# Test adding line item by XeroGateway::LineItem
line_item = credit_note.add_line_item(line_item_params)
assert_kind_of(XeroGateway::LineItem, line_item)
assert_equal(line_item_params[:description], line_item.description)
assert_equal(line_item_params[:unit_amount], line_item.unit_amount)
assert_equal(2, credit_note.line_items.size)
# Test that pushing anything else into add_line_item fails.
["invalid", 100, nil, []].each do | invalid_object |
assert_raise(XeroGateway::InvalidLineItemError) { credit_note.add_line_item(invalid_object) }
assert_equal(2, credit_note.line_items.size)
end
end
private
def create_test_credit_note(credit_note_params = {}, contact_params = {}, line_item_params = [])
unless credit_note_params.nil?
credit_note_params = {
:type => 'ACCRECCREDIT',
:date => Date.today,
:credit_note_number => '12345',
:reference => "MY REFERENCE FOR THIS CREDIT NOTE",
:line_amount_types => "Exclusive"
}.merge(credit_note_params)
end
credit_note = XeroGateway::CreditNote.new(credit_note_params || {})
unless contact_params.nil?
# Strip out :address key from contact_params to use as the default address.
stripped_address = {
:address_type => 'DEFAULT',
:line_1 => 'LINE 1 OF THE ADDRESS'
}.merge(contact_params.delete(:address) || {})
# Strip out :phone key from contact_params to use at the default phone.
stripped_phone = {
:phone_type => 'DEFAULT',
:number => '12345678'
}.merge(contact_params.delete(:phone) || {})
contact_params = {
:contact_id => '00000000-0000-0000-0000-000000000000', # Just any valid GUID
:name => "CONTACT NAME",
:first_name => "Bob",
:last_name => "Builder"
}.merge(contact_params)
# Create credit_note.contact from contact_params.
credit_note.contact = XeroGateway::Contact.new(contact_params)
credit_note.contact.address = XeroGateway::Address.new(stripped_address)
credit_note.contact.phone = XeroGateway::Phone.new(stripped_phone)
end
unless line_item_params.nil?
line_item_params = [line_item_params].flatten # always use an array, even if only a single hash passed in
# At least one line item, make first have some defaults.
line_item_params << {} if line_item_params.size == 0
line_item_params[0] = {
:description => "A LINE ITEM",
:account_code => "200",
:unit_amount => BigDecimal.new("100"),
:tax_amount => BigDecimal.new("12.5"),
:tracking => XeroGateway::TrackingCategory.new(:name => "blah", :options => "hello")
}.merge(line_item_params[0])
# Create credit_note.line_items from line_item_params
line_item_params.each do | line_item |
credit_note.add_line_item(line_item)
end
end
credit_note
end
end