eco-helpers 2.0.22 → 2.0.27

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +95 -5
  3. data/lib/eco/api/common.rb +0 -1
  4. data/lib/eco/api/common/loaders.rb +2 -0
  5. data/lib/eco/api/common/loaders/base.rb +58 -0
  6. data/lib/eco/api/common/loaders/case_base.rb +33 -0
  7. data/lib/eco/api/common/loaders/error_handler.rb +2 -2
  8. data/lib/eco/api/common/loaders/parser.rb +30 -5
  9. data/lib/eco/api/common/loaders/policy.rb +1 -1
  10. data/lib/eco/api/common/loaders/use_case.rb +1 -1
  11. data/lib/eco/api/common/people/default_parsers/csv_parser.rb +129 -1
  12. data/lib/eco/api/common/people/entries.rb +83 -14
  13. data/lib/eco/api/common/people/entry_factory.rb +11 -10
  14. data/lib/eco/api/common/people/person_attribute_parser.rb +8 -0
  15. data/lib/eco/api/common/people/person_entry.rb +7 -6
  16. data/lib/eco/api/common/people/person_entry_attribute_mapper.rb +55 -16
  17. data/lib/eco/api/common/people/person_factory.rb +4 -2
  18. data/lib/eco/api/common/people/person_parser.rb +7 -1
  19. data/lib/eco/api/common/people/supervisor_helpers.rb +1 -1
  20. data/lib/eco/api/common/version_patches/ecoportal_api/external_person.rb +0 -8
  21. data/lib/eco/api/common/version_patches/ecoportal_api/internal_person.rb +0 -8
  22. data/lib/eco/api/microcases/set_core_with_supervisor.rb +4 -2
  23. data/lib/eco/api/microcases/set_supervisor.rb +29 -8
  24. data/lib/eco/api/microcases/with_each.rb +7 -3
  25. data/lib/eco/api/microcases/with_each_starter.rb +3 -2
  26. data/lib/eco/api/organization/people.rb +7 -1
  27. data/lib/eco/api/session.rb +7 -2
  28. data/lib/eco/api/session/batch.rb +1 -1
  29. data/lib/eco/api/session/batch/job.rb +42 -9
  30. data/lib/eco/api/usecases/default_cases/create_case.rb +10 -1
  31. data/lib/eco/api/usecases/default_cases/create_details_case.rb +10 -1
  32. data/lib/eco/api/usecases/default_cases/create_details_with_supervisor_case.rb +10 -1
  33. data/lib/eco/api/usecases/default_cases/hris_case.rb +25 -1
  34. data/lib/eco/api/usecases/default_cases/to_csv_case.rb +1 -37
  35. data/lib/eco/api/usecases/default_cases/to_csv_detailed_case.rb +42 -0
  36. data/lib/eco/api/usecases/default_cases/upsert_case.rb +10 -1
  37. data/lib/eco/cli/config/default/input.rb +2 -2
  38. data/lib/eco/cli/config/default/options.rb +44 -7
  39. data/lib/eco/cli/config/default/usecases.rb +16 -0
  40. data/lib/eco/cli/config/default/workflow.rb +7 -4
  41. data/lib/eco/cli/config/filters.rb +6 -2
  42. data/lib/eco/cli/config/filters/input_filters.rb +3 -2
  43. data/lib/eco/cli/config/filters/people_filters.rb +3 -2
  44. data/lib/eco/cli/config/help.rb +1 -1
  45. data/lib/eco/cli/config/options_set.rb +6 -4
  46. data/lib/eco/cli/config/use_cases.rb +6 -3
  47. data/lib/eco/csv.rb +2 -0
  48. data/lib/eco/language/models/collection.rb +5 -2
  49. data/lib/eco/version.rb +1 -1
  50. metadata +3 -2
  51. data/lib/eco/api/common/base_loader.rb +0 -72
@@ -7,16 +7,20 @@ module Eco
7
7
  # @param entries [Eco::API::Common::People::Entries] the input entries with the data.
8
8
  # @param people [Eco::API::Organization::People] target existing _People_ of the current update.
9
9
  # @param options [Hash] the options.
10
+ # @param append_created [Boolean] whether or not a new person will be added to the `people` object.
10
11
  # @yield [entry, person] gives each entry, and the paired person thereof (new or existing).
11
12
  # @yieldparam entry [PersonEntry] the input entry with the data we should set on person.
12
13
  # @yieldparam person [Ecoportal::API::V1::Person] the found person that matches `entry`, or a new person otherwise.
13
14
  # @return [Eco::API::Organization::People] all the people, including new and existing ones.
14
- def with_each(entries, people, options)
15
+ def with_each(entries, people, options, append_created: true)
15
16
  @_skip_all_multiple_results = false
17
+ people_copy = people.newFrom(people.to_a)
16
18
  entries.each_with_object([]) do |entry, scoped|
17
19
  begin
18
- unless person = people.find(entry, strict: micro.strict_search?(options))
19
- person = session.new_person
20
+ unless person = people_copy.find(entry, strict: micro.strict_search?(options))
21
+ person = session.new_person.tap do |person|
22
+ people << person if append_created
23
+ end
20
24
  end
21
25
  rescue Eco::API::Organization::People::MultipleSearchResults => e
22
26
  unless @_skip_all_multiple_results
@@ -8,13 +8,14 @@ module Eco
8
8
  # @param people [Eco::API::Organization::People] target existing _People_ of the current update.
9
9
  # @param options [Hash] the options.
10
10
  # @param log_present [Boolean] log error message if an `entry` has match in `people`.
11
+ # @param append_created [Boolean] whether or not a new person will be added to the `people` object.
11
12
  # @yield [entry, person] gives each **new** `person` of `entries` that is not present in `people`.
12
13
  # @yieldparam entry [PersonEntry] the input entry with the data we should set on person.
13
14
  # @yieldparam person [Ecoportal::API::V1::Person] the **new** person.
14
15
  # @return [Eco::API::Organization::People] the starters.
15
- def with_each_starter(entries, people, options, log_present: false)
16
+ def with_each_starter(entries, people, options, log_present: false, append_created: true)
16
17
  starters = []
17
- micro.with_each(entries, people, options) do |entry, person|
18
+ micro.with_each(entries, people, options, append_created: append_created) do |entry, person|
18
19
  if !person.new?
19
20
  if log_present
20
21
  session.logger.error("This person (id: '#{person.id}') already exists: #{entry.to_s(:identify)}")
@@ -210,6 +210,12 @@ module Eco
210
210
  to_h(:supervisor_id)
211
211
  end
212
212
 
213
+ def group_by_schema
214
+ to_h do |person|
215
+ person.details && person.details.schema_id
216
+ end
217
+ end
218
+
213
219
  def to_h(attr = "id")
214
220
  super(attr || "id")
215
221
  end
@@ -252,7 +258,7 @@ module Eco
252
258
 
253
259
  def init_caches
254
260
  return if @caches_init
255
- @by_id = to_h
261
+ @by_id = no_nil_key(to_h)
256
262
  @by_external_id = no_nil_key(to_h('external_id'))
257
263
  @by_users_email = no_nil_key(existing_users.to_h('email'))
258
264
  @by_non_users_email = no_nil_key(non_users.to_h('email'))
@@ -153,9 +153,14 @@ module Eco
153
153
  # Generates an entries collection from a csv input file.
154
154
  # @see Eco::API::Common::People::EntryFactory#entries
155
155
  # @param file [String] file to generate the entries from.
156
+ # @param (see Eco::API::Session#entries)
156
157
  # @return [Eco::API::Common::People::Entries] collection of entries.
157
- def csv_entries(file)
158
- return entries(file: file, format: :csv)
158
+ def csv_entries(file, **kargs)
159
+ kargs.merge!({
160
+ file: file,
161
+ format: :csv
162
+ })
163
+ return entries(**kargs)
159
164
  end
160
165
 
161
166
  # Generates the collection of entries that should be discarded from an update.
@@ -137,7 +137,7 @@ module Eco
137
137
  rescue error_type => e
138
138
  raise unless retries_left > 0
139
139
  explanation = "Batch TimeOut. You have #{retries_left} retries left."
140
- prompt_user("Do you want to retry (y/N)?", explanation, default: "Y", timeout: 10) do |response|
140
+ prompt_user(" Do you want to retry (y/N)?", default: "Y", explanation: explanation, timeout: 10) do |response|
141
141
  if response.upcase.start_with?("Y")
142
142
  offer_retry_on(error_type, retries_left - 1, &block)
143
143
  else
@@ -164,12 +164,17 @@ module Eco
164
164
  # @return [Eco::API::Session::Batch::Status]
165
165
  def launch(simulate: false)
166
166
  pqueue = processed_queue
167
- @requests = pqueue.map {|e| as_update(e)}
167
+ @requests = as_update(pqueue)
168
168
  pre_checks(requests, simulate: simulate)
169
169
 
170
- unless simulate
170
+ if simulate
171
+ if options.dig(:requests, :backup)
172
+ req_backup = as_update(pqueue, add_feedback: false)
173
+ backup_update(req_backup, simulate: simulate)
174
+ end
175
+ else
171
176
  if pqueue.length > 0
172
- req_backup = pqueue.map {|e| as_update(e, add_feedback: false)}
177
+ req_backup = as_update(pqueue, add_feedback: false)
173
178
  backup_update(req_backup)
174
179
  session.batch.launch(pqueue, method: type).tap do |job_status|
175
180
  @status = job_status
@@ -220,13 +225,26 @@ module Eco
220
225
  end.join("\n")
221
226
  end
222
227
 
223
- def as_update(*args)
224
- feedback.as_update(*args)
228
+ def as_update(data, *args)
229
+ if data.is_a?(Array)
230
+ data.map do |e|
231
+ feedback.as_update(e, *args)
232
+ end.compact.select {|e| e && !e.empty?}
233
+ else
234
+ feedback.as_update(data, *args)
235
+ end
225
236
  end
226
237
 
227
238
  def processed_queue
228
239
  @queue.each {|e| @callbacks[e].call(e) if @callbacks.key?(e) }
229
- apply_policies(api_included(@queue)).select {|e| !as_update(e).empty?}
240
+ apply_policies(api_included(@queue)).select do |e|
241
+ !as_update(e).empty?
242
+ end.select do |e|
243
+ next true unless e.is_a?(Ecoportal::API::V1::Person)
244
+ next true unless e.new?
245
+ # new people should either have account or details
246
+ e.account || e.details
247
+ end
230
248
  end
231
249
 
232
250
  # if there is a config definition to exclude entries
@@ -235,7 +253,13 @@ module Eco
235
253
  def api_included(full_queue)
236
254
  return full_queue if type == :create
237
255
  return full_queue unless excluded = session.config.people.api_excluded
238
- full_queue.select {|entry| !excluded.call(entry, session, options, self)}
256
+ if options.dig(:include, :excluded, :only)
257
+ full_queue.select {|entry| excluded.call(entry, session, options, self)}
258
+ elsif options.dig(:include, :excluded)
259
+ full_queue
260
+ else
261
+ full_queue.select {|entry| !excluded.call(entry, session, options, self)}
262
+ end
239
263
  end
240
264
 
241
265
  # Applies the changes introduced by api policies
@@ -280,6 +304,9 @@ module Eco
280
304
  if !simulate && status
281
305
  status.queue.map do |entry|
282
306
  if status.success?(entry)
307
+ if type == :create && entry.respond_to?(:id=)
308
+ entry.id = status[entry].body["id"]
309
+ end
283
310
  entry.consolidate! if entry.respond_to?(:consolidate!)
284
311
  #else # do not entry.reset! (keep track on changes still)
285
312
  end
@@ -300,16 +327,22 @@ module Eco
300
327
  end
301
328
  end
302
329
  elsif simulate
330
+ fake_id = 111111111111111111111111
303
331
  queue.map do |entry|
332
+ if type == :create && entry.respond_to?(:id=)
333
+ entry.id = fake_id.to_s
334
+ fake_id += 1
335
+ end
304
336
  entry.consolidate! if entry.respond_to?(:consolidate!)
305
337
  end
306
338
  end
307
339
  end
308
340
 
309
341
  # Keep a copy of the requests for future reference
310
- def backup_update(requests)
342
+ def backup_update(requests, simulate: false)
343
+ dry_run = simulate ? "_dry_run" : ""
311
344
  dir = config.people.requests_folder
312
- file = File.join(dir, "#{type}_data.json")
345
+ file = File.join(dir, "#{type}_data#{dry_run}.json")
313
346
  file_manager.save_json(requests, file, :timestamp)
314
347
  end
315
348
 
@@ -2,12 +2,15 @@ class Eco::API::UseCases::DefaultCases::CreateCase < Eco::API::Common::Loaders::
2
2
  name "create"
3
3
  type :sync
4
4
 
5
+ attr_reader :options
6
+
5
7
  def main(entries, people, session, options, usecase)
8
+ options = @options
6
9
  micro = session.micro
7
10
  creation = session.new_job("main", "create", :create, usecase)
8
11
  supers = session.new_job("post", "supers", :update, usecase, :core)
9
12
 
10
- micro.with_each_starter(entries, people, options, log_present: true) do |entry, person|
13
+ micro.with_each_starter(entries, people, options, log_present: true, append_created: append_created) do |entry, person|
11
14
  creation.add(person)
12
15
  micro.set_core_with_supervisor(entry, person, people, supers, options)
13
16
  entry.set_details(person) unless options.dig(:exclude, :details)
@@ -15,4 +18,10 @@ class Eco::API::UseCases::DefaultCases::CreateCase < Eco::API::Common::Loaders::
15
18
  end
16
19
  end
17
20
 
21
+ private
22
+
23
+ def append_created
24
+ options.dig(:people, :append_created)
25
+ end
26
+
18
27
  end
@@ -2,15 +2,24 @@ class Eco::API::UseCases::DefaultCases::CreateDetailsCase < Eco::API::Common::Lo
2
2
  name "create-details"
3
3
  type :sync
4
4
 
5
+ attr_reader :options
6
+
5
7
  def main(entries, people, session, options, usecase)
8
+ @options = options
6
9
  micro = session.micro
7
10
  creation = session.new_job("main", "create", :create, usecase)
8
11
 
9
- micro.with_each_starter(entries, people, options, log_present: true) do |entry, person|
12
+ micro.with_each_starter(entries, people, options, log_present: true, append_created: append_created) do |entry, person|
10
13
  creation.add(person)
11
14
  micro.set_core(entry, person, options)
12
15
  entry.set_details(person) unless options.dig(:exclude, :details)
13
16
  end
14
17
  end
15
18
 
19
+ private
20
+
21
+ def append_created
22
+ options.dig(:people, :append_created)
23
+ end
24
+
16
25
  end
@@ -2,16 +2,25 @@ class Eco::API::UseCases::DefaultCases::CreateDetailsWithSupervisorCase < Eco::A
2
2
  name "create-details-with-supervisor"
3
3
  type :sync
4
4
 
5
+ attr_reader :options
6
+
5
7
  def main(entries, people, session, options, usecase)
8
+ @options = options
6
9
  micro = session.micro
7
10
  creation = session.new_job("main", "create", :create, usecase)
8
11
  supers = session.new_job("post", "supers", :update, usecase, :core)
9
12
 
10
- micro.with_each_starter(entries, people, options, log_present: true) do |entry, person|
13
+ micro.with_each_starter(entries, people, options, log_present: true, append_created: append_created) do |entry, person|
11
14
  creation.add(person)
12
15
  micro.set_core_with_supervisor(entry, person, people, supers, options)
13
16
  entry.set_details(person) unless options.dig(:exclude, :details)
14
17
  end
15
18
  end
16
19
 
20
+ private
21
+
22
+ def append_created
23
+ options.dig(:people, :append_created)
24
+ end
25
+
17
26
  end
@@ -3,8 +3,11 @@ class Eco::API::UseCases::DefaultCases::HrisCase < Eco::API::Common::Loaders::Us
3
3
  type :sync
4
4
 
5
5
  attr_reader :creation, :update, :supers, :leavers
6
+ attr_reader :people, :session, :options
6
7
 
7
8
  def main(entries, people, session, options, usecase)
9
+ @session = session; @options = options; @people = people
10
+ require_only_one_schema!
8
11
  micro = session.micro
9
12
  @creation = session.new_job("main", "create", :create, usecase)
10
13
  @update = session.new_job("main", "update", :update, usecase)
@@ -15,7 +18,7 @@ class Eco::API::UseCases::DefaultCases::HrisCase < Eco::API::Common::Loaders::Us
15
18
  leavers.add(person, &method(:leavers_callback))
16
19
  end
17
20
 
18
- micro.with_each(entries, people, options) do |entry, person|
21
+ micro.with_each(entries, people, options, append_created: append_created) do |entry, person|
19
22
  person.new? ? creation.add(person) : update.add(person)
20
23
  micro.set_core_with_supervisor(entry, person, people, supers, options)
21
24
  entry.set_details(person) unless options.dig(:exclude, :details)
@@ -25,9 +28,30 @@ class Eco::API::UseCases::DefaultCases::HrisCase < Eco::API::Common::Loaders::Us
25
28
 
26
29
  private
27
30
 
31
+ def append_created
32
+ options.dig(:people, :append_created)
33
+ end
34
+
28
35
  def leavers_callback(person)
29
36
  person.supervisor_id = nil
30
37
  person.account = nil if person.account
31
38
  end
32
39
 
40
+ def require_only_one_schema!
41
+ unless schema_id = options.dig(:people, :filter, :details, :schema_id)
42
+ active_schema = session.schema
43
+ other_schemas = session.schemas.map(&:id) - [active_schema.id]
44
+ other_people = people.group_by_schema.values_at(*other_schemas).map(&:to_a).flatten
45
+ if other_people.length > 3
46
+ msg = "There are #{other_people.length} people in schemas other than #{active_schema.name}."
47
+ msg << " Please, use the filter option '-schema_id SchemaName' for the 'hris' case to only include those of that schema"
48
+ msg << " in the current update. The HRIS case identifies people that are not in the file as leavers"
49
+ msg << " (as it will remove the account of all the people of other schemas if they are not in the input file)."
50
+ msg << "\n For example: -schema-id '#{active_schema.name.downcase}'"
51
+ logger.error(msg)
52
+ raise msg
53
+ end
54
+ end
55
+ end
56
+
33
57
  end
@@ -125,43 +125,7 @@ class Eco::API::UseCases::DefaultCases::ToCsvCase < Eco::API::Common::Loaders::U
125
125
  "id" => "ecoPortal ID",
126
126
  "external_id" => "Reference ID (ext_id)",
127
127
  "login_provider_ids" => "Login Methods",
128
- "landing_page_id" => "Landing Page ID",
129
- "show_sidebar" => "(pref) Sidebar Open?",
130
- "show_shortcuts" => "(pref) Link to Registers?",
131
- "show_coming_soon" => "(pref) Coming Soon List?",
132
- "show_recently_visited_forms" => "(pref) Recently Visited Forms List?",
133
- "show_tasks" => "(pref) Tasks List?",
134
- "show_task_bubbles" => "(pref) Task Count Bubbles",
135
- "kiosk_enabled" => "Kiosk User?",
136
- "freemium" => "Freemium User?",
137
- "files" => "(able) on Files",
138
- "reports" => "(able) on Report Structures",
139
- "data" => "(able) on Data (hours, datasets)",
140
- "organization" => "(able) on Organization Config",
141
- "pages" => "(able) on Page/Entries",
142
- "page_editor" => "(able) page Editor Level",
143
- "registers" => "(able) on Registers",
144
- "tasks" => "(able) on Tasks",
145
- "person_core" => "(able) on People",
146
- "person_core_create" => "(able) Create People?",
147
- "person_core_edit" => "(able) Edit People?",
148
- "person_details" => "(able) on People Schema Details",
149
- "person_account" => "(able) on Users",
150
- "person_abilities" => "(able) on Users' Abilities",
151
- "custom_files" => "(min) on Files",
152
- "custom_reports" => "(min) on Report Structures",
153
- "custom_data" => "(min) on Data (hours, datasets)",
154
- "custom_organization" => "(min) on Organization Config",
155
- "custom_pages" => "(min) on Page/Entries",
156
- "custom_page_editor" => "(min) page Editor Level",
157
- "custom_registers" => "(min) on Registers",
158
- "custom_tasks" => "(min) on Tasks",
159
- "custom_person_core" => "(min) on People",
160
- "custom_person_core_create" => "(min) Create People?",
161
- "custom_person_core_edit" => "(min) Edit People?",
162
- "custom_person_details" => "(min) on People Schema Details",
163
- "custom_person_account" => "(min) on Users",
164
- "custom_person_abilities" => "(min) on Users' Abilities"
128
+ "landing_page_id" => "Landing Page ID"
165
129
  }
166
130
  end
167
131
 
@@ -75,4 +75,46 @@ class Eco::API::UseCases::DefaultCases::ToCsvDetailedCase < Eco::API::UseCases::
75
75
  ]
76
76
  end
77
77
 
78
+ def nice_header_maps
79
+ @nice_header_maps ||= super.merge({
80
+ "landing_page_id" => "Landing Page ID",
81
+ "show_sidebar" => "(pref) Sidebar Open?",
82
+ "show_shortcuts" => "(pref) Link to Registers?",
83
+ "show_coming_soon" => "(pref) Coming Soon List?",
84
+ "show_recently_visited_forms" => "(pref) Recently Visited Forms List?",
85
+ "show_tasks" => "(pref) Tasks List?",
86
+ "show_task_bubbles" => "(pref) Task Count Bubbles",
87
+ "kiosk_enabled" => "Kiosk User?",
88
+ "freemium" => "Freemium User?",
89
+ "files" => "(able) on Files",
90
+ "reports" => "(able) on Report Structures",
91
+ "data" => "(able) on Data (hours, datasets)",
92
+ "organization" => "(able) on Organization Config",
93
+ "pages" => "(able) on Page/Entries",
94
+ "page_editor" => "(able) page Editor Level",
95
+ "registers" => "(able) on Registers",
96
+ "tasks" => "(able) on Tasks",
97
+ "person_core" => "(able) on People",
98
+ "person_core_create" => "(able) Create People?",
99
+ "person_core_edit" => "(able) Edit People?",
100
+ "person_details" => "(able) on People Schema Details",
101
+ "person_account" => "(able) on Users",
102
+ "person_abilities" => "(able) on Users' Abilities",
103
+ "custom_files" => "(min) on Files",
104
+ "custom_reports" => "(min) on Report Structures",
105
+ "custom_data" => "(min) on Data (hours, datasets)",
106
+ "custom_organization" => "(min) on Organization Config",
107
+ "custom_pages" => "(min) on Page/Entries",
108
+ "custom_page_editor" => "(min) page Editor Level",
109
+ "custom_registers" => "(min) on Registers",
110
+ "custom_tasks" => "(min) on Tasks",
111
+ "custom_person_core" => "(min) on People",
112
+ "custom_person_core_create" => "(min) Create People?",
113
+ "custom_person_core_edit" => "(min) Edit People?",
114
+ "custom_person_details" => "(min) on People Schema Details",
115
+ "custom_person_account" => "(min) on Users",
116
+ "custom_person_abilities" => "(min) on Users' Abilities"
117
+ })
118
+ end
119
+
78
120
  end
@@ -2,13 +2,16 @@ class Eco::API::UseCases::DefaultCases::UpsertCase < Eco::API::Common::Loaders::
2
2
  name "upsert"
3
3
  type :sync
4
4
 
5
+ attr_reader :options
6
+
5
7
  def main(entries, people, session, options, usecase)
8
+ @options = options
6
9
  micro = session.micro
7
10
  creation = session.new_job("main", "create", :create, usecase)
8
11
  update = session.new_job("main", "update", :update, usecase)
9
12
  supers = session.new_job("post", "supers", :update, usecase, :core)
10
13
 
11
- micro.with_each(entries, people, options) do |entry, person|
14
+ micro.with_each(entries, people, options, append_created: append_created) do |entry, person|
12
15
  person.new? ? creation.add(person) : update.add(person)
13
16
  micro.set_core_with_supervisor(entry, person, people, supers, options)
14
17
  entry.set_details(person) unless options.dig(:exclude, :details)
@@ -16,4 +19,10 @@ class Eco::API::UseCases::DefaultCases::UpsertCase < Eco::API::Common::Loaders::
16
19
  end
17
20
  end
18
21
 
22
+ private
23
+
24
+ def append_created
25
+ options.dig(:people, :append_created)
26
+ end
27
+
19
28
  end