xeroizer 2.17.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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