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
@@ -3,14 +3,14 @@ require 'active_support/time'
3
3
  module Xeroizer
4
4
  module Record
5
5
  module XmlHelper
6
-
6
+
7
7
  def self.included(base)
8
8
  base.extend(ClassMethods)
9
9
  base.send :include, InstanceMethods
10
10
  end
11
-
11
+
12
12
  module ClassMethods
13
-
13
+
14
14
  # Build a record instance from the XML node.
15
15
  def build_from_node(node, parent, base_module)
16
16
  record = new(parent)
@@ -22,14 +22,14 @@ module Xeroizer
22
22
  when :string then element.text
23
23
  when :boolean then (element.text == 'true')
24
24
  when :integer then element.text.to_i
25
- when :decimal then BigDecimal.new(element.text)
25
+ when :decimal then BigDecimal(element.text)
26
26
  when :date then Date.parse(element.text)
27
27
  when :datetime then Time.parse(element.text)
28
28
  when :datetime_utc then ActiveSupport::TimeZone['UTC'].parse(element.text).utc
29
- when :belongs_to
29
+ when :belongs_to
30
30
  model_name = field[:model_name] ? field[:model_name].to_sym : element.name.to_sym
31
31
  base_module.const_get(model_name).build_from_node(element, parent, base_module)
32
-
32
+
33
33
  when :has_many
34
34
  if element.element_children.size > 0
35
35
  sub_field_name = field[:model_name] ? field[:model_name].to_sym : element.children.first.name.to_sym
@@ -51,13 +51,13 @@ module Xeroizer
51
51
  parent.mark_clean(record)
52
52
  record
53
53
  end
54
-
54
+
55
55
  end
56
-
56
+
57
57
  module InstanceMethods
58
-
58
+
59
59
  public
60
-
60
+
61
61
  # Turn a record into its XML representation.
62
62
  def to_xml(b = Builder::XmlMarkup.new(:indent => 2))
63
63
  optional_root_tag(parent.class.optional_xml_root_name, b) do |c|
@@ -70,9 +70,9 @@ module Xeroizer
70
70
  }
71
71
  end
72
72
  end
73
-
73
+
74
74
  protected
75
-
75
+
76
76
  # Add top-level root name if required.
77
77
  # E.g. Payments need specifying in the form:
78
78
  # <Payments>
@@ -87,7 +87,7 @@ module Xeroizer
87
87
  yield(b)
88
88
  end
89
89
  end
90
-
90
+
91
91
  # Format an attribute for use in the XML passed to Xero.
92
92
  def xml_value_from_field(b, field, value)
93
93
  case field[:type]
@@ -95,10 +95,10 @@ module Xeroizer
95
95
  when :string then b.tag!(field[:api_name], value)
96
96
  when :boolean then b.tag!(field[:api_name], value ? 'true' : 'false')
97
97
  when :integer then b.tag!(field[:api_name], value.to_i)
98
- when :decimal
98
+ when :decimal
99
99
  real_value = case value
100
100
  when BigDecimal then value.to_s
101
- when String then BigDecimal.new(value).to_s
101
+ when String then BigDecimal(value).to_s
102
102
  else value
103
103
  end
104
104
  b.tag!(field[:api_name], real_value)
@@ -111,13 +111,13 @@ module Xeroizer
111
111
  else raise ArgumentError.new("Expected Date or Time object for the #{field[:api_name]} field")
112
112
  end
113
113
  b.tag!(field[:api_name], real_value)
114
-
114
+
115
115
  when :datetime then b.tag!(field[:api_name], value.utc.strftime("%Y-%m-%dT%H:%M:%S"))
116
- when :belongs_to
116
+ when :belongs_to
117
117
  value.to_xml(b)
118
118
  nil
119
119
 
120
- when :has_many
120
+ when :has_many
121
121
  if value.size > 0
122
122
  sub_parent = value.first.parent
123
123
  b.tag!(sub_parent.class.xml_root_name || sub_parent.model_name.pluralize) {
@@ -31,7 +31,7 @@ module Xeroizer
31
31
  end
32
32
 
33
33
  def sum(column_name, &block)
34
- sections.first.rows.inject(BigDecimal.new('0')) do | sum, row |
34
+ sections.first.rows.inject(BigDecimal('0')) do | sum, row |
35
35
  sum += row.cell(column_name).value if row.class == Xeroizer::Report::Row && (block.nil? || block.call(row))
36
36
  sum
37
37
  end
@@ -1,19 +1,19 @@
1
1
  module Xeroizer
2
2
  module Report
3
3
  module CellXmlHelper
4
-
4
+
5
5
  def self.included(base)
6
6
  base.extend(ClassMethods)
7
7
  base.send :include, InstanceMethods
8
8
  end
9
-
9
+
10
10
  module ClassMethods
11
-
11
+
12
12
  public
13
-
13
+
14
14
  # Create an instance of Cell from the node.
15
15
  #
16
- # Additionally, parse the attributes and return them as a hash to the
16
+ # Additionally, parse the attributes and return them as a hash to the
17
17
  # cell. If a cell's attributes look like:
18
18
  #
19
19
  # <Attributes>
@@ -22,7 +22,7 @@ module Xeroizer
22
22
  # <Id>account</Id>
23
23
  # </Attribute>
24
24
  # </Attributes>
25
- #
25
+ #
26
26
  # Return a hash like:
27
27
  #
28
28
  # {
@@ -42,17 +42,17 @@ module Xeroizer
42
42
  end
43
43
  cell
44
44
  end
45
-
45
+
46
46
  protected
47
47
 
48
48
  def parse_value(value)
49
49
  case value
50
- when /^[-]?\d+(\.\d+)?$/ then BigDecimal.new(value)
51
- when /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$/ then Time.xmlschema(value)
52
- else value
50
+ when /\A[-]?\d+(\.\d+)?\z/ then BigDecimal(value)
51
+ when /\A\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\z/ then Time.xmlschema(value)
52
+ else value
53
53
  end
54
54
  end
55
-
55
+
56
56
  def parse_attribute(attribute_node)
57
57
  id = nil
58
58
  value = nil
@@ -65,10 +65,10 @@ module Xeroizer
65
65
  [id, value]
66
66
  end
67
67
  end
68
-
68
+
69
69
  module InstanceMethods
70
70
  end
71
-
71
+
72
72
  end
73
73
  end
74
74
  end
@@ -1,9 +1,9 @@
1
1
  # Copyright (c) 2008 Tim Connor <tlconnor@gmail.com>
2
- #
2
+ #
3
3
  # Permission to use, copy, modify, and/or distribute this software for any
4
4
  # purpose with or without fee is hereby granted, provided that the above
5
5
  # copyright notice and this permission notice appear in all copies.
6
- #
6
+ #
7
7
  # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
8
  # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
9
  # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
@@ -14,23 +14,23 @@
14
14
 
15
15
  module Xeroizer
16
16
  class Response
17
-
17
+
18
18
  attr_accessor :id, :status, :errors, :provider, :date_time, :response_items, :request_params, :request_xml, :response_xml
19
-
19
+
20
20
  class << self
21
-
21
+
22
22
  # Parse the response retreived during any request.
23
23
  def parse(raw_response, request = {}, options = {}, &block)
24
24
  response = Xeroizer::Response.new
25
25
  response.response_xml = raw_response
26
-
26
+
27
27
  doc = Nokogiri::XML(raw_response) { | cfg | cfg.noblanks }
28
-
28
+
29
29
  # check for responses we don't understand
30
30
  raise Xeroizer::UnparseableResponse.new(doc.root.name) unless doc.root.name == 'Response'
31
-
31
+
32
32
  doc.root.elements.each do | element |
33
-
33
+
34
34
  # Text element
35
35
  if element.children && element.children.size == 1 && element.children.first.text?
36
36
  case element.name
@@ -39,31 +39,36 @@ module Xeroizer
39
39
  when 'ProviderName' then response.provider = element.text
40
40
  when 'DateTimeUTC' then response.date_time = Time.parse(element.text)
41
41
  end
42
-
42
+
43
+ # Special case for Paystubs and PayItems because they are not wrapped in plural element or
44
+ # don't have singular children
45
+ elsif element.children && element.children.size > 0 && (element.name == 'Paystub' || element.name == 'PayItems')
46
+ yield(response, [element], element.name)
47
+
43
48
  # Records in response
44
49
  elsif element.children && element.children.size > 0
45
50
  yield(response, element.children, element.children.first.name)
46
51
  end
47
52
  end
48
-
53
+
49
54
  response
50
55
  end
51
-
56
+
52
57
  end
53
-
58
+
54
59
  public
55
-
60
+
56
61
  def initialize
57
62
  @response_items = []
58
63
  end
59
-
64
+
60
65
  def success?
61
66
  status == 'OK'
62
67
  end
63
-
68
+
64
69
  def error
65
70
  errors.blank? ? nil : errors[0]
66
71
  end
67
-
72
+
68
73
  end
69
74
  end
@@ -1,3 +1,3 @@
1
1
  module Xeroizer
2
- VERSION = "2.17.1".freeze
2
+ VERSION = "3.0.0".freeze
3
3
  end
data/lib/xeroizer.rb CHANGED
@@ -5,6 +5,7 @@ require 'active_support/inflector'
5
5
  require "active_support/core_ext/array"
6
6
  require "active_support/core_ext/big_decimal/conversions"
7
7
  require 'oauth'
8
+ require 'oauth2'
8
9
  require 'oauth/signature/rsa/sha1'
9
10
  require 'nokogiri'
10
11
  require 'builder'
@@ -17,14 +18,17 @@ $: << File.expand_path(File.dirname(__FILE__))
17
18
  require 'class_level_inheritable_attributes'
18
19
  require 'xeroizer/exceptions'
19
20
  require 'xeroizer/oauth'
21
+ require 'xeroizer/oauth2'
20
22
  require 'xeroizer/http_encoding_helper'
21
23
  require 'xeroizer/http'
24
+ require 'xeroizer/connection'
22
25
 
23
26
  require 'xeroizer/record/base_model'
24
27
  require 'xeroizer/record/payroll_base_model'
25
28
  require 'xeroizer/record/base'
26
29
  require 'xeroizer/record/payroll_base'
27
30
  require 'xeroizer/configuration'
31
+ require 'xeroizer/http_response'
28
32
 
29
33
  # Include models
30
34
  require 'xeroizer/models/account'
@@ -33,6 +37,7 @@ require 'xeroizer/models/allocation'
33
37
  require 'xeroizer/models/branding_theme'
34
38
  require 'xeroizer/models/bank_transaction'
35
39
  require 'xeroizer/models/bank_account'
40
+ require 'xeroizer/models/batch_payment'
36
41
  require 'xeroizer/models/from_bank_account'
37
42
  require 'xeroizer/models/to_bank_account'
38
43
  require 'xeroizer/models/bank_transfer'
@@ -42,8 +47,10 @@ require 'xeroizer/models/credit_note'
42
47
  require 'xeroizer/models/currency'
43
48
  require 'xeroizer/models/employee'
44
49
  require 'xeroizer/models/expense_claim'
50
+ require 'xeroizer/models/history_record'
45
51
  require 'xeroizer/models/invoice'
46
52
  require 'xeroizer/models/invoice_reminder'
53
+ require 'xeroizer/models/online_invoice'
47
54
  require 'xeroizer/models/item'
48
55
  require 'xeroizer/models/item_purchase_details'
49
56
  require 'xeroizer/models/item_sales_details'
@@ -55,10 +62,12 @@ require 'xeroizer/models/manual_journal_line'
55
62
  require 'xeroizer/models/option'
56
63
  require 'xeroizer/models/organisation'
57
64
  require 'xeroizer/models/payment'
65
+ require 'xeroizer/models/payment_service'
58
66
  require 'xeroizer/models/prepayment'
59
67
  require 'xeroizer/models/overpayment'
60
68
  require 'xeroizer/models/phone'
61
69
  require 'xeroizer/models/purchase_order'
70
+ require 'xeroizer/models/quote'
62
71
  require 'xeroizer/models/receipt'
63
72
  require 'xeroizer/models/repeating_invoice'
64
73
  require 'xeroizer/models/schedule'
@@ -71,16 +80,37 @@ require 'xeroizer/models/journal_line_tracking_category'
71
80
  require 'xeroizer/models/contact_sales_tracking_category'
72
81
  require 'xeroizer/models/contact_purchases_tracking_category'
73
82
 
74
- require 'xeroizer/models/payroll/home_address'
75
83
  require 'xeroizer/models/payroll/bank_account'
84
+ require 'xeroizer/models/payroll/benefit_line'
85
+ require 'xeroizer/models/payroll/benefit_type'
86
+ require 'xeroizer/models/payroll/deduction_line'
87
+ require 'xeroizer/models/payroll/deduction_type'
88
+ require 'xeroizer/models/payroll/earnings_line'
89
+ require 'xeroizer/models/payroll/earnings_type'
76
90
  require 'xeroizer/models/payroll/employee'
91
+ require 'xeroizer/models/payroll/address'
92
+ require 'xeroizer/models/payroll/leave_line'
93
+ require 'xeroizer/models/payroll/pay_items'
94
+ require 'xeroizer/models/payroll/pay_run'
95
+ require 'xeroizer/models/payroll/pay_template'
96
+ require 'xeroizer/models/payroll/payment_method'
97
+ require 'xeroizer/models/payroll/pay_schedule'
98
+ require 'xeroizer/models/payroll/paystub'
99
+ require 'xeroizer/models/payroll/reimbursement_line'
100
+ require 'xeroizer/models/payroll/reimbursement_type'
101
+ require 'xeroizer/models/payroll/salary_and_wage'
102
+ require 'xeroizer/models/payroll/super_line'
103
+ require 'xeroizer/models/payroll/tax_declaration'
104
+ require 'xeroizer/models/payroll/time_off_line'
105
+ require 'xeroizer/models/payroll/time_off_type'
106
+ require 'xeroizer/models/payroll/work_location'
107
+ require 'xeroizer/models/payroll/leave_application'
108
+ require 'xeroizer/models/payroll/leave_period'
77
109
 
78
110
  require 'xeroizer/report/factory'
79
111
 
80
112
  require 'xeroizer/response'
81
113
 
82
114
  require 'xeroizer/generic_application'
83
- require 'xeroizer/public_application'
84
- require 'xeroizer/private_application'
85
- require 'xeroizer/partner_application'
115
+ require 'xeroizer/oauth2_application'
86
116
  require 'xeroizer/payroll_application'
@@ -4,40 +4,67 @@ require "acceptance_test"
4
4
  class AboutCreatingBankTransactions < Test::Unit::TestCase
5
5
  include AcceptanceTest
6
6
 
7
- let :client do
8
- Xeroizer::PrivateApplication.new(@consumer_key, @consumer_secret, @key_file)
7
+ def assert_exists(bank_transaction, client)
8
+ assert_not_nil bank_transaction.id,
9
+ "Cannot check for exitence unless the bank transaction has non-null identifier"
10
+ assert_not_nil client.BankTransaction.find bank_transaction.id
11
+ end
12
+
13
+ def any_line_items(account)
14
+ [{
15
+ :description => "Clingfilm bike shorts",
16
+ :quantity => 1,
17
+ :unit_amount => "17.00",
18
+ :account_code => account.code,
19
+ :tax_type => account.tax_type
20
+ }]
9
21
  end
10
22
 
11
- def setup
12
- super
13
- all_accounts = client.Account.all
23
+ def get_inclusive_tax(amount, tax_rate)
24
+ inclusive_tax = amount * (1 - (100/(100 + tax_rate)))
25
+ BigDecimal(inclusive_tax.to_s).round(2)
26
+ end
27
+
28
+ def get_exclusive_tax(amount, tax_rate)
29
+ exclusive_tax = amount * (tax_rate/100)
30
+ BigDecimal(exclusive_tax.to_s).round(2)
31
+ end
32
+
33
+ def get_tax_rate(tax_type, client)
34
+ @all_tax_types ||= client.TaxRate.all
35
+ @all_tax_types.select{|tax_rate| tax_rate.tax_type == tax_type}.first
36
+ end
37
+
38
+ setup do
39
+ @client = AcceptanceTestHelpers.oauth2_client
40
+ all_accounts = @client.Account.all
14
41
  @account = all_accounts.select{|acct| acct.status == "ACTIVE" && acct.type == "REVENUE"}.first
15
- @bank_account = all_accounts.select{|acct| acct.status == "ACTIVE" && acct.type == "BANK"}.first
42
+ @bank_account = all_accounts.select{|acct| acct.status == "ACTIVE" && acct.type == "BANK"}.first
16
43
  end
17
44
 
18
45
  can "create a new SPEND bank transaction" do
19
- new_transaction = client.BankTransaction.build(
20
- :type => "SPEND",
21
- :contact => { :name => "Jazz Kang" },
22
- :line_items => any_line_items(@account),
23
- :bank_account => { :account_id => @bank_account.account_id }
46
+ new_transaction = @client.BankTransaction.build(
47
+ :type => "SPEND",
48
+ :contact => { :name => "Jazz Kang" },
49
+ :line_items => any_line_items(@account),
50
+ :bank_account => { :account_id => @bank_account.account_id }
24
51
  )
25
52
 
26
53
  assert new_transaction.save, "Save failed with the following errors: #{new_transaction.errors.inspect}"
27
- assert_exists new_transaction
54
+ assert_exists(new_transaction, @client)
28
55
  end
29
56
 
30
57
  can "update a SPEND bank transaction, for example by setting its status" do
31
- new_transaction = client.BankTransaction.build(
32
- :type => "SPEND",
33
- :contact => { :name => "Jazz Kang" },
34
- :line_items => any_line_items(@account),
35
- :bank_account => { :account_id => @bank_account.account_id }
58
+ new_transaction = @client.BankTransaction.build(
59
+ :type => "SPEND",
60
+ :contact => { :name => "Jazz Kang" },
61
+ :line_items => any_line_items(@account),
62
+ :bank_account => { :account_id => @bank_account.account_id }
36
63
  )
37
64
 
38
65
  assert new_transaction.save, "Save failed with the following errors: #{new_transaction.errors.inspect}"
39
66
 
40
- assert_exists new_transaction
67
+ assert_exists new_transaction, @client
41
68
 
42
69
  the_new_type = "RECEIVE"
43
70
 
@@ -49,114 +76,95 @@ class AboutCreatingBankTransactions < Test::Unit::TestCase
49
76
 
50
77
  assert_equal expected_id, new_transaction.id, "Expected the id to be the same because it has been updated"
51
78
 
52
- refreshed_bank_transaction = client.BankTransaction.find expected_id
79
+ refreshed_bank_transaction = @client.BankTransaction.find expected_id
53
80
 
54
81
  assert_equal the_new_type, refreshed_bank_transaction.type,
55
- "Expected the bank transaction to've had its type updated"
82
+ "Expected the bank transaction to've had its type updated"
56
83
  end
57
84
 
58
85
  can "update a bank transaction by adding line items provided you calculate the tax_amount correctly" do
59
- new_transaction = client.BankTransaction.build(
60
- :type => "SPEND",
61
- :contact => { :name => "Jazz Kang" },
62
- :line_items => any_line_items(@account),
63
- :bank_account => { :account_id => @bank_account.account_id },
64
- :line_amount_types => "Exclusive"
86
+ new_transaction = @client.BankTransaction.build(
87
+ :type => "SPEND",
88
+ :contact => { :name => "Jazz Kang" },
89
+ :line_items => any_line_items(@account),
90
+ :bank_account => { :account_id => @bank_account.account_id },
91
+ :line_amount_types => "Exclusive"
65
92
  )
66
93
 
67
94
  assert new_transaction.save, "Save failed with the following errors: #{new_transaction.errors.inspect}"
68
- assert_exists new_transaction
95
+ assert_exists new_transaction, @client
69
96
 
70
97
  expected_id = new_transaction.id
71
98
 
72
- tax_rate = get_tax_rate(@account.tax_type).effective_rate
99
+ tax_rate = get_tax_rate(@account.tax_type, @client).effective_rate
73
100
 
74
101
  unit_price = BigDecimal("1337.00")
75
102
 
76
103
  the_new_line_items = [
77
- {
78
- :description => "Burrito skin",
79
- :quantity => 1,
80
- :unit_amount => unit_price,
81
- :account_code => @account.code,
82
- :tax_type => @account.tax_type,
83
- :tax_amount => get_exclusive_tax(unit_price, tax_rate)
84
- }
104
+ {
105
+ :description => "Burrito skin",
106
+ :quantity => 1,
107
+ :unit_amount => unit_price,
108
+ :account_code => @account.code,
109
+ :tax_type => @account.tax_type,
110
+ :tax_amount => get_exclusive_tax(unit_price, tax_rate)
111
+ }
85
112
  ]
86
113
 
87
114
  new_transaction.line_items = the_new_line_items
88
115
 
89
116
  assert new_transaction.save, "Update failed with the following errors: #{new_transaction.errors.inspect}"
90
117
 
91
- refreshed_bank_transaction = client.BankTransaction.find expected_id
118
+ refreshed_bank_transaction = @client.BankTransaction.find expected_id
92
119
 
93
120
  assert_equal expected_id, new_transaction.id,
94
- "Expected the id to be the same because it has been updated"
121
+ "Expected the id to be the same because it has been updated"
95
122
 
96
123
  assert_equal 1, refreshed_bank_transaction.line_items.size,
97
- "Expected the bank transaction to've had its line items updated to just one"
124
+ "Expected the bank transaction to've had its line items updated to just one"
98
125
 
99
126
  the_first_line_item = refreshed_bank_transaction.line_items.first
100
127
 
101
128
  assert_equal "Burrito skin", the_first_line_item.description,
102
- "Expected the bank transaction to've had its line items updated, " +
103
- "but the first one's description does not match: #{the_first_line_item.inspect}"
104
- end
105
-
106
- def get_inclusive_tax(amount, tax_rate)
107
- inclusive_tax = amount * (1 - (100/(100 + tax_rate)))
108
- BigDecimal(inclusive_tax.to_s).round(2)
109
- end
110
-
111
- def get_exclusive_tax(amount, tax_rate)
112
- exclusive_tax = amount * (tax_rate/100)
113
- BigDecimal(exclusive_tax.to_s).round(2)
114
- end
115
-
116
- def get_tax_rate tax_type
117
- @all_tax_types ||= client.TaxRate.all
118
- @all_tax_types.select{|tax_rate| tax_rate.tax_type == tax_type}.first
129
+ "Expected the bank transaction to've had its line items updated, " +
130
+ "but the first one's description does not match: #{the_first_line_item.inspect}"
119
131
  end
120
132
 
121
133
  can "create a new RECEIVE bank transaction" do
122
- new_transaction = client.BankTransaction.build(
123
- :type => "RECEIVE",
124
- :contact => { :name => "Jazz Kang" },
125
- :line_items => any_line_items(@account),
126
- :bank_account => { :account_id => @bank_account.account_id }
134
+ new_transaction = @client.BankTransaction.build(
135
+ :type => "RECEIVE",
136
+ :contact => { :name => "Jazz Kang" },
137
+ :line_items => any_line_items(@account),
138
+ :bank_account => { :account_id => @bank_account.account_id }
127
139
  )
128
140
 
129
141
  assert new_transaction.save, "Save failed with the following errors: #{new_transaction.errors.inspect}"
130
- assert_exists new_transaction
142
+ assert_exists new_transaction, @client
131
143
  end
132
144
 
133
145
  it "treats line item unit_amounts as tax EXCLUSIVE"
134
146
  must "not set the tax_amount manually on line items"
135
147
 
136
- def assert_exists(bank_transaction)
137
- assert_not_nil bank_transaction.id,
138
- "Cannot check for exitence unless the bank transaction has non-null identifier"
139
- assert_not_nil client.BankTransaction.find bank_transaction.id
140
- end
141
148
 
142
- def any_line_items(account)
143
- [{
144
- :description => "Clingfilm bike shorts",
145
- :quantity => 1,
146
- :unit_amount => "17.00",
147
- :account_code => account.code,
148
- :tax_type => account.tax_type
149
- }]
150
- end
151
149
 
152
- it "fails with ApiException when you try and create a new bank account with missing account type" do
153
- new_account = client.Account.build(
154
- :name => "Example bank account",
155
- :code => "ACC-001"
150
+ it "fails with ApiException when you try and create a new bank account with missing account type with save! method" do
151
+ new_account = @client.Account.build(
152
+ :name => "Example bank account",
153
+ :code => "ACC-001"
156
154
  )
157
155
 
158
156
  assert_raise Xeroizer::ApiException do
159
- new_account.save
157
+ new_account.save!
160
158
  end
161
159
  end
160
+
161
+ it "returns false when you try and create a new bank account with a missing account type with save method" do
162
+ new_account = @client.Account.build(
163
+ :name => "Example bank account",
164
+ :code => "ACC-001"
165
+ )
166
+
167
+ assert new_account.save == false, "Account save method expected to return false"
168
+
169
+ end
162
170
  end