xero_gateway-float 2.0.15
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +12 -0
- data/LICENSE +14 -0
- data/README.textile +357 -0
- data/Rakefile +14 -0
- data/examples/oauth.rb +25 -0
- data/examples/partner_app.rb +36 -0
- data/init.rb +1 -0
- data/lib/oauth/oauth_consumer.rb +14 -0
- data/lib/xero_gateway.rb +39 -0
- data/lib/xero_gateway/account.rb +95 -0
- data/lib/xero_gateway/accounts_list.rb +87 -0
- data/lib/xero_gateway/address.rb +96 -0
- data/lib/xero_gateway/bank_transaction.rb +178 -0
- data/lib/xero_gateway/ca-certificates.crt +2560 -0
- data/lib/xero_gateway/contact.rb +206 -0
- data/lib/xero_gateway/credit_note.rb +222 -0
- data/lib/xero_gateway/currency.rb +56 -0
- data/lib/xero_gateway/dates.rb +30 -0
- data/lib/xero_gateway/error.rb +18 -0
- data/lib/xero_gateway/exceptions.rb +46 -0
- data/lib/xero_gateway/gateway.rb +622 -0
- data/lib/xero_gateway/http.rb +138 -0
- data/lib/xero_gateway/http_encoding_helper.rb +49 -0
- data/lib/xero_gateway/invoice.rb +236 -0
- data/lib/xero_gateway/line_item.rb +125 -0
- data/lib/xero_gateway/line_item_calculations.rb +55 -0
- data/lib/xero_gateway/money.rb +16 -0
- data/lib/xero_gateway/oauth.rb +87 -0
- data/lib/xero_gateway/organisation.rb +75 -0
- data/lib/xero_gateway/partner_app.rb +30 -0
- data/lib/xero_gateway/payment.rb +40 -0
- data/lib/xero_gateway/phone.rb +77 -0
- data/lib/xero_gateway/private_app.rb +17 -0
- data/lib/xero_gateway/response.rb +41 -0
- data/lib/xero_gateway/tax_rate.rb +63 -0
- data/lib/xero_gateway/tracking_category.rb +87 -0
- data/test/integration/accounts_list_test.rb +109 -0
- data/test/integration/create_bank_transaction_test.rb +38 -0
- data/test/integration/create_contact_test.rb +66 -0
- data/test/integration/create_credit_note_test.rb +49 -0
- data/test/integration/create_invoice_test.rb +49 -0
- data/test/integration/get_accounts_test.rb +23 -0
- data/test/integration/get_bank_transaction_test.rb +51 -0
- data/test/integration/get_bank_transactions_test.rb +88 -0
- data/test/integration/get_contact_test.rb +28 -0
- data/test/integration/get_contacts_test.rb +40 -0
- data/test/integration/get_credit_note_test.rb +48 -0
- data/test/integration/get_credit_notes_test.rb +90 -0
- data/test/integration/get_currencies_test.rb +25 -0
- data/test/integration/get_invoice_test.rb +48 -0
- data/test/integration/get_invoices_test.rb +92 -0
- data/test/integration/get_organisation_test.rb +24 -0
- data/test/integration/get_tax_rates_test.rb +25 -0
- data/test/integration/get_tracking_categories_test.rb +27 -0
- data/test/integration/update_bank_transaction_test.rb +31 -0
- data/test/integration/update_contact_test.rb +31 -0
- data/test/integration/update_invoice_test.rb +31 -0
- data/test/test_helper.rb +179 -0
- data/test/unit/account_test.rb +47 -0
- data/test/unit/bank_transaction_test.rb +126 -0
- data/test/unit/contact_test.rb +97 -0
- data/test/unit/credit_note_test.rb +284 -0
- data/test/unit/currency_test.rb +31 -0
- data/test/unit/gateway_test.rb +119 -0
- data/test/unit/invoice_test.rb +326 -0
- data/test/unit/oauth_test.rb +116 -0
- data/test/unit/organisation_test.rb +38 -0
- data/test/unit/tax_rate_test.rb +38 -0
- data/test/unit/tracking_category_test.rb +52 -0
- data/xero_gateway.gemspec +15 -0
- metadata +164 -0
@@ -0,0 +1,47 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../test_helper.rb')
|
2
|
+
|
3
|
+
class AccountTest < Test::Unit::TestCase
|
4
|
+
# Tests that an account can be converted into XML that Xero can understand, and then converted back to an account
|
5
|
+
def test_build_and_parse_xml
|
6
|
+
account = create_test_account
|
7
|
+
|
8
|
+
# Generate the XML message
|
9
|
+
account_as_xml = account.to_xml
|
10
|
+
|
11
|
+
# Parse the XML message and retrieve the account element
|
12
|
+
account_element = REXML::XPath.first(REXML::Document.new(account_as_xml), "/Account")
|
13
|
+
|
14
|
+
# Build a new account from the XML
|
15
|
+
result_account = XeroGateway::Account.from_xml(account_element)
|
16
|
+
|
17
|
+
# Check the account details
|
18
|
+
assert_equal account, result_account
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_build_and_parse_xml_for_bank_accounts
|
22
|
+
account = create_test_account(:type => 'BANK', :currency_code => 'NZD')
|
23
|
+
account_as_xml = account.to_xml
|
24
|
+
assert_match 'CurrencyCode', account_as_xml.to_s
|
25
|
+
|
26
|
+
account_element = REXML::XPath.first(REXML::Document.new(account_as_xml), "/Account")
|
27
|
+
result_account = XeroGateway::Account.from_xml(account_element)
|
28
|
+
assert_equal 'BANK', result_account.type
|
29
|
+
assert_equal 'NZD', result_account.currency_code
|
30
|
+
assert_equal account, result_account
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def create_test_account(options={})
|
36
|
+
account = XeroGateway::Account.new(:account_id => "57cedda9")
|
37
|
+
account.code = "200"
|
38
|
+
account.name = "Sales"
|
39
|
+
account.type = options[:type] || "REVENUE"
|
40
|
+
account.tax_type = "OUTPUT"
|
41
|
+
account.description = "Income from any normal business activity"
|
42
|
+
account.enable_payments_to_account = false
|
43
|
+
account.currency_code = options[:currency_code] if options[:currency_code]
|
44
|
+
|
45
|
+
account
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../test_helper.rb')
|
2
|
+
|
3
|
+
class BankTransactionTest < Test::Unit::TestCase
|
4
|
+
include TestHelper
|
5
|
+
|
6
|
+
context "creating test bank transactions" do
|
7
|
+
should "work" do
|
8
|
+
bank_transaction = create_test_bank_transaction
|
9
|
+
|
10
|
+
# test transaction defaults
|
11
|
+
assert_equal 'RECEIVE', bank_transaction.type
|
12
|
+
assert_kind_of Date, bank_transaction.date
|
13
|
+
assert_equal '12345', bank_transaction.reference
|
14
|
+
assert_equal 'ACTIVE', bank_transaction.status
|
15
|
+
|
16
|
+
# Test the contact defaults.
|
17
|
+
contact = bank_transaction.contact
|
18
|
+
assert_equal '00000000-0000-0000-0000-000000000000', contact.contact_id
|
19
|
+
assert_equal 'CONTACT NAME', contact.name
|
20
|
+
|
21
|
+
# Test address defaults.
|
22
|
+
assert_equal 'STREET', contact.address.address_type
|
23
|
+
assert_equal 'LINE 1 OF THE ADDRESS', contact.address.line_1
|
24
|
+
|
25
|
+
# Test phone defaults.
|
26
|
+
assert_equal('DEFAULT', contact.phone.phone_type)
|
27
|
+
assert_equal('12345678', contact.phone.number)
|
28
|
+
|
29
|
+
# Test the line_item defaults.
|
30
|
+
line_item = bank_transaction.line_items.first
|
31
|
+
assert_equal('A LINE ITEM', line_item.description)
|
32
|
+
assert_equal('200', line_item.account_code)
|
33
|
+
assert_equal(BigDecimal.new('100'), line_item.unit_amount)
|
34
|
+
assert_equal(BigDecimal.new('12.5'), line_item.tax_amount)
|
35
|
+
end
|
36
|
+
|
37
|
+
should "allow overriding transaction defaults" do
|
38
|
+
assert_equal 'SPEND', create_test_bank_transaction(:type => 'SPEND').type
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "adding line items" do
|
43
|
+
setup do
|
44
|
+
@bank_transaction = create_test_bank_transaction({}, {}, nil) # no line_items
|
45
|
+
end
|
46
|
+
|
47
|
+
should "work" do
|
48
|
+
assert_equal(0, @bank_transaction.line_items.size)
|
49
|
+
|
50
|
+
line_item_params = {:description => "Test Item 1", :unit_amount => 100}
|
51
|
+
|
52
|
+
# Test adding line item by hash
|
53
|
+
line_item = @bank_transaction.add_line_item(line_item_params)
|
54
|
+
assert_kind_of(XeroGateway::LineItem, line_item)
|
55
|
+
assert_equal(line_item_params[:description], line_item.description)
|
56
|
+
assert_equal(line_item_params[:unit_amount], line_item.unit_amount)
|
57
|
+
assert_equal(1, @bank_transaction.line_items.size)
|
58
|
+
|
59
|
+
# Test adding line item by XeroGateway::LineItem
|
60
|
+
line_item = @bank_transaction.add_line_item(line_item_params)
|
61
|
+
assert_kind_of(XeroGateway::LineItem, line_item)
|
62
|
+
assert_equal(line_item_params[:description], line_item.description)
|
63
|
+
assert_equal(line_item_params[:unit_amount], line_item.unit_amount)
|
64
|
+
assert_equal(2, @bank_transaction.line_items.size)
|
65
|
+
|
66
|
+
# Test that pushing anything else into add_line_item fails.
|
67
|
+
["invalid", 100, nil, []].each do | invalid_object |
|
68
|
+
assert_raise(XeroGateway::Invoice::InvalidLineItemError) { @bank_transaction.add_line_item(invalid_object) }
|
69
|
+
assert_equal(2, @bank_transaction.line_items.size)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
context "building and parsing XML" do
|
76
|
+
should "work vice versa" do
|
77
|
+
bank_transaction = create_test_bank_transaction
|
78
|
+
bank_transaction_as_xml = bank_transaction.to_xml
|
79
|
+
bank_transaction_element = REXML::XPath.first(REXML::Document.new(bank_transaction_as_xml), "/BankTransaction")
|
80
|
+
|
81
|
+
# checking for mandatory fields
|
82
|
+
assert_xml_field bank_transaction_element, 'Type', :value => 'RECEIVE'
|
83
|
+
assert_xml_field bank_transaction_element, 'Date'
|
84
|
+
assert_xml_field bank_transaction_element, 'Reference', :value => '12345'
|
85
|
+
assert_xml_field bank_transaction_element, 'Status', :value => 'ACTIVE'
|
86
|
+
assert_xml_field bank_transaction_element, 'Contact', :value => 'CONTACT NAME'
|
87
|
+
assert_xml_field bank_transaction_element, 'LineItems', :value => 'A LINE ITEM'
|
88
|
+
assert_xml_field bank_transaction_element, 'BankAccount'
|
89
|
+
|
90
|
+
parsed_bank_transaction = XeroGateway::BankTransaction.from_xml(bank_transaction_element)
|
91
|
+
assert_equal(bank_transaction, parsed_bank_transaction)
|
92
|
+
end
|
93
|
+
|
94
|
+
should "work for optional params" do
|
95
|
+
bank_transaction = create_test_bank_transaction(:url => 'http://example.com?with=params&and=more')
|
96
|
+
bank_transaction_element = REXML::XPath.first(REXML::Document.new(bank_transaction.to_xml), "/BankTransaction")
|
97
|
+
|
98
|
+
assert_xml_field bank_transaction_element, 'Url', :value => 'http://example.com\?with=params&and=more'
|
99
|
+
|
100
|
+
parsed_bank_transaction = XeroGateway::BankTransaction.from_xml(bank_transaction_element)
|
101
|
+
assert_equal 'http://example.com?with=params&and=more', parsed_bank_transaction.url
|
102
|
+
end
|
103
|
+
|
104
|
+
should "ignore missing contact" do
|
105
|
+
bank_transaction = create_test_bank_transaction
|
106
|
+
bank_transaction.contact = nil
|
107
|
+
bank_transaction.to_xml
|
108
|
+
end
|
109
|
+
|
110
|
+
should "ignore missing bank account" do
|
111
|
+
bank_transaction = create_test_bank_transaction
|
112
|
+
bank_transaction.bank_account = nil
|
113
|
+
bank_transaction.to_xml
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
private
|
118
|
+
|
119
|
+
def assert_xml_field(xml, field_name, options={})
|
120
|
+
assert_match /#{field_name}/, xml.to_s, "Didn't find the field #{field_name} in the XML document!"
|
121
|
+
if options[:value]
|
122
|
+
assert_match /#{field_name}.*#{options[:value]}.*#{field_name}/, xml.to_s, "The field #{field_name} was expected to be '#{options[:value]}'!"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../test_helper.rb')
|
2
|
+
|
3
|
+
class ContactTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@schema = LibXML::XML::Schema.document(LibXML::XML::Document.file(File.join(File.dirname(__FILE__), '../xsd/create_contact.xsd')))
|
6
|
+
end
|
7
|
+
|
8
|
+
# Tests that the XML generated from a contact object validates against the Xero XSD
|
9
|
+
def test_build_xml
|
10
|
+
contact = create_test_contact
|
11
|
+
|
12
|
+
message = contact.to_xml
|
13
|
+
|
14
|
+
# Check that the document matches the XSD
|
15
|
+
assert LibXML::XML::Parser.string(message).parse.validate_schema(@schema), "The XML document generated did not validate against the XSD"
|
16
|
+
end
|
17
|
+
|
18
|
+
# Tests that a contact can be converted into XML that Xero can understand, and then converted back to a contact
|
19
|
+
def test_build_and_parse_xml
|
20
|
+
contact = create_test_contact
|
21
|
+
|
22
|
+
# Generate the XML message
|
23
|
+
contact_as_xml = contact.to_xml
|
24
|
+
|
25
|
+
# Parse the XML message and retrieve the contact element
|
26
|
+
contact_element = REXML::XPath.first(REXML::Document.new(contact_as_xml), "/Contact")
|
27
|
+
|
28
|
+
# Build a new contact from the XML
|
29
|
+
result_contact = XeroGateway::Contact.from_xml(contact_element)
|
30
|
+
|
31
|
+
# Check the contact details
|
32
|
+
assert_equal contact, result_contact
|
33
|
+
end
|
34
|
+
|
35
|
+
# Test Contact#add_address helper creates a valid XeroGateway::Contact object with the passed in values
|
36
|
+
# and appends it to the Contact#addresses attribute.
|
37
|
+
def test_add_address_helper
|
38
|
+
contact = create_test_contact
|
39
|
+
assert_equal(1, contact.addresses.size)
|
40
|
+
|
41
|
+
new_values = {
|
42
|
+
:address_type => 'POBOX',
|
43
|
+
:line_1 => 'NEW LINE 1',
|
44
|
+
:line_2 => 'NEW LINE 2',
|
45
|
+
:line_3 => 'NEW LINE 3',
|
46
|
+
:line_4 => 'NEW LINE 4',
|
47
|
+
:city => 'NEW CITY',
|
48
|
+
:region => 'NEW REGION',
|
49
|
+
:post_code => '5555',
|
50
|
+
:country => 'Australia'
|
51
|
+
}
|
52
|
+
contact.add_address(new_values)
|
53
|
+
|
54
|
+
assert_equal(2, contact.addresses.size)
|
55
|
+
assert_kind_of(XeroGateway::Address, contact.addresses.last)
|
56
|
+
new_values.each { |k,v| assert_equal(v, contact.addresses.last.send("#{k}")) }
|
57
|
+
end
|
58
|
+
|
59
|
+
# Test Contact#add_phone helper creates a valid XeroGateway::Phone object with the passed in values
|
60
|
+
# and appends it to the Contact#phones attribute.
|
61
|
+
def test_add_address_helper
|
62
|
+
contact = create_test_contact
|
63
|
+
assert_equal(1, contact.phones.size)
|
64
|
+
|
65
|
+
new_values = {
|
66
|
+
:phone_type => 'MOBILE',
|
67
|
+
:country_code => '61',
|
68
|
+
:area_code => '406',
|
69
|
+
:number => '123456'
|
70
|
+
}
|
71
|
+
contact.add_phone(new_values)
|
72
|
+
|
73
|
+
assert_equal(2, contact.phones.size)
|
74
|
+
assert_kind_of(XeroGateway::Phone, contact.phones.last)
|
75
|
+
new_values.each { |k,v| assert_equal(v, contact.phones.last.send("#{k}")) }
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def create_test_contact
|
82
|
+
contact = XeroGateway::Contact.new(:contact_id => "55555")
|
83
|
+
contact.contact_number = "aaa111"
|
84
|
+
contact.name = "CONTACT NAME"
|
85
|
+
contact.email = "someone@somewhere.com"
|
86
|
+
contact.address.address_type = "THE ADDRESS TYPE FOR THE CONTACT"
|
87
|
+
contact.address.line_1 = "LINE 1 OF THE ADDRESS"
|
88
|
+
contact.address.line_2 = "LINE 2 OF THE ADDRESS"
|
89
|
+
contact.address.line_3 = "LINE 3 OF THE ADDRESS"
|
90
|
+
contact.address.line_4 = "LINE 4 OF THE ADDRESS"
|
91
|
+
contact.phone.number = "12345"
|
92
|
+
contact.is_customer = true
|
93
|
+
contact.is_supplier = true
|
94
|
+
|
95
|
+
contact
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,284 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../test_helper.rb')
|
2
|
+
|
3
|
+
class CreditNoteTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
# Tests that a credit note can be converted into XML that Xero can understand, and then converted back to a credit note
|
6
|
+
def test_build_and_parse_xml
|
7
|
+
credit_note = create_test_credit_note
|
8
|
+
|
9
|
+
# Generate the XML message
|
10
|
+
credit_note_as_xml = credit_note.to_xml
|
11
|
+
|
12
|
+
# Parse the XML message and retrieve the credit_note element
|
13
|
+
credit_note_element = REXML::XPath.first(REXML::Document.new(credit_note_as_xml), "/CreditNote")
|
14
|
+
|
15
|
+
# Build a new credit_note from the XML
|
16
|
+
result_credit_note = XeroGateway::CreditNote.from_xml(credit_note_element)
|
17
|
+
|
18
|
+
assert_equal(credit_note, result_credit_note)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Tests the sub_total calculation and that setting it manually doesn't modify the data.
|
22
|
+
def test_credit_note_sub_total_calculation
|
23
|
+
credit_note = create_test_credit_note
|
24
|
+
line_item = credit_note.line_items.first
|
25
|
+
|
26
|
+
# Make sure that everything adds up to begin with.
|
27
|
+
expected_sub_total = credit_note.line_items.inject(BigDecimal.new('0')) { | sum, line_item | line_item.line_amount }
|
28
|
+
assert_equal(expected_sub_total, credit_note.sub_total)
|
29
|
+
|
30
|
+
# Change the sub_total and check that it doesn't modify anything.
|
31
|
+
credit_note.sub_total = expected_sub_total * 10
|
32
|
+
assert_equal(expected_sub_total, credit_note.sub_total)
|
33
|
+
|
34
|
+
# Change the amount of the first line item and make sure that
|
35
|
+
# everything still continues to add up.
|
36
|
+
line_item.unit_amount = line_item.unit_amount + 10
|
37
|
+
assert_not_equal(expected_sub_total, credit_note.sub_total)
|
38
|
+
expected_sub_total = credit_note.line_items.inject(BigDecimal.new('0')) { | sum, line_item | line_item.line_amount }
|
39
|
+
assert_equal(expected_sub_total, credit_note.sub_total)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Tests the total_tax calculation and that setting it manually doesn't modify the data.
|
43
|
+
def test_credit_note_sub_total_calculation
|
44
|
+
credit_note = create_test_credit_note
|
45
|
+
line_item = credit_note.line_items.first
|
46
|
+
|
47
|
+
# Make sure that everything adds up to begin with.
|
48
|
+
expected_total_tax = credit_note.line_items.inject(BigDecimal.new('0')) { | sum, line_item | line_item.tax_amount }
|
49
|
+
assert_equal(expected_total_tax, credit_note.total_tax)
|
50
|
+
|
51
|
+
# Change the total_tax and check that it doesn't modify anything.
|
52
|
+
credit_note.total_tax = expected_total_tax * 10
|
53
|
+
assert_equal(expected_total_tax, credit_note.total_tax)
|
54
|
+
|
55
|
+
# Change the tax_amount of the first line item and make sure that
|
56
|
+
# everything still continues to add up.
|
57
|
+
line_item.tax_amount = line_item.tax_amount + 10
|
58
|
+
assert_not_equal(expected_total_tax, credit_note.total_tax)
|
59
|
+
expected_total_tax = credit_note.line_items.inject(BigDecimal.new('0')) { | sum, line_item | line_item.tax_amount }
|
60
|
+
assert_equal(expected_total_tax, credit_note.total_tax)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Tests the total calculation and that setting it manually doesn't modify the data.
|
64
|
+
def test_credit_note_sub_total_calculation
|
65
|
+
credit_note = create_test_credit_note
|
66
|
+
line_item = credit_note.line_items.first
|
67
|
+
|
68
|
+
# Make sure that everything adds up to begin with.
|
69
|
+
expected_total = credit_note.sub_total + credit_note.total_tax
|
70
|
+
assert_equal(expected_total, credit_note.total)
|
71
|
+
|
72
|
+
# Change the total and check that it doesn't modify anything.
|
73
|
+
credit_note.total = expected_total * 10
|
74
|
+
assert_equal(expected_total, credit_note.total)
|
75
|
+
|
76
|
+
# Change the quantity of the first line item and make sure that
|
77
|
+
# everything still continues to add up.
|
78
|
+
line_item.quantity = line_item.quantity + 5
|
79
|
+
assert_not_equal(expected_total, credit_note.total)
|
80
|
+
expected_total = credit_note.sub_total + credit_note.total_tax
|
81
|
+
assert_equal(expected_total, credit_note.total)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Tests that the LineItem#line_amount calculation is working correctly.
|
85
|
+
def test_line_amount_calculation
|
86
|
+
credit_note = create_test_credit_note
|
87
|
+
line_item = credit_note.line_items.first
|
88
|
+
|
89
|
+
# Make sure that everything adds up to begin with.
|
90
|
+
expected_amount = line_item.quantity * line_item.unit_amount
|
91
|
+
assert_equal(expected_amount, line_item.line_amount)
|
92
|
+
|
93
|
+
# Change the line_amount and check that it doesn't modify anything.
|
94
|
+
line_item.line_amount = expected_amount * 10
|
95
|
+
assert_equal(expected_amount, line_item.line_amount)
|
96
|
+
|
97
|
+
# Change the quantity and check that the line_amount has been updated.
|
98
|
+
quantity = line_item.quantity + 2
|
99
|
+
line_item.quantity = quantity
|
100
|
+
assert_not_equal(expected_amount, line_item.line_amount)
|
101
|
+
assert_equal(quantity * line_item.unit_amount, line_item.line_amount)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Ensure that the totalling methods don't raise exceptions, even when
|
105
|
+
# credit_note.line_items is empty.
|
106
|
+
def test_totalling_methods_when_line_items_empty
|
107
|
+
credit_note = create_test_credit_note
|
108
|
+
credit_note.line_items = []
|
109
|
+
|
110
|
+
assert_nothing_raised(Exception) {
|
111
|
+
assert_equal(BigDecimal.new('0'), credit_note.sub_total)
|
112
|
+
assert_equal(BigDecimal.new('0'), credit_note.total_tax)
|
113
|
+
assert_equal(BigDecimal.new('0'), credit_note.total)
|
114
|
+
}
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_type_helper_methods
|
118
|
+
# Test accounts receivable credit_notes.
|
119
|
+
credit_note = create_test_credit_note({:type => 'ACCRECCREDIT'})
|
120
|
+
assert_equal(true, credit_note.accounts_receivable?, "Accounts RECEIVABLE credit_note doesn't think it is.")
|
121
|
+
assert_equal(false, credit_note.accounts_payable?, "Accounts RECEIVABLE credit_note thinks it's payable.")
|
122
|
+
|
123
|
+
# Test accounts payable credit_notes.
|
124
|
+
credit_note = create_test_credit_note({:type => 'ACCPAYCREDIT'})
|
125
|
+
assert_equal(false, credit_note.accounts_receivable?, "Accounts PAYABLE credit_note doesn't think it is.")
|
126
|
+
assert_equal(true, credit_note.accounts_payable?, "Accounts PAYABLE credit_note thinks it's receivable.")
|
127
|
+
end
|
128
|
+
|
129
|
+
|
130
|
+
# Make sure that the create_test_credit_note method is working correctly
|
131
|
+
# with all the defaults and overrides.
|
132
|
+
def test_create_test_credit_note_defaults_working
|
133
|
+
credit_note = create_test_credit_note
|
134
|
+
|
135
|
+
# Test credit_note defaults.
|
136
|
+
assert_equal('ACCRECCREDIT', credit_note.type)
|
137
|
+
assert_kind_of(Date, credit_note.date)
|
138
|
+
assert_equal('12345', credit_note.credit_note_number)
|
139
|
+
assert_equal('MY REFERENCE FOR THIS CREDIT NOTE', credit_note.reference)
|
140
|
+
assert_equal("Exclusive", credit_note.line_amount_types)
|
141
|
+
|
142
|
+
# Test the contact defaults.
|
143
|
+
assert_equal('00000000-0000-0000-0000-000000000000', credit_note.contact.contact_id)
|
144
|
+
assert_equal('CONTACT NAME', credit_note.contact.name)
|
145
|
+
|
146
|
+
# Test address defaults.
|
147
|
+
assert_equal('DEFAULT', credit_note.contact.address.address_type)
|
148
|
+
assert_equal('LINE 1 OF THE ADDRESS', credit_note.contact.address.line_1)
|
149
|
+
|
150
|
+
# Test phone defaults.
|
151
|
+
assert_equal('DEFAULT', credit_note.contact.phone.phone_type)
|
152
|
+
assert_equal('12345678', credit_note.contact.phone.number)
|
153
|
+
|
154
|
+
# Test the line_item defaults.
|
155
|
+
assert_equal('A LINE ITEM', credit_note.line_items.first.description)
|
156
|
+
assert_equal('200', credit_note.line_items.first.account_code)
|
157
|
+
assert_equal(BigDecimal.new('100'), credit_note.line_items.first.unit_amount)
|
158
|
+
assert_equal(BigDecimal.new('12.5'), credit_note.line_items.first.tax_amount)
|
159
|
+
|
160
|
+
# Test overriding an credit_note parameter (assume works for all).
|
161
|
+
credit_note = create_test_credit_note({:type => 'ACCPAYCREDIT'})
|
162
|
+
assert_equal('ACCPAYCREDIT', credit_note.type)
|
163
|
+
|
164
|
+
# Test overriding a contact/address/phone parameter (assume works for all).
|
165
|
+
credit_note = create_test_credit_note({}, {:name => 'OVERRIDDEN NAME', :address => {:line_1 => 'OVERRIDDEN LINE 1'}, :phone => {:number => '999'}})
|
166
|
+
assert_equal('OVERRIDDEN NAME', credit_note.contact.name)
|
167
|
+
assert_equal('OVERRIDDEN LINE 1', credit_note.contact.address.line_1)
|
168
|
+
assert_equal('999', credit_note.contact.phone.number)
|
169
|
+
|
170
|
+
# Test overriding line_items with hash.
|
171
|
+
credit_note = create_test_credit_note({}, {}, {:description => 'OVERRIDDEN LINE ITEM'})
|
172
|
+
assert_equal(1, credit_note.line_items.size)
|
173
|
+
assert_equal('OVERRIDDEN LINE ITEM', credit_note.line_items.first.description)
|
174
|
+
assert_equal(BigDecimal.new('100'), credit_note.line_items.first.unit_amount)
|
175
|
+
|
176
|
+
# Test overriding line_items with array of 2 line_items.
|
177
|
+
credit_note = create_test_credit_note({}, {}, [
|
178
|
+
{:description => 'OVERRIDDEN ITEM 1'},
|
179
|
+
{:description => 'OVERRIDDEN ITEM 2', :account_code => '200', :unit_amount => BigDecimal.new('200'), :tax_amount => '25.0'}
|
180
|
+
])
|
181
|
+
assert_equal(2, credit_note.line_items.size)
|
182
|
+
assert_equal('OVERRIDDEN ITEM 1', credit_note.line_items[0].description)
|
183
|
+
assert_equal(BigDecimal.new('100'), credit_note.line_items[0].unit_amount)
|
184
|
+
assert_equal('OVERRIDDEN ITEM 2', credit_note.line_items[1].description)
|
185
|
+
assert_equal(BigDecimal.new('200'), credit_note.line_items[1].unit_amount)
|
186
|
+
end
|
187
|
+
|
188
|
+
def test_auto_creation_of_associated_contact
|
189
|
+
credit_note = create_test_credit_note({}, nil) # no contact
|
190
|
+
assert_nil(credit_note.instance_variable_get("@contact"))
|
191
|
+
|
192
|
+
new_contact = credit_note.contact
|
193
|
+
assert_kind_of(XeroGateway::Contact, new_contact)
|
194
|
+
end
|
195
|
+
|
196
|
+
def test_add_line_item
|
197
|
+
credit_note = create_test_credit_note({}, {}, nil) # no line_items
|
198
|
+
assert_equal(0, credit_note.line_items.size)
|
199
|
+
|
200
|
+
line_item_params = {:description => "Test Item 1", :unit_amount => 100}
|
201
|
+
|
202
|
+
# Test adding line item by hash
|
203
|
+
line_item = credit_note.add_line_item(line_item_params)
|
204
|
+
assert_kind_of(XeroGateway::LineItem, line_item)
|
205
|
+
assert_equal(line_item_params[:description], line_item.description)
|
206
|
+
assert_equal(line_item_params[:unit_amount], line_item.unit_amount)
|
207
|
+
assert_equal(1, credit_note.line_items.size)
|
208
|
+
|
209
|
+
# Test adding line item by XeroGateway::LineItem
|
210
|
+
line_item = credit_note.add_line_item(line_item_params)
|
211
|
+
assert_kind_of(XeroGateway::LineItem, line_item)
|
212
|
+
assert_equal(line_item_params[:description], line_item.description)
|
213
|
+
assert_equal(line_item_params[:unit_amount], line_item.unit_amount)
|
214
|
+
assert_equal(2, credit_note.line_items.size)
|
215
|
+
|
216
|
+
# Test that pushing anything else into add_line_item fails.
|
217
|
+
["invalid", 100, nil, []].each do | invalid_object |
|
218
|
+
assert_raise(XeroGateway::CreditNote::InvalidLineItemError) { credit_note.add_line_item(invalid_object) }
|
219
|
+
assert_equal(2, credit_note.line_items.size)
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
private
|
224
|
+
|
225
|
+
def create_test_credit_note(credit_note_params = {}, contact_params = {}, line_item_params = [])
|
226
|
+
unless credit_note_params.nil?
|
227
|
+
credit_note_params = {
|
228
|
+
:type => 'ACCRECCREDIT',
|
229
|
+
:date => Date.today,
|
230
|
+
:credit_note_number => '12345',
|
231
|
+
:reference => "MY REFERENCE FOR THIS CREDIT NOTE",
|
232
|
+
:line_amount_types => "Exclusive"
|
233
|
+
}.merge(credit_note_params)
|
234
|
+
end
|
235
|
+
credit_note = XeroGateway::CreditNote.new(credit_note_params || {})
|
236
|
+
|
237
|
+
unless contact_params.nil?
|
238
|
+
# Strip out :address key from contact_params to use as the default address.
|
239
|
+
stripped_address = {
|
240
|
+
:address_type => 'DEFAULT',
|
241
|
+
:line_1 => 'LINE 1 OF THE ADDRESS'
|
242
|
+
}.merge(contact_params.delete(:address) || {})
|
243
|
+
|
244
|
+
# Strip out :phone key from contact_params to use at the default phone.
|
245
|
+
stripped_phone = {
|
246
|
+
:phone_type => 'DEFAULT',
|
247
|
+
:number => '12345678'
|
248
|
+
}.merge(contact_params.delete(:phone) || {})
|
249
|
+
|
250
|
+
contact_params = {
|
251
|
+
:contact_id => '00000000-0000-0000-0000-000000000000', # Just any valid GUID
|
252
|
+
:name => "CONTACT NAME",
|
253
|
+
:first_name => "Bob",
|
254
|
+
:last_name => "Builder"
|
255
|
+
}.merge(contact_params)
|
256
|
+
|
257
|
+
# Create credit_note.contact from contact_params.
|
258
|
+
credit_note.contact = XeroGateway::Contact.new(contact_params)
|
259
|
+
credit_note.contact.address = XeroGateway::Address.new(stripped_address)
|
260
|
+
credit_note.contact.phone = XeroGateway::Phone.new(stripped_phone)
|
261
|
+
end
|
262
|
+
|
263
|
+
unless line_item_params.nil?
|
264
|
+
line_item_params = [line_item_params].flatten # always use an array, even if only a single hash passed in
|
265
|
+
|
266
|
+
# At least one line item, make first have some defaults.
|
267
|
+
line_item_params << {} if line_item_params.size == 0
|
268
|
+
line_item_params[0] = {
|
269
|
+
:description => "A LINE ITEM",
|
270
|
+
:account_code => "200",
|
271
|
+
:unit_amount => BigDecimal.new("100"),
|
272
|
+
:tax_amount => BigDecimal.new("12.5"),
|
273
|
+
:tracking => XeroGateway::TrackingCategory.new(:name => "blah", :options => "hello")
|
274
|
+
}.merge(line_item_params[0])
|
275
|
+
|
276
|
+
# Create credit_note.line_items from line_item_params
|
277
|
+
line_item_params.each do | line_item |
|
278
|
+
credit_note.add_line_item(line_item)
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
credit_note
|
283
|
+
end
|
284
|
+
end
|