xeroizer 2.16.5 → 2.17.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +21 -27
  3. data/lib/class_level_inheritable_attributes.rb +3 -0
  4. data/lib/xeroizer.rb +13 -1
  5. data/lib/xeroizer/exceptions.rb +1 -1
  6. data/lib/xeroizer/generic_application.rb +13 -1
  7. data/lib/xeroizer/http.rb +128 -120
  8. data/lib/xeroizer/models/account.rb +1 -0
  9. data/lib/xeroizer/models/address.rb +18 -9
  10. data/lib/xeroizer/models/attachment.rb +1 -1
  11. data/lib/xeroizer/models/balances.rb +1 -0
  12. data/lib/xeroizer/models/bank_transaction.rb +2 -2
  13. data/lib/xeroizer/models/bank_transfer.rb +28 -0
  14. data/lib/xeroizer/models/contact.rb +11 -4
  15. data/lib/xeroizer/models/credit_note.rb +9 -4
  16. data/lib/xeroizer/models/from_bank_account.rb +12 -0
  17. data/lib/xeroizer/models/invoice.rb +11 -3
  18. data/lib/xeroizer/models/invoice_reminder.rb +19 -0
  19. data/lib/xeroizer/models/line_item.rb +21 -9
  20. data/lib/xeroizer/models/manual_journal.rb +6 -0
  21. data/lib/xeroizer/models/organisation.rb +4 -0
  22. data/lib/xeroizer/models/overpayment.rb +40 -0
  23. data/lib/xeroizer/models/payroll/bank_account.rb +23 -0
  24. data/lib/xeroizer/models/payroll/employee.rb +45 -0
  25. data/lib/xeroizer/models/payroll/home_address.rb +24 -0
  26. data/lib/xeroizer/models/prepayment.rb +1 -0
  27. data/lib/xeroizer/models/tax_rate.rb +5 -4
  28. data/lib/xeroizer/models/to_bank_account.rb +12 -0
  29. data/lib/xeroizer/oauth.rb +8 -8
  30. data/lib/xeroizer/partner_application.rb +4 -8
  31. data/lib/xeroizer/payroll_application.rb +28 -0
  32. data/lib/xeroizer/private_application.rb +2 -4
  33. data/lib/xeroizer/record/base_model.rb +137 -122
  34. data/lib/xeroizer/record/base_model_http_proxy.rb +1 -1
  35. data/lib/xeroizer/record/payroll_base.rb +25 -0
  36. data/lib/xeroizer/record/payroll_base_model.rb +29 -0
  37. data/lib/xeroizer/record/record_association_helper.rb +13 -14
  38. data/lib/xeroizer/record/validation_helper.rb +1 -1
  39. data/lib/xeroizer/record/xml_helper.rb +10 -8
  40. data/lib/xeroizer/report/aged_receivables_by_contact.rb +0 -1
  41. data/lib/xeroizer/report/base.rb +0 -1
  42. data/lib/xeroizer/report/factory.rb +3 -3
  43. data/lib/xeroizer/report/row/header.rb +4 -4
  44. data/lib/xeroizer/report/row/xml_helper.rb +2 -2
  45. data/lib/xeroizer/version.rb +1 -1
  46. data/test/acceptance/about_creating_prepayment_test.rb +46 -0
  47. data/test/acceptance/about_fetching_bank_transactions_test.rb +21 -21
  48. data/test/acceptance/acceptance_test.rb +4 -4
  49. data/test/acceptance/bank_transaction_reference_data.rb +3 -1
  50. data/test/acceptance/bank_transfer_test.rb +26 -0
  51. data/test/test_helper.rb +6 -4
  52. data/test/unit/models/address_test.rb +92 -0
  53. data/test/unit/models/bank_transaction_validation_test.rb +1 -1
  54. data/test/unit/models/contact_test.rb +20 -4
  55. data/test/unit/models/line_item_test.rb +20 -6
  56. data/test/unit/models/tax_rate_test.rb +52 -1
  57. data/test/unit/record/base_model_test.rb +1 -1
  58. data/test/unit/record/base_test.rb +9 -6
  59. data/test/unit/record/model_definition_test.rb +2 -2
  60. data/test/unit/report_test.rb +19 -21
  61. metadata +20 -3
@@ -64,6 +64,7 @@ module Xeroizer
64
64
  string :bank_account_number
65
65
  string :reporting_code
66
66
  string :reporting_code_name
67
+ datetime_utc :updated_date_utc, api_name: 'UpdatedDateUTC'
67
68
 
68
69
  end
69
70
 
@@ -1,18 +1,18 @@
1
1
  module Xeroizer
2
2
  module Record
3
-
3
+
4
4
  class AddressModel < BaseModel
5
-
5
+
6
6
  end
7
-
7
+
8
8
  class Address < Base
9
-
9
+
10
10
  ADDRESS_TYPE = {
11
11
  'STREET' => 'Street',
12
12
  'POBOX' => 'PO Box',
13
13
  'DEFAULT' => 'Default address type'
14
14
  } unless defined?(ADDRESS_TYPE)
15
-
15
+
16
16
  string :address_type, :internal_name => :type
17
17
  string :attention_to
18
18
  string :address_line1, :internal_name => :line1
@@ -23,10 +23,19 @@ module Xeroizer
23
23
  string :region
24
24
  string :postal_code
25
25
  string :country
26
-
26
+
27
27
  validates_inclusion_of :type, :in => ADDRESS_TYPE.keys
28
-
28
+ validates_length_of :address_line1, :max => 500
29
+ validates_length_of :address_line2, :max => 500
30
+ validates_length_of :address_line3, :max => 500
31
+ validates_length_of :address_line4, :max => 500
32
+ validates_length_of :city, :max => 255
33
+ validates_length_of :region, :max => 255
34
+ validates_length_of :postal_code, :max => 50
35
+ validates_length_of :country, :max => 50
36
+ validates_length_of :attention_to, :max => 255
37
+
29
38
  end
30
-
39
+
31
40
  end
32
- end
41
+ end
@@ -82,7 +82,7 @@ module Xeroizer
82
82
  def get(filename = nil)
83
83
  data = parent.application.http_get(parent.application.client, url)
84
84
  if filename
85
- File.open(filename, "w") { | fp | fp.write data }
85
+ File.open(filename, "wb") { | fp | fp.write data }
86
86
  nil
87
87
  else
88
88
  data
@@ -6,6 +6,7 @@ module Xeroizer
6
6
 
7
7
  class BalancesModel < BaseModel
8
8
  set_permissions :read
9
+ set_api_controller_name 'Balances'
9
10
  end
10
11
 
11
12
  class Balances < Base
@@ -52,8 +52,8 @@ module Xeroizer
52
52
  :in => Xeroizer::Record::LINE_AMOUNT_TYPES, :allow_blanks => false
53
53
 
54
54
  validates_inclusion_of :type,
55
- :in => %w{SPEND RECEIVE RECEIVE-PREPAYMENT RECEIVE-OVERPAYMENT}, :allow_blanks => false,
56
- :message => "Invalid type. Expected either SPEND, RECEIVE, RECEIVE-PREPAYMENT or RECEIVE-OVERPAYMENT."
55
+ :in => %w{RECEIVE RECEIVE-OVERPAYMENT RECEIVE-PREPAYMENT SPEND SPEND-OVERPAYMENT SPEND-PREPAYMENT}, :allow_blanks => false,
56
+ :message => "Invalid type. Expected one of https://developer.xero.com/documentation/api/types#BankTransactionTypes"
57
57
  validates_inclusion_of :status, :in => BANK_TRANSACTION_STATUSES, :allow_blanks => true
58
58
 
59
59
  validates_presence_of :contact, :bank_account, :allow_blanks => false
@@ -0,0 +1,28 @@
1
+ module Xeroizer
2
+ module Record
3
+ class BankTransferModel < BaseModel
4
+ set_permissions :read, :write, :update
5
+ end
6
+
7
+ class BankTransfer < Base
8
+
9
+ def initialize(parent)
10
+ super parent
11
+ end
12
+
13
+ set_primary_key :bank_transfer_id
14
+
15
+ string :bank_transfer_id, :api_name => "BankTransferID"
16
+ datetime_utc :created_date_utc, :api_name => "CreatedDateUTC"
17
+ date :date
18
+ decimal :amount
19
+ decimal :currency_rate
20
+ string :from_bank_transaction_id, :api_name => "FromBankTransactionID"
21
+ string :to_bank_transaction_id, :api_name => "ToBankTransactionID"
22
+
23
+ validates_presence_of :from_bank_account, :to_bank_account, :allow_blanks => false
24
+ belongs_to :from_bank_account, :model_name => 'FromBankAccount'
25
+ belongs_to :to_bank_account, :model_name => 'ToBankAccount'
26
+ end
27
+ end
28
+ end
@@ -10,6 +10,8 @@ module Xeroizer
10
10
 
11
11
  set_permissions :read, :write, :update
12
12
 
13
+ include AttachmentModel::Extensions
14
+
13
15
  end
14
16
 
15
17
  class Contact < Base
@@ -20,6 +22,8 @@ module Xeroizer
20
22
  'ARCHIVED' => 'Archived'
21
23
  } unless defined?(CONTACT_STATUS)
22
24
 
25
+ include Attachment::Extensions
26
+
23
27
  set_primary_key :contact_id
24
28
  set_possible_primary_keys :contact_id, :contact_number
25
29
  list_contains_summary_only true
@@ -37,13 +41,15 @@ module Xeroizer
37
41
  string :last_name
38
42
  string :email_address
39
43
  string :skype_user_name
40
- string :contact_groups
41
44
  string :default_currency
42
45
  string :purchases_default_account_code
43
46
  string :sales_default_account_code
44
47
  datetime_utc :updated_date_utc, :api_name => 'UpdatedDateUTC'
45
48
  boolean :is_supplier
46
49
  boolean :is_customer
50
+ string :website # read only
51
+ decimal :discount # read only
52
+ boolean :has_attachments
47
53
 
48
54
  has_many :addresses, :list_complete => true
49
55
  has_many :phones, :list_complete => true
@@ -53,12 +59,13 @@ module Xeroizer
53
59
  has_many :sales_tracking_categories, :model_name => 'ContactSalesTrackingCategory'
54
60
  has_many :purchases_tracking_categories, :model_name => 'ContactPurchasesTrackingCategory'
55
61
 
56
- has_one :balances ,:model_name => 'Balances', :list_complete => true
57
- has_one :batch_payments ,:model_name => 'BatchPayments', :list_complete => true
58
- has_one :payment_terms ,:model_name => 'PaymentTerms', :list_complete => true
62
+ has_one :balances, :model_name => 'Balances', :list_complete => true
63
+ has_one :batch_payments, :model_name => 'BatchPayments', :list_complete => true
64
+ has_one :payment_terms, :model_name => 'PaymentTerms', :list_complete => true
59
65
 
60
66
  validates_presence_of :name, :unless => Proc.new { | contact | contact.contact_id.present?}
61
67
  validates_inclusion_of :contact_status, :in => CONTACT_STATUS.keys, :allow_blanks => true
68
+ validates_associated :addresses, allow_blanks: true
62
69
 
63
70
  def email_address?
64
71
  email_address.present?
@@ -5,6 +5,8 @@ module Xeroizer
5
5
 
6
6
  set_permissions :read, :write, :update
7
7
 
8
+ include AttachmentModel::Extensions
9
+
8
10
  public
9
11
 
10
12
  # Retrieve the PDF version of the credit matching the `id`.
@@ -39,6 +41,8 @@ module Xeroizer
39
41
  'ACCPAYCREDIT' => 'Accounts Payable'
40
42
  } unless defined?(CREDIT_NOTE_TYPE)
41
43
  CREDIT_NOTE_TYPES = CREDIT_NOTE_TYPE.keys.sort
44
+
45
+ include Attachment::Extensions
42
46
 
43
47
  set_primary_key :credit_note_id
44
48
  set_possible_primary_keys :credit_note_id, :credit_note_number
@@ -60,7 +64,8 @@ module Xeroizer
60
64
  decimal :currency_rate
61
65
  datetime :fully_paid_on_date
62
66
  boolean :sent_to_contact
63
- decimal :remaining_credit
67
+ decimal :remaining_credit
68
+ boolean :has_attachments
64
69
 
65
70
  belongs_to :contact
66
71
  has_many :line_items
@@ -94,11 +99,11 @@ module Xeroizer
94
99
  # Calculate sub_total from line_items.
95
100
  def sub_total(always_summary = false)
96
101
  if !always_summary && (new_record? || (!new_record? && line_items && line_items.size > 0))
97
- sum = (line_items || []).inject(BigDecimal.new('0')) { | sum, line_item | sum + line_item.line_amount }
102
+ overall_sum = (line_items || []).inject(BigDecimal.new('0')) { | sum, line_item | sum + line_item.line_amount }
98
103
 
99
104
  # If the default amount types are inclusive of 'tax' then remove the tax amount from this sub-total.
100
- sum -= total_tax if line_amount_types == 'Inclusive'
101
- sum
105
+ overall_sum -= total_tax if line_amount_types == 'Inclusive'
106
+ overall_sum
102
107
  else
103
108
  attributes[:sub_total]
104
109
  end
@@ -0,0 +1,12 @@
1
+ module Xeroizer
2
+ module Record
3
+ class FromBankAccountModel < BaseModel
4
+ set_permissions :read
5
+ end
6
+
7
+ class FromBankAccount < Base
8
+ guid :account_id
9
+ string :code
10
+ end
11
+ end
12
+ end
@@ -69,6 +69,7 @@ module Xeroizer
69
69
  decimal :sub_total, :calculated => true
70
70
  decimal :total_tax, :calculated => true
71
71
  decimal :total, :calculated => true
72
+ decimal :total_discount
72
73
  decimal :amount_due
73
74
  decimal :amount_paid
74
75
  decimal :amount_credited
@@ -77,6 +78,7 @@ module Xeroizer
77
78
  decimal :currency_rate
78
79
  datetime :fully_paid_on_date
79
80
  datetime :expected_payment_date
81
+ datetime :planned_payment_date
80
82
  boolean :sent_to_contact
81
83
  boolean :has_attachments
82
84
 
@@ -94,6 +96,12 @@ module Xeroizer
94
96
  validates_associated :line_items, :if => :approved?
95
97
 
96
98
  public
99
+ def initialize(parent)
100
+ super(parent)
101
+ @sub_total_is_set = false
102
+ @total_tax_is_set = false
103
+ @total_is_set = false
104
+ end
97
105
 
98
106
  # Access the contact name without forcing a download of
99
107
  # an incomplete, summary invoice.
@@ -140,11 +148,11 @@ module Xeroizer
140
148
  # Calculate sub_total from line_items.
141
149
  def sub_total(always_summary = false)
142
150
  if !@sub_total_is_set && not_summary_or_loaded_record(always_summary)
143
- sum = (line_items || []).inject(BigDecimal.new('0')) { | sum, line_item | sum + line_item.line_amount }
151
+ overall_sum = (line_items || []).inject(BigDecimal.new('0')) { | sum, line_item | sum + line_item.line_amount }
144
152
 
145
153
  # If the default amount types are inclusive of 'tax' then remove the tax amount from this sub-total.
146
- sum -= total_tax if line_amount_types == 'Inclusive'
147
- sum
154
+ overall_sum -= total_tax if line_amount_types == 'Inclusive'
155
+ overall_sum
148
156
  else
149
157
  attributes[:sub_total]
150
158
  end
@@ -0,0 +1,19 @@
1
+ module Xeroizer
2
+ module Record
3
+
4
+ class InvoiceReminderModel < BaseModel
5
+
6
+ set_api_controller_name 'InvoiceReminders/Settings'
7
+
8
+ set_permissions :read
9
+
10
+ end
11
+
12
+ class InvoiceReminder < Base
13
+
14
+ boolean :enabled
15
+
16
+ end
17
+
18
+ end
19
+ end
@@ -4,12 +4,12 @@ require 'xeroizer/models/line_amount_type'
4
4
  module Xeroizer
5
5
  module Record
6
6
  class LineItemModel < BaseModel
7
-
7
+
8
8
  end
9
-
9
+
10
10
  class LineItem < Base
11
11
  TAX_TYPE = Account::TAX_TYPE unless defined?(TAX_TYPE)
12
-
12
+
13
13
  string :item_code
14
14
  string :description
15
15
  decimal :quantity
@@ -20,22 +20,34 @@ module Xeroizer
20
20
  decimal :line_amount, :calculated => true
21
21
  decimal :discount_rate
22
22
  string :line_item_id
23
-
23
+
24
24
  has_many :tracking, :model_name => 'TrackingCategoryChild'
25
-
25
+
26
+ def initialize(parent)
27
+ super(parent)
28
+ @line_amount_set = false
29
+ end
30
+
26
31
  def line_amount=(line_amount)
27
32
  @line_amount_set = true
28
33
  attributes[:line_amount] = line_amount
29
34
  end
30
-
35
+
31
36
  # Calculate the line_total (if there is a quantity and unit_amount).
32
37
  # Description-only lines have been allowed since Xero V2.09.
33
38
  def line_amount(summary_only = false)
34
39
  return attributes[:line_amount] if summary_only || @line_amount_set
35
-
36
- BigDecimal((quantity * unit_amount).to_s).round(2) if quantity && unit_amount
40
+
41
+ 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
+ else
46
+ BigDecimal(total.to_s).round(2)
47
+ end
48
+ end
37
49
  end
38
-
50
+
39
51
  end
40
52
 
41
53
  end
@@ -1,9 +1,13 @@
1
+ require "xeroizer/models/attachment"
2
+
1
3
  module Xeroizer
2
4
  module Record
3
5
 
4
6
  class ManualJournalModel < BaseModel
5
7
 
6
8
  set_permissions :read, :write, :update
9
+
10
+ include AttachmentModel::Extensions
7
11
 
8
12
  end
9
13
 
@@ -14,6 +18,8 @@ module Xeroizer
14
18
  'POSTED' => 'Posted'
15
19
  } unless defined?(JOURNAL_STATUS)
16
20
  JOURNAL_STATUSES = JOURNAL_STATUS.keys.sort
21
+
22
+ include Attachment::Extensions
17
23
 
18
24
  set_primary_key :manual_journal_id
19
25
  set_possible_primary_keys :manual_journal_id
@@ -36,9 +36,12 @@ module Xeroizer
36
36
  string :name
37
37
  string :legal_name
38
38
  string :short_code
39
+ string :organisation_id
39
40
  boolean :pays_tax
40
41
  string :version
41
42
  string :organisation_type
43
+ string :organisation_entity_type
44
+ string :line_of_business
42
45
  string :base_currency
43
46
  string :country_code
44
47
  boolean :is_demo_company
@@ -58,6 +61,7 @@ module Xeroizer
58
61
 
59
62
  has_many :addresses
60
63
  has_many :phones
64
+ has_many :external_links
61
65
 
62
66
  validates :sales_tax_basis, :message => "is not a valid option" do
63
67
  valid = true
@@ -0,0 +1,40 @@
1
+ module Xeroizer
2
+ module Record
3
+
4
+ class OverpaymentModel < BaseModel
5
+
6
+ set_xml_root_name 'Overpayments'
7
+ set_api_controller_name 'Overpayment'
8
+ set_permissions :read
9
+
10
+ end
11
+
12
+ class Overpayment < Base
13
+ set_primary_key :overpayment_id
14
+
15
+ guid :overpayment_id
16
+ date :date
17
+ string :status
18
+ string :line_amount_types
19
+ decimal :sub_total
20
+ decimal :total_tax
21
+ decimal :total
22
+ datetime_utc :updated_date_utc, :api_name => 'UpdatedDateUTC'
23
+ string :currency_code
24
+ string :type
25
+ decimal :remaining_credit
26
+ boolean :has_attachments
27
+
28
+ belongs_to :contact
29
+ belongs_to :invoice
30
+ has_many :allocations
31
+ has_many :line_items
32
+ has_many :payments
33
+
34
+ def contact_id
35
+ contact.id if contact
36
+ end
37
+
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,23 @@
1
+ module Xeroizer
2
+ module Record
3
+ module Payroll
4
+
5
+ class BankAccountModel < PayrollBaseModel
6
+
7
+ end
8
+
9
+ class BankAccount < PayrollBase
10
+
11
+ string :statement_text
12
+ string :account_name
13
+ string :bsb
14
+ string :account_number
15
+ boolean :remainder
16
+ string :percentage
17
+ decimal :amount
18
+
19
+ end
20
+
21
+ end
22
+ end
23
+ end