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: false) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength log(:info) { "Going to api get #{data.length} entries..." } silent &&= data.count <= 500 start = Time.now people = session.batch.search(data, silent: silent).then do |status| secs = (Time.now - start).round(3) Eco::API::Organization::People.new(status.people).tap do |people| # rubocop:disable Lint/ShadowingOuterLocalVariable cnt = people.count per_sec = (cnt.to_f / secs).round(2) msg = "... could get #{cnt} people " msg << "(out of #{data.length} entries) in #{secs} seconds (#{per_sec} people/sec)" log(:info) { msg } end end # get the supervisors of found people (current supervisors) supers = people_search_prepare_supers_request(people) if supers.length.positive? log(:info) { " Going to api get #{supers.length} current supervisors..." } start = Time.now people = session.batch.search(supers, silent: silent).then 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 " msg << "(out of #{supers.length}) in #{secs} seconds (#{per_sec} people/sec)" log(: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.positive? log(:info) { " Going to api get #{supers.length} supervisors as per input entries..." } start = Time.now people = session.batch.search(supers, silent: silent).then 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 " msg << "(out of #{supers.length}) in #{secs} seconds (#{per_sec} people/sec)" log(:info) { msg } people.merge(found, strict: micro.strict_search?(options)) end end log(: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))} next if !sup_id || request.include?(spr) micro.with_supervisor(sup_id, people) do |supervisor| request.push(spr) unless supervisor 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