tlconnor-xero_gateway 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,30 @@
1
+ # Copyright (c) 2008 Tim Connor <tlconnor@gmail.com>
2
+ #
3
+ # Permission to use, copy, modify, and/or distribute this software for any
4
+ # purpose with or without fee is hereby granted, provided that the above
5
+ # copyright notice and this permission notice appear in all copies.
6
+ #
7
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
+
15
+ module XeroGateway
16
+ module Money
17
+ def self.included(base)
18
+ base.extend(ClassMethods)
19
+ end
20
+
21
+ module ClassMethods
22
+ def format_money(amount)
23
+ if amount.class == BigDecimal
24
+ return amount.to_s("F")
25
+ end
26
+ return amount
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,38 @@
1
+ # Copyright (c) 2008 Tim Connor <tlconnor@gmail.com>
2
+ #
3
+ # Permission to use, copy, modify, and/or distribute this software for any
4
+ # purpose with or without fee is hereby granted, provided that the above
5
+ # copyright notice and this permission notice appear in all copies.
6
+ #
7
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
+
15
+ module XeroGateway
16
+ class Phone
17
+ attr_accessor :phone_type, :number, :area_code, :country_code
18
+
19
+ def initialize(params = {})
20
+ params = {
21
+ :phone_type => "DEFAULT"
22
+ }.merge(params)
23
+
24
+ params.each do |k,v|
25
+ self.instance_variable_set("@#{k}", v) ## create and initialize an instance variable for this key/value pair
26
+ self.send("#{k}=", v)
27
+ end
28
+ end
29
+
30
+ def ==(other)
31
+ equal = true
32
+ [:phone_type, :number, :area_code, :country_code].each do |field|
33
+ equal &&= (send(field) == other.send(field))
34
+ end
35
+ return equal
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,44 @@
1
+ # Copyright (c) 2008 Tim Connor <tlconnor@gmail.com>
2
+ #
3
+ # Permission to use, copy, modify, and/or distribute this software for any
4
+ # purpose with or without fee is hereby granted, provided that the above
5
+ # copyright notice and this permission notice appear in all copies.
6
+ #
7
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
+
15
+ module XeroGateway
16
+ class Response
17
+ attr_accessor :id, :status, :errors, :provider, :date_time, :response_item, :request_params, :request_xml, :response_xml
18
+
19
+ alias_method :invoice, :response_item
20
+ alias_method :invoices, :response_item
21
+ alias_method :contact, :response_item
22
+ alias_method :contacts, :response_item
23
+ alias_method :accounts, :response_item
24
+
25
+
26
+
27
+ def initialize(params = {})
28
+ params.each do |k,v|
29
+ self.instance_variable_set("@#{k}", v) ## create and initialize an instance variable for this key/value pair
30
+ self.send("#{k}=", v)
31
+ end
32
+
33
+ @errors ||= []
34
+ end
35
+
36
+ def success?
37
+ status == "OK"
38
+ end
39
+
40
+ def error
41
+ errors.blank? ? nil : errors[0]
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,166 @@
1
+ # Copyright (c) 2008 Tim Connor <tlconnor@gmail.com>
2
+ #
3
+ # Permission to use, copy, modify, and/or distribute this software for any
4
+ # purpose with or without fee is hereby granted, provided that the above
5
+ # copyright notice and this permission notice appear in all copies.
6
+ #
7
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
+
15
+ require File.dirname(__FILE__) + '/../test_helper'
16
+
17
+ class GatewayTest < Test::Unit::TestCase
18
+ # If false, the tests will be run against the Xero test environment
19
+ STUB_XERO_CALLS = true
20
+
21
+ # If the requests are not stubbed, enter your API key and you test company customer key here
22
+ API_KEY = "OWFKZTA4YZNHYWNKNDDJM2JKNZQWOW"
23
+ CUSTOMER_KEY = "YWZIMZQ3ZGVJMME1NDCWNTK3YWZMNW"
24
+
25
+
26
+ def setup
27
+ @gateway = XeroGateway::Gateway.new(
28
+ :customer_key => CUSTOMER_KEY,
29
+ :api_key => API_KEY
30
+ )
31
+
32
+ if STUB_XERO_CALLS
33
+ @gateway.xero_url = "DUMMY_URL"
34
+ # Stub out the HTTP request
35
+ @gateway.stubs(:http_get).with {|url, params| url =~ /contact$/ }.returns(get_file_as_string("contact.xml"))
36
+ @gateway.stubs(:http_get).with {|url, params| url =~ /contacts$/ }.returns(get_file_as_string("contacts.xml"))
37
+ @gateway.stubs(:http_get).with {|url, params| url =~ /invoice$/ }.returns(get_file_as_string("invoice.xml"))
38
+ @gateway.stubs(:http_get).with {|url, params| url =~ /invoices$/ }.returns(get_file_as_string("invoices.xml"))
39
+ @gateway.stubs(:http_get).with {|url, params| url =~ /accounts$/ }.returns(get_file_as_string("accounts.xml"))
40
+ @gateway.stubs(:http_put).with {|url, body, params| url =~ /invoice$/ }.returns(get_file_as_string("invoice.xml"))
41
+ @gateway.stubs(:http_put).with {|url, body, params| url =~ /contact$/ }.returns(get_file_as_string("contact.xml"))
42
+
43
+
44
+ end
45
+ end
46
+
47
+ def dummy_invoice
48
+ invoice = XeroGateway::Invoice.new({
49
+ :invoice_type => "ACCREC",
50
+ :due_date => Date.today + 20,
51
+ :invoice_number => STUB_XERO_CALLS ? "INV-0001" : "#{Time.now.to_i}",
52
+ :reference => "YOUR REFERENCE (NOT NECESSARILY UNIQUE!)",
53
+ :sub_total => 1000,
54
+ :total_tax => 125,
55
+ :total => 1125
56
+ })
57
+ invoice.contact = dummy_contact
58
+ invoice.line_items << XeroGateway::LineItem.new(
59
+ :description => "THE DESCRIPTION OF THE LINE ITEM",
60
+ :unit_amount => 1000,
61
+ :tax_amount => 125,
62
+ :line_amount => 1000,
63
+ :tracking_category => "THE TRACKING CATEGORY FOR THE LINE ITEM",
64
+ :tracking_option => "THE TRACKING OPTION FOR THE LINE ITEM"
65
+ )
66
+ invoice
67
+ end
68
+
69
+ def dummy_contact
70
+ contact = XeroGateway::Contact.new(:name => STUB_XERO_CALLS ? "CONTACT NAME" : "THE NAME OF THE CONTACT #{Time.now.to_i}")
71
+ contact.contact_number = STUB_XERO_CALLS ? "12345" : "#{Time.now.to_i}"
72
+ contact.email = "whoever@something.com"
73
+ contact.phone.number = "12345"
74
+ contact.address.line_1 = "LINE 1 OF THE ADDRESS"
75
+ contact.address.line_2 = "LINE 2 OF THE ADDRESS"
76
+ contact.address.line_3 = "LINE 3 OF THE ADDRESS"
77
+ contact.address.line_4 = "LINE 4 OF THE ADDRESS"
78
+ contact.address.city = "WELLINGTON"
79
+ contact.address.region = "WELLINGTON"
80
+ contact.address.country = "NEW ZEALAND"
81
+ contact.address.post_code = "6021"
82
+
83
+ contact
84
+ end
85
+
86
+ def get_file_as_string(filename)
87
+ data = ''
88
+ f = File.open(File.dirname(__FILE__) + "/stub_responses/" + filename, "r")
89
+ f.each_line do |line|
90
+ data += line
91
+ end
92
+ f.close
93
+ return data
94
+ end
95
+
96
+ def test_create_and_get_contact
97
+ contact = dummy_contact
98
+
99
+ create_contact_result = @gateway.create_contact(contact)
100
+ assert create_contact_result.success?
101
+
102
+ contact_from_create_request = create_contact_result.contact
103
+ assert contact_from_create_request.name == contact.name
104
+
105
+ get_contact_by_id_result = @gateway.get_contact_by_id(contact_from_create_request.id)
106
+ assert get_contact_by_id_result.success?
107
+ assert get_contact_by_id_result.contact.name == contact.name
108
+
109
+ get_contact_by_number_result = @gateway.get_contact_by_number(contact.contact_number)
110
+ assert get_contact_by_number_result.success?
111
+ assert get_contact_by_number_result.contact.name == contact.name
112
+ end
113
+
114
+ def test_create_and_get_invoice
115
+ invoice = dummy_invoice
116
+
117
+ result = @gateway.create_invoice(invoice)
118
+ assert result.success?
119
+
120
+ invoice_from_create_request = result.invoice
121
+ assert invoice_from_create_request.invoice_number == invoice.invoice_number
122
+
123
+ result = @gateway.get_invoice_by_id(invoice_from_create_request.id)
124
+ assert result.success?
125
+ assert result.invoice.invoice_number == invoice_from_create_request.invoice_number
126
+
127
+ result = @gateway.get_invoice_by_number(invoice_from_create_request.invoice_number)
128
+ assert result.success?
129
+ assert result.invoice.id == invoice_from_create_request.id
130
+ end
131
+
132
+ def test_get_contacts
133
+ result = @gateway.get_contacts
134
+ assert result.success?
135
+ assert result.contacts.size > 0
136
+ end
137
+
138
+ def test_get_invoices
139
+ # Create a test invoice
140
+ invoice = dummy_invoice
141
+ @gateway.create_invoice(invoice)
142
+
143
+ # Check that it is returned
144
+ result = @gateway.get_invoices
145
+ assert result.success?
146
+ assert result.invoices.collect {|response_invoice| response_invoice.invoice_number}.include?(invoice.invoice_number)
147
+ end
148
+
149
+ def test_get_invoices_with_modified_since_date
150
+ # Create a test invoice
151
+ invoice = dummy_invoice
152
+ @gateway.create_invoice(invoice)
153
+
154
+ # Check that it is returned
155
+ result = @gateway.get_invoices(Date.today - 1)
156
+ assert result.success?
157
+ assert result.invoices.collect {|response_invoice| response_invoice.invoice_number}.include?(invoice.invoice_number)
158
+ end
159
+
160
+ def test_get_accounts
161
+ result = @gateway.get_accounts
162
+ assert result.success?
163
+ assert result.accounts.size > 0
164
+ assert_equal XeroGateway::Account, result.accounts.first.class
165
+ end
166
+ end
@@ -0,0 +1 @@
1
+ <?xml version="1.0"?><Response xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><ID>cf37ba46-29a7-4824-ad63-43482463afed</ID><Status>OK</Status><ProviderName>WebStock</ProviderName><DateTimeUTC>2008-12-01T08:39:54.70175Z</DateTimeUTC><Accounts><Account><Code>200</Code><Name>Sales</Name><Type>REVENUE</Type><TaxType>OUTPUT</TaxType><Description>Income from any normal business activity</Description></Account><Account><Code>260</Code><Name>Other Revenue</Name><Type>REVENUE</Type><TaxType>OUTPUT</TaxType><Description>Any other income that does not relate to normal business activities and is not recurring</Description></Account><Account><Code>270</Code><Name>Interest Income</Name><Type>REVENUE</Type><TaxType>NONE</TaxType><Description>Gross interest income (i.e. before deducting Residential Withholding Tax), such as bank interest</Description></Account><Account><Code>400</Code><Name>Advertising</Name><Type>OVERHEADS</Type><TaxType>INPUT</TaxType><Description>Expenses incurred for advertising while trying to increase sales</Description></Account><Account><Code>404</Code><Name>Bank Fees</Name><Type>OVERHEADS</Type><TaxType>NONE</TaxType><Description>Fees charged by your bank for transactions regarding your bank account(s).</Description></Account><Account><Code>408</Code><Name>Cleaning</Name><Type>OVERHEADS</Type><TaxType>INPUT</TaxType><Description>Expenses incurred for cleaning business property.</Description></Account><Account><Code>412</Code><Name>Consulting &amp; Accounting</Name><Type>OVERHEADS</Type><TaxType>INPUT</TaxType><Description>Expenses related to paying consultants</Description></Account><Account><Code>416</Code><Name>Depreciation</Name><Type>OVERHEADS</Type><TaxType>NONE</TaxType><Description>The amount of the asset's cost (based on the useful life) that was consumed during the period</Description></Account><Account><Code>420</Code><Name>Entertainment</Name><Type>OVERHEADS</Type><TaxType>INPUT</TaxType><Description>50% of the total expense relating to business-related entertainment. E.g. shouting clients or employees a drink or a meal etc.</Description></Account><Account><Code>424</Code><Name>Entertainment - Non deductible</Name><Type>OVERHEADS</Type><TaxType>NONE</TaxType><Description>Expenses paid by company for the business but are not deductable for income tax purposes.</Description></Account><Account><Code>425</Code><Name>Freight &amp; Courier</Name><Type>OVERHEADS</Type><TaxType>INPUT</TaxType><Description>Expenses incurred on courier &amp; freight costs</Description></Account><Account><Code>429</Code><Name>General Expenses</Name><Type>OVERHEADS</Type><TaxType>INPUT</TaxType><Description>General expenses related to the running of the business.</Description></Account><Account><Code>433</Code><Name>Insurance</Name><Type>OVERHEADS</Type><TaxType>INPUT</TaxType><Description>Expenses incurred for insuring the business' assets</Description></Account><Account><Code>437</Code><Name>Interest Expense</Name><Type>OVERHEADS</Type><TaxType>NONE</TaxType><Description>Any interest expenses paid to IRD, business bank accounts or credit card accounts.</Description></Account><Account><Code>441</Code><Name>Legal expenses</Name><Type>OVERHEADS</Type><TaxType>INPUT</TaxType><Description>Expenses incurred on any legal matters</Description></Account><Account><Code>445</Code><Name>Light, Power, Heating</Name><Type>OVERHEADS</Type><TaxType>INPUT</TaxType><Description>Expenses incurred for lighting, powering or heating the premises</Description></Account><Account><Code>449</Code><Name>Motor Vehicle Expenses</Name><Type>OVERHEADS</Type><TaxType>INPUT</TaxType><Description>Expenses incurred on the running of company motor vehicles</Description></Account><Account><Code>453</Code><Name>Office Expenses</Name><Type>OVERHEADS</Type><TaxType>INPUT</TaxType><Description>General expenses related to the running of the business office.</Description></Account><Account><Code>461</Code><Name>Printing &amp; Stationery</Name><Type>OVERHEADS</Type><TaxType>INPUT</TaxType><Description>Expenses incurred by the entity as a result of printing and stationery</Description></Account><Account><Code>469</Code><Name>Rent</Name><Type>OVERHEADS</Type><TaxType>INPUT</TaxType><Description>The payment to lease a building or area.</Description></Account><Account><Code>473</Code><Name>Repairs and Maintenance</Name><Type>OVERHEADS</Type><TaxType>INPUT</TaxType><Description>Expenses incurred on a damaged or run down asset that will bring the asset back to its original condition.</Description></Account><Account><Code>477</Code><Name>Salaries</Name><Type>OVERHEADS</Type><TaxType>NONE</TaxType><Description>Payment to employees in exchange for their resources</Description></Account><Account><Code>478</Code><Name>KiwiSaver Employer Contributions</Name><Type>OVERHEADS</Type><TaxType>NONE</TaxType><Description>KiwiSaver employer contributions</Description></Account><Account><Code>485</Code><Name>Subscriptions</Name><Type>OVERHEADS</Type><TaxType>INPUT</TaxType><Description>E.g. Magazines, professional bodies.</Description></Account><Account><Code>489</Code><Name>Telephone &amp; Internet</Name><Type>OVERHEADS</Type><TaxType>INPUT</TaxType><Description>Expenditure incurred from any business-related phone calls, phone lines, or internet connections</Description></Account><Account><Code>493</Code><Name>Travel - National</Name><Type>OVERHEADS</Type><TaxType>INPUT</TaxType><Description>Expenses incurred from domestic travel which has a business purpose</Description></Account><Account><Code>494</Code><Name>Travel - International</Name><Type>OVERHEADS</Type><TaxType>NONE</TaxType><Description>Expenses incurred from international travel which has a business purpose</Description></Account><Account><Code>505</Code><Name>Income Tax Expense</Name><Type>EXPENSE</Type><TaxType>NONE</TaxType><Description>A percentage of total earnings paid to the government.</Description></Account><Account><Code>610</Code><Name>Accounts Receivable</Name><Type>CURRENT</Type><TaxType>NONE</TaxType><Description>Outstanding invoices the company has issued out to the client but has not yet received in cash at balance date.</Description></Account><Account><Code>611</Code><Name>less Provision for Doubtful Debts</Name><Type>CURRENT</Type><TaxType>NONE</TaxType><Description>A provision anticipating that some of the accounts receivables will become bad debts.</Description></Account><Account><Code>620</Code><Name>Prepayments</Name><Type>CURRENT</Type><TaxType>NONE</TaxType><Description>An expenditure that has been paid for in advance.</Description></Account><Account><Code>625</Code><Name>Withholding tax paid</Name><Type>CURRENT</Type><TaxType>NONE</TaxType><Description>Withholding tax paid</Description></Account><Account><Code>710</Code><Name>Office Equipment</Name><Type>FIXED</Type><TaxType>INPUT</TaxType><Description>Office equipment that is owned and controlled by the business</Description></Account><Account><Code>711</Code><Name>Less Accumulated Depreciation on Office Equipment</Name><Type>FIXED</Type><TaxType>NONE</TaxType><Description>The total amount of office equipment cost that has been consumed by the entity (based on the useful life)</Description></Account><Account><Code>720</Code><Name>Computer Equipment</Name><Type>FIXED</Type><TaxType>INPUT</TaxType><Description>Computer equipment that is owned and controlled by the business</Description></Account><Account><Code>721</Code><Name>Less Accumulated Depreciation on Computer Equipment</Name><Type>FIXED</Type><TaxType>NONE</TaxType><Description>The total amount of computer equipment cost that has been consumed by the business (based on the useful life)</Description></Account><Account><Code>800</Code><Name>Accounts Payable</Name><Type>CURRLIAB</Type><TaxType>NONE</TaxType><Description>Outstanding invoices the company has received from suppliers but has not yet paid at balance date</Description></Account><Account><Code>801</Code><Name>Unpaid Expense Claims</Name><Type>CURRLIAB</Type><TaxType>NONE</TaxType><Description>Expense claims typically made by employees/shareholder employees still outstanding.</Description></Account><Account><Code>820</Code><Name>GST</Name><Type>CURRLIAB</Type><TaxType>NONE</TaxType><Description>The balance in this account represents GST owing to or from the IRD. At the end of the GST period, it is this account that should be used to code against either the 'refunds from' or 'payments to' the IRD that will appear on the bank statement. Xero has been designed to use only one GST account to track GST on income and expenses, so there is no need to add any new GST accounts to Xero.</Description></Account><Account><Code>821</Code><Name>GST On Imports</Name><Type>CURRLIAB</Type><TaxType>NONE</TaxType><Description>GST paid to customs.</Description></Account><Account><Code>825</Code><Name>PAYE Payable</Name><Type>CURRLIAB</Type><TaxType>NONE</TaxType><Description>The amount of PAYE tax that is due to be paid</Description></Account><Account><Code>830</Code><Name>Income Tax</Name><Type>CURRLIAB</Type><TaxType>NONE</TaxType><Description>The amount of income tax that is due to be paid, also resident withholding tax paid on interest received.</Description></Account><Account><Code>840</Code><Name>Historical Adjustment</Name><Type>CURRLIAB</Type><TaxType>NONE</TaxType><Description>For accountant adjustments</Description></Account><Account><Code>850</Code><Name>Suspense</Name><Type>CURRLIAB</Type><TaxType>NONE</TaxType><Description>An entry that allows an unknown transaction to be entered, so the accounts can still be worked on in balance and the entry can be dealt with later.</Description></Account><Account><Code>860</Code><Name>Rounding</Name><Type>CURRLIAB</Type><TaxType>NONE</TaxType><Description>An adjustment entry to allow for rounding</Description></Account><Account><Code>877</Code><Name>Tracking Transfers</Name><Type>CURRLIAB</Type><TaxType>NONE</TaxType><Description>Transfers between tracking categories</Description></Account><Account><Code>900</Code><Name>Loan</Name><Type>TERMLIAB</Type><TaxType>NONE</TaxType><Description>Money that has been borrowed from a creditor</Description></Account><Account><Code>960</Code><Name>Retained Earnings</Name><Type>EQUITY</Type><TaxType>NONE</TaxType><Description>Do not Use</Description></Account><Account><Code>970</Code><Name>Owner A Funds Introduced</Name><Type>EQUITY</Type><TaxType>NONE</TaxType><Description>Funds contributed by the owner</Description></Account><Account><Code>980</Code><Name>Owner A Drawings</Name><Type>EQUITY</Type><TaxType>NONE</TaxType><Description>Withdrawals by the owners</Description></Account></Accounts></Response>
@@ -0,0 +1 @@
1
+ <?xml version="1.0"?><Response xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><ID>a99a9aaa-9999-99a9-9aa9-aaaaaa9a9999</ID><Status>OK</Status><ProviderName>YOUR PROVIDER</ProviderName><DateTimeUTC>2008-10-09T02:40:54.3997437Z</DateTimeUTC><Contact><ContactID>a99a9aaa-9999-99a9-9aa9-aaaaaa9a9999</ContactID><ContactNumber>12345</ContactNumber><ContactStatus>ACTIVE</ContactStatus><Name>CONTACT NAME</Name><EmailAddress>bob@example.com</EmailAddress><Addresses><Address><AddressType>POBOX</AddressType><AddressLine1>LINE 1 OF THE ADDRESS</AddressLine1><AddressLine2/><AddressLine3/><AddressLine4/><City>Somewhere</City><Region/><PostalCode/><Country>Some Country</Country></Address></Addresses><Phones><Phone><PhoneType>MOBILE</PhoneType><PhoneNumber>1234567</PhoneNumber><PhoneAreaCode>123</PhoneAreaCode><PhoneCountryCode/></Phone><Phone><PhoneType>DEFAULT</PhoneType><PhoneNumber/><PhoneAreaCode/><PhoneCountryCode/></Phone><Phone><PhoneType>FAX</PhoneType><PhoneNumber/><PhoneAreaCode/><PhoneCountryCode/></Phone><Phone><PhoneType>DDI</PhoneType><PhoneNumber/><PhoneAreaCode/><PhoneCountryCode/></Phone></Phones></Contact></Response>
@@ -0,0 +1 @@
1
+ <?xml version="1.0"?><Response xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><ID>a99a9aaa-9999-99a9-9aa9-aaaaaa9a9999</ID><Status>OK</Status><ProviderName>YOUR PROVIDER</ProviderName><DateTimeUTC>2008-10-09T02:40:54.3997437Z</DateTimeUTC><Contacts><Contact><ContactID>a99a9aaa-9999-99a9-9aa9-aaaaaa9a9999</ContactID><ContactStatus>ACTIVE</ContactStatus><Name>CONTACT NAME</Name><EmailAddress>bob@example.com</EmailAddress><Addresses><Address><AddressType>POBOX</AddressType><AddressLine1>LINE 1 OF THE ADDRESS</AddressLine1><AddressLine2/><AddressLine3/><AddressLine4/><City>Somewhere</City><Region/><PostalCode/><Country>Some Country</Country></Address></Addresses><Phones><Phone><PhoneType>MOBILE</PhoneType><PhoneNumber>1234567</PhoneNumber><PhoneAreaCode>123</PhoneAreaCode><PhoneCountryCode/></Phone><Phone><PhoneType>DEFAULT</PhoneType><PhoneNumber/><PhoneAreaCode/><PhoneCountryCode/></Phone><Phone><PhoneType>FAX</PhoneType><PhoneNumber/><PhoneAreaCode/><PhoneCountryCode/></Phone><Phone><PhoneType>DDI</PhoneType><PhoneNumber/><PhoneAreaCode/><PhoneCountryCode/></Phone></Phones></Contact><Contact><ContactID>a99a9aaa-9999-99a9-9aa9-aaaaaa9a9999</ContactID><ContactStatus>ACTIVE</ContactStatus><Name>CONTACT NAME</Name><EmailAddress>bob@example.com</EmailAddress><Addresses><Address><AddressType>POBOX</AddressType><AddressLine1>LINE 1 OF THE ADDRESS</AddressLine1><AddressLine2/><AddressLine3/><AddressLine4/><City>Somewhere</City><Region/><PostalCode/><Country>Some Country</Country></Address></Addresses><Phones><Phone><PhoneType>MOBILE</PhoneType><PhoneNumber>1234567</PhoneNumber><PhoneAreaCode>123</PhoneAreaCode><PhoneCountryCode/></Phone><Phone><PhoneType>DEFAULT</PhoneType><PhoneNumber/><PhoneAreaCode/><PhoneCountryCode/></Phone><Phone><PhoneType>FAX</PhoneType><PhoneNumber/><PhoneAreaCode/><PhoneCountryCode/></Phone><Phone><PhoneType>DDI</PhoneType><PhoneNumber/><PhoneAreaCode/><PhoneCountryCode/></Phone></Phones></Contact><Contact><ContactID>a99a9aaa-9999-99a9-9aa9-aaaaaa9a9999</ContactID><ContactStatus>ACTIVE</ContactStatus><Name>CONTACT NAME</Name><EmailAddress>bob@example.com</EmailAddress><Addresses><Address><AddressType>POBOX</AddressType><AddressLine1>LINE 1 OF THE ADDRESS</AddressLine1><AddressLine2/><AddressLine3/><AddressLine4/><City>Somewhere</City><Region/><PostalCode/><Country>Some Country</Country></Address></Addresses><Phones><Phone><PhoneType>MOBILE</PhoneType><PhoneNumber>1234567</PhoneNumber><PhoneAreaCode>123</PhoneAreaCode><PhoneCountryCode/></Phone><Phone><PhoneType>DEFAULT</PhoneType><PhoneNumber/><PhoneAreaCode/><PhoneCountryCode/></Phone><Phone><PhoneType>FAX</PhoneType><PhoneNumber/><PhoneAreaCode/><PhoneCountryCode/></Phone><Phone><PhoneType>DDI</PhoneType><PhoneNumber/><PhoneAreaCode/><PhoneCountryCode/></Phone></Phones></Contact><Contact><ContactID>a99a9aaa-9999-99a9-9aa9-aaaaaa9a9999</ContactID><ContactStatus>ACTIVE</ContactStatus><Name>CONTACT NAME</Name><EmailAddress>bob@example.com</EmailAddress><Addresses><Address><AddressType>POBOX</AddressType><AddressLine1>LINE 1 OF THE ADDRESS</AddressLine1><AddressLine2/><AddressLine3/><AddressLine4/><City>Somewhere</City><Region/><PostalCode/><Country>Some Country</Country></Address></Addresses><Phones><Phone><PhoneType>MOBILE</PhoneType><PhoneNumber>1234567</PhoneNumber><PhoneAreaCode>123</PhoneAreaCode><PhoneCountryCode/></Phone><Phone><PhoneType>DEFAULT</PhoneType><PhoneNumber/><PhoneAreaCode/><PhoneCountryCode/></Phone><Phone><PhoneType>FAX</PhoneType><PhoneNumber/><PhoneAreaCode/><PhoneCountryCode/></Phone><Phone><PhoneType>DDI</PhoneType><PhoneNumber/><PhoneAreaCode/><PhoneCountryCode/></Phone></Phones></Contact><Contact><ContactID>a99a9aaa-9999-99a9-9aa9-aaaaaa9a9999</ContactID><ContactStatus>ACTIVE</ContactStatus><Name>CONTACT NAME</Name><EmailAddress>bob@example.com</EmailAddress><Addresses><Address><AddressType>POBOX</AddressType><AddressLine1>LINE 1 OF THE ADDRESS</AddressLine1><AddressLine2/><AddressLine3/><AddressLine4/><City>Somewhere</City><Region/><PostalCode/><Country>Some Country</Country></Address></Addresses><Phones><Phone><PhoneType>MOBILE</PhoneType><PhoneNumber>1234567</PhoneNumber><PhoneAreaCode>123</PhoneAreaCode><PhoneCountryCode/></Phone><Phone><PhoneType>DEFAULT</PhoneType><PhoneNumber/><PhoneAreaCode/><PhoneCountryCode/></Phone><Phone><PhoneType>FAX</PhoneType><PhoneNumber/><PhoneAreaCode/><PhoneCountryCode/></Phone><Phone><PhoneType>DDI</PhoneType><PhoneNumber/><PhoneAreaCode/><PhoneCountryCode/></Phone></Phones></Contact><Contact><ContactID>a99a9aaa-9999-99a9-9aa9-aaaaaa9a9999</ContactID><ContactStatus>ACTIVE</ContactStatus><Name>CONTACT NAME</Name><EmailAddress>bob@example.com</EmailAddress><Addresses><Address><AddressType>POBOX</AddressType><AddressLine1>LINE 1 OF THE ADDRESS</AddressLine1><AddressLine2/><AddressLine3/><AddressLine4/><City>Somewhere</City><Region/><PostalCode/><Country>Some Country</Country></Address></Addresses><Phones><Phone><PhoneType>MOBILE</PhoneType><PhoneNumber>1234567</PhoneNumber><PhoneAreaCode>123</PhoneAreaCode><PhoneCountryCode/></Phone><Phone><PhoneType>DEFAULT</PhoneType><PhoneNumber/><PhoneAreaCode/><PhoneCountryCode/></Phone><Phone><PhoneType>FAX</PhoneType><PhoneNumber/><PhoneAreaCode/><PhoneCountryCode/></Phone><Phone><PhoneType>DDI</PhoneType><PhoneNumber/><PhoneAreaCode/><PhoneCountryCode/></Phone></Phones></Contact></Contacts></Response>
@@ -0,0 +1 @@
1
+ <?xml version="1.0"?><Response xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><ID>a99a9aaa-9999-99a9-9aa9-aaaaaa9a9999</ID><Status>OK</Status><ProviderName>YOUR PROVIDER</ProviderName><DateTimeUTC>2008-10-09T00:59:11.1341229Z</DateTimeUTC><Invoice><InvoiceType>ACCREC</InvoiceType><InvoiceID>a99a9aaa-9999-99a9-9aa9-aaaaaa9a9999</InvoiceID><Contact><ContactID>a99a9aaa-9999-99a9-9aa9-aaaaaa9a9999</ContactID><ContactStatus>ACTIVE</ContactStatus><Name>CONTACT NAME</Name><EmailAddress>bob@example.com</EmailAddress><Addresses><Address><AddressType>POBOX</AddressType><AddressLine1>LINE 1 OF THE ADDRESS</AddressLine1><AddressLine2></AddressLine2><AddressLine3></AddressLine3><AddressLine4></AddressLine4><City>Somewhere</City><Region></Region><PostalCode></PostalCode><Country>Some Country</Country></Address></Addresses><Phones><Phone><PhoneType>MOBILE</PhoneType><PhoneNumber>1234567</PhoneNumber><PhoneAreaCode>123</PhoneAreaCode><PhoneCountryCode></PhoneCountryCode></Phone><Phone><PhoneType>DEFAULT</PhoneType><PhoneNumber></PhoneNumber><PhoneAreaCode></PhoneAreaCode><PhoneCountryCode></PhoneCountryCode></Phone><Phone><PhoneType>FAX</PhoneType><PhoneNumber></PhoneNumber><PhoneAreaCode></PhoneAreaCode><PhoneCountryCode></PhoneCountryCode></Phone><Phone><PhoneType>DDI</PhoneType><PhoneNumber></PhoneNumber><PhoneAreaCode></PhoneAreaCode><PhoneCountryCode></PhoneCountryCode></Phone></Phones></Contact><InvoiceDate>2008-10-03T00:00:00</InvoiceDate><DueDate>2008-10-20T00:00:00</DueDate><InvoiceNumber>INV-0001</InvoiceNumber><Reference></Reference><IncludesTax>true</IncludesTax><SubTotal>1000.0000</SubTotal><TotalTax>125.0000</TotalTax><Total>1125.0000</Total><InvoiceStatus>AUTHORISED</InvoiceStatus><LineItems><LineItem><LineItemID>e5a8a4ee-85ee-4532-a79f-a552ec63a0d7</LineItemID><Description>A LINE ITEM</Description><Quantity>100.0</Quantity><UnitAmount>12.34</UnitAmount><TaxType>OUTPUT</TaxType><TaxAmount>125.0000</TaxAmount><LineAmount>1125.0000</LineAmount><Tracking><TrackingCategory><Name>Region</Name><Option>Central</Option></TrackingCategory></Tracking></LineItem></LineItems></Invoice></Response>
@@ -0,0 +1 @@
1
+ <?xml version="1.0"?><Response xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><ID>a99a9aaa-9999-99a9-9aa9-aaaaaa9a9999</ID><Status>OK</Status><ProviderName>YOUR PROVIDER</ProviderName><DateTimeUTC>2008-10-09T00:59:11.1341229Z</DateTimeUTC><Invoices><Invoice><InvoiceType>ACCREC</InvoiceType><InvoiceID>a99a9aaa-9999-99a9-9aa9-aaaaaa9a9999</InvoiceID><Contact><ContactID>a99a9aaa-9999-99a9-9aa9-aaaaaa9a9999</ContactID><ContactStatus>ACTIVE</ContactStatus><Name>CONTACT NAME</Name><EmailAddress>bob@example.com</EmailAddress><Addresses><Address><AddressType>POBOX</AddressType><AddressLine1>LINE 1 OF THE ADDRESS</AddressLine1><AddressLine2/><AddressLine3/><AddressLine4/><City>Somewhere</City><Region/><PostalCode/><Country>Some Country</Country></Address></Addresses><Phones><Phone><PhoneType>MOBILE</PhoneType><PhoneNumber>1234567</PhoneNumber><PhoneAreaCode>123</PhoneAreaCode><PhoneCountryCode/></Phone><Phone><PhoneType>DEFAULT</PhoneType><PhoneNumber/><PhoneAreaCode/><PhoneCountryCode/></Phone><Phone><PhoneType>FAX</PhoneType><PhoneNumber/><PhoneAreaCode/><PhoneCountryCode/></Phone><Phone><PhoneType>DDI</PhoneType><PhoneNumber/><PhoneAreaCode/><PhoneCountryCode/></Phone></Phones></Contact><InvoiceDate>2008-10-03T00:00:00</InvoiceDate><DueDate>2008-10-20T00:00:00</DueDate><InvoiceNumber>INV-0001</InvoiceNumber><Reference/><IncludesTax>true</IncludesTax><SubTotal>1000.0000</SubTotal><TotalTax>125.0000</TotalTax><Total>1125.0000</Total><InvoiceStatus>AUTHORISED</InvoiceStatus><LineItems><LineItem><LineItemID>e5a8a4ee-85ee-4532-a79f-a552ec63a0d7</LineItemID><Description>A LINE ITEM</Description><Quantity>100.0</Quantity><UnitAmount>12.34</UnitAmount><TaxType>OUTPUT</TaxType><TaxAmount>125.0000</TaxAmount><LineAmount>1125.0000</LineAmount><Tracking><TrackingCategory><Name>Region</Name><Option>Central</Option></TrackingCategory></Tracking></LineItem></LineItems></Invoice><Invoice><InvoiceType>ACCREC</InvoiceType><InvoiceID>a11a1aaa-1111-11a1-1aa1-aaaaaa1a1111</InvoiceID><Contact><ContactID>a11a1aaa-1111-11a1-1aa1-aaaaaa1a1111</ContactID><ContactStatus>ACTIVE</ContactStatus><Name>CONTACT NAME</Name><EmailAddress>bob@example.com</EmailAddress><Addresses><Address><AddressType>POBOX</AddressType><AddressLine1>LINE 1 OF THE ADDRESS</AddressLine1><AddressLine2/><AddressLine3/><AddressLine4/><City>Somewhere</City><Region/><PostalCode/><Country>Some Country</Country></Address></Addresses><Phones><Phone><PhoneType>MOBILE</PhoneType><PhoneNumber>1234567</PhoneNumber><PhoneAreaCode>123</PhoneAreaCode><PhoneCountryCode/></Phone><Phone><PhoneType>DEFAULT</PhoneType><PhoneNumber/><PhoneAreaCode/><PhoneCountryCode/></Phone><Phone><PhoneType>FAX</PhoneType><PhoneNumber/><PhoneAreaCode/><PhoneCountryCode/></Phone><Phone><PhoneType>DDI</PhoneType><PhoneNumber/><PhoneAreaCode/><PhoneCountryCode/></Phone></Phones></Contact><InvoiceDate>2008-10-03T00:00:00</InvoiceDate><DueDate>2008-10-20T00:00:00</DueDate><InvoiceNumber>INV-0001</InvoiceNumber><Reference/><IncludesTax>true</IncludesTax><SubTotal>1000.0000</SubTotal><TotalTax>125.0000</TotalTax><Total>1125.0000</Total><InvoiceStatus>AUTHORISED</InvoiceStatus><LineItems><LineItem><LineItemID>e5a8a4ee-85ee-4532-a79f-a552ec63a0d7</LineItemID><Description>A LINE ITEM</Description><Quantity>100.0</Quantity><UnitAmount>12.34</UnitAmount><TaxType>OUTPUT</TaxType><TaxAmount>125.0000</TaxAmount><LineAmount>1125.0000</LineAmount><Tracking><TrackingCategory><Name>Region</Name><Option>Central</Option></TrackingCategory></Tracking></LineItem></LineItems></Invoice></Invoices></Response>
@@ -0,0 +1,22 @@
1
+ # Copyright (c) 2008 Tim Connor <tlconnor@gmail.com>
2
+ #
3
+ # Permission to use, copy, modify, and/or distribute this software for any
4
+ # purpose with or without fee is hereby granted, provided that the above
5
+ # copyright notice and this permission notice appear in all copies.
6
+ #
7
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
+
15
+ require "rubygems"
16
+
17
+ require 'test/unit'
18
+ require 'mocha'
19
+
20
+ require 'libxml'
21
+
22
+ require File.dirname(__FILE__) + '/../lib/xero_gateway.rb'
@@ -0,0 +1,66 @@
1
+ # Copyright (c) 2008 Tim Connor <tlconnor@gmail.com>
2
+ #
3
+ # Permission to use, copy, modify, and/or distribute this software for any
4
+ # purpose with or without fee is hereby granted, provided that the above
5
+ # copyright notice and this permission notice appear in all copies.
6
+ #
7
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
+
15
+ require File.join(File.dirname(__FILE__), '../../test_helper.rb')
16
+
17
+ class ContactMessageTest < Test::Unit::TestCase
18
+ def setup
19
+ @schema = LibXML::XML::Schema.document(LibXML::XML::Document.file(File.join(File.dirname(__FILE__), '../../xsd/create_contact.xsd')))
20
+ end
21
+
22
+ # Tests that the XML generated from a contact object validates against the Xero XSD
23
+ def test_build_xml
24
+ contact = create_test_contact
25
+
26
+ message = XeroGateway::Messages::ContactMessage.build_xml(contact)
27
+
28
+ # Check that the document matches the XSD
29
+ assert LibXML::XML::Parser.string(message).parse.validate_schema(@schema), "The XML document generated did not validate against the XSD"
30
+ end
31
+
32
+ # Tests that a contact can be converted into XML that Xero can understand, and then converted back to a contact
33
+ def test_build_and_parse_xml
34
+ contact = create_test_contact
35
+
36
+ # Generate the XML message
37
+ contact_as_xml = XeroGateway::Messages::ContactMessage.build_xml(contact)
38
+
39
+ # Parse the XML message and retrieve the contact element
40
+ contact_element = REXML::XPath.first(REXML::Document.new(contact_as_xml), "/Contact")
41
+
42
+ # Build a new contact from the XML
43
+ result_contact = XeroGateway::Messages::ContactMessage.from_xml(contact_element)
44
+
45
+ # Check the contact details
46
+ assert_equal contact, result_contact
47
+ end
48
+
49
+
50
+ private
51
+
52
+ def create_test_contact
53
+ contact = XeroGateway::Contact.new(:id => "55555")
54
+ contact.contact_number = "aaa111"
55
+ contact.name = "CONTACT NAME"
56
+ contact.email = "someone@somewhere.com"
57
+ contact.address.address_type = "THE ADDRESS TYPE FOR THE CONTACT"
58
+ contact.address.line_1 = "LINE 1 OF THE ADDRESS"
59
+ contact.address.line_2 = "LINE 2 OF THE ADDRESS"
60
+ contact.address.line_3 = "LINE 3 OF THE ADDRESS"
61
+ contact.address.line_4 = "LINE 4 OF THE ADDRESS"
62
+ contact.phone.number = "12345"
63
+
64
+ contact
65
+ end
66
+ end
@@ -0,0 +1,76 @@
1
+ # Copyright (c) 2008 Tim Connor <tlconnor@gmail.com>
2
+ #
3
+ # Permission to use, copy, modify, and/or distribute this software for any
4
+ # purpose with or without fee is hereby granted, provided that the above
5
+ # copyright notice and this permission notice appear in all copies.
6
+ #
7
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
+
15
+ require File.join(File.dirname(__FILE__), '../../test_helper.rb')
16
+
17
+ class InvoiceMessageTest < Test::Unit::TestCase
18
+ def setup
19
+ @schema = LibXML::XML::Schema.document(LibXML::XML::Document.file(File.join(File.dirname(__FILE__), '../../xsd/create_invoice.xsd')))
20
+ end
21
+
22
+ # Tests that the XML generated from an invoice object validates against the Xero XSD
23
+ def test_build_xml
24
+ invoice = create_test_invoice
25
+
26
+ message = XeroGateway::Messages::InvoiceMessage.build_xml(invoice)
27
+
28
+ # Check that the document matches the XSD
29
+ assert LibXML::XML::Parser.string(message).parse.validate_schema(@schema), "The XML document generated did not validate against the XSD"
30
+ end
31
+
32
+ # Tests that an invoice can be converted into XML that Xero can understand, and then converted back to an invoice
33
+ def test_build_and_parse_xml
34
+ invoice = create_test_invoice
35
+
36
+ # Generate the XML message
37
+ invoice_as_xml = XeroGateway::Messages::InvoiceMessage.build_xml(invoice)
38
+
39
+ # Parse the XML message and retrieve the invoice element
40
+ invoice_element = REXML::XPath.first(REXML::Document.new(invoice_as_xml), "/Invoice")
41
+
42
+ # Build a new invoice from the XML
43
+ result_invoice = XeroGateway::Messages::InvoiceMessage.from_xml(invoice_element)
44
+
45
+ assert_equal(invoice, result_invoice)
46
+ end
47
+
48
+
49
+ private
50
+
51
+ def create_test_invoice
52
+ invoice = XeroGateway::Invoice.new(:invoice_type => "THE INVOICE TYPE")
53
+ invoice.date = Time.now
54
+ invoice.due_date = Time.now + 10
55
+ invoice.invoice_number = "12345"
56
+ invoice.reference = "MY REFERENCE FOR THIS INVOICE"
57
+ invoice.includes_tax = false
58
+ invoice.sub_total = BigDecimal.new("1000")
59
+ invoice.total_tax = BigDecimal.new("125")
60
+ invoice.total = BigDecimal.new("1125")
61
+
62
+ invoice.contact = XeroGateway::Contact.new(:id => 55555)
63
+ invoice.contact.name = "CONTACT NAME"
64
+ invoice.contact.address.address_type = "THE ADDRESS TYPE FOR THE CONTACT"
65
+ invoice.contact.address.line_1 = "LINE 1 OF THE ADDRESS"
66
+ invoice.contact.phone.number = "12345"
67
+
68
+ invoice.line_items << XeroGateway::LineItem.new({
69
+ :description => "A LINE ITEM",
70
+ :unit_amount => BigDecimal.new("100"),
71
+ :tax_amount => BigDecimal.new("12.5"),
72
+ :line_amount => BigDecimal.new("125")
73
+ })
74
+ invoice
75
+ end
76
+ end