eco-helpers 2.0.14 → 2.0.19

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +90 -2
  3. data/eco-helpers.gemspec +6 -4
  4. data/lib/eco-helpers.rb +2 -0
  5. data/lib/eco/api/common/base_loader.rb +14 -0
  6. data/lib/eco/api/common/people/default_parsers/date_parser.rb +11 -1
  7. data/lib/eco/api/common/people/default_parsers/login_providers_parser.rb +1 -1
  8. data/lib/eco/api/common/people/default_parsers/policy_groups_parser.rb +11 -11
  9. data/lib/eco/api/common/people/entry_factory.rb +26 -9
  10. data/lib/eco/api/common/people/person_entry.rb +5 -2
  11. data/lib/eco/api/common/people/supervisor_helpers.rb +27 -0
  12. data/lib/eco/api/common/session.rb +1 -0
  13. data/lib/eco/api/common/session/base_session.rb +2 -0
  14. data/lib/eco/api/common/session/file_manager.rb +2 -2
  15. data/lib/eco/api/common/session/helpers.rb +30 -0
  16. data/lib/eco/api/common/session/helpers/prompt_user.rb +34 -0
  17. data/lib/eco/api/common/session/mailer.rb +0 -1
  18. data/lib/eco/api/common/session/s3_uploader.rb +0 -1
  19. data/lib/eco/api/common/session/sftp.rb +0 -1
  20. data/lib/eco/api/common/version_patches/ecoportal_api/external_person.rb +1 -1
  21. data/lib/eco/api/common/version_patches/ecoportal_api/internal_person.rb +7 -4
  22. data/lib/eco/api/common/version_patches/exception.rb +8 -4
  23. data/lib/eco/api/microcases.rb +3 -1
  24. data/lib/eco/api/microcases/append_usergroups.rb +0 -1
  25. data/lib/eco/api/microcases/people_cache.rb +2 -2
  26. data/lib/eco/api/microcases/people_load.rb +2 -2
  27. data/lib/eco/api/microcases/people_refresh.rb +2 -2
  28. data/lib/eco/api/microcases/people_search.rb +6 -6
  29. data/lib/eco/api/microcases/preserve_default_tag.rb +23 -0
  30. data/lib/eco/api/microcases/preserve_filter_tags.rb +28 -0
  31. data/lib/eco/api/microcases/preserve_policy_groups.rb +30 -0
  32. data/lib/eco/api/microcases/set_account.rb +0 -1
  33. data/lib/eco/api/microcases/with_each.rb +67 -6
  34. data/lib/eco/api/microcases/with_each_present.rb +4 -2
  35. data/lib/eco/api/microcases/with_each_starter.rb +4 -2
  36. data/lib/eco/api/organization.rb +1 -0
  37. data/lib/eco/api/organization/people.rb +98 -22
  38. data/lib/eco/api/organization/people_similarity.rb +112 -0
  39. data/lib/eco/api/organization/person_schemas.rb +5 -1
  40. data/lib/eco/api/organization/policy_groups.rb +5 -1
  41. data/lib/eco/api/organization/presets_factory.rb +40 -80
  42. data/lib/eco/api/organization/presets_integrity.json +6 -0
  43. data/lib/eco/api/organization/presets_values.json +5 -4
  44. data/lib/eco/api/policies/default_policies/99_user_access_policy.rb +0 -30
  45. data/lib/eco/api/session.rb +6 -22
  46. data/lib/eco/api/session/batch.rb +25 -7
  47. data/lib/eco/api/session/config.rb +16 -15
  48. data/lib/eco/api/session/config/api.rb +4 -0
  49. data/lib/eco/api/session/config/apis.rb +80 -0
  50. data/lib/eco/api/session/config/files.rb +7 -0
  51. data/lib/eco/api/session/config/people.rb +3 -19
  52. data/lib/eco/api/usecases/default_cases.rb +4 -1
  53. data/lib/eco/api/usecases/default_cases/abstract_policygroup_abilities_case.rb +161 -0
  54. data/lib/eco/api/usecases/default_cases/analyse_people_case.rb +53 -0
  55. data/lib/eco/api/usecases/default_cases/codes_to_tags_case.rb +2 -3
  56. data/lib/eco/api/usecases/default_cases/reset_landing_page_case.rb +11 -1
  57. data/lib/eco/api/usecases/default_cases/restore_db_case.rb +1 -2
  58. data/lib/eco/api/usecases/default_cases/supers_cyclic_identify_case.rb +72 -0
  59. data/lib/eco/api/usecases/default_cases/supers_hierarchy_case.rb +59 -0
  60. data/lib/eco/api/usecases/default_cases/to_csv_case.rb +132 -29
  61. data/lib/eco/api/usecases/default_cases/to_csv_detailed_case.rb +61 -36
  62. data/lib/eco/api/usecases/ooze_samples/ooze_update_case.rb +3 -2
  63. data/lib/eco/cli.rb +0 -10
  64. data/lib/eco/cli/config/default/options.rb +20 -17
  65. data/lib/eco/cli/config/default/people_filters.rb +3 -3
  66. data/lib/eco/cli/config/default/usecases.rb +80 -26
  67. data/lib/eco/cli/config/default/workflow.rb +16 -4
  68. data/lib/eco/cli/config/help.rb +1 -0
  69. data/lib/eco/cli/config/options_set.rb +106 -13
  70. data/lib/eco/cli/config/use_cases.rb +33 -33
  71. data/lib/eco/cli/scripting/args_helpers.rb +30 -3
  72. data/lib/eco/csv.rb +4 -2
  73. data/lib/eco/data.rb +1 -0
  74. data/lib/eco/data/crypto/encryption.rb +3 -3
  75. data/lib/eco/data/files/directory.rb +28 -20
  76. data/lib/eco/data/files/helpers.rb +6 -4
  77. data/lib/eco/data/fuzzy_match.rb +161 -0
  78. data/lib/eco/data/fuzzy_match/array_helpers.rb +75 -0
  79. data/lib/eco/data/fuzzy_match/chars_position_score.rb +37 -0
  80. data/lib/eco/data/fuzzy_match/ngrams_score.rb +78 -0
  81. data/lib/eco/data/fuzzy_match/pairing.rb +101 -0
  82. data/lib/eco/data/fuzzy_match/result.rb +73 -0
  83. data/lib/eco/data/fuzzy_match/results.rb +59 -0
  84. data/lib/eco/data/fuzzy_match/score.rb +44 -0
  85. data/lib/eco/data/fuzzy_match/stop_words.rb +35 -0
  86. data/lib/eco/data/fuzzy_match/string_helpers.rb +69 -0
  87. data/lib/eco/version.rb +1 -1
  88. metadata +87 -10
  89. data/lib/eco/api/microcases/refresh_abilities.rb +0 -19
  90. data/lib/eco/api/organization/presets_reference.json +0 -59
  91. data/lib/eco/api/usecases/default_cases/refresh_abilities_case.rb +0 -30
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 697d71754e809691a39f62a86d5fc46e2988578c19c965945e1c06ea73b290b6
4
- data.tar.gz: 01ef5ca1a9bcf941d44b5f7088f54dd9c2cba950cc562ed0516400811df60f12
3
+ metadata.gz: 14260868c76936513a93d4d104eacebbd11e47ed05806d4102ee76196a300d2b
4
+ data.tar.gz: 35784d03a18f89d2ce8bf5c4105e0eaa647dd10b4e1fee03897319d9ad838760
5
5
  SHA512:
6
- metadata.gz: b24db6ddf741e3f0dcc3f080dba19132d7926c85cf211ae0f98c090c7a3cd93f513b6e977ac21ca24d5c2092d524cc1e7ef3d04250bb29ae672400623c823964
7
- data.tar.gz: 9585e95676aab71322af2f174d06aed7d6226502bed1e2560cfd0915643e682c02fb857c33310f7c5f1b6d083b83267d14194f0f1e315c940048ef1c3c43faff
6
+ metadata.gz: 514d71e93bfa4fb854d9062be03306e154a4dfd184256ab03da30e2bf4bb2a45fb305efd5e2206821e522dc7cc0bfbc69e75285e3c6292dca78f359bd166f52a
7
+ data.tar.gz: c99a424905916cef61333c18bb31726e90fb9759a4a1b747b72ab123f4bc09ecc6962205a966b3ea46aa1f0a4cc3dd7f72a8c53829cc764a7993d64ad45495bf
data/CHANGELOG.md CHANGED
@@ -1,7 +1,96 @@
1
1
  # Change Log
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
- ## [2.0.14] - 2021-03-xx
4
+ ## [2.0.19] - 2021-05-xx
5
+
6
+ ### Added
7
+ - Better error message for people searches & **offer** to select among the candidates:
8
+ - `Eco::API::Organization::People::MultipleSearchResults`, triggered from `Eco::API::Organization::People#find`
9
+ - `Eco::API::MicroCases#with_each` will offer the selection of candidates
10
+
11
+ ### Changed
12
+ - **renamed** and repurposed `Eco::API::Organization::PeopleAnalytics` to `PeopleSimilarity`
13
+
14
+ ### Fixed
15
+ - `Eco::Data::FuzzyMatch` adjustments for configuration propagation + some fixes
16
+ - Command option `-entries-from` can still be useful when used to obtain `-get-partial` of people base for `:export` use cases !!
17
+
18
+ ## [2.0.18] - 2021-05-25
19
+
20
+ ### Added
21
+ - **`-one-off`** option to not having to type the `-api-key` every time you launch one-off scripts
22
+ - `-api-key` will store the key to the `./.env_one_off` file (supports update and multi-environment)
23
+
24
+ ### Fixed
25
+ - patched `Exception#patch_full_message` to do not enter into a cyclic error rescue
26
+ - also rescue on `workflow.rescue`
27
+
28
+ ## [2.0.17] - 2021-05-25
29
+
30
+ Specific changes due to eP **release `1.5.9.70`** (_Policy Group Abilities_)
31
+ - And some improvements as well as new tools
32
+
33
+ ### Added
34
+ - `Eco::API::Organization::PresetsFactory` added integrity validation for `person_abilities` ability
35
+ - `Eco::API::Organization::PresetsFactory`
36
+ - `#validate`: returns an `Array` with all the errors that a `permissions_custom` has
37
+ - `#valid?`: checks if a `permissions_custom` is valid
38
+ - `Eco::API::Organization::PeopleAnalytics`: a **helper** class to identify things in the People Manager and provide mitigation action methods to resolve them.
39
+ - Added dependencies to `fuzzy_match`, `amatch` and `jaro_winkler` **gems**
40
+ - `Eco::Data::FuzzyMatch` with string match helpers and a set of home-made generic libs.
41
+ - `Eco::API::Organization::PeopleAnalytics` to launch analysis on the People Manager
42
+ - `Eco::API::UseCases::DefaultCases::AnalysePeople` invokable via `-analyse-people`
43
+ - **new** -> a way to define a hierarchy of options (at least of 1 Level)
44
+ - `API::CLI::Config::OptionsSet`
45
+ - `API::CLI::Config::UseCases::CaseConfig`
46
+ - Integrated the new feature to the `--help` command and methods.
47
+ - **Usecase** `Eco::API::UseCases::DefaultCases::ResetLandingPageCase` added parameter to specify `-page-id`
48
+ - `Eco::API::Common::BaseLoader` new shortcut methods `#micro` (_MicroCases_), `#session` and `#config`
49
+ - At this stage of the execution workflow it uses `ASSETS.session`
50
+ - **Important note**: when the `#parser` or `#serializer` are called the `ASSETS.session` might already be linked to the specific invoked environment
51
+ - New method helpers in `Ecoporta::API::MicroCases`
52
+ - `preserve_filter_tags`, `preserve_default_tag` and `preserve_policy_groups`
53
+
54
+ ### Changed
55
+ - upgraded dependency on `ecoportal-api` and `ecoportal-api-v2`
56
+ - **removed** `Eco::API::MicroCases#refresh_abilities`
57
+ - `Eco::API::MicroCases#set_account` **removed** `refresh_abilities`
58
+ - `Eco::API::MicroCases#append_usergroups` **removed** `refresh_abilities`
59
+ - **removed** _usecase_ `Eco::API::UseCases::DefaultCases::RefreshAbilitiesCase` (`-refresh-abilities`)
60
+ - `Eco::API::Policies::DefaultPolicies::UserAccess`: **removed** `refresh_abilities`
61
+ - **removed** `Eco::API::Session#new_preset`
62
+ - `Eco::API::Organization::PresetsFactory`
63
+ - **removed** `rspecs`
64
+ - `.new`: **removed** parameters `presets_custom` & `presets_map`
65
+ - **removed** constants `DEFAULT_CUSTOM`, and `DEFAULT_MAP`
66
+ - **removed** private methods `#presets_custom` and `#presets_map`
67
+ - **changed** private method `#compile` receives directly an array of `permissions_custom`
68
+ - `Eco::API::Session::Config` **removed** methods `#presets_custom=` & `presets_map=`
69
+ - `Eco::API::Session::Config::People` **removed** methods `#presets_custom=`, `#presets_map=`,`#presets_custom` & `#presets_map`
70
+ - **removed** `eco/api/organization/presets_reference.json`
71
+ - **moved** case-specific options to only be active when the user case is previously invoked in the command line.
72
+
73
+ ### Fixed
74
+ - **handle** `Ecoportal::API:Errors::TimeOut` in `Eco::API::Session::Batch` by offering to retry.
75
+
76
+ ## [2.0.16] - 2021-05-04
77
+
78
+ ### Added
79
+ - Use case `Eco::API::UseCases::DefaultCases::SupersCyclicIdentify`, invokable via `-identify-cyclic-supers`
80
+ - Use case `Eco::API::UseCases::DefaultCases::AbstractPolicyGroupAbilities`, invokable via `-abstract-policygroup-abilities`
81
+ - Option to run `one-off` scripts, without org configurations:
82
+ 1. `-api-key INTERNAL_API_KEY`
83
+ 2. `-enviro [live|pre.dev]`
84
+ 3. `-org NAME_OF_ORG`
85
+
86
+ ## [2.0.15] - 2021-04-29
87
+
88
+ ### Added
89
+ - Use case `Eco::API::UseCases::DefaultCases::SupersHierarchy`, invokable via `-supers-hierarchy`
90
+ ### Fixed
91
+ - `eco/cli/config/default/workflow.rb` prevent `rescue` looping
92
+
93
+ ## [2.0.14] - 2021-04-15
5
94
 
6
95
  ### Added
7
96
  - `Eco::API::UseCases::DefaultCases::ToCsvCase` added option `-internal-names` to avoid overriding data on export
@@ -9,7 +98,6 @@ All notable changes to this project will be documented in this file.
9
98
  - `Eco::API::Organization::PresetsFactory` added integrity validation for `person_*` abilities
10
99
  - `Eco::API::Session::Batch::Job` more debug info on erron handlers
11
100
 
12
- ### Changed
13
101
  ### Fixed
14
102
  - `Eco::API::Error.get_type` was almost always matching `Eco::API::Error::Unclassified` -> fixed
15
103
 
data/eco-helpers.gemspec CHANGED
@@ -24,17 +24,19 @@ Gem::Specification.new do |spec|
24
24
  #spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
25
25
  spec.require_paths = ["lib"]
26
26
 
27
- spec.add_development_dependency "bundler", ">= 2.2.11", "< 2.3"
27
+ spec.add_development_dependency "bundler", ">= 2.2.17", "< 2.3"
28
28
  spec.add_development_dependency "rspec", ">= 3.10.0", "< 3.11"
29
29
  spec.add_development_dependency "rake", ">= 13.0.3", "< 13.1"
30
30
  spec.add_development_dependency "yard", ">= 0.9.26", "< 0.10"
31
31
  spec.add_development_dependency "redcarpet", ">= 3.5.1", "< 3.6"
32
32
 
33
- spec.add_dependency 'ecoportal-api', '>= 0.8.2', '< 0.9'
34
- spec.add_dependency 'ecoportal-api-v2', '>= 0.8.6', '< 0.9'
33
+ spec.add_dependency 'ecoportal-api', '>= 0.8.3', '< 0.9'
34
+ spec.add_dependency 'ecoportal-api-v2', '>= 0.8.7', '< 0.9'
35
35
  spec.add_dependency 'aws-sdk-s3', '>= 1.83.0', '< 2'
36
36
  spec.add_dependency 'aws-sdk-ses', '>= 1.36.0', '< 2'
37
37
  spec.add_dependency 'dotenv', '>= 2.7.6', '< 2.8'
38
38
  spec.add_dependency 'net-sftp', '>= 3.0.0', '< 3.1'
39
-
39
+ spec.add_dependency 'fuzzy_match', '>= 2.1.0', '< 2.2'
40
+ spec.add_dependency 'amatch', '>= 0.4.0', '< 0.5'
41
+ spec.add_dependency 'jaro_winkler', '>= 1.5.4', '< 1.6'
40
42
  end
data/lib/eco-helpers.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  require 'csv'
2
2
  require 'json'
3
3
  require 'pp'
4
+ require 'dotenv'
5
+ require 'dotenv/load'
4
6
 
5
7
 
6
8
  module Eco
@@ -48,6 +48,20 @@ module Eco
48
48
  self.class.name
49
49
  end
50
50
 
51
+ private
52
+
53
+ def session
54
+ @session ||= ASSETS.session
55
+ end
56
+
57
+ def micro
58
+ session.micro
59
+ end
60
+
61
+ def config
62
+ @config ||= ASSETS.config
63
+ end
64
+
51
65
  end
52
66
  end
53
67
  end
@@ -6,7 +6,7 @@ class Eco::API::Common::People::DefaultParsers::DateParser < Eco::API::Common::L
6
6
  end
7
7
 
8
8
  def serializer(value, deps)
9
- value.is_a?(Array) ? value.map { |d| d && d.strftime('%Y-%m-%d') } : value && value.strftime('%Y-%m-%d')
9
+ value.is_a?(Array) ? value.map { |d| serialize_date(d) } : serialize_date(value)
10
10
  end
11
11
 
12
12
  private
@@ -19,4 +19,14 @@ class Eco::API::Common::People::DefaultParsers::DateParser < Eco::API::Common::L
19
19
  end
20
20
  end
21
21
 
22
+ def serialize_date(value)
23
+ return value if value.is_a?(String)
24
+ begin
25
+ value && value.strftime('%Y-%m-%d')
26
+ rescue
27
+ nil
28
+ end
29
+ end
30
+
31
+
22
32
  end
@@ -20,7 +20,7 @@ class Eco::API::Common::People::DefaultParsers::LoginProvidersParser < Eco::API:
20
20
  private
21
21
 
22
22
  def login_providers
23
- @login_providers ||= ASSETS.config.login_providers
23
+ @login_providers ||= config.login_providers
24
24
  end
25
25
 
26
26
  end
@@ -1,31 +1,31 @@
1
1
  class Eco::API::Common::People::DefaultParsers::PolicyGroupsParser < Eco::API::Common::Loaders::Parser
2
2
  attribute "policy_group_ids"
3
+ parsing_phase :final
3
4
 
4
5
  def parser(hash, deps)
5
- policy_group_ids = []
6
- if policy_ids = hash["policy_group_ids"]
7
- policy_group_ids = policy_ids.split("|").map do |name|
8
- policy_groups.to_id(name&.downcase.strip)
9
- end.compact
6
+ policy_group_ids = hash["policy_group_ids"] || []
7
+ policy_group_ids.map do |name|
8
+ policy_groups.to_id(name&.downcase.strip)
9
+ end.compact.tap do |pg_names|
10
+ pg_names.push(default_id) if pg_names.empty?
10
11
  end
11
- policy_group_ids.empty?? default_id : policy_group_ids.join("|")
12
12
  end
13
13
 
14
14
  def serializer(person, deps)
15
15
  ids = person&.account&.policy_group_ids || []
16
16
  ids.map do |id|
17
17
  policy_groups.to_name(id)
18
- end.compact.join("|")
18
+ end.compact
19
19
  end
20
20
 
21
21
  private
22
22
 
23
- def policy_groups
24
- @policy_groups ||= ASSETS.config.policy_groups
23
+ def default_id
24
+ @default_id ||= policy_groups.to_id(config.people.default_usergroup)
25
25
  end
26
26
 
27
- def default_id
28
- @default_id ||= policy_groups.to_id(ASSETS.config.people.default_usergroup)
27
+ def policy_groups
28
+ @policy_groups ||= config.policy_groups
29
29
  end
30
30
 
31
31
  end
@@ -2,6 +2,10 @@ module Eco
2
2
  module API
3
3
  module Common
4
4
  module People
5
+ # TODO: EntryFactory should suppport multiple schemas itself
6
+ # => currently, it's through session.entry_factory(schema: id), but this is wrong
7
+ # => This way, Entries and PersonEntry will be able to refer to attr_map and person_parser linked to schema_id
8
+ # => "schema_id" should be an optional column in the input file, or parsable via a custom parser to scope the schema
5
9
  # Helper factory class to generate entries (input entries).
6
10
  # @attr_reader schema [Ecoportal::API::V1::PersonSchema] person schema to be used in this entry factory
7
11
  class EntryFactory < Eco::API::Common::Session::BaseSession
@@ -12,7 +16,7 @@ module Eco
12
16
  # @param schema [Ecoportal::API::V1::PersonSchema] schema of person details that the parser will be based upon.
13
17
  # @param person_parser [nil, Eco::API::Common::People::PersonParser] set of attribute, type and format parsers/serializers.
14
18
  # @param attr_map [nil, Eco::Data::Mapper] attribute names mapper to translate external names into internal ones and _vice versa_.
15
- def initialize(e, schema:, person_parser: nil, attr_map: nil)
19
+ def initialize(e, schema:, person_parser: nil, default_parser: nil, attr_map: nil)
16
20
  fatal "Constructor needs a PersonSchema. Given: #{schema}" if !schema.is_a?(Ecoportal::API::V1::PersonSchema)
17
21
  fatal "Expecting PersonParser. Given: #{person_parser}" if person_parser && !person_parser.is_a?(Eco::API::Common::People::PersonParser)
18
22
  fatal "Expecting Mapper object. Given: #{fields_mapper}" if attr_map && !attr_map.is_a?(Eco::Data::Mapper)
@@ -22,14 +26,25 @@ module Eco
22
26
  @source_person_parser = person_parser
23
27
 
24
28
  # load default parser + custom parsers
25
- base_parser = Eco::API::Common::People::DefaultParsers.new(schema: @schema).merge(@source_person_parser)
29
+ @default_parser = default_parser&.new(schema: @schema) || Eco::API::Common::People::DefaultParsers.new(schema: @schema)
30
+ base_parser = @default_parser.merge(@source_person_parser)
26
31
  # new parser with linked schema
27
32
  @person_parser = @source_person_parser.new(schema: @schema).merge(base_parser)
28
33
  @person_parser_patch_version = @source_person_parser.patch_version
29
-
30
34
  @attr_map = attr_map
31
35
  end
32
36
 
37
+ def newFactory(schema: nil)
38
+ self.class.new(
39
+ environment,
40
+ schema: schema,
41
+ person_parser: @source_person_parser,
42
+ default_parser: @default_parser,
43
+ attr_map: @attr_map
44
+ )
45
+ end
46
+
47
+
33
48
  # provides with a Eco::API::Common::People::PersonParser object (collection of attribute parsers)
34
49
  # @note if the custom person parser has changed, it updates the copy of this EntryFactory instance
35
50
  # @return [Eco::API::Common::People::PersonParser] set of attribute, type and format parsers/serializers.
@@ -43,7 +58,7 @@ module Eco
43
58
 
44
59
  # key method to generate objects of `PersonEntry` that share dependencies via this `EntryFactory` environment.
45
60
  # @note this method is necessary to make the factory object work as a if it was a class `PersonEntry` you can call `new` on.
46
- # @param data [Array<Hash>] data to be parsed. The external hashed entry.
61
+ # @param data [Hash, Person] data to be parsed/serialized. Parsed: the external hashed entry. Serialized: a Person object.
47
62
  # @return [Eco::API::Common::People::PersonEntry]
48
63
  def new(data, dependencies: {})
49
64
  PersonEntry.new(
@@ -104,7 +119,7 @@ module Eco
104
119
  # @param format [Symbol] it specifies the format of the output `file:` (i.e. `:xml`, `:csv`). There must be a parser/serializer defined for it.
105
120
  # @param encoding [String] optional parameter to geneate `file:` content by unsing certain encoding.
106
121
  # @return [Void].
107
- def export(data:, file: "export", format: :csv, encoding: "utf-8")
122
+ def export(data:, file: "export", format: :csv, encoding: "utf-8", internal_names: false)
108
123
  fatal("data: Expected Eco::API::Organization::People object. Given: #{data.class}") unless data.is_a?(Eco::API::Organization::People)
109
124
  fatal("A file should be specified.") unless !file.to_s.strip.empty?
110
125
  fatal("Format should be a Symbol. Given '#{format}'") if format && !format.is_a?(Symbol)
@@ -112,16 +127,18 @@ module Eco
112
127
 
113
128
  run = true
114
129
  if Eco::API::Common::Session::FileManager.file_exists?(file)
115
- print "The file '#{file}' already exists. Do you want to overwrite it? (Y/n): "
116
- res = STDIN.gets.strip
117
- run = ["y", "Y", ""].include?(res)
130
+ prompt_user("The file '#{file}' already exists. Do you want to overwrite it? (Y/n):", default: "Y") do |response|
131
+ run = (response == "") || reponse.upcase.start_with?("Y")
132
+ end
118
133
  end
119
134
 
120
135
  if run
121
136
  deps = {"supervisor_id" => {people: data}}
122
137
 
123
138
  data_entries = data.map do |person|
124
- self.new(person, dependencies: deps).external_entry
139
+ self.new(person, dependencies: deps).yield_self do |entry|
140
+ internal_names ? entry.mapped_entry : entry.external_entry
141
+ end
125
142
  end
126
143
 
127
144
  File.open(file, "w", enconding: encoding) do |fd|
@@ -210,13 +210,13 @@ module Eco
210
210
  # @param exclude [String, Array<String>] account properties that should not be set/changed to the person.
211
211
  def set_account(person, exclude: nil)
212
212
  person.account = {} if !person.account
213
- person.account.permissions_preset = nil unless person.account.permissions_preset = "custom"
214
213
  scoped_attrs = @emap.account_attrs - into_a(exclude)
215
214
  @final_entry.slice(*scoped_attrs).each do |attr, value|
216
215
  set_part(person.account, attr, value)
217
216
  end
218
217
  end
219
218
 
219
+ # TO DO: use person.details.schema_id to switch @emap and @person_parser (or just crash if they don't match?)
220
220
  # Setter to fill in all the schema `details` fields of the `Person` that are present in the `Entry`.
221
221
  # @note it only sets those details properties defined in the entry.
222
222
  # Meaning that if an details property is not present in the entry, this will not be set on the target person.
@@ -290,7 +290,10 @@ module Eco
290
290
  # @param internal_entry [Hash] entry with **internal** names and values, but **external** types.
291
291
  # @return [Hash] entry with **internal** names and **external** values and types.
292
292
  def _mapped_serializing(internal_entry)
293
- internal_entry.merge(_serialize_values(internal_entry, :internal))
293
+ mapped_hash = internal_entry.merge(_serialize_values(internal_entry, :internal))
294
+ model_attrs = @person_parser.all_model_attrs - ["send_invites"]
295
+ aux_hash = mapped_hash.slice(*model_attrs)
296
+ merge_missing_attrs(aux_hash, mapped_hash)
294
297
  end
295
298
 
296
299
  # Parsing helper that just **parses the values** that have a parser/serializer defined.
@@ -15,6 +15,7 @@ module Eco
15
15
  # Reorders as follows:
16
16
  # 1. supervisors, people with no supervisor or where their supervisor not present
17
17
  # 2. subordinates
18
+ # @return [Array<Entry>] `values` sorted by supervisors/subordinates
18
19
  def sort_by_supervisors(values, supervisors_first: true)
19
20
  raise "Expected non hash Enumerable. Given: #{values.class}" if values.is_a?(Hash)
20
21
  return [] unless values && values.is_a?(Enumerable)
@@ -32,6 +33,32 @@ module Eco
32
33
  roam.call(supervisors_tree(values))
33
34
  end
34
35
 
36
+ # Identifies all the cyclic supervisor chains
37
+ # @note as `supervisors_tree` will have any entry involved in a cycle at the top, it just checks all the top entries against their offspring
38
+ # @return [Array<Array>] the sets of entries that are cyclic
39
+ def identify_cyclic_chains(values)
40
+ raise "Expected non hash Enumerable. Given: #{values.class}" if values.is_a?(Hash)
41
+ return [] unless values && values.is_a?(Enumerable)
42
+
43
+ identify = Proc.new do |top_sup, offspring, chain = [top_sup]|
44
+ next [] if offspring.empty?
45
+ offspring.each_with_object([]) do |(sup, subordinates), set|
46
+ break set unless set.empty?
47
+ if top_sup.supervisor_id == sup.id
48
+ set.concat(chain, [sup])
49
+ else
50
+ set = identify.call(top_sup, subordinates, chain | [sup])
51
+ end
52
+ end
53
+ end
54
+
55
+ supervisors_tree(values).each_with_object([]) do |(top_sup, offspring), sets|
56
+ if (set = identify.call(top_sup, offspring)) && !set.empty?
57
+ sets.push(set)
58
+ end
59
+ end
60
+ end
61
+
35
62
  def tree_to_str(tree, lev: 0)
36
63
  raise "Required Hash tree structure. Given: #{tree.class}" unless tree.is_a?(Hash)
37
64
  "".tap do |str|
@@ -13,4 +13,5 @@ require_relative 'session/sftp'
13
13
  require_relative 'session/s3_uploader'
14
14
  require_relative 'session/file_manager'
15
15
  require_relative 'session/environment'
16
+ require_relative 'session/helpers'
16
17
  require_relative 'session/base_session'
@@ -11,6 +11,8 @@ module Eco
11
11
  attr_reader :api, :file_manager, :logger
12
12
  alias_method :fm, :file_manager
13
13
 
14
+ include Session::Helpers
15
+
14
16
  def initialize(e)
15
17
  raise "Expected object Eco::API::Common::Session::Environment. Given: #{e.class}" unless e.is_a?(Environment)
16
18
  self.environment = e
@@ -20,8 +20,8 @@ module Eco
20
20
  begin
21
21
  @dir = Eco::Data::Files::Directory.new(value)
22
22
  @dir_path = @dir.create
23
- rescue
24
- logger.error("could not create or make any sense of directory '#{value}'")
23
+ rescue Exception => e
24
+ logger.error("could not create or make any sense of directory '#{value}': #{e.to_s}")
25
25
  end
26
26
  end
27
27
 
@@ -0,0 +1,30 @@
1
+ require_relative 'helpers/prompt_user'
2
+
3
+ module Eco
4
+ module API
5
+ module Common
6
+ module Session
7
+ module Helpers
8
+
9
+ class << self
10
+ def included(base)
11
+ base.send(:include, InstanceMethods)
12
+ base.extend(ClassMethods)
13
+ end
14
+ end
15
+
16
+
17
+ module ClassMethods
18
+
19
+ end
20
+
21
+ module InstanceMethods
22
+ include Helpers::PromptUser
23
+
24
+ end
25
+
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end