business-central 1.0.4 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +58 -15
  3. data/lib/business_central.rb +4 -0
  4. data/lib/business_central/client.rb +5 -3
  5. data/lib/business_central/object/attachment.rb +30 -0
  6. data/lib/business_central/object/customer.rb +1 -0
  7. data/lib/business_central/object/default_dimension.rb +1 -1
  8. data/lib/business_central/object/general_ledger_entry.rb +13 -0
  9. data/lib/business_central/object/income_statement.rb +13 -0
  10. data/lib/business_central/object/irs1099_code.rb +16 -0
  11. data/lib/business_central/object/journal_line.rb +1 -1
  12. data/lib/business_central/object/picture.rb +1 -1
  13. data/lib/business_central/object/sales_credit_memo_line.rb +1 -1
  14. data/lib/business_central/object/sales_invoice_line.rb +1 -1
  15. data/lib/business_central/object/sales_order_line.rb +1 -1
  16. data/lib/business_central/object/sales_quote_line.rb +1 -1
  17. data/lib/business_central/version.rb +1 -1
  18. data/test/business_central/object/attachment_test.rb +117 -0
  19. data/test/business_central/object/customer_test.rb +44 -0
  20. data/test/business_central/object/general_ledger_entry_test.rb +82 -0
  21. data/test/business_central/object/income_statement_test.rb +82 -0
  22. data/test/business_central/object/irs1099_code_test.rb +124 -0
  23. data/test/business_central/object/journal_line_test.rb +8 -8
  24. data/test/business_central/object/journal_test.rb +20 -0
  25. data/test/business_central/object/sales_credit_memo_line_test.rb +8 -8
  26. data/test/business_central/object/sales_credit_memo_test.rb +1 -1
  27. data/test/business_central/object/sales_invoice_line_test.rb +8 -8
  28. data/test/business_central/object/sales_invoice_test.rb +22 -0
  29. data/test/business_central/object/sales_order_line_test.rb +8 -8
  30. data/test/business_central/object/sales_order_test.rb +1 -1
  31. data/test/business_central/object/sales_quote_line_test.rb +8 -8
  32. data/test/business_central/object/sales_quote_test.rb +1 -1
  33. metadata +18 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 68fd68c7e0cf337b5f2c83ba5f08e21cdbab84b3c10a3515338a6d5241ab3c8d
4
- data.tar.gz: 14b3bcbe75143b2457c7ca2606a33926de4e89fd7001323c97911d557037301e
3
+ metadata.gz: eb391f19d6cbf2649ddbe7eb0cf937d2657c140de32d6f6a8c1f92483a353f57
4
+ data.tar.gz: c9ad222424c8b46bd9cdc4e282e5b583b2e795d1e1917c942b7da259e8380c92
5
5
  SHA512:
6
- metadata.gz: bfe06ca5d2427eaed0f8bcb6826e87635d72f02e456e7f4dba47bb19645edb757cc85af0436038f611821975fe43e39387238e180172e3ec09b95720ab45edcb
7
- data.tar.gz: 461aadc6e03b1a77bbe6737d69776d2c909baebd36c680a558320abc674f27824983cc1e3b1401b35f85b90fb9ba28f5ff7aaa93a0adbd79e50d8df828532fc6
6
+ metadata.gz: 3413af99b793f31b5913c726dd7fc3f5c48328f39321809b35da46f62100a12b529996eadfd3191d1581c52a718d749fa7eb2b808eb3f063f7a2e9c05975967e
7
+ data.tar.gz: 5e96d79316386187618b362f3ea365f2f510b50622a50f2436ec45feaa32d435e839fcbf4ac20b8c7bb8dc8b33e98a5a7295b2d9beeac7257bd4f1d5e6a4aca5
data/README.md CHANGED
@@ -26,6 +26,22 @@ This gem supports both authentication methods:
26
26
 
27
27
  https://docs.microsoft.com/en-us/dynamics-nav/api-reference/v1.0/endpoints-apis-for-dynamics
28
28
 
29
+ ```Ruby
30
+ require 'business_central'
31
+
32
+ client = BusinessCentral::Client.new(
33
+ username: '<username>', # Basic authentication username
34
+ password: '<password>', # Basic authentication password
35
+ url: '<url>', # URL for API defaults to https://api.businesscentral.dynamics.com/v2.0/production/api/v1.0
36
+ web_service_url: '<url>', # URL for custom web services defaults to https://api.businesscentral.dynamics.com/v2.0/production/ODataV4
37
+ application_id: '<application_id>', # Oauth2 authentication application ID
38
+ secret_key: '<application_secret_key>', # OAuth2 authentication application secret key
39
+ oauth2_login_url: '<url>', # OAuth2 authentication login URL defaults to https://login.microsoftonline.com/common
40
+ default_company_id: '<company_id>', # Default company ID used in all requests (if required)
41
+ debug: false # Output requests to console
42
+ )
43
+ ```
44
+
29
45
  ### Basic Authentication:
30
46
 
31
47
  https://docs.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/devenv-develop-connect-apps#setting-up-basic-authentication
@@ -36,26 +52,27 @@ require 'business_central'
36
52
  client = BusinessCentral::Client.new(
37
53
  username: '<username>',
38
54
  password: '<password>',
39
- url: '<url>'
55
+ url: '<url>',
56
+ default_company_id: '11111111-2222-3333-4444-555555555555'
40
57
  )
41
58
 
42
59
  # Find all vendors
43
- vendors = client.vendor(company_id: '3a502065-2a08-4c3b-9468-fb83642d3d3a').find_all
60
+ vendors = client.vendor.all
44
61
 
45
62
  # Find vendor by ID
46
- vendor = client.vendor(company_id: '3a502065-2a08-4c3b-9468-fb83642d3d3a').find_by_id('3f445b08-2ffd-4f9d-81a0-b82f0d9714c4')
63
+ vendor = client.vendor.find('3f445b08-2ffd-4f9d-81a0-b82f0d9714c4')
47
64
 
48
65
  # Query vendor by display name
49
- vendor = client.vendor(company_id: '3a502065-2a08-4c3b-9468-fb83642d3d3a').where("displayName eq 'First Up Consultants'")
66
+ vendor = client.vendor.where("displayName eq 'First Up Consultants'")
50
67
 
51
68
  # Create a new vendor
52
- vendor = client.vendor(company_id: '3a502065-2a08-4c3b-9468-fb83642d3d3a').create({ display_name: 'hello testing new vendor' })
69
+ vendor = client.vendor.create({ display_name: 'hello testing new vendor' })
53
70
 
54
71
  # Update an existing vendor by ID
55
- vendor = client.vendor(company_id: '3a502065-2a08-4c3b-9468-fb83642d3d3a').update('3f445b08-2ffd-4f9d-81a0-b82f0d9714c4', { phone_number: '1112' })
72
+ vendor = client.vendor.update('3f445b08-2ffd-4f9d-81a0-b82f0d9714c4', { phone_number: '1112' })
56
73
 
57
74
  # Delete a vendor
58
- client.vendor(company_id: '3a502065-2a08-4c3b-9468-fb83642d3d3a').destroy('f0730ada-b315-ea11-a813-000d3ad21e99')
75
+ client.vendor.destroy('f0730ada-b315-ea11-a813-000d3ad21e99')
59
76
  ```
60
77
 
61
78
  ### Oauth2 Authentication
@@ -67,10 +84,10 @@ require 'business_central'
67
84
 
68
85
  # Create client - used to connect to the API
69
86
  client = BusinessCentral::Client.new(
70
- tenant_id: '<tenant_id>',
71
87
  application_id: '<application_id>',
72
88
  secret_key: '<application_secret_key>',
73
- url: '<url>'
89
+ url: '<url>',
90
+ default_company_id: '11111111-2222-3333-4444-555555555555'
74
91
  )
75
92
 
76
93
  # Controller endpoint 1
@@ -87,22 +104,48 @@ client.authorize_from_token(
87
104
  )
88
105
 
89
106
  # Find all vendors
90
- vendors = client.vendor(company_id: '3a502065-2a08-4c3b-9468-fb83642d3d3a').find_all
107
+ vendors = client.vendor.all
91
108
 
92
109
  # Find vendor by ID
93
- vendor = client.vendor(company_id: '3a502065-2a08-4c3b-9468-fb83642d3d3a').find_by_id('3f445b08-2ffd-4f9d-81a0-b82f0d9714c4')
110
+ vendor = client.vendor.find('3f445b08-2ffd-4f9d-81a0-b82f0d9714c4')
94
111
 
95
112
  # Query vendor by display name
96
- vendor = client.vendor(company_id: '3a502065-2a08-4c3b-9468-fb83642d3d3a').where("displayName eq 'First Up Consultants'")
113
+ vendor = client.vendor.where("displayName eq 'First Up Consultants'")
97
114
 
98
115
  # Create a new vendor
99
- vendor = client.vendor(company_id: '3a502065-2a08-4c3b-9468-fb83642d3d3a').create({ display_name: 'hello testing' })
116
+ vendor = client.vendor.create({ display_name: 'hello testing' })
100
117
 
101
118
  # Update an existing vendor by ID
102
- vendor = client.vendor(company_id: '3a502065-2a08-4c3b-9468-fb83642d3d3a').update('3f445b08-2ffd-4f9d-81a0-b82f0d9714c4', { phone_number: '1112' })
119
+ vendor = client.vendor.update('3f445b08-2ffd-4f9d-81a0-b82f0d9714c4', { phone_number: '1112' })
103
120
 
104
121
  # Delete a vendor
105
- client.vendor(company_id: '3a502065-2a08-4c3b-9468-fb83642d3d3a').destroy('f0730ada-b315-ea11-a813-000d3ad21e99')
122
+ client.vendor.destroy('f0730ada-b315-ea11-a813-000d3ad21e99')
123
+ ```
124
+
125
+ ### OData Web Services
126
+
127
+ https://docs.microsoft.com/en-us/dynamics365/business-central/dev-itpro/webservices/odata-web-services
128
+
129
+ ```Ruby
130
+ require 'business_central'
131
+
132
+ client = BusinessCentral::Client.new(
133
+ username: '<username>',
134
+ password: '<password>',
135
+ web_service_url: '<url>'
136
+ )
137
+
138
+ # Query a record
139
+ company = client.web_service.object("Company('?')/Purchase_Order", 'My Company').get
140
+
141
+ # Create a record
142
+ client.web_service.object("Company('?')/Purchase_Order", 'My Company').post({})
143
+
144
+ # Update a record
145
+ client.web_service.object("Company('?')/Purchase_Order", 'My Company').patch({})
146
+
147
+ # Delete a record
148
+ client.web_service.object("Company('?')/Purchase_Order", 'My Company').delete
106
149
  ```
107
150
 
108
151
  ## Development
@@ -19,6 +19,7 @@ require 'business_central/object/url_builder'
19
19
  require 'business_central/object/account'
20
20
  require 'business_central/object/aged_account_payable'
21
21
  require 'business_central/object/aged_account_receivable'
22
+ require 'business_central/object/attachment'
22
23
  require 'business_central/object/cash_flow_statement'
23
24
  require 'business_central/object/balance_sheet'
24
25
  require 'business_central/object/company'
@@ -35,6 +36,9 @@ require 'business_central/object/dimension'
35
36
  require 'business_central/object/dimension_line'
36
37
  require 'business_central/object/dimension_value'
37
38
  require 'business_central/object/employee'
39
+ require 'business_central/object/general_ledger_entry'
40
+ require 'business_central/object/income_statement'
41
+ require 'business_central/object/irs1099_code'
38
42
  require 'business_central/object/item'
39
43
  require 'business_central/object/item_category'
40
44
  require 'business_central/object/journal'
@@ -8,8 +8,7 @@ module BusinessCentral
8
8
 
9
9
  DEFAULT_URL = 'https://api.businesscentral.dynamics.com/v2.0/production/api/v1.0'
10
10
 
11
- attr_reader :tenant_id,
12
- :username,
11
+ attr_reader :username,
13
12
  :password,
14
13
  :application_id,
15
14
  :secret_key,
@@ -25,6 +24,7 @@ module BusinessCentral
25
24
  object :account
26
25
  object :aged_account_payable
27
26
  object :aged_account_receivable
27
+ object :attachment
28
28
  object :balance_sheet
29
29
  object :cash_flow_statement
30
30
  object :company
@@ -41,6 +41,9 @@ module BusinessCentral
41
41
  object :dimension_line
42
42
  object :dimension_value
43
43
  object :employee
44
+ object :general_ledger_entry
45
+ object :income_statement
46
+ object :irs1099_code
44
47
  object :purchase_invoice
45
48
  object :purchase_invoice_line
46
49
  object :item
@@ -71,7 +74,6 @@ module BusinessCentral
71
74
 
72
75
  def initialize(options = {})
73
76
  opts = options.dup
74
- @tenant_id = opts.delete(:tenant_id)
75
77
  @username = opts.delete(:username)
76
78
  @password = opts.delete(:password)
77
79
  @url = opts.delete(:url) || DEFAULT_URL
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BusinessCentral
4
+ module Object
5
+ class Attachment < Base
6
+ OBJECT = 'attachments'
7
+
8
+ OBJECT_METHODS = %i[
9
+ get
10
+ post
11
+ patch
12
+ delete
13
+ ].freeze
14
+
15
+ def update(parent_id:, attachment_id:, **params)
16
+ url = "#{build_url(child_path: OBJECT)}(parentId=#{parent_id},id=#{attachment_id})/content"
17
+ Request.call(:patch, @client, url, etag: '', params: {}) do |request|
18
+ request['Content-Type'] = 'application/json'
19
+ request['If-Match'] = 'application/json'
20
+ request.body = Request.convert(params)
21
+ end
22
+ end
23
+
24
+ def destroy(parent_id:, attachment_id:)
25
+ url = "#{build_url(child_path: OBJECT)}(#{parent_id},#{attachment_id})"
26
+ Request.call(:delete, @client, url, etag: '')
27
+ end
28
+ end
29
+ end
30
+ end
@@ -27,6 +27,7 @@ module BusinessCentral
27
27
  delete
28
28
  ].freeze
29
29
 
30
+ navigation :default_dimension
30
31
  navigation :picture
31
32
  end
32
33
  end
@@ -36,7 +36,7 @@ module BusinessCentral
36
36
 
37
37
  super(client, args)
38
38
  @parent_path << {
39
- path: parent.downcase,
39
+ path: parent,
40
40
  id: parent_id
41
41
  }
42
42
  @parent_id = parent_id
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BusinessCentral
4
+ module Object
5
+ class GeneralLedgerEntry < Base
6
+ OBJECT = 'generalLedgerEntries'
7
+
8
+ OBJECT_METHODS = %i[
9
+ get
10
+ ].freeze
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BusinessCentral
4
+ module Object
5
+ class IncomeStatement < Base
6
+ OBJECT = 'incomeStatement'
7
+
8
+ OBJECT_METHODS = %i[
9
+ get
10
+ ].freeze
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BusinessCentral
4
+ module Object
5
+ class Irs1099Code < Base
6
+ OBJECT = 'irs1099Codes'
7
+
8
+ OBJECT_METHODS = %i[
9
+ get
10
+ post
11
+ patch
12
+ delete
13
+ ].freeze
14
+ end
15
+ end
16
+ end
@@ -39,7 +39,7 @@ module BusinessCentral
39
39
 
40
40
  super(client, args)
41
41
  @parent_path << {
42
- path: parent.downcase,
42
+ path: parent,
43
43
  id: parent_id
44
44
  }
45
45
  end
@@ -24,7 +24,7 @@ module BusinessCentral
24
24
 
25
25
  super(client, args)
26
26
  @parent_path << {
27
- path: parent.downcase,
27
+ path: parent,
28
28
  id: parent_id
29
29
  }
30
30
  @parent_id = parent_id
@@ -21,7 +21,7 @@ module BusinessCentral
21
21
 
22
22
  super(client, args)
23
23
  @parent_path << {
24
- path: parent.downcase,
24
+ path: parent,
25
25
  id: parent_id
26
26
  }
27
27
  end
@@ -21,7 +21,7 @@ module BusinessCentral
21
21
 
22
22
  super(client, args)
23
23
  @parent_path << {
24
- path: parent.downcase,
24
+ path: parent,
25
25
  id: parent_id
26
26
  }
27
27
  end
@@ -21,7 +21,7 @@ module BusinessCentral
21
21
 
22
22
  super(client, args)
23
23
  @parent_path << {
24
- path: parent.downcase,
24
+ path: parent,
25
25
  id: parent_id
26
26
  }
27
27
  end
@@ -21,7 +21,7 @@ module BusinessCentral
21
21
 
22
22
  super(client, args)
23
23
  @parent_path << {
24
- path: parent.downcase,
24
+ path: parent,
25
25
  id: parent_id
26
26
  }
27
27
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BusinessCentral
4
- VERSION = '1.0.4'
4
+ VERSION = '1.0.5'
5
5
  end
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+ # rake test TEST=test/business_central/object/attachment_test.rb
5
+
6
+ class BusinessCentral::Object::AttachmentTest < Minitest::Test
7
+ def setup
8
+ @company_id = '123456'
9
+ @client = BusinessCentral::Client.new
10
+ @attachment = @client.attachment(company_id: @company_id)
11
+ end
12
+
13
+ def test_find_all
14
+ stub_request(:get, /attachments/)
15
+ .to_return(
16
+ status: 200,
17
+ body: {
18
+ 'value': [
19
+ {
20
+ id: '111',
21
+ fileName: 'attachment1.pdf'
22
+ }
23
+ ]
24
+ }.to_json
25
+ )
26
+
27
+ response = @attachment.find_all
28
+ assert_equal response.first[:file_name], 'attachment1.pdf'
29
+ end
30
+
31
+ def test_find_by_id
32
+ test_id = '09876'
33
+ stub_request(:get, /attachments\(#{test_id}\)/)
34
+ .to_return(
35
+ status: 200,
36
+ body: {
37
+ id: '222',
38
+ fileName: 'attachment2.jpg'
39
+ }.to_json
40
+ )
41
+
42
+ response = @attachment.find_by_id(test_id)
43
+ assert_equal response[:file_name], 'attachment2.jpg'
44
+ end
45
+
46
+ def test_where
47
+ test_filter = "fileName eq 'attachment3.png'"
48
+ stub_request(:get, /attachments\?\$filter=#{test_filter}/)
49
+ .to_return(
50
+ status: 200,
51
+ body: {
52
+ 'value': [
53
+ {
54
+ id: '333',
55
+ fileName: 'attachment3.png'
56
+ }
57
+ ]
58
+ }.to_json
59
+ )
60
+
61
+ response = @attachment.where(test_filter)
62
+ assert_equal response.first[:file_name], 'attachment3.png'
63
+ end
64
+
65
+ def test_create
66
+ stub_request(:post, /attachments/)
67
+ .to_return(
68
+ status: 200,
69
+ body: {
70
+ fileName: 'attachment4.gif'
71
+ }.to_json
72
+ )
73
+
74
+ response = @attachment.create(
75
+ file_name: 'attachment4.gif'
76
+ )
77
+ assert_equal response[:file_name], 'attachment4.gif'
78
+ end
79
+
80
+ def test_update
81
+ test_parent_id = '011123'
82
+ test_attachment_id = '11123'
83
+ stub_request(:get, /attachments\(parentId=#{test_parent_id},id=#{test_attachment_id}\)/)
84
+ .to_return(
85
+ status: 200,
86
+ body: {
87
+ etag: '112',
88
+ fileName: 'attachment5.pdf'
89
+ }.to_json
90
+ )
91
+
92
+ stub_request(:patch, /attachments\(parentId=#{test_parent_id},id=#{test_attachment_id}\)/)
93
+ .to_return(
94
+ status: 200,
95
+ body: {
96
+ fileName: 'attachment6.pdf'
97
+ }.to_json
98
+ )
99
+
100
+ response = @attachment.update(
101
+ parent_id: test_parent_id,
102
+ attachment_id: test_attachment_id,
103
+ file_name: 'attachment6.pdf'
104
+ )
105
+ assert_equal response[:file_name], 'attachment6.pdf'
106
+ end
107
+
108
+ def test_delete
109
+ test_parent_id = '011124'
110
+ test_attachment_id = '11124'
111
+
112
+ stub_request(:delete, /attachments\(#{test_parent_id},#{test_attachment_id}\)/)
113
+ .to_return(status: 204)
114
+
115
+ assert @attachment.destroy(parent_id: test_parent_id, attachment_id: test_attachment_id)
116
+ end
117
+ end