xeroizer 2.17.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +246 -213
  3. data/lib/xeroizer/connection.rb +49 -0
  4. data/lib/xeroizer/exceptions.rb +4 -0
  5. data/lib/xeroizer/generic_application.rb +13 -5
  6. data/lib/xeroizer/http.rb +7 -80
  7. data/lib/xeroizer/http_response.rb +154 -0
  8. data/lib/xeroizer/models/bank_account.rb +1 -0
  9. data/lib/xeroizer/models/bank_transaction.rb +1 -0
  10. data/lib/xeroizer/models/batch_payment.rb +27 -0
  11. data/lib/xeroizer/models/branding_theme.rb +49 -9
  12. data/lib/xeroizer/models/contact.rb +12 -6
  13. data/lib/xeroizer/models/contact_group.rb +45 -0
  14. data/lib/xeroizer/models/credit_note.rb +24 -22
  15. data/lib/xeroizer/models/currency.rb +14 -2
  16. data/lib/xeroizer/models/from_bank_account.rb +1 -0
  17. data/lib/xeroizer/models/history_record.rb +72 -0
  18. data/lib/xeroizer/models/invoice.rb +17 -3
  19. data/lib/xeroizer/models/item.rb +2 -1
  20. data/lib/xeroizer/models/item_purchase_details.rb +1 -1
  21. data/lib/xeroizer/models/line_item.rb +17 -5
  22. data/lib/xeroizer/models/manual_journal.rb +2 -1
  23. data/lib/xeroizer/models/online_invoice.rb +37 -0
  24. data/lib/xeroizer/models/option.rb +1 -1
  25. data/lib/xeroizer/models/organisation.rb +2 -0
  26. data/lib/xeroizer/models/payment_service.rb +22 -0
  27. data/lib/xeroizer/models/payroll/address.rb +53 -0
  28. data/lib/xeroizer/models/payroll/bank_account.rb +18 -6
  29. data/lib/xeroizer/models/payroll/benefit_line.rb +26 -0
  30. data/lib/xeroizer/models/payroll/benefit_type.rb +45 -0
  31. data/lib/xeroizer/models/payroll/deduction_line.rb +32 -0
  32. data/lib/xeroizer/models/payroll/deduction_type.rb +49 -0
  33. data/lib/xeroizer/models/payroll/earnings_line.rb +39 -0
  34. data/lib/xeroizer/models/payroll/earnings_type.rb +53 -0
  35. data/lib/xeroizer/models/payroll/employee.rb +30 -8
  36. data/lib/xeroizer/models/payroll/leave_application.rb +27 -0
  37. data/lib/xeroizer/models/payroll/leave_line.rb +30 -0
  38. data/lib/xeroizer/models/payroll/leave_period.rb +15 -0
  39. data/lib/xeroizer/models/payroll/pay_items.rb +22 -0
  40. data/lib/xeroizer/models/payroll/pay_run.rb +33 -0
  41. data/lib/xeroizer/models/payroll/pay_schedule.rb +40 -0
  42. data/lib/xeroizer/models/payroll/pay_template.rb +24 -0
  43. data/lib/xeroizer/models/payroll/payment_method.rb +24 -0
  44. data/lib/xeroizer/models/payroll/paystub.rb +44 -0
  45. data/lib/xeroizer/models/payroll/reimbursement_line.rb +21 -0
  46. data/lib/xeroizer/models/payroll/reimbursement_type.rb +22 -0
  47. data/lib/xeroizer/models/payroll/salary_and_wage.rb +29 -0
  48. data/lib/xeroizer/models/payroll/super_line.rb +40 -0
  49. data/lib/xeroizer/models/payroll/tax_declaration.rb +50 -0
  50. data/lib/xeroizer/models/payroll/time_off_line.rb +20 -0
  51. data/lib/xeroizer/models/payroll/time_off_type.rb +32 -0
  52. data/lib/xeroizer/models/payroll/work_location.rb +25 -0
  53. data/lib/xeroizer/models/prepayment.rb +1 -0
  54. data/lib/xeroizer/models/purchase_order.rb +6 -6
  55. data/lib/xeroizer/models/quote.rb +76 -0
  56. data/lib/xeroizer/models/schedule.rb +1 -0
  57. data/lib/xeroizer/models/tax_component.rb +1 -0
  58. data/lib/xeroizer/models/to_bank_account.rb +1 -0
  59. data/lib/xeroizer/oauth.rb +12 -1
  60. data/lib/xeroizer/oauth2.rb +82 -0
  61. data/lib/xeroizer/oauth2_application.rb +49 -0
  62. data/lib/xeroizer/payroll_application.rb +8 -3
  63. data/lib/xeroizer/record/base.rb +11 -2
  64. data/lib/xeroizer/record/base_model.rb +1 -1
  65. data/lib/xeroizer/record/base_model_http_proxy.rb +37 -17
  66. data/lib/xeroizer/record/model_definition_helper.rb +1 -1
  67. data/lib/xeroizer/record/payroll_base.rb +4 -0
  68. data/lib/xeroizer/record/record_association_helper.rb +4 -4
  69. data/lib/xeroizer/record/validators/associated_validator.rb +1 -0
  70. data/lib/xeroizer/record/xml_helper.rb +18 -18
  71. data/lib/xeroizer/report/aged_receivables_by_contact.rb +1 -1
  72. data/lib/xeroizer/report/cell_xml_helper.rb +13 -13
  73. data/lib/xeroizer/response.rb +22 -17
  74. data/lib/xeroizer/version.rb +1 -1
  75. data/lib/xeroizer.rb +34 -4
  76. data/test/acceptance/about_creating_bank_transactions_test.rb +89 -81
  77. data/test/acceptance/about_creating_prepayment_test.rb +25 -30
  78. data/test/acceptance/about_fetching_bank_transactions_test.rb +12 -12
  79. data/test/acceptance/about_online_invoice_test.rb +25 -0
  80. data/test/acceptance/acceptance_test.rb +28 -26
  81. data/test/acceptance/bank_transfer_test.rb +12 -17
  82. data/test/acceptance/bulk_operations_test.rb +18 -16
  83. data/test/acceptance/connections_test.rb +11 -0
  84. data/test/stub_responses/bad_request.json +6 -0
  85. data/test/stub_responses/connections.json +16 -0
  86. data/test/stub_responses/expired_oauth2_token.json +6 -0
  87. data/test/stub_responses/generic_response_error.json +6 -0
  88. data/test/stub_responses/invalid_oauth2_request_token.json +6 -0
  89. data/test/stub_responses/invalid_tenant_header.json +6 -0
  90. data/test/stub_responses/object_not_found.json +6 -0
  91. data/test/stub_responses/organisations.xml +10 -0
  92. data/test/stub_responses/payment_service.xml +15 -0
  93. data/test/test_helper.rb +17 -12
  94. data/test/unit/generic_application_test.rb +21 -10
  95. data/test/unit/http_test.rb +282 -10
  96. data/test/unit/models/address_test.rb +2 -2
  97. data/test/unit/models/bank_transaction_model_parsing_test.rb +2 -2
  98. data/test/unit/models/bank_transaction_test.rb +1 -1
  99. data/test/unit/models/bank_transaction_validation_test.rb +1 -1
  100. data/test/unit/models/contact_test.rb +20 -11
  101. data/test/unit/models/credit_note_test.rb +8 -8
  102. data/test/unit/models/employee_test.rb +4 -4
  103. data/test/unit/models/invoice_test.rb +12 -12
  104. data/test/unit/models/journal_line_test.rb +6 -6
  105. data/test/unit/models/journal_test.rb +4 -4
  106. data/test/unit/models/line_item_sum_test.rb +1 -1
  107. data/test/unit/models/line_item_test.rb +29 -37
  108. data/test/unit/models/manual_journal_test.rb +3 -3
  109. data/test/unit/models/organisation_test.rb +16 -2
  110. data/test/unit/models/payment_service_test.rb +29 -0
  111. data/test/unit/models/phone_test.rb +7 -7
  112. data/test/unit/models/prepayment_test.rb +4 -4
  113. data/test/unit/models/repeating_invoice_test.rb +3 -3
  114. data/test/unit/models/tax_rate_test.rb +2 -2
  115. data/test/unit/oauth2_test.rb +171 -0
  116. data/test/unit/oauth_config_test.rb +1 -1
  117. data/test/unit/record/base_model_test.rb +13 -13
  118. data/test/unit/record/base_test.rb +73 -4
  119. data/test/unit/record/block_validator_test.rb +1 -1
  120. data/test/unit/record/connection_test.rb +60 -0
  121. data/test/unit/record/model_definition_test.rb +36 -36
  122. data/test/unit/record/parse_params_test.rb +59 -0
  123. data/test/unit/record/parse_where_hash_test.rb +13 -13
  124. data/test/unit/record/record_association_test.rb +14 -14
  125. data/test/unit/record/validators_test.rb +43 -43
  126. data/test/unit/record_definition_test.rb +7 -7
  127. data/test/unit/report_definition_test.rb +7 -7
  128. data/test/unit/report_test.rb +20 -20
  129. data/test/unit_test_helper.rb +16 -0
  130. metadata +117 -27
  131. data/lib/xeroizer/models/payroll/home_address.rb +0 -24
  132. data/lib/xeroizer/partner_application.rb +0 -51
  133. data/lib/xeroizer/private_application.rb +0 -25
  134. data/lib/xeroizer/public_application.rb +0 -21
  135. data/test/unit/oauth_test.rb +0 -118
  136. data/test/unit/private_application_test.rb +0 -20
@@ -1,12 +1,12 @@
1
1
  module Xeroizer
2
2
  module Record
3
-
3
+
4
4
  class CreditNoteModel < BaseModel
5
-
5
+
6
6
  set_permissions :read, :write, :update
7
-
7
+
8
8
  include AttachmentModel::Extensions
9
-
9
+
10
10
  public
11
11
 
12
12
  # Retrieve the PDF version of the credit matching the `id`.
@@ -21,11 +21,11 @@ module Xeroizer
21
21
  pdf_data
22
22
  end
23
23
  end
24
-
24
+
25
25
  end
26
-
26
+
27
27
  class CreditNote < Base
28
-
28
+
29
29
  CREDIT_NOTE_STATUS = {
30
30
  'AUTHORISED' => 'Approved credit_notes awaiting payment',
31
31
  'DELETED' => 'Draft credit_notes that are deleted',
@@ -35,7 +35,7 @@ module Xeroizer
35
35
  'VOIDED' => 'Approved credit_notes that are voided'
36
36
  } unless defined?(CREDIT_NOTE_STATUS)
37
37
  CREDIT_NOTE_STATUSES = CREDIT_NOTE_STATUS.keys.sort
38
-
38
+
39
39
  CREDIT_NOTE_TYPE = {
40
40
  'ACCRECCREDIT' => 'Accounts Receivable',
41
41
  'ACCPAYCREDIT' => 'Accounts Payable'
@@ -43,14 +43,15 @@ module Xeroizer
43
43
  CREDIT_NOTE_TYPES = CREDIT_NOTE_TYPE.keys.sort
44
44
 
45
45
  include Attachment::Extensions
46
-
46
+
47
47
  set_primary_key :credit_note_id
48
48
  set_possible_primary_keys :credit_note_id, :credit_note_number
49
49
  list_contains_summary_only true
50
-
50
+
51
51
  guid :credit_note_id
52
52
  string :credit_note_number
53
53
  string :reference
54
+ guid :branding_theme_id
54
55
  string :type
55
56
  date :date
56
57
  date :due_date
@@ -65,20 +66,21 @@ module Xeroizer
65
66
  datetime :fully_paid_on_date
66
67
  boolean :sent_to_contact
67
68
  decimal :remaining_credit
69
+ decimal :applied_amount
68
70
  boolean :has_attachments
69
71
 
70
72
  belongs_to :contact
71
73
  has_many :line_items
72
74
  has_many :allocations
73
-
75
+
74
76
  validates_inclusion_of :type, :in => CREDIT_NOTE_TYPES
75
77
  validates_inclusion_of :status, :in => CREDIT_NOTE_STATUSES, :allow_blanks => true
76
78
  validates_associated :contact
77
79
  validates_associated :line_items
78
80
  validates_associated :allocations, :allow_blanks => true
79
-
81
+
80
82
  public
81
-
83
+
82
84
  # Access the contact name without forcing a download of
83
85
  # an incomplete, summary credit note.
84
86
  def contact_name
@@ -89,20 +91,20 @@ module Xeroizer
89
91
  # incomplete, summary credit note.
90
92
  def contact_id
91
93
  attributes[:contact] && attributes[:contact][:contact_id]
92
- end
93
-
94
+ end
95
+
94
96
  # Swallow assignment of attributes that should only be calculated automatically.
95
97
  def sub_total=(value); raise SettingTotalDirectlyNotSupported.new(:sub_total); end
96
98
  def total_tax=(value); raise SettingTotalDirectlyNotSupported.new(:total_tax); end
97
99
  def total=(value); raise SettingTotalDirectlyNotSupported.new(:total); end
98
-
100
+
99
101
  # Calculate sub_total from line_items.
100
102
  def sub_total(always_summary = false)
101
103
  if !always_summary && (new_record? || (!new_record? && line_items && line_items.size > 0))
102
- overall_sum = (line_items || []).inject(BigDecimal.new('0')) { | sum, line_item | sum + line_item.line_amount }
103
-
104
+ overall_sum = (line_items || []).inject(BigDecimal('0')) { | sum, line_item | sum + line_item.line_amount }
105
+
104
106
  # If the default amount types are inclusive of 'tax' then remove the tax amount from this sub-total.
105
- overall_sum -= total_tax if line_amount_types == 'Inclusive'
107
+ overall_sum -= total_tax if line_amount_types == 'Inclusive'
106
108
  overall_sum
107
109
  else
108
110
  attributes[:sub_total]
@@ -112,7 +114,7 @@ module Xeroizer
112
114
  # Calculate total_tax from line_items.
113
115
  def total_tax(always_summary = false)
114
116
  if !always_summary && (new_record? || (!new_record? && line_items && line_items.size > 0))
115
- (line_items || []).inject(BigDecimal.new('0')) { | sum, line_item | sum + line_item.tax_amount }
117
+ (line_items || []).inject(BigDecimal('0')) { | sum, line_item | sum + line_item.tax_amount }
116
118
  else
117
119
  attributes[:total_tax]
118
120
  end
@@ -126,14 +128,14 @@ module Xeroizer
126
128
  attributes[:total]
127
129
  end
128
130
  end
129
-
131
+
130
132
  # Retrieve the PDF version of this credit note.
131
133
  # @param [String] filename optional filename to store the PDF in instead of returning the data.
132
134
  def pdf(filename = nil)
133
135
  parent.pdf(id, filename)
134
136
  end
135
137
 
136
- def save
138
+ def save!
137
139
  # Calling parse_save_response() on the credit note will wipe out
138
140
  # the allocations, so we have to manually preserve them.
139
141
  allocations_backup = self.allocations
@@ -3,14 +3,26 @@ module Xeroizer
3
3
 
4
4
  class CurrencyModel < BaseModel
5
5
 
6
- set_permissions :read
6
+ set_permissions :read, :write
7
+
8
+ # Currencies can only be created (added), no update or delete is possible
9
+ def create_method
10
+ :http_put
11
+ end
7
12
 
8
13
  end
9
14
 
10
15
  class Currency < Base
16
+
17
+ # Currency does not have an ID
18
+ # This method overrides the base model to always treat a Currency as new (so it can be saved)
19
+ # Attempting to update a currency will result in a validation error.
20
+ def new_record?
21
+ true
22
+ end
11
23
 
12
24
  string :code
13
- string :description
25
+ string :description # read only
14
26
 
15
27
  end
16
28
 
@@ -7,6 +7,7 @@ module Xeroizer
7
7
  class FromBankAccount < Base
8
8
  guid :account_id
9
9
  string :code
10
+ string :name
10
11
  end
11
12
  end
12
13
  end
@@ -0,0 +1,72 @@
1
+ module Xeroizer
2
+ module Record
3
+
4
+ class HistoryRecordModel < BaseModel
5
+
6
+ module Extensions
7
+ def history(id)
8
+ application.HistoryRecord.history(url, id)
9
+ end
10
+
11
+ def add_note(id, details)
12
+ application.HistoryRecord.add_note(url, id, details)
13
+ end
14
+ end
15
+
16
+ set_permissions :read
17
+
18
+ # History Records can only be added, no update or delete is possible
19
+ def create_method
20
+ :http_put
21
+ end
22
+
23
+ def history(url, id)
24
+ response_xml = @application.http_get(@application.client, "#{url}/#{CGI.escape(id)}/history")
25
+
26
+ response = parse_response(response_xml)
27
+
28
+ response.response_items
29
+ end
30
+
31
+ def add_note(url, id, details)
32
+ record = build(details: details)
33
+ xml = to_bulk_xml([record])
34
+ response_xml = @application.http_put(@application.client,
35
+ "#{url}/#{CGI.escape(id)}/history",
36
+ xml,
37
+ raw_body: true
38
+ )
39
+ response = parse_response(response_xml)
40
+ if (response_items = response.response_items) && response_items.size > 0
41
+ response_items.size == 1 ? response_items.first : response_items
42
+ else
43
+ response
44
+ end
45
+ end
46
+
47
+ end
48
+
49
+ class HistoryRecord < Base
50
+
51
+ module Extensions
52
+ def history
53
+ parent.history(id)
54
+ end
55
+
56
+ def add_note(details)
57
+ parent.add_note(id, details)
58
+ end
59
+ end
60
+
61
+ datetime_utc :date_utc, :api_name => 'DateUTC'
62
+ string :date_utc_string, :api_name => 'DateUTCString'
63
+ string :changes
64
+ string :user
65
+ string :details
66
+
67
+ validates_presence_of :details
68
+
69
+ end
70
+
71
+ end
72
+ end
@@ -1,4 +1,6 @@
1
1
  require "xeroizer/models/attachment"
2
+ require "xeroizer/models/online_invoice"
3
+ require "xeroizer/models/history_record"
2
4
 
3
5
  module Xeroizer
4
6
  module Record
@@ -14,6 +16,8 @@ module Xeroizer
14
16
  set_permissions :read, :write, :update
15
17
 
16
18
  include AttachmentModel::Extensions
19
+ include OnlineInvoiceModel::Extensions
20
+ include HistoryRecordModel::Extensions
17
21
 
18
22
  public
19
23
 
@@ -51,6 +55,8 @@ module Xeroizer
51
55
  INVOICE_STATUSES = INVOICE_STATUS.keys.sort
52
56
 
53
57
  include Attachment::Extensions
58
+ include OnlineInvoice::Extensions
59
+ include HistoryRecord::Extensions
54
60
 
55
61
  set_primary_key :invoice_id
56
62
  set_possible_primary_keys :invoice_id, :invoice_number
@@ -86,8 +92,10 @@ module Xeroizer
86
92
  has_many :line_items, :complete_on_page => true
87
93
  has_many :payments
88
94
  has_many :credit_notes
95
+ has_many :prepayments
89
96
 
90
- validates_presence_of :date, :due_date, :unless => :new_record?
97
+ validates_presence_of :date, :if => :new_record?
98
+ validates_presence_of :due_date, :if => :approved?
91
99
  validates_inclusion_of :type, :in => INVOICE_TYPES
92
100
  validates_inclusion_of :status, :in => INVOICE_STATUSES, :unless => :new_record?
93
101
  validates_inclusion_of :line_amount_types, :in => LINE_AMOUNT_TYPES, :unless => :new_record?
@@ -148,7 +156,7 @@ module Xeroizer
148
156
  # Calculate sub_total from line_items.
149
157
  def sub_total(always_summary = false)
150
158
  if !@sub_total_is_set && not_summary_or_loaded_record(always_summary)
151
- overall_sum = (line_items || []).inject(BigDecimal.new('0')) { | sum, line_item | sum + line_item.line_amount }
159
+ overall_sum = (line_items || []).inject(BigDecimal('0')) { | sum, line_item | sum + line_item.line_amount }
152
160
 
153
161
  # If the default amount types are inclusive of 'tax' then remove the tax amount from this sub-total.
154
162
  overall_sum -= total_tax if line_amount_types == 'Inclusive'
@@ -161,7 +169,7 @@ module Xeroizer
161
169
  # Calculate total_tax from line_items.
162
170
  def total_tax(always_summary = false)
163
171
  if !@total_tax_is_set && not_summary_or_loaded_record(always_summary)
164
- (line_items || []).inject(BigDecimal.new('0')) { | sum, line_item | sum + line_item.tax_amount }
172
+ (line_items || []).inject(BigDecimal('0')) { | sum, line_item | sum + line_item.tax_amount }
165
173
  else
166
174
  attributes[:total_tax]
167
175
  end
@@ -206,6 +214,12 @@ module Xeroizer
206
214
  change_status!('AUTHORISED')
207
215
  end
208
216
 
217
+ # Send an email containing the invoice.
218
+ def email
219
+ email_url = "#{parent.url}/#{CGI.escape(id)}/Email"
220
+ parent.application.http_post(parent.application.client, email_url, "")
221
+ end
222
+
209
223
  protected
210
224
 
211
225
  def change_status!(new_status)
@@ -18,7 +18,6 @@ module Xeroizer
18
18
  string :purchase_description
19
19
  string :name
20
20
 
21
- decimal :unit_price
22
21
  decimal :total_cost_pool # read only
23
22
  decimal :quantity_on_hand # read only
24
23
 
@@ -27,6 +26,8 @@ module Xeroizer
27
26
  boolean :is_tracked_as_inventory # read only, infered from inventory_asset_account_code, cogs_account_code, is_sold and is_purchased
28
27
  string :inventory_asset_account_code
29
28
 
29
+ datetime_utc :updated_date_utc, api_name: 'UpdatedDateUTC'
30
+
30
31
  belongs_to :purchase_details, :model_name => 'ItemPurchaseDetails'
31
32
  belongs_to :sales_details, :model_name => 'ItemSalesDetails'
32
33
 
@@ -12,7 +12,7 @@ module Xeroizer
12
12
  decimal :unit_price
13
13
  string :account_code
14
14
  string :tax_type
15
- decimal :cogs_account_code
15
+ string :cogs_account_code, api_name: 'COGSAccountCode'
16
16
 
17
17
  end
18
18
 
@@ -4,7 +4,7 @@ require 'xeroizer/models/line_amount_type'
4
4
  module Xeroizer
5
5
  module Record
6
6
  class LineItemModel < BaseModel
7
-
7
+ set_permissions
8
8
  end
9
9
 
10
10
  class LineItem < Base
@@ -19,10 +19,13 @@ module Xeroizer
19
19
  decimal :tax_amount
20
20
  decimal :line_amount, :calculated => true
21
21
  decimal :discount_rate
22
+ decimal :discount_amount
22
23
  string :line_item_id
23
24
 
24
25
  has_many :tracking, :model_name => 'TrackingCategoryChild'
25
26
 
27
+ validates_presence_of :description, :unless => Proc.new { |line_item| line_item.item_code.present? }
28
+
26
29
  def initialize(parent)
27
30
  super(parent)
28
31
  @line_amount_set = false
@@ -39,16 +42,25 @@ module Xeroizer
39
42
  return attributes[:line_amount] if summary_only || @line_amount_set
40
43
 
41
44
  if quantity && unit_amount
42
- total = quantity * unit_amount
43
- if discount_rate
44
- BigDecimal((total * ((100 - discount_rate) / 100)).to_s).round(2)
45
+ total = coerce_numeric(quantity) * coerce_numeric(unit_amount)
46
+ if discount_rate.nonzero?
47
+ BigDecimal((total * ((100 - discount_rate.to_f) / 100)).to_s).round(2)
48
+ elsif discount_amount
49
+ BigDecimal((total - discount_amount).to_s).round(2)
45
50
  else
46
51
  BigDecimal(total.to_s).round(2)
47
52
  end
48
53
  end
49
54
  end
50
55
 
56
+ private
57
+
58
+ def coerce_numeric(number)
59
+ return number if number.is_a? Numeric
60
+ BigDecimal(number)
61
+ end
62
+
51
63
  end
52
-
64
+
53
65
  end
54
66
  end
@@ -34,7 +34,8 @@ module Xeroizer
34
34
  string :external_link_provider_name # only seems to be read-only at the moment
35
35
  boolean :show_on_cash_basis_reports
36
36
  datetime_utc :updated_date_utc, :api_name => 'UpdatedDateUTC'
37
-
37
+ boolean :has_attachments
38
+
38
39
  has_many :journal_lines, :model_name => 'ManualJournalLine', :complete_on_page => true
39
40
 
40
41
  validates_presence_of :narration
@@ -0,0 +1,37 @@
1
+ module Xeroizer
2
+ module Record
3
+
4
+ class OnlineInvoiceModel < BaseModel
5
+
6
+ module Extensions
7
+ def online_invoice(id)
8
+ application.OnlineInvoice.online_invoice(url, id)
9
+ end
10
+ end
11
+
12
+ set_permissions :read
13
+
14
+ def online_invoice(url, id)
15
+ response_xml = @application.http_get(@application.client, "#{url}/#{CGI.escape(id)}/OnlineInvoice")
16
+
17
+ response = parse_response(response_xml)
18
+
19
+ response.response_items.first
20
+ end
21
+
22
+ end
23
+
24
+ class OnlineInvoice < Base
25
+
26
+ module Extensions
27
+ def online_invoice
28
+ parent.online_invoice(id)
29
+ end
30
+ end
31
+
32
+ string :online_invoice_url
33
+
34
+ end
35
+
36
+ end
37
+ end
@@ -11,7 +11,7 @@ module Xeroizer
11
11
 
12
12
  guid :tracking_option_id
13
13
  string :name
14
-
14
+ string :status
15
15
  end
16
16
 
17
17
  end
@@ -1,3 +1,4 @@
1
+ require "xeroizer/models/payment_terms"
1
2
  module Xeroizer
2
3
  module Record
3
4
 
@@ -62,6 +63,7 @@ module Xeroizer
62
63
  has_many :addresses
63
64
  has_many :phones
64
65
  has_many :external_links
66
+ has_one :payment_terms, :model_name => 'PaymentTerms'
65
67
 
66
68
  validates :sales_tax_basis, :message => "is not a valid option" do
67
69
  valid = true
@@ -0,0 +1,22 @@
1
+ module Xeroizer
2
+ module Record
3
+
4
+ class PaymentServiceModel < BaseModel
5
+
6
+ set_permissions :read, :write, :update
7
+
8
+ end
9
+
10
+ class PaymentService < Base
11
+
12
+ set_primary_key :payment_service_id
13
+
14
+ guid :payment_service_id
15
+ string :payment_service_name
16
+ string :payment_service_url
17
+ string :payment_service_type
18
+ string :pay_now_text
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,53 @@
1
+ module Xeroizer
2
+ module Record
3
+ module Payroll
4
+
5
+ class AddressModel < PayrollBaseModel
6
+
7
+ class_inheritable_attributes :api_controller_name
8
+ class_inheritable_attributes :permissions
9
+ class_inheritable_attributes :xml_root_name
10
+ class_inheritable_attributes :optional_xml_root_name
11
+ class_inheritable_attributes :xml_node_name
12
+
13
+ end
14
+
15
+ class Address < PayrollBase
16
+
17
+ class_inheritable_attributes :fields, :possible_primary_keys, :primary_key_name, :summary_only, :validators
18
+
19
+
20
+ string :address_line1
21
+ string :address_line2
22
+ string :city
23
+ string :region
24
+ string :postal_code
25
+ string :country
26
+
27
+ # US Payroll fields
28
+ string :street_address
29
+ string :suite_or_apt_or_unit
30
+ string :state
31
+ string :zip
32
+ decimal :latitude
33
+ decimal :longitude
34
+
35
+ end
36
+
37
+ class HomeAddressModel < AddressModel
38
+ set_xml_node_name 'HomeAddress'
39
+ end
40
+
41
+ class HomeAddress < Address
42
+ end
43
+
44
+ class MailingAddressModel < AddressModel
45
+ set_xml_node_name 'MailingAddress'
46
+ end
47
+
48
+ class MailingAddress < Address
49
+ end
50
+
51
+ end
52
+ end
53
+ end
@@ -1,23 +1,35 @@
1
1
  module Xeroizer
2
2
  module Record
3
3
  module Payroll
4
-
4
+
5
5
  class BankAccountModel < PayrollBaseModel
6
-
6
+
7
7
  end
8
-
8
+
9
9
  class BankAccount < PayrollBase
10
-
10
+
11
11
  string :statement_text
12
12
  string :account_name
13
- string :bsb
13
+ string :bsb, :api_name => 'BSB'
14
14
  string :account_number
15
15
  boolean :remainder
16
16
  string :percentage
17
17
  decimal :amount
18
18
 
19
+ # US Payroll fields
20
+
21
+ BANK_ACCOUNT_TYPE = {
22
+ 'CHECKING' => '',
23
+ 'SAVINGS' => ''
24
+ } unless defined?(BANK_ACCOUNT_TYPE)
25
+
26
+ string :account_holder_name
27
+ string :account_type
28
+ string :routing_number
29
+
30
+ validates_inclusion_of :account_type, :in => BANK_ACCOUNT_TYPE
19
31
  end
20
32
 
21
- end
33
+ end
22
34
  end
23
35
  end
@@ -0,0 +1,26 @@
1
+ module Xeroizer
2
+ module Record
3
+ module Payroll
4
+
5
+ class BenefitLineModel < PayrollBaseModel
6
+
7
+ end
8
+
9
+ class BenefitLine < PayrollBase
10
+
11
+ BENEFIT_TYPE_CALCULATION_TYPE = {
12
+ 'FIXEDAMOUNT' => '',
13
+ 'STANDARDAMOUNT' => ''
14
+ } unless defined?(BENEFIT_TYPE_CALCULATION_TYPE)
15
+
16
+ guid :benefit_type_id, :api_name => 'BenefitTypeID'
17
+ string :calculation_type
18
+ decimal :amount
19
+
20
+ validates_presence_of :benefit_type_id, :calculation_type, :unless => :new_record?
21
+ validates_inclusion_of :calculation_type, :in => BENEFIT_TYPE_CALCULATION_TYPE
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,45 @@
1
+ module Xeroizer
2
+ module Record
3
+ module Payroll
4
+
5
+ class BenefitTypeModel < PayrollBaseModel
6
+
7
+ set_permissions :read
8
+
9
+ end
10
+
11
+ class BenefitType < PayrollBase
12
+
13
+ BENEFIT_CATEGORIES = {
14
+ 'AFTERTAXBENEFIT' => '',
15
+ 'DEPENDENTCARE' => '',
16
+ 'FLEXIBLESPENDINGACCOUNT' => '',
17
+ 'HEALTHSAVINGSACCOUNTSINGLEPLAN' => '',
18
+ 'HEALTHSAVINGSACCOUNTFAMILYPLAN' => '',
19
+ 'ROTH401KREITREMENTPLAN' => '',
20
+ 'ROTH403BRETIREMENTPLAN' => '',
21
+ 'SECTION125PLAN' => '',
22
+ 'SIMPLEIRARETIREMENTPLAN' => '',
23
+ '401KRETIREMENTPLAN' => '',
24
+ '403BRETIREMENTPLAN' => '',
25
+ '457RETIREMENTPLAN' => ''
26
+ } unless defined?(BENEFIT_CATEGORIES)
27
+
28
+ set_primary_key :benefit_type_id
29
+
30
+ guid :benefit_type_id
31
+ string :benefit_type
32
+ string :benefit_category
33
+ string :liability_account_code
34
+ string :expense_account_code
35
+ decimal :standard_amount
36
+ decimal :company_max
37
+ decimal :percentage
38
+ boolean :show_balance_on_paystub
39
+
40
+ validates_inclusion_of :benefit_category, :in => BENEFIT_CATEGORIES
41
+
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,32 @@
1
+ module Xeroizer
2
+ module Record
3
+ module Payroll
4
+
5
+ class DeductionLineModel < PayrollBaseModel
6
+
7
+ end
8
+
9
+ class DeductionLine < PayrollBase
10
+
11
+ DEDUCTION_TYPE_CALCULATION_TYPE = {
12
+ 'FIXEDAMOUNT' => '',
13
+ 'PRETAX' => '',
14
+ 'POSTTAX' => ''
15
+ } unless defined?(DEDUCTION_TYPE_CALCULATION_TYPE)
16
+
17
+ guid :deduction_type_id, :api_name => 'DeductionTypeID'
18
+ string :calculation_type
19
+
20
+ decimal :percentage
21
+ decimal :amount
22
+
23
+ # US Payroll fields
24
+ decimal :employee_max
25
+
26
+ validates_presence_of :earning_rate_id, :calculation_type, :unless => :new_record?
27
+ validates_inclusion_of :calculation_type, :in => DEDUCTION_TYPE_CALCULATION_TYPE
28
+ end
29
+
30
+ end
31
+ end
32
+ end