xeroizer 2.15.9 → 2.16.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +59 -1
- data/lib/xeroizer/exceptions.rb +14 -11
- data/lib/xeroizer/generic_application.rb +8 -1
- data/lib/xeroizer/http.rb +19 -10
- data/lib/xeroizer/models/attachment.rb +15 -13
- data/lib/xeroizer/models/bank_transaction.rb +3 -1
- data/lib/xeroizer/models/branding_theme.rb +1 -1
- data/lib/xeroizer/models/contact.rb +3 -1
- data/lib/xeroizer/models/credit_note.rb +26 -2
- data/lib/xeroizer/models/employee.rb +49 -4
- data/lib/xeroizer/models/invoice.rb +1 -1
- data/lib/xeroizer/models/journal.rb +3 -1
- data/lib/xeroizer/models/journal_line.rb +1 -0
- data/lib/xeroizer/models/journal_line_tracking_category.rb +2 -1
- data/lib/xeroizer/models/line_item.rb +1 -0
- data/lib/xeroizer/models/manual_journal.rb +1 -1
- data/lib/xeroizer/models/organisation.rb +41 -1
- data/lib/xeroizer/models/phone.rb +2 -1
- data/lib/xeroizer/models/prepayment.rb +39 -0
- data/lib/xeroizer/models/repeating_invoice.rb +80 -0
- data/lib/xeroizer/models/schedule.rb +33 -0
- data/lib/xeroizer/record/base.rb +6 -0
- data/lib/xeroizer/record/base_model.rb +41 -26
- data/lib/xeroizer/record/record_association_helper.rb +1 -1
- data/lib/xeroizer/record/validation_helper.rb +6 -2
- data/lib/xeroizer/record/validators/length_of_validator.rb +23 -0
- data/lib/xeroizer/record/xml_helper.rb +10 -2
- data/lib/xeroizer/version.rb +1 -1
- data/lib/xeroizer.rb +3 -0
- data/test/stub_responses/prepayments.xml +27 -0
- data/test/stub_responses/records/prepayment-7d3619b1-82cc-405b-8f44-9d4f9a787a8a.xml +92 -0
- data/test/stub_responses/records/repeating_invoice-ad3550bc-1ae0-45c0-a782-48c6d2061127.xml +43 -0
- data/test/stub_responses/repeating_invoices.xml +43 -0
- data/test/unit/models/contact_test.rb +1 -1
- data/test/unit/models/employee_test.rb +43 -0
- data/test/unit/models/invoice_test.rb +21 -1
- data/test/unit/models/journal_test.rb +44 -0
- data/test/unit/models/manual_journal_test.rb +25 -0
- data/test/unit/models/organisation_test.rb +38 -0
- data/test/unit/models/phone_test.rb +31 -0
- data/test/unit/models/prepayment_test.rb +21 -0
- data/test/unit/models/repeating_invoice_test.rb +36 -0
- data/test/unit/record/base_test.rb +4 -2
- metadata +27 -1
@@ -0,0 +1,80 @@
|
|
1
|
+
require "xeroizer/models/attachment"
|
2
|
+
|
3
|
+
module Xeroizer
|
4
|
+
module Record
|
5
|
+
|
6
|
+
class RepeatingInvoiceModel < BaseModel
|
7
|
+
|
8
|
+
set_permissions :read
|
9
|
+
|
10
|
+
include AttachmentModel::Extensions
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
class RepeatingInvoice < Base
|
15
|
+
|
16
|
+
INVOICE_TYPE = {
|
17
|
+
'ACCREC' => 'Accounts Receivable',
|
18
|
+
'ACCPAY' => 'Accounts Payable'
|
19
|
+
} unless defined?(INVOICE_TYPE)
|
20
|
+
|
21
|
+
INVOICE_STATUS = {
|
22
|
+
'AUTHORISED' => 'Approved invoices awaiting payment',
|
23
|
+
'DRAFT' => 'Invoices saved as draft or entered via API',
|
24
|
+
} unless defined?(INVOICE_STATUS)
|
25
|
+
|
26
|
+
include Attachment::Extensions
|
27
|
+
|
28
|
+
set_primary_key :repeating_invoice_id
|
29
|
+
set_possible_primary_keys :repeating_invoice_id
|
30
|
+
list_contains_summary_only false
|
31
|
+
|
32
|
+
guid :repeating_invoice_id
|
33
|
+
string :reference
|
34
|
+
guid :branding_theme_id
|
35
|
+
string :type
|
36
|
+
string :status
|
37
|
+
string :line_amount_types
|
38
|
+
decimal :sub_total, :calculated => true
|
39
|
+
decimal :total_tax, :calculated => true
|
40
|
+
decimal :total, :calculated => true
|
41
|
+
string :currency_code
|
42
|
+
boolean :has_attachments
|
43
|
+
|
44
|
+
belongs_to :contact
|
45
|
+
belongs_to :schedule
|
46
|
+
has_many :line_items, :complete_on_page => true
|
47
|
+
|
48
|
+
public
|
49
|
+
|
50
|
+
# Access the contact name without forcing a download of
|
51
|
+
# an incomplete, summary invoice.
|
52
|
+
def contact_name
|
53
|
+
attributes[:contact] && attributes[:contact][:name]
|
54
|
+
end
|
55
|
+
|
56
|
+
# Access the contact ID without forcing a download of an
|
57
|
+
# incomplete, summary invoice.
|
58
|
+
def contact_id
|
59
|
+
attributes[:contact] && attributes[:contact][:contact_id]
|
60
|
+
end
|
61
|
+
|
62
|
+
# Helper method to check if the invoice has been approved.
|
63
|
+
def approved?
|
64
|
+
[ 'AUTHORISED' ].include? status
|
65
|
+
end
|
66
|
+
|
67
|
+
# Helper method to check if the invoice is accounts payable.
|
68
|
+
def accounts_payable?
|
69
|
+
type == 'ACCPAY'
|
70
|
+
end
|
71
|
+
|
72
|
+
# Helper method to check if the invoice is accounts receivable.
|
73
|
+
def accounts_receivable?
|
74
|
+
type == 'ACCREC'
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Xeroizer
|
2
|
+
module Record
|
3
|
+
|
4
|
+
class ScheduleModel < BaseModel
|
5
|
+
|
6
|
+
end
|
7
|
+
|
8
|
+
class Schedule < Base
|
9
|
+
|
10
|
+
UNIT = {
|
11
|
+
'WEEKLY' => 'Weekly',
|
12
|
+
'MONTHLY' => 'Monthly',
|
13
|
+
} unless defined?(UNIT)
|
14
|
+
|
15
|
+
PAYMENT_TERM = {
|
16
|
+
'DAYSAFTERBILLDATE' => 'day(s) after bill date',
|
17
|
+
'DAYSAFTERBILLMONTH' => 'day(s) after bill month',
|
18
|
+
'OFCURRENTMONTH' => 'of the current month',
|
19
|
+
'OFFOLLOWINGMONTH' => 'of the following month',
|
20
|
+
} unless defined?(PAYMENT_TERM)
|
21
|
+
|
22
|
+
integer :period
|
23
|
+
string :unit
|
24
|
+
integer :due_date
|
25
|
+
string :due_date_type
|
26
|
+
date :start_date
|
27
|
+
date :next_scheduled_date
|
28
|
+
date :end_date
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
data/lib/xeroizer/record/base.rb
CHANGED
@@ -17,6 +17,7 @@ module Xeroizer
|
|
17
17
|
attr_reader :model
|
18
18
|
attr_accessor :errors
|
19
19
|
attr_accessor :complete_record_downloaded
|
20
|
+
attr_accessor :paged_record_downloaded
|
20
21
|
|
21
22
|
include ModelDefinitionHelper
|
22
23
|
include RecordAssociationHelper
|
@@ -89,6 +90,11 @@ module Xeroizer
|
|
89
90
|
end
|
90
91
|
end
|
91
92
|
|
93
|
+
|
94
|
+
def paged_record_downloaded?
|
95
|
+
!!paged_record_downloaded
|
96
|
+
end
|
97
|
+
|
92
98
|
# Downloads the complete record if we only have a summary of the record.
|
93
99
|
def download_complete_record!
|
94
100
|
record = self.parent.find(self.id)
|
@@ -140,43 +140,51 @@ module Xeroizer
|
|
140
140
|
result
|
141
141
|
end
|
142
142
|
|
143
|
-
def
|
143
|
+
def save_records(records, chunk_size = DEFAULT_RECORDS_PER_BATCH_SAVE)
|
144
144
|
no_errors = true
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
response.response_items.each_with_index do |record, i|
|
159
|
-
if record and record.is_a?(model_class)
|
160
|
-
some_records[i].attributes = record.non_calculated_attributes
|
161
|
-
some_records[i].errors = record.errors
|
162
|
-
no_errors = record.errors.nil? || record.errors.empty? if no_errors
|
163
|
-
some_records[i].saved!
|
164
|
-
end
|
145
|
+
return false unless records.all?(&:valid?)
|
146
|
+
|
147
|
+
actions = records.group_by {|o| o.new_record? ? create_method : :http_post }
|
148
|
+
actions.each_pair do |http_method, records_for_method|
|
149
|
+
records_for_method.each_slice(chunk_size) do |some_records|
|
150
|
+
request = to_bulk_xml(some_records)
|
151
|
+
response = parse_response(self.send(http_method, request, {:summarizeErrors => false}))
|
152
|
+
response.response_items.each_with_index do |record, i|
|
153
|
+
if record and record.is_a?(model_class)
|
154
|
+
some_records[i].attributes = record.non_calculated_attributes
|
155
|
+
some_records[i].errors = record.errors
|
156
|
+
no_errors = record.errors.nil? || record.errors.empty? if no_errors
|
157
|
+
some_records[i].saved!
|
165
158
|
end
|
166
159
|
end
|
167
160
|
end
|
168
161
|
end
|
169
162
|
|
170
|
-
@objects = {}
|
171
|
-
@allow_batch_operations = false
|
172
163
|
no_errors
|
173
164
|
end
|
174
165
|
|
166
|
+
def batch_save(chunk_size = DEFAULT_RECORDS_PER_BATCH_SAVE)
|
167
|
+
@objects = {}
|
168
|
+
@allow_batch_operations = true
|
169
|
+
|
170
|
+
begin
|
171
|
+
yield
|
172
|
+
|
173
|
+
if @objects[model_class]
|
174
|
+
objects = @objects[model_class].values.compact
|
175
|
+
save_records(objects, chunk_size)
|
176
|
+
end
|
177
|
+
ensure
|
178
|
+
@objects = {}
|
179
|
+
@allow_batch_operations = false
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
175
183
|
def parse_response(response_xml, options = {})
|
176
184
|
Response.parse(response_xml, options) do | response, elements, response_model_name |
|
177
185
|
if model_name == response_model_name
|
178
186
|
@response = response
|
179
|
-
parse_records(response, elements)
|
187
|
+
parse_records(response, elements, paged_records_requested?(options))
|
180
188
|
end
|
181
189
|
end
|
182
190
|
end
|
@@ -187,8 +195,14 @@ module Xeroizer
|
|
187
195
|
|
188
196
|
protected
|
189
197
|
|
190
|
-
|
191
|
-
def
|
198
|
+
|
199
|
+
def paged_records_requested?(options)
|
200
|
+
options.has_key?(:page) and options[:page].to_i >= 0
|
201
|
+
end
|
202
|
+
|
203
|
+
|
204
|
+
# Parse the records part of the XML response and builds model instances as necessary.
|
205
|
+
def parse_records(response, elements, paged_results)
|
192
206
|
elements.each do | element |
|
193
207
|
new_record = model_class.build_from_node(element, self)
|
194
208
|
if element.attribute('status').try(:value) == 'ERROR'
|
@@ -197,6 +211,7 @@ module Xeroizer
|
|
197
211
|
new_record.errors << err.text.gsub(/^\s+/, '').gsub(/\s+$/, '')
|
198
212
|
end
|
199
213
|
end
|
214
|
+
new_record.paged_record_downloaded = paged_results
|
200
215
|
response.response_items << new_record
|
201
216
|
end
|
202
217
|
end
|
@@ -127,7 +127,7 @@ module Xeroizer
|
|
127
127
|
# the complete version of the record before accessing the association.
|
128
128
|
if list_contains_summary_only?
|
129
129
|
define_method internal_field_name do
|
130
|
-
download_complete_record! unless new_record? || options[:list_complete] || complete_record_downloaded?
|
130
|
+
download_complete_record! unless new_record? || options[:list_complete] || options[:complete_on_page] && paged_record_downloaded? || complete_record_downloaded?
|
131
131
|
self.attributes[field_name] || ((association_type == :has_many) ? [] : nil)
|
132
132
|
end
|
133
133
|
end
|
@@ -31,8 +31,12 @@ module Xeroizer
|
|
31
31
|
|
32
32
|
def validates_presence_of(*args)
|
33
33
|
validates_with_validator(Validator::PresenceOfValidator, args)
|
34
|
-
end
|
35
|
-
|
34
|
+
end
|
35
|
+
|
36
|
+
def validates_length_of(*args)
|
37
|
+
validates_with_validator(Validator::LengthOfValidator, args)
|
38
|
+
end
|
39
|
+
|
36
40
|
def validates(*args, &block)
|
37
41
|
fail "Block required" unless block_given?
|
38
42
|
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Xeroizer
|
2
|
+
module Record
|
3
|
+
|
4
|
+
class Validator
|
5
|
+
|
6
|
+
class LengthOfValidator < Validator
|
7
|
+
|
8
|
+
def valid?(record)
|
9
|
+
if options[:max] && record.attributes[attribute].to_s.length > options[:max]
|
10
|
+
record.errors << [attribute, options[:message] || "must be shorter than #{options[:max]} characters"]
|
11
|
+
end
|
12
|
+
|
13
|
+
if options[:min] && record.attributes[attribute].to_s.length < options[:min]
|
14
|
+
record.errors << [attribute, options[:message] || "must be greater than #{options[:min]} characters"]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -126,9 +126,17 @@ module Xeroizer
|
|
126
126
|
|
127
127
|
end
|
128
128
|
end
|
129
|
-
|
129
|
+
|
130
|
+
def association_to_xml(association_name)
|
131
|
+
builder = Builder::XmlMarkup.new(indent: 2)
|
132
|
+
records = send(association_name)
|
133
|
+
|
134
|
+
optional_root_tag(association_name.to_s.camelize, builder) do |b|
|
135
|
+
records.each { |record| record.to_xml(b) }
|
136
|
+
end
|
137
|
+
end
|
130
138
|
end
|
131
|
-
|
139
|
+
|
132
140
|
end
|
133
141
|
end
|
134
142
|
end
|
data/lib/xeroizer/version.rb
CHANGED
data/lib/xeroizer.rb
CHANGED
@@ -49,8 +49,11 @@ require 'xeroizer/models/manual_journal_line'
|
|
49
49
|
require 'xeroizer/models/option'
|
50
50
|
require 'xeroizer/models/organisation'
|
51
51
|
require 'xeroizer/models/payment'
|
52
|
+
require 'xeroizer/models/prepayment'
|
52
53
|
require 'xeroizer/models/phone'
|
53
54
|
require 'xeroizer/models/receipt'
|
55
|
+
require 'xeroizer/models/repeating_invoice'
|
56
|
+
require 'xeroizer/models/schedule'
|
54
57
|
require 'xeroizer/models/tax_rate'
|
55
58
|
require 'xeroizer/models/tax_component'
|
56
59
|
require 'xeroizer/models/tracking_category'
|
@@ -0,0 +1,27 @@
|
|
1
|
+
<Response xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
2
|
+
<Id>370b7dab-e069-4424-84e0-74e7d1f7cbb3</Id>
|
3
|
+
<Status>OK</Status>
|
4
|
+
<ProviderName>Xero API Previewer</ProviderName>
|
5
|
+
<DateTimeUTC>2015-04-23T05:28:25.5811998Z</DateTimeUTC>
|
6
|
+
<Prepayments>
|
7
|
+
<Prepayment>
|
8
|
+
<Contact>
|
9
|
+
<ContactID>e1826204-cc0a-42a5-a6d0-4b352d9d5953</ContactID>
|
10
|
+
<Name>Carlton Technical Books</Name>
|
11
|
+
</Contact>
|
12
|
+
<Date>2015-04-15T00:00:00</Date>
|
13
|
+
<Status>AUTHORISED</Status>
|
14
|
+
<LineAmountTypes>Inclusive</LineAmountTypes>
|
15
|
+
<SubTotal>363.64</SubTotal>
|
16
|
+
<TotalTax>36.36</TotalTax>
|
17
|
+
<Total>400.00</Total>
|
18
|
+
<UpdatedDateUTC>2015-04-23T05:28:06.653</UpdatedDateUTC>
|
19
|
+
<CurrencyCode>AUD</CurrencyCode>
|
20
|
+
<Type>RECEIVE-PREPAYMENT</Type>
|
21
|
+
<Reference>ORC1040</Reference>
|
22
|
+
<RemainingCredit>400.00</RemainingCredit>
|
23
|
+
<HasAttachments>false</HasAttachments>
|
24
|
+
<PrepaymentID>7d3619b1-82cc-405b-8f44-9d4f9a787a8a</PrepaymentID>
|
25
|
+
</Prepayment>
|
26
|
+
</Prepayments>
|
27
|
+
</Response>
|
@@ -0,0 +1,92 @@
|
|
1
|
+
<Response xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
2
|
+
<Id>22e77b56-ccfc-4bce-9357-40dd82328b45</Id>
|
3
|
+
<Status>OK</Status>
|
4
|
+
<ProviderName>Xero API Previewer</ProviderName>
|
5
|
+
<DateTimeUTC>2015-04-23T05:31:12.4452174Z</DateTimeUTC>
|
6
|
+
<Prepayments>
|
7
|
+
<Prepayment>
|
8
|
+
<Contact>
|
9
|
+
<ContactID>e1826204-cc0a-42a5-a6d0-4b352d9d5953</ContactID>
|
10
|
+
<ContactStatus>ACTIVE</ContactStatus>
|
11
|
+
<Name>Carlton Technical Books</Name>
|
12
|
+
<Addresses>
|
13
|
+
<Address>
|
14
|
+
<AddressType>POBOX</AddressType>
|
15
|
+
</Address>
|
16
|
+
<Address>
|
17
|
+
<AddressType>STREET</AddressType>
|
18
|
+
</Address>
|
19
|
+
</Addresses>
|
20
|
+
<Phones>
|
21
|
+
<Phone>
|
22
|
+
<PhoneType>DEFAULT</PhoneType>
|
23
|
+
<PhoneNumber>3786543</PhoneNumber>
|
24
|
+
<PhoneAreaCode>03</PhoneAreaCode>
|
25
|
+
</Phone>
|
26
|
+
<Phone>
|
27
|
+
<PhoneType>DDI</PhoneType>
|
28
|
+
</Phone>
|
29
|
+
<Phone>
|
30
|
+
<PhoneType>FAX</PhoneType>
|
31
|
+
</Phone>
|
32
|
+
<Phone>
|
33
|
+
<PhoneType>MOBILE</PhoneType>
|
34
|
+
</Phone>
|
35
|
+
</Phones>
|
36
|
+
<UpdatedDateUTC>2015-04-23T19:31:18.733</UpdatedDateUTC>
|
37
|
+
</Contact>
|
38
|
+
<Date>2015-04-15T00:00:00</Date>
|
39
|
+
<Status>AUTHORISED</Status>
|
40
|
+
<LineAmountTypes>Inclusive</LineAmountTypes>
|
41
|
+
<LineItems>
|
42
|
+
<LineItem>
|
43
|
+
<Description>Technical Book</Description>
|
44
|
+
<UnitAmount>64.00</UnitAmount>
|
45
|
+
<TaxType>OUTPUT</TaxType>
|
46
|
+
<TaxAmount>17.45</TaxAmount>
|
47
|
+
<LineAmount>192.00</LineAmount>
|
48
|
+
<AccountCode>200</AccountCode>
|
49
|
+
<Quantity>3.0000</Quantity>
|
50
|
+
</LineItem>
|
51
|
+
<LineItem>
|
52
|
+
<Description>Stickers</Description>
|
53
|
+
<UnitAmount>2.00</UnitAmount>
|
54
|
+
<TaxType>OUTPUT</TaxType>
|
55
|
+
<TaxAmount>11.64</TaxAmount>
|
56
|
+
<LineAmount>128.00</LineAmount>
|
57
|
+
<AccountCode>260</AccountCode>
|
58
|
+
<Quantity>64.0000</Quantity>
|
59
|
+
</LineItem>
|
60
|
+
<LineItem>
|
61
|
+
<Description>Swag</Description>
|
62
|
+
<UnitAmount>48.00</UnitAmount>
|
63
|
+
<TaxType>OUTPUT</TaxType>
|
64
|
+
<TaxAmount>4.36</TaxAmount>
|
65
|
+
<LineAmount>48.00</LineAmount>
|
66
|
+
<AccountCode>200</AccountCode>
|
67
|
+
<Quantity>1.0000</Quantity>
|
68
|
+
</LineItem>
|
69
|
+
<LineItem>
|
70
|
+
<Description>Calculator</Description>
|
71
|
+
<UnitAmount>16.00</UnitAmount>
|
72
|
+
<TaxType>OUTPUT</TaxType>
|
73
|
+
<TaxAmount>2.91</TaxAmount>
|
74
|
+
<LineAmount>32.00</LineAmount>
|
75
|
+
<AccountCode>260</AccountCode>
|
76
|
+
<Quantity>2.0000</Quantity>
|
77
|
+
</LineItem>
|
78
|
+
</LineItems>
|
79
|
+
<SubTotal>363.64</SubTotal>
|
80
|
+
<TotalTax>36.36</TotalTax>
|
81
|
+
<Total>400.00</Total>
|
82
|
+
<UpdatedDateUTC>2015-04-23T05:28:06.653</UpdatedDateUTC>
|
83
|
+
<CurrencyCode>AUD</CurrencyCode>
|
84
|
+
<CurrencyRate>1.000000</CurrencyRate>
|
85
|
+
<Type>RECEIVE-PREPAYMENT</Type>
|
86
|
+
<Reference>ORC1040</Reference>
|
87
|
+
<RemainingCredit>400.00</RemainingCredit>
|
88
|
+
<HasAttachments>false</HasAttachments>
|
89
|
+
<PrepaymentID>7d3619b1-82cc-405b-8f44-9d4f9a787a8a</PrepaymentID>
|
90
|
+
</Prepayment>
|
91
|
+
</Prepayments>
|
92
|
+
</Response>
|
@@ -0,0 +1,43 @@
|
|
1
|
+
<Response xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
2
|
+
<Id>a70214d6-fbee-4a3a-89d6-57cfdb387a69</Id>
|
3
|
+
<Status>OK</Status>
|
4
|
+
<ProviderName>Test App</ProviderName>
|
5
|
+
<DateTimeUTC>2011-02-14T01:54:32.2566964Z</DateTimeUTC>
|
6
|
+
<RepeatingInvoices>
|
7
|
+
<RepeatingInvoice>
|
8
|
+
<Contact>
|
9
|
+
<ContactID>9b9ba9e5-e907-4b4e-8210-54d82b0aa479</ContactID>
|
10
|
+
<Name>PowerDirect</Name>
|
11
|
+
</Contact>
|
12
|
+
<Status>DRAFT</Status>
|
13
|
+
<LineAmountTypes>Inclusive</LineAmountTypes>
|
14
|
+
<LineItems>
|
15
|
+
<LineItem>
|
16
|
+
<Description>Monthly electricity</Description>
|
17
|
+
<UnitAmount>78.26</UnitAmount>
|
18
|
+
<TaxType>INPUT2</TaxType>
|
19
|
+
<TaxAmount>11.74</TaxAmount>
|
20
|
+
<LineAmount>78.26</LineAmount>
|
21
|
+
<AccountCode>445</AccountCode>
|
22
|
+
<Quantity>1.0000</Quantity>
|
23
|
+
</LineItem>
|
24
|
+
</LineItems>
|
25
|
+
<SubTotal>78.26</SubTotal>
|
26
|
+
<TotalTax>11.74</TotalTax>
|
27
|
+
<Total>90.00</Total>
|
28
|
+
<CurrencyCode>NZD</CurrencyCode>
|
29
|
+
<Schedule>
|
30
|
+
<Period>1</Period>
|
31
|
+
<Unit>MONTHLY</Unit>
|
32
|
+
<DueDate>10</DueDate>
|
33
|
+
<DueDateType>OFFOLLOWINGMONTH</DueDateType>
|
34
|
+
<StartDate>2013-01-21T00:00:00</StartDate>
|
35
|
+
<NextScheduledDate>2014-03-23T00:00:00</NextScheduledDate>
|
36
|
+
</Schedule>
|
37
|
+
<RepeatingInvoiceID>ad3550bc-1ae0-45c0-a782-48c6d2061127</RepeatingInvoiceID>
|
38
|
+
<Type>ACCPAY</Type>
|
39
|
+
<Reference>RPT445-1</Reference>
|
40
|
+
<HasAttachments>false</HasAttachments>
|
41
|
+
</RepeatingInvoice>
|
42
|
+
</RepeatingInvoices>
|
43
|
+
</Response>
|
@@ -0,0 +1,43 @@
|
|
1
|
+
<Response xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
2
|
+
<Id>a70214d6-fbee-4a3a-89d6-57cfdb387a69</Id>
|
3
|
+
<Status>OK</Status>
|
4
|
+
<ProviderName>Test App</ProviderName>
|
5
|
+
<DateTimeUTC>2011-02-14T01:54:32.2566964Z</DateTimeUTC>
|
6
|
+
<RepeatingInvoices>
|
7
|
+
<RepeatingInvoice>
|
8
|
+
<Contact>
|
9
|
+
<ContactID>9b9ba9e5-e907-4b4e-8210-54d82b0aa479</ContactID>
|
10
|
+
<Name>PowerDirect</Name>
|
11
|
+
</Contact>
|
12
|
+
<Status>DRAFT</Status>
|
13
|
+
<LineAmountTypes>Inclusive</LineAmountTypes>
|
14
|
+
<LineItems>
|
15
|
+
<LineItem>
|
16
|
+
<Description>Monthly electricity</Description>
|
17
|
+
<UnitAmount>78.26</UnitAmount>
|
18
|
+
<TaxType>INPUT2</TaxType>
|
19
|
+
<TaxAmount>11.74</TaxAmount>
|
20
|
+
<LineAmount>78.26</LineAmount>
|
21
|
+
<AccountCode>445</AccountCode>
|
22
|
+
<Quantity>1.0000</Quantity>
|
23
|
+
</LineItem>
|
24
|
+
</LineItems>
|
25
|
+
<SubTotal>78.26</SubTotal>
|
26
|
+
<TotalTax>11.74</TotalTax>
|
27
|
+
<Total>90.00</Total>
|
28
|
+
<CurrencyCode>NZD</CurrencyCode>
|
29
|
+
<Schedule>
|
30
|
+
<Period>1</Period>
|
31
|
+
<Unit>MONTHLY</Unit>
|
32
|
+
<DueDate>10</DueDate>
|
33
|
+
<DueDateType>OFFOLLOWINGMONTH</DueDateType>
|
34
|
+
<StartDate>2013-01-21T00:00:00</StartDate>
|
35
|
+
<NextScheduledDate>2014-03-23T00:00:00</NextScheduledDate>
|
36
|
+
</Schedule>
|
37
|
+
<RepeatingInvoiceID>ad3550bc-1ae0-45c0-a782-48c6d2061127</RepeatingInvoiceID>
|
38
|
+
<Type>ACCPAY</Type>
|
39
|
+
<Reference>RPT445-1</Reference>
|
40
|
+
<HasAttachments>false</HasAttachments>
|
41
|
+
</RepeatingInvoice>
|
42
|
+
</RepeatingInvoices>
|
43
|
+
</Response>
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'test_helper'))
|
2
|
+
|
3
|
+
class EmployeeTest < Test::Unit::TestCase
|
4
|
+
include TestHelper
|
5
|
+
include Xeroizer::Record
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@client = Xeroizer::PublicApplication.new(CONSUMER_KEY, CONSUMER_SECRET)
|
9
|
+
@employee = @client.Employee.build
|
10
|
+
|
11
|
+
@employee.employee_id = 'GUID'
|
12
|
+
@employee.status = 'ACTIVE'
|
13
|
+
|
14
|
+
@employee.first_name = 'Example'
|
15
|
+
@employee.last_name = 'User'
|
16
|
+
|
17
|
+
@employee.date_of_birth = DateTime.strptime("2015-01-01T00:00:00Z")
|
18
|
+
|
19
|
+
@employee.gender = 'F'
|
20
|
+
@employee.email = 'user@example.com'
|
21
|
+
|
22
|
+
@employee.start_date = DateTime.strptime("2015-01-02T00:00:00Z")
|
23
|
+
@employee.termination_date = DateTime.strptime("2015-01-03T00:00:00Z")
|
24
|
+
@employee.is_authorised_to_approve_timesheets = false
|
25
|
+
@employee.employee_group_name = "TEAM A"
|
26
|
+
@doc = Nokogiri::XML(@employee.to_xml)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should render" do
|
30
|
+
assert_equal "GUID", @doc.xpath("//EmployeeID").text
|
31
|
+
assert_equal "ACTIVE", @doc.xpath("//Status").text
|
32
|
+
assert_equal "Example", @doc.xpath("//FirstName").text
|
33
|
+
assert_equal "User", @doc.xpath("//LastName").text
|
34
|
+
assert_equal "2015-01-01", @doc.xpath("//DateOfBirth").text
|
35
|
+
assert_equal "2015-01-02", @doc.xpath("//StartDate").text
|
36
|
+
assert_equal "2015-01-03", @doc.xpath("//TerminationDate").text
|
37
|
+
assert_equal "F", @doc.xpath("//Gender").text
|
38
|
+
assert_equal "user@example.com", @doc.xpath("//Email").text
|
39
|
+
|
40
|
+
assert_equal "false", @doc.xpath("//IsAuthorisedToApproveTimesheets").text
|
41
|
+
assert_equal "TEAM A", @doc.xpath("//EmployeeGroupName").text
|
42
|
+
end
|
43
|
+
end
|
@@ -83,7 +83,27 @@ class InvoiceTest < Test::Unit::TestCase
|
|
83
83
|
end
|
84
84
|
|
85
85
|
end
|
86
|
-
|
86
|
+
|
87
|
+
context "paging" do
|
88
|
+
|
89
|
+
should "have line items without downloading full invoice when paging" do
|
90
|
+
|
91
|
+
invoices = @client.Invoice.all(page: 1)
|
92
|
+
|
93
|
+
invoices.each do |invoice|
|
94
|
+
# This would kick off a full download without page param.
|
95
|
+
invoice.line_items.size
|
96
|
+
assert_equal(true, invoice.paged_record_downloaded?)
|
97
|
+
|
98
|
+
# This indicates that there wasn't a separate download of the individual invoice.
|
99
|
+
assert_equal(false, invoice.complete_record_downloaded?)
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
87
107
|
context "contact shortcuts" do
|
88
108
|
|
89
109
|
should "have valid #contact_name and #contact_id without downloading full invoice" do
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'test_helper'))
|
2
|
+
|
3
|
+
class JournalTest < Test::Unit::TestCase
|
4
|
+
include TestHelper
|
5
|
+
include Xeroizer::Record
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@client = Xeroizer::PublicApplication.new(CONSUMER_KEY, CONSUMER_SECRET)
|
9
|
+
|
10
|
+
@journal = @client.Journal.build
|
11
|
+
@journal.journal_id = "0d926df3-459f-4264-a3a3-49ac065eb0ed"
|
12
|
+
@journal.date = DateTime.strptime("2015-01-01T00:00:00Z")
|
13
|
+
@journal.created_date_utc = DateTime.strptime("2015-01-01T00:00:00Z")
|
14
|
+
@journal.journal_number = "JOURNAL_NUMBER"
|
15
|
+
@journal.reference = "Web"
|
16
|
+
@journal.source_id = "GUID"
|
17
|
+
@journal.source_type = "Fish"
|
18
|
+
|
19
|
+
@journal_line = @journal.add_journal_line({})
|
20
|
+
|
21
|
+
@doc = Nokogiri::XML(@journal.to_xml)
|
22
|
+
end
|
23
|
+
|
24
|
+
context "rendering" do
|
25
|
+
|
26
|
+
it "should render journal_lines" do
|
27
|
+
assert_equal 1, @doc.xpath("//JournalLine").size
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should render source_type, source_id" do
|
31
|
+
assert_equal "GUID", @doc.xpath("//SourceID").text
|
32
|
+
assert_equal "Fish", @doc.xpath("//SourceType").text
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should render reference" do
|
36
|
+
assert_equal "Web", @doc.xpath("//Reference").text
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should render date" do
|
40
|
+
assert_equal "2015-01-01", @doc.xpath("//JournalDate").text
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|