eco-helpers 2.0.48 → 2.0.51
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +29 -1
- data/lib/eco/api/microcases/person_update.rb +39 -0
- data/lib/eco/api/microcases/take_email_from_account.rb +89 -0
- data/lib/eco/api/microcases.rb +3 -1
- data/lib/eco/api/session/batch/jobs.rb +9 -1
- data/lib/eco/api/session/batch/jobs_groups.rb +7 -2
- data/lib/eco/api/session/batch/request_stats.rb +50 -34
- data/lib/eco/api/session/config.rb +12 -0
- data/lib/eco/api/usecases/default_cases/create_tag_paths_case.rb +25 -0
- data/lib/eco/api/usecases/default_cases/reinvite_trans_case.rb +13 -4
- data/lib/eco/api/usecases/default_cases/samples/sftp_case.rb +1 -1
- data/lib/eco/api/usecases/default_cases.rb +1 -0
- data/lib/eco/cli/config/default/usecases.rb +9 -0
- data/lib/eco/cli/config/default/workflow.rb +1 -1
- data/lib/eco/version.rb +1 -1
- metadata +4 -1
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: fb5e3755230835f1a3ad402b7dd2fc9b25902ea2ca3a621c8eae0229de716791
         | 
| 4 | 
            +
              data.tar.gz: c0af346142ec3ff97c32503597ae36d9844273e1c20fb6908a3cfcf5595dff54
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 4a2f508415dac83ffe596e330d56a55eb427788d57d239b62b1523bb6abb8f465d6400c1f0c61135d7eb6e036a595d7aacb158cc464e9840a5af8ac56d3582af
         | 
| 7 | 
            +
              data.tar.gz: b791358e41d4aa2db17b5fcd68e0e2aa97af7b4c31d21d9308132e470f07a67c638b53085846006363e2d9d962dba9b5250a9afe358844b113ac4a7c73a4df53
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,9 +1,37 @@ | |
| 1 1 | 
             
            # Change Log
         | 
| 2 2 | 
             
            All notable changes to this project will be documented in this file.
         | 
| 3 3 |  | 
| 4 | 
            -
            ## [2.0. | 
| 4 | 
            +
            ## [2.0.51] - 2022-02-27
         | 
| 5 5 |  | 
| 6 6 | 
             
            ### Added
         | 
| 7 | 
            +
              - `Eco::API::MicroCases#person_update!` launches an update against the Server for one person
         | 
| 8 | 
            +
              - `Eco::API::MicroCases#take_email_from_account` with given an account associated to an `email` that we cannot take, it associates that account to a different email
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            ### Changed
         | 
| 11 | 
            +
            ### Fixed
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            ## [2.0.50] - 2022-02-23
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            ### Added
         | 
| 16 | 
            +
              - Ability to configure delay between jobs and job groups
         | 
| 17 | 
            +
                - `Eco::API::Session::Batch::Jobs`, `#delay_between_jobs`
         | 
| 18 | 
            +
                - `Eco::API::Session::Batch::JobsGroups`, `#delay_between_groups`
         | 
| 19 | 
            +
                - `Eco::API::Session::Config`, added methods `#delay_between_jobs` and `#delay_between_job_groups`
         | 
| 20 | 
            +
              - New use case `Eco::API::UseCases::DefaultCases::TagPaths` to create a `csv` with all `tag` paths
         | 
| 21 | 
            +
                - Its purpose is to ease the build of tag remaps
         | 
| 22 | 
            +
                - Ideally, after remapping the tags of an org, you would want to fix the tag paths based on the current tagtree
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            ### Changed
         | 
| 25 | 
            +
              - `workflow`, when no operation specified it logs as `info`, rather than `warn`
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            ## [2.0.49] - 2022-02-14
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            ### Added
         | 
| 30 | 
            +
              - `Eco::API::Session::Batch::RequestStats#message` now it shows which details have changed
         | 
| 31 | 
            +
              - `Eco::API::UseCases::DefaultCases::ReinviteTransCase` the option `-force` will also send an invite to users that have accepted the invitation
         | 
| 32 | 
            +
             | 
| 33 | 
            +
            ## [2.0.48] - 2022-02-04
         | 
| 34 | 
            +
             | 
| 7 35 | 
             
            ### Changed
         | 
| 8 36 | 
             
              - upgraded `ecoportal-api-v2` dependency
         | 
| 9 37 |  | 
| @@ -0,0 +1,39 @@ | |
| 1 | 
            +
            module Eco
         | 
| 2 | 
            +
              module API
         | 
| 3 | 
            +
                class MicroCases
         | 
| 4 | 
            +
                  # It updates an idividual person.
         | 
| 5 | 
            +
                  # @note if it succeeds the update, it calls `person.consolidate!`
         | 
| 6 | 
            +
                  # @param person [Ecoportal::API::V1::Person] the person we want to update, carrying the changes to be done.
         | 
| 7 | 
            +
                  # @param context [String] main part of the message.
         | 
| 8 | 
            +
                  # @param reason [String] why are we updating now.
         | 
| 9 | 
            +
                  # @return [Boolean] `true` if it succeded to update, and `false` otherwise
         | 
| 10 | 
            +
                  def person_update!(person, context: "Session", reason: "")
         | 
| 11 | 
            +
                    logger.debug("#{context}, going to \"#{reason}\".\nPerson: #{person_ref(person)}")
         | 
| 12 | 
            +
                    if response = api.people.update(person)
         | 
| 13 | 
            +
                      if response.success?
         | 
| 14 | 
            +
                        person.consolidate!
         | 
| 15 | 
            +
                        true
         | 
| 16 | 
            +
                      else
         | 
| 17 | 
            +
                        msg  = "#{context} Error #{response.status}: #{response.body}\n"
         | 
| 18 | 
            +
                        msg += " -- Failed to \"#{reason}\".\n"
         | 
| 19 | 
            +
                        msg += "  • Person: #{person_ref(person)}"
         | 
| 20 | 
            +
                        logger.error(msg)
         | 
| 21 | 
            +
                        false
         | 
| 22 | 
            +
                      end
         | 
| 23 | 
            +
                    else
         | 
| 24 | 
            +
                      msg  = "#{context} Error (connection error)\n"
         | 
| 25 | 
            +
                      msg += " -- Failed to \"#{reason}\".\n"
         | 
| 26 | 
            +
                      msg += "  • Person: #{person_ref(person)}"
         | 
| 27 | 
            +
                      logger.error(msg)
         | 
| 28 | 
            +
                      false
         | 
| 29 | 
            +
                    end
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  private
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  def person_ref(person)
         | 
| 35 | 
            +
                    Eco::API::Session::Batch::Feedback.person_ref(person)
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
            end
         | 
| @@ -0,0 +1,89 @@ | |
| 1 | 
            +
            module Eco
         | 
| 2 | 
            +
              module API
         | 
| 3 | 
            +
                class MicroCases
         | 
| 4 | 
            +
                  # Frees up `target_email` from an account not present in this org.
         | 
| 5 | 
            +
                  #   Allows to force `target_email` on the current user's account.
         | 
| 6 | 
            +
                  #   - If the person does not have account, this case will not do anything.
         | 
| 7 | 
            +
                  #   - If `original_doc["account"]` is `nil` (no account on server side), this case will not do anything.
         | 
| 8 | 
            +
                  #   - If the `target_email` and the `current_email` are the same or empty, this case will not do anything.
         | 
| 9 | 
            +
                  # @note
         | 
| 10 | 
            +
                  #   - **It does not do the final update to the server to the `target_email`**. You will need to do this part yourself.
         | 
| 11 | 
            +
                  #   - You would call this function only when you got an error of `email already taken`.
         | 
| 12 | 
            +
                  #   - If the `target_email` is associated to a user in the same org, this will fail.
         | 
| 13 | 
            +
                  # @param person [Ecoportal::API::V1::Person] the person we want to update, carrying the changes to be done.
         | 
| 14 | 
            +
                  # @param dest_email [String, Proc] the email that we will move the other account to, when we free up `target_email`.
         | 
| 15 | 
            +
                  # @param target_email [String] the email that we want to free up from another account and bring to ours.
         | 
| 16 | 
            +
                  #   If it's empty, the `person.email` will be used instead.
         | 
| 17 | 
            +
                  # @param options [Hash] the options.
         | 
| 18 | 
            +
                  # @param current_email [String] the email that the person's account is currently linked.
         | 
| 19 | 
            +
                  #   As the current email should be associated with this person's account on server side, we use `original_doc["email"]`.
         | 
| 20 | 
            +
                  # @param context [String] main core part of logs. Provides context to the logs.
         | 
| 21 | 
            +
                  def take_email_from_account(person, dest_email:, target_email: nil, options: {}, context: "Session")
         | 
| 22 | 
            +
                    return false if options.dig(:exclude, :account)
         | 
| 23 | 
            +
                    return false unless account     = person.account
         | 
| 24 | 
            +
                    return false unless had_account = person.original_doc["account"]
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                    target_email  ||= person.email
         | 
| 27 | 
            +
                    account_email   = person.original_doc["email"]
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                    return false unless target_email != account_email
         | 
| 30 | 
            +
                    return false if account_email.to_s.strip.empty?
         | 
| 31 | 
            +
                    return false if target_email.to_s.strip.empty?
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                    if dest_email.is_a?(String)
         | 
| 34 | 
            +
                      return false unless target_email != dest_email
         | 
| 35 | 
            +
                      return false unless dest_email   != account_email
         | 
| 36 | 
            +
                      return false if dest_email.to_s.strip.empty?
         | 
| 37 | 
            +
                    end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                    account_json  = JSON.parse(account.to_json)
         | 
| 40 | 
            +
                    person.email = account_email
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                    if success = _take_email_remove_account!(person, context: context)
         | 
| 43 | 
            +
                      if success = _take_email_acquire_account!(person, target_email, account: {}, context: context)
         | 
| 44 | 
            +
                        if success = _take_email_email_free_up!(person, dest_email: dest_email, context: context)
         | 
| 45 | 
            +
                          if success = _take_email_remove_account!(person, context: context)
         | 
| 46 | 
            +
                            if success = _take_email_acquire_account!(person, account_email, account: account_json, context: context)
         | 
| 47 | 
            +
                              person.email = target_email
         | 
| 48 | 
            +
                            end
         | 
| 49 | 
            +
                          end
         | 
| 50 | 
            +
                        else # free up target email
         | 
| 51 | 
            +
                          # restore
         | 
| 52 | 
            +
                          if _take_email_remove_account!(person, context: context)
         | 
| 53 | 
            +
                            _take_email_acquire_account!(person, account_email, account: account_json, context: context)
         | 
| 54 | 
            +
                          end
         | 
| 55 | 
            +
                          success = false
         | 
| 56 | 
            +
                        end
         | 
| 57 | 
            +
                      else # aquire other account
         | 
| 58 | 
            +
                        # restore
         | 
| 59 | 
            +
                        _take_email_acquire_account!(person, account_email, account: account_json, context: context)
         | 
| 60 | 
            +
                        success = false
         | 
| 61 | 
            +
                      end
         | 
| 62 | 
            +
                    end
         | 
| 63 | 
            +
                    success
         | 
| 64 | 
            +
                  end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                  private
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                  def _take_email_acquire_account!(person, target_email, account: {}, context: "Session")
         | 
| 69 | 
            +
                    person.account = account
         | 
| 70 | 
            +
                    person.account.send_invites = false
         | 
| 71 | 
            +
                    person.email   = target_email
         | 
| 72 | 
            +
                    micro.person_update!(person, reason: "bring account with email '#{target_email}'", context: context)
         | 
| 73 | 
            +
                  end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                  def _take_email_email_free_up!(person, dest_email:, target_email: nil, context: "Session")
         | 
| 76 | 
            +
                    target_email ||= person.email
         | 
| 77 | 
            +
                    person.email   = dest_email.is_a?(Proc)? dest_email.call(target_email) : dest_email
         | 
| 78 | 
            +
                    reason = "free up email '#{target_email}', by moving account to '#{person.email}'"
         | 
| 79 | 
            +
                    micro.person_update!(person, reason: reason, context: context)
         | 
| 80 | 
            +
                  end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                  def _take_email_remove_account!(person, context: "Session")
         | 
| 83 | 
            +
                    person.account = nil
         | 
| 84 | 
            +
                    micro.person_update!(person, reason: "remove account", context: context)
         | 
| 85 | 
            +
                  end
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                end
         | 
| 88 | 
            +
              end
         | 
| 89 | 
            +
            end
         | 
    
        data/lib/eco/api/microcases.rb
    CHANGED
    
    | @@ -19,6 +19,7 @@ require_relative 'microcases/people_cache' | |
| 19 19 | 
             
            require_relative 'microcases/people_load'
         | 
| 20 20 | 
             
            require_relative 'microcases/people_refresh'
         | 
| 21 21 | 
             
            require_relative 'microcases/people_search'
         | 
| 22 | 
            +
            require_relative 'microcases/person_update'
         | 
| 22 23 | 
             
            require_relative 'microcases/preserve_filter_tags'
         | 
| 23 24 | 
             
            require_relative 'microcases/preserve_default_tag'
         | 
| 24 25 | 
             
            require_relative 'microcases/preserve_policy_groups'
         | 
| @@ -26,9 +27,10 @@ require_relative 'microcases/set_account' | |
| 26 27 | 
             
            require_relative 'microcases/set_core_with_supervisor'
         | 
| 27 28 | 
             
            require_relative 'microcases/set_core'
         | 
| 28 29 | 
             
            require_relative 'microcases/refresh_default_tag'
         | 
| 30 | 
            +
            require_relative 'microcases/s3upload_targets'
         | 
| 29 31 | 
             
            require_relative 'microcases/set_supervisor'
         | 
| 30 32 | 
             
            require_relative 'microcases/strict_search'
         | 
| 31 | 
            -
            require_relative 'microcases/ | 
| 33 | 
            +
            require_relative 'microcases/take_email_from_account'
         | 
| 32 34 | 
             
            require_relative 'microcases/with_each'
         | 
| 33 35 | 
             
            require_relative 'microcases/with_each_leaver'
         | 
| 34 36 | 
             
            require_relative 'microcases/with_each_present'
         | 
| @@ -3,6 +3,8 @@ module Eco | |
| 3 3 | 
             
                class Session
         | 
| 4 4 | 
             
                  class Batch
         | 
| 5 5 | 
             
                    class Jobs < API::Common::Session::BaseSession
         | 
| 6 | 
            +
                      DELAY_BETWEEN_JOBS = 0.3
         | 
| 7 | 
            +
             | 
| 6 8 | 
             
                      include Enumerable
         | 
| 7 9 | 
             
                      attr_reader :name
         | 
| 8 10 |  | 
| @@ -87,11 +89,12 @@ module Eco | |
| 87 89 | 
             
                      #   - if there was post-launch callback for a `Batch::Job`, it calls it.
         | 
| 88 90 | 
             
                      # @return [Hash<Eco::API::Session::Batch::Job, Eco::API::Session::Batch::Status>]
         | 
| 89 91 | 
             
                      def launch(simulate: false)
         | 
| 90 | 
            -
                         | 
| 92 | 
            +
                        each_with_index do |job, idx|
         | 
| 91 93 | 
             
                          if job.pending?
         | 
| 92 94 | 
             
                            status[job] = job_status = job.launch(simulate: simulate)
         | 
| 93 95 | 
             
                            callback    = @callbacks[job]
         | 
| 94 96 | 
             
                            callback.call(job, job_status) if callback
         | 
| 97 | 
            +
                            Eco::API::Session::Batch::JobsGroups.counter(delay_between_jobs) if !simulate && idx < self.length - 1
         | 
| 95 98 | 
             
                          end
         | 
| 96 99 | 
             
                        end
         | 
| 97 100 | 
             
                        launch(simulate: simulate) if pending?
         | 
| @@ -125,6 +128,11 @@ module Eco | |
| 125 128 | 
             
                        end.join("\n")
         | 
| 126 129 | 
             
                      end
         | 
| 127 130 |  | 
| 131 | 
            +
                      private
         | 
| 132 | 
            +
             | 
| 133 | 
            +
                      def delay_between_jobs
         | 
| 134 | 
            +
                        config.delay_between_jobs || DELAY_BETWEEN_JOBS
         | 
| 135 | 
            +
                      end
         | 
| 128 136 | 
             
                    end
         | 
| 129 137 | 
             
                  end
         | 
| 130 138 | 
             
                end
         | 
| @@ -93,10 +93,10 @@ module Eco | |
| 93 93 | 
             
                            status[group] = group_status = group.launch(simulate: simulate)
         | 
| 94 94 | 
             
                            callback = @callbacks[group]
         | 
| 95 95 | 
             
                            callback.call(group, group_status) if callback
         | 
| 96 | 
            -
                            self.class.counter( | 
| 96 | 
            +
                            self.class.counter(delay_between_groups) if !simulate && idx < @order.length - 1
         | 
| 97 97 | 
             
                          end
         | 
| 98 98 | 
             
                        end
         | 
| 99 | 
            -
                        launch(simulate: simulate) if pending? | 
| 99 | 
            +
                        launch(simulate: simulate) if pending?
         | 
| 100 100 | 
             
                        return status
         | 
| 101 101 | 
             
                      end
         | 
| 102 102 |  | 
| @@ -127,6 +127,11 @@ module Eco | |
| 127 127 | 
             
                        end.join("\n")
         | 
| 128 128 | 
             
                      end
         | 
| 129 129 |  | 
| 130 | 
            +
                      private
         | 
| 131 | 
            +
             | 
| 132 | 
            +
                      def delay_between_groups
         | 
| 133 | 
            +
                        config.delay_between_job_groups || DELAY_BETWEEN_GROUPS
         | 
| 134 | 
            +
                      end
         | 
| 130 135 | 
             
                    end
         | 
| 131 136 | 
             
                  end
         | 
| 132 137 | 
             
                end
         | 
| @@ -9,6 +9,7 @@ module Eco | |
| 9 9 | 
             
                      ACCOUNT_ATTRS  = (Eco::API::Common::People::PersonParser::ACCOUNT_ATTRS + ["permissions_custom"]).uniq
         | 
| 10 10 | 
             
                      DETAILS_ATTRS  = ["fields"]
         | 
| 11 11 | 
             
                      BLANKED_PREFIX = "blanked_"
         | 
| 12 | 
            +
                      DETAILS_FIELDS = "details_fields"
         | 
| 12 13 |  | 
| 13 14 | 
             
                      class << self
         | 
| 14 15 |  | 
| @@ -74,44 +75,43 @@ module Eco | |
| 74 75 | 
             
                      end
         | 
| 75 76 |  | 
| 76 77 | 
             
                      def message(percent: false)
         | 
| 77 | 
            -
                        key_val_delimiter = ": "; attr_delimiter = " ++ "
         | 
| 78 | 
            -
                        pairs_to_line = Proc.new do |pairs|
         | 
| 79 | 
            -
                          pairs.map do |p|
         | 
| 80 | 
            -
                            [p.first.to_s, "#{p.last.to_s}" + (percent ? "%" : "")].join(key_val_delimiter)
         | 
| 81 | 
            -
                          end.join(attr_delimiter)
         | 
| 82 | 
            -
                        end
         | 
| 83 | 
            -
             | 
| 84 78 | 
             
                        lines = []
         | 
| 85 | 
            -
                        lines << pairs_to_line | 
| 86 | 
            -
                        lines << pairs_to_line | 
| 87 | 
            -
                        lines << pairs_to_line | 
| 79 | 
            +
                        lines << pairs_to_line(core_pairs(percent: percent))
         | 
| 80 | 
            +
                        lines << pairs_to_line(account_pairs(percent: percent))
         | 
| 81 | 
            +
                        lines << pairs_to_line(details_pairs(percent: percent))
         | 
| 88 82 | 
             
                        lines.join("\n")
         | 
| 89 83 | 
             
                      end
         | 
| 90 84 |  | 
| 91 85 | 
             
                      private
         | 
| 92 86 |  | 
| 93 | 
            -
                      def  | 
| 94 | 
            -
                         | 
| 87 | 
            +
                      def attr_value(attr, percent: false, total: count, details: false)
         | 
| 88 | 
            +
                        target = details ? (@stats[DETAILS_FIELDS] || {}) : @stats
         | 
| 89 | 
            +
                        i = target["#{attr}"]
         | 
| 95 90 | 
             
                        return i unless percent
         | 
| 96 91 | 
             
                        percentage(i, total: total)
         | 
| 97 92 | 
             
                      end
         | 
| 98 93 |  | 
| 99 94 | 
             
                      def core(percent: false)
         | 
| 100 | 
            -
                         | 
| 95 | 
            +
                        attr_value("core", percent: percent)
         | 
| 101 96 | 
             
                      end
         | 
| 102 97 |  | 
| 103 98 | 
             
                      def account(percent: false)
         | 
| 104 | 
            -
                         | 
| 99 | 
            +
                        attr_value("account", percent: percent)
         | 
| 105 100 | 
             
                      end
         | 
| 106 101 |  | 
| 107 102 | 
             
                      def details(percent: false)
         | 
| 108 | 
            -
                         | 
| 103 | 
            +
                        attr_value("details", percent: percent)
         | 
| 104 | 
            +
                      end
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                      def stats
         | 
| 107 | 
            +
                        @stats ||= Hash.new(0)
         | 
| 109 108 | 
             
                      end
         | 
| 110 109 |  | 
| 111 110 | 
             
                      def build(requests)
         | 
| 112 | 
            -
                         | 
| 111 | 
            +
                        stats.tap do |stats|
         | 
| 113 112 | 
             
                          stats[type] = count
         | 
| 114 113 | 
             
                          unless !requests || !requests.is_a?(Enumerable) || requests.empty?
         | 
| 114 | 
            +
                            stats[DETAILS_FIELDS] = Hash.new(0)
         | 
| 115 115 | 
             
                            requests.each_with_index do |request|
         | 
| 116 116 | 
             
                              add_core_stats(stats, request || {})
         | 
| 117 117 | 
             
                              add_account_stats(stats, request || {})
         | 
| @@ -149,16 +149,15 @@ module Eco | |
| 149 149 | 
             
                        if request.key?("details")
         | 
| 150 150 | 
             
                          stats["details"] += 1
         | 
| 151 151 | 
             
                          stats["details_remove"] += 1 if !request["details"]
         | 
| 152 | 
            +
             | 
| 153 | 
            +
                          det_attrs = {}
         | 
| 152 154 | 
             
                          if fields = request.dig("details", "fields")
         | 
| 153 155 | 
             
                            stats["fields"] += fields.length
         | 
| 156 | 
            +
                            det_attrs = fields.each_with_object(det_attrs) {|fld, hash| hash[fld["alt_id"]] = fld["value"]}
         | 
| 154 157 | 
             
                          end
         | 
| 155 | 
            -
                        end
         | 
| 156 | 
            -
                      end
         | 
| 157 158 |  | 
| 158 | 
            -
             | 
| 159 | 
            -
                         | 
| 160 | 
            -
                          (v = attr(a, percent: percent, total: count)) > 0 ? [a, v] : nil
         | 
| 161 | 
            -
                        end.compact
         | 
| 159 | 
            +
                          attrs_to_stat(stats[DETAILS_FIELDS], det_attrs, det_attrs.keys)
         | 
| 160 | 
            +
                        end
         | 
| 162 161 | 
             
                      end
         | 
| 163 162 |  | 
| 164 163 | 
             
                      def core_pairs(percent: false)
         | 
| @@ -172,22 +171,23 @@ module Eco | |
| 172 171 | 
             
                      end
         | 
| 173 172 |  | 
| 174 173 | 
             
                      def details_pairs(percent: false)
         | 
| 175 | 
            -
                         | 
| 176 | 
            -
                         | 
| 177 | 
            -
                         | 
| 174 | 
            +
                        det_pairs  = [["details", details(percent: percent)]]
         | 
| 175 | 
            +
                        det_pairs += [["fields", fields_average]] if attr_value("fields") && fields_average
         | 
| 176 | 
            +
                        det_pairs += pairs(["details_remove"], percent: percent, total: details)
         | 
| 177 | 
            +
                        det_pairs += pairs(details_field_attrs, percent: percent, total: details, details: true)
         | 
| 178 178 | 
             
                      end
         | 
| 179 179 |  | 
| 180 | 
            -
                      def  | 
| 181 | 
            -
                         | 
| 182 | 
            -
                          ( | 
| 183 | 
            -
                        end
         | 
| 180 | 
            +
                      def pairs(attrs, percent: false, total: count, details: false)
         | 
| 181 | 
            +
                        pairs = attrs.map do |a|
         | 
| 182 | 
            +
                          (v = attr_value(a, percent: percent, total: count, details: details)) > 0 ? [a, v] : nil
         | 
| 183 | 
            +
                        end.compact
         | 
| 184 184 | 
             
                      end
         | 
| 185 185 |  | 
| 186 | 
            -
                      def  | 
| 187 | 
            -
                         | 
| 188 | 
            -
                         | 
| 189 | 
            -
                           | 
| 190 | 
            -
                        end
         | 
| 186 | 
            +
                      def pairs_to_line(pairs, percent: false)
         | 
| 187 | 
            +
                        key_val_delimiter = ": "; attr_delimiter = " ++ "
         | 
| 188 | 
            +
                        pairs.map do |p|
         | 
| 189 | 
            +
                          [p.first.to_s, "#{p.last.to_s}" + (percent ? "%" : "")].join(key_val_delimiter)
         | 
| 190 | 
            +
                        end.join(attr_delimiter)
         | 
| 191 191 | 
             
                      end
         | 
| 192 192 |  | 
| 193 193 | 
             
                      def core_attrs
         | 
| @@ -202,6 +202,10 @@ module Eco | |
| 202 202 | 
             
                        @details_attrs ||= self.class.details_attrs
         | 
| 203 203 | 
             
                      end
         | 
| 204 204 |  | 
| 205 | 
            +
                      def details_field_attrs
         | 
| 206 | 
            +
                        @stats[DETAILS_FIELDS].keys
         | 
| 207 | 
            +
                      end
         | 
| 208 | 
            +
             | 
| 205 209 | 
             
                      def blank_attrs(attrs)
         | 
| 206 210 | 
             
                        self.class.blank_attrs(attrs)
         | 
| 207 211 | 
             
                      end
         | 
| @@ -225,6 +229,18 @@ module Eco | |
| 225 229 | 
             
                        end
         | 
| 226 230 | 
             
                      end
         | 
| 227 231 |  | 
| 232 | 
            +
                      def fields_average
         | 
| 233 | 
            +
                        if (fields_num = attr_value("fields")) && (total = details) > 0
         | 
| 234 | 
            +
                          (fields_num.to_f / total.to_f).round(2)
         | 
| 235 | 
            +
                        end
         | 
| 236 | 
            +
                      end
         | 
| 237 | 
            +
             | 
| 238 | 
            +
                      def percentage(num, total: count)
         | 
| 239 | 
            +
                        total ||= count
         | 
| 240 | 
            +
                        if num
         | 
| 241 | 
            +
                          (num.to_f / total * 100).round(2)
         | 
| 242 | 
            +
                        end
         | 
| 243 | 
            +
                      end
         | 
| 228 244 | 
             
                    end
         | 
| 229 245 | 
             
                  end
         | 
| 230 246 | 
             
                end
         | 
| @@ -363,6 +363,18 @@ module Eco | |
| 363 363 | 
             
                        yield(wf) if block_given?
         | 
| 364 364 | 
             
                      end
         | 
| 365 365 | 
             
                    end
         | 
| 366 | 
            +
             | 
| 367 | 
            +
                    # @return [nil, Interger] seconds between jobs
         | 
| 368 | 
            +
                    def delay_between_jobs(seconds = nil)
         | 
| 369 | 
            +
                      self["delay_between_jobs"] = seconds if seconds
         | 
| 370 | 
            +
                      self["delay_between_jobs"]
         | 
| 371 | 
            +
                    end
         | 
| 372 | 
            +
             | 
| 373 | 
            +
                    # @return [nil, Interger] seconds between job groups
         | 
| 374 | 
            +
                    def delay_between_job_groups(seconds = nil)
         | 
| 375 | 
            +
                      self["delay_between_job_groups"] = seconds if seconds
         | 
| 376 | 
            +
                      self["delay_between_job_groups"]
         | 
| 377 | 
            +
                    end
         | 
| 366 378 | 
             
                    # @!endgroup
         | 
| 367 379 |  | 
| 368 380 | 
             
                  end
         | 
| @@ -0,0 +1,25 @@ | |
| 1 | 
            +
            class Eco::API::UseCases::DefaultCases::TagPaths < Eco::API::Common::Loaders::UseCase
         | 
| 2 | 
            +
              name "create-tag-paths"
         | 
| 3 | 
            +
              type :other
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              def main(session, options, usecase)
         | 
| 6 | 
            +
                CSV.open("tag_paths.csv", "w") do |csv|
         | 
| 7 | 
            +
                  csv << ["Tag", "Path"]
         | 
| 8 | 
            +
                  tag_paths.each do |values|
         | 
| 9 | 
            +
                    csv << values
         | 
| 10 | 
            +
                  end
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              private
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              def tag_paths
         | 
| 17 | 
            +
                @tag_paths ||= tagtree.tags.map do |tag|
         | 
| 18 | 
            +
                  [tag, tagtree.path(tag).join("|")]
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              def tagtree
         | 
| 23 | 
            +
                session.tagtree
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
            end
         | 
| @@ -2,16 +2,25 @@ class Eco::API::UseCases::DefaultCases::ReinviteTransCase < Eco::API::Common::Lo | |
| 2 2 | 
             
              name "reinvite"
         | 
| 3 3 | 
             
              type :transform
         | 
| 4 4 |  | 
| 5 | 
            +
              def main(people, session, options, usecase)
         | 
| 6 | 
            +
                reinvite(people.users, session, options, usecase)
         | 
| 7 | 
            +
              end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              private
         | 
| 10 | 
            +
             | 
| 5 11 | 
             
              def reinvite(users, session, options, usecase)
         | 
| 6 12 | 
             
                invite   = session.new_job("main", "invite", :update, usecase, :account)
         | 
| 7 13 | 
             
                users.each do |person|
         | 
| 8 | 
            -
                   | 
| 14 | 
            +
                  if force_invite?
         | 
| 15 | 
            +
                    person.account.send_invites = true
         | 
| 16 | 
            +
                  else
         | 
| 17 | 
            +
                    person.account.force_send_invites = true
         | 
| 18 | 
            +
                  end
         | 
| 9 19 | 
             
                  invite.add(person)
         | 
| 10 20 | 
             
                end
         | 
| 11 21 | 
             
              end
         | 
| 12 22 |  | 
| 13 | 
            -
              def  | 
| 14 | 
            -
                 | 
| 23 | 
            +
              def force_invite?
         | 
| 24 | 
            +
                options.dig(:force, :invite)
         | 
| 15 25 | 
             
              end
         | 
| 16 | 
            -
             | 
| 17 26 | 
             
            end
         | 
| @@ -28,7 +28,7 @@ class Eco::API::UseCases::DefaultCases::Samples::Sftp < Eco::API::Common::Loader | |
| 28 28 |  | 
| 29 29 | 
             
              # Ex: "/IN/Personnel"
         | 
| 30 30 | 
             
              def remote_subfolder
         | 
| 31 | 
            -
                raise "You should redefine remote_subfolder as the folder where the target file sits"
         | 
| 31 | 
            +
                raise "You should redefine remote_subfolder as the folder where the target file sits. Ex: /IN/Personnel"
         | 
| 32 32 | 
             
              end
         | 
| 33 33 |  | 
| 34 34 | 
             
              def archive_subfolder
         | 
| @@ -19,6 +19,7 @@ require_relative 'default_cases/codes_to_tags_case' | |
| 19 19 | 
             
            require_relative 'default_cases/create_case'
         | 
| 20 20 | 
             
            require_relative 'default_cases/create_details_case'
         | 
| 21 21 | 
             
            require_relative 'default_cases/create_details_with_supervisor_case'
         | 
| 22 | 
            +
            require_relative 'default_cases/create_tag_paths_case'
         | 
| 22 23 | 
             
            require_relative 'default_cases/delete_trans_case'
         | 
| 23 24 | 
             
            require_relative 'default_cases/delete_sync_case'
         | 
| 24 25 | 
             
            require_relative 'default_cases/email_as_id_case'
         | 
| @@ -87,6 +87,9 @@ ASSETS.cli.config do |cnf| | |
| 87 87 | 
             
                  options.deep_merge!(other: {file: {codes_column: col_codes}})
         | 
| 88 88 | 
             
                end
         | 
| 89 89 |  | 
| 90 | 
            +
                desc = "Creates a CSV with the paths to each tag"
         | 
| 91 | 
            +
                cases.add("-create-tag-paths", :other, desc, case_name: "create-tag-paths")
         | 
| 92 | 
            +
             | 
| 90 93 | 
             
                desc  = "Cleans from filter_tags those tags that are not present in the tagtree (as per tagtree.json file)."
         | 
| 91 94 | 
             
                desc += " It will preserve standard register tags of most common registers (i.e. EVENT, RISK)."
         | 
| 92 95 | 
             
                cases.add("-clean-unknown-tags", :transform, desc, case_name: "clean-unknown-tags")
         | 
| @@ -183,9 +186,15 @@ ASSETS.cli.config do |cnf| | |
| 183 186 |  | 
| 184 187 | 
             
                desc = "Re-sends invites to all filtered users that have not accepted the invite as yet"
         | 
| 185 188 | 
             
                cases.add("-reinvite", :transform, desc, case_name: "reinvite")
         | 
| 189 | 
            +
                .add_option("-force", "If also send an invite email to those that have accepted the invite") do |options|
         | 
| 190 | 
            +
                  options.deep_merge!(force: {invite: true})
         | 
| 191 | 
            +
                end
         | 
| 186 192 |  | 
| 187 193 | 
             
                desc = "Re-sends invites to target users that have not accepted the invite as yet"
         | 
| 188 194 | 
             
                cases.add("-reinvite-from", :sync, desc, case_name: "reinvite")
         | 
| 195 | 
            +
                .add_option("-force", "If also send an invite email to those that have accepted the invite") do |options|
         | 
| 196 | 
            +
                  options.deep_merge!(force: {invite: true})
         | 
| 197 | 
            +
                end
         | 
| 189 198 |  | 
| 190 199 | 
             
                desc = "Deletes everybody that has been filtered from the people manager"
         | 
| 191 200 | 
             
                cases.add("-delete", :transform, desc, case_name: "delete")
         | 
    
        data/lib/eco/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: eco-helpers
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 2.0. | 
| 4 | 
            +
              version: 2.0.51
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Oscar Segura
         | 
| @@ -462,6 +462,7 @@ files: | |
| 462 462 | 
             
            - lib/eco/api/microcases/people_load.rb
         | 
| 463 463 | 
             
            - lib/eco/api/microcases/people_refresh.rb
         | 
| 464 464 | 
             
            - lib/eco/api/microcases/people_search.rb
         | 
| 465 | 
            +
            - lib/eco/api/microcases/person_update.rb
         | 
| 465 466 | 
             
            - lib/eco/api/microcases/preserve_default_tag.rb
         | 
| 466 467 | 
             
            - lib/eco/api/microcases/preserve_filter_tags.rb
         | 
| 467 468 | 
             
            - lib/eco/api/microcases/preserve_policy_groups.rb
         | 
| @@ -472,6 +473,7 @@ files: | |
| 472 473 | 
             
            - lib/eco/api/microcases/set_core_with_supervisor.rb
         | 
| 473 474 | 
             
            - lib/eco/api/microcases/set_supervisor.rb
         | 
| 474 475 | 
             
            - lib/eco/api/microcases/strict_search.rb
         | 
| 476 | 
            +
            - lib/eco/api/microcases/take_email_from_account.rb
         | 
| 475 477 | 
             
            - lib/eco/api/microcases/with_each.rb
         | 
| 476 478 | 
             
            - lib/eco/api/microcases/with_each_leaver.rb
         | 
| 477 479 | 
             
            - lib/eco/api/microcases/with_each_present.rb
         | 
| @@ -530,6 +532,7 @@ files: | |
| 530 532 | 
             
            - lib/eco/api/usecases/default_cases/create_case.rb
         | 
| 531 533 | 
             
            - lib/eco/api/usecases/default_cases/create_details_case.rb
         | 
| 532 534 | 
             
            - lib/eco/api/usecases/default_cases/create_details_with_supervisor_case.rb
         | 
| 535 | 
            +
            - lib/eco/api/usecases/default_cases/create_tag_paths_case.rb
         | 
| 533 536 | 
             
            - lib/eco/api/usecases/default_cases/delete_sync_case.rb
         | 
| 534 537 | 
             
            - lib/eco/api/usecases/default_cases/delete_trans_case.rb
         | 
| 535 538 | 
             
            - lib/eco/api/usecases/default_cases/email_as_id_case.rb
         |