43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
# File 'app/models/dataset_record/darwin_core/occurrence.rb', line 43
def get_protonym(parent, name)
name = name.except(:rank_class) if name[:rank_class].nil?
%I(name masculine_name feminine_name neuter_name).inject(nil) do |protonym, field|
break protonym unless protonym.nil?
potential_protonyms = Protonym.where(name.slice(:rank_class).merge({ field => name[:name], :parent => parent }))
if potential_protonyms.count > 1
if (cached_author = name[:verbatim_author])
if cached_author.start_with?('(') && cached_author.end_with?(')')
cached_author = cached_author.delete_prefix('(').delete_suffix(')')
potential_protonyms_narrowed = potential_protonyms.is_not_original_name
else
potential_protonyms_narrowed = potential_protonyms.is_original_name
end
potential_protonyms_narrowed = potential_protonyms_narrowed.where(cached_author:)
if name[:year_of_publication]
potential_protonyms_narrowed = potential_protonyms_narrowed.where(year_of_publication: name[:year_of_publication])
end
if potential_protonyms_narrowed.count == 1
potential_protonyms = potential_protonyms_narrowed
elsif potential_protonyms_narrowed.count == 0
potential_protonym_strings = potential_protonyms.map { |proto| "[id: #{proto.id} #{proto.cached_html_name_and_author_year}]" }.join(', ')
error_message =
["Multiple matches found for name #{name[:name]}, rank #{name[:rank_class]}, parent #{parent.id} #{parent.cached_html_name_and_author_year}: #{potential_protonym_strings}",
"No names matched author name #{name[:verbatim_author]}#{(', year ' + name[:year_of_publication].to_s) if name[:year_of_publication]}: "]
raise DatasetRecord::DarwinCore::InvalidData.new({ 'scientificName' => error_message })
else
potential_protonym_strings = potential_protonyms_narrowed.map { |proto| "[id: #{proto.id} #{proto.cached_html_name_and_author_year}]" }.join(', ')
raise DatasetRecord::DarwinCore::InvalidData.new(
{ 'scientificName' => ["Multiple matches found for name #{name[:name]} and author name #{name[:verbatim_author]}, year #{name[:year_of_publication]}: #{potential_protonym_strings}"] }
)
end
else
return parent
end
end
p = potential_protonyms.first
if p.nil? && Protonym.where(name.slice(:rank_class).merge({ field => name[:name] })).where(project_id: parent.project_id).exists?
if (cached_author = name[:verbatim_author])
if cached_author.start_with?('(') && cached_author.end_with?(')')
cached_author = cached_author.delete_prefix('(').delete_suffix(')')
end
end
potential_protonyms = Protonym.where(name.slice(:rank_class, :year_of_publication).merge({ field => name[:name], cached_author: }).compact).with_ancestor(parent)
if potential_protonyms.count > 1
return parent
end
p = potential_protonyms.first
if p.nil? && !parent.cached_is_valid
p = Protonym.where(name.slice(:rank_class).merge!({ field => name[:name] })).with_ancestor(parent.valid_taxon_name).first
end
end
if p&.cached_misspelling && p.has_misspelling_relationship?
correct_spelling = TaxonNameRelationship.where_subject_is_taxon_name(p)
.with_type_array(TAXON_NAME_RELATIONSHIP_NAMES_MISSPELLING_ONLY)
.first&.object_taxon_name
if correct_spelling&.values_at(:name, :masculine_name, :feminine_name, :neuter_name).include?(name[:name])
return correct_spelling
end
end
p
end
end
|