backend/app/lib/bulk_import/top_container_linker_validator.rb
require_relative "bulk_import_parser"
class TopContainerLinkerValidator < BulkImportParser
include BulkImportMixins
#ASpace field headers row indicator
START_MARKER = /ArchivesSpace field code/.freeze
def initialize(input_file, content_type, current_user, opts)
super(input_file, content_type, current_user, opts, nil)
@resource_ref = "/repositories/#{@opts[:repo_id]}/resources/#{@opts[:rid]}"
@start_marker = START_MARKER
@barcode_tc_existing_in_spreadsheet = {}
@instance_types ||= CvList.new("instance_instance_type", @current_user) # for when we move instances over here
end
# look for all the required fields to make sure they are legit
# strip all the strings and turn publish and restrictions_flag into true/false
def process_row(row_hash = nil)
#This allows the processing of a single row
if (!row_hash.nil?)
@row_hash = row_hash
end
err_arr = []
begin
# Check that the archival object ref id exists
ref_id = @row_hash["ref_id"]
if ref_id.nil?
err_arr.push I18n.t("top_container_linker.error.ref_id_miss", :row_num => @counter.to_s)
raise BulkImportException.new(err_arr.join("; "))
else
#Check that the AO can be found in the db
ao = archival_object_from_ref(ref_id.strip)
if (ao.nil?)
err_arr.push I18n.t("top_container_linker.error.ao_not_in_db", :ref_id => ref_id.to_s, :row_num => @counter.to_s)
end
end
ead_id = @row_hash["ead_id"]
if ead_id.nil?
err_arr.push I18n.t("top_container_linker.error.ead_id_miss", :ref_id => ref_id.to_s, :row_num => @counter.to_s)
else
#Check that the AO can be found in the db
resource = resource_from_ref(ead_id.strip)
if (resource.nil?)
err_arr.push I18n.t("top_container_linker.error.resource_not_in_db", :ead_id => ead_id.to_s, :row_num => @counter.to_s)
elsif (resource.uri != @resource_ref)
err_arr.push I18n.t("top_container_linker.error.resources_do_not_match", :spreadsheet_resource => resource.uri, :ead_id => ead_id.to_s, :current_resource => @resource_ref, :row_num => @counter.to_s)
end
end
#Check that the instance type exists
instance_type = @row_hash["instance_type"]
if instance_type.nil?
err_arr.push I18n.t("top_container_linker.error.instance_type_miss", :ref_id => ref_id.to_s, :row_num => @counter.to_s)
end
retval = value_check(@instance_types, instance_type, [])
if (retval == nil)
err_arr.push I18n.t("top_container_linker.error.instance_type_does_not_exist", :instance_type => instance_type, :ref_id => ref_id.to_s, :row_num => @counter.to_s)
end
#Check that either the Top Container Indicator or Top Container Record No. is present
tc_indicator = @row_hash["top_container_indicator"]
tc_record_no = @row_hash["top_container_id"]
#Both missing
if (tc_indicator.nil? && tc_record_no.nil?)
err_arr.push I18n.t("top_container_linker.error.tc_indicator_and_record_no_miss", :ref_id => ref_id.to_s, :row_num => @counter.to_s)
end
#Both exist
if (!tc_indicator.nil? && !tc_record_no.nil?)
err_arr.push I18n.t("top_container_linker.error.tc_indicator_and_record_no_exist", :ref_id => ref_id.to_s, :row_num => @counter.to_s)
end
if (!tc_record_no.nil?)
begin
tc_obj = TopContainer.get_or_die(tc_record_no.strip.to_i)
rescue NotFoundException
tc_obj = nil
end
if tc_obj.nil?
#Cannot find TC record with ID
err_arr.push I18n.t("top_container_linker.error.tc_record_no_missing", :tc_id=> tc_record_no, :ref_id => ref_id.to_s, :row_num => @counter.to_s)
end
end
#Container type/Container indicator combo already exists
tc_type = @row_hash["top_container_type"]
if (!tc_indicator.nil? && !tc_type.nil?)
type_id = BackendEnumSource.id_for_value("container_type", tc_type.strip)
tc_exists = indicator_and_type_exist_for_resource?(ead_id, tc_indicator, type_id)
if (tc_exists)
err_arr.push I18n.t("top_container_linker.error.tc_ind_ct_exists", :indicator=> tc_indicator, :tc_type=> tc_type, :ead_id => ead_id, :ref_id => ref_id.to_s, :row_num => @counter.to_s)
end
end
#Check if the barcode already exists in the db (fail if so)
barcode = @row_hash["top_container_barcode"]
if (!barcode.nil?)
tc_obj = find_top_container({:barcode => barcode.strip})
if (!tc_obj.nil?)
err_arr.push I18n.t("top_container_linker.error.tc_barcode_exists", :barcode=> barcode, :ref_id => ref_id.to_s, :row_num => @counter.to_s)
elsif barcode_differs_from_prev_tc?(tc_indicator, tc_type, barcode)
err_arr.push I18n.t("top_container_linker.error.tc_barcode_differs", :barcode=> barcode, :type=>tc_type, :indicator=> tc_indicator, :ref_id => ref_id.to_s, :row_num => @counter.to_s)
else
add_tc_bc(tc_indicator, tc_type, barcode)
end
end
#Check if the barcode_2 already exists in the db (fail if so).
#This will be put in place when Harvard's code is merged
barcode_2 = @row_hash["child_barcode"]
child_type = @row_hash["child_type"]
child_indicator = @row_hash["child_indicator"]
if (!barcode_2.nil?)
sc_obj = sub_container_from_barcode(barcode_2.strip)
if (!sc_obj.nil?)
err_arr.push I18n.t("top_container_linker.error.sc_barcode_exists", :barcode=> barcode_2, :ref_id => ref_id.to_s, :row_num => @counter.to_s)
elsif (!child_type.nil? && !child_indicator.nil?)
if barcode_differs_from_prev_tc?(child_indicator, child_type, barcode_2, true)
err_arr.push I18n.t("top_container_linker.error.sc_barcode_differs", :barcode=> barcode_2, :type=>child_type, :indicator=>child_indicator, :ref_id => ref_id.to_s, :row_num => @counter.to_s)
end
add_tc_bc(child_indicator, child_type, barcode_2, true)
end
end
#Check if the location ID can be found in the db
loc_id = @row_hash["location_id"]
if (!loc_id.nil?)
begin
loc = Location.get_or_die(loc_id.strip.to_i)
rescue NotFoundException
loc = nil
end
if (loc.nil?)
err_arr.push I18n.t("top_container_linker.error.loc_not_in_db", :loc_id=> loc_id.to_s, :ref_id => ref_id.to_s, :row_num => @counter.to_s)
end
end
#Check if Container Profile Record No. can be found in the db
cp_id = @row_hash["container_profile_id"]
if (!cp_id.nil?)
begin
cp = ContainerProfile.get_or_die(cp_id.strip.to_i)
rescue NotFoundException
cp = nil
end
if (cp.nil?)
err_arr.push I18n.t("top_container_linker.error.cp_not_in_db", :cp_id=> cp_id.to_s, :ref_id => ref_id.to_s, :row_num => @counter.to_s)
end
end
rescue Exception => e
Log.error(["UNEXPLAINED EXCEPTION on check row", e.message, e.backtrace, @row_hash].pretty_inspect)
raise
end
if !err_arr.empty?
raise BulkImportException.new(err_arr.join("; "))
end
end
def get_hash_table()
@barcode_tc_existing_in_spreadsheet
end
private
def add_tc_bc(indicator, type, barcode, is_child=false)
key = "#{type} #{indicator}"
key += " child" if is_child
@barcode_tc_existing_in_spreadsheet[key] = barcode
end
#Checks to see if the barcode for subsequent indicator-type combos
#are the same
def barcode_differs_from_prev_tc?(indicator, type, barcode, is_child=false)
key = "#{type} #{indicator}"
key += " child" if is_child
@barcode_tc_existing_in_spreadsheet[key] && @barcode_tc_existing_in_spreadsheet[key] != barcode
end
end