business-central 1.0.2 → 1.0.3

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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/lib/business_central.rb +6 -0
  3. data/lib/business_central/client.rb +16 -4
  4. data/lib/business_central/exceptions.rb +11 -1
  5. data/lib/business_central/object/account.rb +0 -10
  6. data/lib/business_central/object/aged_account_payable.rb +0 -10
  7. data/lib/business_central/object/aged_account_receivable.rb +0 -10
  8. data/lib/business_central/object/balance_sheet.rb +0 -10
  9. data/lib/business_central/object/base.rb +30 -13
  10. data/lib/business_central/object/cash_flow_statement.rb +0 -10
  11. data/lib/business_central/object/company.rb +5 -0
  12. data/lib/business_central/object/company_information.rb +0 -10
  13. data/lib/business_central/object/country_region.rb +0 -10
  14. data/lib/business_central/object/currency.rb +0 -10
  15. data/lib/business_central/object/customer.rb +27 -0
  16. data/lib/business_central/object/customer_financial_detail.rb +11 -0
  17. data/lib/business_central/object/customer_payment.rb +41 -0
  18. data/lib/business_central/object/customer_payment_journal.rb +23 -0
  19. data/lib/business_central/object/customer_sale.rb +11 -0
  20. data/lib/business_central/object/default_dimension.rb +54 -0
  21. data/lib/business_central/object/helper.rb +29 -3
  22. data/lib/business_central/object/item.rb +0 -10
  23. data/lib/business_central/object/purchase_invoice.rb +0 -10
  24. data/lib/business_central/object/purchase_invoice_line.rb +4 -10
  25. data/lib/business_central/object/request.rb +2 -2
  26. data/lib/business_central/object/vendor.rb +3 -9
  27. data/lib/business_central/version.rb +1 -1
  28. data/test/business_central/client_test.rb +37 -2
  29. data/test/business_central/object/base_test.rb +39 -0
  30. data/test/business_central/object/customer_financial_detail_test.rb +66 -0
  31. data/test/business_central/object/customer_payment_journal_test.rb +135 -0
  32. data/test/business_central/object/customer_payment_test.rb +142 -0
  33. data/test/business_central/object/customer_sale_test.rb +70 -0
  34. data/test/business_central/object/customer_test.rb +125 -0
  35. data/test/business_central/object/default_dimension_test.rb +171 -0
  36. data/test/business_central/object/request_test.rb +58 -3
  37. data/test/business_central/object/response_test.rb +24 -6
  38. data/test/test_helper.rb +6 -2
  39. metadata +36 -2
@@ -0,0 +1,11 @@
1
+ module BusinessCentral
2
+ module Object
3
+ class CustomerSale < Base
4
+ OBJECT = 'customerSales'.freeze
5
+
6
+ OBJECT_METHODS = [
7
+ :get
8
+ ].freeze
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,54 @@
1
+ module BusinessCentral
2
+ module Object
3
+ class DefaultDimension < Base
4
+ OBJECT = 'defaultDimensions'.freeze
5
+
6
+ OBJECT_VALIDATION = {
7
+ parent_id: {
8
+ required: true
9
+ },
10
+ dimension_code: {
11
+ maximum_length: 20
12
+ },
13
+ dimension_value_code: {
14
+ maximum_length: 20
15
+ }
16
+ }.freeze
17
+
18
+ OBJECT_METHODS = [
19
+ :get,
20
+ :post,
21
+ :patch,
22
+ :delete
23
+ ].freeze
24
+
25
+ OBJECT_PARENTS = [
26
+ 'items',
27
+ 'customers',
28
+ 'vendors',
29
+ 'employees'
30
+ ].freeze
31
+
32
+ def initialize(client, company_id:, parent:, parent_id:)
33
+ raise InvalidArgumentException.new("parents allowed: #{OBJECT_PARENTS.join(', ')}") if !valid_parent?(parent)
34
+ super(client, company_id: company_id)
35
+ @parent_path << {
36
+ path: parent.downcase,
37
+ id: parent_id
38
+ }
39
+ @parent_id = parent_id
40
+ end
41
+
42
+ def create(params = {})
43
+ params[:parent_id] = @parent_id
44
+ super(params)
45
+ end
46
+
47
+ private
48
+
49
+ def valid_parent?(parent)
50
+ OBJECT_PARENTS.include?(parent.downcase)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -4,10 +4,36 @@ module BusinessCentral
4
4
  def object(object_name, *params)
5
5
  define_method(object_name) do |argument=nil|
6
6
  object = "@#{object_name}_cache".to_sym
7
- if !instance_variable_defined?(object)
8
- instance_variable_set(object, BusinessCentral::Object.const_get("#{object_name.to_s.to_camel_case(true)}".to_sym).new(self, argument))
7
+ if argument.nil?
8
+ if !instance_variable_defined?(object)
9
+ instance_variable_set(
10
+ object,
11
+ BusinessCentral::Object.const_get("#{object_name.to_s.to_camel_case(true)}".to_sym).new(self, argument)
12
+ )
13
+ else
14
+ instance_variable_get(object)
15
+ end
16
+ else
17
+ instance_variable_set(
18
+ object,
19
+ BusinessCentral::Object.const_get("#{object_name.to_s.to_camel_case(true)}".to_sym).new(self, argument)
20
+ )
9
21
  end
10
- instance_variable_get(object)
22
+ end
23
+ end
24
+
25
+ def navigation(object_name, *params)
26
+ define_method(object_name) do |argument=nil|
27
+ object = "@#{object_name}_cache".to_sym
28
+ instance_variable_set(
29
+ object,
30
+ BusinessCentral::Object.const_get("#{object_name.to_s.to_camel_case(true)}".to_sym).new(
31
+ self.client,
32
+ company_id: company_id(argument),
33
+ parent: self.class.const_get(:OBJECT),
34
+ parent_id: id(argument)
35
+ )
36
+ )
11
37
  end
12
38
  end
13
39
  end
@@ -35,16 +35,6 @@ module BusinessCentral
35
35
  :patch,
36
36
  :delete
37
37
  ].freeze
38
-
39
- def initialize(client, company_id:)
40
- super(client, company_id: company_id)
41
- @parent_path = [
42
- {
43
- path: 'companies',
44
- id: company_id
45
- }
46
- ]
47
- end
48
38
  end
49
39
  end
50
40
  end
@@ -62,16 +62,6 @@ module BusinessCentral
62
62
  :patch,
63
63
  :delete
64
64
  ].freeze
65
-
66
- def initialize(client, company_id:)
67
- super(client, company_id: company_id)
68
- @parent_path = [
69
- {
70
- path: 'companies',
71
- id: company_id
72
- }
73
- ]
74
- end
75
65
  end
76
66
  end
77
67
  end
@@ -25,16 +25,10 @@ module BusinessCentral
25
25
 
26
26
  def initialize(client, company_id:, purchase_invoice_id:)
27
27
  super(client, company_id: company_id)
28
- @parent_path = [
29
- {
30
- path: 'companies',
31
- id: company_id
32
- },
33
- {
34
- path: 'purchaseInvoices',
35
- id: purchase_invoice_id
36
- }
37
- ]
28
+ @parent_path << {
29
+ path: 'purchaseInvoices',
30
+ id: purchase_invoice_id
31
+ }
38
32
  end
39
33
  end
40
34
  end
@@ -42,7 +42,7 @@ module BusinessCentral
42
42
  def self.convert(request = {})
43
43
  result = {}
44
44
  request.each do |key, value|
45
- result[key.to_s.to_camel_case] = value
45
+ result[key.to_s.to_camel_case] = value if key.is_a? Symbol
46
46
  end
47
47
 
48
48
  return result.to_json
@@ -61,7 +61,7 @@ module BusinessCentral
61
61
  if Response.unauthorized?(request.code.to_i)
62
62
  raise UnauthorizedException.new
63
63
  else
64
- if !response[:error][:code].blank?
64
+ if !response.fetch(:error, nil).nil?
65
65
  case response[:error][:code]
66
66
  when 'Internal_CompanyNotFound'
67
67
  raise CompanyNotFoundException.new
@@ -1,6 +1,8 @@
1
1
  module BusinessCentral
2
2
  module Object
3
3
  class Vendor < Base
4
+ extend BusinessCentral::Object::Helper
5
+
4
6
  OBJECT = 'vendors'.freeze
5
7
 
6
8
  OBJECT_VALIDATION = {
@@ -31,15 +33,7 @@ module BusinessCentral
31
33
  :delete
32
34
  ].freeze
33
35
 
34
- def initialize(client, company_id:)
35
- super(client, company_id: company_id)
36
- @parent_path = [
37
- {
38
- path: 'companies',
39
- id: company_id
40
- }
41
- ]
42
- end
36
+ navigation :default_dimension
43
37
  end
44
38
  end
45
39
  end
@@ -1,3 +1,3 @@
1
1
  module BusinessCentral
2
- VERSION = "1.0.2".freeze
2
+ VERSION = "1.0.3".freeze
3
3
  end
@@ -17,7 +17,7 @@ class BusinessCentral::ClientTest < Minitest::Test
17
17
  test_redirect_url = 'www.example.com'
18
18
  test_access_token = '123'
19
19
 
20
- stub_request(:post, /login.windows.net/)
20
+ stub_request(:post, /#{BusinessCentral::Client::DEFAULT_LOGIN_URL}/)
21
21
  .to_return(
22
22
  status: 200,
23
23
  headers: {
@@ -56,7 +56,7 @@ class BusinessCentral::ClientTest < Minitest::Test
56
56
  expires_in: 3600
57
57
  )
58
58
 
59
- stub_request(:post, /login.windows.net/)
59
+ stub_request(:post, /#{BusinessCentral::Client::DEFAULT_LOGIN_URL}/)
60
60
  .to_return(
61
61
  status: 200,
62
62
  headers: {
@@ -74,4 +74,39 @@ class BusinessCentral::ClientTest < Minitest::Test
74
74
  assert_equal test_access_token, response.token
75
75
  end
76
76
 
77
+ def test_authorize_throws_exception
78
+ stub_request(:get, BusinessCentral::Client::DEFAULT_LOGIN_URL)
79
+ .to_return(status: 200, body: "", headers: {})
80
+
81
+ mock = MiniTest::Mock.new
82
+ def mock.authorize_url(arguments)
83
+ response = Faraday.get(BusinessCentral::Client::DEFAULT_LOGIN_URL)
84
+ response = OAuth2::Response.new(response)
85
+ raise OAuth2::Error.new(response)
86
+ end
87
+
88
+ OAuth2::Strategy::AuthCode.stub(:new, mock) do
89
+ assert_raises(BusinessCentral::ApiException) do
90
+ @client.authorize
91
+ end
92
+ end
93
+ end
94
+
95
+ def test_request_token_throws_exception
96
+ stub_request(:get, BusinessCentral::Client::DEFAULT_URL)
97
+ .to_return(status: 200, body: "", headers: {})
98
+
99
+ mock = MiniTest::Mock.new
100
+ def mock.get_token(code, redirect_uri: '')
101
+ response = Faraday.get(BusinessCentral::Client::DEFAULT_URL)
102
+ response = OAuth2::Response.new(response)
103
+ raise OAuth2::Error.new(response)
104
+ end
105
+
106
+ OAuth2::Strategy::AuthCode.stub(:new, mock) do
107
+ assert_raises(BusinessCentral::ApiException) do
108
+ @client.request_token
109
+ end
110
+ end
111
+ end
77
112
  end
@@ -0,0 +1,39 @@
1
+ require "test_helper"
2
+ # rake test TEST=test/business_central/object/base_test.rb
3
+
4
+ class BusinessCentral::Object::BaseTest < Minitest::Test
5
+ def setup
6
+ @company_id = '123456'
7
+ @client = BusinessCentral::Client.new
8
+ end
9
+
10
+ def test_no_method_supported_for_find_all
11
+ base = BusinessCentral::Object::Base.new(@client, {})
12
+ set_object_method(base, [])
13
+ assert_raises(BusinessCentral::NoSupportedMethod) do
14
+ base.find_all
15
+ end
16
+ end
17
+
18
+ def test_no_method_supported_for_find_by_id
19
+ base = BusinessCentral::Object::Base.new(@client, {})
20
+ set_object_method(base, [])
21
+ assert_raises(BusinessCentral::NoSupportedMethod) do
22
+ base.find_by_id('123')
23
+ end
24
+ end
25
+
26
+ def test_no_method_supported_for_where_query
27
+ base = BusinessCentral::Object::Base.new(@client, {})
28
+ set_object_method(base, [])
29
+ assert_raises(BusinessCentral::NoSupportedMethod) do
30
+ base.where("displayName eq '123'")
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def set_object_method(base, value)
37
+ base.class.const_set('OBJECT_METHODS', value) if !base.class.const_defined?('OBJECT_METHODS')
38
+ end
39
+ end
@@ -0,0 +1,66 @@
1
+ require "test_helper"
2
+ # rake test TEST=test/business_central/object/customer_financial_detail_test.rb
3
+
4
+ class BusinessCentral::Object::CustomerFinancialDetailTest < Minitest::Test
5
+ def setup
6
+ @company_id = '123456'
7
+ @client = BusinessCentral::Client.new
8
+ @customer_financial_detail = @client.customer_financial_detail(
9
+ company_id: @company_id
10
+ )
11
+ end
12
+
13
+ def test_find_all
14
+ stub_request(:get, /customerFinancialDetails/)
15
+ .to_return(
16
+ status: 200,
17
+ body: {
18
+ 'value': [
19
+ {
20
+ id: 1,
21
+ number: 'N1',
22
+ balance: 0
23
+ }
24
+ ]
25
+ }.to_json,
26
+ )
27
+
28
+ response = @customer_financial_detail.find_all
29
+ assert_equal response.first[:number], 'N1'
30
+ end
31
+
32
+ def test_find_by_id
33
+ test_id = '2'
34
+ stub_request(:get, /customerFinancialDetails\(#{test_id}\)/)
35
+ .to_return(
36
+ status: 200,
37
+ body: {
38
+ id: test_id,
39
+ number: 'N2',
40
+ balance: 0
41
+ }.to_json
42
+ )
43
+
44
+ response = @customer_financial_detail.find_by_id(test_id)
45
+ assert_equal response[:number], 'N2'
46
+ end
47
+
48
+ def test_where
49
+ test_filter = "number eq 'N3'"
50
+ stub_request(:get, /customerFinancialDetails\?\$filter=#{test_filter}/)
51
+ .to_return(
52
+ status: 200,
53
+ body: {
54
+ 'value': [
55
+ {
56
+ id: 3,
57
+ number: 'N3'
58
+ }
59
+ ]
60
+ }.to_json
61
+ )
62
+
63
+ response = @customer_financial_detail.where(test_filter)
64
+ assert_equal response.first[:number], 'N3'
65
+ end
66
+ end
@@ -0,0 +1,135 @@
1
+ require "test_helper"
2
+ # rake test TEST=test/business_central/object/customer_payment_journal_test.rb
3
+
4
+ class BusinessCentral::Object::CustomerPaymentJournalTest < Minitest::Test
5
+ def setup
6
+ @company_id = '123456'
7
+ @client = BusinessCentral::Client.new
8
+ @customer_payment_journal = @client.customer_payment_journal(company_id: @company_id)
9
+ end
10
+
11
+ def test_find_all
12
+ stub_request(:get, /customerPaymentJournals/)
13
+ .to_return(
14
+ status: 200,
15
+ body: {
16
+ 'value': [
17
+ {
18
+ id: 1,
19
+ code: 'GENERAL',
20
+ displayName: 'GENERAL 1'
21
+ }
22
+ ]
23
+ }.to_json,
24
+ )
25
+
26
+ response = @customer_payment_journal.find_all
27
+ assert_equal response.first[:display_name], 'GENERAL 1'
28
+ end
29
+
30
+ def test_find_by_id
31
+ test_id = 2
32
+ stub_request(:get, /customerPaymentJournals\(#{test_id}\)/)
33
+ .to_return(
34
+ status: 200,
35
+ body: {
36
+ id: test_id,
37
+ code: 'GENERAL',
38
+ displayName: 'GENERAL 2'
39
+ }.to_json
40
+ )
41
+
42
+ response = @customer_payment_journal.find_by_id(test_id)
43
+ assert_equal response[:display_name], 'GENERAL 2'
44
+ end
45
+
46
+ def test_where
47
+ test_filter = "displayName eq 'GENERAL 3'"
48
+ stub_request(:get, /customerPaymentJournals\?\$filter=#{test_filter}/)
49
+ .to_return(
50
+ status: 200,
51
+ body: {
52
+ 'value': [
53
+ {
54
+ id: 1,
55
+ code: 'GENERAL',
56
+ displayName: 'GENERAL 3'
57
+ }
58
+ ]
59
+ }.to_json
60
+ )
61
+
62
+ response = @customer_payment_journal.where(test_filter)
63
+ assert_equal response.first[:display_name], 'GENERAL 3'
64
+ end
65
+
66
+ def test_create
67
+ stub_request(:post, /customerPaymentJournals/)
68
+ .to_return(
69
+ status: 200,
70
+ body: {
71
+ id: 1,
72
+ code: 'GENERAL',
73
+ displayName: 'GENERAL 4'
74
+ }.to_json
75
+ )
76
+
77
+ response = @customer_payment_journal.create({
78
+ display_name: 'GENERAL 4'
79
+ })
80
+ assert_equal response[:display_name], 'GENERAL 4'
81
+ end
82
+
83
+
84
+ def test_update
85
+ test_id = 2
86
+ stub_request(:get, /customerPaymentJournals\(#{test_id}\)/)
87
+ .to_return(
88
+ status: 200,
89
+ body: {
90
+ etag: '3333',
91
+ id: test_id,
92
+ code: 'GENERAL',
93
+ displayName: 'GENERAL 4'
94
+ }.to_json
95
+ )
96
+
97
+ stub_request(:patch, /customerPaymentJournals\(#{test_id}\)/)
98
+ .to_return(
99
+ status: 200,
100
+ body: {
101
+ etag: '4444',
102
+ id: test_id,
103
+ code: 'GENERAL',
104
+ displayName: 'GENERAL 5'
105
+ }.to_json
106
+ )
107
+
108
+ response = @customer_payment_journal.update(
109
+ test_id,
110
+ {
111
+ display_name: 'GENERAL 5'
112
+ }
113
+ )
114
+ assert_equal response[:display_name], 'GENERAL 5'
115
+ end
116
+
117
+ def test_delete
118
+ test_id = '33333'
119
+ stub_request(:get, /customerPaymentJournals\(#{test_id}\)/)
120
+ .to_return(
121
+ status: 200,
122
+ body: {
123
+ etag: '5555',
124
+ id: test_id,
125
+ code: 'GENERAL',
126
+ displayName: 'GENERAL 5'
127
+ }.to_json
128
+ )
129
+
130
+ stub_request(:delete, /customerPaymentJournals\(#{test_id}\)/)
131
+ .to_return(status: 204)
132
+
133
+ assert @customer_payment_journal.destroy(test_id)
134
+ end
135
+ end