xero_gateway-float 2.0.15
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.
- 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
|