eco-helpers 2.7.11 → 2.7.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +17 -4
  3. data/Gemfile +2 -0
  4. data/eco-helpers.gemspec +17 -15
  5. data/lib/eco/api/common/session/logger.rb +12 -8
  6. data/lib/eco/api/session/batch/jobs.rb +10 -9
  7. data/lib/eco/api/usecases/default/people/{clean_unknown_tags_case.rb → amend/clean_unknown_tags_case.rb} +2 -2
  8. data/lib/eco/api/usecases/default/people/{clear_abilities_case.rb → amend/clear_abilities_case.rb} +2 -2
  9. data/lib/eco/api/usecases/default/people/{refresh_case.rb → amend/refresh_case.rb} +1 -1
  10. data/lib/eco/api/usecases/default/people/amend/reinvite_sync_case.rb +11 -0
  11. data/lib/eco/api/usecases/default/people/{reinvite_trans_case.rb → amend/reinvite_trans_case.rb} +2 -2
  12. data/lib/eco/api/usecases/default/people/amend/reinvite_trans_cli.rb +4 -0
  13. data/lib/eco/api/usecases/default/people/{restore_db_case.rb → amend/restore_db_case.rb} +1 -1
  14. data/lib/eco/api/usecases/default/people/amend.rb +11 -0
  15. data/lib/eco/api/usecases/default/people/migrate/cli/remap_tags_cli.rb +23 -0
  16. data/lib/eco/api/usecases/default/people/migrate/remap_tags_case.rb +269 -0
  17. data/lib/eco/api/usecases/default/people/migrate.rb +6 -0
  18. data/lib/eco/api/usecases/default/people/{analyse_people_case.rb → treat/analyse_people_case.rb} +1 -1
  19. data/lib/eco/api/usecases/default/people/{org_data_convert_case.rb → treat/org_data_convert_case.rb} +1 -1
  20. data/lib/eco/api/usecases/default/people/{supers_cyclic_identify_case.rb → treat/supers_cyclic_identify_case.rb} +2 -2
  21. data/lib/eco/api/usecases/default/people/{supers_hierarchy_case.rb → treat/supers_hierarchy_case.rb} +18 -17
  22. data/lib/eco/api/usecases/default/people/treat.rb +9 -0
  23. data/lib/eco/api/usecases/default/people/{change_email_case.rb → utils/change_email_case.rb} +1 -1
  24. data/lib/eco/api/usecases/default/people/{set_default_tag_case.rb → utils/set_default_tag_case.rb} +1 -1
  25. data/lib/eco/api/usecases/default/people/{switch_supervisor_case.rb → utils/switch_supervisor_case.rb} +1 -1
  26. data/lib/eco/api/usecases/default/people/{transfer_account_case.rb → utils/transfer_account_case.rb} +1 -1
  27. data/lib/eco/api/usecases/default/people/utils.rb +9 -0
  28. data/lib/eco/api/usecases/default/people.rb +4 -14
  29. data/lib/eco/api/usecases/default/utils/cli/split_csv_cli.rb +15 -0
  30. data/lib/eco/api/usecases/default/utils/split_csv_case.rb +34 -0
  31. data/lib/eco/api/usecases/default/utils.rb +12 -0
  32. data/lib/eco/api/usecases/default.rb +1 -0
  33. data/lib/eco/api/usecases/graphql/samples/location/command/service/tree_update.rb +1 -2
  34. data/lib/eco/api/usecases/graphql/samples/location/command/track_changed_ids.rb +3 -3
  35. data/lib/eco/csv/split.rb +114 -0
  36. data/lib/eco/csv/stream.rb +66 -0
  37. data/lib/eco/csv.rb +14 -0
  38. data/lib/eco/language/basic_logger.rb +7 -6
  39. data/lib/eco/version.rb +1 -1
  40. metadata +159 -120
  41. data/lib/eco/api/usecases/default/people/reinvite_sync_case.rb +0 -9
  42. data/lib/eco/api/usecases/default/people/reinvite_trans_cli.rb +0 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e3c92964baf09be5673e74f4a1762d03ce0efe159e7d6a2bc6da3839ac99f4f0
4
- data.tar.gz: 26525ccfbdbb06f348d293a50a02de644f7a0a32f3f5285537c75d8d14fe3601
3
+ metadata.gz: 260621a685a9d1426362308eb8fc12d479f7dc3c5b9702844fcd2c9d6aac90fd
4
+ data.tar.gz: 62283e9e29d539cc2f475acd4294292efb147c7f6bef2ecfb8e6841f156199e9
5
5
  SHA512:
6
- metadata.gz: 7620a74731fbfc7d17d1b21f7930df4753003a919fa9d79550083002f454c57716cceab6afec8738d9a37e5b2cd749cd42541f0913286d66c1387b7b88b27c5e
7
- data.tar.gz: 1db57df2c9a4b8e5863580524d34e655c92d5e4ddd15e6a8cacbe8b9e9e8af73ae2d3fb05fd1f4dc6de119c2ee5e20b3971b234c073910153aec5137807ef37b
6
+ metadata.gz: a45aee37bc0e81dbb89d5bfe9cf6cff2b380797b5c6f115975625206dc444be5096ee9d03a22aa7e7491132290bbc879cd4e246ae2a3eb4430bdcc058e780574
7
+ data.tar.gz: 1c0e6ab8b9f09bd34ae920945c9d99e2fdbaa3e8be2856ca2edd5f9468368e8d7ff2f4d4c4a799511b4a5cfa83eb5dfddea227e7d7f63394dba09fbc8cc8bb26
data/CHANGELOG.md CHANGED
@@ -1,18 +1,31 @@
1
1
  # Change Log
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
-
5
- ## [2.7.11] - 2024-05-xx
4
+ ## [2.7.13] - 2024-06-13
6
5
 
7
6
  ### Added
7
+ - Case `-split-csv`
8
+ - Case `-remap-tags` on people case
9
+
10
+ ### Changed
11
+ - `close_handling_tags_remap_csv` will display table on dry-run too
12
+ - See `Eco::API::UseCases::GraphQL::Samples::Location::Command::TrackChangedIds`
13
+
14
+ ### Fixed
15
+
16
+ ## [2.7.12] - 2024-05-30
17
+
18
+ ### Changed
19
+ - Decouple `Eco::API::UseCases::Default::People` namespace
20
+
21
+ ## [2.7.11] - 2024-05-27
22
+
8
23
  ### Changed\
9
24
  - `Eco::API::Common::Session::SFTP#download`
10
25
  - It now returns the local filename(s) of the downloaded files.
11
26
  - `Eco::API::UseCases::GraphQL::Utils#sftp_download_files`
12
27
  - It now returns the local filename(s) of the downloaded files.
13
28
 
14
- ### Fixed
15
-
16
29
  ## [2.7.10] - 2024-05-20
17
30
 
18
31
  ### Changed
data/Gemfile CHANGED
@@ -4,3 +4,5 @@ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
4
 
5
5
  # Specify your gem's dependencies in eco-helpers.gemspec
6
6
  gemspec
7
+
8
+ # gem 'rubocop-rake', require: false
data/eco-helpers.gemspec CHANGED
@@ -10,13 +10,13 @@ Gem::Specification.new do |spec|
10
10
  spec.authors = ["Oscar Segura"]
11
11
  spec.email = ["oscar@ecoportal.co.nz"]
12
12
  spec.date = %q{2018-09-05}
13
- spec.summary = %q{eco-helpers to manage people api cases}
13
+ spec.summary = %q(eco-helpers to manage people api cases)
14
14
  spec.homepage = "https://www.ecoportal.com"
15
15
  spec.licenses = %w[MIT]
16
16
 
17
17
  spec.required_ruby_version = '>= 2.7.2'
18
18
 
19
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
19
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
20
20
  f.match(%r{^(test|spec|features)/})
21
21
  end
22
22
 
@@ -25,29 +25,31 @@ Gem::Specification.new do |spec|
25
25
  spec.require_paths = ["lib"]
26
26
 
27
27
  spec.add_development_dependency "bundler", ">= 2.4.12", "< 3"
28
- spec.add_development_dependency "rspec", ">= 3.12.0", "< 4"
29
28
  spec.add_development_dependency "rake", ">= 13.0.3", "< 14"
30
- spec.add_development_dependency "yard", ">= 0.9.34", "< 1"
31
29
  spec.add_development_dependency "redcarpet", ">= 3.6.0", "< 4"
30
+ spec.add_development_dependency "rspec", ">= 3.12.0", "< 4"
31
+ spec.add_development_dependency "rubocop", "~> 1"
32
+ spec.add_development_dependency "rubocop-rake", "~> 0"
33
+ spec.add_development_dependency "yard", ">= 0.9.34", "< 1"
32
34
 
33
- spec.add_dependency 'ecoportal-api', '>= 0.9.8', '< 0.10'
34
- spec.add_dependency 'ecoportal-api-v2', '>= 1.1.8', '< 1.2'
35
- spec.add_dependency 'ecoportal-api-graphql', '>= 0.3.18', '< 0.4'
36
- spec.add_dependency 'ed25519', '>= 1.2'
37
- spec.add_dependency 'bcrypt_pbkdf', '>= 1.0'
35
+ spec.add_dependency 'amatch', '>= 0.4.1', '< 0.5'
38
36
  spec.add_dependency 'aws-sdk-s3', '>= 1.142.0', '< 2'
39
37
  spec.add_dependency 'aws-sdk-ses', '>= 1.58.0', '< 2'
38
+ spec.add_dependency 'bcrypt_pbkdf', '>= 1.0'
39
+ spec.add_dependency 'docx', '>= 0.8.0', '< 0.9'
40
40
  spec.add_dependency 'dotenv', '>= 2.8.1', '< 3'
41
- spec.add_dependency 'net-ssh', '>= 7.2.1', '< 8'
42
- spec.add_dependency 'net-sftp', '>= 4.0.0', '< 5'
43
- spec.add_dependency 'hashdiff', '>= 1.1.0', '< 1.2'
41
+ spec.add_dependency 'ecoportal-api', '>= 0.9.8', '< 0.10'
42
+ spec.add_dependency 'ecoportal-api-graphql', '>= 0.3.18', '< 0.4'
43
+ spec.add_dependency 'ecoportal-api-v2', '>= 1.1.8', '< 1.2'
44
+ spec.add_dependency 'ed25519', '>= 1.2'
45
+ spec.add_dependency 'fast_excel', '>= 0.5.0', '< 0.6'
44
46
  spec.add_dependency 'fuzzy_match', '>= 2.1.0', '< 2.2'
45
- spec.add_dependency 'amatch', '>= 0.4.1', '< 0.5'
47
+ spec.add_dependency 'hashdiff', '>= 1.1.0', '< 1.2'
46
48
  spec.add_dependency 'jaro_winkler', '>= 1.5.6', '< 1.6'
49
+ spec.add_dependency 'net-sftp', '>= 4.0.0', '< 5'
50
+ spec.add_dependency 'net-ssh', '>= 7.2.1', '< 8'
47
51
  spec.add_dependency 'nokogiri', '>= 1.13', '< 1.17'
48
52
  spec.add_dependency 'roo', '>= 2.10.1', '< 2.11'
49
53
  spec.add_dependency 'roo-xls', '>= 1.2.0', '< 1.3'
50
- spec.add_dependency 'fast_excel', '>= 0.5.0', '< 0.6'
51
- spec.add_dependency 'docx', '>= 0.8.0', '< 0.9'
52
54
  spec.add_dependency 'rubyzip', '>= 2.3.2', '< 2.4'
53
55
  end
@@ -3,17 +3,20 @@ module Eco
3
3
  module Common
4
4
  module Session
5
5
  class Logger < Eco::Language::BasicLogger
6
- TIMESTAMP_PATTERN = '%Y-%m-%dT%H:%M:%S'
6
+ TIMESTAMP_PATTERN = '%Y-%m-%dT%H:%M:%S'.freeze
7
7
 
8
8
  attr_reader :cache
9
9
 
10
10
  def initialize(file_level: ::Logger::DEBUG, log_file: nil, enviro: nil, **kargs)
11
11
  super(**kargs)
12
- raise "Required Environment object (enviro:). Given: #{enviro}" if enviro && !enviro.is_a?(Eco::API::Common::Session::Environment)
12
+
13
+ msg = "Required Environment object (enviro:). Given: #{enviro.class}"
14
+ raise ArgumentError, msg if enviro && !enviro.is_a?(Eco::API::Common::Session::Environment)
15
+
13
16
  @enviro = enviro
14
17
  @cache = Logger::Cache.new
15
18
 
16
- if log_file = fetch_log_file(log_file)
19
+ if (log_file = fetch_log_file(log_file))
17
20
  loggers[:file] = ::Logger.new(log_file).tap do |logger|
18
21
  logger.formatter = format_proc(console: false) do |severity, datetime, msg, formatted_msg|
19
22
  cache.add(severity, datetime, msg, formatted_msg)
@@ -34,15 +37,16 @@ module Eco
34
37
  private
35
38
 
36
39
  def config(attr)
37
- return nil unless cnf = @enviro&.config&.logger
40
+ return unless (cnf = @enviro&.config&.logger)
41
+
38
42
  cnf.send(attr) if cnf.respond_to?(attr)
39
43
  end
40
44
 
41
45
  def if_config(attr)
42
- unless (value = config(attr)).nil?
43
- yield(value) if block_given?
44
- value
45
- end
46
+ return if (value = config(attr)).nil?
47
+
48
+ yield(value) if block_given?
49
+ value
46
50
  end
47
51
 
48
52
  def fetch_log_file(log_file)
@@ -24,7 +24,7 @@ module Eco
24
24
  end
25
25
 
26
26
  def empty?
27
- count == 0
27
+ count.zero?
28
28
  end
29
29
 
30
30
  def each(&block)
@@ -90,15 +90,16 @@ module Eco
90
90
  # @return [Hash<Eco::API::Session::Batch::Job, Eco::API::Session::Batch::Status>]
91
91
  def launch(simulate: false)
92
92
  each_with_index do |job, idx|
93
- if job.pending?
94
- status[job] = job_status = job.launch(simulate: simulate)
95
- callback = @callbacks[job]
96
- callback.call(job, job_status) if callback
97
- Eco::API::Session::Batch::JobsGroups.counter(delay_between_jobs) if !simulate && idx < self.length - 1
98
- end
93
+ next unless job.pending?
94
+
95
+ status[job] = job_status = job.launch(simulate: simulate)
96
+ callback = @callbacks[job]
97
+ callback&.call(job, job_status)
98
+ Eco::API::Session::Batch::JobsGroups.counter(delay_between_jobs) if !simulate && idx < length - 1
99
99
  end
100
100
  launch(simulate: simulate) if pending?
101
- return status
101
+
102
+ status
102
103
  end
103
104
 
104
105
  def find_jobs(type:)
@@ -113,7 +114,7 @@ module Eco
113
114
  yield(job, job_status)
114
115
  end
115
116
  self
116
- else
117
+ else # rubocop:disable Naming/MemoizedInstanceVariableName
117
118
  @jobs_status ||= {}
118
119
  end
119
120
  end
@@ -1,4 +1,4 @@
1
- class Eco::API::UseCases::Default::People::CleanUnknownTags < Eco::API::Common::Loaders::UseCase
1
+ class Eco::API::UseCases::Default::People::Amend::CleanUnknownTags < Eco::API::Common::Loaders::UseCase
2
2
  name "clean-unknown-tags"
3
3
  type :transform
4
4
 
@@ -35,7 +35,7 @@ class Eco::API::UseCases::Default::People::CleanUnknownTags < Eco::API::Common::
35
35
  private
36
36
 
37
37
  def default_tag(person)
38
- return nil unless account = person.account
38
+ return unless (account = person.account)
39
39
  account.default_tag
40
40
  end
41
41
 
@@ -1,8 +1,8 @@
1
- class Eco::API::UseCases::Default::People::ClearAbilitiesTransCase < Eco::API::Common::Loaders::UseCase
1
+ class Eco::API::UseCases::Default::People::Amend::ClearAbilitiesTransCase < Eco::API::Common::Loaders::UseCase
2
2
  name "clear-abilities"
3
3
  type :transform
4
4
 
5
- def main(people, _session, _options, _usecase)
5
+ def main(*_args)
6
6
  clear_abilities(people.users)
7
7
  end
8
8
 
@@ -1,4 +1,4 @@
1
- class Eco::API::UseCases::Default::People::RefreshCase < Eco::API::Common::Loaders::UseCase
1
+ class Eco::API::UseCases::Default::People::Amend::RefreshCase < Eco::API::Common::Loaders::UseCase
2
2
  name "refresh"
3
3
  type :transform
4
4
 
@@ -0,0 +1,11 @@
1
+ module Eco::API::UseCases::Default::People::Amend
2
+ class ReinviteSyncCase < ReinviteTransCase
3
+ name "reinvite"
4
+ type :sync
5
+
6
+ def main(entries, *_args)
7
+ found = micro.with_each_present(entries, people, options, log_starter: true)
8
+ reinvite(found.users)
9
+ end
10
+ end
11
+ end
@@ -1,8 +1,8 @@
1
- class Eco::API::UseCases::Default::People::ReinviteTransCase < Eco::API::Common::Loaders::UseCase
1
+ class Eco::API::UseCases::Default::People::Amend::ReinviteTransCase < Eco::API::Common::Loaders::UseCase
2
2
  name "reinvite"
3
3
  type :transform
4
4
 
5
- def main(people, session, options, usecase)
5
+ def main(*_args)
6
6
  reinvite(people.users)
7
7
  end
8
8
 
@@ -0,0 +1,4 @@
1
+ class Eco::API::UseCases::Default::People::Amend::ReinviteTransCase
2
+ class Cli < Eco::API::UseCases::Cli
3
+ end
4
+ end
@@ -1,6 +1,6 @@
1
1
  # @example
2
2
  # -restore-db-from backup.json -skip-api-policies -skip-batch-policy -include-excluded -simulate
3
- class Eco::API::UseCases::Default::People::RestoreDBCase < Eco::API::Common::Loaders::UseCase
3
+ class Eco::API::UseCases::Default::People::Amend::RestoreDBCase < Eco::API::Common::Loaders::UseCase
4
4
  name "restore-db"
5
5
  type :sync
6
6
 
@@ -0,0 +1,11 @@
1
+ module Eco::API::UseCases::Default::People
2
+ module Amend
3
+ end
4
+ end
5
+
6
+ require_relative 'amend/clean_unknown_tags_case'
7
+ require_relative 'amend/clear_abilities_case'
8
+ require_relative 'amend/reinvite_trans_case'
9
+ require_relative 'amend/reinvite_sync_case'
10
+ require_relative 'amend/refresh_case'
11
+ require_relative 'amend/restore_db_case'
@@ -0,0 +1,23 @@
1
+ class Eco::API::UseCases::Default::People::Migrate::RemapTags
2
+ class Cli < Eco::API::UseCases::Cli
3
+ desc 'Maps filter_tags and default_tag based on input file'
4
+
5
+ callback do |_people, _session, options, _usecase|
6
+ if (file = SCR.get_file('-remap-tags', required: true, should_exist: true))
7
+ options.deep_merge!(input: {file: {name: file}})
8
+ end
9
+ end
10
+
11
+ add_option('-remove-source-tag', 'Whether source mapped tags should be removed') do |options|
12
+ options.deep_merge!(usecase: {remove_source_tag: true})
13
+ end
14
+
15
+ add_option('-clear-unknown-tag', 'Whether unknown tags should be cleared') do |options|
16
+ options.deep_merge!(usecase: {clear_unknown_tags: true})
17
+ end
18
+
19
+ add_option('-clear-archived-nodes', 'Whether archived nodes should be cleared') do |options|
20
+ options.deep_merge!(usecase: {clear_archived_nodes: true})
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,269 @@
1
+ class Eco::API::UseCases::Default::People::Migrate::RemapTags < Eco::API::Common::Loaders::UseCase
2
+ name 'remap-tags'
3
+ type :transform
4
+
5
+ require_relative 'cli/remap_tags_cli'
6
+
7
+ REGISTER_TAGS = %w[
8
+ EVENT INJURY RISK CONTRACTOR PERMIT
9
+ AUDIT JSEA
10
+ TRAINING INDUCTION
11
+ MEETING PPE CHEMICAL
12
+ PLANT ASSET
13
+ POLICY IDEA REPORTS
14
+ ].freeze
15
+
16
+ def main(*_args)
17
+ tune_options!
18
+
19
+ people.each do |person|
20
+ update_job.add(person)
21
+
22
+ update_filter_tags!(person)
23
+ update_default_tag!(person)
24
+ clear_unkown_tags!(person) if clear_unknown_tags?
25
+ clear_archived_nodes!(person) if clear_archived_nodes?
26
+ end
27
+ end
28
+
29
+ def update_job
30
+ @update_job ||= session.new_job('main', 'update', :update, usecase) do |_job, _job_status|
31
+ report_removed_src_tags
32
+ report_archived_cleared
33
+ report_unknown_cleared
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ # If the map on `value` exists, it returns the new value,
40
+ # otherwise mirrors the `value` (to prevent data loss)
41
+ def apply_map(value)
42
+ case value
43
+ when Array
44
+ value.map {|val| apply_map(val)}
45
+ when String
46
+ if (new_tag = id_maps[value])
47
+ new_tag
48
+ else
49
+ value
50
+ end
51
+ end
52
+ end
53
+
54
+ def update_filter_tags!(person)
55
+ mapped_tags = apply_map(person.filter_tags)
56
+
57
+ if remove_source_tag?
58
+ removed = person.filter_tags - mapped_tags
59
+ removed_src_tag!(*removed)
60
+ person.filter_tags = mapped_tags
61
+ else
62
+ person.filter_tags |= mapped_tags
63
+ end
64
+ end
65
+
66
+ # We always map the default_tag
67
+ def update_default_tag!(person)
68
+ return unless (account = person.account)
69
+
70
+ default_tag = apply_map(account.default_tag)
71
+ return unless default_tag.nil? || active_node?(default_tag)
72
+
73
+ account.default_tag = default_tag
74
+ end
75
+
76
+ # @note it still keeps archived nodes
77
+ def clear_unkown_tags!(person)
78
+ person.filter_tags = person.filter_tags.select do |tag|
79
+ known_tag?(tag).tap do |known|
80
+ cleared_unknown_tag!(tag) unless known
81
+ end
82
+ end
83
+ end
84
+
85
+ # @note it only targets archived nodes
86
+ def clear_archived_nodes!(person)
87
+ person.filter_tags = person.filter_tags.reject do |tag|
88
+ archived_node?(tag).tap do |known|
89
+ cleared_archived_node!(tag) unless known
90
+ end
91
+ end
92
+ end
93
+
94
+ def report_removed_src_tags
95
+ return if removed_src_tags.empty?
96
+
97
+ log(:info) {
98
+ msg = "Here list of the #{removed_src_tags.count} removed source-mapped tags..."
99
+ msg << "\n • "
100
+ msg << removed_src_tags.sort.join("\n • ")
101
+ msg
102
+ }
103
+ end
104
+
105
+ # Clean OLD Tags
106
+ def report_unknown_cleared
107
+ report_cleared(cleared_unknown_tags, msg: 'Cleared up the following non existing tags:')
108
+ end
109
+
110
+ def report_archived_cleared
111
+ report_cleared(cleared_archived_nodes, msg: 'Cleared up the following archived nodes:')
112
+ end
113
+
114
+ # Whether it should remove the original tag
115
+ # @note we might want to preserve it at the moment, and remove them
116
+ # at a later stage (i.e. after migrating the pages)
117
+ def remove_source_tag?
118
+ options.dig(:usecase, :remove_source_tag) || false
119
+ end
120
+
121
+ # Whether it should clear out any unkonwn tag
122
+ def clear_unknown_tags?
123
+ options.dig(:usecase, :clear_unknown_tags) || false
124
+ end
125
+
126
+ # Whether it should clear out any archived node
127
+ def clear_archived_nodes?
128
+ options.dig(:usecase, :clear_archived_nodes) || false
129
+ end
130
+
131
+ def report_cleared(data, msg:)
132
+ return if data.empty?
133
+
134
+ cleared_sorted = data.sort_by {|tag, count| [count * -1, tag]}
135
+
136
+ msg << "\n • "
137
+ msg += cleared_sorted.map do |tag, count|
138
+ "'#{tag}' (#{count})"
139
+ end.join("\n • ")
140
+
141
+ log(:info) { msg }
142
+ data.clear
143
+ end
144
+
145
+ def removed_src_tag!(*tags)
146
+ @removed_src_tags = removed_src_tags | tags
147
+ end
148
+
149
+ def removed_src_tags
150
+ @removed_src_tags ||= []
151
+ end
152
+
153
+ def cleared_unknown_tag!(tag)
154
+ cleared_unknown_tags[tag] ||= 0
155
+ cleared_unknown_tags[tag] += 1
156
+ end
157
+
158
+ def cleared_unknown_tags
159
+ @cleared_unknown_tags ||= {}
160
+ end
161
+
162
+ def cleared_archived_node!(tag)
163
+ cleared_archived_nodes[tag] ||= 0
164
+ cleared_archived_nodes[tag] += 1
165
+ end
166
+
167
+ def cleared_archived_nodes
168
+ @cleared_archived_nodes ||= {}
169
+ end
170
+
171
+ # @note validations on src -> dst location ids isn't done because
172
+ # we might be in a case where we are moving from old locations to
173
+ # location ids, but it might be a case where we are mapping an actual
174
+ # location id to a custom tag as well... so trying to keep this standard.
175
+ def id_maps
176
+ @id_maps ||= input_csv.each.with_object({}) do |row, out|
177
+ from, to = row.fields.to_a.first(2)
178
+ froms = from.split('|').map(&:strip).map(&:upcase).reject(&:empty?)
179
+ tos = to.split('|').map(&:strip).map(&:upcase).reject(&:empty?)
180
+ from = froms.first
181
+ to = tos.first
182
+ next if from == to
183
+ next unless from && to
184
+
185
+ out[from] = to
186
+ end
187
+ end
188
+
189
+ def input_csv
190
+ @input_csv ||= Eco::CSV.read(input_file, encoding: input_encoding)
191
+ end
192
+
193
+ def input_encoding
194
+ options.dig(:input, :file, :encoding) || 'utf-8'
195
+ end
196
+
197
+ def input_file
198
+ @input_file ||= options.dig(:input, :file, :name).tap do |file|
199
+ if file.nil?
200
+ log(:warn) { "No input file specified" }
201
+ exit(1)
202
+ elsif File.exist?(file)
203
+ log(:info) { "Using input file '#{file}'" }
204
+ else
205
+ log(:error) { "File not found '#{file}'" }
206
+ exit(1)
207
+ end
208
+ end
209
+ end
210
+
211
+ def default_tag(person)
212
+ return unless (account = person.account)
213
+ account.default_tag
214
+ end
215
+
216
+ def known_tag?(value)
217
+ register_tag?(value) || tag?(value)
218
+ end
219
+
220
+ def unknown_tag?(value)
221
+ !known_tag?(value)
222
+ end
223
+
224
+ def register_tag?(value)
225
+ register_tags.include?(value)
226
+ end
227
+
228
+ def archived_tag?(value)
229
+ return false if register_tag?(value)
230
+ return false unless (node = tagtree.node(value))
231
+ node.archived
232
+ end
233
+
234
+ def tag?(value)
235
+ return false if value.nil?
236
+ return true if tagtree.tag?(value)
237
+ register_tags.any? { |reg| value.upcase == reg }
238
+ end
239
+
240
+ def active_node?(value)
241
+ return false if value.nil?
242
+ return false unless tagtree.tag?(value)
243
+ !archived_node?(value)
244
+ end
245
+
246
+ def archived_node?(value)
247
+ return false unless (node = tagtree.node(value))
248
+ node.archived
249
+ end
250
+
251
+ # Get all the location structures merged into a single one
252
+ def tagtree
253
+ @tagtree ||= session.tagtree(
254
+ live: true,
255
+ include_archived: true,
256
+ merge: true
257
+ )
258
+ end
259
+
260
+ def register_tags
261
+ @register_tags ||= self.class::REGISTER_TAGS.compact.map(&:upcase)
262
+ end
263
+
264
+ def tune_options!
265
+ # options.deep_merge!(include: {excluded: true})
266
+ options.deep_merge!(skip: {api_policies: true})
267
+ options.deep_merge!(skip: {batch_policy: true})
268
+ end
269
+ end
@@ -0,0 +1,6 @@
1
+ module Eco::API::UseCases::Default::People
2
+ module Migrate
3
+ end
4
+ end
5
+
6
+ require_relative 'migrate/remap_tags_case'
@@ -1,4 +1,4 @@
1
- class Eco::API::UseCases::Default::People::Analyse < Eco::API::Common::Loaders::UseCase
1
+ class Eco::API::UseCases::Default::People::Treat::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::Default::People::OrgDataConvertCase < Eco::API::Common::Loaders::UseCase
1
+ class Eco::API::UseCases::Default::People::Treat::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::Default::People::SupersCyclicIdentify < Eco::API::Common::Loaders::UseCase
1
+ class Eco::API::UseCases::Default::People::Treat::SupersCyclicIdentify < Eco::API::Common::Loaders::UseCase
2
2
  name "identify-cyclic-supers"
3
3
  type :export
4
4
 
@@ -62,7 +62,7 @@ class Eco::API::UseCases::Default::People::SupersCyclicIdentify < Eco::API::Comm
62
62
 
63
63
  "".tap do |str|
64
64
  entry = set.shift
65
- str << " " * lev
65
+ str << (" " * lev)
66
66
  str << lev&.positive? ? "+-#{lev}- " : ""
67
67
  str << entry.name
68
68
  str << " (#{entry.external_id}|#{entry.email}|#{entry.id})\n"