ledger_sync-netsuite 0.1.1

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 (140) hide show
  1. checksums.yaml +7 -0
  2. data/.env.test +14 -0
  3. data/.github/workflows/gem-workflow.yml +63 -0
  4. data/.gitignore +20 -0
  5. data/.overcommit.yml +29 -0
  6. data/.rubocop.yml +78 -0
  7. data/.rubocop_todo.yml +25 -0
  8. data/Gemfile +8 -0
  9. data/Gemfile.lock +203 -0
  10. data/README.md +19 -0
  11. data/Rakefile +8 -0
  12. data/bin/console +15 -0
  13. data/bin/setup +8 -0
  14. data/ledger_sync-netsuite.gemspec +44 -0
  15. data/lib/ledger_sync/netsuite.rb +13 -0
  16. data/lib/ledger_sync/netsuite/account/deserializer.rb +21 -0
  17. data/lib/ledger_sync/netsuite/account/operations/create.rb +26 -0
  18. data/lib/ledger_sync/netsuite/account/operations/find.rb +26 -0
  19. data/lib/ledger_sync/netsuite/account/searcher.rb +10 -0
  20. data/lib/ledger_sync/netsuite/account/searcher_deserializer.rb +27 -0
  21. data/lib/ledger_sync/netsuite/account/serializer.rb +19 -0
  22. data/lib/ledger_sync/netsuite/check/deserializer.rb +27 -0
  23. data/lib/ledger_sync/netsuite/check/operations/create.rb +25 -0
  24. data/lib/ledger_sync/netsuite/check/operations/delete.rb +25 -0
  25. data/lib/ledger_sync/netsuite/check/operations/find.rb +25 -0
  26. data/lib/ledger_sync/netsuite/check/operations/update.rb +25 -0
  27. data/lib/ledger_sync/netsuite/check/searcher.rb +13 -0
  28. data/lib/ledger_sync/netsuite/check/searcher_deserializer.rb +14 -0
  29. data/lib/ledger_sync/netsuite/check/serializer.rb +49 -0
  30. data/lib/ledger_sync/netsuite/check_line_item/deserializer.rb +16 -0
  31. data/lib/ledger_sync/netsuite/check_line_item/serializer.rb +24 -0
  32. data/lib/ledger_sync/netsuite/client.rb +186 -0
  33. data/lib/ledger_sync/netsuite/config.rb +12 -0
  34. data/lib/ledger_sync/netsuite/currency/deserializer.rb +21 -0
  35. data/lib/ledger_sync/netsuite/currency/operations/create.rb +23 -0
  36. data/lib/ledger_sync/netsuite/currency/operations/delete.rb +21 -0
  37. data/lib/ledger_sync/netsuite/currency/operations/find.rb +25 -0
  38. data/lib/ledger_sync/netsuite/currency/operations/update.rb +21 -0
  39. data/lib/ledger_sync/netsuite/currency/serializer.rb +19 -0
  40. data/lib/ledger_sync/netsuite/customer/deserializer.rb +20 -0
  41. data/lib/ledger_sync/netsuite/customer/operations/create.rb +24 -0
  42. data/lib/ledger_sync/netsuite/customer/operations/delete.rb +24 -0
  43. data/lib/ledger_sync/netsuite/customer/operations/find.rb +24 -0
  44. data/lib/ledger_sync/netsuite/customer/operations/update.rb +24 -0
  45. data/lib/ledger_sync/netsuite/customer/searcher.rb +10 -0
  46. data/lib/ledger_sync/netsuite/customer/searcher_deserializer.rb +16 -0
  47. data/lib/ledger_sync/netsuite/customer/serializer.rb +27 -0
  48. data/lib/ledger_sync/netsuite/customer_deposit/deserializer.rb +18 -0
  49. data/lib/ledger_sync/netsuite/customer_deposit/operations/create.rb +22 -0
  50. data/lib/ledger_sync/netsuite/customer_deposit/operations/delete.rb +22 -0
  51. data/lib/ledger_sync/netsuite/customer_deposit/operations/find.rb +22 -0
  52. data/lib/ledger_sync/netsuite/customer_deposit/operations/update.rb +22 -0
  53. data/lib/ledger_sync/netsuite/customer_deposit/searcher.rb +10 -0
  54. data/lib/ledger_sync/netsuite/customer_deposit/searcher_deserializer.rb +14 -0
  55. data/lib/ledger_sync/netsuite/customer_deposit/serializer.rb +23 -0
  56. data/lib/ledger_sync/netsuite/dashboard_url_helper.rb +26 -0
  57. data/lib/ledger_sync/netsuite/department/deserializer.rb +13 -0
  58. data/lib/ledger_sync/netsuite/department/operations/create.rb +23 -0
  59. data/lib/ledger_sync/netsuite/department/operations/delete.rb +23 -0
  60. data/lib/ledger_sync/netsuite/department/operations/find.rb +23 -0
  61. data/lib/ledger_sync/netsuite/department/operations/update.rb +23 -0
  62. data/lib/ledger_sync/netsuite/department/searcher.rb +10 -0
  63. data/lib/ledger_sync/netsuite/department/searcher_deserializer.rb +17 -0
  64. data/lib/ledger_sync/netsuite/department/serializer.rb +11 -0
  65. data/lib/ledger_sync/netsuite/deserializer.rb +16 -0
  66. data/lib/ledger_sync/netsuite/error.rb +17 -0
  67. data/lib/ledger_sync/netsuite/journal_entry/deserializer.rb +29 -0
  68. data/lib/ledger_sync/netsuite/journal_entry/operations/create.rb +24 -0
  69. data/lib/ledger_sync/netsuite/journal_entry/operations/delete.rb +24 -0
  70. data/lib/ledger_sync/netsuite/journal_entry/operations/find.rb +24 -0
  71. data/lib/ledger_sync/netsuite/journal_entry/operations/update.rb +28 -0
  72. data/lib/ledger_sync/netsuite/journal_entry/serializer.rb +34 -0
  73. data/lib/ledger_sync/netsuite/journal_entry_line_item/deserializer.rb +18 -0
  74. data/lib/ledger_sync/netsuite/journal_entry_line_item/serializer.rb +18 -0
  75. data/lib/ledger_sync/netsuite/ledger_class/deserializer.rb +13 -0
  76. data/lib/ledger_sync/netsuite/ledger_class/operations/create.rb +23 -0
  77. data/lib/ledger_sync/netsuite/ledger_class/operations/delete.rb +23 -0
  78. data/lib/ledger_sync/netsuite/ledger_class/operations/find.rb +23 -0
  79. data/lib/ledger_sync/netsuite/ledger_class/operations/update.rb +23 -0
  80. data/lib/ledger_sync/netsuite/ledger_class/searcher.rb +10 -0
  81. data/lib/ledger_sync/netsuite/ledger_class/searcher_deserializer.rb +17 -0
  82. data/lib/ledger_sync/netsuite/ledger_class/serializer.rb +11 -0
  83. data/lib/ledger_sync/netsuite/location/deserializer.rb +13 -0
  84. data/lib/ledger_sync/netsuite/location/operations/create.rb +19 -0
  85. data/lib/ledger_sync/netsuite/location/operations/delete.rb +19 -0
  86. data/lib/ledger_sync/netsuite/location/operations/find.rb +19 -0
  87. data/lib/ledger_sync/netsuite/location/operations/update.rb +19 -0
  88. data/lib/ledger_sync/netsuite/location/searcher.rb +10 -0
  89. data/lib/ledger_sync/netsuite/location/serializer.rb +11 -0
  90. data/lib/ledger_sync/netsuite/operation.rb +38 -0
  91. data/lib/ledger_sync/netsuite/operation/create.rb +56 -0
  92. data/lib/ledger_sync/netsuite/operation/delete.rb +47 -0
  93. data/lib/ledger_sync/netsuite/operation/find.rb +68 -0
  94. data/lib/ledger_sync/netsuite/operation/update.rb +59 -0
  95. data/lib/ledger_sync/netsuite/record/http_method.rb +31 -0
  96. data/lib/ledger_sync/netsuite/record/metadata.rb +107 -0
  97. data/lib/ledger_sync/netsuite/record/parameter.rb +18 -0
  98. data/lib/ledger_sync/netsuite/record/property.rb +20 -0
  99. data/lib/ledger_sync/netsuite/reference/serializer.rb +11 -0
  100. data/lib/ledger_sync/netsuite/resource.rb +8 -0
  101. data/lib/ledger_sync/netsuite/resources/account.rb +41 -0
  102. data/lib/ledger_sync/netsuite/resources/check.rb +21 -0
  103. data/lib/ledger_sync/netsuite/resources/check_line_item.rb +13 -0
  104. data/lib/ledger_sync/netsuite/resources/currency.rb +11 -0
  105. data/lib/ledger_sync/netsuite/resources/customer.rb +17 -0
  106. data/lib/ledger_sync/netsuite/resources/customer_deposit.rb +13 -0
  107. data/lib/ledger_sync/netsuite/resources/department.rb +14 -0
  108. data/lib/ledger_sync/netsuite/resources/deposit.rb +26 -0
  109. data/lib/ledger_sync/netsuite/resources/deposit_line_item.rb +23 -0
  110. data/lib/ledger_sync/netsuite/resources/invoice.rb +26 -0
  111. data/lib/ledger_sync/netsuite/resources/invoice_line_item.rb +19 -0
  112. data/lib/ledger_sync/netsuite/resources/item.rb +9 -0
  113. data/lib/ledger_sync/netsuite/resources/journal_entry.rb +24 -0
  114. data/lib/ledger_sync/netsuite/resources/journal_entry_line_item.rb +22 -0
  115. data/lib/ledger_sync/netsuite/resources/ledger_class.rb +14 -0
  116. data/lib/ledger_sync/netsuite/resources/location.rb +9 -0
  117. data/lib/ledger_sync/netsuite/resources/subsidiary.rb +10 -0
  118. data/lib/ledger_sync/netsuite/resources/vendor.rb +21 -0
  119. data/lib/ledger_sync/netsuite/searcher.rb +64 -0
  120. data/lib/ledger_sync/netsuite/serializer.rb +11 -0
  121. data/lib/ledger_sync/netsuite/subsidiary/deserializer.rb +15 -0
  122. data/lib/ledger_sync/netsuite/subsidiary/searcher.rb +10 -0
  123. data/lib/ledger_sync/netsuite/subsidiary/searcher_deserializer.rb +13 -0
  124. data/lib/ledger_sync/netsuite/subsidiary/serializer.rb +13 -0
  125. data/lib/ledger_sync/netsuite/token.rb +156 -0
  126. data/lib/ledger_sync/netsuite/type/deserializer_active_type.rb +30 -0
  127. data/lib/ledger_sync/netsuite/type/deserializer_customer_type.rb +33 -0
  128. data/lib/ledger_sync/netsuite/type/deserializer_entity_type.rb +28 -0
  129. data/lib/ledger_sync/netsuite/type/deserializer_subsidiary_type.rb +33 -0
  130. data/lib/ledger_sync/netsuite/vendor/deserializer.rb +28 -0
  131. data/lib/ledger_sync/netsuite/vendor/operations/create.rb +25 -0
  132. data/lib/ledger_sync/netsuite/vendor/operations/delete.rb +25 -0
  133. data/lib/ledger_sync/netsuite/vendor/operations/find.rb +25 -0
  134. data/lib/ledger_sync/netsuite/vendor/operations/update.rb +25 -0
  135. data/lib/ledger_sync/netsuite/vendor/searcher.rb +10 -0
  136. data/lib/ledger_sync/netsuite/vendor/searcher_deserializer.rb +19 -0
  137. data/lib/ledger_sync/netsuite/vendor/serializer.rb +28 -0
  138. data/lib/ledger_sync/netsuite/version.rb +17 -0
  139. data/license.txt +4 -0
  140. metadata +392 -0
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ # require client-specific types
4
+ Gem.find_files('ledger_sync/netsuite/type/**/*.rb').each { |path| require path }
5
+
6
+ module LedgerSync
7
+ module NetSuite
8
+ class Serializer < LedgerSync::Serializer
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LedgerSync
4
+ module NetSuite
5
+ class Subsidiary
6
+ class Deserializer < NetSuite::Deserializer
7
+ id
8
+
9
+ attribute :name
10
+
11
+ attribute :state
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LedgerSync
4
+ module NetSuite
5
+ class Subsidiary
6
+ class Searcher < NetSuite::Searcher
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LedgerSync
4
+ module NetSuite
5
+ class Subsidiary
6
+ class SearcherDeserializer < NetSuite::Deserializer
7
+ id
8
+
9
+ attribute :name
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LedgerSync
4
+ module NetSuite
5
+ class Subsidiary
6
+ class Serializer < NetSuite::Serializer
7
+ attribute :name
8
+
9
+ attribute :state
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,156 @@
1
+ # frozen_string_literal: true
2
+
3
+ # ref: https://docs.oracle.com/cloud/latest/netsuitecs_gs/NSATH/NSATH.pdf
4
+ # ref: Search "The Signature for Web Services and RESTlets" in NetSuite documentation (must have an account)
5
+ module LedgerSync
6
+ module NetSuite
7
+ class Token
8
+ DEFAULT_SIGNATURE_METHOD = 'HMAC-SHA256'
9
+ OAUTH_VERSION = '1.0'
10
+
11
+ attr_reader :consumer_key,
12
+ :consumer_secret,
13
+ :method,
14
+ :oauth_version,
15
+ :signature_method,
16
+ :token_id,
17
+ :token_secret,
18
+ :url
19
+
20
+ def initialize(args = {})
21
+ @consumer_key = args.fetch(:consumer_key)
22
+ @consumer_secret = args.fetch(:consumer_secret)
23
+ @method = args.fetch(:method).to_s.upcase
24
+ @nonce = args.fetch(:nonce, nil)
25
+ @oauth_version = args.fetch(:oauth_version, nil) || self.class::OAUTH_VERSION
26
+ @signature_method = args.fetch(:signature_method, nil) || self.class::DEFAULT_SIGNATURE_METHOD
27
+ @timestamp = args.fetch(:timestamp, nil)
28
+ @token_id = args.fetch(:token_id)
29
+ @token_secret = args.fetch(:token_secret)
30
+ @url = args.fetch(:url)
31
+ end
32
+
33
+ def alphanumerics
34
+ [*'0'..'9', *'A'..'Z', *'a'..'z']
35
+ end
36
+
37
+ def headers(realm:)
38
+ @headers ||= begin
39
+ authorization_parts = [
40
+ [:realm, realm],
41
+ [:oauth_consumer_key, escape(consumer_key)],
42
+ [:oauth_token, escape(token_id)],
43
+ [:oauth_signature_method, signature_method],
44
+ [:oauth_timestamp, timestamp],
45
+ [:oauth_nonce, escape(nonce)],
46
+ [:oauth_version, oauth_version],
47
+ [:oauth_signature, escape(signature)]
48
+ ]
49
+
50
+ ret = {
51
+ 'Authorization' => "OAuth #{authorization_parts.map { |k, v| "#{k}=\"#{v}\"" }.join(',')}"
52
+ }
53
+
54
+ ret
55
+ end
56
+ end
57
+
58
+ def nonce
59
+ @nonce ||= Array.new(20) { alphanumerics.sample }.join
60
+ end
61
+
62
+ def signature
63
+ @signature ||= compute_digest(signature_data_string)
64
+ end
65
+
66
+ # Ref: https://tools.ietf.org/html/rfc5849#section-3.4.1.3.2
67
+ def signature_data_string
68
+ @signature_data_string ||= begin
69
+ [
70
+ method,
71
+ escape(url_without_params),
72
+ escape(parameters_string)
73
+ ].join('&')
74
+ end
75
+ end
76
+
77
+ def signature_key
78
+ @signature_key ||= [
79
+ consumer_secret,
80
+ token_secret
81
+ ].join('&')
82
+ end
83
+
84
+ def timestamp
85
+ @timestamp ||= Time.now.to_i
86
+ end
87
+
88
+ private
89
+
90
+ def compute_digest(str)
91
+ signer = Util::Signer.new(str: str)
92
+
93
+ case signature_method
94
+ when 'HMAC-SHA1'
95
+ signer.hmac_sha1(key: signature_key)
96
+ when 'HMAC-SHA256'
97
+ signer.hmac_sha256(key: signature_key)
98
+ else
99
+ raise "Uknown signature method: #{signature_method}"
100
+ end
101
+ end
102
+
103
+ def escape(val)
104
+ Util::Signer.escape(str: val.to_s)
105
+ end
106
+
107
+ def oauth_parameters_array
108
+ {
109
+ oauth_consumer_key: consumer_key,
110
+ oauth_nonce: nonce,
111
+ oauth_signature_method: signature_method,
112
+ oauth_timestamp: timestamp,
113
+ oauth_token: token_id,
114
+ oauth_version: oauth_version
115
+ }.to_a
116
+ end
117
+
118
+ def parameters_string
119
+ @parameters_string ||= sorted_encoded_parameters
120
+ .map { |e| "#{e[0]}=#{e[1]}" }
121
+ .join('&')
122
+ end
123
+
124
+ def sorted_encoded_parameters
125
+ @sorted_encoded_parameters ||= url_params
126
+ .to_a
127
+ .concat(oauth_parameters_array)
128
+ .map { |k, v| [escape(k), escape(v)] }
129
+ .sort { |a, b| a <=> b }
130
+ end
131
+
132
+ def unescape(val)
133
+ Util::Signer.unescape(str: val.to_s)
134
+ end
135
+
136
+ def uri
137
+ @uri ||= URI(url)
138
+ end
139
+
140
+ def url_params
141
+ return {} if uri.query.nil?
142
+
143
+ @url_params ||= CGI.parse(uri.query).transform_values(&:first)
144
+ end
145
+
146
+ def url_without_params
147
+ @url_without_params ||= begin
148
+ temp_url = uri.dup
149
+ temp_url.fragment = nil
150
+ temp_url.query = nil
151
+ temp_url.to_s
152
+ end
153
+ end
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LedgerSync
4
+ module NetSuite
5
+ class Type
6
+ class DeserializerActiveType < LedgerSync::Type::Value
7
+ def cast_value(args = {})
8
+ value = args.fetch(:value)
9
+
10
+ return if value.nil?
11
+
12
+ case value
13
+ when 'F'
14
+ true
15
+ when 'T'
16
+ false
17
+ else
18
+ raise 'Unknown value'
19
+ end
20
+ end
21
+ end
22
+
23
+ def valid_classes
24
+ [
25
+ String
26
+ ]
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LedgerSync
4
+ module NetSuite
5
+ class Type
6
+ class DeserializerCustomerType < LedgerSync::Type::Value
7
+ def initialize(args = {})
8
+ @customer_class = args.fetch(:customer_class)
9
+
10
+ super()
11
+ end
12
+
13
+ private
14
+
15
+ def cast_value(args = {})
16
+ value = args.fetch(:value)
17
+
18
+ return if value.nil?
19
+
20
+ @customer_class.new(
21
+ ledger_id: value.fetch('id', nil)
22
+ )
23
+ end
24
+
25
+ def valid_classes
26
+ [
27
+ Hash
28
+ ]
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LedgerSync
4
+ module NetSuite
5
+ class Type
6
+ class DeserializerEntityType < LedgerSync::Type::Value
7
+ private
8
+
9
+ def cast_value(args = {})
10
+ value = args.fetch(:value)
11
+
12
+ return if value.nil?
13
+
14
+ resource = value.fetch('links').first.fetch('href').include?('vendor') ? Vendor : Customer
15
+ resource.new(
16
+ ledger_id: value['id']
17
+ )
18
+ end
19
+
20
+ def valid_classes
21
+ [
22
+ Hash
23
+ ]
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LedgerSync
4
+ module NetSuite
5
+ class Type
6
+ class DeserializerSubsidiaryType < LedgerSync::Type::Value
7
+ def initialize(args = {})
8
+ @subsidiary_class = args.fetch(:subsidiary_class)
9
+
10
+ super()
11
+ end
12
+
13
+ private
14
+
15
+ def cast_value(args = {})
16
+ value = args.fetch(:value)
17
+
18
+ return if value.nil?
19
+
20
+ @subsidiary_class.new(
21
+ ledger_id: value.fetch('id', nil)
22
+ )
23
+ end
24
+
25
+ def valid_classes
26
+ [
27
+ Hash
28
+ ]
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LedgerSync
4
+ module NetSuite
5
+ class Vendor
6
+ class Deserializer < NetSuite::Deserializer
7
+ id
8
+
9
+ attribute :company_name,
10
+ hash_attribute: :companyName
11
+
12
+ attribute :email
13
+
14
+ attribute :phone_number,
15
+ hash_attribute: :phone
16
+
17
+ attribute :first_name,
18
+ hash_attribute: :firstName
19
+
20
+ attribute :last_name,
21
+ hash_attribute: :lastName
22
+
23
+ attribute :subsidiary,
24
+ type: Type::DeserializerSubsidiaryType.new(subsidiary_class: Subsidiary)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LedgerSync
4
+ module NetSuite
5
+ class Vendor
6
+ module Operations
7
+ class Create < NetSuite::Operation::Create
8
+ class Contract < LedgerSync::Ledgers::Contract
9
+ params do
10
+ required(:external_id).filled(:string)
11
+ required(:ledger_id).value(:nil)
12
+ required(:company_name).filled(:string)
13
+ required(:display_name).filled(:string)
14
+ optional(:first_name).maybe(:string)
15
+ optional(:last_name).maybe(:string)
16
+ optional(:email).maybe(:string)
17
+ optional(:phone_number).maybe(:string)
18
+ required(:subsidiary).filled(:hash, Types::Reference)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LedgerSync
4
+ module NetSuite
5
+ class Vendor
6
+ module Operations
7
+ class Delete < NetSuite::Operation::Delete
8
+ class Contract < LedgerSync::Ledgers::Contract
9
+ params do
10
+ optional(:external_id).maybe(:string)
11
+ required(:ledger_id).filled(:string)
12
+ optional(:company_name).maybe(:string)
13
+ optional(:display_name).maybe(:string)
14
+ optional(:first_name).maybe(:string)
15
+ optional(:last_name).maybe(:string)
16
+ optional(:email).maybe(:string)
17
+ optional(:phone_number).maybe(:string)
18
+ optional(:subsidiary).maybe(:hash, Types::Reference)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LedgerSync
4
+ module NetSuite
5
+ class Vendor
6
+ module Operations
7
+ class Find < NetSuite::Operation::Find
8
+ class Contract < LedgerSync::Ledgers::Contract
9
+ params do
10
+ optional(:external_id).maybe(:string)
11
+ required(:ledger_id).filled(:string)
12
+ optional(:company_name).maybe(:string)
13
+ optional(:display_name).maybe(:string)
14
+ optional(:first_name).maybe(:string)
15
+ optional(:last_name).maybe(:string)
16
+ optional(:email).maybe(:string)
17
+ optional(:phone_number).maybe(:string)
18
+ optional(:subsidiary).maybe(:hash, Types::Reference)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end