class Eco::API::Common::People::DefaultParsers::CSVParser

Public Instance Methods

parser(data, deps) click to toggle source
# File lib/eco/api/common/people/default_parsers/csv_parser.rb, line 4
def parser(data, deps)
  Eco::CSV.parse(data, headers: true, skip_blanks: true).tap do |table|
    check_headers(table) if deps[:check_headers]
  end.each_with_object([]) do |row, arr_hash|
    row_hash = row.headers.uniq.each_with_object({}) do |attr, hash|
      next if attr.to_s.strip.empty?
      hash[attr.strip] = parse_string(row[attr])
    end
    arr_hash.push(row_hash)
  end
end
serializer(array_hash, deps) click to toggle source
# File lib/eco/api/common/people/default_parsers/csv_parser.rb, line 16
def serializer(array_hash, deps)
  arr_rows = []
  unless array_hash.empty?
    header = array_hash.first.keys
    arr_rows = array_hash.map do |csv_row|
      CSV::Row.new(header, csv_row.values_at(*header))
    end
  end
  CSV::Table.new(arr_rows).to_csv
end

Private Instance Methods

all_internal_attrs() click to toggle source
# File lib/eco/api/common/people/default_parsers/csv_parser.rb, line 155
def all_internal_attrs
  @all_internal_attrs ||= [].tap do |int_attrs|
    known_int_attrs  = person_parser.all_attrs(include_defined_parsers: true)
    known_int_attrs |= fields_mapper.list(:internal).compact
    int_attrs.concat(known_int_attrs)
  end
end
check_headers(table) click to toggle source
# File lib/eco/api/common/people/default_parsers/csv_parser.rb, line 41
def check_headers(table)
  headers = table.headers
  missing = missing_headers(headers)
  unknown = unknown_headers(headers)
  unless missing.empty? && unknown.empty?
    msg  = "Detected possible HEADER ISSUES !!!\n"
    msg << "There might be Missing or Wrong HEADER names in the CSV file:\n"
    msg << "  * UNKNOWN (or not used?): #{unknown}\n" unless unknown.empty?
    msg << "  * MISSING DIRECT: #{missing[:direct]}\n" unless (missing[:direct] || []).empty?
    unless (data =  missing[:indirect] || []).empty?
      msg << "  * MISSING INDIRECT:\n"
      data.each do |ext, info|
        msg <<  "    - '#{ext}' => "
        msg << (info[:attrs] || {}).map do |status, attrs|
          if status == :inactive
            "makes inactive: #{attrs}"
          elsif status == :active
            "there could be missing info in: #{attrs}"
          end
        end.compact.join("; ") + "\n"
      end
    end
    logger.warn(msg)
    sleep(2)
  end
end
fields_mapper() click to toggle source
# File lib/eco/api/common/people/default_parsers/csv_parser.rb, line 145
def fields_mapper
  session.fields_mapper
end
internal_present_or_active(headers, inactive_requirements = {}) click to toggle source
# File lib/eco/api/common/people/default_parsers/csv_parser.rb, line 113
def internal_present_or_active(headers, inactive_requirements = {})
  hint = headers & all_internal_attrs
  hext = headers - hint
  int_present = hint + hext.map {|e| fields_mapper.to_internal(e)}.compact

  update_inactive = Proc.new do
    inactive_requirements.dup.each do |attr, req|
      if req.active?(*int_present)
        inactive_requirements.delete(attr)
        int_present << attr
        update_inactive.call
      end
    end
  end

  required_attrs.values.each do |req|
    next if int_present.include?(req)
    if req.active?(*int_present)
      inactive_requirements.delete(req.attr)
      int_present << req.attr
      update_inactive.call
    else
      inactive_requirements[req.attr] = req
    end
  end
  int_present
end
known_headers() click to toggle source
# File lib/eco/api/common/people/default_parsers/csv_parser.rb, line 141
def known_headers
  @known_headers ||= fields_mapper.list(:external).compact
end
known_headers_present(headers_internal) click to toggle source
# File lib/eco/api/common/people/default_parsers/csv_parser.rb, line 106
def known_headers_present(headers_internal)
  @known_internal ||= known_headers.select do |ext|
    int = fields_mapper.to_internal(ext)
    headers_internal.include?(int)
  end
end
missing_headers(headers) click to toggle source
# File lib/eco/api/common/people/default_parsers/csv_parser.rb, line 72
def missing_headers(headers)
  int_head = internal_present_or_active(headers)
  ext  = headers.select do |e|
    i = fields_mapper.to_internal(e)
    int_head.include?(i)
  end
  ext_present = known_headers_present(int_head) | ext
  ext_miss    = known_headers - ext_present

  ext_miss.each_with_object({}) do |ext, missing|
    next unless int = fields_mapper.to_internal(ext)
    if all_internal_attrs.include?(int)
      missing[:direct] ||= []
      missing[:direct] << ext
    end
    related_attrs_requirements = required_attrs.values.select do |req|
      dep       = req.dependant?(int)
      affects   = dep && !int_head.include?(int)
      in_header = int_head.include?(req.attr)
      affects || (dep && !in_header)
    end
    next if related_attrs_requirements.empty?
    missing[:indirect] ||= {}
    data = missing[:indirect][ext] = {}
    data[:int]   = int
    data[:attrs] = {}
    related_attrs_requirements.each_with_object(data[:attrs]) do |req, attrs|
      status = req.active?(*int_head) ? :active : :inactive
      attrs[status] ||= []
      attrs[status] << req.attr
    end
  end
end
null?(value) click to toggle source
# File lib/eco/api/common/people/default_parsers/csv_parser.rb, line 35
def null?(value)
  return true if !value
  str = value.strip.upcase
  ["NULL"].any? {|token| str == token}
end
parse_string(value) click to toggle source
# File lib/eco/api/common/people/default_parsers/csv_parser.rb, line 29
def parse_string(value)
  return nil if value.to_s.empty?
  return nil if null?(value)
  value
end
person_parser() click to toggle source
# File lib/eco/api/common/people/default_parsers/csv_parser.rb, line 163
def person_parser
  session.entry_factory.person_parser
end
required_attrs() click to toggle source
# File lib/eco/api/common/people/default_parsers/csv_parser.rb, line 149
def required_attrs
  @required_attrs ||= person_parser.required_attrs.each_with_object({}) do |ra, out|
    out[ra.attr] = ra
  end
end
unknown_headers(headers) click to toggle source
# File lib/eco/api/common/people/default_parsers/csv_parser.rb, line 68
def unknown_headers(headers)
  (headers - known_headers) - all_internal_attrs
end