eco-helpers 2.0.12 → 2.0.17

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +80 -73
  3. data/eco-helpers.gemspec +6 -4
  4. data/lib/eco-helpers.rb +1 -0
  5. data/lib/eco/api/common/base_loader.rb +14 -0
  6. data/lib/eco/api/common/loaders/use_case.rb +1 -1
  7. data/lib/eco/api/common/people/default_parsers/date_parser.rb +11 -1
  8. data/lib/eco/api/common/people/default_parsers/login_providers_parser.rb +1 -1
  9. data/lib/eco/api/common/people/default_parsers/policy_groups_parser.rb +11 -11
  10. data/lib/eco/api/common/people/person_entry.rb +9 -2
  11. data/lib/eco/api/common/people/supervisor_helpers.rb +27 -0
  12. data/lib/eco/api/common/session/file_manager.rb +2 -2
  13. data/lib/eco/api/common/session/mailer.rb +0 -1
  14. data/lib/eco/api/common/session/s3_uploader.rb +0 -1
  15. data/lib/eco/api/common/session/sftp.rb +0 -1
  16. data/lib/eco/api/error.rb +5 -3
  17. data/lib/eco/api/microcases.rb +3 -1
  18. data/lib/eco/api/microcases/append_usergroups.rb +0 -1
  19. data/lib/eco/api/microcases/people_cache.rb +2 -2
  20. data/lib/eco/api/microcases/people_load.rb +2 -2
  21. data/lib/eco/api/microcases/people_refresh.rb +2 -2
  22. data/lib/eco/api/microcases/people_search.rb +6 -6
  23. data/lib/eco/api/microcases/preserve_default_tag.rb +23 -0
  24. data/lib/eco/api/microcases/preserve_filter_tags.rb +28 -0
  25. data/lib/eco/api/microcases/preserve_policy_groups.rb +30 -0
  26. data/lib/eco/api/microcases/set_account.rb +0 -1
  27. data/lib/eco/api/organization.rb +1 -0
  28. data/lib/eco/api/organization/people.rb +7 -0
  29. data/lib/eco/api/organization/people_analytics.rb +60 -0
  30. data/lib/eco/api/organization/presets_factory.rb +116 -93
  31. data/lib/eco/api/organization/presets_integrity.json +58 -0
  32. data/lib/eco/api/organization/presets_values.json +5 -4
  33. data/lib/eco/api/policies/default_policies/99_user_access_policy.rb +0 -30
  34. data/lib/eco/api/session.rb +1 -20
  35. data/lib/eco/api/session/batch.rb +42 -10
  36. data/lib/eco/api/session/batch/job.rb +3 -0
  37. data/lib/eco/api/session/config.rb +16 -15
  38. data/lib/eco/api/session/config/api.rb +4 -0
  39. data/lib/eco/api/session/config/apis.rb +14 -0
  40. data/lib/eco/api/session/config/files.rb +7 -0
  41. data/lib/eco/api/session/config/people.rb +3 -19
  42. data/lib/eco/api/usecases.rb +2 -0
  43. data/lib/eco/api/usecases/default_cases.rb +4 -1
  44. data/lib/eco/api/usecases/default_cases/abstract_policygroup_abilities_case.rb +161 -0
  45. data/lib/eco/api/usecases/default_cases/analyse_people_case.rb +76 -0
  46. data/lib/eco/api/usecases/default_cases/codes_to_tags_case.rb +2 -3
  47. data/lib/eco/api/usecases/default_cases/hris_case.rb +14 -8
  48. data/lib/eco/api/usecases/default_cases/reset_landing_page_case.rb +11 -1
  49. data/lib/eco/api/usecases/default_cases/restore_db_case.rb +1 -2
  50. data/lib/eco/api/usecases/default_cases/supers_cyclic_identify_case.rb +72 -0
  51. data/lib/eco/api/usecases/default_cases/supers_hierarchy_case.rb +59 -0
  52. data/lib/eco/api/usecases/default_cases/to_csv_case.rb +104 -26
  53. data/lib/eco/api/usecases/default_cases/to_csv_detailed_case.rb +62 -36
  54. data/lib/eco/cli.rb +0 -10
  55. data/lib/eco/cli/config/default/options.rb +19 -17
  56. data/lib/eco/cli/config/default/people_filters.rb +3 -3
  57. data/lib/eco/cli/config/default/usecases.rb +77 -25
  58. data/lib/eco/cli/config/default/workflow.rb +6 -1
  59. data/lib/eco/cli/config/help.rb +1 -0
  60. data/lib/eco/cli/config/options_set.rb +106 -13
  61. data/lib/eco/cli/config/use_cases.rb +33 -33
  62. data/lib/eco/cli/scripting/args_helpers.rb +30 -3
  63. data/lib/eco/data.rb +1 -0
  64. data/lib/eco/data/crypto/encryption.rb +3 -3
  65. data/lib/eco/data/files/directory.rb +28 -20
  66. data/lib/eco/data/files/helpers.rb +6 -4
  67. data/lib/eco/data/fuzzy_match.rb +119 -0
  68. data/lib/eco/data/fuzzy_match/array_helpers.rb +75 -0
  69. data/lib/eco/data/fuzzy_match/chars_position_score.rb +37 -0
  70. data/lib/eco/data/fuzzy_match/ngrams_score.rb +73 -0
  71. data/lib/eco/data/fuzzy_match/pairing.rb +102 -0
  72. data/lib/eco/data/fuzzy_match/result.rb +67 -0
  73. data/lib/eco/data/fuzzy_match/results.rb +53 -0
  74. data/lib/eco/data/fuzzy_match/score.rb +44 -0
  75. data/lib/eco/data/fuzzy_match/stop_words.rb +35 -0
  76. data/lib/eco/data/fuzzy_match/string_helpers.rb +69 -0
  77. data/lib/eco/version.rb +1 -1
  78. metadata +86 -10
  79. data/lib/eco/api/microcases/refresh_abilities.rb +0 -19
  80. data/lib/eco/api/organization/presets_reference.json +0 -59
  81. data/lib/eco/api/usecases/default_cases/refresh_abilities_case.rb +0 -30
@@ -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,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 = nil
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
- 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
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 << session.new_entry(person, dependencies: deps).external_entry.values
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
@@ -1,53 +1,79 @@
1
- class Eco::API::UseCases::DefaultCases::ToCsvDetailedCase < Eco::API::Common::Loaders::UseCase
1
+ class Eco::API::UseCases::DefaultCases::ToCsvDetailedCase < Eco::API::UseCases::DefaultCases::ToCsvCase
2
2
  name "to-csv-detailed"
3
3
  type :export
4
4
 
5
- def main(people, session, options, usecase)
6
- unless people && !people.empty?
7
- session.logger.warn("No source people to create the file... aborting!")
8
- return false
9
- end
5
+ private
6
+
7
+ def to_row(person)
8
+ entry = to_entry_type(person)
9
+ data = entry.values_at(*keys(entry))
10
+ data << person.subordinates
11
+ data << person_supervisor(person)
12
+ data += user_abilities(person)
13
+ data += user_permissions_custom(person) if options.dig(:export, :options, :permissions_custom)
14
+ account = person.account
15
+ data << account&.landing_page_id
16
+ data += user_preferences(person)
17
+ data
18
+ end
10
19
 
11
- unless file = options[:file] || options.dig(:export, :file, :name)
12
- session.logger.error("Destination file not specified")
13
- return false
20
+ def person_supervisor(person)
21
+ session.micro.with_supervisor(person.supervisor_id, people) do |supervisor|
22
+ return supervisor ? supervisor.name : ""
14
23
  end
24
+ end
15
25
 
16
- login_providers = session.login_providers
17
- abilities = session.presets_factory.keys
26
+ def user_abilities(person)
27
+ account_abilities = (person.account && person.account.permissions_merged) || {}
28
+ abilities.map {|key| account_abilities[key] || "no access"}
29
+ end
18
30
 
19
- session.logger.info("going to create file: #{file}")
20
- CSV.open(file, "w") do |csv|
21
- deps = {"supervisor_id" => {people: people}}
31
+ def user_permissions_custom(person)
32
+ account_abilities = (person.account && person.account.permissions_custom) || {}
33
+ abilities.map {|key| account_abilities[key] || "no access"}
34
+ end
22
35
 
23
- person_model = people.first
24
- person_entry = session.new_entry(person_model, dependencies: deps)
25
- header = person_entry.external_entry.keys
26
- header += ["Subordinates"]
27
- header += ["Supervisor Name"]
28
- header += abilities
29
- header += ["Landing Page"]
36
+ def user_preferences(person)
37
+ user_preferences = (person.account && person.account.preferences&.doc) || {}
38
+ preferences.map {|key| user_preferences[key] || false}
39
+ end
30
40
 
31
- csv << header
32
- people.each do |person|
33
- data = session.new_entry(person, dependencies: deps).external_entry.values
41
+ def spot_header
42
+ super do |header|
43
+ header << "Subordinates"
44
+ header << "Supervisor Name"
45
+ header += abilities_header
46
+ header += abilities_header("custom") if options.dig(:export, :options, :permissions_custom)
47
+ header << "Landing Page"
48
+ header += preferences
49
+ header
50
+ end
51
+ end
34
52
 
35
- data.push(person.subordinates)
36
- session.micro.with_supervisor(person.supervisor_id, people) do |supervisor|
37
- data.push supervisor ? supervisor.name : ""
38
- end
53
+ def keys(entry)
54
+ super(entry) + ["freemium"]
55
+ end
39
56
 
40
- person_abilities = (person.account && person.account.permissions_custom) || {}
41
- data += abilities.map {|key| person_abilities[key] || "no access"}
57
+ def login_providers
58
+ session.login_providers
59
+ end
42
60
 
43
- if person.account && landing_id = person.account.landing_page_id
44
- data.push(landing_id)
45
- end
61
+ def abilities
62
+ @abilities ||= session.presets_factory.keys
63
+ end
46
64
 
47
- csv << data
48
- end
65
+ def abilities_header(prefix = nil)
66
+ abilities.map do |key|
67
+ prefix ? "#{prefix}_#{key}" : key
49
68
  end
50
- exit(0)
69
+ end
70
+
71
+ def preferences
72
+ @preferences ||= [
73
+ "show_sidebar", "show_shortcuts", "show_coming_soon", "show_recently_visited_forms",
74
+ "show_tasks", "show_task_bubbles",
75
+ "kiosk_enabled"
76
+ ]
51
77
  end
52
78
 
53
79
  end