eco-helpers 0.6.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 (123) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.rspec +3 -0
  4. data/README.md +20 -0
  5. data/eco-helpers.gemspec +34 -0
  6. data/lib/eco-helpers.rb +15 -0
  7. data/lib/eco/api.rb +13 -0
  8. data/lib/eco/api/common.rb +10 -0
  9. data/lib/eco/api/common/people.rb +17 -0
  10. data/lib/eco/api/common/people/base_parser.rb +16 -0
  11. data/lib/eco/api/common/people/default_parsers.rb +40 -0
  12. data/lib/eco/api/common/people/default_parsers/boolean_parser.rb +28 -0
  13. data/lib/eco/api/common/people/default_parsers/date_parser.rb +33 -0
  14. data/lib/eco/api/common/people/default_parsers/multi_parser.rb +33 -0
  15. data/lib/eco/api/common/people/default_parsers/numeric_parser.rb +23 -0
  16. data/lib/eco/api/common/people/default_parsers/select_parser.rb +29 -0
  17. data/lib/eco/api/common/people/entries.rb +120 -0
  18. data/lib/eco/api/common/people/person_entry.rb +380 -0
  19. data/lib/eco/api/common/people/person_factory.rb +114 -0
  20. data/lib/eco/api/common/people/person_modifier.rb +62 -0
  21. data/lib/eco/api/common/people/person_parser.rb +140 -0
  22. data/lib/eco/api/common/people/types.rb +47 -0
  23. data/lib/eco/api/common/session.rb +15 -0
  24. data/lib/eco/api/common/session/base_session.rb +46 -0
  25. data/lib/eco/api/common/session/environment.rb +47 -0
  26. data/lib/eco/api/common/session/file_manager.rb +90 -0
  27. data/lib/eco/api/common/session/logger.rb +105 -0
  28. data/lib/eco/api/common/session/mailer.rb +92 -0
  29. data/lib/eco/api/common/session/s3_uploader.rb +110 -0
  30. data/lib/eco/api/common/version_patches.rb +11 -0
  31. data/lib/eco/api/common/version_patches/external_person.rb +11 -0
  32. data/lib/eco/api/eco_faker.rb +59 -0
  33. data/lib/eco/api/organization.rb +13 -0
  34. data/lib/eco/api/organization/account.rb +23 -0
  35. data/lib/eco/api/organization/people.rb +118 -0
  36. data/lib/eco/api/organization/policy_groups.rb +51 -0
  37. data/lib/eco/api/organization/preferences.rb +28 -0
  38. data/lib/eco/api/organization/preferences_reference.json +23 -0
  39. data/lib/eco/api/organization/presets.rb +138 -0
  40. data/lib/eco/api/organization/presets_backup.rb +220 -0
  41. data/lib/eco/api/organization/presets_values.json +10 -0
  42. data/lib/eco/api/organization/tag_tree.rb +134 -0
  43. data/lib/eco/api/organization_old.rb +73 -0
  44. data/lib/eco/api/session.rb +180 -0
  45. data/lib/eco/api/session/batch.rb +132 -0
  46. data/lib/eco/api/session/batch_job.rb +152 -0
  47. data/lib/eco/api/session/batch_jobs.rb +131 -0
  48. data/lib/eco/api/session/batch_status.rb +138 -0
  49. data/lib/eco/api/session/task.rb +92 -0
  50. data/lib/eco/api/session_config.rb +179 -0
  51. data/lib/eco/api/session_config/api.rb +47 -0
  52. data/lib/eco/api/session_config/apis.rb +78 -0
  53. data/lib/eco/api/session_config/files.rb +30 -0
  54. data/lib/eco/api/session_config/logger.rb +54 -0
  55. data/lib/eco/api/session_config/mailer.rb +65 -0
  56. data/lib/eco/api/session_config/people.rb +89 -0
  57. data/lib/eco/api/session_config/s3_bucket.rb +62 -0
  58. data/lib/eco/api/session_config/use_cases.rb +30 -0
  59. data/lib/eco/api/usecases.rb +12 -0
  60. data/lib/eco/api/usecases/base_case.rb +14 -0
  61. data/lib/eco/api/usecases/case_data.rb +13 -0
  62. data/lib/eco/api/usecases/default_cases.rb +53 -0
  63. data/lib/eco/api/usecases/default_cases/change_email_case.rb +47 -0
  64. data/lib/eco/api/usecases/default_cases/create_details_case.rb +29 -0
  65. data/lib/eco/api/usecases/default_cases/create_details_with_supervisor_case.rb +49 -0
  66. data/lib/eco/api/usecases/default_cases/delete_case.rb +20 -0
  67. data/lib/eco/api/usecases/default_cases/email_as_id_case.rb +24 -0
  68. data/lib/eco/api/usecases/default_cases/hris_case.rb +67 -0
  69. data/lib/eco/api/usecases/default_cases/new_email_case.rb +26 -0
  70. data/lib/eco/api/usecases/default_cases/new_id_case.rb +26 -0
  71. data/lib/eco/api/usecases/default_cases/refresh_presets.rb +25 -0
  72. data/lib/eco/api/usecases/default_cases/reinvite_case.rb +22 -0
  73. data/lib/eco/api/usecases/default_cases/remove_account_case.rb +36 -0
  74. data/lib/eco/api/usecases/default_cases/reset_landing_page_case.rb +24 -0
  75. data/lib/eco/api/usecases/default_cases/set_default_tag_case.rb +44 -0
  76. data/lib/eco/api/usecases/default_cases/set_supervisor_case.rb +39 -0
  77. data/lib/eco/api/usecases/default_cases/to_csv_case.rb +36 -0
  78. data/lib/eco/api/usecases/default_cases/update_details_case.rb +30 -0
  79. data/lib/eco/api/usecases/default_cases/upsert_account_case.rb +35 -0
  80. data/lib/eco/api/usecases/use_case.rb +177 -0
  81. data/lib/eco/api/usecases/use_group.rb +104 -0
  82. data/lib/eco/cli.rb +9 -0
  83. data/lib/eco/cli/input.rb +109 -0
  84. data/lib/eco/cli/input_multi.rb +137 -0
  85. data/lib/eco/cli/root.rb +8 -0
  86. data/lib/eco/cli/session.rb +9 -0
  87. data/lib/eco/cli/session/batch.rb +9 -0
  88. data/lib/eco/common.rb +7 -0
  89. data/lib/eco/common/base_cli.rb +116 -0
  90. data/lib/eco/common/language.rb +9 -0
  91. data/lib/eco/data.rb +9 -0
  92. data/lib/eco/data/crypto.rb +7 -0
  93. data/lib/eco/data/crypto/encryption.rb +318 -0
  94. data/lib/eco/data/files.rb +10 -0
  95. data/lib/eco/data/files/directory.rb +93 -0
  96. data/lib/eco/data/files/file_pattern.rb +32 -0
  97. data/lib/eco/data/files/helpers.rb +90 -0
  98. data/lib/eco/data/mapper.rb +54 -0
  99. data/lib/eco/data/random.rb +10 -0
  100. data/lib/eco/data/random/distribution.rb +133 -0
  101. data/lib/eco/data/random/fake.rb +320 -0
  102. data/lib/eco/data/random/values.rb +80 -0
  103. data/lib/eco/language.rb +12 -0
  104. data/lib/eco/language/curry.rb +28 -0
  105. data/lib/eco/language/hash_transform.rb +68 -0
  106. data/lib/eco/language/hash_transform_modifier.rb +114 -0
  107. data/lib/eco/language/match.rb +30 -0
  108. data/lib/eco/language/match_modifier.rb +190 -0
  109. data/lib/eco/language/models.rb +11 -0
  110. data/lib/eco/language/models/attribute_parser.rb +38 -0
  111. data/lib/eco/language/models/collection.rb +181 -0
  112. data/lib/eco/language/models/modifier.rb +68 -0
  113. data/lib/eco/language/models/wrap.rb +114 -0
  114. data/lib/eco/language/values_at.rb +159 -0
  115. data/lib/eco/lexic/dictionary.rb +33 -0
  116. data/lib/eco/lexic/dictionary/dictionary.txt +355484 -0
  117. data/lib/eco/lexic/dictionary/tags.json +38 -0
  118. data/lib/eco/scripting.rb +30 -0
  119. data/lib/eco/scripting/README.md +11 -0
  120. data/lib/eco/scripting/arguments.rb +40 -0
  121. data/lib/eco/tester.rb +97 -0
  122. data/lib/eco/version.rb +3 -0
  123. metadata +325 -0
@@ -0,0 +1,380 @@
1
+ module Eco
2
+ module API
3
+ module Common
4
+ module People
5
+ class PersonEntry
6
+ @@cached_warnings = {}
7
+
8
+ def initialize(data, parser:, mapper:, dependencies: {}, logger: ::Logger.new(IO::NULL))
9
+ raise "Constructor needs a PersonParser. Given: #{parser}" if !parser.is_a?(Eco::API::Common::People::PersonParser)
10
+ raise "Expecting Mapper object. Given: #{mapper}" if mapper && !mapper.is_a?(Eco::Data::Mapper)
11
+
12
+ @source = data
13
+ @parser = parser
14
+ @mapper = mapper
15
+ @deps = dependencies
16
+ @logger = logger
17
+
18
+ if parsing?
19
+ # PARSING
20
+ @raw_entry = data
21
+ init_attr_trackers
22
+ @aliased_entry = mapped_entry(@raw_entry)
23
+ @int_row = internal_entry(@aliased_entry)
24
+
25
+ # internally named attrs scoped by mapper and parser against the current row
26
+ @int_attrs = @int_row.keys
27
+ else
28
+ # SERIALIZING
29
+ @person = data
30
+ @int_row = internal_entry(@person)
31
+ @aliased_entry = mapped_entry(@int_row)
32
+ @int_attrs = @parser.all_attrs
33
+ end
34
+
35
+ @core_attrs = @parser.target_attrs_core(@int_attrs)
36
+ @details_attrs = @parser.target_attrs_details(@int_attrs)
37
+ @account_attrs = @parser.target_attrs_account(@int_attrs)
38
+ end
39
+
40
+ def parsing?
41
+ !is_person?(@source)
42
+ end
43
+
44
+ def serializing?
45
+ !parsing?
46
+ end
47
+
48
+ # SHORTCUTS
49
+
50
+ def id
51
+ @int_row["id"]
52
+ end
53
+
54
+ def external_id
55
+ @int_row["external_id"]
56
+ end
57
+
58
+ def name
59
+ @int_row["name"]
60
+ end
61
+
62
+ def email
63
+ @int_row["email"]
64
+ end
65
+
66
+ def supervisor_id
67
+ @int_row["supervisor_id"]
68
+ end
69
+
70
+ def supervisor_id=(value)
71
+ @int_row["supervisor_id"] = value
72
+ end
73
+
74
+ def to_s(options)
75
+ options = into_a(options)
76
+ case
77
+ when options.include?(:identify)
78
+ "'#{name}' ('#{external_id}': '#{email}')"
79
+ else
80
+ @int_row.each.map do |k, v|
81
+ "'#{k}': '#{v.to_json}'"
82
+ end.join(" | ")
83
+ end
84
+ end
85
+
86
+ # SETTERS
87
+ def set_core(person, exclude: nil)
88
+ scoped_attrs = @core_attrs - into_a(exclude)
89
+ @int_row.slice(*scoped_attrs).each do |attr, value|
90
+ set_to_core(person, attr, value)
91
+ end
92
+ end
93
+
94
+ def set_details(person, exclude: nil)
95
+ person.add_details(@parser.schema) if !person.details || !person.details.schema_id
96
+ scoped_attrs = @details_attrs - into_a(exclude)
97
+ @int_row.slice(*scoped_attrs).each do |attr, value|
98
+ set_to_details(person, attr, value)
99
+ end
100
+ end
101
+
102
+ def set_account(person, exclude: nil)
103
+ person.account = {} if !person.account
104
+ person.account.permissions_preset = nil unless person.account.permissions_preset = "custom"
105
+ scoped_attrs = @account_attrs - into_a(exclude)
106
+ @int_row.slice(*scoped_attrs).each do |attr, value|
107
+ set_to_account(person, attr, value)
108
+ end
109
+ end
110
+
111
+ # GETTERS
112
+ def entry(klass: nil)
113
+ return klass.new(to_hash) if klass
114
+ to_hash
115
+ end
116
+
117
+ def to_hash
118
+ @aliased_entry.each.map do |int_attr, v|
119
+ [to_external(int_attr), v || ""] if to_external(int_attr)
120
+ end.compact.to_h
121
+ end
122
+
123
+ private
124
+
125
+ def set_to_core (person, attr, value)
126
+ value = value&.downcase if attr == "email"
127
+ person.send("#{attr}=", value&.strip)
128
+ end
129
+
130
+ def set_to_account (person, attr, value)
131
+ return if !person.account
132
+ multiple = ["policy_group_ids", "filter_tags"].include?(attr)
133
+ if multiple
134
+ value = @parser.parse(:multiple, value)
135
+ value = value.map { |v| v&.upcase } if attr == "filter_tags"
136
+ # preserve previous order
137
+ current = into_a(person.account.send(attr))
138
+ value = (current & value) + (value - current)
139
+ end
140
+
141
+ person.account.send("#{attr}=", value)
142
+ end
143
+
144
+ def set_to_details (person, attr, value)
145
+ return if !person.details
146
+ field = person.details.get_field(attr)
147
+ fatal("Field '#{attr}' does not exist in details of schema: '#{person.details.schema_id}'") if !field
148
+ value = @parser.parse(:multiple, value) if field.multiple
149
+
150
+ if @parser.defined?(field.type.to_sym)
151
+ value = @parser.parse(field.type.to_sym, value, deps: {"attr" => attr})
152
+ end
153
+
154
+ person.details[attr] = value
155
+ end
156
+
157
+ def get_from_core (person, attr)
158
+ person.send(attr)
159
+ end
160
+
161
+ def get_from_account (person, attr)
162
+ return "-" if !person.account
163
+ multiple = ["policy_group_ids", "filter_tags"].include?(attr)
164
+ value = person.account.send(attr)
165
+ @parser.serialize(:multiple, value) if multiple
166
+ end
167
+
168
+ def get_from_details (person, attr)
169
+ return "-" if !person.details || !person&.details&.schema_id
170
+ field = person.details.get_field(attr)
171
+ fatal("Field '#{attr}' does not exist in details of schema: '#{person.details.schema_id}'") if !field
172
+ value = person.details[attr]
173
+ value = @parser.serialize(:date, value) if field.type == "date"
174
+ value = @parser.serialize(:multiple, value) if field.multiple
175
+ value
176
+ end
177
+
178
+ # INIT
179
+
180
+ # when parsing:
181
+ def init_attr_trackers
182
+ # internal <-> external attributes
183
+ int_aliased = @parser.all_attrs.select { |attr| to_external(attr) }
184
+ ext_alias = int_aliased.map { |attr| to_external(attr) }
185
+
186
+ # virtual attrs (non native internal attr that require aliasing):
187
+ ext_vi_aliased = attributes(@raw_entry).select do |attr|
188
+ !ext_alias.include?(attr) && @mapper.external?(attr)
189
+ end
190
+
191
+ int_vi_aliased = ext_vi_aliased.map { |attr| @mapper.to_internal(attr) }
192
+ @aliased_attrs = int_aliased + int_vi_aliased
193
+
194
+ int_unlinked = @parser.undefined_attrs.select { |attr| !to_external(attr) }
195
+ # those with parser or alias:
196
+ int_linked = @parser.all_attrs - int_unlinked
197
+
198
+ ext_aliased = ext_alias + ext_vi_aliased
199
+ # those that are direct external to internal:
200
+ ext_direct = attributes(@raw_entry) - ext_aliased
201
+ # to avoid collisions between internal names:
202
+ @direct_attrs = ext_direct - int_linked
203
+ end
204
+
205
+ # MAPPED ENTRY (when and where applicable)
206
+ # return entry with internal names and external values
207
+ def mapped_entry(data)
208
+ return aliased_entry(data) if parsing?
209
+ serialized_entry(data)
210
+ end
211
+
212
+ # parse: here we aliase attribute names
213
+ def aliased_entry(raw_data)
214
+ aliased_hash = @aliased_attrs.map do |attr|
215
+ [attr, raw_data[to_external(attr)]]
216
+ end.to_h
217
+
218
+ direct_hash = @direct_attrs.map do |attr|
219
+ [attr, raw_data[attr]]
220
+ end.to_h
221
+
222
+ aliased_hash.merge!(direct_hash)
223
+ end
224
+
225
+ def hash_attr(attr, value)
226
+ return value if value.is_a?(Hash)
227
+ { attr => value }
228
+ end
229
+
230
+ # serializing: run serializers (overrides existing keys)
231
+ def serialized_entry(unserialized_entry)
232
+ serial_attrs = @parser.defined_attrs.reduce({}) do |serial_hash, attr|
233
+ deps = @deps[attr] || {}
234
+ serial_attr = @parser.serialize(attr, @person, deps: deps)
235
+ serial_hash.merge(hash_attr(attr, serial_attr))
236
+ end
237
+ unserialized_entry.merge(serial_attrs)
238
+ end
239
+
240
+ # returns entry with interal names and values
241
+ def internal_entry(data)
242
+ return parsed_entry(data) if parsing?
243
+ unserialized_entry(data)
244
+ end
245
+
246
+ # parse: to internal entry (parse values)
247
+ def parsed_entry(aliased_entry)
248
+ parsed = @parser.defined_attrs.map do |attr|
249
+ value = @parser.parse(attr, aliased_entry)
250
+ [attr, value]
251
+ end.to_h
252
+ aliased_entry.merge(parsed)
253
+ end
254
+
255
+ # serializing: to internal entry (create the internal entry out of a person)
256
+ def unserialized_entry(person)
257
+ core_hash = @parser.target_attrs_core.reduce({}) do |hash, attr|
258
+ value = get_from_core(person, attr)
259
+ hash.merge(hash_attr(attr, value))
260
+ end
261
+
262
+ details_hash = @parser.target_attrs_details.reduce({}) do |hash, attr|
263
+ value = get_from_details(person, attr)
264
+ hash.merge(hash_attr(attr, value))
265
+ end
266
+
267
+ account_hash = @parser.target_attrs_account.reduce({}) do |hash, attr|
268
+ value = get_from_account(person, attr)
269
+ hash.merge(hash_attr(attr, value))
270
+ end
271
+
272
+ details_hash.merge(account_hash).merge(core_hash)
273
+ #core_hash.merge(account_hash).merge(details_hash)
274
+ end
275
+
276
+
277
+ def to_internal(value)
278
+ return value if !@mapper
279
+ attr = value
280
+ case value
281
+ when Array
282
+ return value.map do |v|
283
+ to_internal(v)
284
+ end.compact
285
+ when String
286
+ case
287
+ when @mapper.external?(value)
288
+ attr = @mapper.to_internal(value)
289
+ when @mapper.external?(value.strip)
290
+ unless cached_warning("external", "spaces", value)
291
+ logger.warn("The external person field name '#{value}' contains additional spaces in the reference file")
292
+ end
293
+ attr = @mapper.to_internal(value.strip)
294
+ when @mapper.internal?(value) || @mapper.internal?(value.strip) || @mapper.internal?(value.strip.downcase)
295
+ unless cached_warning("external", "reversed", value)
296
+ logger.warn("The mapper [external, internal] attribute names may be declared reversedly for EXTERNAL attribute: '#{value}'")
297
+ end
298
+ end
299
+ end
300
+
301
+ return nil unless @parser.all_attrs.include?(attr)
302
+ end
303
+
304
+ def to_external(value)
305
+ return value if !@mapper
306
+ attr = value
307
+ case value
308
+ when Array
309
+ return value.map do |v|
310
+ to_external(v)
311
+ end.compact
312
+ when String
313
+ case
314
+ when @mapper.internal?(value)
315
+ attr = @mapper.to_external(value)
316
+ when @mapper.internal?(value.strip)
317
+ unless cached_warning("internal", "spaces", value)
318
+ logger.warn("The internal person field name '#{value}' contains additional spaces in the reference file")
319
+ end
320
+ attr = @mapper.to_external(value.strip)
321
+ when @mapper.external?(value) || @mapper.external?(value.strip) || @mapper.external?(value.strip.downcase)
322
+ unless cached_warning("internal", "reversed", value)
323
+ logger.warn("The mapper [external, internal] attribute names may be declared reversedly for INTERNAL attribute: '#{value}'")
324
+ end
325
+ end
326
+ end
327
+
328
+ return nil unless !@raw_entry || attributes(@raw_entry).include?(attr)
329
+ attr
330
+ end
331
+
332
+ # LOGGER
333
+ def logger
334
+ @logger || ::Logger.new(IO::NULL)
335
+ end
336
+
337
+ def cached_warning(*args)
338
+ unless exists = !!@@cached_warnings.dig(*args)
339
+ args.reduce(@@cached_warnings) do |cache, level|
340
+ cache[level] = {} if !cache.key?(level)
341
+ cache[level]
342
+ end
343
+ end
344
+ exists
345
+ end
346
+
347
+ def fatal(msg)
348
+ logger.fatal(msg)
349
+ exit
350
+ end
351
+
352
+ # HELPERS
353
+ def into_a(value)
354
+ value = [] if value == nil
355
+ value = [].push(value) unless value.is_a?(Array)
356
+ value
357
+ end
358
+
359
+ def attributes(value)
360
+ case value
361
+ when CSV::Row
362
+ value&.headers
363
+ when Hash
364
+ value&.keys
365
+ when PersonEntry
366
+ @parser.target_attrs_core
367
+ else
368
+ []
369
+ end
370
+ end
371
+
372
+ def is_person?(value)
373
+ value.is_a?(Ecoportal::API::Internal::Person)
374
+ end
375
+
376
+ end
377
+ end
378
+ end
379
+ end
380
+ end
@@ -0,0 +1,114 @@
1
+ module Eco
2
+ module API
3
+ module Common
4
+ module People
5
+ class PersonFactory
6
+
7
+ include Common::People
8
+
9
+ attr_reader :schema_attrs
10
+
11
+ def initialize(person: {}, schema: {}, account: {}, modifier: Common::People::PersonModifier.new)
12
+ @modifier = Common::People::PersonModifier.new(modifier)
13
+ @person = person
14
+ @account = account
15
+ @schema = schema
16
+ @schema_attrs = @schema&.fields&.map { |fld| fld.alt_id }
17
+ end
18
+
19
+ def new(person: nil)
20
+ in_raw_modifier = Common::People::PersonModifier.new.no_details
21
+ return PersonFactory.new(person: person, schema: @schema, modifier: in_raw_modifier).new unless !person
22
+ person = klass.new(person_hash(@person))
23
+ person.account = account_hash(@account) if @modifier.add_account? && @modifier.internal?
24
+ person.details = details_hash(@schema) unless @modifier.no_details?
25
+ person
26
+ end
27
+
28
+ def new_contact(schema)
29
+ factory = self.class.new(@modifier.reset_account, person: @person, schema: @schema, account: @account)
30
+ factory.new
31
+ end
32
+
33
+ def new_doc
34
+ new_hash(@modifier)
35
+ end
36
+
37
+ def schema_id
38
+ nil if !@schema
39
+ @schema['schema_id'] || @schema['id']
40
+ end
41
+
42
+ private
43
+
44
+ def klass
45
+ if @modifier.external?
46
+ EXTERNAL::Person
47
+ else
48
+ INTERNAL::Person
49
+ end
50
+ end
51
+
52
+ def new_hash(modifier)
53
+ modifier = Common::People::PersonModifier.new(modifier)
54
+ doc = person_hash(@person)
55
+ doc = add_account(doc, @account) if modifier.add_account? && modifier.internal?
56
+ doc = add_details(doc, @schema) unless modifier.no_details?
57
+ end
58
+
59
+ def add_details(doc, details)
60
+ return nil if !doc
61
+ doc_det = details_hash(details)
62
+ doc.merge({ "details" => doc_det })
63
+ end
64
+
65
+ def add_account(doc, account)
66
+ return nil if !doc
67
+ doc_acc = account_hash(account)
68
+ doc.merge({ "account" => doc_acc })
69
+ end
70
+
71
+ def person_hash(person)
72
+ case
73
+ when is_person?(person)
74
+ JSON.parse(person.doc.to_json)
75
+ when person.is_a?(Hash)
76
+ JSON.parse(person.to_json)
77
+ else
78
+ {}
79
+ end
80
+ end
81
+
82
+ def details_hash(details)
83
+ case
84
+ when details.is_a?(EXTERNAL::PersonDetails)
85
+ doc = JSON.parse(details.doc.to_json)
86
+ when details.is_a?(EXTERNAL::PersonSchema)
87
+ doc =JSON.parse(details.doc.to_json)
88
+ when details.is_a?(Hash)
89
+ doc = JSON.parse(details.to_json)
90
+ doc = doc["details"] if doc.key?("details")
91
+ else
92
+ doc = {}
93
+ end
94
+ doc["schema_id"] = doc.delete("id") if doc&.key?("id")
95
+ doc
96
+ end
97
+
98
+ def account_hash(account)
99
+ case
100
+ when account.is_a?(INTERNAL::Account)
101
+ JSON.parse(account.doc.to_json)
102
+ when account.is_a?(Hash)
103
+ doc = JSON.parse(account.to_json)
104
+ doc["account"] if doc.key?("account")
105
+ else
106
+ {}
107
+ end
108
+ end
109
+
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end