eco-helpers 2.5.2 → 2.5.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +62 -2
  3. data/eco-helpers.gemspec +2 -2
  4. data/lib/eco/api/common/loaders/use_case.rb +0 -2
  5. data/lib/eco/api/common/people/person_entry_attribute_mapper.rb +0 -2
  6. data/lib/eco/api/common/session/logger.rb +22 -77
  7. data/lib/eco/api/microcases/with_each.rb +0 -1
  8. data/lib/eco/api/organization/tag_tree.rb +64 -15
  9. data/lib/eco/api/session/config/tagtree.rb +32 -10
  10. data/lib/eco/api/session/config/workflow.rb +0 -1
  11. data/lib/eco/api/session/config.rb +6 -2
  12. data/lib/eco/api/session.rb +2 -2
  13. data/lib/eco/api/usecases/default_cases/abstract_policygroup_abilities_case.rb +2 -3
  14. data/lib/eco/api/usecases/default_cases/analyse_people_case.rb +2 -3
  15. data/lib/eco/api/usecases/default_cases/append_usergroups_case.rb +0 -1
  16. data/lib/eco/api/usecases/default_cases/change_email_case.rb +1 -2
  17. data/lib/eco/api/usecases/default_cases/clean_unknown_tags_case.rb +0 -5
  18. data/lib/eco/api/usecases/default_cases/clear_abilities_case.rb +2 -2
  19. data/lib/eco/api/usecases/default_cases/codes_to_tags_case.rb +5 -7
  20. data/lib/eco/api/usecases/default_cases/create_case.rb +0 -5
  21. data/lib/eco/api/usecases/default_cases/create_details_case.rb +0 -5
  22. data/lib/eco/api/usecases/default_cases/create_details_with_supervisor_case.rb +0 -5
  23. data/lib/eco/api/usecases/default_cases/csv_to_tree_case/helper.rb +1 -1
  24. data/lib/eco/api/usecases/default_cases/csv_to_tree_case.rb +0 -4
  25. data/lib/eco/api/usecases/default_cases/delete_sync_case.rb +2 -4
  26. data/lib/eco/api/usecases/default_cases/delete_trans_case.rb +2 -3
  27. data/lib/eco/api/usecases/default_cases/email_as_id_case.rb +0 -1
  28. data/lib/eco/api/usecases/default_cases/entries_to_csv_case.rb +0 -4
  29. data/lib/eco/api/usecases/default_cases/hris_case.rb +2 -3
  30. data/lib/eco/api/usecases/default_cases/new_email_case.rb +0 -2
  31. data/lib/eco/api/usecases/default_cases/new_id_case.rb +0 -2
  32. data/lib/eco/api/usecases/default_cases/org_data_convert_case.rb +0 -5
  33. data/lib/eco/api/usecases/default_cases/refresh_case.rb +0 -1
  34. data/lib/eco/api/usecases/default_cases/reinvite_sync_case.rb +1 -3
  35. data/lib/eco/api/usecases/default_cases/reinvite_trans_case.rb +2 -2
  36. data/lib/eco/api/usecases/default_cases/remove_account_sync_case.rb +1 -2
  37. data/lib/eco/api/usecases/default_cases/remove_account_trans_case.rb +2 -3
  38. data/lib/eco/api/usecases/default_cases/reset_landing_page_case.rb +1 -7
  39. data/lib/eco/api/usecases/default_cases/restore_db_case.rb +0 -10
  40. data/lib/eco/api/usecases/default_cases/set_default_tag_case.rb +0 -1
  41. data/lib/eco/api/usecases/default_cases/set_supervisor_case.rb +0 -1
  42. data/lib/eco/api/usecases/default_cases/supers_cyclic_identify_case.rb +2 -3
  43. data/lib/eco/api/usecases/default_cases/supers_hierarchy_case.rb +2 -3
  44. data/lib/eco/api/usecases/default_cases/switch_supervisor_case.rb +2 -4
  45. data/lib/eco/api/usecases/default_cases/tagtree_case.rb +0 -2
  46. data/lib/eco/api/usecases/default_cases/to_csv_case.rb +4 -5
  47. data/lib/eco/api/usecases/default_cases/to_csv_detailed_case.rb +0 -1
  48. data/lib/eco/api/usecases/default_cases/transfer_account_case.rb +0 -2
  49. data/lib/eco/api/usecases/default_cases/update_case.rb +0 -2
  50. data/lib/eco/api/usecases/default_cases/update_details_case.rb +0 -2
  51. data/lib/eco/api/usecases/default_cases/upsert_case.rb +0 -4
  52. data/lib/eco/api/usecases/graphql/base.rb +6 -18
  53. data/lib/eco/api/usecases/graphql/helpers/base/case_env.rb +15 -0
  54. data/lib/eco/api/usecases/graphql/helpers/base.rb +23 -0
  55. data/lib/eco/api/usecases/graphql/helpers/location/base.rb +87 -0
  56. data/lib/eco/api/usecases/graphql/helpers/location/command/result.rb +69 -0
  57. data/lib/eco/api/usecases/graphql/helpers/location/command/results.rb +126 -0
  58. data/lib/eco/api/usecases/graphql/helpers/location/command.rb +92 -0
  59. data/lib/eco/api/usecases/graphql/helpers/location.rb +7 -0
  60. data/lib/eco/api/usecases/graphql/helpers.rb +2 -1
  61. data/lib/eco/api/usecases/graphql/samples/location/command/dsl.rb +54 -0
  62. data/lib/eco/api/usecases/graphql/samples/location/command/results.rb +125 -0
  63. data/lib/eco/api/usecases/graphql/samples/location/command.rb +10 -0
  64. data/lib/eco/api/usecases/graphql/samples/location/dsl.rb +6 -0
  65. data/lib/eco/api/usecases/graphql/samples/location.rb +10 -0
  66. data/lib/eco/api/usecases/graphql/samples.rb +6 -0
  67. data/lib/eco/api/usecases/graphql/utils/sftp.rb +74 -0
  68. data/lib/eco/api/usecases/graphql/utils.rb +6 -0
  69. data/lib/eco/api/usecases/graphql.rb +3 -1
  70. data/lib/eco/api/usecases/ooze_cases/export_register_case.rb +0 -1
  71. data/lib/eco/api/usecases/ooze_samples/ooze_base_case.rb +0 -2
  72. data/lib/eco/api/usecases/ooze_samples/register_migration_case.rb +0 -2
  73. data/lib/eco/api/usecases/use_case.rb +2 -2
  74. data/lib/eco/cli/config/default/workflow.rb +2 -4
  75. data/lib/eco/cli/scripting/args_helpers.rb +0 -2
  76. data/lib/eco/csv/table.rb +39 -3
  77. data/lib/eco/data/files/helpers.rb +4 -3
  78. data/lib/eco/data/hashes/array_diff.rb +21 -61
  79. data/lib/eco/data/hashes/diff_meta.rb +52 -0
  80. data/lib/eco/data/hashes/diff_result.rb +36 -25
  81. data/lib/eco/data/hashes.rb +1 -0
  82. data/lib/eco/data/locations/convert.rb +92 -0
  83. data/lib/eco/data/locations/dsl.rb +35 -0
  84. data/lib/eco/data/locations/node_base/builder.rb +26 -0
  85. data/lib/eco/data/locations/node_base/csv_convert.rb +57 -0
  86. data/lib/eco/data/locations/node_base/parsing.rb +30 -0
  87. data/lib/eco/data/locations/node_base/serial.rb +26 -0
  88. data/lib/eco/data/locations/node_base/tag_validations.rb +52 -0
  89. data/lib/eco/data/locations/node_base/treeify.rb +150 -0
  90. data/lib/eco/data/locations/node_base.rb +48 -0
  91. data/lib/eco/data/locations/node_diff/accessors.rb +46 -0
  92. data/lib/eco/data/locations/node_diff/nodes_diff.rb +90 -0
  93. data/lib/eco/data/locations/node_diff/selectors.rb +20 -0
  94. data/lib/eco/data/locations/node_diff.rb +55 -0
  95. data/lib/eco/data/locations/node_level/builder.rb +6 -0
  96. data/lib/eco/data/locations/node_level/cleaner.rb +74 -0
  97. data/lib/eco/data/locations/node_level/parsing.rb +63 -0
  98. data/lib/eco/data/locations/node_level/serial.rb +37 -0
  99. data/lib/eco/data/locations/node_level.rb +153 -0
  100. data/lib/eco/data/locations/node_plain/builder.rb +6 -0
  101. data/lib/eco/data/locations/node_plain/parsing.rb +36 -0
  102. data/lib/eco/data/locations/node_plain/serial.rb +14 -0
  103. data/lib/eco/data/locations/node_plain.rb +31 -0
  104. data/lib/eco/data/locations.rb +13 -0
  105. data/lib/eco/data.rb +1 -0
  106. data/lib/eco/language/auxiliar_logger.rb +9 -1
  107. data/lib/eco/language/basic_logger.rb +74 -0
  108. data/lib/eco/language.rb +2 -1
  109. data/lib/eco/version.rb +1 -1
  110. metadata +45 -8
  111. data/lib/eco/api/usecases/default_cases/new_id_case0.rb +0 -14
  112. data/lib/eco/api/usecases/graphql/helpers/locations/commands.rb +0 -4
  113. data/lib/eco/api/usecases/graphql/helpers/locations.rb +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 140086432682ed765773ca3f1fabcdd46606c04507d6652d94f3df68233cc7ec
4
- data.tar.gz: fb68c2d6ab307711c45660cf169303b3e79f7555eb5199a6ed33455030def28a
3
+ metadata.gz: 444bec4cd18402a38eff718340932ca7d72c9959b865805964b0ec9787d94636
4
+ data.tar.gz: 97291544f70b525781d81f168ffc86c1d960151e53535a540ac1b7824b9eaf28
5
5
  SHA512:
6
- metadata.gz: 96ab04ce3bdb34c994becd6a6223cbae38a95aa8bd2309906c047a39a0476b689cf76d7538556c650a826eae5f31cd807c351f0fd6f765cb5efb39857022981f
7
- data.tar.gz: 0365d9f8777250747eef5580df8531bc07a77dfa7d46c7aaefd29898e44f2450f62fcad8c64f97976d1ae1f7526bfa5e8dcf34eeaa1c4d36777e3e0beff43dff
6
+ metadata.gz: 02360de987395d801aa1b1fb659dd4b6011c317a21058be33c3283b3a2856c69db519baf6eb85a022f7a2c7c4e826861b108c2cf09aefad3ca57b32d53b45c72
7
+ data.tar.gz: 402c880d701446c072f6534d4df35b2a104704dc79480e37e5033101df63a8b10baa25257911af1cc84994efe05744b15c608798dbc1637ad268811ca2d7d926
data/CHANGELOG.md CHANGED
@@ -1,13 +1,73 @@
1
1
  # Change Log
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
- ## [2.5.2] - 2023-06-xx
4
+ ## [2.5.5] - 2023-07-xx
5
+
6
+ ### Added
7
+ ### Changed
8
+ ### Fixed
9
+
10
+ ## [2.5.4] - 2023-07-27
11
+
12
+ ### Added
13
+ - SFTP case helpers: `Eco::API::UseCases::GraphQL::Utils::Sftp`
14
+ - `Eco::Data::Locations::NodeDiff` and `Eco::Data::Locations::NodeDiff::NodeDiffs`
15
+ - Aim to identify changes in the locations structure
16
+
17
+ ### Changed
18
+ - Some internal tidy up in `Eco::API::UseCases::GraphQL`
19
+
20
+ ## [2.5.3] - 2023-07-19
21
+
22
+ ### Added
23
+ - _GraphQL base case_ for **locations structure update**.
24
+ - Refer to `Eco::API::UseCases::GraphQL::Samples::LocationCommands`
25
+ - See also `Eco::API::UseCases::GraphQL`. **Added** `Helpers` and `Samples`
26
+ - `Eco::Data::Locations` helpers
27
+ - **Converters**: it offers a `DSL` (see `Eco::Data::Locations::DSL`) manage as input/output:
28
+ 1. CSV files with locations in two basic formats (list of nodes and hierarchy of locations)
29
+ 2. This comes with integrity checkers to ensure the input data files are correct (warnings)
30
+ 3. It also allows to convert to/from an organization locations structure and csv files.
31
+ - Making generic the helpers of `Eco::API::UseCases::DefaultCases::CsvToTree`
32
+ - The prospect is to move to the new/reviewed helpers at some stage (so remove the old helpers)
33
+ - This comes with a series of **converters** and **parsers** to allow two basic forms of input/output:
34
+ - CSV with list of nodes (`id`, `name`, `parent_id`)
35
+ - CSV of the actual tree (each column is one level of the tree)
36
+ - `Eco::API::Organization::TagTree` - **added/improved methods**
37
+ - **added** shortcuts: `parent_id`, `parent_name`
38
+ - **added** filters: `select`, `reject`
39
+ - **improved** `as_json`:
40
+ 1. new parameter `include_children`
41
+ 2. Hash keys | Header names to `HEADER` column
42
+ - **added** `as_nodes_json` to obtain a plain list (rather than hierarchical `as_json`)
43
+ - `Eco::CSV::Table`
44
+ - **added** `#add_index_column` to numerate the rows in a new column
45
+ - **improved** `#add_column` with new parameter `pos`
46
+ - **added** `#nil_blank_cells` and `#nil_blank_cells!`
47
+ - `Eco::Language::BasicLogger` brief extensible logger.
48
+
49
+ ### Changed
50
+ - Refactored `Eco::API::Session::Logger` inheriting from `Eco::Language::BasicLogger`
51
+
52
+ ### Fixed
53
+ - Live tree retrieval. Allow to specify locations structure `id`, `kargs` & `block`.
54
+ - `Eco::API::Session#live_tree` allow `id`, `kargs` & `block`, **fix** pass `include_archived`
55
+ - `Eco::API::Session::Config#live_tree` allow `id`, `kargs` & `block`
56
+ - When `id` is given, it uses `tagtree_config#live_tree_get`
57
+ - **fixed** neither `kargs` nor `include_archived` where defined
58
+ - `Eco::API::Session::Config::Tagtree` methods
59
+ - `#live_trees` allow `kargs`
60
+ - `#live_tree_get` **added**: it does not memoize
61
+ - `#live_tree` allow `id` and `kargs`
62
+ - **fixed** `include_archived` nodes should not be redirected to `live_trees` as in the latter this parameter has a different meaning (it refers to archived structures).
63
+ - **Important note**: the `ecoportal-api-graphql` gem, at the moment always retrieves archived nodes. This makes the `include_archived` argument non-functional. However, at some stage this will be changed and everything should be sorted out by then.
64
+
65
+ ## [2.5.2] - 2023-06-23
5
66
 
6
67
  ### Added
7
68
  - `Eco::API::Session::Config::Workflow#exit_handle`
8
69
  - Allows to define a callback on `SystemExit` (`exit` call).
9
70
 
10
- ### Changed
11
71
  ### Fixed
12
72
  - `Eco::API::Session::Config::Workflow` on `SystemExit` preserve original exit `status` value (i.e. `0`, `1`)
13
73
  - It was changing an `exit 1` to be an `exit 0`
data/eco-helpers.gemspec CHANGED
@@ -31,8 +31,8 @@ Gem::Specification.new do |spec|
31
31
  spec.add_development_dependency "redcarpet", ">= 3.5.1", "< 4"
32
32
 
33
33
  spec.add_dependency 'ecoportal-api', '>= 0.9.4', '< 0.10'
34
- spec.add_dependency 'ecoportal-api-v2', '>= 1.1.2', '< 1.2'
35
- spec.add_dependency 'ecoportal-api-graphql', '>= 0.3.7', '< 0.4'
34
+ spec.add_dependency 'ecoportal-api-v2', '>= 1.1.3', '< 1.2'
35
+ spec.add_dependency 'ecoportal-api-graphql', '>= 0.3.8', '< 0.4'
36
36
  spec.add_dependency 'aws-sdk-s3', '>= 1.83.0', '< 2'
37
37
  spec.add_dependency 'aws-sdk-ses', '>= 1.36.0', '< 2'
38
38
  spec.add_dependency 'dotenv', '>= 2.7.6', '< 3'
@@ -3,7 +3,6 @@ module Eco
3
3
  module Common
4
4
  module Loaders
5
5
  class UseCase < Eco::API::Common::Loaders::CaseBase
6
-
7
6
  class << self
8
7
  # @return [Symbol] the `type` of usecase (i.e. `:sync`, `:transform`, `:import`, `:other`)
9
8
  def type(value = nil)
@@ -34,7 +33,6 @@ module Eco
34
33
  def type
35
34
  self.class.type
36
35
  end
37
-
38
36
  end
39
37
  end
40
38
  end
@@ -2,7 +2,6 @@ module Eco
2
2
  module API
3
3
  module Common
4
4
  module People
5
-
6
5
  # @attr_reader direct_attrs [Array<String>] only those internal attributes present in the person entry that do **not** have an internal/external name mapping.
7
6
  class PersonEntryAttributeMapper
8
7
  @@cached_warnings = {}
@@ -266,7 +265,6 @@ module Eco
266
265
  logger.fatal(msg)
267
266
  raise msg
268
267
  end
269
-
270
268
  end
271
269
  end
272
270
  end
@@ -2,111 +2,56 @@ module Eco
2
2
  module API
3
3
  module Common
4
4
  module Session
5
- class Logger
6
- DEFAULT_TIMESTAMP_PATTERN = '%Y-%m-%dT%H:%M:%S'
5
+ class Logger < Eco::Language::BasicLogger
6
+ TIMESTAMP_PATTERN = '%Y-%m-%dT%H:%M:%S'
7
7
 
8
8
  attr_reader :cache
9
9
 
10
- def initialize(console_level: nil, file_level: ::Logger::DEBUG, log_file: nil, timestamp_console: false, enviro: nil)
10
+ def initialize(file_level: ::Logger::DEBUG, log_file: nil, enviro: nil, **kargs)
11
+ super(**kargs)
11
12
  raise "Required Environment object (enviro:). Given: #{enviro}" if enviro && !enviro.is_a?(Eco::API::Common::Session::Environment)
12
13
  @enviro = enviro
13
14
  @cache = Logger::Cache.new
14
15
 
15
- timestamp_console = fetch_timestamp_console(timestamp_console)
16
- @console_logger = ::Logger.new(STDOUT).tap do |_logger|
17
- _logger.formatter = proc do |severity, datetime, progname, msg|
18
- str_timestamp = timestamp_console ? "#{datetime.strftime(DEFAULT_TIMESTAMP_PATTERN)} >" : ""
19
- "#{severity.to_s[0]}: #{str_timestamp} #{msg}\n"
20
- end
21
- _logger.level = fetch_console_level(console_level)
22
- end
23
-
24
16
  if log_file = fetch_log_file(log_file)
25
- @file_logger = ::Logger.new(log_file).tap do |_logger|
26
- _logger.formatter = proc do |severity, datetime, progname, msg|
27
- "#{severity.to_s[0]}: #{datetime.strftime(DEFAULT_TIMESTAMP_PATTERN)} > #{msg}\n".tap do |formatted|
28
- cache.add(severity, datetime, msg, formatted)
29
- end
17
+ loggers[:file] = ::Logger.new(log_file).tap do |logger|
18
+ logger.formatter = format_proc(console: false) do |severity, datetime, msg, formatted_msg|
19
+ cache.add(severity, datetime, msg, formatted_msg)
30
20
  end
31
- _logger.level = fetch_file_level(file_level)
21
+ logger.level = file_level
32
22
  end
33
23
  end
34
- end
35
-
36
- def level=(value)
37
- @console_logger.level = value
38
- end
39
-
40
- def debug(*args, &block)
41
- log(:debug, *args, &block)
42
- end
43
-
44
- def info(*args, &block)
45
- log(:info, *args, &block)
46
- end
47
-
48
- def warn(*args, &block)
49
- return log(:warn, *args, &block)
50
- end
51
-
52
- def error(*args, &block)
53
- return log(:error, *args, &block)
54
- end
55
24
 
56
- def fatal(*args, &block)
57
- return log(:fatal, *args, &block)
25
+ if_config(:timestamp_console) { |value| self.timestamp = value }
26
+ if_config(:console_level) { |value| self.level = value }
27
+ if_config(:file_level) { |value| self.file_level = value }
58
28
  end
59
29
 
60
- def unknown(msg, &block)
61
- return log(:unknown, *args, &block)
62
- end
63
-
64
- def << (msg)
65
- @console_logger << msg unless !@console_logger
66
- @file_logger << msg unless !@file_logger
67
- end
68
-
69
- def close()
70
- @console_logger.close unless !@console_logger
71
- @file_logger.close unless !@file_logger
72
- end
73
-
74
- def add(*args)
75
- @console_logger.add(*args) unless !@console_logger
76
- @file_logger.add(*args) unless !@file_logger
30
+ def file_level=(value)
31
+ loggers[:file]&.level = value
77
32
  end
78
33
 
79
34
  private
80
35
 
81
- def log(level, *args, &block)
82
- @console_logger.send(level, *args, &block) unless !@console_logger
83
- @file_logger.send(level, *args, &block) unless !@file_logger
84
- end
85
-
86
- def config
87
- @enviro.config || {}
88
- end
89
-
90
- def fetch_timestamp_console(value)
91
- value || config.logger.timestamp_console
36
+ def config(attr)
37
+ return nil unless cnf = @enviro&.config&.logger
38
+ cnf.send(attr) if cnf.respond_to?(attr)
92
39
  end
93
40
 
94
- def fetch_console_level(value)
95
- value || config.logger.console_level || ::Logger::INFO
96
- end
97
-
98
- def fetch_file_level(value)
99
- value || config.logger.file_level || ::Logger::DEBUG
41
+ def if_config(attr)
42
+ unless (value = config(attr)).nil?
43
+ yield(value) if block_given?
44
+ value
45
+ end
100
46
  end
101
47
 
102
48
  def fetch_log_file(log_file)
103
- if log_file ||= config.logger.file
49
+ if log_file ||= config(:file)
104
50
  log_file = @enviro.file_manager.dir.file(log_file) if @enviro
105
51
  FileManager.create_directory(log_file, includes_file: true)
106
52
  end
107
53
  log_file
108
54
  end
109
-
110
55
  end
111
56
  end
112
57
  end
@@ -86,7 +86,6 @@ module Eco
86
86
  end
87
87
  end
88
88
  end
89
-
90
89
  end
91
90
  end
92
91
  end
@@ -2,7 +2,15 @@ module Eco
2
2
  module API
3
3
  module Organization
4
4
  # Provides helpers to deal with tagtrees.
5
+ # @note that currenlty the parsing assumes top level to be array.
6
+ # This does not allow to capture the `name` and `id` of the locations
7
+ # structure itself into the json storing model.
5
8
  class TagTree
9
+ HEADER = [
10
+ 'id', 'name', 'weight', 'parent_id',
11
+ 'archived', 'archived_token'
12
+ ].freeze
13
+
6
14
  attr_accessor :id
7
15
  alias_method :tag, :id
8
16
  attr_accessor :name, :weight
@@ -82,6 +90,27 @@ module Eco
82
90
  all_nodes.each(&block)
83
91
  end
84
92
 
93
+ # @note rejected nodes will not include their children nodes
94
+ # @return [Array<TagTree>] plain list of nodes
95
+ def select(when_is: true, &block)
96
+ raise ArgumentError, "Missing block" unless block_given?
97
+ [].tap do |out_nodes|
98
+ selected = false
99
+ selected = (yield(self) == when_is) unless top?
100
+ out_nodes.push(self) if selected
101
+ next unless selected || top?
102
+ nodes.each do |nd|
103
+ out_nodes.concat(nd.select(when_is: when_is, &block))
104
+ end
105
+ end
106
+ end
107
+
108
+ # @note rejected nodes will not include their children nodes
109
+ # @return [Array<TagTree>] plain list of nodes
110
+ def reject(&block)
111
+ select(when_is: false, &block)
112
+ end
113
+
85
114
  # All actual nodes of this tree
86
115
  # @note order is that of the parent to child relationships
87
116
  # @return [Array<TagTree>]
@@ -91,8 +120,8 @@ module Eco
91
120
  out_nodes.push(self)
92
121
  yield(self) if block_given?
93
122
  end
94
- nodes.each do |node|
95
- out_nodes.concat(node.all_nodes(&block))
123
+ nodes.each do |nd|
124
+ out_nodes.concat(nd.all_nodes(&block))
96
125
  end
97
126
  end
98
127
  end
@@ -109,6 +138,16 @@ module Eco
109
138
  end
110
139
  end
111
140
 
141
+ # @return [String] the `id` of the parent (unless we are on a top level node)
142
+ def parent_id
143
+ parent.id unless parent.top?
144
+ end
145
+
146
+ # @return [String] the `name` of the parent (unless we are on a top level node)
147
+ def parent_name
148
+ parent.name unless parent.top?
149
+ end
150
+
112
151
  # @return [Array] with the differences
113
152
  def diff(tagtree, differences: {}, level: 0, **options)
114
153
  require 'hashdiff'
@@ -119,22 +158,32 @@ module Eco
119
158
  depth == -1
120
159
  end
121
160
 
122
- # @return [Array[Hash]] where `Hash` is a `node` `{"tag" => TAG, "nodes": Array[Hash]}`
123
- def as_json
124
- nodes_json = nodes.map {|node| node.as_json}
161
+ # Returns a tree of Hashes form nested via `nodes` (or just a list of hash nodes)
162
+ # @yield [node_json, node] block for custom output json model
163
+ # @yiledreturn [Hash] the custom json model.
164
+ # @include_children [Boolean] whether it should return a tree hash or just a list of hash nodes.
165
+ # @return [Array[Hash]] where `Hash` is a `node` (i.e. `{"tag" => TAG, "nodes": Array[Hash]}`)
166
+ def as_json(include_children: true, &block)
167
+ return [] if top? && !include_children
168
+ children_json = nodes.map {|nd| nd.as_json(include_children: true, &block)} if include_children
169
+
125
170
  if top?
126
- nodes_json
171
+ children_json
127
172
  else
128
- {
129
- "id" => tag,
130
- "archived" => archived,
131
- "archived_token" => archived_token,
132
- "weight" => weight,
133
- "nodes" => nodes_json
134
- }
173
+ values = [id, name, weight, parent_id, archived, archived_token]
174
+ node_json = self.class::HEADER.zip(values).to_h
175
+ node_json["nodes"] = children_json if include_children
176
+ node_json = yield(node_json, self) if block_given?
177
+ node_json
135
178
  end
136
179
  end
137
180
 
181
+ # Returns a plain list form of hash nodes.
182
+ # @return [Array[Hash]] where `Hash` is a plain `node`
183
+ def as_nodes_json(&block)
184
+ all_nodes.map {|nd| nd.as_json(include_children: false, &block)}
185
+ end
186
+
138
187
  # @return [Boolean] `true` if there are tags in the node, `false` otherwise.
139
188
  def empty?
140
189
  count <= 1
@@ -148,8 +197,8 @@ module Eco
148
197
  # @return [Integer] the highest `depth` of all the children.
149
198
  def total_depth
150
199
  @total_depth ||= if has_children?
151
- deepest_node = nodes.max_by do |node|
152
- node.total_depth
200
+ deepest_node = nodes.max_by do |nd|
201
+ nd.total_depth
153
202
  end
154
203
  deepest_node.total_depth
155
204
  else
@@ -20,33 +20,55 @@ module Eco
20
20
  end
21
21
 
22
22
  # Among all the locations structures it selects the one with more location nodes
23
- def live_tree(enviro: nil, include_archived: false, &block)
23
+ # If `id` is provided, it only retrieves this locations structure.
24
+ def live_tree(id: nil, enviro: nil, include_archived: false, **kargs, &block)
24
25
  return @live_tree if instance_variable_defined?(:@live_tree) && @live_tree.enviro == enviro
25
- trees = live_trees(enviro: enviro, include_archived: include_archived, &block)
26
- @live_tree = trees.reject do |tree|
27
- tree.empty?
28
- end.max do |a,b|
29
- a.count <=> b.count
26
+ if id
27
+ args = {id: id, enviro: enviro, include_archived: include_archived}.merge(kargs)
28
+ @live_tree = live_tree_get(**args, &block)
29
+ else
30
+ # note that `include_archived` nodes is NOT the same as including archived structures
31
+ # => In `live_tree` the paramter refers to nodes
32
+ trees = live_trees(enviro: enviro, &block)
33
+ @live_tree = trees.reject do |tree|
34
+ tree.empty?
35
+ end.max do |a,b|
36
+ a.count <=> b.count
37
+ end
30
38
  end.tap do |tree|
31
39
  if tree
32
- msg ="Using LIVE LOCATIONS Structure: '#{tree.name}' (#{tree.count} nodes)"
40
+ msg = "Using LIVE LOCATIONS Structure: '#{tree.name}' (#{tree.count} nodes)"
33
41
  session_logger.info(msg)
34
42
  end
35
43
  end
36
44
  end
37
45
 
46
+ # Gets a single locations structure
47
+ # @note it does not memoize
48
+ def live_tree_get(id: nil, enviro: nil, include_archived: false, **kargs, &block)
49
+ return nil unless apis.active_api.version_available?(:graphql)
50
+ return nil unless graphql = apis.api(version: :graphql)
51
+ #kargs = { includeArchived: include_archived }.merge(kargs).slice(:includeArchived)
52
+ # For now, this endpoint only accepts `id` as a parameter. It is pending to
53
+ # expose further parameters via query
54
+ return nil unless tree = graphql.currentOrganization.locationStructure(id: id, &block)
55
+ args = { enviro: enviro, id: tree.id, name: tree.name }
56
+ Eco::API::Organization::TagTree.new(tree.treeify, **args)
57
+ end
58
+
38
59
  # Retrieves all the location structures of the organisation
39
- def live_trees(enviro: nil, include_archived: false, &block)
60
+ def live_trees(enviro: nil, include_archived: false, **kargs, &block)
40
61
  [].tap do |eco_trees|
41
62
  next unless apis.active_api.version_available?(:graphql)
42
63
  next unless graphql = apis.api(version: :graphql)
43
64
  kargs = {
44
65
  includeArchived: include_archived,
45
66
  includeUnpublished: false
46
- }
67
+ }.merge(kargs).slice(:includeArchived, :includeUnpublished)
68
+
47
69
  next unless trees = graphql.currentOrganization.locationStructures(**kargs, &block)
48
70
  trees.each do |tree|
49
- args = { enviro: enviro, id: tree.id, name: tree.name}
71
+ args = { enviro: enviro, id: tree.id, name: tree.name }
50
72
  eco_tree = Eco::API::Organization::TagTree.new(tree.treeify, **args)
51
73
  eco_trees.push(eco_tree)
52
74
  end
@@ -290,7 +290,6 @@ module Eco
290
290
  self.class.validate_stage(key)
291
291
  @stages[key] ||= self.class.workflow_class(key).new(key, _parent: self, config: config)
292
292
  end
293
-
294
293
  end
295
294
  end
296
295
  end
@@ -243,8 +243,12 @@ module Eco
243
243
  # It obtains the first of the live tagtree in the org
244
244
  # @note it requires graphql connection configuration parameters
245
245
  # @return [Eco::API::Organization::TagTree]
246
- def live_tree(enviro: nil)
247
- @live_tree ||= tagtree_config.live_tree(enviro: enviro)
246
+ def live_tree(id: nil, enviro: nil, **kargs, &block)
247
+ if id
248
+ tagtree_config.live_tree_get(id: id, enviro: enviro, **kargs, &block)
249
+ else
250
+ tagtree_config.live_tree(enviro: enviro, **kargs, &block)
251
+ end
248
252
  end
249
253
 
250
254
  # @return [Eco::API::Organization::PolicyGroups]
@@ -45,8 +45,8 @@ module Eco
45
45
  end
46
46
 
47
47
  # @see Eco::API::Session::Config#live_tree
48
- def live_tree(include_archived: false, &block)
49
- config.live_tree(enviro: enviro, &block)
48
+ def live_tree(id: nil, include_archived: false, **kargs, &block)
49
+ config.live_tree(id: nil, include_archived: include_archived, enviro: enviro, **kargs, &block)
50
50
  end
51
51
 
52
52
  # @see Eco::API::Session::Config#schemas
@@ -2,11 +2,11 @@ class Eco::API::UseCases::DefaultCases::AbstractPolicyGroupAbilities < Eco::API:
2
2
  name "abstract-policygroup-abilities"
3
3
  type :export
4
4
 
5
- attr_reader :session, :people, :options
5
+ attr_reader :people
6
6
 
7
7
  def main(people, session, options, usecase)
8
8
  options[:end_get] = false
9
- @session = session; @options = options; @people = people
9
+ @people = people
10
10
 
11
11
  generate_csv!
12
12
  end
@@ -157,5 +157,4 @@ class Eco::API::UseCases::DefaultCases::AbstractPolicyGroupAbilities < Eco::API:
157
157
  def percent(num, total)
158
158
  (100 * num.to_f / total).round(2)
159
159
  end
160
-
161
160
  end
@@ -2,11 +2,11 @@ class Eco::API::UseCases::DefaultCases::AnalysePeople < Eco::API::Common::Loader
2
2
  name "analyse-people"
3
3
  type :export
4
4
 
5
- attr_reader :session, :people, :options
5
+ attr_reader :people
6
6
 
7
7
  def main(people, session, options, usecase)
8
8
  options[:end_get] = false
9
- @session = session; @options = options; @people = people
9
+ @people = people
10
10
 
11
11
  case
12
12
  when case_options[:identify_duplicates]
@@ -219,5 +219,4 @@ class Eco::API::UseCases::DefaultCases::AnalysePeople < Eco::API::Common::Loader
219
219
  raise "Review your expression. Cannot recognize '#{part}' as part of '#{obj.class}'"
220
220
  end
221
221
  end
222
-
223
222
  end
@@ -11,5 +11,4 @@ class Eco::API::UseCases::DefaultCases::AppendUsergroupsCase < Eco::API::Common:
11
11
  micro.append_usergroups(entry, person, options)
12
12
  end
13
13
  end
14
-
15
14
  end
@@ -1,7 +1,7 @@
1
1
  class Eco::API::UseCases::DefaultCases::ChangeEMailCase < Eco::API::Common::Loaders::UseCase
2
2
  name "change-email"
3
3
  type :sync
4
-
4
+
5
5
  # Target people with non-up-to-date emails will be updated to the new email
6
6
  def main(entries, people, session, options, usecase)
7
7
  micro = session.micro
@@ -24,5 +24,4 @@ class Eco::API::UseCases::DefaultCases::ChangeEMailCase < Eco::API::Common::Load
24
24
  end
25
25
  end
26
26
  end
27
-
28
27
  end
@@ -13,11 +13,7 @@ class Eco::API::UseCases::DefaultCases::CleanUnknownTags < Eco::API::Common::Loa
13
13
  "POLICY", "IDEA", "REPORTS"
14
14
  ]
15
15
 
16
- attr_reader :session, :options
17
-
18
16
  def main(people, session, options, usecase)
19
- @session = session; @options = options
20
-
21
17
  update = session.new_job("main", "update", :update, usecase)
22
18
  people.each do |person|
23
19
  unknown_tags = person.filter_tags.select {|tag| !tag?(tag)}
@@ -75,5 +71,4 @@ class Eco::API::UseCases::DefaultCases::CleanUnknownTags < Eco::API::Common::Loa
75
71
  def clean_register_tags?
76
72
  !options.dig(:usecase, :include_register_tags)
77
73
  end
78
-
79
74
  end
@@ -3,12 +3,12 @@ class Eco::API::UseCases::DefaultCases::ClearAbilitiesTransCase < Eco::API::Comm
3
3
  type :transform
4
4
 
5
5
  def main(people, session, options, usecase)
6
- clear_abilities(people.users, session, options, usecase)
6
+ clear_abilities(people.users)
7
7
  end
8
8
 
9
9
  private
10
10
 
11
- def clear_abilities(users, session, options, usecase)
11
+ def clear_abilities(users)
12
12
  update = session.new_job("main", "clear-abilities", :update, usecase, :account)
13
13
  users.each do |person|
14
14
  person.account.permissions_custom = nil_abilities.dup
@@ -17,7 +17,6 @@ class Eco::API::UseCases::DefaultCases::CodesToTagsCase < Eco::API::Common::Load
17
17
 
18
18
  def main(session, options, usecase)
19
19
  options[:end_get] = false
20
- @session = session; @options = options
21
20
  codes_to_tags
22
21
  end
23
22
 
@@ -26,26 +25,26 @@ class Eco::API::UseCases::DefaultCases::CodesToTagsCase < Eco::API::Common::Load
26
25
  def to_tag(code)
27
26
  if mapper.external?(code)
28
27
  mapper.to_internal(code)
29
- elsif @session.tagtree.tag?(code)
28
+ elsif session.tagtree.tag?(code)
30
29
  code.upcase
31
30
  else
32
- @session.logger.warn("Unknown Location Code: '#{code}'")
31
+ logger.warn("Unknown Location Code: '#{code}'")
33
32
  nil
34
33
  end
35
34
  end
36
35
 
37
36
  def mapper
38
- unless mapper ||= @session.config.location_codes && @session.config.locations_mapper
37
+ unless mapper ||= session.config.location_codes && session.config.locations_mapper
39
38
  raise "No filter_tags parser, nor location mappings are present"
40
39
  end
41
40
  end
42
41
 
43
42
  def codes_column
44
- @codes_column ||= @options.dig(:other, :file, :codes_column)
43
+ @codes_column ||= options.dig(:other, :file, :codes_column)
45
44
  end
46
45
 
47
46
  def input_file
48
- @input_file ||= @options.dig(:other, :file, :name)
47
+ @input_file ||= options.dig(:other, :file, :name)
49
48
  end
50
49
 
51
50
  def output_file
@@ -55,5 +54,4 @@ class Eco::API::UseCases::DefaultCases::CodesToTagsCase < Eco::API::Common::Load
55
54
  def clean_file_name(filename)
56
55
  File.basename(filename).gsub(/\s/, "")
57
56
  end
58
-
59
57
  end