# frozen_string_literal: true # handles the import of repository records # requires 4 parameters: # @sheet: the csv file with imported rows # @mappings: mappings for columns # @user: current_user # @repository: the repository in which we import the items module RepositoryImportParser class Importer def initialize(sheet, mappings, user, repository) @columns = [] @name_index = -1 @total_new_rows = 0 @new_rows_added = 0 @header_skipped = false @repository = repository @sheet = sheet @rows = SpreadsheetParser.spreadsheet_enumerator(@sheet) @mappings = mappings @user = user @repository_columns = @repository.repository_columns end def run get_columns return check_for_duplicate_columns if check_for_duplicate_columns import_rows! end private def get_columns @mappings.each.with_index do |(_, value), index| if value == '-1' # Fill blank space, so our indices stay the same @columns << nil @name_index = index else @columns << @repository_columns.find_by_id(value) end end end def check_for_duplicate_columns col_compact = @columns.compact if col_compact.map(&:id).uniq.length != col_compact.length return { status: :error, nr_of_added: @new_rows_added, total_nr: @total_new_rows } end end def import_rows! errors = false @rows.each do |row| # Skip empty rows next if row.empty? unless @header_skipped @header_skipped = true next end @total_new_rows += 1 row = SpreadsheetParser.parse_row(row, @sheet) record_row = new_repository_row(row) record_row.transaction do unless record_row.save errors = true raise ActiveRecord::Rollback end row_cell_values = [] row.each.with_index do |value, index| column = @columns[index] if column && value.present? # uses RepositoryCellValueResolver to retrieve the correct value cell_value_resolver = RepositoryImportParser::RepositoryCellValueResolver.new( column, @user, @repository ) cell_value = cell_value_resolver.get_value(value, record_row) unless cell_value.valid? errors = true raise ActiveRecord::Rollback end row_cell_values << cell_value end end unless import_to_database(row_cell_values) errors = true raise ActiveRecord::Rollback end @new_rows_added += 1 end end if errors return { status: :error, nr_of_added: @new_rows_added, total_nr: @total_new_rows } end { status: :ok, nr_of_added: @new_rows_added, total_nr: @total_new_rows } end def new_repository_row(row) RepositoryRow.new(name: row[@name_index], repository: @repository, created_by: @user, last_modified_by: @user) end def import_to_database(row_cell_values) return false if RepositoryTextValue.import( row_cell_values.select { |element| element.is_a? RepositoryTextValue }, recursive: true, validate: false ).failed_instances.any? return false if RepositoryListValue.import( row_cell_values.select { |element| element.is_a? RepositoryListValue }, recursive: true, validate: false ).failed_instances.any? true end end end