atlas_engine 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +497 -33
- data/app/countries/atlas_engine/be/country_profile.yml +2 -0
- data/app/countries/atlas_engine/be/validation_transcriber/address_parser.rb +84 -0
- data/app/countries/atlas_engine/bm/address_importer/corrections/open_address/city_alias_corrector.rb +12 -11
- data/app/countries/atlas_engine/bm/synonyms.yml +6 -0
- data/app/countries/atlas_engine/ch/country_profile.yml +2 -0
- data/app/countries/atlas_engine/ch/locales/de/country_profile.yml +0 -1
- data/app/countries/atlas_engine/ch/locales/fr/country_profile.yml +3 -0
- data/app/countries/atlas_engine/ch/locales/fr/validation_transcriber/address_parser.rb +29 -0
- data/app/countries/atlas_engine/cz/address_validation/es/query_builder.rb +43 -0
- data/app/countries/atlas_engine/cz/country_profile.yml +2 -1
- data/app/countries/atlas_engine/cz/validation_transcriber/address_parser.rb +26 -0
- data/app/countries/atlas_engine/it/address_importer/open_address/mapper.rb +1 -1
- data/app/countries/atlas_engine/it/country_profile.yml +1 -0
- data/app/countries/atlas_engine/sa/country_profile.yml +4 -1
- data/app/countries/atlas_engine/us/country_profile.yml +0 -2
- data/app/lib/atlas_engine/validation_transcriber/address_parsings.rb +1 -1
- data/app/lib/atlas_engine/validation_transcriber/formatter.rb +2 -2
- data/app/models/atlas_engine/address_validation/datastore_base.rb +3 -0
- data/app/models/atlas_engine/address_validation/es/datastore.rb +11 -6
- data/app/models/atlas_engine/address_validation/es/query_builder.rb +40 -29
- data/app/models/atlas_engine/address_validation/es/validators/full_address.rb +1 -1
- data/app/models/atlas_engine/address_validation/log_emitter.rb +1 -0
- data/app/models/atlas_engine/address_validation/normalizer.rb +0 -9
- data/app/models/atlas_engine/address_validation/validators/full_address/address_comparison.rb +7 -23
- data/app/models/atlas_engine/address_validation/validators/full_address/candidate_result.rb +42 -16
- data/app/models/atlas_engine/address_validation/validators/full_address/comparison_helper.rb +109 -109
- data/app/models/atlas_engine/address_validation/validators/full_address/{components_to_validate.rb → relevant_components.rb} +26 -18
- data/app/models/atlas_engine/country_profile_validation_subset.rb +5 -0
- data/app/tasks/maintenance/atlas_engine/elasticsearch_index_create_task.rb +1 -1
- data/db/data/country_profiles/default.yml +0 -2
- data/lib/atlas_engine/version.rb +1 -1
- metadata +11 -5
data/app/countries/atlas_engine/bm/address_importer/corrections/open_address/city_alias_corrector.rb
CHANGED
@@ -11,22 +11,23 @@ module AtlasEngine
|
|
11
11
|
extend T::Sig
|
12
12
|
|
13
13
|
BM_PARISH_AND_CITY_NAMES = {
|
14
|
-
"
|
15
|
-
"
|
16
|
-
"
|
17
|
-
"
|
18
|
-
"
|
19
|
-
"
|
20
|
-
"
|
21
|
-
"
|
22
|
-
"
|
23
|
-
"
|
14
|
+
"City of Hamilton" => ["City of Hamilton", "Hamilton"],
|
15
|
+
"Devonshire" => ["Devonshire Parish", "Devonshire"],
|
16
|
+
"Hamilton" => ["Hamilton Parish", "Hamilton"],
|
17
|
+
"Paget" => ["Paget Parish", "Paget"],
|
18
|
+
"Pembroke" => ["Pembroke Parish", "Pembroke"],
|
19
|
+
"Sandys" => ["Sandys Parish", "Sandys"],
|
20
|
+
"Smiths" => ["Smiths Parish", "Smiths"],
|
21
|
+
"Southampton" => ["Southampton Parish", "Southampton"],
|
22
|
+
"St. George's" => ["St. George's Parish", "St. George's"],
|
23
|
+
"Town of St. George" => ["Town of St. George", "St. George"],
|
24
|
+
"Warwick" => ["Warwick Parish", "Warwick"],
|
24
25
|
}.freeze
|
25
26
|
|
26
27
|
sig { params(address: Hash).void }
|
27
28
|
def apply(address)
|
28
29
|
if BM_PARISH_AND_CITY_NAMES.key?(address[:city][0])
|
29
|
-
address[:city]
|
30
|
+
address[:city] = BM_PARISH_AND_CITY_NAMES[address[:city][0]]
|
30
31
|
end
|
31
32
|
end
|
32
33
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# French address in Switzerland can be written in the following ways:
|
5
|
+
# 1. thoroughfare type[ ]Thoroughfare name[ ]number
|
6
|
+
# 2. number[ ]thoroughfare type[ ]Thoroughfare name
|
7
|
+
|
8
|
+
module AtlasEngine
|
9
|
+
module Ch
|
10
|
+
module Locales
|
11
|
+
module Fr
|
12
|
+
module ValidationTranscriber
|
13
|
+
class AddressParser < AtlasEngine::ValidationTranscriber::AddressParserBase
|
14
|
+
private
|
15
|
+
|
16
|
+
sig { returns(T::Array[Regexp]) }
|
17
|
+
def country_regex_formats
|
18
|
+
@country_regex_formats ||=
|
19
|
+
[
|
20
|
+
/^#{BUILDING_NUM}?\s*#{STREET_NO_COMMAS}$/o,
|
21
|
+
/^#{STREET_NO_COMMAS}?\s*#{BUILDING_NUM}$/o,
|
22
|
+
]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module AtlasEngine
|
5
|
+
module Cz
|
6
|
+
module AddressValidation
|
7
|
+
module Es
|
8
|
+
class QueryBuilder < AtlasEngine::AddressValidation::Es::DefaultQueryBuilder
|
9
|
+
private
|
10
|
+
|
11
|
+
sig { returns(Hash) }
|
12
|
+
def street_clause
|
13
|
+
street_queries = [build_street_queries, empty_street_clause]
|
14
|
+
|
15
|
+
{
|
16
|
+
"dis_max" => {
|
17
|
+
"queries" => street_queries.flatten,
|
18
|
+
},
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
sig { returns(Hash) }
|
23
|
+
def empty_street_clause
|
24
|
+
{
|
25
|
+
"bool" => {
|
26
|
+
"must_not" => {
|
27
|
+
"exists" => {
|
28
|
+
"field" => "street",
|
29
|
+
},
|
30
|
+
},
|
31
|
+
},
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
sig { returns(T::Array[String]) }
|
36
|
+
def street_query_values
|
37
|
+
street_names.presence || []
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -2,5 +2,6 @@ id: CZ
|
|
2
2
|
validation:
|
3
3
|
enabled: true
|
4
4
|
default_matching_strategy: es
|
5
|
-
address_parser: AtlasEngine::
|
5
|
+
address_parser: AtlasEngine::Cz::ValidationTranscriber::AddressParser
|
6
|
+
query_builder: AtlasEngine::Cz::AddressValidation::Es::QueryBuilder
|
6
7
|
has_provinces: false
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module AtlasEngine
|
5
|
+
module Cz
|
6
|
+
module ValidationTranscriber
|
7
|
+
class AddressParser < AtlasEngine::ValidationTranscriber::AddressParserBase
|
8
|
+
private
|
9
|
+
|
10
|
+
sig { returns(T::Array[Regexp]) }
|
11
|
+
def country_regex_formats
|
12
|
+
@country_regex_formats ||= [
|
13
|
+
/^#{BUILDING_NUM}$/,
|
14
|
+
/^#{STREET_NO_COMMAS}\s+#{BUILDING_NUM}?$/,
|
15
|
+
]
|
16
|
+
end
|
17
|
+
|
18
|
+
def ridiculous?(captures, address)
|
19
|
+
return false if captures[:street].blank?
|
20
|
+
|
21
|
+
address.city == captures[:street]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -29,7 +29,7 @@ module AtlasEngine
|
|
29
29
|
city: [city.titleize],
|
30
30
|
suburb: nil,
|
31
31
|
zip: postcode,
|
32
|
-
street: street
|
32
|
+
street: street,
|
33
33
|
building_and_unit_ranges: housenumber_and_unit(number, unit),
|
34
34
|
latitude: geometry(feature)&.at(1),
|
35
35
|
longitude: geometry(feature)&.at(0),
|
@@ -42,7 +42,7 @@ module AtlasEngine
|
|
42
42
|
|
43
43
|
sig { returns(T::Array[String]) }
|
44
44
|
def potential_building_numbers
|
45
|
-
parsings.pluck(:building_num).compact.uniq
|
45
|
+
parsings.pluck(:building_num).compact.uniq.reject { |n| n.match?(/\d{7,}/) }
|
46
46
|
end
|
47
47
|
|
48
48
|
sig { params(address_input: AddressValidation::AbstractAddress).void }
|
@@ -13,8 +13,8 @@ module AtlasEngine
|
|
13
13
|
|
14
14
|
sig { params(haystack: String, needle: String).returns(String) }
|
15
15
|
def strip_word(haystack, needle)
|
16
|
-
string = haystack.sub(/[\s](#{Regexp.escape(needle)})([\s]|$)/i, " ").strip
|
17
|
-
string = string.sub(/[\s,](#{Regexp.escape(needle)})([\s,]|$)/i, "").strip
|
16
|
+
string = haystack.sub(/([\s]|^)(#{Regexp.escape(needle)})([\s]|$)/i, " ").strip
|
17
|
+
string = string.sub(/([\s,]|^)(#{Regexp.escape(needle)})([\s,]|$)/i, "").strip
|
18
18
|
string = strip_trailing_punctuation(string)
|
19
19
|
string || ""
|
20
20
|
end
|
@@ -20,6 +20,9 @@ module AtlasEngine
|
|
20
20
|
sig { abstract.returns(T::Hash[T.untyped, T.untyped]) }
|
21
21
|
def validation_response; end
|
22
22
|
|
23
|
+
sig { abstract.returns(CountryProfile) }
|
24
|
+
def country_profile; end
|
25
|
+
|
23
26
|
sig { abstract.returns(ValidationTranscriber::AddressParsings) }
|
24
27
|
def parsings; end
|
25
28
|
end
|
@@ -10,7 +10,12 @@ module AtlasEngine
|
|
10
10
|
include DatastoreBase
|
11
11
|
extend T::Sig
|
12
12
|
|
13
|
+
sig { override.returns(CountryProfile) }
|
14
|
+
attr_reader :country_profile
|
15
|
+
|
16
|
+
sig { override.returns(ValidationTranscriber::AddressParsings) }
|
13
17
|
attr_reader :parsings
|
18
|
+
|
14
19
|
attr_writer :candidates # meant for test setup only
|
15
20
|
|
16
21
|
sig { params(address: AbstractAddress, locale: T.nilable(String)).void }
|
@@ -21,9 +26,9 @@ module AtlasEngine
|
|
21
26
|
raise ArgumentError, "address has no country_code" if address.country_code.blank?
|
22
27
|
|
23
28
|
@country_code = T.must(address.country_code.to_s)
|
24
|
-
@
|
29
|
+
@country_profile = CountryProfile.for(country_code.to_s.upcase, @locale)
|
25
30
|
|
26
|
-
if locale.nil? && @
|
31
|
+
if locale.nil? && @country_profile.validation.multi_locale?
|
27
32
|
raise ArgumentError, "#{country_code} is a multi-locale country and requires a locale"
|
28
33
|
end
|
29
34
|
|
@@ -107,7 +112,7 @@ module AtlasEngine
|
|
107
112
|
|
108
113
|
private
|
109
114
|
|
110
|
-
attr_reader :address, :country_code, :locale, :
|
115
|
+
attr_reader :address, :country_code, :locale, :query_builder
|
111
116
|
|
112
117
|
sig { returns(Token::Sequence) }
|
113
118
|
def fetch_city_sequence_internal
|
@@ -153,7 +158,7 @@ module AtlasEngine
|
|
153
158
|
|
154
159
|
sig { params(candidates: T::Array[Candidate]).void }
|
155
160
|
def assign_term_vectors_to_candidates(candidates)
|
156
|
-
return if
|
161
|
+
return if country_profile.validation.normalized_components.blank?
|
157
162
|
|
158
163
|
candidate_term_vectors = measure_es_validation_request_time(method: "term_vectors") do
|
159
164
|
repository.term_vectors(term_vectors_query(candidates))
|
@@ -167,7 +172,7 @@ module AtlasEngine
|
|
167
172
|
{
|
168
173
|
ids: candidates.map(&:id),
|
169
174
|
parameters: {
|
170
|
-
fields:
|
175
|
+
fields: country_profile.validation.normalized_components,
|
171
176
|
field_statistics: false,
|
172
177
|
},
|
173
178
|
}
|
@@ -219,7 +224,7 @@ module AtlasEngine
|
|
219
224
|
FieldDecompounder.new(
|
220
225
|
field: :street,
|
221
226
|
value: street_value,
|
222
|
-
country_profile
|
227
|
+
country_profile:,
|
223
228
|
).call,
|
224
229
|
)
|
225
230
|
end
|
@@ -37,22 +37,15 @@ module AtlasEngine
|
|
37
37
|
sig { returns(CountryProfile) }
|
38
38
|
attr_reader :profile
|
39
39
|
|
40
|
-
sig { returns(Hash) }
|
40
|
+
sig { returns(T.nilable(Hash)) }
|
41
41
|
def building_number_clause
|
42
|
-
|
43
|
-
AddressNumber.new(value: n).to_i
|
44
|
-
end.uniq
|
42
|
+
building_number_clause = approx_building_clauses
|
45
43
|
|
46
|
-
|
47
|
-
building_number_queries.unshift(
|
48
|
-
*T.unsafe(potential_building_numbers.map do |value|
|
49
|
-
approx_building_clause(value)
|
50
|
-
end),
|
51
|
-
) if potential_building_numbers.any?
|
44
|
+
return if building_number_clause.nil?
|
52
45
|
|
53
46
|
{
|
54
47
|
"dis_max" => {
|
55
|
-
"queries" =>
|
48
|
+
"queries" => building_number_clause,
|
56
49
|
},
|
57
50
|
}
|
58
51
|
end
|
@@ -68,6 +61,19 @@ module AtlasEngine
|
|
68
61
|
}
|
69
62
|
end
|
70
63
|
|
64
|
+
sig { returns(T.nilable(Array)) }
|
65
|
+
def approx_building_clauses
|
66
|
+
potential_building_numbers = @parsings.potential_building_numbers.filter_map do |n|
|
67
|
+
AddressNumber.new(value: n).to_i
|
68
|
+
end.uniq
|
69
|
+
|
70
|
+
if potential_building_numbers.any?
|
71
|
+
potential_building_numbers.map do |value|
|
72
|
+
approx_building_clause(value)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
71
77
|
sig { returns(Hash) }
|
72
78
|
def empty_approx_building_clause
|
73
79
|
{
|
@@ -85,25 +91,30 @@ module AtlasEngine
|
|
85
91
|
def street_clause
|
86
92
|
{
|
87
93
|
"dis_max" => {
|
88
|
-
"queries" =>
|
89
|
-
{
|
90
|
-
"match" => {
|
91
|
-
"street" => { "query" => value, "fuzziness" => "auto" },
|
92
|
-
},
|
93
|
-
}
|
94
|
-
end.union(
|
95
|
-
stripped_street_query_values.map do |value|
|
96
|
-
{
|
97
|
-
"match" => {
|
98
|
-
"street_stripped" => { "query" => value, "fuzziness" => "auto" },
|
99
|
-
},
|
100
|
-
}
|
101
|
-
end,
|
102
|
-
),
|
94
|
+
"queries" => build_street_queries,
|
103
95
|
},
|
104
96
|
}
|
105
97
|
end
|
106
98
|
|
99
|
+
sig { returns(Array) }
|
100
|
+
def build_street_queries
|
101
|
+
street_query_values.map do |value|
|
102
|
+
{
|
103
|
+
"match" => {
|
104
|
+
"street" => { "query" => value, "fuzziness" => "auto" },
|
105
|
+
},
|
106
|
+
}
|
107
|
+
end.union(
|
108
|
+
stripped_street_query_values.map do |value|
|
109
|
+
{
|
110
|
+
"match" => {
|
111
|
+
"street_stripped" => { "query" => value, "fuzziness" => "auto" },
|
112
|
+
},
|
113
|
+
}
|
114
|
+
end,
|
115
|
+
)
|
116
|
+
end
|
117
|
+
|
107
118
|
sig { returns(T::Array[String]) }
|
108
119
|
def street_query_values
|
109
120
|
street_names.presence || [address.address1.to_s, address.address2.to_s].compact_blank.uniq
|
@@ -149,10 +160,10 @@ module AtlasEngine
|
|
149
160
|
sig { returns(T.nilable(Hash)) }
|
150
161
|
def province_clause
|
151
162
|
{
|
152
|
-
"
|
153
|
-
"province_code" => { "
|
163
|
+
"match" => {
|
164
|
+
"province_code" => { "query" => address.province_code.to_s.downcase },
|
154
165
|
},
|
155
|
-
} if profile.attributes.dig("validation", "has_provinces")
|
166
|
+
} if profile.attributes.dig("validation", "has_provinces") && address.province_code.present?
|
156
167
|
end
|
157
168
|
end
|
158
169
|
end
|
@@ -80,7 +80,7 @@ module AtlasEngine
|
|
80
80
|
.returns(T.untyped)
|
81
81
|
end
|
82
82
|
def publish_notification(candidate_result: nil)
|
83
|
-
ActiveSupport::Notifications.instrument("
|
83
|
+
ActiveSupport::Notifications.instrument("atlas_engine.address_validation.validation_completed", {
|
84
84
|
candidate_result: candidate_result,
|
85
85
|
result: result,
|
86
86
|
}.compact)
|
@@ -18,15 +18,6 @@ module AtlasEngine
|
|
18
18
|
.gsub("æ", "ae")
|
19
19
|
.gsub("œ", "oe")
|
20
20
|
.gsub(" ", " ")
|
21
|
-
# normalizes Arabic characters
|
22
|
-
.tr("آ", "ا")
|
23
|
-
.tr("أ", "ا")
|
24
|
-
.tr("إ", "ا")
|
25
|
-
.tr("ئ", "ي")
|
26
|
-
.tr("ة", "ه")
|
27
|
-
.tr("ى", "ي")
|
28
|
-
# removes Arabic stretching characters and diacritics
|
29
|
-
.gsub(/[\u064B|\u064C|\u064D|\u064E|\u064F|\u0650|\u0651|\u0652|\u0640]/, "")
|
30
21
|
# TODO: Strip hyphens for USPS not zip
|
31
22
|
.gsub(/[!@%&"'*,.();:]/, "")
|
32
23
|
.downcase
|
data/app/models/atlas_engine/address_validation/validators/full_address/address_comparison.rb
CHANGED
@@ -9,34 +9,18 @@ module AtlasEngine
|
|
9
9
|
extend T::Sig
|
10
10
|
include Comparable
|
11
11
|
|
12
|
-
attr_reader :
|
12
|
+
attr_reader :comparison_helper
|
13
|
+
|
14
|
+
delegate :street_comparison,
|
13
15
|
:city_comparison,
|
14
|
-
:zip_comparison,
|
15
16
|
:province_code_comparison,
|
16
|
-
:
|
17
|
+
:zip_comparison,
|
18
|
+
:building_comparison,
|
19
|
+
to: :comparison_helper
|
17
20
|
|
18
21
|
sig { params(address: AbstractAddress, candidate: Candidate, datastore: DatastoreBase).void }
|
19
22
|
def initialize(address:, candidate:, datastore:)
|
20
|
-
@
|
21
|
-
datastore: datastore,
|
22
|
-
candidate: candidate,
|
23
|
-
)
|
24
|
-
@city_comparison = ComparisonHelper.city_comparison(
|
25
|
-
datastore: datastore,
|
26
|
-
candidate: candidate,
|
27
|
-
)
|
28
|
-
@zip_comparison = ComparisonHelper.zip_comparison(
|
29
|
-
address: address,
|
30
|
-
candidate: candidate,
|
31
|
-
)
|
32
|
-
@province_code_comparison = ComparisonHelper.province_code_comparison(
|
33
|
-
address: address,
|
34
|
-
candidate: candidate,
|
35
|
-
)
|
36
|
-
@building_comparison = ComparisonHelper.building_comparison(
|
37
|
-
datastore: datastore,
|
38
|
-
candidate: candidate,
|
39
|
-
)
|
23
|
+
@comparison_helper = ComparisonHelper.new(address:, candidate:, datastore:)
|
40
24
|
end
|
41
25
|
|
42
26
|
sig { params(other: AddressComparison).returns(Integer) }
|
@@ -9,6 +9,8 @@ module AtlasEngine
|
|
9
9
|
extend T::Sig
|
10
10
|
include LogHelper
|
11
11
|
|
12
|
+
delegate :street_comparison, to: :address_comparison
|
13
|
+
|
12
14
|
sig do
|
13
15
|
params(
|
14
16
|
candidate: AddressValidation::CandidateTuple,
|
@@ -25,8 +27,8 @@ module AtlasEngine
|
|
25
27
|
|
26
28
|
sig { override.void }
|
27
29
|
def update_result
|
28
|
-
result.candidate = candidate
|
29
|
-
return if
|
30
|
+
result.candidate = candidate.serialize
|
31
|
+
return if unmatched_components_to_validate.empty?
|
30
32
|
|
31
33
|
update_concerns_and_suggestions
|
32
34
|
update_result_scope
|
@@ -39,8 +41,12 @@ module AtlasEngine
|
|
39
41
|
|
40
42
|
private
|
41
43
|
|
44
|
+
sig { returns(Candidate) }
|
42
45
|
attr_reader :candidate
|
43
46
|
|
47
|
+
sig { returns(AddressComparison) }
|
48
|
+
attr_reader :address_comparison
|
49
|
+
|
44
50
|
sig { void }
|
45
51
|
def update_concerns_and_suggestions
|
46
52
|
if suggestable?
|
@@ -62,7 +68,7 @@ module AtlasEngine
|
|
62
68
|
|
63
69
|
sig { void }
|
64
70
|
def add_concerns_with_suggestions
|
65
|
-
|
71
|
+
unmatched_components_to_validate.keys.each do |unmatched_component|
|
66
72
|
field_name = unmatched_field_name(unmatched_component)
|
67
73
|
if field_name.nil?
|
68
74
|
log_unknown_field_name
|
@@ -72,7 +78,7 @@ module AtlasEngine
|
|
72
78
|
concern = ConcernBuilder.new(
|
73
79
|
unmatched_component: unmatched_component,
|
74
80
|
unmatched_field: field_name,
|
75
|
-
matched_components:
|
81
|
+
matched_components: matched_components_to_validate.keys,
|
76
82
|
address: session.address,
|
77
83
|
suggestion_ids: [suggestion.id].compact,
|
78
84
|
).build
|
@@ -87,7 +93,7 @@ module AtlasEngine
|
|
87
93
|
|
88
94
|
@suggestion ||= SuggestionBuilder.from_comparisons(
|
89
95
|
session.address.to_h,
|
90
|
-
|
96
|
+
unmatched_components_to_validate,
|
91
97
|
candidate,
|
92
98
|
unmatched_fields,
|
93
99
|
)
|
@@ -103,11 +109,25 @@ module AtlasEngine
|
|
103
109
|
@unmatched_components || split_matched_and_unmatched_components.second
|
104
110
|
end
|
105
111
|
|
112
|
+
sig { returns(T::Hash[Symbol, AtlasEngine::AddressValidation::Token::Sequence::Comparison]) }
|
113
|
+
def matched_components_to_validate
|
114
|
+
matched_components.select do |k, _v|
|
115
|
+
components_to_validate.include?(k)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
sig { returns(T::Hash[Symbol, AtlasEngine::AddressValidation::Token::Sequence::Comparison]) }
|
120
|
+
def unmatched_components_to_validate
|
121
|
+
unmatched_components.select do |k, _v|
|
122
|
+
components_to_validate.include?(k)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
106
126
|
sig { returns(T::Hash[Symbol, T.nilable(AtlasEngine::AddressValidation::Token::Sequence::Comparison)]) }
|
107
127
|
def matched_and_unmatched_components
|
108
128
|
components = {}
|
109
129
|
@matched_and_unmatched_components ||= begin
|
110
|
-
|
130
|
+
components_to_compare.each do |field|
|
111
131
|
components[field] = @address_comparison.send(:"#{field}_comparison")
|
112
132
|
end
|
113
133
|
components
|
@@ -116,7 +136,17 @@ module AtlasEngine
|
|
116
136
|
|
117
137
|
sig { returns(T::Array[Symbol]) }
|
118
138
|
def components_to_validate
|
119
|
-
|
139
|
+
relevant_components.components_to_validate
|
140
|
+
end
|
141
|
+
|
142
|
+
sig { returns(T::Array[Symbol]) }
|
143
|
+
def components_to_compare
|
144
|
+
relevant_components.components_to_compare
|
145
|
+
end
|
146
|
+
|
147
|
+
sig { returns(RelevantComponents) }
|
148
|
+
def relevant_components
|
149
|
+
@relevant_components ||= RelevantComponents.new(session, candidate, street_comparison)
|
120
150
|
end
|
121
151
|
|
122
152
|
sig do
|
@@ -124,24 +154,20 @@ module AtlasEngine
|
|
124
154
|
T.nilable(AtlasEngine::AddressValidation::Token::Sequence::Comparison)]])
|
125
155
|
end
|
126
156
|
def split_matched_and_unmatched_components
|
157
|
+
return @matched_components, @unmatched_components if defined?(@matched_components) &&
|
158
|
+
defined?(@unmatched_components)
|
159
|
+
|
127
160
|
@matched_components, @unmatched_components = matched_and_unmatched_components.partition do |_, comparison|
|
128
161
|
comparison&.match?
|
129
162
|
end.map(&:to_h)
|
130
163
|
end
|
131
164
|
|
132
|
-
sig { returns(T.nilable(AtlasEngine::AddressValidation::Token::Sequence::Comparison)) }
|
133
|
-
def street_comparison
|
134
|
-
return @street_comparison if defined?(@street_comparison)
|
135
|
-
|
136
|
-
@street_comparison = @address_comparison.street_comparison
|
137
|
-
end
|
138
|
-
|
139
165
|
sig { params(component: Symbol).returns(T.nilable(Symbol)) }
|
140
166
|
def unmatched_field_name(component)
|
141
167
|
return component unless component == :street
|
142
|
-
return if
|
168
|
+
return if unmatched_components_to_validate[:street].nil?
|
143
169
|
|
144
|
-
original_street = T.must(
|
170
|
+
original_street = T.must(unmatched_components_to_validate[:street]).left_sequence.raw_value
|
145
171
|
|
146
172
|
if session.address.address1.to_s.include?(original_street)
|
147
173
|
:address1
|