xeroizer 2.15.5 → 2.15.6
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.
- data/README.md +14 -3
- data/lib/xeroizer.rb +5 -0
- data/lib/xeroizer/generic_application.rb +15 -9
- data/lib/xeroizer/http.rb +44 -34
- data/lib/xeroizer/models/account.rb +15 -11
- data/lib/xeroizer/models/allocation.rb +13 -0
- data/lib/xeroizer/models/attachment.rb +93 -0
- data/lib/xeroizer/models/bank_transaction.rb +3 -2
- data/lib/xeroizer/models/contact.rb +20 -12
- data/lib/xeroizer/models/contact_person.rb +20 -0
- data/lib/xeroizer/models/credit_note.rb +2 -0
- data/lib/xeroizer/models/expense_claim.rb +29 -0
- data/lib/xeroizer/models/invoice.rb +42 -29
- data/lib/xeroizer/models/line_item.rb +1 -0
- data/lib/xeroizer/models/organisation.rb +6 -1
- data/lib/xeroizer/models/payment.rb +16 -11
- data/lib/xeroizer/models/receipt.rb +39 -0
- data/lib/xeroizer/models/tax_component.rb +13 -0
- data/lib/xeroizer/models/tax_rate.rb +14 -3
- data/lib/xeroizer/models/user.rb +26 -0
- data/lib/xeroizer/oauth.rb +3 -3
- data/lib/xeroizer/record/base.rb +40 -31
- data/lib/xeroizer/record/base_model.rb +31 -25
- data/lib/xeroizer/record/base_model_http_proxy.rb +4 -1
- data/lib/xeroizer/record/record_association_helper.rb +35 -35
- data/lib/xeroizer/record/xml_helper.rb +1 -1
- data/lib/xeroizer/report/factory.rb +2 -1
- data/lib/xeroizer/version.rb +3 -0
- data/test/stub_responses/organisation.xml +30 -0
- data/test/stub_responses/tax_rates.xml +81 -1
- data/test/stub_responses/users.xml +17 -0
- data/test/unit/generic_application_test.rb +21 -0
- data/test/unit/http_test.rb +18 -0
- data/test/unit/models/bank_transaction_test.rb +1 -4
- data/test/unit/models/line_item_sum_test.rb +3 -2
- data/test/unit/models/tax_rate_test.rb +81 -0
- data/test/unit/oauth_test.rb +4 -2
- data/test/unit/record/base_test.rb +1 -1
- data/test/unit/record/model_definition_test.rb +9 -3
- data/test/unit/record/record_association_test.rb +1 -1
- data/test/unit/record_definition_test.rb +1 -1
- metadata +540 -205
- data/.bundle/config +0 -2
- data/.gitattributes +0 -22
- data/Gemfile +0 -20
- data/Gemfile.lock +0 -59
- data/Rakefile +0 -55
- data/VERSION +0 -1
- data/xeroizer.gemspec +0 -409
@@ -29,6 +29,7 @@ module Xeroizer
|
|
29
29
|
|
30
30
|
datetime_utc :updated_date_utc, :api_name => "UpdatedDateUTC"
|
31
31
|
date :fully_paid_on_date
|
32
|
+
string :url
|
32
33
|
string :reference
|
33
34
|
string :bank_transaction_id, :api_name => "BankTransactionID"
|
34
35
|
boolean :is_reconciled
|
@@ -45,8 +46,8 @@ module Xeroizer
|
|
45
46
|
:in => Xeroizer::Record::LINE_AMOUNT_TYPES, :allow_blanks => false
|
46
47
|
|
47
48
|
validates_inclusion_of :type,
|
48
|
-
:in => %w{SPEND RECEIVE}, :allow_blanks => false,
|
49
|
-
:message => "Invalid type. Expected either SPEND or RECEIVE."
|
49
|
+
:in => %w{SPEND RECEIVE RECEIVE-PREPAYMENT RECEIVE-OVERPAYMENT}, :allow_blanks => false,
|
50
|
+
:message => "Invalid type. Expected either SPEND, RECEIVE, RECEIVE-PREPAYMENT or RECEIVE-OVERPAYMENT."
|
50
51
|
validates_inclusion_of :status, :in => BANK_TRANSACTION_STATUSES, :unless => :new_record?
|
51
52
|
|
52
53
|
validates_presence_of :contact, :bank_account, :allow_blanks => false
|
@@ -1,23 +1,26 @@
|
|
1
|
+
require "xeroizer/models/contact_person"
|
2
|
+
|
1
3
|
module Xeroizer
|
2
4
|
module Record
|
3
|
-
|
5
|
+
|
4
6
|
class ContactModel < BaseModel
|
5
|
-
|
7
|
+
|
6
8
|
set_permissions :read, :write, :update
|
7
|
-
|
9
|
+
|
8
10
|
end
|
9
|
-
|
11
|
+
|
10
12
|
class Contact < Base
|
11
|
-
|
13
|
+
|
12
14
|
CONTACT_STATUS = {
|
13
15
|
'ACTIVE' => 'Active',
|
14
|
-
'DELETED' => 'Deleted'
|
16
|
+
'DELETED' => 'Deleted',
|
17
|
+
'ARCHIVED' => 'Archived'
|
15
18
|
} unless defined?(CONTACT_STATUS)
|
16
|
-
|
19
|
+
|
17
20
|
set_primary_key :contact_id
|
18
21
|
set_possible_primary_keys :contact_id, :contact_number
|
19
22
|
list_contains_summary_only true
|
20
|
-
|
23
|
+
|
21
24
|
guid :contact_id
|
22
25
|
string :contact_number
|
23
26
|
string :contact_status
|
@@ -35,15 +38,20 @@ module Xeroizer
|
|
35
38
|
datetime_utc :updated_date_utc, :api_name => 'UpdatedDateUTC'
|
36
39
|
boolean :is_supplier
|
37
40
|
boolean :is_customer
|
38
|
-
|
41
|
+
|
39
42
|
has_many :addresses, :list_complete => true
|
40
43
|
has_many :phones, :list_complete => true
|
41
44
|
has_many :contact_groups
|
42
|
-
|
45
|
+
has_many :contact_persons, :internal_name => :contact_people
|
46
|
+
|
43
47
|
validates_presence_of :name
|
44
48
|
validates_inclusion_of :contact_status, :in => CONTACT_STATUS.keys, :allow_blanks => true
|
45
|
-
|
49
|
+
|
50
|
+
def email_address?
|
51
|
+
email_address.present?
|
52
|
+
end
|
53
|
+
|
46
54
|
end
|
47
|
-
|
55
|
+
|
48
56
|
end
|
49
57
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'xeroizer/models/account'
|
2
|
+
require 'xeroizer/models/line_amount_type'
|
3
|
+
|
4
|
+
module Xeroizer
|
5
|
+
module Record
|
6
|
+
class ContactPersonModel < BaseModel
|
7
|
+
set_xml_root_name "ContactPersons"
|
8
|
+
end
|
9
|
+
|
10
|
+
class ContactPerson < Base
|
11
|
+
|
12
|
+
string :first_name
|
13
|
+
string :last_name
|
14
|
+
string :email_address
|
15
|
+
boolean :include_in_emails
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -62,11 +62,13 @@ module Xeroizer
|
|
62
62
|
|
63
63
|
belongs_to :contact
|
64
64
|
has_many :line_items
|
65
|
+
has_many :allocations
|
65
66
|
|
66
67
|
validates_inclusion_of :type, :in => CREDIT_NOTE_TYPES
|
67
68
|
validates_inclusion_of :status, :in => CREDIT_NOTE_STATUSES, :allow_blanks => true
|
68
69
|
validates_associated :contact
|
69
70
|
validates_associated :line_items
|
71
|
+
validates_associated :allocations, :allow_blanks => true
|
70
72
|
|
71
73
|
public
|
72
74
|
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Xeroizer
|
2
|
+
module Record
|
3
|
+
|
4
|
+
class ExpenseClaimModel < BaseModel
|
5
|
+
|
6
|
+
set_permissions :read, :write, :update
|
7
|
+
|
8
|
+
end
|
9
|
+
|
10
|
+
class ExpenseClaim < Base
|
11
|
+
|
12
|
+
set_primary_key :expense_claim_id
|
13
|
+
|
14
|
+
guid :expense_claim_id
|
15
|
+
string :status
|
16
|
+
decimal :total
|
17
|
+
decimal :amount_due
|
18
|
+
decimal :amount_paid
|
19
|
+
date :payment_due_date
|
20
|
+
date :reporting_date
|
21
|
+
datetime_utc :updated_date_utc, :api_name => 'UpdatedDateUTC'
|
22
|
+
|
23
|
+
belongs_to :user
|
24
|
+
has_many :receipts
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -1,32 +1,36 @@
|
|
1
|
+
require "xeroizer/models/attachment"
|
2
|
+
|
1
3
|
module Xeroizer
|
2
4
|
module Record
|
3
|
-
|
5
|
+
|
4
6
|
class InvoiceModel < BaseModel
|
5
7
|
# To create a new invoice, use the folowing
|
6
8
|
# $xero_client.Invoice.build(type: 'ACCREC', ..., contact: {name: 'Foo Bar'},...)
|
7
9
|
# Note that we are not making an api request to xero just to get the contact
|
8
|
-
|
10
|
+
|
9
11
|
set_permissions :read, :write, :update
|
10
|
-
|
12
|
+
|
13
|
+
include AttachmentModel::Extensions
|
14
|
+
|
11
15
|
public
|
12
|
-
|
16
|
+
|
13
17
|
# Retrieve the PDF version of the invoice matching the `id`.
|
14
18
|
# @param [String] id invoice's ID.
|
15
19
|
# @param [String] filename optional filename to store the PDF in instead of returning the data.
|
16
20
|
def pdf(id, filename = nil)
|
17
21
|
pdf_data = @application.http_get(@application.client, "#{url}/#{CGI.escape(id)}", :response => :pdf)
|
18
22
|
if filename
|
19
|
-
File.open(filename, "
|
23
|
+
File.open(filename, "wb") { | fp | fp.write pdf_data }
|
20
24
|
nil
|
21
25
|
else
|
22
26
|
pdf_data
|
23
27
|
end
|
24
28
|
end
|
25
|
-
|
29
|
+
|
26
30
|
end
|
27
|
-
|
31
|
+
|
28
32
|
class Invoice < Base
|
29
|
-
|
33
|
+
|
30
34
|
INVOICE_TYPE = {
|
31
35
|
'ACCREC' => 'Accounts Receivable',
|
32
36
|
'ACCPAY' => 'Accounts Payable'
|
@@ -42,11 +46,13 @@ module Xeroizer
|
|
42
46
|
'VOIDED' => 'Approved invoices that are voided'
|
43
47
|
} unless defined?(INVOICE_STATUS)
|
44
48
|
INVOICE_STATUSES = INVOICE_STATUS.keys.sort
|
45
|
-
|
49
|
+
|
50
|
+
include Attachment::Extensions
|
51
|
+
|
46
52
|
set_primary_key :invoice_id
|
47
53
|
set_possible_primary_keys :invoice_id, :invoice_number
|
48
54
|
list_contains_summary_only true
|
49
|
-
|
55
|
+
|
50
56
|
guid :invoice_id
|
51
57
|
string :invoice_number
|
52
58
|
string :reference
|
@@ -65,14 +71,16 @@ module Xeroizer
|
|
65
71
|
decimal :amount_credited
|
66
72
|
datetime_utc :updated_date_utc, :api_name => 'UpdatedDateUTC'
|
67
73
|
string :currency_code
|
74
|
+
decimal :currency_rate
|
68
75
|
datetime :fully_paid_on_date
|
69
76
|
boolean :sent_to_contact
|
70
|
-
|
77
|
+
boolean :has_attachments
|
78
|
+
|
71
79
|
belongs_to :contact
|
72
80
|
has_many :line_items
|
73
81
|
has_many :payments
|
74
82
|
has_many :credit_notes
|
75
|
-
|
83
|
+
|
76
84
|
validates_presence_of :date, :due_date, :unless => :new_record?
|
77
85
|
validates_inclusion_of :type, :in => INVOICE_TYPES
|
78
86
|
validates_inclusion_of :status, :in => INVOICE_STATUSES, :unless => :new_record?
|
@@ -80,9 +88,9 @@ module Xeroizer
|
|
80
88
|
validates_associated :contact
|
81
89
|
validates_associated :line_items, :allow_blanks => true, :unless => :approved?
|
82
90
|
validates_associated :line_items, :if => :approved?
|
83
|
-
|
91
|
+
|
84
92
|
public
|
85
|
-
|
93
|
+
|
86
94
|
# Access the contact name without forcing a download of
|
87
95
|
# an incomplete, summary invoice.
|
88
96
|
def contact_name
|
@@ -94,12 +102,12 @@ module Xeroizer
|
|
94
102
|
def contact_id
|
95
103
|
attributes[:contact] && attributes[:contact][:contact_id]
|
96
104
|
end
|
97
|
-
|
105
|
+
|
98
106
|
# Helper method to check if the invoice has been approved.
|
99
107
|
def approved?
|
100
108
|
[ 'AUTHORISED', 'PAID', 'VOIDED' ].include? status
|
101
109
|
end
|
102
|
-
|
110
|
+
|
103
111
|
# Helper method to check if the invoice is accounts payable.
|
104
112
|
def accounts_payable?
|
105
113
|
type == 'ACCPAY'
|
@@ -109,12 +117,12 @@ module Xeroizer
|
|
109
117
|
def accounts_receivable?
|
110
118
|
type == 'ACCREC'
|
111
119
|
end
|
112
|
-
|
120
|
+
|
113
121
|
def sub_total=(sub_total)
|
114
122
|
@sub_total_is_set = true
|
115
123
|
attributes[:sub_total] = sub_total
|
116
124
|
end
|
117
|
-
|
125
|
+
|
118
126
|
def total_tax=(total_tax)
|
119
127
|
@total_tax_is_set = true
|
120
128
|
attributes[:total_tax] = total_tax
|
@@ -129,9 +137,9 @@ module Xeroizer
|
|
129
137
|
def sub_total(always_summary = false)
|
130
138
|
if !@sub_total_is_set && not_summary_or_loaded_record(always_summary)
|
131
139
|
sum = (line_items || []).inject(BigDecimal.new('0')) { | sum, line_item | sum + line_item.line_amount }
|
132
|
-
|
140
|
+
|
133
141
|
# If the default amount types are inclusive of 'tax' then remove the tax amount from this sub-total.
|
134
|
-
sum -= total_tax if line_amount_types == 'Inclusive'
|
142
|
+
sum -= total_tax if line_amount_types == 'Inclusive'
|
135
143
|
sum
|
136
144
|
else
|
137
145
|
attributes[:sub_total]
|
@@ -155,16 +163,16 @@ module Xeroizer
|
|
155
163
|
attributes[:total]
|
156
164
|
end
|
157
165
|
end
|
158
|
-
|
166
|
+
|
159
167
|
def not_summary_or_loaded_record(always_summary)
|
160
168
|
!always_summary && loaded_record?
|
161
169
|
end
|
162
170
|
|
163
171
|
def loaded_record?
|
164
|
-
new_record? ||
|
172
|
+
new_record? ||
|
165
173
|
(!new_record? && line_items && line_items.size > 0)
|
166
174
|
end
|
167
|
-
|
175
|
+
|
168
176
|
# Retrieve the PDF version of this invoice.
|
169
177
|
# @param [String] filename optional filename to store the PDF in instead of returning the data.
|
170
178
|
def pdf(filename = nil)
|
@@ -173,23 +181,28 @@ module Xeroizer
|
|
173
181
|
|
174
182
|
# Delete an approved invoice with no payments.
|
175
183
|
def delete!
|
176
|
-
|
184
|
+
change_status!('DELETED')
|
177
185
|
end
|
178
186
|
|
179
187
|
# Void an approved invoice with no payments.
|
180
188
|
def void!
|
181
|
-
|
189
|
+
change_status!('VOIDED')
|
190
|
+
end
|
191
|
+
|
192
|
+
# Approve a draft invoice
|
193
|
+
def approve!
|
194
|
+
change_status!('AUTHORISED')
|
182
195
|
end
|
183
196
|
|
184
197
|
protected
|
185
198
|
|
186
|
-
def
|
187
|
-
raise CannotChangeInvoiceStatus.new(
|
199
|
+
def change_status!(new_status)
|
200
|
+
raise CannotChangeInvoiceStatus.new(self, new_status) unless self.payments.size == 0
|
188
201
|
self.status = new_status
|
189
202
|
self.save
|
190
203
|
end
|
191
|
-
|
204
|
+
|
192
205
|
end
|
193
|
-
|
206
|
+
|
194
207
|
end
|
195
208
|
end
|
@@ -13,6 +13,7 @@ module Xeroizer
|
|
13
13
|
string :api_key, :api_name => 'APIKey'
|
14
14
|
string :name
|
15
15
|
string :legal_name
|
16
|
+
string :short_code
|
16
17
|
boolean :pays_tax
|
17
18
|
string :version
|
18
19
|
string :organisation_type
|
@@ -26,9 +27,13 @@ module Xeroizer
|
|
26
27
|
date :end_of_year_lock_date
|
27
28
|
string :tax_number
|
28
29
|
string :registration_number
|
30
|
+
string :timezone
|
29
31
|
datetime :created_date_utc, :api_name => 'CreatedDateUTC'
|
30
32
|
|
33
|
+
has_many :addresses
|
34
|
+
has_many :phones
|
35
|
+
|
31
36
|
end
|
32
37
|
|
33
38
|
end
|
34
|
-
end
|
39
|
+
end
|
@@ -1,17 +1,17 @@
|
|
1
1
|
module Xeroizer
|
2
2
|
module Record
|
3
|
-
|
3
|
+
|
4
4
|
class PaymentModel < BaseModel
|
5
|
-
|
5
|
+
|
6
6
|
set_xml_root_name 'Payments'
|
7
7
|
set_permissions :read, :write
|
8
|
-
|
8
|
+
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
class Payment < Base
|
12
|
-
|
12
|
+
|
13
13
|
set_primary_key :payment_id
|
14
|
-
|
14
|
+
|
15
15
|
guid :payment_id
|
16
16
|
date :date
|
17
17
|
decimal :amount
|
@@ -23,20 +23,25 @@ module Xeroizer
|
|
23
23
|
|
24
24
|
belongs_to :account
|
25
25
|
belongs_to :invoice
|
26
|
-
|
26
|
+
belongs_to :credit_note
|
27
|
+
|
27
28
|
def invoice_id
|
28
29
|
invoice.id if invoice
|
29
30
|
end
|
30
|
-
|
31
|
+
|
32
|
+
def credit_note_id
|
33
|
+
credit_note.id if credit_note
|
34
|
+
end
|
35
|
+
|
31
36
|
def account_id
|
32
37
|
account.id if account
|
33
38
|
end
|
34
|
-
|
39
|
+
|
35
40
|
def account_code
|
36
41
|
account.code if account
|
37
42
|
end
|
38
|
-
|
43
|
+
|
39
44
|
end
|
40
|
-
|
45
|
+
|
41
46
|
end
|
42
47
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Xeroizer
|
2
|
+
module Record
|
3
|
+
|
4
|
+
class ReceiptModel < BaseModel
|
5
|
+
|
6
|
+
set_permissions :read, :write, :update
|
7
|
+
|
8
|
+
include AttachmentModel::Extensions
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
class Receipt < Base
|
13
|
+
|
14
|
+
include Attachment::Extensions
|
15
|
+
|
16
|
+
set_primary_key :receipt_id
|
17
|
+
set_possible_primary_keys :receipt_id, :receipt_number
|
18
|
+
|
19
|
+
guid :receipt_id
|
20
|
+
string :receipt_number
|
21
|
+
string :reference
|
22
|
+
string :status
|
23
|
+
string :line_amount_types
|
24
|
+
decimal :sub_total, :calculated => true
|
25
|
+
decimal :total_tax, :calculated => true
|
26
|
+
decimal :total, :calculated => true
|
27
|
+
date :date
|
28
|
+
string :url
|
29
|
+
boolean :has_attachments
|
30
|
+
datetime_utc :updated_date_utc, :api_name => 'UpdatedDateUTC'
|
31
|
+
|
32
|
+
belongs_to :user
|
33
|
+
belongs_to :contact
|
34
|
+
has_many :line_items
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|