eco-helpers 2.5.10 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -2
  3. data/CHANGELOG.md +64 -4
  4. data/eco-helpers.gemspec +20 -16
  5. data/lib/eco/api/common/loaders/base.rb +2 -9
  6. data/lib/eco/api/common/loaders/use_case.rb +27 -1
  7. data/lib/eco/api/common/people/default_parsers.rb +2 -2
  8. data/lib/eco/api/common/people/person_entry.rb +3 -0
  9. data/lib/eco/api/common/people/person_entry_attribute_mapper.rb +111 -16
  10. data/lib/eco/api/common/session/base_session.rb +4 -0
  11. data/lib/eco/api/common/session/environment.rb +4 -0
  12. data/lib/eco/api/common/session/sftp.rb +1 -1
  13. data/lib/eco/api/organization/tag_tree.rb +20 -23
  14. data/lib/eco/api/session/batch/job.rb +4 -4
  15. data/lib/eco/api/session/batch/jobs.rb +2 -2
  16. data/lib/eco/api/session/batch/jobs_groups.rb +2 -2
  17. data/lib/eco/api/session/config/files.rb +2 -2
  18. data/lib/eco/api/session/config/people.rb +2 -2
  19. data/lib/eco/api/session/config/sftp.rb +4 -0
  20. data/lib/eco/api/session/config/tagtree.rb +9 -8
  21. data/lib/eco/api/session/config/workflow.rb +3 -2
  22. data/lib/eco/api/session/config.rb +7 -0
  23. data/lib/eco/api/session.rb +17 -2
  24. data/lib/eco/api/usecases/cli/dsl.rb +84 -0
  25. data/lib/eco/api/usecases/cli/option.rb +19 -0
  26. data/lib/eco/api/usecases/cli.rb +13 -0
  27. data/lib/eco/api/usecases/default/locations/cli/tagtree_extract_cli.rb +24 -0
  28. data/lib/eco/api/usecases/{default_cases → default/locations}/codes_to_tags_case.rb +1 -1
  29. data/lib/eco/api/usecases/{default_cases → default/locations}/create_tag_paths_case.rb +1 -1
  30. data/lib/eco/api/usecases/{default_cases → default/locations}/csv_to_tree_case.rb +1 -1
  31. data/lib/eco/api/usecases/default/locations/tagtree_extract_case.rb +173 -0
  32. data/lib/eco/api/usecases/default/locations.rb +15 -0
  33. data/lib/eco/api/usecases/{default_cases → default/people}/analyse_people_case.rb +1 -1
  34. data/lib/eco/api/usecases/{default_cases → default/people}/change_email_case.rb +1 -1
  35. data/lib/eco/api/usecases/default/people/clean_unknown_tags_case.rb +66 -0
  36. data/lib/eco/api/usecases/{default_cases → default/people}/clear_abilities_case.rb +1 -1
  37. data/lib/eco/api/usecases/{default_cases → default/people}/org_data_convert_case.rb +1 -1
  38. data/lib/eco/api/usecases/{default_cases → default/people}/refresh_case.rb +1 -1
  39. data/lib/eco/api/usecases/{default_cases → default/people}/reinvite_sync_case.rb +1 -1
  40. data/lib/eco/api/usecases/{default_cases → default/people}/reinvite_trans_case.rb +1 -1
  41. data/lib/eco/api/usecases/default/people/reinvite_trans_cli.rb +5 -0
  42. data/lib/eco/api/usecases/{default_cases → default/people}/restore_db_case.rb +1 -1
  43. data/lib/eco/api/usecases/{default_cases → default/people}/set_default_tag_case.rb +1 -1
  44. data/lib/eco/api/usecases/{default_cases → default/people}/supers_cyclic_identify_case.rb +1 -1
  45. data/lib/eco/api/usecases/{default_cases → default/people}/supers_hierarchy_case.rb +1 -1
  46. data/lib/eco/api/usecases/{default_cases → default/people}/switch_supervisor_case.rb +1 -1
  47. data/lib/eco/api/usecases/{default_cases → default/people}/transfer_account_case.rb +1 -1
  48. data/lib/eco/api/usecases/default/people.rb +25 -0
  49. data/lib/eco/api/usecases/default.rb +16 -0
  50. data/lib/eco/api/usecases/default_cases/samples/cli/sftp_cli.rb +46 -0
  51. data/lib/eco/api/usecases/default_cases/samples/sftp_case.rb +21 -9
  52. data/lib/eco/api/usecases/default_cases.rb +2 -30
  53. data/lib/eco/api/usecases/graphql/utils/sftp.rb +1 -1
  54. data/lib/eco/api/usecases/use_case.rb +21 -7
  55. data/lib/eco/api/usecases/use_case_chain.rb +2 -2
  56. data/lib/eco/api/usecases.rb +4 -1
  57. data/lib/eco/assets.rb +1 -3
  58. data/lib/eco/cli/config/filters/people_filters.rb +0 -1
  59. data/lib/eco/cli/config/filters.rb +2 -6
  60. data/lib/eco/cli/config/help.rb +0 -1
  61. data/lib/eco/cli/config/input.rb +0 -1
  62. data/lib/eco/cli/config/options_set.rb +3 -4
  63. data/lib/eco/cli/config/use_cases.rb +13 -6
  64. data/lib/eco/cli/config.rb +4 -5
  65. data/lib/eco/cli/scripting/args_helpers.rb +1 -1
  66. data/lib/eco/cli/scripting/argument.rb +0 -1
  67. data/lib/eco/cli/scripting/arguments.rb +0 -2
  68. data/lib/eco/cli.rb +0 -1
  69. data/lib/eco/{cli/config/default → cli_default}/input_filters.rb +0 -1
  70. data/lib/eco/{cli/config/default → cli_default}/people_filters.rb +0 -1
  71. data/lib/eco/{cli/config/default → cli_default}/usecases.rb +2 -52
  72. data/lib/eco/{cli/config/default → cli_default}/workflow.rb +3 -2
  73. data/lib/eco/cli_default.rb +13 -0
  74. data/lib/eco/csv/table.rb +0 -1
  75. data/lib/eco/data/files/encoding.rb +1 -1
  76. data/lib/eco/data/files/helpers.rb +1 -1
  77. data/lib/eco/data/locations/convert.rb +8 -4
  78. data/lib/eco/data/locations/node_base/csv_convert.rb +4 -4
  79. data/lib/eco/data/mapper.rb +6 -1
  80. data/lib/eco/version.rb +1 -1
  81. metadata +156 -79
  82. data/lib/eco/api/usecases/default_cases/abstract_policygroup_abilities_case.rb +0 -160
  83. data/lib/eco/api/usecases/default_cases/append_usergroups_case.rb +0 -14
  84. data/lib/eco/api/usecases/default_cases/clean_unknown_tags_case.rb +0 -74
  85. data/lib/eco/api/usecases/default_cases/create_details_case.rb +0 -20
  86. data/lib/eco/api/usecases/default_cases/create_details_with_supervisor_case.rb +0 -21
  87. data/lib/eco/api/usecases/default_cases/email_as_id_case.rb +0 -12
  88. data/lib/eco/api/usecases/default_cases/new_email_case.rb +0 -13
  89. data/lib/eco/api/usecases/default_cases/new_id_case.rb +0 -12
  90. data/lib/eco/api/usecases/default_cases/remove_account_sync_case.rb +0 -10
  91. data/lib/eco/api/usecases/default_cases/remove_account_trans_case.rb +0 -16
  92. data/lib/eco/api/usecases/default_cases/reset_landing_page_case.rb +0 -18
  93. data/lib/eco/api/usecases/default_cases/set_supervisor_case.rb +0 -16
  94. data/lib/eco/api/usecases/default_cases/tagtree_case.rb +0 -42
  95. data/lib/eco/api/usecases/default_cases/update_details_case.rb +0 -15
  96. data/lib/eco/cli/config/default.rb +0 -16
  97. /data/lib/eco/{cli/config/default → cli_default}/input.rb +0 -0
  98. /data/lib/eco/{cli/config/default → cli_default}/options.rb +0 -0
  99. /data/lib/eco/{cli/config/default → cli_default}/people.rb +0 -0
@@ -8,6 +8,9 @@ module Eco
8
8
 
9
9
  attr_key :file, :structure_id
10
10
 
11
+ # @note it retrieves the tree this way:
12
+ # 1. If there's a file tagtree.json file, it uses it
13
+ # 2. If no file, retrieves `structure_id` (config)
11
14
  # @param include_archived [Boolean] whether or not it should include archived nodes.
12
15
  # @return [Eco::API::Organization::TagTree]
13
16
  def scope_tree(enviro: nil, include_archived: true, raise_on_missing: true)
@@ -20,7 +23,7 @@ module Eco
20
23
 
21
24
  if tree_file = self.file
22
25
  if (tree = file_manager.load_json(tree_file)) && !tree.empty?
23
- @tagtree = Eco::API::Organization::TagTree.new(tree, enviro: enviro)
26
+ @tagtree = Eco::API::Organization::TagTree.new(tree)
24
27
  end
25
28
  elsif self.structure_id
26
29
  kargs.merge(id: self.structure_id)
@@ -36,6 +39,7 @@ module Eco
36
39
 
37
40
  # Among all the locations structures it selects the one with more location nodes
38
41
  # If `id` is provided, it only retrieves this locations structure.
42
+ # @param [enviro] used for re-caching
39
43
  def live_tree(id: nil, enviro: nil, include_archived: false, **kargs, &block)
40
44
  existing_cache = !!@live_tree
41
45
  first_load = !existing_cache
@@ -47,7 +51,6 @@ module Eco
47
51
  refresh_cache = existing_cache && !switching_target
48
52
 
49
53
  kargs = {
50
- enviro: enviro,
51
54
  includeArchivedNodes: include_archived
52
55
  }.merge(kargs)
53
56
 
@@ -81,7 +84,7 @@ module Eco
81
84
  # @note it does not memoize
82
85
  # @param include_archived [Boolean] whether or not to include archived **nodes**
83
86
  # @return [Eco::API::Organization::TagTree, NilClass]
84
- def live_tree_get(id: nil, enviro: nil, include_archived: false, **kargs, &block)
87
+ def live_tree_get(id: nil, include_archived: false, **kargs, &block)
85
88
  return nil unless apis.active_api.version_available?(:graphql)
86
89
  return nil unless graphql = apis.api(version: :graphql)
87
90
 
@@ -92,14 +95,13 @@ module Eco
92
95
 
93
96
  return nil unless tree = graphql.currentOrganization.locationStructure(**kargs, &block)
94
97
 
95
- args = { enviro: enviro, id: tree.id, name: tree.name }
96
- Eco::API::Organization::TagTree.new(tree.treeify, **args)
98
+ Eco::API::Organization::TagTree.new(tree.treeify, id: tree.id, name: tree.name)
97
99
  end
98
100
 
99
101
  # Retrieves all the location structures of the organisation
100
102
  # @param include_archived [Boolean] whether or not to include archived **nodes**
101
103
  # @return [Array<Eco::API::Organization::TagTree>]
102
- def live_trees(enviro: nil, include_archived: false, **kargs, &block)
104
+ def live_trees(include_archived: false, **kargs, &block)
103
105
  [].tap do |eco_trees|
104
106
  next unless apis.active_api.version_available?(:graphql)
105
107
  next unless graphql = apis.api(version: :graphql)
@@ -110,8 +112,7 @@ module Eco
110
112
 
111
113
  next unless trees = graphql.currentOrganization.locationStructures(**kargs, &block)
112
114
  trees.each do |tree|
113
- args = { enviro: enviro, id: tree.id, name: tree.name }
114
- eco_tree = Eco::API::Organization::TagTree.new(tree.treeify, **args)
115
+ eco_tree = Eco::API::Organization::TagTree.new(tree.treeify, id: tree.id, name: tree.name)
115
116
  eco_trees.push(eco_tree)
116
117
  end
117
118
  end
@@ -87,15 +87,16 @@ module Eco
87
87
  # @yield [stage_workflow] further _workflow_ configuration `for` the target stage `key`
88
88
  # @yieldparam stage_workflow [Eco::API::Session::Config::Workflow] the _target stage_ referred by `key`
89
89
  # @return [Eco::API::Session::Config::Workflow] the current stage object (to ease chainig).
90
- def for(key = nil)
90
+ def for(key = nil, &block)
91
91
  raise "A block should be given." unless block_given?
92
92
  if !key
93
93
  yield(self)
94
94
  else
95
- stage(key).for(&Proc.new)
95
+ stage(key).for(&block)
96
96
  end
97
97
  self
98
98
  end
99
+ alias_method :open, :for
99
100
 
100
101
  # Used in **configuration** time **to define** the **behaviour** the target (sub)stage `key`
101
102
  # @note if a `block` is provided it will **not** `yield` the target stage immediately, but when the _workflow_ reaches the stage
@@ -257,6 +257,13 @@ module Eco
257
257
  tagtree_config.live_tree(id: id, enviro: enviro, **kargs, &block)
258
258
  end
259
259
 
260
+ # Retrieves all the location structures of the organisation
261
+ # @param include_archived [Boolean] whether or not to include archived **nodes**
262
+ # @return [Array<Eco::API::Organization::TagTree>]
263
+ def live_trees(**kargs, &block)
264
+ tagtree_config.live_trees(**kargs, &block)
265
+ end
266
+
260
267
  # @return [Eco::API::Organization::PolicyGroups]
261
268
  def policy_groups
262
269
  return @policy_groups if instance_variable_defined?(:@policy_groups)
@@ -39,16 +39,31 @@ module Eco
39
39
  config.login_providers
40
40
  end
41
41
 
42
+ # @param live [Boolean] states preference of `live` tree if available over file.
43
+ # @param merge [Boolean] when in `live` mode, if mulitple trees, merge into one.
42
44
  # @see Eco::API::Session::Config#tagtree
43
- def tagtree
44
- config.tagtree(enviro: enviro)
45
+ # @see Eco::API::Session#live_trees
46
+ # @return [Eco::API::Organization::TagTree]
47
+ def tagtree(live: false, merge: false, include_archived: false, **kargs, &block)
48
+ if live && api?(version: :graphql)
49
+ return live_tree(include_archived: include_archived, **kargs, &block) unless merge
50
+ live_trees(include_archived: include_archived, **kargs, &block).inject(&:merge)
51
+ else
52
+ config.tagtree(enviro: enviro)
53
+ end
45
54
  end
46
55
 
47
56
  # @see Eco::API::Session::Config#live_tree
57
+ # @return [Eco::API::Organization::TagTree]
48
58
  def live_tree(id: nil, include_archived: false, **kargs, &block)
49
59
  config.live_tree(id: id, include_archived: include_archived, enviro: enviro, **kargs, &block)
50
60
  end
51
61
 
62
+ # @see Eco::API::Session::Config#live_tree
63
+ def live_trees(include_archived: false, **kargs, &block)
64
+ config.live_trees(include_archived: include_archived, **kargs, &block)
65
+ end
66
+
52
67
  # @see Eco::API::Session::Config#schemas
53
68
  def schemas
54
69
  config.schemas
@@ -0,0 +1,84 @@
1
+ module Eco
2
+ module API
3
+ class UseCases
4
+ class Cli
5
+ module DSL
6
+ # Links the usecase to the Cli via `option_case`
7
+ def apply!(option_case = cli_name)
8
+ cli_config_case(option_case)
9
+ apply_options(option_case)
10
+ applied!
11
+ self
12
+ end
13
+
14
+ def applied?
15
+ @applied || false
16
+ end
17
+
18
+ def applied!
19
+ @applied = true
20
+ end
21
+
22
+ attr_writer :usecase
23
+ # Unless specified, assume Cli class hangs from its case namespace
24
+ def usecase
25
+ raise "#{self} is to use to extend a class" unless self.is_a?(Class)
26
+ @usecase ||= Kernel.const_get(self.to_s.split('::')[0..-2].join('::'))
27
+ end
28
+
29
+ def description(value = nil)
30
+ @description = (value.nil? ? @description : value)
31
+ end
32
+ alias_method :desc, :description
33
+
34
+ def type
35
+ usecase.type
36
+ end
37
+
38
+ def name
39
+ usecase.name
40
+ end
41
+
42
+ # It defaults to the use case preceded by dash
43
+ def cli_name(arg_name = nil)
44
+ @cli_name = (arg_name.nil? ? @cli_name : arg_name).yield_self do |value|
45
+ value = "-#{name}" if value.nil?
46
+ value
47
+ end
48
+ end
49
+
50
+ def callback(&block)
51
+ @callback = block
52
+ end
53
+
54
+ def options
55
+ @options ||= {}
56
+ end
57
+
58
+ def add_option(arg, desc = nil, &block)
59
+ self.tap do
60
+ "Overriding option '#{arg}' on case '#{name}'" if options.key?(arg)
61
+ @options[arg] = Eco::API::UseCases::Cli::Option.new(arg, desc, &block)
62
+ end
63
+ end
64
+
65
+ private
66
+
67
+ def apply_options(option_case)
68
+ options.each do |_key, option|
69
+ option.link_case(cli_config_case(option_case))
70
+ end
71
+ end
72
+
73
+ def cli_config_case(option_case = nil)
74
+ @cli_config_case ||= usecases.add(option_case, type, desc, case_name: name, &callback)
75
+ end
76
+
77
+ def usecases(&block)
78
+ ::ASSETS.cli.config.usecases(&block)
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,19 @@
1
+ # Class to delay the case options configuration (declaration vs configuration)
2
+ class Eco::API::UseCases::Cli
3
+ class Option
4
+ attr_accessor :name, :desc, :callback
5
+
6
+ def initialize(name, desc, &block)
7
+ @name, @desc, @callback = name, desc, block
8
+ end
9
+
10
+ def dup(name: self.name, desc: self.desc, &block)
11
+ self.class.new(name, desc, &(block || callback))
12
+ end
13
+
14
+ def link_case(cli_config_case)
15
+ raise ArgumentError, "cli_config_case must have an 'add_option' method. Given: #{cli_config_case.class}" unless cli_config_case.respond_to?(:add_option)
16
+ cli_config_case.add_option(name, desc, &callback)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ # Class to integrate with the Cli a use case
2
+ module Eco
3
+ module API
4
+ class UseCases
5
+ class Cli
6
+ require_relative 'cli/dsl'
7
+ extend DSL
8
+ end
9
+ end
10
+ end
11
+ end
12
+
13
+ require_relative 'cli/option'
@@ -0,0 +1,24 @@
1
+ class Eco::API::UseCases::Default::Locations::TagtreeExtract
2
+ # Class to define the CLI integration of a usecase anywhere it suits.
3
+ class Cli < Eco::API::UseCases::Cli
4
+ desc "Exports the tagtree in a specific format"
5
+
6
+ add_option("-include-archived", "Whether the archived nodes should be included") do |options|
7
+ options.deep_merge!(output: {include: {archived: true}})
8
+ end
9
+
10
+ add_option("-format", "Kind of extract (list | json | nodes | csv_tree | excel_tree | excel_nodes )") do |options|
11
+ format = SCR.get_arg("-format", with_param: true)
12
+ options.deep_merge!(output: {format: format})
13
+ end
14
+
15
+ add_option("-node-attrs", "Attributes to be dumped (i.e. name|id ). Default: id") do |options|
16
+ attrs = SCR.get_arg("-node-attrs", with_param: true)
17
+ options.deep_merge!(output: {attrs: attrs.split('|').map(&:to_sym)})
18
+ end
19
+
20
+ add_option("-with-ancestors", "Include ancestors in tree csv/excel_tree") do |options|
21
+ options.deep_merge!(output: {include: {ancestors: true}})
22
+ end
23
+ end
24
+ end
@@ -1,4 +1,4 @@
1
- class Eco::API::UseCases::DefaultCases::CodesToTagsCase < Eco::API::Common::Loaders::UseCase
1
+ class Eco::API::UseCases::Default::Locations::CodesToTagsCase < Eco::API::Common::Loaders::UseCase
2
2
  name "codes-to-tags-from"
3
3
  type :other
4
4
 
@@ -1,4 +1,4 @@
1
- class Eco::API::UseCases::DefaultCases::TagPaths < Eco::API::Common::Loaders::UseCase
1
+ class Eco::API::UseCases::Default::Locations::TagPaths < Eco::API::Common::Loaders::UseCase
2
2
  name "create-tag-paths"
3
3
  type :other
4
4
 
@@ -1,4 +1,4 @@
1
- class Eco::API::UseCases::DefaultCases::CsvToTree < Eco::API::Common::Loaders::UseCase
1
+ class Eco::API::UseCases::Default::Locations::CsvToTree < Eco::API::Common::Loaders::UseCase
2
2
  name "csv-to-tree"
3
3
  type :other
4
4
 
@@ -0,0 +1,173 @@
1
+ # Use case to export an org tree into some of the offered forms.
2
+ class Eco::API::UseCases::Default::Locations::TagtreeExtract < Eco::API::UseCases::GraphQL::Samples::Location
3
+ require_relative 'cli/tagtree_extract_cli'
4
+ #cli self::Cli
5
+
6
+ name "export-tree"
7
+ type :other
8
+
9
+ include Eco::Data::Files
10
+
11
+ OUT_FOLDER = "sftp"
12
+ OUT_TIME_FORMAT = '%Y%m%dT%H%M%S'
13
+ OUT_FILENAME = "live_tree"
14
+
15
+ def process
16
+ case format
17
+ when :excel_tree, :excel_nodes
18
+ excel(output_filename) do |workbook|
19
+ tag_trees.each do |tree|
20
+ excel_sheet(workbook, tree.name.gsub(/\s+/, "_"), header: format == :excel_nodes) do |sheet|
21
+ tree_extract(tree).each_with_index do |row, idx|
22
+ sheet.append_row(row)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ when :list, :nodes, :csv_tree, :json
28
+ tag_trees.each do |tree|
29
+ file(output_filename(tree.name.gsub(/\s+/, "_"))) do |fd|
30
+ fd << tree_extract(tree)
31
+ end
32
+ end
33
+ else
34
+ log(:error) { "Unknown selected output format '#{format}'. Abort..." }
35
+ exit 1
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def str_node_attrs
42
+ options.dig(:output, :attrs) || [:id]
43
+ end
44
+
45
+ def tree_extract(tree)
46
+ case format
47
+ when :list
48
+ to_indented_list(tree)
49
+ when :csv_tree
50
+ with_ancestors(csv_tree(tree, attrs: str_node_attrs)).to_csv
51
+ when :excel_tree
52
+ with_ancestors(csv_tree(tree, attrs: str_node_attrs)).to_a
53
+ when :nodes
54
+ csv_list(tree).to_csv
55
+ when :excel_nodes
56
+ csv_list(tree).to_a
57
+ when :json
58
+ hash_tree(tree).to_json
59
+ else
60
+ log(:error) { "Unsupported or must use a different function for '#{format}'. Aboart..."}
61
+ exit 1
62
+ end
63
+ rescue StandardError => err
64
+ log(:error) { "Something went wrong whene extracting '#{tree.name}':\n • #{err}" }
65
+ exit 1
66
+ end
67
+
68
+ def with_ancestors(csv)
69
+ return csv unless include_ancestors?
70
+ # TODO: transform table so it includes previous row's ancestors up to the node level
71
+ csv
72
+ end
73
+
74
+ def format
75
+ options.dig(:output, :format)&.to_sym || :list
76
+ end
77
+
78
+ def output_file_format
79
+ case format
80
+ when :list; 'txt'
81
+ when :nodes; 'csv'
82
+ when :csv_tree; 'csv'
83
+ when :json; 'json'
84
+ when :excel_tree; 'xlsx'
85
+ when :excel_nodes; 'xlsx'
86
+ else
87
+ 'txt'
88
+ end
89
+ end
90
+
91
+ def tag_trees
92
+ @tag_trees ||= session.live_trees(include_archived: include_archived?).reject do |tree|
93
+ tree.empty?.tap do |rejected|
94
+ log(:warn) { "Tree '#{tree.name}' does NOT have location nodes. Skipping..." } if rejected
95
+ end
96
+ end
97
+ end
98
+
99
+ def include_ancestors?
100
+ options.dit(:output, :include, :ancestors)
101
+ end
102
+
103
+ def include_archived?
104
+ options.dig(:output, :include, :archived)
105
+ end
106
+
107
+ def output_filename(name = self.class::OUT_FILENAME)
108
+ File.join(output_folder, "#{timestamp}_#{config.active_enviro}_#{name}.#{output_file_format}")
109
+ end
110
+
111
+ def output_folder
112
+ "#{config.active_enviro}/#{self.class::OUT_FOLDER}"
113
+ end
114
+
115
+ def timestamp(date = Time.now)
116
+ date.strftime(self.class::OUT_TIME_FORMAT)
117
+ end
118
+
119
+ # Transforms the input `tree` into a String list of indented nodes
120
+ def to_indented_list(tree, level: 0, attrs: str_node_attrs, indent: " ")
121
+ ''.tap do |result|
122
+ out_str = nil
123
+ sublevel = tree.top?? 0 : level + 1
124
+ str_ary = tree.nodes.map { |subtree| to_indented_list(subtree, level: sublevel) }
125
+ out_str = str_ary.join("\n") unless str_ary.empty?
126
+
127
+ unless tree.top?
128
+ node_name = tree.as_json(include_children: false).values_at(*attrs.map(&:to_s)).join(" ## ")
129
+ out_head = "#{indent * level}#{node_name}"
130
+ out_str = out_str ? "#{out_head}\n#{out_str}" : out_head
131
+ end
132
+ result << out_str
133
+ end
134
+ end
135
+
136
+ def csv(filename, header = [])
137
+ CSV.open(filename, "w") do |csv|
138
+ csv << header unless header.empty?
139
+ yield(csv)
140
+ end
141
+ ensure
142
+ log(:info) { "Created file: #{filename}" }
143
+ end
144
+
145
+ def file(filename)
146
+ File.open(filename, "w") do |fd|
147
+ yield(fd)
148
+ end
149
+ ensure
150
+ log(:info) { "Created file: #{filename}" }
151
+ end
152
+
153
+ def excel(filename)
154
+ require 'fast_excel'
155
+ FastExcel.open(filename, constant_memory: true).tap do |workbook|
156
+ yield(workbook)
157
+ workbook.close
158
+ end
159
+ log(:info) { "Created file: #{filename}" }
160
+ end
161
+
162
+ def excel_sheet(workbook, name, header: true)
163
+ #unless sheet = workbook.get_worksheet_by_name(name)
164
+ sheet = workbook.add_worksheet(name)
165
+ #end
166
+ sheet.auto_width = true
167
+ yield(sheet)
168
+ if header
169
+ sheet.set_row(0, 30, workbook.bold_format)
170
+ sheet.freeze_panes(1, 0)
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,15 @@
1
+ module Eco
2
+ module API
3
+ class UseCases
4
+ class Default
5
+ module Locations
6
+ end
7
+ end
8
+ end
9
+ end
10
+ end
11
+
12
+ require_relative 'locations/codes_to_tags_case'
13
+ require_relative 'locations/create_tag_paths_case'
14
+ require_relative 'locations/csv_to_tree_case'
15
+ require_relative 'locations/tagtree_extract_case'
@@ -1,4 +1,4 @@
1
- class Eco::API::UseCases::DefaultCases::AnalysePeople < Eco::API::Common::Loaders::UseCase
1
+ class Eco::API::UseCases::Default::People::Analyse < Eco::API::Common::Loaders::UseCase
2
2
  name "analyse-people"
3
3
  type :export
4
4
 
@@ -1,4 +1,4 @@
1
- class Eco::API::UseCases::DefaultCases::ChangeEMailCase < Eco::API::Common::Loaders::UseCase
1
+ class Eco::API::UseCases::Default::People::ChangeEMailCase < Eco::API::Common::Loaders::UseCase
2
2
  name "change-email"
3
3
  type :sync
4
4
 
@@ -0,0 +1,66 @@
1
+ class Eco::API::UseCases::Default::People::CleanUnknownTags < Eco::API::Common::Loaders::UseCase
2
+ name "clean-unknown-tags"
3
+ type :transform
4
+
5
+ REGISTER_TAGS = [
6
+ "EVENT", "INJURY", "RISK", "CONTRACTOR", "PERMIT",
7
+ "AUDIT", "JSEA",
8
+ "TRAINING", "INDUCTION",
9
+ "MEETING", "PPE", "CHEMICAL",
10
+ "PLANT", "ASSET",
11
+ "POLICY", "IDEA", "REPORTS"
12
+ ]
13
+
14
+ def main(people, session, options, usecase)
15
+ update = session.new_job("main", "update", :update, usecase)
16
+ people.each do |person|
17
+ unknown_tags = person.filter_tags.reject { |tag| tag?(tag) }
18
+ person.filter_tags -= unknown_tags
19
+ removed_tag!(*unknown_tags)
20
+ if (tag = default_tag(person)) && !tag?(tag)
21
+ removed_tag!(tag)
22
+ micro.refresh_default_tag(person.entry, person, options)
23
+ end
24
+ update.add(person)
25
+ end
26
+
27
+ log(:info) {
28
+ msg = "Here list of the #{removed_tags.count} removed locations..."
29
+ msg + "\n • " + removed_tags.sort.join("\n • ")
30
+ }
31
+ end
32
+
33
+ private
34
+
35
+ def default_tag(person)
36
+ return nil unless account = person.account
37
+ account.default_tag
38
+ end
39
+
40
+ def register_tags
41
+ @register_tags ||= self.class::REGISTER_TAGS.compact.map(&:upcase)
42
+ end
43
+
44
+ def removed_tag!(*tags)
45
+ @removed_tags = removed_tags | tags
46
+ end
47
+
48
+ def removed_tags
49
+ @removed_tags ||= []
50
+ end
51
+
52
+ def tag?(value)
53
+ return false if value.nil?
54
+ return true if tagtree.tag?(value)
55
+ return false if clean_register_tags?
56
+ register_tags.any? { |reg| value.upcase == reg }
57
+ end
58
+
59
+ def tagtree
60
+ @tagtree ||= session.tagtree(live: true, merge: true)
61
+ end
62
+
63
+ def clean_register_tags?
64
+ options.dig(:usecase, :clear_register_tags)
65
+ end
66
+ end
@@ -1,4 +1,4 @@
1
- class Eco::API::UseCases::DefaultCases::ClearAbilitiesTransCase < Eco::API::Common::Loaders::UseCase
1
+ class Eco::API::UseCases::Default::People::ClearAbilitiesTransCase < Eco::API::Common::Loaders::UseCase
2
2
  name "clear-abilities"
3
3
  type :transform
4
4
 
@@ -1,4 +1,4 @@
1
- class Eco::API::UseCases::DefaultCases::OrgDataConvertCase < Eco::API::Common::Loaders::UseCase
1
+ class Eco::API::UseCases::Default::People::OrgDataConvertCase < Eco::API::Common::Loaders::UseCase
2
2
  name "org-data-convert"
3
3
  type :import
4
4
 
@@ -1,4 +1,4 @@
1
- class Eco::API::UseCases::DefaultCases::RefreshCase < Eco::API::Common::Loaders::UseCase
1
+ class Eco::API::UseCases::Default::People::RefreshCase < Eco::API::Common::Loaders::UseCase
2
2
  name "refresh"
3
3
  type :transform
4
4
 
@@ -1,4 +1,4 @@
1
- class Eco::API::UseCases::DefaultCases::ReinviteSyncCase < Eco::API::UseCases::DefaultCases::ReinviteTransCase
1
+ class Eco::API::UseCases::Default::People::ReinviteSyncCase < Eco::API::UseCases::Default::People::ReinviteTransCase
2
2
  name "reinvite"
3
3
  type :sync
4
4
 
@@ -1,4 +1,4 @@
1
- class Eco::API::UseCases::DefaultCases::ReinviteTransCase < Eco::API::Common::Loaders::UseCase
1
+ class Eco::API::UseCases::Default::People::ReinviteTransCase < Eco::API::Common::Loaders::UseCase
2
2
  name "reinvite"
3
3
  type :transform
4
4
 
@@ -0,0 +1,5 @@
1
+ class Eco::API::UseCases::Default::People::ReinviteTransCase
2
+ class Cli < Eco::API::UseCases::Cli
3
+
4
+ end
5
+ end
@@ -1,4 +1,4 @@
1
- class Eco::API::UseCases::DefaultCases::RestoreDBCase < Eco::API::Common::Loaders::UseCase
1
+ class Eco::API::UseCases::Default::People::RestoreDBCase < Eco::API::Common::Loaders::UseCase
2
2
  name "restore-db"
3
3
  type :sync
4
4
 
@@ -1,4 +1,4 @@
1
- class Eco::API::UseCases::DefaultCases::SetDefaultTagCase < Eco::API::Common::Loaders::UseCase
1
+ class Eco::API::UseCases::Default::People::SetDefaultTagCase < Eco::API::Common::Loaders::UseCase
2
2
  name "set-default-tag"
3
3
  type :transform
4
4
 
@@ -1,4 +1,4 @@
1
- class Eco::API::UseCases::DefaultCases::SupersCyclicIdentify < Eco::API::Common::Loaders::UseCase
1
+ class Eco::API::UseCases::Default::People::SupersCyclicIdentify < Eco::API::Common::Loaders::UseCase
2
2
  name "identify-cyclic-supers"
3
3
  type :export
4
4
 
@@ -1,4 +1,4 @@
1
- class Eco::API::UseCases::DefaultCases::SupersHierarchy < Eco::API::Common::Loaders::UseCase
1
+ class Eco::API::UseCases::Default::People::SupersHierarchy < Eco::API::Common::Loaders::UseCase
2
2
  name "supers-hierarchy"
3
3
  type :export
4
4
 
@@ -1,4 +1,4 @@
1
- class Eco::API::UseCases::DefaultCases::SwitchSupervisorCase < Eco::API::Common::Loaders::UseCase
1
+ class Eco::API::UseCases::Default::People::SwitchSupervisorCase < Eco::API::Common::Loaders::UseCase
2
2
  name "switch-supervisor"
3
3
  type :transform
4
4
 
@@ -1,4 +1,4 @@
1
- class Eco::API::UseCases::DefaultCases::TransferAccountCase < Eco::API::Common::Loaders::UseCase
1
+ class Eco::API::UseCases::Default::People::TransferAccountCase < Eco::API::Common::Loaders::UseCase
2
2
  name "transfer-account"
3
3
  type :sync
4
4