module Eco module API class MicroCases # Helper to search/obtain people from `data` against the server (_People Manager_). # @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). # @param data [Eco::API::Organization::People, Enumerable, Enumerable] `People` to search against the server. # @param options [Hash] the options. # @param silent [Boolean] `false` if low level search messages should be shown. # @return [Eco::API::Organization::People] the `People` object with the found persons. def people_search(data, options: {}, silent: true) session.logger.info("Going to api get #{data.length} entries...") start = Time.now people = session.batch.search(data, silent: silent).yield_self do |status| secs = (Time.now - start).round(3) Eco::API::Organization::People.new(status.people).tap do |people| cnt = people.count per_sec = (cnt.to_f / secs).round(2) msg = "... could get #{cnt} people (out of #{data.length} entries) in #{secs} seconds (#{per_sec} people/sec)" session.logger.info(msg) end end # 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...") start = Time.now people = session.batch.search(supers, silent: silent).yield_self do |status| secs = (Time.now - start).round(3) found = status.people cnt = found.count per_sec = (cnt.to_f / secs).round(2) msg = "... could find #{cnt} current supers (out of #{supers.length}) in #{secs} seconds (#{per_sec} people/sec)" session.logger.info(msg) people.merge(found, strict: micro.strict_search?(options)) end 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 input entries...") start = Time.now people = session.batch.search(supers, silent: silent).yield_self do |status| secs = (Time.now - start).round(3) found = status.people cnt = found.count per_sec = (cnt.to_f / secs).round(2) msg = "... could find #{cnt} input supers (out of #{supers.length}) in #{secs} seconds (#{per_sec} people/sec)" session.logger.info(msg) people.merge(found, strict: micro.strict_search?(options)) end end session.logger.info("Finally got #{people.length} people (out of #{data.length} entries)") people end private # Prepares a unique request with only the supervisor ids missing in `people` def people_search_prepare_supers_request(data, people = data) data.each_with_object([]) do |entry, request| spr = {"id" => (sup_id = people_search_super_id(entry))} unless !sup_id || request.include?(spr) micro.with_supervisor(sup_id, people) do |supervisor| request.push(spr) unless supervisor end end end end # Gets the `supervisor_id` from `value` def people_search_super_id(value) sup_id = if value.respond_to?(:supervisor_id) value.supervisor_id elsif value.is_a?(Hash) && value.key("supervisor_id") value["supervisor_id"] end sup_id = nil if sup_id.to_s.strip.empty? sup_id end end end end