class Eco::API::UseCases::DefaultCases::ToCsvCase < Eco::API::Common::Loaders::UseCase name "to-csv" type :export OUT_FILENAME = 'pm' attr_reader :people def main(people, _session, options, _usecase) options[:end_get] = false @people = people unless people && !people.empty? log(:warn) { "No source people to create the file... aborting!" } return false end if options.dig(:export, :options, :split_schemas) by_schema.each do |id, people| sch_name = schemas.to_name(id) prefix = sch_name ? sch_name.gsub(" ", "_").downcase : "no_schema" filename = in_folder("#{prefix}_#{File.basename(file)}") create_file!(filename, people) end else create_file!(file, people) end end private def create_file!(filename = file, data = people) logger.info("going to create file: #{filename}") CSV.open(filename, "w") do |csv| csv << spot_header(data.first) data.each do |person| csv << to_row(person) end end end def to_row(person) entry = to_entry_type(person) entry.values_at(*keys(entry)).tap do |row| row << (schemas.to_name(person.details&.schema_id) || "No Schema") end end def spot_header(person = people.first) header = keys(to_entry_type(person)) header << "Schema" header = yield(header) if block_given? header = nice_header_names(header, schema: schema(person.details)) if nice_header_names? header end def keys(entry) entry.keys - %w[freemium send_invites] end def nice_header_names? options[:nice_header] || options.dig(:export, :options, :nice_header) end def nice_header_names(header, schema: nil) schema ||= session.schema name_maps = schema.fields_by_alt_id.transform_values(&:name).merge(nice_header_maps) header.map {|name| name_maps[name] || name} end def to_entry_type(person) session.new_entry(person, dependencies: deps).then do |person_entry| options.dig(:export, :options, :internal_names) ? person_entry.mapped_entry : person_entry.external_entry end end def deps @deps ||= {"supervisor_id" => {people: people}} end def file @file ||= out_filename.tap do |filename| next if filename log(:error) { "Destination file not specified" } return false end end def out_filename return options_file unless options_folder? File.join(options_file, "#{config.active_enviro}_#{OUT_FILENAME}.csv") end def in_folder(filename) basename = File.basename(filename) return basename unless options_folder? File.join(options_file, basename) end def options_folder? return false unless (value = options_file) File.directory?(value) end def options_file options[:file] || options.dig(:export, :file, :name) end def by_schema people.group_by do |person| if (details = person.details) details.schema_id end end.transform_values do |persons| people.newFrom persons end end def schema(value) case value when Ecoportal::API::V1::Person schema(value.details&.schema_id) when String schemas[value] when Ecoportal::API::V1::PersonDetails schema(value.schema_id) when Ecoportal::API::V1::PersonSchema value end end def schemas session.schemas end def nice_header_maps @nice_header_maps ||= { "policy_group_ids" => "User Group(s)", "email" => "Email", "name" => "Name", "supervisor_id" => "Manager ID", "filter_tags" => "Locations", "default_tag" => "Default Location", "id" => "ecoPortal ID", "external_id" => "Reference ID (ext_id)", "login_provider_ids" => "Login Methods", "landing_page_id" => "Landing Page ID" } end end