xeroizer 2.15.9 → 2.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/README.md +59 -1
  2. data/lib/xeroizer/exceptions.rb +14 -11
  3. data/lib/xeroizer/generic_application.rb +8 -1
  4. data/lib/xeroizer/http.rb +19 -10
  5. data/lib/xeroizer/models/attachment.rb +15 -13
  6. data/lib/xeroizer/models/bank_transaction.rb +3 -1
  7. data/lib/xeroizer/models/branding_theme.rb +1 -1
  8. data/lib/xeroizer/models/contact.rb +3 -1
  9. data/lib/xeroizer/models/credit_note.rb +26 -2
  10. data/lib/xeroizer/models/employee.rb +49 -4
  11. data/lib/xeroizer/models/invoice.rb +1 -1
  12. data/lib/xeroizer/models/journal.rb +3 -1
  13. data/lib/xeroizer/models/journal_line.rb +1 -0
  14. data/lib/xeroizer/models/journal_line_tracking_category.rb +2 -1
  15. data/lib/xeroizer/models/line_item.rb +1 -0
  16. data/lib/xeroizer/models/manual_journal.rb +1 -1
  17. data/lib/xeroizer/models/organisation.rb +41 -1
  18. data/lib/xeroizer/models/phone.rb +2 -1
  19. data/lib/xeroizer/models/prepayment.rb +39 -0
  20. data/lib/xeroizer/models/repeating_invoice.rb +80 -0
  21. data/lib/xeroizer/models/schedule.rb +33 -0
  22. data/lib/xeroizer/record/base.rb +6 -0
  23. data/lib/xeroizer/record/base_model.rb +41 -26
  24. data/lib/xeroizer/record/record_association_helper.rb +1 -1
  25. data/lib/xeroizer/record/validation_helper.rb +6 -2
  26. data/lib/xeroizer/record/validators/length_of_validator.rb +23 -0
  27. data/lib/xeroizer/record/xml_helper.rb +10 -2
  28. data/lib/xeroizer/version.rb +1 -1
  29. data/lib/xeroizer.rb +3 -0
  30. data/test/stub_responses/prepayments.xml +27 -0
  31. data/test/stub_responses/records/prepayment-7d3619b1-82cc-405b-8f44-9d4f9a787a8a.xml +92 -0
  32. data/test/stub_responses/records/repeating_invoice-ad3550bc-1ae0-45c0-a782-48c6d2061127.xml +43 -0
  33. data/test/stub_responses/repeating_invoices.xml +43 -0
  34. data/test/unit/models/contact_test.rb +1 -1
  35. data/test/unit/models/employee_test.rb +43 -0
  36. data/test/unit/models/invoice_test.rb +21 -1
  37. data/test/unit/models/journal_test.rb +44 -0
  38. data/test/unit/models/manual_journal_test.rb +25 -0
  39. data/test/unit/models/organisation_test.rb +38 -0
  40. data/test/unit/models/phone_test.rb +31 -0
  41. data/test/unit/models/prepayment_test.rb +21 -0
  42. data/test/unit/models/repeating_invoice_test.rb +36 -0
  43. data/test/unit/record/base_test.rb +4 -2
  44. 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
@@ -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 batch_save(chunk_size = DEFAULT_RECORDS_PER_BATCH_SAVE)
143
+ def save_records(records, chunk_size = DEFAULT_RECORDS_PER_BATCH_SAVE)
144
144
  no_errors = true
145
- @objects = {}
146
- @allow_batch_operations = true
147
-
148
- yield
149
-
150
- if @objects[model_class]
151
- objects = @objects[model_class].values.compact
152
- return false unless objects.all?(&:valid?)
153
- actions = objects.group_by {|o| o.new_record? ? create_method : :http_post }
154
- actions.each_pair do |http_method, records|
155
- records.each_slice(chunk_size) do |some_records|
156
- request = to_bulk_xml(some_records)
157
- response = parse_response(self.send(http_method, request, {:summarizeErrors => false}))
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
- # Parse the records part of the XML response and builds model instances as necessary.
191
- def parse_records(response, elements)
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
@@ -1,3 +1,3 @@
1
1
  module Xeroizer
2
- VERSION = "2.15.9".freeze
2
+ VERSION = "2.16.0".freeze
3
3
  end
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>
@@ -20,7 +20,7 @@ class ContactTest < Test::Unit::TestCase
20
20
  assert_equal(true, @contact.valid?)
21
21
  assert_equal(0, @contact.errors.size)
22
22
  end
23
-
23
+
24
24
  end
25
25
 
26
26
  end
@@ -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