eco-helpers 2.0.9 → 2.0.14

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: 75a468069bd29d7dc25347e6da7d4d9faebc52043eba8b4ea1e91f6d383a8690
4
- data.tar.gz: dee338f8e23d4608f0d359bd44712377d15723c70730e823c11766f179f4877e
3
+ metadata.gz: 697d71754e809691a39f62a86d5fc46e2988578c19c965945e1c06ea73b290b6
4
+ data.tar.gz: 01ef5ca1a9bcf941d44b5f7088f54dd9c2cba950cc562ed0516400811df60f12
5
5
  SHA512:
6
- metadata.gz: 36c25c8a37c8fe894c57309e07126251e658846881698d4eec1660bf2a1a6cdc2e09f6b3f94c28434e47e7ea1f70cbf69196d2965d0a45609492867b2b356478
7
- data.tar.gz: 98bdbf74599ab4a3ab98ac6c76d068bbcf7871774e3f7315f992dbcb9cc31066ac7d2293b8cbee1bc3019bf94e1b9f78c7fdf02b8751cafb403451be12c8c159
6
+ metadata.gz: b24db6ddf741e3f0dcc3f080dba19132d7926c85cf211ae0f98c090c7a3cd93f513b6e977ac21ca24d5c2092d524cc1e7ef3d04250bb29ae672400623c823964
7
+ data.tar.gz: 9585e95676aab71322af2f174d06aed7d6226502bed1e2560cfd0915643e682c02fb857c33310f7c5f1b6d083b83267d14194f0f1e315c940048ef1c3c43faff
data/CHANGELOG.md CHANGED
@@ -1,32 +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.9] - 2021-03-xx
4
+ ## [2.0.14] - 2021-03-xx
5
5
 
6
6
  ### Added
7
+ - `Eco::API::UseCases::DefaultCases::ToCsvCase` added option `-internal-names` to avoid overriding data on export
8
+ - `Eco::API::Common::People::PersonEntry#mapped_entry` exposed method for raw `csv` generation
9
+ - `Eco::API::Organization::PresetsFactory` added integrity validation for `person_*` abilities
10
+ - `Eco::API::Session::Batch::Job` more debug info on erron handlers
11
+
7
12
  ### Changed
8
- - `Eco::API::Session::Batch:Errors#person_ref` moved to the public method
13
+ ### Fixed
14
+ - `Eco::API::Error.get_type` was almost always matching `Eco::API::Error::Unclassified` -> fixed
15
+
16
+ ## [2.0.13] - 2021-03-31
17
+
18
+ ### Added
19
+ - Stats on the `Eco::API::Session::Batch`
20
+ - Allow to inherit and re-use the `Eco::API::UseCases::DefaultCase::HrisCase`
9
21
 
10
22
  ### Fixed
23
+ - Ensure auto-loading for `Eco::API::UseCases`
11
24
 
12
- ## [2.0.8] - 2021-03-09
25
+ ## [2.0.12] - 2021-03-29
26
+
27
+ ### Changed
28
+ - `Eco::CLI#run` it does include any defined states on the workflow
29
+
30
+
31
+ ## [2.0.11] - 2021-03-29
32
+
33
+ ### Fixed
34
+ - `Eco::API::Session::Batch:Errors#errors` changed `Array#filter` call to `Array#select` call
35
+
36
+ ## [2.0.10] - 2021-03-26
13
37
 
14
38
  ### Added
39
+ - `Eco::API::Common::People::PersonParser`
40
+ - `#defined_attrs`: list of all attribute defined parsers (regardless they belong to the model)
41
+ - `Eco::API::Organization::TagTree` methods
42
+ - `#total_depth` to know the total depth of a tree
43
+ - `#flat?` to know if the tagtree has only 1 level
44
+
15
45
  ### Changed
46
+ - `Eco::API::Common::People::PersonParser`
47
+ - Renamed `#all_attrs` to `#all_model_attrs`
48
+ - Ranamed `#defined_attrs` to `#defined_model_attrs`
49
+ - Ranamed `#undefined_attrs` to `#undefined_model_attrs`
50
+
51
+ ## [2.0.9] - 2021-03-19
52
+
53
+ ### Changed
54
+ - `Eco::API::Session::Batch:Errors#person_ref` moved to the public method
55
+
56
+ ## [2.0.8] - 2021-03-09
57
+
16
58
  ### Fixed
17
59
  - `Ecoportal::API::V1::Person#identity` adjust behavior
18
60
 
19
61
  ## [2.0.7] - 2021-03-09
20
62
 
21
- ### Added
22
- ### Changed
23
63
  ### Fixed
24
64
  - `Eco::API::Session::Batch::JobsGroups` and `Eco::API::Session::Batch::Jobs`: when new `Batch::Job`s are creating during launch, they remained unlaunched
25
65
  - this fix makes `#launch` method to iterate until there are no pending
26
66
 
27
67
  ## [2.0.6] - 2021-03-08
28
68
 
29
- ### Added
30
69
  ### Changed
31
70
  - `Eco::API::Session::Batch:Errors` moved some methods to be private
32
71
  ### Fixed
@@ -34,46 +73,33 @@ All notable changes to this project will be documented in this file.
34
73
 
35
74
  ## [2.0.5] - 2021-02-24
36
75
 
37
- ### Added
38
- ### Changed
39
76
  ### Fixed
40
77
  - `Eco::API::Common::People::PersonParser#symbol_keys` to use `Array#select`
41
78
  - as `Array#filter` was introduced in ruby `2.5.5`
42
79
 
43
80
  ## [2.0.4] - 2021-02-23
44
81
 
45
- ### Added
46
82
  ### Changed
47
83
  - `Eco::API::Common::People::PersonParser#defined_attrs` to include virtual attributes
48
84
 
49
- ### Fixed
50
-
51
85
  ## [2.0.3] - 2021-02-23
52
86
 
53
87
  ### Added
54
88
  - `Eco::API::UseCases::OozeSamples::OozeUpdateCase`: added integration to update page instances (non-templates)
55
89
 
56
- ### Changed
57
90
  ### Fixed
58
91
  - `Eco::API::Policies::DefaultPolicies::UserAccess` complete default policy code.
59
92
 
60
93
  ## [2.0.2] - 2021-02-22
61
94
 
62
- ### Added
63
95
  ### Changed
64
96
  - upgraded dependencies with `ecoportal-api`
65
97
 
66
- ### Fixed
67
-
68
-
69
98
  ## [2.0.1] - 2021-02-22
70
99
 
71
- ### Added
72
100
  ### Changed
73
101
  - upgraded dependencies with `ecoportal-api-oozes` to `ecoportal-api-v2`
74
102
 
75
- ### Fixed
76
-
77
103
  ## [1.5.15] - 2021-02-17
78
104
 
79
105
  ### Added
@@ -87,7 +113,6 @@ All notable changes to this project will be documented in this file.
87
113
  - `Eco::API::MicroCases#people_search`
88
114
  - `Eco::API::MicroCases#refresh`
89
115
 
90
- ### Changed
91
116
  ### Fixed
92
117
  - `Eco::API::Policies::DefaultPolicies::UserAccess` typos in default api policy
93
118
 
@@ -109,11 +134,8 @@ All notable changes to this project will be documented in this file.
109
134
  - `Eco::API::Common::People::PersonEntry` add error log when wrong email error is detected
110
135
  - previously it would have crashed
111
136
 
112
- ### Fixed
113
-
114
137
  ## [1.5.13] - 2021-02-01
115
138
 
116
- ### Added
117
139
  ### Changed
118
140
  - upgraded dependency with `ecoportal-api-oozes`
119
141
 
@@ -129,23 +151,16 @@ All notable changes to this project will be documented in this file.
129
151
  ### Changed
130
152
  - upgraded `ecoportal-api` dependency
131
153
 
132
- ### Fixed
133
-
134
-
135
154
  ## [1.5.11] - 2021-01-25
136
155
 
137
156
  ### Added
138
157
  - `Eco::API::Organization::TagTree#subtag?` to check if the tag is in any subtree.
139
158
 
140
- ### Changed
141
-
142
159
  ### Fixed
143
160
  - `Eco::API::MicroCases#set_supervisor` shouldn't set it if the entry does not have it.
144
161
 
145
162
  ## [1.5.10] - 2021-01-19
146
163
 
147
- ### Added
148
- ### Changed
149
164
  ### Fixed
150
165
  - `Eco::API::Session::Batch::Errors#print` show the row number of the input data.
151
166
 
@@ -154,14 +169,8 @@ All notable changes to this project will be documented in this file.
154
169
  ### Added
155
170
  - `Eco::API::Organization::TagTree#subtags` to get all the tags but those of the highest level.
156
171
 
157
- ### Changed
158
- ### Fixed
159
-
160
-
161
172
  ## [1.5.8] - 2021-01-05
162
173
 
163
- ### Added
164
- ### Changed
165
174
  ### Fixed
166
175
  - `Eco::API::Session::Batch::Jobs#job` shouldn't be calling the post-launch callback function on creation.
167
176
  - `Eco::API::Session#new_job` should include a `&block` parameter.
@@ -169,15 +178,11 @@ All notable changes to this project will be documented in this file.
169
178
 
170
179
  ## [1.5.7] - 2020-12-17
171
180
 
172
- ### Added
173
- ### Changed
174
181
  ### Fixed
175
182
  - `Eco::API::Sesssion#parse_attribute` was not using phase argument
176
183
 
177
184
  ## [1.5.6] - 2020-12-04
178
185
 
179
- ### Added
180
- ### Changed
181
186
  ### Fixed
182
187
  - `Eco::API::UseCases::DefaultCases::RestoreDBCase` fixed typo and slightly improved
183
188
  - fixed some back-end errors when chaining usecases
@@ -185,8 +190,6 @@ All notable changes to this project will be documented in this file.
185
190
 
186
191
  ## [1.5.5] - 2020-12-03
187
192
 
188
- ### Added
189
- ### Changed
190
193
  ### Fixed
191
194
  - rubies previous to `2.5` do not have `yield_self`
192
195
 
@@ -194,14 +197,11 @@ All notable changes to this project will be documented in this file.
194
197
 
195
198
  ### Added
196
199
  - update `ecoportal-api` dependency
197
- ### Changed
198
200
  ### Fixed
199
201
  - `Eco::API::MicroCases#people_refresh` typo
200
202
 
201
203
  ## [1.5.3] - 2020-11-30
202
204
 
203
- ### Added
204
- ### Changed
205
205
  ### Fixed
206
206
  - `Eco::API::Session::Batch::RequestStats#blanked_value?` better blank detection
207
207
  - `Eco::API::MicroCases#with_each_starter` rectified typo
@@ -342,14 +342,11 @@ All notable changes to this project will be documented in this file.
342
342
 
343
343
  ## [1.4.2] - 2020-07-23
344
344
 
345
- ### Added
346
- ### Changed
347
345
  ### Fixed
348
346
  - preserve backtrace on logging
349
347
 
350
348
  ## [1.4.0] - 2020-07-14
351
349
 
352
- ### Added
353
350
  ### Changed
354
351
  - change abilities to align with ecoPortal release `1.5.0`
355
352
  - remove some patches on `ecoportal-api`
@@ -359,22 +356,17 @@ All notable changes to this project will be documented in this file.
359
356
 
360
357
  ## [1.3.19] - 2020-07-23
361
358
 
362
- ### Added
363
- ### Changed
364
359
  ### Fixed
365
360
  - preserve backtrace on logging
366
361
 
367
362
  ## [1.3.18] - 2020-07-08
368
363
 
369
- ### Added
370
- ### Changed
371
364
  ### Fixed
372
365
  - the `update` case was missing the code to use the `default_usergroup`
373
366
 
374
367
 
375
368
  ## [1.3.17] - 2020-07-06
376
369
 
377
- ### Added
378
370
  ### Changed
379
371
  - the `hris` case should not only include as `leavers` those that have account, but anyone that leaves
380
372
  * as we could have active people with no account
@@ -397,7 +389,6 @@ All notable changes to this project will be documented in this file.
397
389
  ### Added
398
390
  - default usecase to export to `csv` (`-detailed`) now includes `"Supervisor Name"` column
399
391
  ### Changed
400
- ### Fixed
401
392
 
402
393
  ## [1.3.14] - 2020-06-10
403
394
 
@@ -405,33 +396,24 @@ All notable changes to this project will be documented in this file.
405
396
  - `Eco::API::Common::People::SupervisorHelpers` now has its methods as class methods
406
397
  ### Changed
407
398
  - upgraded `ecoportal-api` gem dependency to minimum version `0.5.6`
408
- ### Fixed
409
399
 
410
400
 
411
401
  ## [1.3.13] - 2020-05-29
412
402
 
413
- ### Added
414
- ### Changed
415
403
  ### Fixed
416
404
  - `Eco::API::Organization::TagTree#tag?` to accept `nil` by returning `false`
417
405
  - `Eco::API::Common::People::DefaultParsers::DateParser` will parse to `Date` class
418
406
  * it was parsing to `Time` class, while the native gem `ecoportal-api` parses as `Date` ([reference](https://gitlab.com/ecoPortal/ecoportal-api/-/blob/master/lib/ecoportal/api/v1/schema_field.rb))
419
407
  ## [1.3.12] - 2020-05-19
420
408
 
421
- ### Added
422
409
  ### Changed
423
410
  - stop using `email` as `external_id` on `People#person` & `People#find`
424
411
  * this should result in more accurate searches when using `:strict` options
425
- ### Fixed
426
-
427
412
 
428
413
  ## [1.3.11] - 2020-05-12
429
414
 
430
- ### Added
431
415
  ### Changed
432
416
  - remove popping up comments on `Eco::API::Organization::PolicyGroups#`
433
- ### Fixed
434
-
435
417
 
436
418
  ## [1.3.10] - 2020-05-12
437
419
 
@@ -440,14 +422,11 @@ All notable changes to this project will be documented in this file.
440
422
  - `config.people.default_usergroup`, when defined, will have effect on usecases: `update` (this case was missing the change)
441
423
  * on account creation, if the input file did not specify `policy_group_ids`
442
424
 
443
- ### Changed
444
425
  ### Fixed
445
426
  - `upsert`, `hris` and `create` usecases: fixed condition for use of default_usergroup
446
427
 
447
428
  ## [1.3.9] - 2020-05-12
448
429
 
449
- ### Added
450
- ### Changed
451
430
  ### Fixed
452
431
 
453
432
  - `usecase` callback was not receiving `usecase` paramater
@@ -8,7 +8,7 @@ module Eco
8
8
  # @return [Symbol] the `type` of usecase (i.e. `:sync`, `:transform`, `:import`, `:other`)
9
9
  def type(value = nil)
10
10
  unless value
11
- return @type || raise("You should specify a type of case [:sync, :transform, :import, :other] for #{self.class}")
11
+ return @type || raise("You should specify a type of case [:sync, :transform, :import, :other] for #{self}")
12
12
  end
13
13
  @type = value
14
14
  end
@@ -57,6 +57,11 @@ module Eco
57
57
  @internal_entry
58
58
  end
59
59
 
60
+ # @return [Hash] entry `Hash` with **internal** attribute names, but **external** types and values.
61
+ def mapped_entry
62
+ @mapped_entry
63
+ end
64
+
60
65
  # @note values ready to be set to a person.
61
66
  # @return [Hash] entry `Hash` with **internal** attribute names, values and types.
62
67
  def final_entry
@@ -256,7 +261,7 @@ module Eco
256
261
  # @param mapped_entry [Hash] that with **internal** names but **external** values and types.
257
262
  # @return [Hash] with **external** names, values and types.
258
263
  def _external_serializing(mapped_entry)
259
- target_attrs = @emap.all_attrs | @emap.aliased_attrs
264
+ target_attrs = @emap.all_model_attrs | @emap.aliased_attrs
260
265
  rest_keys = mapped_entry.keys - target_attrs
261
266
  target_attrs -= ["send_invites"]
262
267
  external_entry = target_attrs.each_with_object({}) do |attr, hash|
@@ -6,14 +6,14 @@ module Eco
6
6
  # @attr_reader core_attrs [Array<String>] core attributes that are present in the person entry.
7
7
  # @attr_reader details_attrs [Array<String>] schema details attributes that are present in the person entry.
8
8
  # @attr_reader account_attrs [Array<String>] account attributes that are present in the person entry.
9
- # @attr_reader all_attrs [Array<String>] all the attrs that are present in the person entry.
9
+ # @attr_reader all_model_attrs [Array<String>] all the attrs that are present in the person entry.
10
10
  # @attr_reader internal_attrs [Array<String>] all the internally named attributes that the person entry has.
11
11
  # @attr_reader aliased_attrs [Array<String>] only those internal attributes present in the person entry that have an internal/external name mapping.
12
12
  # @attr_reader direct_attrs [Array<String>] only those internal attributes present in the person entry that do **not** have an internal/external name mapping.
13
13
  class PersonEntryAttributeMapper
14
14
  @@cached_warnings = {}
15
15
 
16
- attr_reader :core_attrs, :details_attrs, :account_attrs, :all_attrs
16
+ attr_reader :core_attrs, :details_attrs, :account_attrs, :all_model_attrs
17
17
  attr_reader :internal_attrs, :aliased_attrs, :direct_attrs
18
18
 
19
19
  # Helper class tied to `PersonEntry` that allows to track which attributes of a person entry are present
@@ -41,14 +41,14 @@ module Eco
41
41
  init_attr_trackers
42
42
  else # SERIALIZING
43
43
  @person = data
44
- @internal_attrs = @person_parser.all_attrs
44
+ @internal_attrs = @person_parser.all_model_attrs
45
45
  @aliased_attrs = @attr_map.list(:internal)
46
46
  end
47
47
 
48
48
  @core_attrs = @person_parser.target_attrs_core(@internal_attrs)
49
49
  @details_attrs = @person_parser.target_attrs_details(@internal_attrs)
50
50
  @account_attrs = @person_parser.target_attrs_account(@internal_attrs)
51
- @all_attrs = @core_attrs | @account_attrs | @details_attrs
51
+ @all_model_attrs = @core_attrs | @account_attrs | @details_attrs
52
52
  end
53
53
 
54
54
  # To know if currently the object is in parse or serialize mode.
@@ -98,7 +98,7 @@ module Eco
98
98
  end
99
99
  end
100
100
 
101
- return nil unless @person_parser.all_attrs.include?(attr)
101
+ return nil unless @person_parser.all_model_attrs.include?(attr)
102
102
  end
103
103
 
104
104
  # Serializing helper also used to do a reverse mapping when parsing:
@@ -146,9 +146,9 @@ module Eco
146
146
  # when parsing:
147
147
  def init_attr_trackers
148
148
  # (def) all internal attributes we can expect
149
- def_all_attrs = @person_parser.all_attrs
149
+ def_all_attrs = @person_parser.all_model_attrs
150
150
  # (def) internal attrs with no aliasing nor parser definition (expected to be direct)
151
- def_unlinked = @person_parser.undefined_attrs.select { |attr| !to_external(attr) }
151
+ def_unlinked = @person_parser.undefined_model_attrs.select { |attr| !to_external(attr) }
152
152
  # (def) those with parser or alias:
153
153
  def_linked = def_all_attrs - def_unlinked
154
154
 
@@ -168,7 +168,7 @@ module Eco
168
168
  # (data) virtual internal attrs (the internal names of those virtual attrs)
169
169
  data_vi_int_aliased = data_vi_ext_alias.map do |attr|
170
170
  # to_internal(attr) can't be used here, becauase virtual fields would get filtered out,
171
- # as they are not recognized by @parser.all_attrs.include?(attr)
171
+ # as they are not recognized by @parser.all_model_attrs.include?(attr)
172
172
  @attr_map.to_internal(attr)
173
173
  end.compact
174
174
 
@@ -7,7 +7,7 @@ module Eco
7
7
  #
8
8
  # @attr_reader schema [Ecoportal::API::V1::PersonSchema, nil] schema of person details that this parser will be based upon.
9
9
  # @attr_reader details_attrs [Array<String>] internal names of schema details attributes.
10
- # @attr_reader all_attrs [Array<String>] all the internal name attributes, including _core_, _account_ and _details_.
10
+ # @attr_reader all_model_attrs [Array<String>] all the internal name attributes, including _core_, _account_ and _details_.
11
11
  class PersonParser
12
12
  extend Eco::API::Common::ClassAutoLoader
13
13
  autoloads_children_of "Eco::API::Common::Loaders::Parser"
@@ -19,8 +19,7 @@ module Eco
19
19
  FORMAT = [:csv, :xml, :json]
20
20
 
21
21
  attr_reader :schema
22
- attr_reader :details_attrs, :all_attrs
23
- attr_reader :defined_attrs
22
+ attr_reader :details_attrs, :all_model_attrs
24
23
  attr_reader :patch_version
25
24
 
26
25
  # @example Example of usage:
@@ -46,7 +45,7 @@ module Eco
46
45
  @details_attrs = @schema&.fields.map { |fld| fld.alt_id }
47
46
  end
48
47
 
49
- @all_attrs = CORE_ATTRS + ACCOUNT_ATTRS + @details_attrs
48
+ @all_model_attrs = CORE_ATTRS + ACCOUNT_ATTRS + @details_attrs
50
49
  self.class.autoload_children(self)
51
50
  end
52
51
 
@@ -60,6 +59,11 @@ module Eco
60
59
 
61
60
  # @!group Scopping attributes (identifying, presence & active)
62
61
 
62
+ # All the internal name attributes, including _core_, _account_ and _details_.
63
+ def all_attrs(include_defined_parsers: false)
64
+ all_model_attrs | defined_model_attrs
65
+ end
66
+
63
67
  # Scopes `source_attrs` using the _**core** attributes_.
64
68
  # @note use this helper to know which among your attributes are **core** ones.
65
69
  # @param source_attrs [Array<String>]
@@ -93,14 +97,21 @@ module Eco
93
97
  @parsers.keys
94
98
  end
95
99
 
100
+ # Returns a list of all the internal attributes that have a parser defined.
101
+ # @note These attributes do not necessarily belong to the model. They could be virtual attributes
102
+ # @return [Array<String>] list of all attribute defined parsers.
103
+ def defined_attrs
104
+ defined_list - symbol_keys
105
+ end
106
+
96
107
  # Returns a list of all the internal attributes of the model that have a parser defined.
97
108
  # @note
98
109
  # - it excludes any parser that is not in the model, such as type parsers (i.e. `:boolean`, `:multiple`)
99
110
  # - the list is sorted according `CORE_ATTRS` + `ACCOUNT_ATTRS` + schema attrs
100
- # @return [Array<String>] list of all attribute defined parsers.
101
- def defined_attrs
111
+ # @return [Array<String>] list of all attribute defined parsers in the model.
112
+ def defined_model_attrs
102
113
  defined = @parsers.keys
103
- defined = (all_attrs | defined) & defined
114
+ defined = (all_model_attrs | defined) & defined
104
115
  defined - symbol_keys
105
116
  end
106
117
 
@@ -118,7 +129,7 @@ module Eco
118
129
  # @param process [Symbol] either `:parse` or `:serialize`, depending if we want to parse or serialize the `attr`.
119
130
  # @return [Array<String>] list of all attribute defined parsers that should be active for the given `source_data`.
120
131
  def active_attrs(source_data, phase = :any, process: :parse)
121
- defined_attrs.select do |attr|
132
+ defined_model_attrs.select do |attr|
122
133
  if process == :serialize
123
134
  @parsers[attr].serializer_active?(phase)
124
135
  else
@@ -130,8 +141,8 @@ module Eco
130
141
  # Returns a list of all the internal attributes of the model that do **not** have a parser defined.
131
142
  # @note it excludes any parser that is **not** in the model, such as type parsers (i.e. :boolean, :multiple)
132
143
  # @return [Array<String>] list of all attributes without a defined parser.
133
- def undefined_attrs
134
- all_attrs - defined_attrs
144
+ def undefined_model_attrs
145
+ all_model_attrs - defined_model_attrs
135
146
  end
136
147
 
137
148
  # @param attr [String] internal name of an attribute.
@@ -238,7 +249,7 @@ module Eco
238
249
  end
239
250
 
240
251
  def valid_attr?(attr)
241
- attr.is_a?(String) && (!@schema || @all_attrs.include?(attr))
252
+ attr.is_a?(String) && (!@schema || @all_model_attrs.include?(attr))
242
253
  end
243
254
 
244
255
  def valid_type?(attr)
data/lib/eco/api/error.rb CHANGED
@@ -80,6 +80,7 @@ module Eco
80
80
  next 1 if k1 < k2
81
81
  0
82
82
  end.tap do |siblings|
83
+ siblings.delete(Unclassified)
83
84
  if direct
84
85
  siblings.reject! do |si|
85
86
  siblings.any? {|s| si < s}
@@ -96,17 +97,18 @@ module Eco
96
97
  err_msg =~ @match
97
98
  end
98
99
 
99
- def get_type(err_msg)
100
+ def get_type(err_msg, first: true)
100
101
  type = nil
101
102
  descendants(direct: true).reverse.each do |klass|
102
103
  if klass.err_match?(err_msg)
103
104
  type = klass
104
105
  if klass.descendants?(direct: true)
105
- type = klass.get_type(err_msg) || type
106
+ type = klass.get_type(err_msg, first: false) || type
106
107
  end
107
108
  end
108
109
  end
109
- type
110
+ return type unless first
111
+ type || Unclassified
110
112
  end
111
113
 
112
114
  def known_err_class?(klass)
@@ -4,38 +4,27 @@ module Eco
4
4
 
5
5
  class PresetsFactory
6
6
  ABILITIES = File.join(__dir__, 'presets_values.json')
7
+ INTEGRITY = File.join(__dir__, 'presets_integrity.json')
7
8
  DEFAULT_CUSTOM = 'presets_custom.json'
8
9
  DEFAULT_MAP = 'presets_map.json'
9
10
 
10
11
  def initialize(presets_custom: DEFAULT_CUSTOM, presets_map: DEFAULT_MAP, enviro: nil, policy_groups: nil)
11
- @abilities = JSON.load(File.open(ABILITIES))
12
- @habilities = @abilities.map do |key, values|
13
- h_values = values.map { |v| [v, true] }.to_h
14
- [key, h_values]
15
- end.to_h
16
-
17
12
  fatal("Expecting Environment object. Given: #{enviro}") if enviro && !enviro.is_a?(Eco::API::Common::Session::Environment)
18
- @enviro = enviro
19
-
20
- policy_groups = policy_groups || @enviro&.api&.policy_groups.to_a
21
- if policy_groups.is_a?(Eco::API::Organization::PolicyGroups)
22
- @policy_groups = policy_groups
23
- else
24
- @policy_groups = Eco::API::Organization::PolicyGroups.new(policy_groups)
25
- end
13
+ @enviro = enviro
26
14
 
27
- init_custom(presets_custom)
28
- init_map(presets_map)
15
+ @policy_groups = policy_groups
16
+ @presets_custom_file = presets_custom || DEFAULT_CUSTOM
17
+ @presets_map_file = presets_map || DEFAULT_MAP
29
18
  end
30
19
 
31
20
  def new(*policy_group_ids_or_names)
32
21
 
33
22
  names = policy_group_ids_or_names.map do |id_name|
34
- @policy_groups.to_name(id_name)&.downcase
23
+ policy_groups.to_name(id_name)&.downcase
35
24
  end.compact
36
25
 
37
- if @presets_map
38
- preset_names = names.map { |name| @presets_map.fetch(name, nil) }
26
+ if presets_map
27
+ preset_names = names.map { |name| presets_map.fetch(name, nil) }
39
28
  else # option to do not use preset mapping (so just the policy group name)
40
29
  preset_names = names
41
30
  end
@@ -44,69 +33,11 @@ module Eco
44
33
 
45
34
  # @return [Array<String>] all the abilities
46
35
  def keys
47
- @abilities.keys
36
+ abilities_model.keys
48
37
  end
49
38
 
50
39
  private
51
40
 
52
- def init_custom(file = DEFAULT_CUSTOM)
53
- @presets_custom = nil
54
-
55
- return if !file
56
- file = File.expand_path(file)
57
-
58
- if File.exists?(file)
59
- @presets_custom = JSON.load(File.open(file))
60
-
61
- errors = @presets_custom.map do |key, preset|
62
- (err = preset_errors(preset)) ? "{ '#{key}' preset -> #{err}}": nil
63
- end.compact
64
-
65
- fatal("File '#{file}' contains invalid presets:\n #{errors.join("\n ")}") if errors.length > 0
66
- end
67
-
68
- end
69
-
70
- def init_map(file = DEFAULT_MAP)
71
- @presets_map = nil
72
-
73
- return if !file
74
- file = File.expand_path(file)
75
-
76
- if File.exists?(file)
77
- fatal("Maps file specified without custom presets file. Aborting!") if !@presets_custom
78
- @presets_map = JSON.load(File.open(file))
79
-
80
- errors = []
81
- if @policy_groups.length > 0
82
- errors = @policy_groups.map do |pg|
83
- exists = @presets_map[pg.name.downcase] || @presets_custom[pg.name.downcase]
84
- exists ? nil : "'#{pg.name}'"
85
- end.compact
86
-
87
- warn("No maps or no preset for policy group(s): #{errors.join(", ")}") if errors.length > 0
88
- end
89
-
90
- errors = @presets_map.map do |source, dest|
91
- @presets_custom[dest] ? nil : "'#{dest}'"
92
- end.compact
93
-
94
- warn("Unexisting mapped preset(s): #{errors.uniq.join(", ")}") if errors.length > 0
95
- end
96
-
97
- end
98
-
99
- def fatal(msg)
100
- raise msg if !@enviro
101
- @enviro.logger.fatal(msg)
102
- raise msg
103
- end
104
-
105
- def warn(msg)
106
- raise msg if !@enviro
107
- @enviro.logger.warn(msg)
108
- end
109
-
110
41
  def compile(*preset_names)
111
42
  fatal("You need to specify an existing file for the custom presets.") if !@presets_custom
112
43
  @presets_custom.values_at(*preset_names).compact.reduce({}) do |p1, p2|
@@ -117,7 +48,7 @@ module Eco
117
48
  def merge(preset1, preset2)
118
49
  keys = preset1.keys | preset2.keys
119
50
 
120
- @abilities.each_with_object({}) do |(key, values), result|
51
+ abilities_model.each_with_object({}) do |(key, values), result|
121
52
  next unless keys.include?(key)
122
53
  idx = [
123
54
  values.index(preset1[key]),
@@ -129,17 +60,149 @@ module Eco
129
60
 
130
61
  # unsused: only play with the given abilities
131
62
  def empty_model
132
- JSON.parse(@abilities.to_json).transform_values {|v| nil }
63
+ JSON.parse(abilities_model.to_json).transform_values {|v| nil }
133
64
  end
134
65
 
135
66
  def preset_errors(preset)
136
67
  return "No preset given" if !preset
137
68
  errors = preset.map do |k, v|
138
- @habilities.dig(k, v) ? nil : "#{k}:#{v}"
69
+ value_exists?(k, v) ? nil : "#{k}:#{v}"
139
70
  end.compact
140
- return " unknown: {#{errors.join(", ")}}" if errors.length > 0
71
+ return " Unknown: {#{errors.join(", ")}}" if errors.length > 0
141
72
  nil
142
73
  end
74
+
75
+ def preset_integrity(preset)
76
+ preset.each_with_object([]) do |(ability, value), errors|
77
+ next unless checks = integrity_model[ability]
78
+
79
+ suberrors = []
80
+
81
+ checks.each do |check|
82
+ next unless check["value"] == value
83
+ check["conditions"].each do |cond, targets|
84
+ case cond
85
+ when "at_least"
86
+ targets.each do |other, minimum|
87
+ unless (ability_value_idx(other, minimum) <= ability_value_idx(other, preset[other]))
88
+ suberrors << "'#{other}' should be at least '#{minimum}'"
89
+ end
90
+ end
91
+ when "one_of"
92
+ unless targets.any? {|other, expected| preset[other] == expected}
93
+ suberrors << targets.each_with_object([]) do |(other, expected), out|
94
+ out << "'#{other}': '#{expected}'"
95
+ end.join(", ").yield_self do |msg|
96
+ "there should be at least one of: {#{msg}}"
97
+ end
98
+ end
99
+ else
100
+ warn("Unsuported integrity condition statement '#{cond}' in '#{ability}' with level '#{value}'")
101
+ end
102
+ end
103
+ end
104
+
105
+ if suberrors.length > 0
106
+ errors << "Incorrect value '#{value}' for '#{ability}' - reasons: {#{suberrors.join(", ")}}"
107
+ end
108
+ end.yield_self do |errors|
109
+ " Integrity errors: { #{errors.join(", ")} }" if errors.length > 0
110
+ end
111
+ end
112
+
113
+ def integrity_model
114
+ @integrity_model ||= JSON.load(File.open(INTEGRITY))
115
+ end
116
+
117
+ def value_exists?(ability, value)
118
+ abilities_model_inverted.dig(ability, value)
119
+ end
120
+
121
+ def abilities_model_inverted
122
+ @abilities_model_inverted ||= abilities_model.each_with_object({}) do |(key, values), out|
123
+ out[key] = values.each_with_object({}) {|v, h| h[v] = true }
124
+ end
125
+ end
126
+
127
+ def ability_value_idx(ability, value)
128
+ abilities_model[ability].index(value)
129
+ end
130
+
131
+ def abilities_model
132
+ @abilities_model ||= JSON.load(File.open(ABILITIES))
133
+ end
134
+
135
+ def policy_groups
136
+ return @policy_groups if @policy_groups.is_a?(Eco::API::Organization::PolicyGroups)
137
+ @policy_groups ||= @enviro&.api&.policy_groups.to_a
138
+
139
+ unless @policy_groups.is_a?(Eco::API::Organization::PolicyGroups)
140
+ @policy_groups = Eco::API::Organization::PolicyGroups.new(@policy_groups)
141
+ end
142
+ @policy_groups
143
+ end
144
+
145
+ def presets_custom
146
+ return @presets_custom if instance_variable_defined?(:@presets_custom)
147
+ @presets_custom = nil
148
+ if @presets_custom_file
149
+ if (file = File.expand_path(@presets_custom_file)) && File.exists?(file)
150
+ @presets_custom = JSON.load(File.open(file)).tap do |custom_presets|
151
+ errors = custom_presets.each_with_object([]) do |(key, preset), errors|
152
+ if err = preset_errors(preset)
153
+ errors << "{ '#{key}' preset -> #{err}}"
154
+ end
155
+ if err = preset_integrity(preset)
156
+ errors << "{ '#{key}' preset -> #{err}}"
157
+ end
158
+ end
159
+
160
+ fatal("File '#{file}' contains invalid presets:\n #{errors.join("\n ")}") if errors.length > 0
161
+ end
162
+ end
163
+ end
164
+ end
165
+
166
+ def presets_map
167
+ return @presets_map if instance_variable_defined?(:@presets_map)
168
+ @presets_map = nil
169
+ if @presets_map_file
170
+ if (file = File.expand_path(@presets_map_file)) && File.exists?(file)
171
+ fatal("Maps file specified without 'presets_custom.json' file. Aborting!") if !presets_custom
172
+ @presets_map = JSON.load(File.open(file)).tap do |map_presets|
173
+
174
+ errors = []
175
+ if policy_groups.length > 0
176
+ errors = policy_groups.map do |pg|
177
+ exists = map_presets[pg.name.downcase] || presets_custom[pg.name.downcase]
178
+ exists ? nil : "'#{pg.name}'"
179
+ end.compact
180
+
181
+ warn("No maps or no preset for policy group(s): #{errors.join(", ")}") if errors.length > 0
182
+ end
183
+
184
+ errors = map_presets.map do |source, dest|
185
+ presets_custom[dest] ? nil : "'#{dest}'"
186
+ end.compact
187
+
188
+ warn("Unexisting mapped preset(s): #{errors.uniq.join(", ")}") if errors.length > 0
189
+
190
+ end
191
+ end
192
+ end
193
+ end
194
+
195
+ def fatal(msg)
196
+ raise msg if !@enviro
197
+ @enviro.logger.fatal(msg)
198
+ raise msg
199
+ end
200
+
201
+ def warn(msg)
202
+ raise msg if !@enviro
203
+ @enviro.logger.warn(msg)
204
+ end
205
+
143
206
  end
144
207
 
145
208
  end
@@ -0,0 +1,52 @@
1
+ {
2
+ "person_core_create": [
3
+ { "value": "create", "conditions": {
4
+ "at_least": {"person_core": "view_people_manager"}
5
+ }
6
+ }
7
+ ],
8
+ "person_core_edit": [
9
+ { "value": "edit", "conditions": {
10
+ "at_least": {"person_core": "view_people_manager"}
11
+ }
12
+ }
13
+ ],
14
+ "person_details": [
15
+ { "value": "view", "conditions": {
16
+ "at_least": {"person_core": "attach"}
17
+ }
18
+ },
19
+ { "value": "edit_public", "conditions": {
20
+ "one_of": {
21
+ "person_core_edit": "edit",
22
+ "person_core_create": "create"
23
+ }
24
+ }
25
+ },
26
+ { "value": "view_private", "conditions": {
27
+ "at_least": {"person_core": "attach" }
28
+ }
29
+ },
30
+ { "value": "edit_private", "conditions": {
31
+ "one_of": {
32
+ "person_core_edit": "edit",
33
+ "person_core_create": "create"
34
+ }
35
+ }
36
+ }
37
+ ],
38
+ "person_account": [
39
+ { "value": "view", "conditions": {
40
+ "at_least": {"person_core": "attach" }
41
+ }
42
+ },
43
+ { "value": "create", "conditions": {
44
+ "at_least": {"person_core_create": "create"}
45
+ }
46
+ },
47
+ { "value": "edit", "conditions": {
48
+ "at_least": {"person_core_edit": "edit"}
49
+ }
50
+ }
51
+ ]
52
+ }
@@ -4,7 +4,7 @@ module Eco
4
4
 
5
5
  # Provides helpers to deal with tagtrees.
6
6
  class TagTree
7
- attr_reader :tag, :nodes
7
+ attr_reader :tag, :nodes, :children_count
8
8
  attr_reader :depth, :path
9
9
  attr_reader :enviro
10
10
 
@@ -37,6 +37,7 @@ module Eco
37
37
 
38
38
  nodes = @source.is_a?(Array) ? @source : @source.dig('nodes') || []
39
39
  @nodes = nodes.map {|cnode| TagTree.new(cnode, depth: @depth + 1, path: @path.dup, enviro: @enviro)}
40
+ @children_count = @nodes.count
40
41
 
41
42
  init_hashes
42
43
  end
@@ -46,6 +47,21 @@ module Eco
46
47
  @has_tags.empty?
47
48
  end
48
49
 
50
+ # @return [Integer] the highest `depth` of all the children.
51
+ def total_depth
52
+ @total_depth ||= if children_count > 0
53
+ deepest_node = nodes.max_by {|node| node.total_depth}
54
+ deepest_node.depth
55
+ else
56
+ depth
57
+ end
58
+ end
59
+
60
+ # @return [Integer] if there's only top level.
61
+ def flat?
62
+ self.total_depth <= 0
63
+ end
64
+
49
65
  # Gets all the tags of the current node tree.
50
66
  # @note
51
67
  # - this will include the upper level tag(s) as well
@@ -147,7 +163,8 @@ module Eco
147
163
  # * take the deepest tag (the one that is further down in the tree)
148
164
  # * if there are different options (several nodes at the same depth):
149
165
  # * take the common node between them (i.e. you have Hamilton and Auckland -> take New Zealand)
150
- # * if there's no common node between them, take the `first` (unless they are at top level of the tree)
166
+ # * if there's no common node between them, take the `first`, unless they are at top level of the tree
167
+ # * to the above, take the `first` also on top level, but only if there's 1 level for the entire tree
151
168
  # @param [Array<String>] values list of tags.
152
169
  # @return [String] default tag.
153
170
  def default_tag(*values)
@@ -169,7 +186,7 @@ module Eco
169
186
  common = nodes.reduce(self.tags.reverse) {|com, cnode| com & cnode.path.reverse}
170
187
  default_tag = common.first if common.length > 0 && depth > 0
171
188
  end
172
- default_tag = nodes.first&.tag if !default_tag && depth > 0
189
+ default_tag = nodes.first&.tag if !default_tag && ( (depth > 0) || flat?)
173
190
  default_tag
174
191
  end
175
192
 
@@ -105,10 +105,15 @@ module Eco
105
105
  iterations = (data.length.to_f / per_page).ceil
106
106
 
107
107
  Eco::API::Session::Batch::Status.new(enviro, queue: data, method: method).tap do |status|
108
+ start_time = Time.now
109
+ start_slice = Time.now; slice = []
108
110
  data.each_slice(per_page) do |slice|
109
- msg = "starting batch '#{method}' iteration #{iteration}/#{iterations}, with #{slice.length} entries of #{data.length} -- #{done} done"
111
+ msg = "starting batch '#{method}' iteration #{iteration}/#{iterations},"
112
+ msg += " with #{slice.length} entries of #{data.length} -- #{done} done"
113
+ msg += " (last: #{str_stats(start_slice, slice.length)}; total: #{str_stats(start_time, done)})"
110
114
  logger.info(msg) unless silent
111
115
 
116
+ start_slice = Time.now
112
117
  people_api.batch do |batch|
113
118
  slice.each do |person|
114
119
  batch.public_send(method, person) do |response|
@@ -118,12 +123,23 @@ module Eco
118
123
  end
119
124
  end # next batch
120
125
 
121
- iteration += 1
122
- done += slice.length
126
+ iteration += 1
127
+ done += slice.length
123
128
  end # next slice
124
129
  end
125
130
  end
126
131
 
132
+ def str_stats(start, count)
133
+ now = Time.now
134
+ secs = (now - start).round(3)
135
+ if secs > 0.0
136
+ per_sec = (count.to_f / secs).round(2)
137
+ "#{secs}s -> #{per_sec} people/s"
138
+ else
139
+ " -- "
140
+ end
141
+ end
142
+
127
143
  end
128
144
  end
129
145
  end
@@ -124,7 +124,7 @@ module Eco
124
124
  # - please, observe that this can only happen if there were repeated entries in the `source_queue`
125
125
  # @return [Array<Hash>, Array<Ecoportal::API::V1::Person>, Array<Ecoportal::API::Internal::Person>]
126
126
  def entries
127
- queue.filter.with_index do |query, i|
127
+ queue.select.with_index do |query, i|
128
128
  unless response = status[i]
129
129
  msg = "Error: query with no response. You might have duplicated entries in your queue.\n"
130
130
  msg += "Queue length: #{queue.length}; Queue elements class: #{queue.first.class}\n"
@@ -45,25 +45,22 @@ module Eco
45
45
  # @!group Pure feedback methods
46
46
 
47
47
  # Slightly modifies the behaviour of `Ecoportal::API::Common::BaseModel#as_update`, so schema details fields show the `alt_id`
48
+ # It also fixes possible patch updates that are incomplete or unnecessary.
48
49
  # @note for better feedback
49
50
  # @param entry [Hash, Ecoportal::API::V1::Person, Ecoportal::API::Internal::Person]
50
- def as_update(entry)
51
+ # @param add_feedback [Boolean] if `true` it tweak the hash update with additional data.
52
+ def as_update(entry, add_feedback: true)
51
53
  case
52
54
  when entry.is_a?(Hash)
53
55
  hash = entry
54
56
  else #entry.is_a?(Ecoportal::API::V1::Person)
55
57
  if only_ids?
56
- hash = {
57
- "id" => entry.id,
58
- "external_id" => entry.external_id,
59
- "email" => entry.email
60
- }
61
58
  hash = entry.as_json.slice("id", "external_id", "email")
62
59
  else
63
60
  hash = entry.as_update
64
- #if entry.details
65
- if hash["details"]
66
- if hfields = hash.dig("details", "fields")
61
+
62
+ if add_feedback && details = hash["details"]
63
+ if hfields = details["fields"]
67
64
  hfields.each do |fld|
68
65
  fld.merge!("alt_id" => entry.details.get_field(fld["id"]).alt_id)
69
66
  end
@@ -169,7 +169,8 @@ module Eco
169
169
 
170
170
  unless simulate
171
171
  if pqueue.length > 0
172
- backup_update(requests)
172
+ req_backup = pqueue.map {|e| as_update(e, add_feedback: false)}
173
+ backup_update(req_backup)
173
174
  session.batch.launch(pqueue, method: type).tap do |job_status|
174
175
  @status = job_status
175
176
  status.root = self
@@ -217,7 +218,7 @@ module Eco
217
218
  [].tap do |msg|
218
219
  subjobs.map {|subjob| msg << subjob.summary}
219
220
  end.join("\n")
220
- end
221
+ end
221
222
 
222
223
  def as_update(*args)
223
224
  feedback.as_update(*args)
@@ -287,10 +288,13 @@ module Eco
287
288
  handlers = session.config.error_handlers
288
289
  if status.errors.any? && !handlers.empty? && !error_handler?
289
290
  err_types = status.errors.by_type
291
+ logger.debug("(#{self.name}) got these error types: #{err_types.keys}")
290
292
  handlers.each do |handler|
291
293
  if entries = err_types[handler.name]
292
294
  handler_job = subjobs_add("#{self.name} => #{handler.name}", usecase: handler)
295
+ logger.debug("Running error handler #{handler.name}")
293
296
  handler.launch(people: people(entries), session: session, options: options, job: handler_job)
297
+ logger.debug("Launching job of error handler: #{handler_job.name}")
294
298
  handler_job.launch(simulate: simulate)
295
299
  end
296
300
  end
@@ -30,6 +30,7 @@ module Eco
30
30
  @usecases = {}
31
31
  @cache_init = false
32
32
  @cases_by_name = {}
33
+ init_caches
33
34
  end
34
35
 
35
36
  def length
@@ -79,6 +80,7 @@ module Eco
79
80
 
80
81
  # @return [Eco::API::UseCases] a copy of instance object of `self`.
81
82
  def dup
83
+ init_caches
82
84
  self.class.new.merge(self)
83
85
  end
84
86
 
@@ -2,18 +2,17 @@ class Eco::API::UseCases::DefaultCases::HrisCase < Eco::API::Common::Loaders::Us
2
2
  name "hris"
3
3
  type :sync
4
4
 
5
+ attr_reader :creation, :update, :supers, :leavers
6
+
5
7
  def main(entries, people, session, options, usecase)
6
8
  micro = session.micro
7
- creation = session.new_job("main", "create", :create, usecase)
8
- update = session.new_job("main", "update", :update, usecase)
9
- supers = session.new_job("post", "supers", :update, usecase, :core)
10
- leavers = session.new_job("post", "leavers", :update, usecase, :account)
9
+ @creation = session.new_job("main", "create", :create, usecase)
10
+ @update = session.new_job("main", "update", :update, usecase)
11
+ @supers = session.new_job("post", "supers", :update, usecase, :core)
12
+ @leavers = session.new_job("post", "leavers", :update, usecase, :account)
11
13
 
12
14
  micro.with_each_leaver(entries, people, options) do |person|
13
- leavers.add(person) do |person|
14
- person.supervisor_id = nil
15
- person.account = nil if person.account
16
- end
15
+ leavers.add(person, &method(:leavers_callback))
17
16
  end
18
17
 
19
18
  micro.with_each(entries, people, options) do |entry, person|
@@ -24,4 +23,11 @@ class Eco::API::UseCases::DefaultCases::HrisCase < Eco::API::Common::Loaders::Us
24
23
  end
25
24
  end
26
25
 
26
+ private
27
+
28
+ def leavers_callback(person)
29
+ person.supervisor_id = nil
30
+ person.account = nil if person.account
31
+ end
32
+
27
33
  end
@@ -2,7 +2,11 @@ class Eco::API::UseCases::DefaultCases::ToCsvCase < Eco::API::Common::Loaders::U
2
2
  name "to-csv"
3
3
  type :export
4
4
 
5
+ attr_reader :session, :options, :people
6
+
5
7
  def main(people, session, options, usecase)
8
+ @session = session; @options = options; @people = people
9
+
6
10
  unless people && !people.empty?
7
11
  session.logger.warn("No source people to create the file... aborting!")
8
12
  return false
@@ -14,32 +18,48 @@ class Eco::API::UseCases::DefaultCases::ToCsvCase < Eco::API::Common::Loaders::U
14
18
  end
15
19
 
16
20
  session.logger.info("going to create file: #{file}")
17
- CSV.open(file, "w") do |csv|
18
- deps = {"supervisor_id" => {people: people}}
19
- entry = session.new_entry(people.first, dependencies: deps)
20
- header = entry.external_entry.keys
21
-
22
- if options.dig(:nice_header) || options.dig(:export, :options, :nice_header)
23
- name_maps = session.schema.fields_by_alt_id.transform_values do |fld|
24
- fld.name
25
- end.merge({
26
- "policy_group_ids" => "User Group(s)",
27
- "email" => "Email",
28
- "name" => "Name",
29
- "supervisor_id" => "Manager ID",
30
- "filter_tags" => "Locations",
31
- "default_tag" => "Default Location",
32
- "id" => "ecoPortal ID"
33
- })
34
- header = header.map {|name| name_maps[name] ? name_maps[name] : name}
35
- end
36
21
 
37
- csv << header
22
+ CSV.open(file, "w") do |csv|
23
+ csv << spot_header
38
24
  people.each do |person|
39
- csv << session.new_entry(person, dependencies: deps).external_entry.values
25
+ csv << target_entry_type(person).values
40
26
  end
41
27
  end
42
28
  exit(0)
43
29
  end
44
30
 
31
+ private
32
+
33
+ def target_entry_type(person)
34
+ session.new_entry(person, dependencies: deps).yield_self do |person_entry|
35
+ options.dig(:export, :options, :internal_names) ? person_entry.mapped_entry : person_entry.external_entry
36
+ end
37
+ end
38
+
39
+ def deps
40
+ @deps ||= {"supervisor_id" => {people: people}}
41
+ end
42
+
43
+ def spot_header
44
+ entry = target_entry_type(people.first)
45
+ header = entry.keys
46
+
47
+ if options.dig(:nice_header) || options.dig(:export, :options, :nice_header)
48
+ name_maps = session.schema.fields_by_alt_id.transform_values do |fld|
49
+ fld.name
50
+ end.merge({
51
+ "policy_group_ids" => "User Group(s)",
52
+ "email" => "Email",
53
+ "name" => "Name",
54
+ "supervisor_id" => "Manager ID",
55
+ "filter_tags" => "Locations",
56
+ "default_tag" => "Default Location",
57
+ "id" => "ecoPortal ID"
58
+ })
59
+ header = header.map {|name| name_maps[name] ? name_maps[name] : name}
60
+ end
61
+ header
62
+ end
63
+
64
+
45
65
  end
data/lib/eco/cli.rb CHANGED
@@ -22,16 +22,17 @@ module Eco
22
22
 
23
23
  def run(session:)
24
24
  io = Eco::API::UseCases::BaseIO.new(session: session, options: options)
25
- #session.workflow.run(io: io)
26
- session.workflow(io: io) do |wf, io|
27
- io = wf.run(:options, io: io)
28
- io = wf.run(:load, io: io)
29
- io = wf.run(:usecases, io: io)
30
- io = wf.run(:launch_jobs, io: io)
31
- io = wf.run(:post_launch, io: io)
32
- io = wf.run(:end, io: io)
33
- io = wf.run(:close, io: io)
34
- end
25
+ session.workflow(io: io).run(io: io)
26
+ #session.workflow(io: io) do |wf, io|
27
+ # io = wf.run(:options, io: io)
28
+ # io = wf.run(:load, io: io)
29
+ # io = wf.run(:usecases, io: io)
30
+ # io = wf.run(:launch_jobs, io: io)
31
+ # io = wf.run(:post_launch, io: io)
32
+ # io = wf.run(:report, io: io)
33
+ # io = wf.run(:end, io: io)
34
+ # io = wf.run(:close, io: io)
35
+ #end
35
36
  end
36
37
 
37
38
  end
@@ -6,7 +6,7 @@ ASSETS.cli.config do |cnf|
6
6
  file = SCR.get_file("-people-to-csv", required: true, should_exist: false)
7
7
  options.deep_merge!(export: {file: {name: file, format: :csv}})
8
8
  options.deep_merge!(export: {options: {nice_header: true}}) if SCR.get_arg("-nice-header")
9
-
9
+ options.deep_merge!(export: {options: {internal_names: true}}) if SCR.get_arg("-internal-names")
10
10
  case_name = SCR.get_arg("-detailed")? "to-csv-detailed" : "to-csv"
11
11
  session.usecases.case(case_name)
12
12
  end
@@ -73,7 +73,7 @@ ASSETS.cli.config do |cnf|
73
73
  end
74
74
 
75
75
  options.deep_merge!(ignore: {missing: {policy_groups: true}}) if SCR.get_arg("-ignore-missing-policy-groups")
76
-
76
+
77
77
  end
78
78
 
79
79
  desc = "Restores the people manager by using a backup.json file"
data/lib/eco/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Eco
2
- VERSION = "2.0.9"
2
+ VERSION = "2.0.14"
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.9
4
+ version: 2.0.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oscar Segura
@@ -340,6 +340,7 @@ files:
340
340
  - lib/eco/api/organization/preferences.rb
341
341
  - lib/eco/api/organization/preferences_reference.json
342
342
  - lib/eco/api/organization/presets_factory.rb
343
+ - lib/eco/api/organization/presets_integrity.json
343
344
  - lib/eco/api/organization/presets_reference.json
344
345
  - lib/eco/api/organization/presets_values.json
345
346
  - lib/eco/api/organization/tag_tree.rb