Class: Eco::API::MicroCases

Inherits:
Common::Session::BaseSession show all
Defined in:
lib/eco/api/microcases.rb,
lib/eco/api/microcases/set_core.rb,
lib/eco/api/microcases/with_each.rb,
lib/eco/api/microcases/people_load.rb,
lib/eco/api/microcases/set_account.rb,
lib/eco/api/microcases/people_cache.rb,
lib/eco/api/microcases/core_excluded.rb,
lib/eco/api/microcases/people_search.rb,
lib/eco/api/microcases/strict_search.rb,
lib/eco/api/microcases/people_refresh.rb,
lib/eco/api/microcases/set_supervisor.rb,
lib/eco/api/microcases/fix_filter_tags.rb,
lib/eco/api/microcases/with_supervisor.rb,
lib/eco/api/microcases/account_excluded.rb,
lib/eco/api/microcases/s3upload_targets.rb,
lib/eco/api/microcases/with_each_leaver.rb,
lib/eco/api/microcases/append_usergroups.rb,
lib/eco/api/microcases/fix_default_group.rb,
lib/eco/api/microcases/refresh_abilities.rb,
lib/eco/api/microcases/with_each_present.rb,
lib/eco/api/microcases/with_each_starter.rb,
lib/eco/api/microcases/refresh_default_tag.rb,
lib/eco/api/microcases/with_each_subordinate.rb,
lib/eco/api/microcases/set_core_with_supervisor.rb

Instance Attribute Summary

Attributes inherited from Common::Session::BaseSession

#api, #config, #environment, #file_manager, #logger, #session

Instance Method Summary collapse

Methods inherited from Common::Session::BaseSession

#enviro=, #fatal, #fm, #initialize, #mailer, #mailer?, #s3uploader, #s3uploader?, #sftp, #sftp?

Constructor Details

This class inherits a constructor from Eco::API::Common::Session::BaseSession

Instance Method Details

#account_excluded(person, options) ⇒ Array<String>

Returns the account parameters that should not be included.

Parameters:

Returns:

  • (Array<String>)

    the account parameters that should not be included.



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/eco/api/microcases/account_excluded.rb', line 7

def (person, options)
  [].tap do ||
    unless person.new?
      if options.dig(:exclude, :policy_groups)
        .push("policy_group_ids")
      end
      if options.dig(:exclude, :default_tag)
        .push("default_tag")
      end
      if options.dig(:exclude, :login_providers)
        .push("login_provider_ids")
      end
    end
  end
end

#append_usergroups(entry, person, options) ⇒ Object

It preserves the usergroups of person and appends those defined in policy_group_ids of the entry

Parameters:

  • entry (PersonEntry)

    the input entry with the data we should set on person.

  • person (Ecoportal::API::V1::Person)

    the person we want to update, carrying the changes to be done.

  • options (Hash)

    the options.



8
9
10
11
12
13
14
15
# File 'lib/eco/api/microcases/append_usergroups.rb', line 8

def append_usergroups(entry, person, options)
  unless options.dig(:exclude, :account)
    if person.
      person..policy_group_ids |= entry.policy_group_ids
      micro.refresh_abilities(person, options)
    end
  end
end

#core_excluded(person, options) ⇒ Array<String>

Note:

by default supervisor_id is always excluded.

Returns the core parameters that should not be included.

Parameters:

Returns:

  • (Array<String>)

    the core parameters that should not be included.



8
9
10
11
12
13
14
15
16
17
# File 'lib/eco/api/microcases/core_excluded.rb', line 8

def core_excluded(person, options)
  ["supervisor_id"].tap do |core_excluded|
    unless person.new?
      exclusions = ["name", "external_id", "email", "filter_tags"].select do |attr|
        options.dig(:exclude, attr.to_sym)
      end
      core_excluded.concat(exclusions)
    end
  end
end

#fix_default_group(entry, person, options) ⇒ Object

If defined, it sets the default usergroup, only when the policy_group_ids was not part of the input data.

Parameters:

  • entry (PersonEntry)

    the input entry with the data we should set on person.

  • person (Ecoportal::API::V1::Person)

    the person we want to update, carrying the changes to be done.

  • options (Hash)

    the options.



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/eco/api/microcases/fix_default_group.rb', line 8

def fix_default_group(entry, person, options)
  unless options.dig(:exclude, :account)
    unless options.dig(:exclude, :policy_groups) && !person.new?
      end_pg_ids = person..policy_group_ids

      if person. && __def_usergroup_id && !entry.policy_group_ids?
        # on account creation, if missing policy_group_ids column in the input
        # use default_usergroup, if it's defined
        end_pg_ids = [__def_usergroup_id]
      end

      person..policy_group_ids = end_pg_ids
    end
  end
end

#fix_filter_tags(person, options) ⇒ Object

Note:
  • this feature is essential to preserve custom tags in users that have register tags.
  • for this to work out, it requires a tagtree to be defined.

Helper that makes sure the custom tags are preserved.

Parameters:

Options Hash (options):

  • :filter_tags (Hash<Symbol, Object>)

    options around filter_tags.

    • :preserve_custom (Boolean) [true] indicates if original tags that are not in the tree should be added/preserved.
    • :add_custom (Boolean) [true] indicates if target tags that are not in the tree should be really added.


13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/eco/api/microcases/fix_filter_tags.rb', line 13

def fix_filter_tags(person, options)
  if session.tagtree
    unless !person.new? && (options.dig(:exclude, :core) || options.dig(:exclude, :filter_tags))
      person.filter_tags = session.tagtree.user_tags(
        initial:          person.original_doc["filter_tags"] || [],
        final:            person.filter_tags,
        preserve_custom:  _fix_filter_tags_preserve_custom?(options),
        add_custom:       _fix_filter_tags_add_custom?(options)
      )
    end
  end
end

#microObject



5
6
7
# File 'lib/eco/api/microcases.rb', line 5

def micro
  self
end

#people_cache(filename = enviro.config.people.cache) ⇒ Eco::API::Organization::People

Helper to locally cache the people manager.

Parameters:

  • filename (String) (defaults to: enviro.config.people.cache)

    the name of the file where the data should be cached.

Returns:



7
8
9
10
11
12
13
# File 'lib/eco/api/microcases/people_cache.rb', line 7

def people_cache(filename = enviro.config.people.cache)
  logger.info("Going to get all the people via API")
  people = session.batch.get_people
  file   = file_manager.save_json(people, filename, :timestamp)
  logger.info("#{people.length} people loaded and saved locally to #{file}.")
  Eco::API::Organization::People.new(people)
end

#people_load(filename = enviro.config.people.cache, modifier: [:newest, :api]) ⇒ Eco::API::Organization::People

Note:
  • filename will be relative to the working directory (the one of the session enviro set by the user).

Helper to load People that works in different phases:

  1. first tries to get the newest cached file that follows filename pattern
    • if not the newest, it tries to find the specific filename
  2. if it succeeds to identif a cached file, it loads it
    • if it fails, it tries to get people from the server

Parameters:

  • filename (String) (defaults to: enviro.config.people.cache)

    the name of the file where the cached data is to be found.

  • modifier (Array<Symbol>) (defaults to: [:newest, :api])

    modifiers to specify how this function should proceed:

    • :newest if it should try to find the newest file (pattern alike).
    • :api if it should try to get people from the server in case there's no cache.
    • :file if it is supposed to load people from a file.
    • :save if it is supposed to cache/save the data locally once obtained people from the server (:api)

Returns:



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/eco/api/microcases/people_load.rb', line 18

def people_load(filename = enviro.config.people.cache, modifier: [:newest, :api])
  modifier  = [modifier].flatten
  load_file = [:file, :newest].any? {|flag| modifier.include?(flag)}
  people    = case
              when filename && load_file
                if file = people_load_filename(filename, newest: modifier.include?(:newest))
                  file_manager.load_json(file).tap do |people|
                    logger.info("#{people&.length} people loaded from file #{file}") if people.is_a?(Array)
                  end
                else
                  logger.error("could not find the file #{file_manager.dir.file(filename)}")
                  exit unless modifier.include?(:api)
                  people_load(modifier: modifier - [:newest, :file])
                end
              when modifier.include?(:api)
                logger.info("Going to get all the people via API")
                session.batch.get_people.tap do |people|
                  if modifier.include?(:save) && people && people.length > 0
                    file = file_manager.save_json(people, filename, :timestamp)
                    logger.info("#{people.length } people saved to file #{file}.")
                  end
                end
              end
  Eco::API::Organization::People.new(people)
end

#people_refresh(people:, include_created: true) ⇒ Eco::API::Organization::People

Note:

this helper is normally used to run consecutive usecases, where data needs refresh.

Helper to obtain all the elements of people anew from the People Manager.

Parameters:

  • people (Eco::API::Organization::People)

    the people that needs refresh.

  • include_created (Boolean) (defaults to: true)

    include people created during this session? (will check :create batch jobs).

Returns:



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/eco/api/microcases/people_refresh.rb', line 9

def people_refresh(people:, include_created: true)
  ini = people.length
  if include_created
    session.job_groups.find_jobs(type: :create).map do |job|
      people = people.merge(job.people)
    end
  end

  created = people.length - ini
  msg  = "Going to refresh #{people.length} people with server data"
  msg += " (including #{created} that were created)" if created > 0
  logger.info(msg)
  entries = session.batch.get_people(people, silent: true)

  missing = people.length - entries.length
  logger.error("Missed to obtain #{missing} people during the refresh") if missing > 0

  Eco::API::Organization::People.new(status.people)
end

#people_search(data, options: {}, silent: true) ⇒ Eco::API::Organization::People

Note:
  • this helper is normally used to get partial part of the people manager.
  • therefore, normally used with delta input files (files with only the differences).

Helper to search/obtain people from data against the server (People Manager).

Parameters:

  • data (Eco::API::Organization::People, Enumerable<Person>, Enumerable<Hash>)

    People to search against the server.

  • options (Hash) (defaults to: {})

    the options.

  • silent (Boolean) (defaults to: true)

    false if low level search messages should be shown.

Returns:



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/eco/api/microcases/people_search.rb', line 12

def people_search(data, options: {}, silent: true)
  session.logger.info("Going to api get #{data.length} entries...")
  status = session.batch.search(data, silent: silent)
  people = Eco::API::Organization::People.new(status.people)
  session.logger.info("... could get #{people.length} people (out of #{data.length} entries)")

  # get the supervisors of found people (current supervisors)
  supers = people_search_prepare_supers_request(people)
  if supers.length > 0
    session.logger.info("  Going to api get #{supers.length} current supervisors...")
    status = session.batch.search(supers, silent: silent)
    people = people.merge(status.people, strict: micro.strict_search?(options))
  end

  # get the supervisors referred in the input data (future supervisors)
  supers = people_search_prepare_supers_request(data, people)
  if supers.length > 0
    session.logger.info("  Going to api get #{supers.length} supervisors as per entries...")
    status = session.batch.search(supers, silent: silent)
    people = people.merge(status.people, strict: micro.strict_search?(options))
  end

  session.logger.info("Finally got #{people.length} people (out of #{data.length} entries)")
  people
end

#refresh_abilities(person, options) ⇒ Object

It sets the correct set of abilities based on the usergroups of person.

Parameters:



7
8
9
10
11
12
13
14
15
# File 'lib/eco/api/microcases/refresh_abilities.rb', line 7

def refresh_abilities(person, options)
  unless options.dig(:exclude, :account)
    if person.
      unless options.dig(:exclude, :abilities) && !person.new?
        person..permissions_custom = session.new_preset(person)
      end
    end
  end
end

#refresh_default_tag(entry, person, options) ⇒ Object

Note:

it assumes default_tag has been already set to person.account

When the input data, or entry, does not provide the default_tag, it sets the default_tag of the user following some criteria

Parameters:

  • entry (PersonEntry)

    the input entry with the data we should set on person.

  • person (Ecoportal::API::V1::Person)

    the person we want to update, carrying the changes to be done.

  • options (Hash)

    the options



10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/eco/api/microcases/refresh_default_tag.rb', line 10

def refresh_default_tag(entry, person, options)
  if person.
    unless options.dig(:exclude, :account)
      unless options.dig(:exclude, :filter_tags) || options.dig(:exclude, :default_tag) || entry&.default_tag?
        if session.tagtree
          person..default_tag = session.tagtree.default_tag(*person.filter_tags)
        else
          tags = person.filter_tags || []
          person..default_tag = tags.first unless tags.length > 1
        end
      end
    end
  end
end

#s3upload_targetsArray<String>

Helper to upload target files to S3.

Returns:

  • (Array<String>)

    the paths in S3 of the uploaded files.



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/eco/api/microcases/s3upload_targets.rb', line 6

def s3upload_targets
  [].tap do |paths|
    session.config.s3storage.target_files.each_with_object(paths) do |file, arr|
      arr.push(session.s3upload(file: file))
    end
    session.config.s3storage.target_directories.each_with_object(paths) do |folder, arr|
      arr.concat(session.s3upload(directory: folder))
    end
    session.config.s3storage.target_file_patterns.each_with_object(paths) do |pattern, arr|
      filenames = []
      case pattern
      when Regexp
        Dir.entries(".").sort.each do |file|
          next unless File.file?(file) # Skip directories
          filenames.push(file) if file =~ pattern
        end
      when String
        Dir.glob(pattern).sort.each do |file|
          next unless File.file?(file) # Skip directories
          filenames.push(file)
        end
      else
        # missconfiguration
      end
      filenames.each do |file|
        arr.push(session.s3upload(file: file))
      end
    end
  end
end

#set_account(entry, person, options) ⇒ Object

Parameters:

  • entry (PersonEntry)

    the input entry with the data we should set on person.

  • person (Ecoportal::API::V1::Person)

    the person we want to update, carrying the changes to be done.

  • options (Hash)

    the options.



7
8
9
10
11
12
13
14
15
16
# File 'lib/eco/api/microcases/set_account.rb', line 7

def (entry, person, options)
  unless options.dig(:exclude, :account)
    entry.(person, exclude: micro.(person, options))

    person..send_invites = options[:send_invites] if options.key?(:send_invites)
    micro.refresh_default_tag(entry, person, options)
    micro.fix_default_group(entry, person, options)
    micro.refresh_abilities(person, options)
  end
end

#set_core(entry, person, options) ⇒ Object

Note:

supervisor_id requires a special treatment, and therefore is always excluded.

Sets all the core details, but the supervisor.

Parameters:

  • entry (PersonEntry)

    the input entry with the data we should set on person.

  • person (Ecoportal::API::V1::Person)

    the person we want to update, carrying the changes to be done.

  • options (Hash)

    the options



9
10
11
12
13
14
# File 'lib/eco/api/microcases/set_core.rb', line 9

def set_core(entry, person, options)
  unless options.dig(:exclude, :core) && !person.new?
    entry.set_core(person, exclude: micro.core_excluded(person, options))
    micro.fix_filter_tags(person, options)
  end
end

#set_core_with_supervisor(entry, person, people, supers_job, options) ⇒ Object

Note:

supervisor_id requires a special treatment, and therefore is always excluded.

Sets all the core details, but the supervisor.

Parameters:



11
12
13
14
15
16
17
18
19
# File 'lib/eco/api/microcases/set_core_with_supervisor.rb', line 11

def set_core_with_supervisor(entry, person, people, supers_job, options)
  unless options.dig(:exclude, :core) && !person.new?
    micro.set_core(entry, person, options)
    micro.set_supervisor(entry.supervisor_id, person, people, options) do |unkown_id|
      # delay setting supervisor if does not exit
      supers_job.add(person) {|person| person.supervisor_id = unkown_id}
    end
  end
end

#set_supervisor(sup_id, person, people, options) {|supervisor_id| ... } ⇒ Object

Note:

delaying the setting of a supervisor_id can save errors when the supervisor still does not exit.

Special snippet to decide if the supervisor_id is set now or in a later batch job supers_job.

Parameters:

Yields:

  • (supervisor_id)

    callback when the supervisor_id is unknown (not nil nor any one's in people).

Yield Parameters:

  • supervisor_id (String)

    the unknown supervisor_id.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/eco/api/microcases/set_supervisor.rb', line 12

def set_supervisor(sup_id, person, people, options)
  unless options.dig(:exclude, :core) || options.dig(:exclude, :supervisor)
    micro.with_supervisor(sup_id, people) do |supervisor|
      if !sup_id
        person.supervisor_id = nil
      elsif supervisor
        person.supervisor_id = supervisor.id
      elsif !block_given?
        person.supervisor_id = sup_id
      else
        yield(sup_id) if block_given?
      end
    end
  end
end

#strict_search?(options) ⇒ Boolean

Note:
  • strict searches ignore the email when the source entry has an external_id specified.
  • see related command line options -search-strict and -search-soft

When trying to find an person with given a source entry, it states if such a search should be strict or soft.

Parameters:

  • options (Hash)

    the options.

Returns:

  • (Boolean)

    true if the search should be strict only, and false otherwise.



10
11
12
13
14
15
# File 'lib/eco/api/microcases/strict_search.rb', line 10

def strict_search?(options)
  strict_config  = session.config.people.strict_search?
  strict_option  = options.dig(:search, :strict)
  soft_option    = options.dig(:search, :soft) && !strict_option
  (strict_config || strict_option) && !soft_option
end

#with_each(entries, people, options) {|entry, person| ... } ⇒ Eco::API::Organization::People

Note:
  • it also links to person.entry the input data entry.

Finds each entry of entries in people and runs a block.

Parameters:

Yields:

  • (entry, person)

    gives each entry, and the paired person thereof (new or existing).

Yield Parameters:

  • entry (PersonEntry)

    the input entry with the data we should set on person.

  • person (Ecoportal::API::V1::Person)

    the found person that matches entry, or a new person otherwise.

Returns:



14
15
16
17
18
19
20
21
22
23
# File 'lib/eco/api/microcases/with_each.rb', line 14

def with_each(entries, people, options)
  entries.map do |entry|
    unless person = people.find(entry, strict: micro.strict_search?(options))
      person = session.new_person
    end
    person.entry = entry
    yield(entry, person) if block_given?
    person
  end.yield_self {|all_people| people.newFrom all_people.uniq}
end

#with_each_leaver(entries, people, options) {|person| ... } ⇒ Eco::API::Organization::People

Note:

to be used only when the input file is the full DB

Detects who has left the organization and yield s them one by one to the given block

Parameters:

Yields:

  • (person)

    gives each person of people that is not present in entries.

Yield Parameters:

Returns:



12
13
14
15
16
17
18
19
20
# File 'lib/eco/api/microcases/with_each_leaver.rb', line 12

def with_each_leaver(entries, people, options)
  leavers = people.map do |person|
    unless entries.find(person, strict: micro.strict_search?(options))
      yield(person) if block_given?
      person
    end
  end.compact
  people.newFrom leavers
end

#with_each_present(entries, people, options, log_starter: false) {|entry, person| ... } ⇒ Eco::API::Organization::People

Note:
  • it also links to person.entry the input data entry.

Finds those in entries that already exist in the organization (people) and yield s them one by one to the given block.

Parameters:

Yields:

  • (entry, person)

    gives each found person of entries that is not present in people.

Yield Parameters:

  • entry (PersonEntry)

    the input entry with the data we should set on person.

  • person (Ecoportal::API::V1::Person)

    the found person.

Returns:



15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/eco/api/microcases/with_each_present.rb', line 15

def with_each_present(entries, people, options, log_starter: false)
  found = []
  micro.with_each(entries, people, options) do |entry, person|
    if person.new? && log_starter
      session.logger.error("This person does not exist: #{entry.to_s(:identify)}")
      next
    end
    found << person
    yield(entry, person) if block_given?
  end
  people.newFrom found
end

#with_each_starter(entries, people, options, log_present: false) {|entry, person| ... } ⇒ Eco::API::Organization::People

Note:
  • it also links to person.entry the input data entry.

Detects who in the entries is new in the organization and yield s them one by one to the given block.

Parameters:

Yields:

  • (entry, person)

    gives each new person of entries that is not present in people.

Yield Parameters:

  • entry (PersonEntry)

    the input entry with the data we should set on person.

  • person (Ecoportal::API::V1::Person)

    the new person.

Returns:



15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/eco/api/microcases/with_each_starter.rb', line 15

def with_each_starter(entries, people, options, log_present: false)
  starters = []
  micro.with_each(entries, people, options) do |entry, person|
    if !person.new? && log_present
      session.logger.error("This person (id: '#{person.id}') already exists: #{entry.to_s(:identify)}")
      next
    end
    starters << person
    yield(entry, person) if block_given?
  end
  people.newFrom starters
end

#with_each_subordinate(supervisor, people) {|subordinate| ... } ⇒ Eco::API::Organization::People

Note:

if supervisor is nil, it will return all people with no supervisor.

Finds all the subordinates of supervisor.

Parameters:

Yields:

  • (subordinate)

    block that does some stuff with subordinate.

Yield Parameters:

Returns:



11
12
13
14
15
16
17
# File 'lib/eco/api/microcases/with_each_subordinate.rb', line 11

def with_each_subordinate(supervisor, people)
  people.supervisor_id(_person_id(supervisor, people)).tap do |subordinates|
    subordinates.each do |subordinate|
      yield(subordinate) if block_given?
    end
  end
end

#with_supervisor(value, people, strict: false) {|supervisor| ... } ⇒ nil, Ecoportal::API::V1::Person

Finds the supervisor among people by using the supervisor_id of value.

Parameters:

Yields:

  • (supervisor)

    block that does some stuff with supevisor.

Yield Parameters:

Returns:



12
13
14
15
16
17
18
# File 'lib/eco/api/microcases/with_supervisor.rb', line 12

def with_supervisor(value, people, strict: false)
  if sup_id = with_supervisor_supervisor_id(value)
    people.person(id: sup_id, external_id: sup_id, email: sup_id, strict: strict)
  end.tap do |supervisor|
    yield(supervisor) if block_given?
  end
end