eco-helpers 2.0.13 → 2.0.18
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +87 -2
- data/eco-helpers.gemspec +6 -4
- data/lib/eco-helpers.rb +2 -0
- data/lib/eco/api/common/base_loader.rb +14 -0
- data/lib/eco/api/common/people/default_parsers/date_parser.rb +11 -1
- data/lib/eco/api/common/people/default_parsers/login_providers_parser.rb +1 -1
- data/lib/eco/api/common/people/default_parsers/policy_groups_parser.rb +11 -11
- data/lib/eco/api/common/people/person_entry.rb +9 -2
- data/lib/eco/api/common/people/supervisor_helpers.rb +27 -0
- data/lib/eco/api/common/session/file_manager.rb +2 -2
- data/lib/eco/api/common/session/mailer.rb +0 -1
- data/lib/eco/api/common/session/s3_uploader.rb +0 -1
- data/lib/eco/api/common/session/sftp.rb +0 -1
- data/lib/eco/api/common/version_patches/exception.rb +8 -4
- data/lib/eco/api/error.rb +5 -3
- data/lib/eco/api/microcases.rb +3 -1
- data/lib/eco/api/microcases/append_usergroups.rb +0 -1
- data/lib/eco/api/microcases/people_cache.rb +2 -2
- data/lib/eco/api/microcases/people_load.rb +2 -2
- data/lib/eco/api/microcases/people_refresh.rb +2 -2
- data/lib/eco/api/microcases/people_search.rb +6 -6
- data/lib/eco/api/microcases/preserve_default_tag.rb +23 -0
- data/lib/eco/api/microcases/preserve_filter_tags.rb +28 -0
- data/lib/eco/api/microcases/preserve_policy_groups.rb +30 -0
- data/lib/eco/api/microcases/set_account.rb +0 -1
- data/lib/eco/api/organization.rb +1 -0
- data/lib/eco/api/organization/people.rb +7 -0
- data/lib/eco/api/organization/people_analytics.rb +60 -0
- data/lib/eco/api/organization/presets_factory.rb +116 -93
- data/lib/eco/api/organization/presets_integrity.json +58 -0
- data/lib/eco/api/organization/presets_values.json +5 -4
- data/lib/eco/api/policies/default_policies/99_user_access_policy.rb +0 -30
- data/lib/eco/api/session.rb +1 -20
- data/lib/eco/api/session/batch.rb +23 -7
- data/lib/eco/api/session/batch/job.rb +3 -0
- data/lib/eco/api/session/config.rb +16 -15
- data/lib/eco/api/session/config/api.rb +4 -0
- data/lib/eco/api/session/config/apis.rb +80 -0
- data/lib/eco/api/session/config/files.rb +7 -0
- data/lib/eco/api/session/config/people.rb +3 -19
- data/lib/eco/api/usecases/default_cases.rb +4 -1
- data/lib/eco/api/usecases/default_cases/abstract_policygroup_abilities_case.rb +161 -0
- data/lib/eco/api/usecases/default_cases/analyse_people_case.rb +76 -0
- data/lib/eco/api/usecases/default_cases/codes_to_tags_case.rb +2 -3
- data/lib/eco/api/usecases/default_cases/reset_landing_page_case.rb +11 -1
- data/lib/eco/api/usecases/default_cases/restore_db_case.rb +1 -2
- data/lib/eco/api/usecases/default_cases/supers_cyclic_identify_case.rb +72 -0
- data/lib/eco/api/usecases/default_cases/supers_hierarchy_case.rb +59 -0
- data/lib/eco/api/usecases/default_cases/to_csv_case.rb +104 -26
- data/lib/eco/api/usecases/default_cases/to_csv_detailed_case.rb +62 -36
- data/lib/eco/cli.rb +0 -10
- data/lib/eco/cli/config/default/options.rb +19 -17
- data/lib/eco/cli/config/default/people_filters.rb +3 -3
- data/lib/eco/cli/config/default/usecases.rb +77 -25
- data/lib/eco/cli/config/default/workflow.rb +12 -3
- data/lib/eco/cli/config/help.rb +1 -0
- data/lib/eco/cli/config/options_set.rb +106 -13
- data/lib/eco/cli/config/use_cases.rb +33 -33
- data/lib/eco/cli/scripting/args_helpers.rb +30 -3
- data/lib/eco/data.rb +1 -0
- data/lib/eco/data/crypto/encryption.rb +3 -3
- data/lib/eco/data/files/directory.rb +28 -20
- data/lib/eco/data/files/helpers.rb +6 -4
- data/lib/eco/data/fuzzy_match.rb +119 -0
- data/lib/eco/data/fuzzy_match/array_helpers.rb +75 -0
- data/lib/eco/data/fuzzy_match/chars_position_score.rb +37 -0
- data/lib/eco/data/fuzzy_match/ngrams_score.rb +73 -0
- data/lib/eco/data/fuzzy_match/pairing.rb +102 -0
- data/lib/eco/data/fuzzy_match/result.rb +67 -0
- data/lib/eco/data/fuzzy_match/results.rb +53 -0
- data/lib/eco/data/fuzzy_match/score.rb +44 -0
- data/lib/eco/data/fuzzy_match/stop_words.rb +35 -0
- data/lib/eco/data/fuzzy_match/string_helpers.rb +69 -0
- data/lib/eco/version.rb +1 -1
- metadata +86 -10
- data/lib/eco/api/microcases/refresh_abilities.rb +0 -19
- data/lib/eco/api/organization/presets_reference.json +0 -59
- data/lib/eco/api/usecases/default_cases/refresh_abilities_case.rb +0 -30
@@ -0,0 +1,161 @@
|
|
1
|
+
class Eco::API::UseCases::DefaultCases::AbstractPolicyGroupAbilities < Eco::API::Common::Loaders::UseCase
|
2
|
+
name "abstract-policygroup-abilities"
|
3
|
+
type :export
|
4
|
+
|
5
|
+
attr_reader :session, :people, :options
|
6
|
+
|
7
|
+
def main(people, session, options, usecase)
|
8
|
+
options[:end_get] = false
|
9
|
+
@session = session; @options = options; @people = people
|
10
|
+
|
11
|
+
generate_csv!
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def file
|
17
|
+
@file ||= options.dig(:output, :file) || "suggested_abilities.csv"
|
18
|
+
end
|
19
|
+
|
20
|
+
def generate_csv!
|
21
|
+
policy_groups.each_with_object({}) do |group, data|
|
22
|
+
data[group.id] ||= {}
|
23
|
+
data[group.id][:name] = group.name
|
24
|
+
data[group.id][:suggested] = group_suggestions(group.id)
|
25
|
+
data[group.id][:percents] = group_abilities(group.id)
|
26
|
+
end.yield_self do |data|
|
27
|
+
abilities_list = Eco::API::Organization::PresetsFactory.abilities
|
28
|
+
CSV.open(file, "w") do |csv|
|
29
|
+
csv << ["Type", "UserGroup", "ID", *abilities_list]
|
30
|
+
# Dump the final suggestions
|
31
|
+
data.each do |id, meta|
|
32
|
+
csv << ["Suggested", meta[:name], id, *meta[:suggested].values_at(*abilities_list)]
|
33
|
+
end
|
34
|
+
# Dump the percentaged levels of each ability
|
35
|
+
data.each do |id, meta|
|
36
|
+
analysis = meta[:percents].values_at(*abilities_list).each_with_object([]) do |levels, values|
|
37
|
+
values << levels.map do |level, percentil|
|
38
|
+
"#{level ? level : "null"} => #{percentil}"
|
39
|
+
end.join("\n")
|
40
|
+
end
|
41
|
+
csv << ["Analysis", meta[:name], id, *analysis]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
puts "Generated file #{file}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def policy_groups
|
49
|
+
@policy_groups ||= session.policy_groups
|
50
|
+
end
|
51
|
+
|
52
|
+
# Suggests 1 final set of abilities for a usergroup
|
53
|
+
def group_suggestions(id)
|
54
|
+
group_abilities(id).each_with_object({}) do |(key, levels), set|
|
55
|
+
data = levels.to_a.sort_by(&:last).reverse.first
|
56
|
+
set[key] = data ? data.shift : nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Cleans up each ability's levels by:
|
61
|
+
# 1. cutting at some minimum threshold percentage
|
62
|
+
# 2. directly selecting those greater than 70%
|
63
|
+
def group_abilities(id)
|
64
|
+
@group_abilities ||= {}
|
65
|
+
@group_abilities[id] ||= ability_levels_percent(id).each_with_object({}) do |(ability, levels), out|
|
66
|
+
outstanding = nil
|
67
|
+
levels.select do |level, percentil|
|
68
|
+
outstanding ||= level if percentil >= 75
|
69
|
+
percentil > 15
|
70
|
+
end.yield_self do |filtered|
|
71
|
+
out[ability] = outstanding ? filtered.slice(outstanding) : filtered
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# With given the percentages of sets of abilities
|
77
|
+
# it abstracts the percentage of each level of each ability
|
78
|
+
def ability_levels_percent(id)
|
79
|
+
@ability_levels_percent ||= {}
|
80
|
+
@ability_levels_percent[id] ||= Eco::API::Organization::PresetsFactory.abilities.each_with_object({}) do |key, out|
|
81
|
+
out[key] ||= {}
|
82
|
+
ability_sets_percent(id).each_with_object(out[key]) do |(set, percentil), levels|
|
83
|
+
levels[set[key]] ||= 0
|
84
|
+
levels[set[key]] = (levels[set[key]] + percentil).round(2)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Give a percentage to each set of abilities
|
90
|
+
def ability_sets_percent(id)
|
91
|
+
@ability_sets_percent ||= {}
|
92
|
+
@ability_sets_percent[id] ||= scoped_relevant_raw_data(id).yield_self do |data|
|
93
|
+
# Transform ability sets counter to percentage
|
94
|
+
total = data[:count]
|
95
|
+
abilities = data[:abilities]
|
96
|
+
data[:abilities].transform_values do |val|
|
97
|
+
percent(val, total)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Get rid of data simingly irrelevant
|
103
|
+
def scoped_relevant_raw_data(id)
|
104
|
+
sp = single_percent(id)
|
105
|
+
sing = single(id); mult = multiple(id)
|
106
|
+
|
107
|
+
# Scope Relevant Raw Data
|
108
|
+
case
|
109
|
+
when sp >= 3 # >= 80
|
110
|
+
sing
|
111
|
+
#when sp < 15
|
112
|
+
# mult
|
113
|
+
else # combine
|
114
|
+
all_abilities = sing[:abilities].keys | mult[:abilities].keys
|
115
|
+
data = {count: sing[:count] + mult[:count], abilities: {}}
|
116
|
+
all_abilities.each_with_object(data) do |abilities, merged|
|
117
|
+
scount = sing[:abilities][abilities] || 0
|
118
|
+
mcount = mult[:abilities][abilities] || 0
|
119
|
+
merged[:abilities][abilities] = scount + mcount
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def single_percent(id)
|
125
|
+
percent(single(id)[:count], count(id))
|
126
|
+
end
|
127
|
+
|
128
|
+
def single(id)
|
129
|
+
groups_abilities.dig(id, :single) || {count: 0, abilities: {}}
|
130
|
+
end
|
131
|
+
|
132
|
+
def multiple(id)
|
133
|
+
groups_abilities.dig(id, :multiple) || {count: 0, abilities: {}}
|
134
|
+
end
|
135
|
+
|
136
|
+
def count(id)
|
137
|
+
groups_abilities.dig(id, :count) || 0
|
138
|
+
end
|
139
|
+
|
140
|
+
def groups_abilities
|
141
|
+
@groups_abilities ||= people.users.each_with_object({}) do |user, groups|
|
142
|
+
abilities = Eco::API::Organization::PresetsFactory.all_abilities(user.account.permissions_custom)
|
143
|
+
ids = user.account.policy_group_ids
|
144
|
+
category = ids.count > 1 ? :multiple : :single
|
145
|
+
|
146
|
+
ids.each do |id|
|
147
|
+
groups[id] ||= {count: 0}
|
148
|
+
groups[id][:count] += 1
|
149
|
+
groups[id][category] ||= {count: 0, abilities: {}}
|
150
|
+
groups[id][category][:count] += 1
|
151
|
+
groups[id][category][:abilities][abilities] ||= 0
|
152
|
+
groups[id][category][:abilities][abilities] += 1
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def percent(num, total)
|
158
|
+
(100 * num.to_f / total).round(2)
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
class Eco::API::UseCases::DefaultCases::AnalysePeople < Eco::API::Common::Loaders::UseCase
|
2
|
+
name "analyse-people"
|
3
|
+
type :export
|
4
|
+
|
5
|
+
attr_reader :session, :people, :options
|
6
|
+
|
7
|
+
def main(people, session, options, usecase)
|
8
|
+
@session = session; @options = options; @people = people
|
9
|
+
|
10
|
+
save!(cyclic_sets)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def identify_double_ups
|
16
|
+
analytics.similarity
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
def analytics
|
21
|
+
@analytics ||= people.analytics
|
22
|
+
end
|
23
|
+
|
24
|
+
def file
|
25
|
+
@file ||= options.dig(:output, :file) || "analytics.txt"
|
26
|
+
end
|
27
|
+
|
28
|
+
def save!(data)
|
29
|
+
if data.empty?
|
30
|
+
session.logger.info("There were no cyclic supervisors identified!!")
|
31
|
+
return
|
32
|
+
end
|
33
|
+
|
34
|
+
ext = File.extname(file).downcase.delete(".")
|
35
|
+
|
36
|
+
File.open(file, "w") do |fd|
|
37
|
+
if ext == "txt"
|
38
|
+
create_file(data, file: file, format: :txt)
|
39
|
+
elsif ext == "html"
|
40
|
+
puts "html is still not supported"
|
41
|
+
exit(1)
|
42
|
+
create_file(data, file: file, format: :html)
|
43
|
+
elsif ext == "json"
|
44
|
+
puts "json is still not supported"
|
45
|
+
exit(1)
|
46
|
+
create_file(data, file: file, format: :json)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def create_file(sets, file:, format: :txt)
|
52
|
+
File.open(file, "w") do |fd|
|
53
|
+
fd << sets_to_str(sets, format: format)
|
54
|
+
end
|
55
|
+
puts "Generated file #{file}"
|
56
|
+
end
|
57
|
+
|
58
|
+
def sets_to_str(sets, format: :txt)
|
59
|
+
raise "Required Array. Given: #{sets.class}" unless sets.is_a?(Array)
|
60
|
+
"".tap do |str|
|
61
|
+
sets.each do |set|
|
62
|
+
str << set_to_str(set, format: format)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def set_to_str(set, lev: 0, format: :txt)
|
68
|
+
raise "Required Array. Given: #{set.class}" unless set.is_a?(Array)
|
69
|
+
"".tap do |str|
|
70
|
+
entry = set.shift
|
71
|
+
str << "#{" " * lev}#{(lev > 0)? "+-#{lev}- " : ""}#{entry.name} (#{entry.external_id}|#{entry.email}|#{entry.id})\n"
|
72
|
+
str << set_to_str(set, lev: lev + 1, format: format) unless !set || set.empty?
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
@@ -16,10 +16,9 @@ class Eco::API::UseCases::DefaultCases::CodesToTagsCase < Eco::API::Common::Load
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def main(session, options, usecase)
|
19
|
-
|
20
|
-
@options = options
|
19
|
+
options[:end_get] = false
|
20
|
+
@session = session; @options = options
|
21
21
|
codes_to_tags
|
22
|
-
exit
|
23
22
|
end
|
24
23
|
|
25
24
|
private
|
@@ -2,13 +2,23 @@ class Eco::API::UseCases::DefaultCases::ResetLandingPageCase < Eco::API::Common:
|
|
2
2
|
name "reset-landing-page"
|
3
3
|
type :transform
|
4
4
|
|
5
|
+
attr_reader :session, :options
|
6
|
+
|
5
7
|
def main(people, session, options, usecase)
|
8
|
+
@session = session; @options = options
|
6
9
|
update = session.new_job("main", "update", :update, usecase, :core)
|
7
10
|
|
8
11
|
people.users.each do |user|
|
9
|
-
user.account.landing_page_id =
|
12
|
+
user.account.landing_page_id = page_id
|
10
13
|
update.add(user)
|
11
14
|
end
|
12
15
|
end
|
13
16
|
|
17
|
+
private
|
18
|
+
|
19
|
+
def page_id
|
20
|
+
options[:page_id]
|
21
|
+
end
|
22
|
+
|
23
|
+
|
14
24
|
end
|
@@ -59,7 +59,6 @@ class Eco::API::UseCases::DefaultCases::RestoreDBCase < Eco::API::Common::Loader
|
|
59
59
|
dst.policy_group_ids = src.policy_group_ids unless options.dig(:exclude, :policy_groups)
|
60
60
|
|
61
61
|
unless options.dig(:exclude, :abilities)
|
62
|
-
dst.permissions_preset = src.permissions_preset
|
63
62
|
dst.permissions_custom = src.permissions_custom
|
64
63
|
end
|
65
64
|
|
@@ -75,7 +74,7 @@ class Eco::API::UseCases::DefaultCases::RestoreDBCase < Eco::API::Common::Loader
|
|
75
74
|
dst.starred_ids = src.starred_ids
|
76
75
|
dst.landing_page_id = src.landing_page_id
|
77
76
|
end
|
78
|
-
|
77
|
+
|
79
78
|
dst&.send_invites = options[:send_invites] if options.key?(:send_invites)
|
80
79
|
end
|
81
80
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
class Eco::API::UseCases::DefaultCases::SupersCyclicIdentify < Eco::API::Common::Loaders::UseCase
|
2
|
+
name "identify-cyclic-supers"
|
3
|
+
type :export
|
4
|
+
|
5
|
+
attr_reader :session, :people, :options
|
6
|
+
|
7
|
+
def main(people, session, options, usecase)
|
8
|
+
options[:end_get] = false
|
9
|
+
@session = session; @options = options; @people = people
|
10
|
+
|
11
|
+
save!(cyclic_sets)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def cyclic_sets
|
17
|
+
Eco::API::Common::People::SupervisorHelpers.identify_cyclic_chains(people)
|
18
|
+
end
|
19
|
+
|
20
|
+
def file
|
21
|
+
@file ||= options.dig(:output, :file) || "cyclic_supers.txt"
|
22
|
+
end
|
23
|
+
|
24
|
+
def save!(data)
|
25
|
+
if data.empty?
|
26
|
+
session.logger.info("There were no cyclic supervisors identified!!")
|
27
|
+
return
|
28
|
+
end
|
29
|
+
|
30
|
+
ext = File.extname(file).downcase.delete(".")
|
31
|
+
|
32
|
+
File.open(file, "w") do |fd|
|
33
|
+
if ext == "txt"
|
34
|
+
create_file(data, file: file, format: :txt)
|
35
|
+
elsif ext == "html"
|
36
|
+
puts "html is still not supported"
|
37
|
+
exit(1)
|
38
|
+
create_file(data, file: file, format: :html)
|
39
|
+
elsif ext == "json"
|
40
|
+
puts "json is still not supported"
|
41
|
+
exit(1)
|
42
|
+
create_file(data, file: file, format: :json)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def create_file(sets, file:, format: :txt)
|
48
|
+
File.open(file, "w") do |fd|
|
49
|
+
fd << sets_to_str(sets, format: format)
|
50
|
+
end
|
51
|
+
puts "Generated file #{file}"
|
52
|
+
end
|
53
|
+
|
54
|
+
def sets_to_str(sets, format: :txt)
|
55
|
+
raise "Required Array. Given: #{sets.class}" unless sets.is_a?(Array)
|
56
|
+
"".tap do |str|
|
57
|
+
sets.each do |set|
|
58
|
+
str << set_to_str(set, format: format)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def set_to_str(set, lev: 0, format: :txt)
|
64
|
+
raise "Required Array. Given: #{set.class}" unless set.is_a?(Array)
|
65
|
+
"".tap do |str|
|
66
|
+
entry = set.shift
|
67
|
+
str << "#{" " * lev}#{(lev > 0)? "+-#{lev}- " : ""}#{entry.name} (#{entry.external_id}|#{entry.email}|#{entry.id})\n"
|
68
|
+
str << set_to_str(set, lev: lev + 1, format: format) unless !set || set.empty?
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
class Eco::API::UseCases::DefaultCases::SupersHierarchy < Eco::API::Common::Loaders::UseCase
|
2
|
+
name "supers-hierarchy"
|
3
|
+
type :export
|
4
|
+
|
5
|
+
attr_reader :session, :people, :options
|
6
|
+
|
7
|
+
def main(people, session, options, usecase)
|
8
|
+
options[:end_get] = false
|
9
|
+
@session = session; @options = options; @people = people
|
10
|
+
|
11
|
+
save!(hierarchy)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def hierarchy
|
17
|
+
Eco::API::Common::People::SupervisorHelpers.supervisors_tree(people)
|
18
|
+
end
|
19
|
+
|
20
|
+
def file
|
21
|
+
@file ||= options.dig(:output, :file) || "supers_hierarchy.txt"
|
22
|
+
end
|
23
|
+
|
24
|
+
def save!(data)
|
25
|
+
ext = File.extname(file).downcase.delete(".")
|
26
|
+
|
27
|
+
File.open(file, "w") do |fd|
|
28
|
+
if ext == "txt"
|
29
|
+
create_file(data, file: file, format: :txt)
|
30
|
+
elsif ext == "html"
|
31
|
+
puts "html is still not supported"
|
32
|
+
exit(1)
|
33
|
+
create_file(data, file: file, format: :html)
|
34
|
+
elsif ext == "json"
|
35
|
+
puts "json is still not supported"
|
36
|
+
exit(1)
|
37
|
+
create_file(data, file: file, format: :json)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def create_file(tree, file:, format: :txt)
|
43
|
+
File.open(file, "w") do |fd|
|
44
|
+
fd << tree_to_str(tree, format: format)
|
45
|
+
end
|
46
|
+
puts "Generated file #{file}"
|
47
|
+
end
|
48
|
+
|
49
|
+
def tree_to_str(tree, lev: 0, format: :txt)
|
50
|
+
raise "Required Hash tree structure. Given: #{tree.class}" unless tree.is_a?(Hash)
|
51
|
+
"".tap do |str|
|
52
|
+
tree.each do |entry, subtree|
|
53
|
+
str << "#{" " * lev}#{(lev > 0)? "+-#{lev}- " : ""}#{entry.name} (#{entry.external_id}|#{entry.email}|#{entry.id})\n"
|
54
|
+
str << tree_to_str(subtree, lev: lev + 1, format: format) unless !subtree || subtree.empty?
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
@@ -2,44 +2,122 @@ 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
|
+
options[:end_get] = false
|
9
|
+
@session = session; @options = options; @people = people
|
10
|
+
|
6
11
|
unless people && !people.empty?
|
7
12
|
session.logger.warn("No source people to create the file... aborting!")
|
8
13
|
return false
|
9
14
|
end
|
10
15
|
|
11
|
-
unless file = options[:file] || options.dig(:export, :file, :name)
|
12
|
-
session.logger.error("Destination file not specified")
|
13
|
-
return false
|
14
|
-
end
|
15
|
-
|
16
16
|
session.logger.info("going to create file: #{file}")
|
17
|
-
|
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
|
17
|
+
header = spot_header
|
36
18
|
|
19
|
+
CSV.open(file, "w") do |csv|
|
37
20
|
csv << header
|
38
21
|
people.each do |person|
|
39
|
-
csv <<
|
22
|
+
csv << to_row(person)
|
40
23
|
end
|
41
24
|
end
|
42
|
-
exit(0)
|
43
25
|
end
|
44
26
|
|
27
|
+
private
|
28
|
+
|
29
|
+
def to_row(person)
|
30
|
+
entry = to_entry_type(person)
|
31
|
+
entry.values_at(*keys(entry))
|
32
|
+
end
|
33
|
+
|
34
|
+
def spot_header
|
35
|
+
header = keys(to_entry_type(people.first))
|
36
|
+
header = yield(header) if block_given?
|
37
|
+
header = nice_header_names(header) if nice_header_names?
|
38
|
+
header
|
39
|
+
end
|
40
|
+
|
41
|
+
def keys(entry)
|
42
|
+
entry.keys - ["freemium", "send_invites"]
|
43
|
+
end
|
44
|
+
|
45
|
+
def nice_header_names?
|
46
|
+
options.dig(:nice_header) || options.dig(:export, :options, :nice_header)
|
47
|
+
end
|
48
|
+
|
49
|
+
def nice_header_names(header)
|
50
|
+
name_maps = session.schema.fields_by_alt_id.each_with_object({}) do |(alt_id, fld), mappings|
|
51
|
+
mappings[alt_id] = fld.name
|
52
|
+
end.merge({
|
53
|
+
"policy_group_ids" => "User Group(s)",
|
54
|
+
"email" => "Email",
|
55
|
+
"name" => "Name",
|
56
|
+
"supervisor_id" => "Manager ID",
|
57
|
+
"filter_tags" => "Locations",
|
58
|
+
"default_tag" => "Default Location",
|
59
|
+
"id" => "ecoPortal ID",
|
60
|
+
"external_id" => "Reference ID (ext_id)",
|
61
|
+
"login_provider_ids" => "Login Methods",
|
62
|
+
"landing_page_id" => "Landing Page ID",
|
63
|
+
"show_sidebar" => "(pref) Sidebar Open?",
|
64
|
+
"show_shortcuts" => "(pref) Link to Registers?",
|
65
|
+
"show_coming_soon" => "(pref) Coming Soon List?",
|
66
|
+
"show_recently_visited_forms" => "(pref) Recently Visited Forms List?",
|
67
|
+
"show_tasks" => "(pref) Tasks List?",
|
68
|
+
"show_task_bubbles" => "(pref) Task Count Bubbles",
|
69
|
+
"kiosk_enabled" => "Kiosk User?",
|
70
|
+
"freemium" => "Freemium User?",
|
71
|
+
"files" => "(able) on Files",
|
72
|
+
"reports" => "(able) on Report Structures",
|
73
|
+
"data" => "(able) on Data (hours, datasets)",
|
74
|
+
"organization" => "(able) on Organization Config",
|
75
|
+
"pages" => "(able) on Page/Entries",
|
76
|
+
"page_editor" => "(able) page Editor Level",
|
77
|
+
"registers" => "(able) on Registers",
|
78
|
+
"tasks" => "(able) on Tasks",
|
79
|
+
"person_core" => "(able) on People",
|
80
|
+
"person_core_create" => "(able) Create People?",
|
81
|
+
"person_core_edit" => "(able) Edit People?",
|
82
|
+
"person_details" => "(able) on People Schema Details",
|
83
|
+
"person_account" => "(able) on Users",
|
84
|
+
"person_abilities" => "(able) on Users' Abilities",
|
85
|
+
"custom_files" => "(min) on Files",
|
86
|
+
"custom_reports" => "(min) on Report Structures",
|
87
|
+
"custom_data" => "(min) on Data (hours, datasets)",
|
88
|
+
"custom_organization" => "(min) on Organization Config",
|
89
|
+
"custom_pages" => "(min) on Page/Entries",
|
90
|
+
"custom_page_editor" => "(min) page Editor Level",
|
91
|
+
"custom_registers" => "(min) on Registers",
|
92
|
+
"custom_tasks" => "(min) on Tasks",
|
93
|
+
"custom_person_core" => "(min) on People",
|
94
|
+
"custom_person_core_create" => "(min) Create People?",
|
95
|
+
"custom_person_core_edit" => "(min) Edit People?",
|
96
|
+
"custom_person_details" => "(min) on People Schema Details",
|
97
|
+
"custom_person_account" => "(min) on Users",
|
98
|
+
"custom_person_abilities" => "(min) on Users' Abilities"
|
99
|
+
})
|
100
|
+
header.map {|name| name_maps[name] ? name_maps[name] : name}
|
101
|
+
end
|
102
|
+
|
103
|
+
def to_entry_type(person)
|
104
|
+
session.new_entry(person, dependencies: deps).yield_self do |person_entry|
|
105
|
+
options.dig(:export, :options, :internal_names) ? person_entry.mapped_entry : person_entry.external_entry
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def deps
|
110
|
+
@deps ||= {"supervisor_id" => {people: people}}
|
111
|
+
end
|
112
|
+
|
113
|
+
def file
|
114
|
+
@file ||= (options[:file] || options.dig(:export, :file, :name)).tap do |filename|
|
115
|
+
unless filename
|
116
|
+
session.logger.error("Destination file not specified")
|
117
|
+
return false
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
|
45
123
|
end
|