eco-helpers 2.7.11 → 2.7.13

Sign up to get free protection for your applications and to get access to all the features.
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"