eco-helpers 2.0.38 → 2.0.42

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0e84f7c290837d063ed13e63165dadaf272219105227d90b983b9af16d338fe5
4
- data.tar.gz: 38ea16433f7a5689cfdcbde0b3bd4f1065e8adb9e742493c097a87c684b97b86
3
+ metadata.gz: c14b952724b755aa88b633094baf947b8c32b3a8699f77e8a4d63cdc94e10765
4
+ data.tar.gz: 015fd112ec97cb490c1bae82cdbd744256ca8879b98578f4c2442a0730652bf5
5
5
  SHA512:
6
- metadata.gz: cef2930cc5941db9baab1a726fd04fb6186b57d9498cb8112589b2b12e40e53ae061ca2b68f062a197111ba85f47acafcf512f4aa3559e043b924412b23ba038
7
- data.tar.gz: e79992f8ed299014a4c30b62c18773c1741a1961c4777560bbd137a60adc265920a3d35b18085256b42ce6cf467b9d4a950ba06e28adf50770a71aa94b3236ad
6
+ metadata.gz: cbdf02bb1b3323069682c6b9dca370b598d846fc185e8db6dba7e337f1939a41f00b17d60bcb599c4f8abf9c0c6a713495e88258eb5a521b061ffa01c63d552d
7
+ data.tar.gz: b656b2a52dc65a7e2ae582ec68999de0d7551a6a17c5b83a3763ead94d161a8c969dc76add52ec6a93ebbfd68b5b47293c06fe3e33c8cfaacc4ad6273bf5b17f
data/CHANGELOG.md CHANGED
@@ -1,6 +1,71 @@
1
1
  # Change Log
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
+ ## [2.0.42] - 2021-10-30
5
+
6
+ ### Added
7
+ - `eco/api/organization/presets_values.json` added abilities:
8
+ - `visitor_management`
9
+ - `broadcast_notifications`
10
+ - `cross_register_reporting`
11
+ - Due to dev pipeline, the `ecoportal-api` version `0.8.4` hasn't been released
12
+ - This part of the current `eco-helpers` version depends on that gem version (to be upgraded later)
13
+ - Changed the `workflow` in
14
+ - `before(:post_launch, :usecases)` => post launch cases are not prevented for **partial** updates
15
+ - rectified message
16
+ - `run(:post_launch, :usecases)` => missing **people** error will log in `debug` level
17
+ - it won't break the script anymore (just prevent a post use case to be run)
18
+ - New use case `Eco::API::UseCases::DefaultCases::EntriesToCsv`: to export input entries as `csv`
19
+ - invokable via `-entries-to-csv`
20
+ - More errors:
21
+ - `Eco::API::Error::ExternalIdTaken`
22
+ - `Eco::API::Error::InternalServerError`
23
+ - **Added** option `processed-people-to-csv file.csv` to export a `csv` with the results of processing people
24
+ - This option allows to preview the final data when launching a `dry-run` (`-simulate`)
25
+ - **Added** ooze case sample `Eco::API::UseCases::OozeSamples::TargetOozesUpdateCase`
26
+ - Allows to retrieve the target entries based on a `csv`
27
+
28
+ ### Changed
29
+ - Moved methods of `#person_ref`, `#get_attr` and `#get_row` as **class methods** of `Eco::API::Session::Batch::Feedback`
30
+ - `Eco::API::Session::Errors` methods above to use them via `Feedback` class
31
+ - `Eco::API::Session::Errors::ErrorCache`: **added** new property `response`
32
+ - `#by_type` added parameter `only_entries` to specify the output type
33
+ - `#errors` capture the `response` in the generated `ErrorCache` object
34
+
35
+ ### Fixed
36
+ - `Eco::API::Session::Config::Workflow#run` to validate **callback** output class
37
+ - It should be a `Eco::API::UseCases::BaseIO`
38
+ - Prevent **uncreated people** to be present in queues or people refresh (if the server side worked perfectly, this contingency shouldn't be necessary):
39
+ - `Eco::API::Session::Batch::Job#processed_queue`
40
+ - Sanity-check to exclude people that are **new** and do not have `id` when the current `Job` is **not** of type `:create` (meaning that it was supposed to be created but failed and it probably doesn't exist on server-side)
41
+ - This prevents errors when trying to update/delete a person that most probably does not exist on the server.
42
+ - `Eco::API::MicroCases#people_refresh`
43
+ - Remove from people run-time object those that are **new** that are `dirty` (with pending changes)
44
+
45
+ ## [2.0.41] - 2021-10-06
46
+
47
+ ### Fixed
48
+ - `Eco::API::Session::Batch::Job` `backup_update`
49
+ - Saved `requests` filename was overlapping due to only batch job type being used
50
+ - Now it uses the name of the batch job as well
51
+
52
+ ## [2.0.40] - 2021-09-29
53
+
54
+ ### Added
55
+ - Unique access point for `validation` via core case `Eco::API::UseCases::OozeSamples::OozeBaseCase#update_ooze`
56
+
57
+ ## [2.0.39] - 2021-09-28
58
+
59
+ ### Changed
60
+ - `Eco::API::UseCases::OozeSamples::OozeBaseCase`
61
+ - Moved helpers from `Eco::API::UseCases::OozeSamples::OozeUpdateCase`
62
+
63
+ ### Fixed
64
+ - `Eco::API::UseCases::OozeSamples::RegisterUpdateCase`
65
+ - fix launch condition to be `Y`
66
+ - fix `search` method call
67
+ - Changed the `workflow` to prevent re-cache of people when `people` was not used
68
+
4
69
  ## [2.0.38] - 2021-09-07
5
70
 
6
71
  ### Added
@@ -12,8 +77,6 @@ All notable changes to this project will be documented in this file.
12
77
  ### Changed
13
78
  - Changed the `workflow` to prevent re-cache of people when `people` was not used
14
79
 
15
- ### Fixed
16
-
17
80
  ## [2.0.37] - 2021-09-03
18
81
 
19
82
  ### Added
data/eco-helpers.gemspec CHANGED
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
31
31
  spec.add_development_dependency "redcarpet", ">= 3.5.1", "< 3.6"
32
32
 
33
33
  spec.add_dependency 'ecoportal-api', '>= 0.8.3', '< 0.9'
34
- spec.add_dependency 'ecoportal-api-v2', '>= 0.8.13', '< 0.9'
34
+ spec.add_dependency 'ecoportal-api-v2', '>= 0.8.19', '< 0.9'
35
35
  spec.add_dependency 'aws-sdk-s3', '>= 1.83.0', '< 2'
36
36
  spec.add_dependency 'aws-sdk-ses', '>= 1.36.0', '< 2'
37
37
  spec.add_dependency 'dotenv', '>= 2.7.6', '< 2.8'
@@ -166,7 +166,7 @@ module Eco
166
166
  run = true
167
167
  if Eco::API::Common::Session::FileManager.file_exists?(file)
168
168
  prompt_user("Do you want to overwrite it? (Y/n):", explanation: "The file '#{file}' already exists.", default: "Y") do |response|
169
- run = (response == "") || reponse.upcase.start_with?("Y")
169
+ run = (response == "") || response.upcase.start_with?("Y")
170
170
  end
171
171
  end
172
172
 
@@ -1,5 +1,4 @@
1
1
  require "net/sftp"
2
-
3
2
  module Eco
4
3
  module API
5
4
  module Common
data/lib/eco/api/error.rb CHANGED
@@ -19,10 +19,18 @@ module Eco
19
19
  @match = /.*/
20
20
  end
21
21
 
22
+ class InternalServerError < Eco::API::Error
23
+ @str_err = "Internal Server Error"
24
+ @match = /#{@str_err}/
25
+ end
22
26
  class UnknownPersonId < Eco::API::Error
23
27
  @str_err = "Unknown person id"
24
28
  @match = /Cannot find person with id (.*)/
25
29
  end
30
+ class ExternalIdTaken < Eco::API::Error
31
+ @str_err = "external ID already taken"
32
+ @match = /#{@str_err}/
33
+ end
26
34
  class EmailMissing < Eco::API::Error
27
35
  @str_err = "missing email for account creation"
28
36
  @match = /#{@str_err}/
@@ -2,15 +2,22 @@ module Eco
2
2
  module API
3
3
  class MicroCases
4
4
  # Helper to obtain all the elements of `people` anew from the _People Manager_.
5
- # @note this helper is normally used to run consecutive usecases, where data needs refresh.
5
+ # @note
6
+ # 1. This helper is normally used to run consecutive usecases, where data needs refresh.
7
+ # 2. It only includes new people if they are not dirty (they do not have pending updates)
8
+ # - This contingency wouldn't be necessary if the server worked perfectly.
6
9
  # @param people [Eco::API::Organization::People] the people that needs refresh.
7
10
  # @param include_created [Boolean] include people created during this session? (will check `:create` batch jobs).
8
11
  # @return [Eco::API::Organization::People] the `People` object with the data.
9
12
  def people_refresh(people:, include_created: true)
13
+ people = people.newFrom people.select do |person|
14
+ !person.new? || !person.dirty?
15
+ end
10
16
  ini = people.length
11
17
  if include_created
12
18
  session.job_groups.find_jobs(type: :create).map do |job|
13
- people = people.merge(job.people)
19
+ to_add = job.people.select {|person| !person.dirty?}
20
+ people = people.merge(to_add)
14
21
  end
15
22
  end
16
23
 
@@ -12,5 +12,8 @@
12
12
  "person_core_edit": [null, "edit"],
13
13
  "person_details": [null, "view", "edit_public", "view_private", "edit_private"],
14
14
  "person_account": [null, "view", "create", "edit"],
15
- "person_abilities": [null, "view", "edit"]
15
+ "person_abilities": [null, "view", "edit"],
16
+ "visitor_management": [null, "view", "edit", "administrate"],
17
+ "broadcast_notifications": [null, "view", "administrate"],
18
+ "cross_register_reporting": [null, "view"]
16
19
  }
@@ -8,7 +8,7 @@ module Eco
8
8
  # @attr_reader status [Eco::API::Session::Batch::Status] `batch status` this `Errors` object is associated to.
9
9
  attr_reader :status
10
10
 
11
- ErrorCache = Struct.new(:type, :err, :entry)
11
+ ErrorCache = Struct.new(:type, :err, :entry, :response)
12
12
 
13
13
  # @param status [Eco::API::Session::Batch::Status] `batch status` this `Errors` object is associated to.
14
14
  def initialize(status:)
@@ -46,31 +46,52 @@ module Eco
46
46
 
47
47
  # @!group Pure errors helper methods
48
48
 
49
+ # @return [Integer] the number of `entries` that got error.
50
+ def count
51
+ entries.length
52
+ end
53
+
49
54
  # Was there any _Sever_ (reply) **error** as a result of this batch?
50
55
  # @return [Boolean] `true` if any of the queried _entries_ got an unsuccessful `Ecoportal::API::Common::BatchResponse`
51
56
  def any?
52
57
  queue.any? {|query| !status[query].success?}
53
58
  end
54
59
 
55
- # @return [Integer] the number of `entries` that got error.
56
- def count
57
- entries.length
60
+ # Groups `entries` with error `type`
61
+ # @return [Hash] where each `key` is a `type` **error** and each value is an `Array` of:
62
+ # 1. `entries` that got that error, if `only_entries` is `true`
63
+ # 2. `ErrorCache` objects, if `only_entries` is `false`
64
+ def by_type(only_entries: true)
65
+ errors.group_by do |e|
66
+ e.type
67
+ end.transform_values do |arr|
68
+ if only_entries
69
+ arr.map {|e| e.entry}
70
+ else
71
+ arr
72
+ end
73
+ end
58
74
  end
75
+ # @!endgroup
59
76
 
60
- # For all the `entries` with errors generates a `Hash` object
61
- # @return [Array<Hash>] where each `Hash` has
62
- # 1. `:type` -> the error type
63
- # 2. `:err` -> the error `class` of that `:type`
64
- # 3. `:entry` -> the entry that generated the error
77
+ # For all the `entries` with errors generates an `Array` of `ErrorCache` objects
78
+ # @return [Array<Eco::API::Session::Batch::Errors::ErrorCache>] where each `object` has
79
+ # 1. `type` -> the error type `Class`
80
+ # 2. `err` -> an instance object of that error `class` type
81
+ # 3. `entry` -> the entry that generated the error
82
+ # 4. `response` -> the original response from the server that carries the error
65
83
  def errors
66
84
  entries.each_with_object([]) do |entry, arr|
67
- if body = status[entry].body
68
- if errs = body["errors"]
85
+ response = status[entry]
86
+ if body = response.body
87
+ if errs = body["errors"] || body["error"]
88
+ errs = [errs].flatten(1).compact
69
89
  errs.each do |msg|
70
90
  arr.push(ErrorCache.new(
71
91
  klass = Eco::API::Error.get_type(msg),
72
92
  klass.new(err_msg: msg, entry: entry, session: session),
73
- entry
93
+ entry,
94
+ response
74
95
  ))
75
96
  end
76
97
  end
@@ -78,18 +99,6 @@ module Eco
78
99
  end
79
100
  end
80
101
 
81
- # Groups `entries` with error `type`
82
- # @return [Hash] where each `key` is a `type` **error** and each value is
83
- # an `Array` of `entries` that got that error
84
- def by_type
85
- errors.group_by do |e|
86
- e.type
87
- end.transform_values do |arr|
88
- arr.map {|e| e.entry}
89
- end
90
- end
91
- # @!endgroup
92
-
93
102
  # @!group Messaging methods
94
103
 
95
104
  def message
@@ -112,8 +121,7 @@ module Eco
112
121
  # @!endgroup
113
122
 
114
123
  def person_ref(entry)
115
- row_str = (row = get_row(entry)) ? "(row: #{row}) " : nil
116
- "#{row_str}(id: '#{get_attr(entry, :id)}') '#{get_attr(entry, :name)}' ('#{get_attr(entry, :external_id)}': '#{get_attr(entry, :email)}')"
124
+ Eco::API::Session::Batch::Feedback.person_ref(entry)
117
125
  end
118
126
 
119
127
  private
@@ -142,20 +150,11 @@ module Eco
142
150
  end
143
151
 
144
152
  def get_attr(entry, attr)
145
- if entry.respond_to?(attr.to_sym)
146
- entry.public_send(attr.to_sym)
147
- elsif entry.is_a?(Hash)
148
- entry["#{attr}"]
149
- end
153
+ Eco::API::Session::Batch::Feedback.get_attr(entry, attr)
150
154
  end
151
155
 
152
156
  def get_row(value)
153
- case value
154
- when Eco::API::Common::People::PersonEntry
155
- value.idx
156
- when Ecoportal::API::V1::Person
157
- get_row(value.entry)
158
- end
157
+ Eco::API::Session::Batch::Feedback.get_row(value)
159
158
  end
160
159
 
161
160
  # Sorts the entries that got server error by error `type` and generates the error messages.
@@ -5,6 +5,30 @@ module Eco
5
5
  # @attr_reader job [Eco::API::Session::Batch::Job] `batch job` the feedback is associated with
6
6
  class Feedback
7
7
 
8
+ class << self
9
+ def person_ref(entry)
10
+ row_str = (row = get_row(entry)) ? "(row: #{row}) " : nil
11
+ "#{row_str}(id: '#{get_attr(entry, :id)}') '#{get_attr(entry, :name)}' ('#{get_attr(entry, :external_id)}': '#{get_attr(entry, :email)}')"
12
+ end
13
+
14
+ def get_attr(entry, attr)
15
+ if entry.respond_to?(attr.to_sym)
16
+ entry.public_send(attr.to_sym)
17
+ elsif entry.is_a?(Hash)
18
+ entry["#{attr}"]
19
+ end
20
+ end
21
+
22
+ def get_row(value)
23
+ case value
24
+ when Eco::API::Common::People::PersonEntry
25
+ value.idx
26
+ when Ecoportal::API::V1::Person
27
+ get_row(value.entry)
28
+ end
29
+ end
30
+ end
31
+
8
32
  attr_reader :job
9
33
 
10
34
  # @param job [Eco::API::Session::Batch::Job] `batch job` the feedback is associated with
@@ -235,9 +235,23 @@ module Eco
235
235
  end
236
236
  end
237
237
 
238
+ # Method to generate the base of people that will be present in the queue
239
+ # @note
240
+ # - If the entry is a new person, we are not in a creation job and the person doesn't have `id`
241
+ # it means that it failed to be created (it doesn't exist on server-side).
242
+ # The entry won't be included.
243
+ # - The contingency above wouldn't be necessary if the server worked perfectly.
238
244
  def processed_queue
239
- @queue.each {|e| @callbacks[e].call(e) if @callbacks.key?(e) }
240
- apply_policies(api_included(@queue)).select do |e|
245
+ pre_filtered = @queue.select do |entry|
246
+ if unexisting = entry.new? && !entry.id && type != :create
247
+ ref = Eco::API::Session::Batch::Feedback.person_ref(entry)
248
+ msg = "Job ('#{name}':#{type}): excluded unexisting entry (failed creation): #{ref}"
249
+ session.logger.warn(msg)
250
+ end
251
+ !unexisting
252
+ end
253
+ pre_filtered.each {|e| @callbacks[e].call(e) if @callbacks.key?(e) }
254
+ apply_policies(api_included(pre_filtered)).select do |e|
241
255
  !as_update(e).empty?
242
256
  end.select do |e|
243
257
  next true unless e.is_a?(Ecoportal::API::V1::Person)
@@ -343,7 +357,8 @@ module Eco
343
357
  def backup_update(requests, simulate: false)
344
358
  dry_run = simulate ? "_dry_run" : ""
345
359
  dir = config.people.requests_folder
346
- file = File.join(dir, "#{type}_data#{dry_run}.json")
360
+ filename = name.split(" ").join("-").gsub(/[=\\\/><,"-]+/,"_")
361
+ file = File.join(dir, "#{type}_data_#{filename}#{dry_run}.json")
347
362
  file_manager.save_json(requests, file, :timestamp)
348
363
  end
349
364
 
@@ -185,6 +185,7 @@ module Eco
185
185
  # - it will **not** run the `callback` for `on` defined during the configuration time
186
186
  # - it will rather `yield` the target stage after all the `before` _callbacks_ have been run
187
187
  # - aside of this, the rest will be the same as when the _block_ is provided (see previous note)
188
+ # @raise [ArgumentError] if the object returned by `before` and `after` callbacks is not an `Eco::API::UseCases::BaseIO`.
188
189
  # @param key [Symbol, nil] cases:
189
190
  # - if `key` is not provided, it targets the _current stage_
190
191
  # - if `key` is provided, it targets the specific _sub-stage_
@@ -200,7 +201,16 @@ module Eco
200
201
  if key
201
202
  io = stage(key).run(io: io, &block)
202
203
  elsif pending?
203
- @before.each {|c| io = c.call(self, io)}
204
+ @before.each do |c|
205
+ io = c.call(self, io).tap do |i_o|
206
+ unless i_o.is_a?(Eco::API::UseCases::BaseIO)
207
+ msg = "Workflow callaback before('#{name}') should return Eco::API::UseCases::BaseIO object."
208
+ msg += " Given #{i_o.class}"
209
+ msg += " • Callback source location: '#{c.source_location}'"
210
+ raise ArgumentError.new(msg)
211
+ end
212
+ end
213
+ end
204
214
 
205
215
  unless skip?
206
216
  io.session.logger.debug("(Workflow: #{path}) running now")
@@ -218,7 +228,16 @@ module Eco
218
228
  @pending = false
219
229
  end
220
230
 
221
- @after.each {|c| io = c.call(self, io)}
231
+ @after.each do |c|
232
+ io = c.call(self, io).tap do |i_o|
233
+ unless i_o.is_a?(Eco::API::UseCases::BaseIO)
234
+ msg = "Workflow callaback after('#{name}') should return Eco::API::UseCases::BaseIO object."
235
+ msg += " Given #{i_o.class}"
236
+ msg += " • Callback source location: '#{c.source_location}'"
237
+ raise ArgumentError.new(msg)
238
+ end
239
+ end
240
+ end
222
241
  end
223
242
  rescue SystemExit
224
243
  exit
@@ -0,0 +1,18 @@
1
+ class Eco::API::UseCases::DefaultCases::EntriesToCsv < Eco::API::Common::Loaders::UseCase
2
+ name "entries-to-csv"
3
+ type :import
4
+
5
+ attr_reader :session, :options
6
+
7
+ def main(entries, session, options, usecase)
8
+ @options = options
9
+ @session = session
10
+ entries.export(filename)
11
+ end
12
+
13
+ private
14
+
15
+ def filename
16
+ options.dig(:export, :file) || "entries.csv"
17
+ end
18
+ end
@@ -24,6 +24,7 @@ require_relative 'default_cases/email_as_id_case'
24
24
  require_relative 'default_cases/hris_case'
25
25
  require_relative 'default_cases/new_id_case'
26
26
  require_relative 'default_cases/new_email_case'
27
+ require_relative 'default_cases/entries_to_csv_case'
27
28
  require_relative 'default_cases/org_data_convert_case'
28
29
  require_relative 'default_cases/refresh_case'
29
30
  require_relative 'default_cases/reinvite_trans_case'
@@ -26,6 +26,48 @@ class Eco::API::UseCases::OozeSamples::OozeBaseCase < Eco::API::Common::Loaders:
26
26
  update_ooze(ooze)
27
27
  end
28
28
 
29
+ protected
30
+
31
+ def add_field(name, type, section, after: nil, before: nil, side: :left)
32
+ unless section.is_a?(Ecoportal::API::V2::Page::Section)
33
+ raise "You need to specify a section for a new field. Given: #{section.class}"
34
+ end
35
+ target.components.add(label: name, type: type) do |field|
36
+ section.add_component(field, after: after, before: before, side: side)
37
+ end.tap do |field|
38
+ yield(field) if block_given?
39
+ end
40
+ end
41
+
42
+ def with_fields(type: nil, label: nil)
43
+ flds = target.components
44
+ flds = flds.get_by_type(type) if type
45
+ flds = flds.select do |fld|
46
+ value = (label == :unnamed) ? nil : label
47
+ !label || same_string?(fld.label, value)
48
+ end.each do |field|
49
+ yield(field) if block_given?
50
+ end
51
+ end
52
+
53
+ def with_sections(type: nil, heading: nil)
54
+ secs = target.sections
55
+ secs = secs.get_by_type(type) if type
56
+ secs = secs.select do |sec|
57
+ value = (heading == :unnamed) ? nil : heading
58
+ !heading || same_string?(sec.heading, value)
59
+ end.each do |sec|
60
+ yield(sec) if block_given?
61
+ end
62
+ end
63
+
64
+ def with_stage(name:)
65
+ if stage = target.stages.get_by_name(name)
66
+ yield(stage) if block_given?
67
+ end
68
+ stage
69
+ end
70
+
29
71
  private
30
72
 
31
73
  # Hook method to use before the target is switched
@@ -70,6 +112,11 @@ class Eco::API::UseCases::OozeSamples::OozeBaseCase < Eco::API::Common::Loaders:
70
112
  def update_ooze(ooze = target)
71
113
  if !options[:simulate]
72
114
  return unless dirty?(ooze)
115
+
116
+ ooze.validate.tap do |validation|
117
+ raise validation if validation.is_a?(String)
118
+ end
119
+
73
120
  apiv2.pages.update(ooze).tap do |response|
74
121
  if response.success?
75
122
  ooze.consolidate!
@@ -4,44 +4,6 @@ class Eco::API::UseCases::OozeSamples::OozeUpdateCase < Eco::API::UseCases::Ooze
4
4
 
5
5
  private
6
6
 
7
- def with_fields(type: nil, label: nil)
8
- flds = target.components
9
- flds = flds.get_by_type(type) if type
10
- flds = flds.select do |fld|
11
- value = (label == :unnamed) ? nil : label
12
- !label || same_string?(fld.label, value)
13
- end.each do |field|
14
- yield(field) if block_given?
15
- end
16
- end
17
-
18
- def with_sections(type: nil, heading: nil)
19
- secs = target.sections
20
- secs = secs.get_by_type(type) if type
21
- secs = secs.select do |sec|
22
- value = (heading == :unnamed) ? nil : heading
23
- !heading || same_string?(sec.heading, value)
24
- end.each do |sec|
25
- yield(sec) if block_given?
26
- end
27
- end
28
-
29
- def with_stage(name:)
30
- if stage = target.stages.get_by_name(name)
31
- yield(stage) if block_given?
32
- end
33
- stage
34
- end
35
-
36
- def add_field(name, type, section, after: nil, side: :left)
37
- raise "You need to specify a section for a new field. Given: #{section.class}" unless section.is_a?(Ecoportal::API::V2::Page::Section)
38
- target.components.add(label: name, type: type) do |field|
39
- section.add_component(field, after: after, side: side)
40
- end.tap do |field|
41
- yield(field) if block_given?
42
- end
43
- end
44
-
45
7
  def to_field(value)
46
8
  fld = nil
47
9
  fld ||= value if value.is_a?(Ecoportal::API::V2::Page::Component)
@@ -50,5 +12,4 @@ class Eco::API::UseCases::OozeSamples::OozeUpdateCase < Eco::API::UseCases::Ooze
50
12
  #fld ||= value.reference if value.is_a?(Ecoportal::API::V2::Page::Force::Binding)
51
13
  end
52
14
 
53
-
54
15
  end
@@ -129,7 +129,7 @@ class Eco::API::UseCases::OozeSamples::RegisterUpdateCase < Eco::API::UseCases::
129
129
  apiv2.registers.search(register_id, search_options.merge(only_first: true)).tap do |search_results|
130
130
  str_results = "Total target entries: #{search_results.total} (out of #{search_results.total_before_filtering})"
131
131
  session.prompt_user("Do you want to proceed (y/N):", explanation: str_results, default: "N", timeout: 10) do |res|
132
- if res.upcase.start_with?("N")
132
+ unless res.upcase.start_with?("Y")
133
133
  puts "..."
134
134
  logger.info "Aborting script..."
135
135
  exit(0)
@@ -142,7 +142,7 @@ class Eco::API::UseCases::OozeSamples::RegisterUpdateCase < Eco::API::UseCases::
142
142
  @search_options ||= {}.tap do |opts|
143
143
  opts.merge!(sort: "created_at")
144
144
  opts.merge!(dir: "asc")
145
- opts.merge!(query: conf_filters) if conf_search
145
+ opts.merge!(query: conf_search) if conf_search
146
146
  opts.merge!(filters: conf_filters)
147
147
  end
148
148
  end
@@ -0,0 +1,64 @@
1
+ # Use case to update a target oozes
2
+ # @note
3
+ # - `target_ids` => Expects options[:source][:file] where at least the 1st column should be the target entry `ids`
4
+ class Eco::API::UseCases::OozeSamples::TargetOozesUpdateCase < Eco::API::UseCases::OozeSamples::RegisterUpdateCase
5
+ name "target-oozes-update-case"
6
+ type :other
7
+
8
+ private
9
+
10
+ def with_each_entry
11
+ batched_target_ids do |ids|
12
+ ids.each do |id|
13
+ if pending = queue_shift(id)
14
+ if dirty?(pending)
15
+ msg = "Same entry 'id' appears more than once. "
16
+ msg << "Launching update on '#{object_reference(pending)}' to be able to queue it back"
17
+ console.warn msg
18
+ update_ooze(pending)
19
+ end
20
+ end
21
+ if ooz = ooze(id)
22
+ yield(ooz)
23
+ end
24
+ end
25
+ update_oozes
26
+ end
27
+ end
28
+
29
+ def batched_target_ids
30
+ raise "Missing block. It yields in slices of #{self.class.batch_size} ids" unless block_given?
31
+ target_ids_preview
32
+ pool = []
33
+ target_ids.each do |id|
34
+ pool << id
35
+ if pool.length >= self.class.batch_size
36
+ yield(pool)
37
+ pool = []
38
+ end
39
+ end
40
+ yield(pool) unless pool.empty?
41
+ end
42
+
43
+ def target_ids_preview
44
+ dups = target_ids.select {|id| target_ids.count(id) > 1}
45
+ dups_str = dups.count > 0 ? "There are #{dups.count} duplicated ids" : "No duplicates detected"
46
+ msg = "Total target entries: #{target_ids.count} (#{dups_str})"
47
+ session.prompt_user("Do you want to proceed (y/N):", explanation: msg, default: "N", timeout: 10) do |res|
48
+ unless res.upcase.start_with?("Y")
49
+ puts "..."
50
+ logger.info "Aborting script..."
51
+ exit(0)
52
+ end
53
+ end
54
+ end
55
+
56
+ def target_ids
57
+ @target_ids ||= input_csv.columns.first[1..-1]
58
+ end
59
+
60
+ def input_csv
61
+ @input_csv ||= Eco::CSV.read(options.dig(:source, :file))
62
+ end
63
+
64
+ end
@@ -14,3 +14,4 @@ require_relative 'ooze_samples/ooze_run_base_case'
14
14
  require_relative 'ooze_samples/ooze_update_case'
15
15
  require_relative 'ooze_samples/ooze_from_doc_case'
16
16
  require_relative 'ooze_samples/register_update_case'
17
+ require_relative 'ooze_samples/target_oozes_update_case'
@@ -96,6 +96,13 @@ ASSETS.cli.config do |cnf|
96
96
  })
97
97
  end
98
98
 
99
+ desc = "Used to export to a csv the final people (after processing). "
100
+ desc += "It is useful analyse the data after a -dry-run (-simulate)."
101
+ options_set.add("-processed-people-to-csv", desc) do |options, session|
102
+ file = SCR.get_file("-processed-people-to-csv", required: true, should_exist: false)
103
+ options.deep_merge!(report: {people: {csv: file}})
104
+ end
105
+
99
106
  desc = "Runs in dry-run (no requests sent to server)"
100
107
  options_set.add(["-dry-run", "-simulate"], desc) do |options, session|
101
108
  options[:dry_run] = true
@@ -137,6 +137,13 @@ ASSETS.cli.config do |cnf|
137
137
  end
138
138
  end
139
139
 
140
+ desc = "Input file dump into a CSV as is."
141
+ cases.add("-entries-to-csv", :import, desc, case_name: "entries-to-csv")
142
+ .add_option("-out") do |options|
143
+ file = SCR.get_file("-out")
144
+ options.deep_merge(export: {file: file})
145
+ end
146
+
140
147
  desc = "Usage '-org-data-convert backup.json -restore-db-from'."
141
148
  desc += " Transforms an input .json file to the values of the destination environment "
142
149
  desc += " (names missmatch won't solve: i.e. usergroups)"
@@ -196,7 +203,7 @@ ASSETS.cli.config do |cnf|
196
203
  .add_option("-append-starters", as1) do |options|
197
204
  options.deep_merge!(people: {append_created: true})
198
205
  end
199
-
206
+
200
207
  desc = "Creates people with only details"
201
208
  cases.add("-create-details-from", :sync, desc, case_name: "create-details")
202
209
  .add_option("-append-starters", as1) do |options|
@@ -101,19 +101,26 @@ ASSETS.cli.config do |config|
101
101
  get_people = io.options.dig(:people, :get)
102
102
  partial_update = get_people && get_people.dig(:type) == :partial
103
103
  run_it = !io.options[:dry_run] || io.options.dig(:post_launch, :run)
104
- if run_it && partial_update
105
- unless io.options[:dry_run]
104
+ refresh_data = !io.options[:dry_run] && partial_update
105
+ if run_it
106
+ if refresh_data
106
107
  # get target people afresh
107
108
  people = io.session.micro.people_refresh(people: io.people, include_created: true)
108
109
  io = io.base.new(people: people)
110
+ else
111
+ msg = "Although there are post_launch cases, data will not be refreshed before their run"
112
+ if io.options[:dry_run]
113
+ msg += ", because we are in dry-run (simulate)."
114
+ elsif !partial_update
115
+ msg += ", because it is not a partial update (-get-partial option not present)."
116
+ end
117
+ io.session.logger.warn(msg)
109
118
  end
110
119
  else
111
120
  wf_post.skip!
112
121
  msg = "Although there are post_launch cases, they will NOT be RUN"
113
122
  if io.options[:dry_run]
114
123
  msg+= ", because we are in dry-run (simulate)."
115
- elsif !partial_update
116
- msg+= ", because it is not a partial update (-get-partial)"
117
124
  end
118
125
  io.session.logger.info(msg)
119
126
  end
@@ -125,7 +132,15 @@ ASSETS.cli.config do |config|
125
132
 
126
133
  wf_post.on(:usecases) do |wf_postcases, io|
127
134
  io.session.post_launch.each do |use|
128
- io = use.launch(io: io).base
135
+ begin
136
+ io = use.launch(io: io).base
137
+ rescue Eco::API::UseCases::BaseIO::MissingParameter => e
138
+ if e.required == :people
139
+ io.session.logger.debug("Skipping use case '#{use.name}' -- no base people detected for the current run")
140
+ else
141
+ raise
142
+ end
143
+ end
129
144
  end
130
145
  io
131
146
  end
@@ -137,8 +152,13 @@ ASSETS.cli.config do |config|
137
152
  end
138
153
 
139
154
  wf.on(:report) do |wf_report, io|
140
- #config.reports.active(io: io)
141
- #io.session.reports
155
+ if file = io.options.dig(:report, :people, :csv)
156
+ io.options.deep_merge!(export: {
157
+ options: {internal_names: true, nice_header: true, split_schemas: true},
158
+ file: {name: file, format: :csv}
159
+ })
160
+ io = io.session.process_case("to-csv", io: io, type: :export)
161
+ end
142
162
  io
143
163
  end
144
164
 
data/lib/eco/csv/table.rb CHANGED
@@ -15,6 +15,7 @@ module Eco
15
15
  end
16
16
  end
17
17
 
18
+ # It allows to rename the header names
18
19
  # @return [Eco::CSV::Table]
19
20
  def transform_headers
20
21
  header = self.headers
@@ -25,6 +26,8 @@ module Eco
25
26
  columns_to_table(cols)
26
27
  end
27
28
 
29
+ # When there are headers with the same name, it merges those columns
30
+ # @note it also offers a way to resolve merge conflicts
28
31
  # @return [Eco::CSV::Table]
29
32
  def merge_same_header_names
30
33
  dups = self.duplicated_header_names
data/lib/eco/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Eco
2
- VERSION = "2.0.38"
2
+ VERSION = "2.0.42"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eco-helpers
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.38
4
+ version: 2.0.42
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oscar Segura
@@ -136,7 +136,7 @@ dependencies:
136
136
  requirements:
137
137
  - - ">="
138
138
  - !ruby/object:Gem::Version
139
- version: 0.8.13
139
+ version: 0.8.19
140
140
  - - "<"
141
141
  - !ruby/object:Gem::Version
142
142
  version: '0.9'
@@ -146,7 +146,7 @@ dependencies:
146
146
  requirements:
147
147
  - - ">="
148
148
  - !ruby/object:Gem::Version
149
- version: 0.8.13
149
+ version: 0.8.19
150
150
  - - "<"
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0.9'
@@ -533,6 +533,7 @@ files:
533
533
  - lib/eco/api/usecases/default_cases/delete_sync_case.rb
534
534
  - lib/eco/api/usecases/default_cases/delete_trans_case.rb
535
535
  - lib/eco/api/usecases/default_cases/email_as_id_case.rb
536
+ - lib/eco/api/usecases/default_cases/entries_to_csv_case.rb
536
537
  - lib/eco/api/usecases/default_cases/hris_case.rb
537
538
  - lib/eco/api/usecases/default_cases/new_email_case.rb
538
539
  - lib/eco/api/usecases/default_cases/new_id_case.rb
@@ -564,6 +565,7 @@ files:
564
565
  - lib/eco/api/usecases/ooze_samples/ooze_run_base_case.rb
565
566
  - lib/eco/api/usecases/ooze_samples/ooze_update_case.rb
566
567
  - lib/eco/api/usecases/ooze_samples/register_update_case.rb
568
+ - lib/eco/api/usecases/ooze_samples/target_oozes_update_case.rb
567
569
  - lib/eco/api/usecases/use_case.rb
568
570
  - lib/eco/api/usecases/use_case_chain.rb
569
571
  - lib/eco/api/usecases/use_case_io.rb