business-central 1.0.3 → 1.0.7

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 (128) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +58 -15
  3. data/lib/business_central/client.rb +71 -41
  4. data/lib/business_central/exceptions.rb +19 -9
  5. data/lib/business_central/object/account.rb +4 -2
  6. data/lib/business_central/object/aged_account_payable.rb +4 -2
  7. data/lib/business_central/object/aged_account_receivable.rb +4 -2
  8. data/lib/business_central/object/argument_helper.rb +22 -0
  9. data/lib/business_central/object/attachment.rb +30 -0
  10. data/lib/business_central/object/balance_sheet.rb +4 -2
  11. data/lib/business_central/object/base.rb +90 -56
  12. data/lib/business_central/object/cash_flow_statement.rb +4 -2
  13. data/lib/business_central/object/company.rb +5 -3
  14. data/lib/business_central/object/company_information.rb +7 -5
  15. data/lib/business_central/object/country_region.rb +8 -6
  16. data/lib/business_central/object/currency.rb +8 -6
  17. data/lib/business_central/object/customer.rb +16 -9
  18. data/lib/business_central/object/customer_financial_detail.rb +3 -1
  19. data/lib/business_central/object/customer_payment.rb +8 -6
  20. data/lib/business_central/object/customer_payment_journal.rb +8 -6
  21. data/lib/business_central/object/customer_sale.rb +3 -1
  22. data/lib/business_central/object/default_dimension.rb +18 -21
  23. data/lib/business_central/object/dimension.rb +20 -0
  24. data/lib/business_central/object/dimension_line.rb +37 -0
  25. data/lib/business_central/object/dimension_value.rb +28 -0
  26. data/lib/business_central/object/employee.rb +21 -0
  27. data/lib/business_central/object/filter_query.rb +18 -0
  28. data/lib/business_central/object/general_ledger_entry.rb +13 -0
  29. data/lib/business_central/object/income_statement.rb +13 -0
  30. data/lib/business_central/object/irs1099_code.rb +16 -0
  31. data/lib/business_central/object/item.rb +17 -10
  32. data/lib/business_central/object/item_category.rb +16 -0
  33. data/lib/business_central/object/journal.rb +29 -0
  34. data/lib/business_central/object/journal_line.rb +48 -0
  35. data/lib/business_central/object/{helper.rb → object_helper.rb} +18 -10
  36. data/lib/business_central/object/payment_method.rb +16 -0
  37. data/lib/business_central/object/payment_term.rb +16 -0
  38. data/lib/business_central/object/picture.rb +53 -0
  39. data/lib/business_central/object/purchase_invoice.rb +8 -6
  40. data/lib/business_central/object/purchase_invoice_line.rb +10 -8
  41. data/lib/business_central/object/purchase_order.rb +16 -0
  42. data/lib/business_central/object/request.rb +60 -49
  43. data/lib/business_central/object/response.rb +31 -23
  44. data/lib/business_central/object/retained_earning_statement.rb +13 -0
  45. data/lib/business_central/object/sales_credit_memo.rb +20 -0
  46. data/lib/business_central/object/sales_credit_memo_line.rb +30 -0
  47. data/lib/business_central/object/sales_invoice.rb +62 -0
  48. data/lib/business_central/object/sales_invoice_line.rb +30 -0
  49. data/lib/business_central/object/sales_order.rb +20 -0
  50. data/lib/business_central/object/sales_order_line.rb +30 -0
  51. data/lib/business_central/object/sales_quote.rb +20 -0
  52. data/lib/business_central/object/sales_quote_line.rb +30 -0
  53. data/lib/business_central/object/shipment_method.rb +16 -0
  54. data/lib/business_central/object/subscription.rb +16 -0
  55. data/lib/business_central/object/tax_area.rb +16 -0
  56. data/lib/business_central/object/tax_group.rb +16 -0
  57. data/lib/business_central/object/time_registration_entry.rb +16 -0
  58. data/lib/business_central/object/trial_balance.rb +13 -0
  59. data/lib/business_central/object/units_of_measure.rb +16 -0
  60. data/lib/business_central/object/url_builder.rb +59 -0
  61. data/lib/business_central/object/url_helper.rb +44 -0
  62. data/lib/business_central/object/validation.rb +10 -7
  63. data/lib/business_central/object/vendor.rb +10 -7
  64. data/lib/business_central/object/vendor_purchase.rb +13 -0
  65. data/lib/business_central/version.rb +4 -2
  66. data/lib/business_central/web_service.rb +78 -0
  67. data/lib/business_central.rb +40 -2
  68. data/lib/core_ext/string.rb +18 -12
  69. data/test/business_central/client_test.rb +18 -11
  70. data/test/business_central/object/account_test.rb +6 -5
  71. data/test/business_central/object/aged_account_payable_test.rb +6 -5
  72. data/test/business_central/object/aged_account_receivable_test.rb +6 -5
  73. data/test/business_central/object/attachment_test.rb +117 -0
  74. data/test/business_central/object/balance_sheet_test.rb +6 -5
  75. data/test/business_central/object/base_test.rb +4 -2
  76. data/test/business_central/object/cash_flow_statement_test.rb +6 -5
  77. data/test/business_central/object/company_information_test.rb +9 -10
  78. data/test/business_central/object/company_test.rb +6 -5
  79. data/test/business_central/object/country_region_test.rb +16 -17
  80. data/test/business_central/object/currency_test.rb +17 -18
  81. data/test/business_central/object/customer_financial_detail_test.rb +8 -6
  82. data/test/business_central/object/customer_payment_journal_test.rb +14 -15
  83. data/test/business_central/object/customer_payment_test.rb +15 -16
  84. data/test/business_central/object/customer_sale_test.rb +8 -6
  85. data/test/business_central/object/customer_test.rb +59 -16
  86. data/test/business_central/object/default_dimension_test.rb +15 -16
  87. data/test/business_central/object/dimension_line_test.rb +165 -0
  88. data/test/business_central/object/dimension_test.rb +65 -0
  89. data/test/business_central/object/dimension_value_test.rb +68 -0
  90. data/test/business_central/object/employee_test.rb +141 -0
  91. data/test/business_central/object/filter_query_test.rb +36 -0
  92. data/test/business_central/object/general_ledger_entry_test.rb +82 -0
  93. data/test/business_central/object/income_statement_test.rb +82 -0
  94. data/test/business_central/object/irs1099_code_test.rb +124 -0
  95. data/test/business_central/object/item_category_test.rb +122 -0
  96. data/test/business_central/object/item_test.rb +16 -17
  97. data/test/business_central/object/journal_line_test.rb +152 -0
  98. data/test/business_central/object/journal_test.rb +144 -0
  99. data/test/business_central/object/payment_method_test.rb +134 -0
  100. data/test/business_central/object/payment_term_test.rb +134 -0
  101. data/test/business_central/object/picture_test.rb +74 -0
  102. data/test/business_central/object/purchase_invoice_line_test.rb +15 -15
  103. data/test/business_central/object/purchase_invoice_test.rb +15 -15
  104. data/test/business_central/object/request_test.rb +17 -9
  105. data/test/business_central/object/response_test.rb +14 -7
  106. data/test/business_central/object/retained_earning_statement_test.rb +52 -0
  107. data/test/business_central/object/sales_credit_memo_line_test.rb +134 -0
  108. data/test/business_central/object/sales_credit_memo_test.rb +146 -0
  109. data/test/business_central/object/sales_invoice_line_test.rb +164 -0
  110. data/test/business_central/object/sales_invoice_test.rb +156 -0
  111. data/test/business_central/object/sales_order_line_test.rb +134 -0
  112. data/test/business_central/object/sales_order_test.rb +146 -0
  113. data/test/business_central/object/sales_quote_line_test.rb +134 -0
  114. data/test/business_central/object/sales_quote_test.rb +146 -0
  115. data/test/business_central/object/shipment_method_test.rb +133 -0
  116. data/test/business_central/object/subscription_test.rb +126 -0
  117. data/test/business_central/object/tax_area_test.rb +126 -0
  118. data/test/business_central/object/tax_group_test.rb +126 -0
  119. data/test/business_central/object/time_registration_entry_test.rb +126 -0
  120. data/test/business_central/object/trial_balance_test.rb +82 -0
  121. data/test/business_central/object/units_of_measure_test.rb +126 -0
  122. data/test/business_central/object/validation_test.rb +5 -4
  123. data/test/business_central/object/vendor_purchase_test.rb +82 -0
  124. data/test/business_central/object/vendor_test.rb +16 -16
  125. data/test/business_central/web_service_test.rb +100 -0
  126. data/test/business_central_test.rb +3 -1
  127. data/test/test_helper.rb +12 -6
  128. metadata +153 -41
@@ -1,7 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module BusinessCentral
2
4
  module Object
3
5
  class Item < Base
4
- OBJECT = 'items'.freeze
6
+ extend BusinessCentral::Object::ObjectHelper
7
+
8
+ OBJECT = 'items'
5
9
 
6
10
  OBJECT_VALIDATION = {
7
11
  number: {
@@ -12,10 +16,10 @@ module BusinessCentral
12
16
  },
13
17
  type: {
14
18
  required: true,
15
- inclusive_of: [
16
- 'Inventory',
17
- 'Service',
18
- 'Non-Inventory'
19
+ inclusive_of: %w[
20
+ Inventory
21
+ Service
22
+ Non-Inventory
19
23
  ]
20
24
  },
21
25
  item_category_code: {
@@ -29,12 +33,15 @@ module BusinessCentral
29
33
  }
30
34
  }.freeze
31
35
 
32
- OBJECT_METHODS = [
33
- :get,
34
- :post,
35
- :patch,
36
- :delete
36
+ OBJECT_METHODS = %i[
37
+ get
38
+ post
39
+ patch
40
+ delete
37
41
  ].freeze
42
+
43
+ navigation :default_dimension
44
+ navigation :picture
38
45
  end
39
46
  end
40
47
  end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BusinessCentral
4
+ module Object
5
+ class ItemCategory < Base
6
+ OBJECT = 'itemCategories'
7
+
8
+ OBJECT_METHODS = %i[
9
+ get
10
+ post
11
+ patch
12
+ delete
13
+ ].freeze
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BusinessCentral
4
+ module Object
5
+ class Journal < Base
6
+ extend BusinessCentral::Object::ObjectHelper
7
+
8
+ OBJECT = 'journals'
9
+
10
+ OBJECT_VALIDATION = {
11
+ code: {
12
+ maximum_length: 10
13
+ },
14
+ display_name: {
15
+ maximum_length: 50
16
+ }
17
+ }.freeze
18
+
19
+ OBJECT_METHODS = %i[
20
+ get
21
+ post
22
+ patch
23
+ delete
24
+ ].freeze
25
+
26
+ navigation :journal_line
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BusinessCentral
4
+ module Object
5
+ class JournalLine < Base
6
+ OBJECT = 'journalLines'
7
+
8
+ OBJECT_VALIDATION = {
9
+ account_number: {
10
+ maximum_length: 20
11
+ },
12
+ document_number: {
13
+ maximum_length: 20
14
+ },
15
+ external_document_number: {
16
+ maximum_length: 20
17
+ },
18
+ description: {
19
+ maximum_length: 50
20
+ },
21
+ comment: {
22
+ maximum_length: 250
23
+ }
24
+ }.freeze
25
+
26
+ OBJECT_METHODS = %i[
27
+ get
28
+ post
29
+ patch
30
+ delete
31
+ ].freeze
32
+
33
+ OBJECT_PARENTS = %w[
34
+ journals
35
+ ].freeze
36
+
37
+ def initialize(client, parent: 'journals', parent_id:, **args)
38
+ return if !valid_parent?(parent)
39
+
40
+ super(client, args)
41
+ @parent_path << {
42
+ path: parent,
43
+ id: parent_id
44
+ }
45
+ end
46
+ end
47
+ end
48
+ end
@@ -1,14 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module BusinessCentral
2
4
  module Object
3
- module Helper
4
- def object(object_name, *params)
5
- define_method(object_name) do |argument=nil|
5
+ module ObjectHelper
6
+ include ArgumentHelper
7
+
8
+ def object(object_name, *_params)
9
+ define_method(object_name) do |argument = nil|
6
10
  object = "@#{object_name}_cache".to_sym
7
11
  if argument.nil?
8
12
  if !instance_variable_defined?(object)
9
13
  instance_variable_set(
10
14
  object,
11
- BusinessCentral::Object.const_get("#{object_name.to_s.to_camel_case(true)}".to_sym).new(self, argument)
15
+ BusinessCentral::Object.const_get(
16
+ object_name.to_s.to_camel_case(true).to_s.to_sym
17
+ ).new(self, argument)
12
18
  )
13
19
  else
14
20
  instance_variable_get(object)
@@ -16,19 +22,21 @@ module BusinessCentral
16
22
  else
17
23
  instance_variable_set(
18
24
  object,
19
- BusinessCentral::Object.const_get("#{object_name.to_s.to_camel_case(true)}".to_sym).new(self, argument)
25
+ BusinessCentral::Object.const_get(
26
+ object_name.to_s.to_camel_case(true).to_s.to_sym
27
+ ).new(self, **argument)
20
28
  )
21
29
  end
22
30
  end
23
31
  end
24
32
 
25
- def navigation(object_name, *params)
26
- define_method(object_name) do |argument=nil|
33
+ def navigation(object_name, *_params)
34
+ define_method(object_name) do |argument = nil|
27
35
  object = "@#{object_name}_cache".to_sym
28
36
  instance_variable_set(
29
37
  object,
30
- BusinessCentral::Object.const_get("#{object_name.to_s.to_camel_case(true)}".to_sym).new(
31
- self.client,
38
+ BusinessCentral::Object.const_get(object_name.to_s.to_camel_case(true).to_s.to_sym).new(
39
+ client,
32
40
  company_id: company_id(argument),
33
41
  parent: self.class.const_get(:OBJECT),
34
42
  parent_id: id(argument)
@@ -38,4 +46,4 @@ module BusinessCentral
38
46
  end
39
47
  end
40
48
  end
41
- end
49
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BusinessCentral
4
+ module Object
5
+ class PaymentMethod < Base
6
+ OBJECT = 'paymentMethods'
7
+
8
+ OBJECT_METHODS = %i[
9
+ get
10
+ post
11
+ patch
12
+ delete
13
+ ].freeze
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BusinessCentral
4
+ module Object
5
+ class PaymentTerm < Base
6
+ OBJECT = 'paymentTerms'
7
+
8
+ OBJECT_METHODS = %i[
9
+ get
10
+ post
11
+ patch
12
+ delete
13
+ ].freeze
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BusinessCentral
4
+ module Object
5
+ class Picture < Base
6
+ OBJECT = 'picture'
7
+
8
+ OBJECT_METHODS = %i[
9
+ get
10
+ post
11
+ patch
12
+ delete
13
+ ].freeze
14
+
15
+ OBJECT_PARENTS = %w[
16
+ items
17
+ customers
18
+ vendors
19
+ employees
20
+ ].freeze
21
+
22
+ def initialize(client, parent:, parent_id:, **args)
23
+ return if !valid_parent?(parent)
24
+
25
+ super(client, args)
26
+ @parent_path << {
27
+ path: parent,
28
+ id: parent_id
29
+ }
30
+ @parent_id = parent_id
31
+ end
32
+
33
+ def create(data)
34
+ url = "#{build_url(parent_path: @parent_path, child_path: object_name)}(#{@parent_id})/content"
35
+ Request.call(:patch, @client, url, etag: '', params: {}) do |request|
36
+ request['Content-Type'] = 'application/octet-stream'
37
+ request['If-Match'] = '*'
38
+ request.body = data
39
+ end
40
+ end
41
+
42
+ def update(data)
43
+ url = "#{build_url(parent_path: @parent_path, child_path: object_name)}(#{@parent_id})"
44
+ object = Request.get(@client, url)
45
+ url = "#{build_url(parent_path: @parent_path, child_path: object_name)}(#{@parent_id})/content"
46
+ Request.call(:patch, @client, url, etag: object[:etag], params: {}) do |request|
47
+ request['Content-Type'] = 'application/octet-stream'
48
+ request.body = data
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module BusinessCentral
2
4
  module Object
3
5
  class PurchaseInvoice < Base
4
- OBJECT = 'purchaseInvoices'.freeze
6
+ OBJECT = 'purchaseInvoices'
5
7
 
6
8
  OBJECT_VALIDATION = {
7
9
  number: {
@@ -56,11 +58,11 @@ module BusinessCentral
56
58
  }
57
59
  }.freeze
58
60
 
59
- OBJECT_METHODS = [
60
- :get,
61
- :post,
62
- :patch,
63
- :delete
61
+ OBJECT_METHODS = %i[
62
+ get
63
+ post
64
+ patch
65
+ delete
64
66
  ].freeze
65
67
  end
66
68
  end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module BusinessCentral
2
4
  module Object
3
5
  class PurchaseInvoiceLine < Base
4
- OBJECT = 'purchaseInvoiceLines'.freeze
6
+ OBJECT = 'purchaseInvoiceLines'
5
7
 
6
8
  OBJECT_VALIDATION = {
7
9
  line_type: {
@@ -16,15 +18,15 @@ module BusinessCentral
16
18
  }
17
19
  }.freeze
18
20
 
19
- OBJECT_METHODS = [
20
- :get,
21
- :post,
22
- :patch,
23
- :delete
21
+ OBJECT_METHODS = %i[
22
+ get
23
+ post
24
+ patch
25
+ delete
24
26
  ].freeze
25
27
 
26
- def initialize(client, company_id:, purchase_invoice_id:)
27
- super(client, company_id: company_id)
28
+ def initialize(client, purchase_invoice_id:, **args)
29
+ super(client, args)
28
30
  @parent_path << {
29
31
  path: 'purchaseInvoices',
30
32
  id: purchase_invoice_id
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BusinessCentral
4
+ module Object
5
+ class PurchaseOrder < Base
6
+ OBJECT = 'purchaseOrders'
7
+
8
+ OBJECT_METHODS = %i[
9
+ get
10
+ post
11
+ patch
12
+ delete
13
+ ].freeze
14
+ end
15
+ end
16
+ end
@@ -1,75 +1,86 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module BusinessCentral
2
4
  module Object
3
5
  class Request
6
+ class << self
7
+ def get(client, url)
8
+ request(:get, client, url)
9
+ end
4
10
 
5
- def self.get(client, url)
6
- request(:get, client, url)
7
- end
8
-
9
- def self.post(client, url, params)
10
- request(:post, client, url, params: params)
11
- end
12
-
13
- def self.patch(client, url, etag, params)
14
- request(:patch, client, url, etag: etag, params: params)
15
- end
11
+ def post(client, url, params)
12
+ request(:post, client, url, params: params)
13
+ end
16
14
 
17
- def self.delete(client, url, etag)
18
- request(:delete, client, url, etag: etag)
19
- end
15
+ def patch(client, url, etag, params)
16
+ request(:patch, client, url, etag: etag, params: params)
17
+ end
20
18
 
21
- private
19
+ def delete(client, url, etag)
20
+ request(:delete, client, url, etag: etag)
21
+ end
22
22
 
23
- def self.request(method, client, url, etag: '', params: {})
24
- send do
25
- uri = URI(url)
26
- https = Net::HTTP.new(uri.host, uri.port);
27
- https.use_ssl = true
28
- request = Object.const_get("Net::HTTP::#{method.to_s.capitalize}").new(uri)
29
- request['Content-Type'] = 'application/json'
30
- request['Accept'] = 'application/json'
31
- request['If-Match'] = etag if !etag.blank?
32
- request.body = convert(params) if method == :post || method == :patch
33
- if client.access_token
34
- request['Authorization'] = "Bearer #{client.access_token.token}"
35
- else
36
- request.basic_auth(client.username, client.password)
23
+ def convert(request = {})
24
+ result = {}
25
+ request.each do |key, value|
26
+ result[key.to_s.to_camel_case] = value if key.is_a? Symbol
27
+ result[key.to_s] = value if key.is_a? String
37
28
  end
38
- https.request(request)
29
+
30
+ result.to_json
39
31
  end
40
- end
41
32
 
42
- def self.convert(request = {})
43
- result = {}
44
- request.each do |key, value|
45
- result[key.to_s.to_camel_case] = value if key.is_a? Symbol
33
+ def request(method, client, url, etag: '', params: {})
34
+ send do
35
+ uri = URI(url)
36
+ https = Net::HTTP.new(uri.host, uri.port)
37
+ https.use_ssl = true
38
+ https.set_debug_output($stdout) if client.debug
39
+ request = Object.const_get("Net::HTTP::#{method.to_s.capitalize}").new(uri)
40
+ request['If-Match'] = etag if !etag.blank?
41
+ request['Accept'] = 'application/json'
42
+ if block_given?
43
+ yield(request)
44
+ else
45
+ request['Content-Type'] = 'application/json'
46
+ request.body = convert(params) if %i[post patch].include?(method)
47
+ end
48
+
49
+ if client.access_token
50
+ request['Authorization'] = "Bearer #{client.access_token.token}"
51
+ else
52
+ request.basic_auth(client.username, client.password)
53
+ end
54
+ https.request(request)
55
+ end
46
56
  end
57
+ alias call request
47
58
 
48
- return result.to_json
49
- end
59
+ private
50
60
 
51
- def self.send
52
- begin
61
+ def send
53
62
  request = yield
54
63
  response = Response.new(request.read_body.to_s).results
55
64
 
56
65
  if Response.success?(request.code.to_i)
57
- return response
58
- elsif Response.deleted?(request.code.to_i)
59
- return true
66
+ response
67
+ elsif Response.success_no_content?(request.code.to_i)
68
+ true
60
69
  else
61
70
  if Response.unauthorized?(request.code.to_i)
62
- raise UnauthorizedException.new
71
+ raise UnauthorizedException
72
+ elsif Response.not_found?(request.code.to_i)
73
+ raise NotFoundException
63
74
  else
64
75
  if !response.fetch(:error, nil).nil?
65
76
  case response[:error][:code]
66
- when 'Internal_CompanyNotFound'
67
- raise CompanyNotFoundException.new
68
- else
69
- raise ApiException.new("#{request.code} - #{response[:error][:code]} #{response[:error][:message]}")
77
+ when 'Internal_CompanyNotFound'
78
+ raise CompanyNotFoundException
79
+ else
80
+ raise ApiException, "#{request.code} - #{response[:error][:code]} #{response[:error][:message]}"
70
81
  end
71
82
  else
72
- raise ApiException.new("#{request.code} - API call failed")
83
+ raise ApiException, "#{request.code} - API call failed"
73
84
  end
74
85
  end
75
86
  end
@@ -77,4 +88,4 @@ module BusinessCentral
77
88
  end
78
89
  end
79
90
  end
80
- end
91
+ end
@@ -1,35 +1,43 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module BusinessCentral
2
4
  module Object
3
5
  class Response
4
- attr_reader :results
6
+ class << self
7
+ def success?(status)
8
+ [200, 201].include?(status)
9
+ end
5
10
 
6
- def initialize(response)
7
- @results = nil
8
- if !response.blank?
9
- @response = JSON.parse(response)
10
- if @response.has_key?('value')
11
- @response = @response['value']
12
- end
13
- process
11
+ def success_no_content?(status)
12
+ status == 204
14
13
  end
15
- end
16
14
 
17
- def self.success?(status)
18
- status == 200 || status == 201
19
- end
15
+ def unauthorized?(status)
16
+ status == 401
17
+ end
20
18
 
21
- def self.deleted?(status)
22
- status == 204
19
+ def not_found?(status)
20
+ status == 404
21
+ end
23
22
  end
24
23
 
25
- def self.unauthorized?(status)
26
- status == 401
24
+ attr_reader :results
25
+
26
+ def initialize(response)
27
+ @results = nil
28
+ return if response.blank?
29
+
30
+ @response = JSON.parse(response)
31
+ @response = @response['value'] if @response.key?('value')
32
+ process
27
33
  end
28
34
 
29
35
  private
30
36
 
31
37
  def process
32
- if @response.is_a?(Array)
38
+ if @response.is_a?(String)
39
+ @results = @response
40
+ elsif @response.is_a?(Array)
33
41
  @results = []
34
42
  @response.each do |data|
35
43
  @results << convert(data)
@@ -40,11 +48,11 @@ module BusinessCentral
40
48
  end
41
49
 
42
50
  def convert(data)
43
- result = {}
51
+ result = {}
44
52
  data.each do |key, value|
45
- if key == "@odata.etag"
53
+ if key == '@odata.etag'
46
54
  result[:etag] = value
47
- elsif key == "@odata.context"
55
+ elsif key == '@odata.context'
48
56
  result[:context] = value
49
57
  elsif value.is_a?(Hash)
50
58
  result[key.to_snake_case.to_sym] = convert(value)
@@ -53,8 +61,8 @@ module BusinessCentral
53
61
  end
54
62
  end
55
63
 
56
- return result
64
+ result
57
65
  end
58
66
  end
59
67
  end
60
- end
68
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BusinessCentral
4
+ module Object
5
+ class RetainedEarningStatement < Base
6
+ OBJECT = 'retainedEarningsStatement'
7
+
8
+ OBJECT_METHODS = %i[
9
+ get
10
+ ].freeze
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BusinessCentral
4
+ module Object
5
+ class SalesCreditMemo < Base
6
+ extend BusinessCentral::Object::ObjectHelper
7
+
8
+ OBJECT = 'salesCreditMemos'
9
+
10
+ OBJECT_METHODS = %i[
11
+ get
12
+ post
13
+ patch
14
+ delete
15
+ ].freeze
16
+
17
+ navigation :sales_credit_memo_line
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BusinessCentral
4
+ module Object
5
+ class SalesCreditMemoLine < Base
6
+ OBJECT = 'salesCreditMemoLines'
7
+
8
+ OBJECT_METHODS = %i[
9
+ get
10
+ post
11
+ patch
12
+ delete
13
+ ].freeze
14
+
15
+ OBJECT_PARENTS = %w[
16
+ salesCreditMemos
17
+ ].freeze
18
+
19
+ def initialize(client, parent: 'salesCreditMemos', parent_id:, **args)
20
+ return if !valid_parent?(parent)
21
+
22
+ super(client, args)
23
+ @parent_path << {
24
+ path: parent,
25
+ id: parent_id
26
+ }
27
+ end
28
+ end
29
+ end
30
+ end