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.
- checksums.yaml +5 -5
- data/README.md +246 -213
- data/lib/xeroizer/connection.rb +49 -0
- data/lib/xeroizer/exceptions.rb +4 -0
- data/lib/xeroizer/generic_application.rb +13 -5
- data/lib/xeroizer/http.rb +7 -80
- data/lib/xeroizer/http_response.rb +154 -0
- data/lib/xeroizer/models/bank_account.rb +1 -0
- data/lib/xeroizer/models/bank_transaction.rb +1 -0
- data/lib/xeroizer/models/batch_payment.rb +27 -0
- data/lib/xeroizer/models/branding_theme.rb +49 -9
- data/lib/xeroizer/models/contact.rb +12 -6
- data/lib/xeroizer/models/contact_group.rb +45 -0
- data/lib/xeroizer/models/credit_note.rb +24 -22
- data/lib/xeroizer/models/currency.rb +14 -2
- data/lib/xeroizer/models/from_bank_account.rb +1 -0
- data/lib/xeroizer/models/history_record.rb +72 -0
- data/lib/xeroizer/models/invoice.rb +17 -3
- data/lib/xeroizer/models/item.rb +2 -1
- data/lib/xeroizer/models/item_purchase_details.rb +1 -1
- data/lib/xeroizer/models/line_item.rb +17 -5
- data/lib/xeroizer/models/manual_journal.rb +2 -1
- data/lib/xeroizer/models/online_invoice.rb +37 -0
- data/lib/xeroizer/models/option.rb +1 -1
- data/lib/xeroizer/models/organisation.rb +2 -0
- data/lib/xeroizer/models/payment_service.rb +22 -0
- data/lib/xeroizer/models/payroll/address.rb +53 -0
- data/lib/xeroizer/models/payroll/bank_account.rb +18 -6
- data/lib/xeroizer/models/payroll/benefit_line.rb +26 -0
- data/lib/xeroizer/models/payroll/benefit_type.rb +45 -0
- data/lib/xeroizer/models/payroll/deduction_line.rb +32 -0
- data/lib/xeroizer/models/payroll/deduction_type.rb +49 -0
- data/lib/xeroizer/models/payroll/earnings_line.rb +39 -0
- data/lib/xeroizer/models/payroll/earnings_type.rb +53 -0
- data/lib/xeroizer/models/payroll/employee.rb +30 -8
- data/lib/xeroizer/models/payroll/leave_application.rb +27 -0
- data/lib/xeroizer/models/payroll/leave_line.rb +30 -0
- data/lib/xeroizer/models/payroll/leave_period.rb +15 -0
- data/lib/xeroizer/models/payroll/pay_items.rb +22 -0
- data/lib/xeroizer/models/payroll/pay_run.rb +33 -0
- data/lib/xeroizer/models/payroll/pay_schedule.rb +40 -0
- data/lib/xeroizer/models/payroll/pay_template.rb +24 -0
- data/lib/xeroizer/models/payroll/payment_method.rb +24 -0
- data/lib/xeroizer/models/payroll/paystub.rb +44 -0
- data/lib/xeroizer/models/payroll/reimbursement_line.rb +21 -0
- data/lib/xeroizer/models/payroll/reimbursement_type.rb +22 -0
- data/lib/xeroizer/models/payroll/salary_and_wage.rb +29 -0
- data/lib/xeroizer/models/payroll/super_line.rb +40 -0
- data/lib/xeroizer/models/payroll/tax_declaration.rb +50 -0
- data/lib/xeroizer/models/payroll/time_off_line.rb +20 -0
- data/lib/xeroizer/models/payroll/time_off_type.rb +32 -0
- data/lib/xeroizer/models/payroll/work_location.rb +25 -0
- data/lib/xeroizer/models/prepayment.rb +1 -0
- data/lib/xeroizer/models/purchase_order.rb +6 -6
- data/lib/xeroizer/models/quote.rb +76 -0
- data/lib/xeroizer/models/schedule.rb +1 -0
- data/lib/xeroizer/models/tax_component.rb +1 -0
- data/lib/xeroizer/models/to_bank_account.rb +1 -0
- data/lib/xeroizer/oauth.rb +12 -1
- data/lib/xeroizer/oauth2.rb +82 -0
- data/lib/xeroizer/oauth2_application.rb +49 -0
- data/lib/xeroizer/payroll_application.rb +8 -3
- data/lib/xeroizer/record/base.rb +11 -2
- data/lib/xeroizer/record/base_model.rb +1 -1
- data/lib/xeroizer/record/base_model_http_proxy.rb +37 -17
- data/lib/xeroizer/record/model_definition_helper.rb +1 -1
- data/lib/xeroizer/record/payroll_base.rb +4 -0
- data/lib/xeroizer/record/record_association_helper.rb +4 -4
- data/lib/xeroizer/record/validators/associated_validator.rb +1 -0
- data/lib/xeroizer/record/xml_helper.rb +18 -18
- data/lib/xeroizer/report/aged_receivables_by_contact.rb +1 -1
- data/lib/xeroizer/report/cell_xml_helper.rb +13 -13
- data/lib/xeroizer/response.rb +22 -17
- data/lib/xeroizer/version.rb +1 -1
- data/lib/xeroizer.rb +34 -4
- data/test/acceptance/about_creating_bank_transactions_test.rb +89 -81
- data/test/acceptance/about_creating_prepayment_test.rb +25 -30
- data/test/acceptance/about_fetching_bank_transactions_test.rb +12 -12
- data/test/acceptance/about_online_invoice_test.rb +25 -0
- data/test/acceptance/acceptance_test.rb +28 -26
- data/test/acceptance/bank_transfer_test.rb +12 -17
- data/test/acceptance/bulk_operations_test.rb +18 -16
- data/test/acceptance/connections_test.rb +11 -0
- data/test/stub_responses/bad_request.json +6 -0
- data/test/stub_responses/connections.json +16 -0
- data/test/stub_responses/expired_oauth2_token.json +6 -0
- data/test/stub_responses/generic_response_error.json +6 -0
- data/test/stub_responses/invalid_oauth2_request_token.json +6 -0
- data/test/stub_responses/invalid_tenant_header.json +6 -0
- data/test/stub_responses/object_not_found.json +6 -0
- data/test/stub_responses/organisations.xml +10 -0
- data/test/stub_responses/payment_service.xml +15 -0
- data/test/test_helper.rb +17 -12
- data/test/unit/generic_application_test.rb +21 -10
- data/test/unit/http_test.rb +282 -10
- data/test/unit/models/address_test.rb +2 -2
- data/test/unit/models/bank_transaction_model_parsing_test.rb +2 -2
- data/test/unit/models/bank_transaction_test.rb +1 -1
- data/test/unit/models/bank_transaction_validation_test.rb +1 -1
- data/test/unit/models/contact_test.rb +20 -11
- data/test/unit/models/credit_note_test.rb +8 -8
- data/test/unit/models/employee_test.rb +4 -4
- data/test/unit/models/invoice_test.rb +12 -12
- data/test/unit/models/journal_line_test.rb +6 -6
- data/test/unit/models/journal_test.rb +4 -4
- data/test/unit/models/line_item_sum_test.rb +1 -1
- data/test/unit/models/line_item_test.rb +29 -37
- data/test/unit/models/manual_journal_test.rb +3 -3
- data/test/unit/models/organisation_test.rb +16 -2
- data/test/unit/models/payment_service_test.rb +29 -0
- data/test/unit/models/phone_test.rb +7 -7
- data/test/unit/models/prepayment_test.rb +4 -4
- data/test/unit/models/repeating_invoice_test.rb +3 -3
- data/test/unit/models/tax_rate_test.rb +2 -2
- data/test/unit/oauth2_test.rb +171 -0
- data/test/unit/oauth_config_test.rb +1 -1
- data/test/unit/record/base_model_test.rb +13 -13
- data/test/unit/record/base_test.rb +73 -4
- data/test/unit/record/block_validator_test.rb +1 -1
- data/test/unit/record/connection_test.rb +60 -0
- data/test/unit/record/model_definition_test.rb +36 -36
- data/test/unit/record/parse_params_test.rb +59 -0
- data/test/unit/record/parse_where_hash_test.rb +13 -13
- data/test/unit/record/record_association_test.rb +14 -14
- data/test/unit/record/validators_test.rb +43 -43
- data/test/unit/record_definition_test.rb +7 -7
- data/test/unit/report_definition_test.rb +7 -7
- data/test/unit/report_test.rb +20 -20
- data/test/unit_test_helper.rb +16 -0
- metadata +117 -27
- data/lib/xeroizer/models/payroll/home_address.rb +0 -24
- data/lib/xeroizer/partner_application.rb +0 -51
- data/lib/xeroizer/private_application.rb +0 -25
- data/lib/xeroizer/public_application.rb +0 -21
- data/test/unit/oauth_test.rb +0 -118
- 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
|
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
|
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
|
|
@@ -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, :
|
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
|
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
|
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)
|
data/lib/xeroizer/models/item.rb
CHANGED
@@ -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
|
|
@@ -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
|
@@ -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
|