Maintenance::Atom::ImportReasonGroupsTask

Source code
# frozen_string_literal: true

# Imports Atom ReasonGroups from a CSV. Idempotent on re-run (matched by id).
#
# Expected CSV headers:
#   id, name, category, global, countries, segment_bits
#
# `countries` is a Postgres array literal, e.g. "{DE}" or "{DK,FI,NO,SE}".
# `segment_bits` is an integer bitfield: AIR=1, CAR=2, HOTEL=4, RAIL=8, OTHER=16.

class Maintenance::Atom::ImportReasonGroupsTask < MaintenanceTasks::Task
  include DatadogTrace
  include Maintenance::Atom::BlankIdSkippable
  include Maintenance::Atom::PgArrayParsable

  SEGMENT_BITS = {
    1 => 'AIR',
    2 => 'CAR',
    4 => 'HOTEL',
    8 => 'RAIL',
    16 => 'OTHER'
  }.freeze

  csv_collection
  report_on(StandardError)

  def process(row)
    return if skip_blank_id?(row)

    ActiveRecord::Base.transaction do
      reason_group = ReasonGroup.find_or_initialize_by(id: row['id'])
      reason_group.assign_attributes(
        name: row['name'],
        category: row['category'],
        global: ActiveModel::Type::Boolean.new.cast(row['global']),
        segments: decode_segments(row['segment_bits'])
      )
      reason_group.countries = resolve_countries(row['countries'])
      reason_group.save!
    end
  end

  private

  def resolve_countries(value)
    parse_pg_array(value).map { |code| Country.find_by!(code: code) }
  end

  def decode_segments(value)
    bits = value.to_i
    return [] if bits.zero?

    SEGMENT_BITS.each_with_object([]) do |(bit, name), acc|
      acc << name if bits.anybits?(bit)
    end
  end
end

Previous Runs

Succeeded

Processed 4 out of 4 items (100%).

Ran for less than 5 seconds, finished .


Metadata:
user_id
-1
Succeeded

Processed 86 out of 86 items (100%).

Ran for less than 5 seconds, finished .


Metadata:
user_id
-1