atlas_engine 1.0.0 → 1.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 +39 -24
- data/app/countries/atlas_engine/at/country_profile.yml +1 -1
- data/app/countries/atlas_engine/au/country_profile.yml +1 -1
- data/app/countries/atlas_engine/be/country_profile.yml +2 -2
- data/app/countries/atlas_engine/ch/country_profile.yml +1 -1
- data/app/countries/atlas_engine/fr/country_profile.yml +1 -1
- data/app/countries/atlas_engine/nl/country_profile.yml +1 -1
- data/app/countries/atlas_engine/pl/country_profile.yml +1 -1
- data/app/countries/atlas_engine/us/country_profile.yml +1 -0
- data/app/graphql/atlas_engine/schema.graphql +14 -1
- data/app/graphql/atlas_engine/types/address_validation/address_input.rb +4 -0
- data/app/graphql/atlas_engine/types/address_validation/concern_type.rb +8 -1
- data/app/graphql/atlas_engine/types/address_validation/suggestion_type.rb +4 -0
- data/app/graphql/atlas_engine/types/message_format_type.rb +11 -0
- data/app/graphql/atlas_engine/types/query_type.rb +3 -1
- data/app/lib/atlas_engine/validation_transcriber/address_parsings.rb +14 -9
- data/app/lib/atlas_engine/validation_transcriber/formatter.rb +10 -1
- data/app/models/atlas_engine/address_number_range.rb +1 -1
- data/app/models/atlas_engine/address_validation/abstract_address.rb +12 -0
- data/app/models/atlas_engine/address_validation/address.rb +8 -0
- data/app/models/atlas_engine/address_validation/concern_record.rb +28 -0
- data/app/models/atlas_engine/address_validation/es/validators/full_address.rb +18 -5
- data/app/models/atlas_engine/address_validation/es/validators/full_address_street.rb +2 -2
- data/app/models/atlas_engine/address_validation/full_address_validator_base.rb +6 -2
- data/app/models/atlas_engine/address_validation/message_format.rb +13 -0
- data/app/models/atlas_engine/address_validation/predicate_pipeline_builder.rb +90 -0
- data/app/models/atlas_engine/address_validation/request.rb +1 -0
- data/app/models/atlas_engine/address_validation/suggestion.rb +26 -1
- data/app/models/atlas_engine/address_validation/validator.rb +31 -14
- data/app/models/atlas_engine/address_validation/validators/full_address/candidate_result.rb +9 -5
- data/app/models/atlas_engine/address_validation/validators/full_address/candidate_result_base.rb +4 -3
- data/app/models/atlas_engine/address_validation/validators/full_address/concern_builder.rb +19 -4
- data/app/models/atlas_engine/address_validation/validators/full_address/invalid_zip_concern_builder.rb +4 -3
- data/app/models/atlas_engine/address_validation/validators/full_address/invalid_zip_for_country_concern_builder.rb +6 -4
- data/app/models/atlas_engine/address_validation/validators/full_address/invalid_zip_for_province_concern_builder.rb +4 -2
- data/app/models/atlas_engine/address_validation/validators/full_address/no_candidate_result.rb +1 -1
- data/app/models/atlas_engine/address_validation/validators/full_address/suggestion_builder.rb +9 -2
- data/app/models/atlas_engine/address_validation/validators/full_address/unknown_address_concern_builder.rb +16 -4
- data/app/models/atlas_engine/address_validation/validators/full_address/unknown_province_concern_builder.rb +8 -3
- data/app/models/atlas_engine/address_validation/validators/full_address/unmatched_field_concern_builder.rb +13 -3
- data/app/models/atlas_engine/address_validation/validators/full_address/unsupported_script_result.rb +1 -1
- data/app/models/atlas_engine/address_validation/validators/predicates/city/present.rb +1 -1
- data/app/models/atlas_engine/address_validation/validators/predicates/country/exists.rb +5 -1
- data/app/models/atlas_engine/address_validation/validators/predicates/country/valid_for_zip.rb +1 -1
- data/app/models/atlas_engine/address_validation/validators/predicates/neighborhood/present.rb +35 -0
- data/app/models/atlas_engine/address_validation/validators/predicates/not_exceed_max_length.rb +18 -3
- data/app/models/atlas_engine/address_validation/validators/predicates/phone/valid.rb +3 -1
- data/app/models/atlas_engine/address_validation/validators/predicates/predicate.rb +6 -2
- data/app/models/atlas_engine/address_validation/validators/predicates/province/exists.rb +3 -1
- data/app/models/atlas_engine/address_validation/validators/predicates/province/valid_for_country.rb +3 -1
- data/app/models/atlas_engine/address_validation/validators/predicates/street/present.rb +3 -1
- data/app/models/atlas_engine/address_validation/validators/predicates/street_name/present.rb +35 -0
- data/app/models/atlas_engine/address_validation/validators/predicates/street_number/present.rb +35 -0
- data/app/models/atlas_engine/address_validation/validators/predicates/zip/present.rb +2 -2
- data/app/models/atlas_engine/address_validation/validators/predicates/zip/valid_for_country.rb +1 -1
- data/app/models/atlas_engine/address_validation/validators/predicates/zip/valid_for_province.rb +1 -1
- data/app/models/atlas_engine/services/validation.rb +4 -0
- data/db/data/validation_pipelines/es.yml +46 -0
- data/db/data/validation_pipelines/es_street.yml +46 -0
- data/db/data/validation_pipelines/local.yml +46 -0
- data/lib/atlas_engine/version.rb +1 -1
- metadata +39 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2ac0ad464ab86fe1db96b5ca3f5a69254d6ad52571d8c83350645c9e031ea58b
|
4
|
+
data.tar.gz: f683950cfa6d89c1cdf4935d8a49d76e416c57220ac29e5aa62adcdaf2a628d5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 79ae2f83d4b4ee2d65a7d6e566bee41ac3b0c5e44f879090b4659151ca9f7987e128badf6f31569530c142ea683b8df6dce10275423469924c44f1477f6480d6
|
7
|
+
data.tar.gz: e1a0e889113742443408d479dba7f1bb294230d4bcfd0af8f128e6c200a19d6c595c1bdf420798ebd2a9cb9caa8fa2cd69ef21ab4361ae066aa6a48861e9f91d
|
data/README.md
CHANGED
@@ -7,6 +7,7 @@ Atlas Engine is a rails engine that provides a global end-to-end address validat
|
|
7
7
|
* [Local Development Installation](#local-development-installation)
|
8
8
|
* [Address Data Ingestion](#address-data-ingestion)
|
9
9
|
* [Elasticsearch Matching Strategy](#elasticsearch-matching-strategy)
|
10
|
+
* [Hosted Solution](#hosted-solution)
|
10
11
|
|
11
12
|
## Address Validation API
|
12
13
|
|
@@ -24,7 +25,6 @@ query validation {
|
|
24
25
|
zip: "K2P 2L8"
|
25
26
|
}
|
26
27
|
locale: "en"
|
27
|
-
matchingStrategy: LOCAL
|
28
28
|
) {
|
29
29
|
validationScope
|
30
30
|
concerns {
|
@@ -69,21 +69,6 @@ presence or absence differs per country.
|
|
69
69
|
|
70
70
|
**Locale:** The language in which to render any messages in the validation API response.
|
71
71
|
|
72
|
-
**MatchingStrategy:** The strategy used to evaluate the validity of the address input. Out of the box, Atlas Engine
|
73
|
-
supports three different matching strategies: `local`, `es`, and `es_street`.
|
74
|
-
- `local` matching uses the [worldwide](https://github.com/Shopify/worldwide) gem to provide the most basic level of
|
75
|
-
address validation. This may include simple errors (required fields not populated) or more advanced errors (province
|
76
|
-
not belonging to the country, zip code not belonging to the province). This level of matching does not require
|
77
|
-
[ingestion](#ingestion) of country data to work, but the level of support and suggestions it can provide in its
|
78
|
-
responses is minimal.
|
79
|
-
- `es` matching uses data indexed in elasticsearch via our [ingestion](#ingestion) process to validate the city,
|
80
|
-
province, country, and zip code fields of the input address, in addition to all of the basic functionality provided
|
81
|
-
in the `local` strategy. A more detailed explanation for how this strategy works can be found [here](#elasticsearch-matching-strategy).
|
82
|
-
- `es_street` is our most advanced matching strategy and requires the highest quality data indexed in elasticsearch
|
83
|
-
via our [ingestion](#ingestion) process. This matching strategy provides everything that `es` and `local` does along
|
84
|
-
with validation of the address1 and address2 components of the address input. A more detailed explanation of how
|
85
|
-
this strategy works can be found [here](#elasticsearch-matching-strategy).
|
86
|
-
|
87
72
|
**Validation Scope:** This response object is populated with the field names from the input that have been successfully
|
88
73
|
validated.
|
89
74
|
|
@@ -108,7 +93,6 @@ query validation {
|
|
108
93
|
zip: "90210"
|
109
94
|
}
|
110
95
|
locale: "en"
|
111
|
-
matchingStrategy: LOCAL
|
112
96
|
) {
|
113
97
|
validationScope
|
114
98
|
concerns {
|
@@ -303,23 +287,24 @@ At the moment, `atlas_engine` supports advanced address validation for the follo
|
|
303
287
|
|
304
288
|
| Country/territory | Two-letter code | Locales | Street | City | Postal Code | Province/State |
|
305
289
|
|-------------------|-----------------|----------|--------|------|-------------|----------------|
|
306
|
-
| Australia | AU | |
|
307
|
-
| Austria | AT | |
|
308
|
-
| Belgium | BE | fr,nl,de |
|
290
|
+
| Australia | AU | | x | x | x | x |
|
291
|
+
| Austria | AT | | x | x | x | x |
|
292
|
+
| Belgium | BE | fr,nl,de | x | x | x | |
|
309
293
|
| Bermuda | BM | | | x | x | x |
|
310
294
|
| Czechia | CZ | | | x | x | |
|
311
295
|
| Denmark | DK | | | x | x | |
|
312
296
|
| Faroe Islands | FO | | | x | x | |
|
313
|
-
| France | FR | |
|
297
|
+
| France | FR | | x | x | x | |
|
298
|
+
| Gurnsey | GG | | | x | x | |
|
314
299
|
| Italy | IT | | | | x | |
|
315
300
|
| Liechtenstein | LI | | | x | x | x |
|
316
301
|
| Luxembourg | LU | fr,lb | | x | x | |
|
317
|
-
| Netherlands | NL | nl |
|
318
|
-
| Poland | PL | |
|
302
|
+
| Netherlands | NL | nl | x | x | x | x |
|
303
|
+
| Poland | PL | | x | x | x | x |
|
319
304
|
| Portugal | PT | | | x | x | x |
|
320
305
|
| Slovenia | SI | | | x | x | x |
|
321
306
|
| South Korea | KR | | | x | x | x |
|
322
|
-
| Switzerland | CH | de,fr,it |
|
307
|
+
| Switzerland | CH | de,fr,it | x | x | x | |
|
323
308
|
| United States | US | en | x | x | x | x |
|
324
309
|
|
325
310
|
### Downloading and indexing instructions
|
@@ -408,6 +393,20 @@ and the US data is in mysql the rest of the process for creating the elasticsear
|
|
408
393
|
|
409
394
|
## Elasticsearch Matching Strategy
|
410
395
|
|
396
|
+
An optional GraphQL parameter, and the strategy used to evaluate the validity of the address input. Out of the box, Atlas Engine
|
397
|
+
supports three different matching strategies: `local`, `es`, and `es_street`.
|
398
|
+
- `local` matching uses the [worldwide](https://github.com/Shopify/worldwide) gem to provide the most basic level of
|
399
|
+
address validation. This may include simple errors (required fields not populated) or more advanced errors (province
|
400
|
+
not belonging to the country, zip code not belonging to the province). This level of matching does not require
|
401
|
+
[ingestion](#ingestion) of country data to work, but the level of support and suggestions it can provide in its
|
402
|
+
responses is minimal.
|
403
|
+
- `es` matching uses data indexed in elasticsearch via our [ingestion](#ingestion) process to validate the city,
|
404
|
+
province, country, and zip code fields of the input address, in addition to all of the basic functionality provided
|
405
|
+
in the `local` strategy.
|
406
|
+
- `es_street` is our most advanced matching strategy and requires the highest quality data indexed in elasticsearch
|
407
|
+
via our [ingestion](#ingestion) process. This matching strategy provides everything that `es` and `local` does along
|
408
|
+
with validation of the address1 and address2 components of the address input.
|
409
|
+
|
411
410
|
Once we have successfully created and activated an elasticsearch index using open address data, we may now use
|
412
411
|
the more advanced elasticsearch matching strategies `es` and `es_street`.
|
413
412
|
|
@@ -653,3 +652,19 @@ will produce the response:
|
|
653
652
|
```
|
654
653
|
|
655
654
|
This response has no concerns or suggestions, and the input address is therefore considered to be valid.
|
655
|
+
|
656
|
+
## Hosted Solution
|
657
|
+
|
658
|
+
If you wish to use the Shopify hosted version of the `atlas_engine` codebase in your applications, you will need to [register for an api key](https://address-validation.shopify.dev/#request-api-key) and agree to our [terms and conditions](https://address-validation.shopify.dev/terms-of-service).
|
659
|
+
|
660
|
+
Once you have successfully redeemed an api key, you will be able to access the `/graphql` endpoint, which can be queried using this example curl request:
|
661
|
+
|
662
|
+
```
|
663
|
+
curl --request POST \
|
664
|
+
--url https://atlas-validation.shopifyapps.com/graphql \
|
665
|
+
--header 'Authorization: Bearer {your-api-key}' \
|
666
|
+
--header 'Content-Type: application/json' \
|
667
|
+
--data '{"query":"query validation { validation(address: { address1: \"233 S Wacker Dr\" address2: \"\" city: \"Chicago\" countryCode: US provinceCode: \"IL\" zip: \"60606\" } locale: \"EN\" ) { validationScope concerns { code fieldNames suggestionIds type typeLevel message } suggestions { id address1 address2 city province provinceCode zip } }}","operationName":"validation"}'
|
668
|
+
```
|
669
|
+
|
670
|
+
Any updates to the `atlas_engine` codebase that are merged into our `main` branch will be deployed to our hosted solution as well.
|
@@ -9,7 +9,7 @@ ingestion:
|
|
9
9
|
data_mapper: AtlasEngine::AddressValidation::Es::DataMappers::DecompoundingDataMapper
|
10
10
|
validation:
|
11
11
|
enabled: true
|
12
|
-
default_matching_strategy:
|
12
|
+
default_matching_strategy: es_street
|
13
13
|
has_provinces: true
|
14
14
|
address_parser: AtlasEngine::At::ValidationTranscriber::AddressParser
|
15
15
|
normalized_components:
|
@@ -8,6 +8,6 @@ ingestion:
|
|
8
8
|
validation:
|
9
9
|
address_parser: AtlasEngine::Au::ValidationTranscriber::AddressParser
|
10
10
|
enabled: true
|
11
|
-
default_matching_strategy:
|
11
|
+
default_matching_strategy: es_street
|
12
12
|
open_address:
|
13
13
|
filter: AtlasEngine::Au::AddressImporter::OpenAddress::Filter
|
@@ -5,9 +5,9 @@ ingestion:
|
|
5
5
|
max_zip_edge_ngram: "4"
|
6
6
|
validation:
|
7
7
|
enabled: true
|
8
|
-
default_matching_strategy:
|
8
|
+
default_matching_strategy: es_street
|
9
9
|
address_parser: AtlasEngine::Be::ValidationTranscriber::AddressParser
|
10
|
-
has_provinces: false
|
10
|
+
has_provinces: false
|
11
11
|
index_locales:
|
12
12
|
- fr
|
13
13
|
- nl
|
@@ -7,7 +7,7 @@ ingestion:
|
|
7
7
|
validation:
|
8
8
|
address_parser: AtlasEngine::Pl::ValidationTranscriber::AddressParser
|
9
9
|
enabled: true
|
10
|
-
default_matching_strategy:
|
10
|
+
default_matching_strategy: es_street
|
11
11
|
exclusions:
|
12
12
|
city:
|
13
13
|
- AtlasEngine::Pl::AddressValidation::Exclusions::RuralAddress
|
@@ -9,6 +9,7 @@ ingestion:
|
|
9
9
|
validation:
|
10
10
|
enabled: true
|
11
11
|
default_matching_strategy: es_street
|
12
|
+
unmatched_components_suggestion_threshold: 1
|
12
13
|
address_parser: AtlasEngine::ValidationTranscriber::AddressParserNorthAmerica
|
13
14
|
open_address:
|
14
15
|
filter: AtlasEngine::Us::AddressImporter::OpenAddress::Filter
|
@@ -6,8 +6,12 @@ input AddressInput {
|
|
6
6
|
address2: String
|
7
7
|
city: String
|
8
8
|
countryCode: ValidationSupportedCountry
|
9
|
+
line2: String
|
10
|
+
neighborhood: String
|
9
11
|
phone: String
|
10
12
|
provinceCode: String
|
13
|
+
streetName: String
|
14
|
+
streetNumber: String
|
11
15
|
zip: String
|
12
16
|
}
|
13
17
|
|
@@ -43,8 +47,13 @@ enum MatchingStrategy {
|
|
43
47
|
LOCAL
|
44
48
|
}
|
45
49
|
|
50
|
+
enum MessageFormat {
|
51
|
+
INFORMATIVE
|
52
|
+
INSTRUCTIONAL
|
53
|
+
}
|
54
|
+
|
46
55
|
type Query {
|
47
|
-
validation(address: AddressInput!, locale: String!, matchingStrategy: MatchingStrategy): Validation!
|
56
|
+
validation(address: AddressInput!, locale: String!, matchingStrategy: MatchingStrategy, messageFormat: MessageFormat): Validation!
|
48
57
|
}
|
49
58
|
|
50
59
|
"""
|
@@ -56,8 +65,12 @@ type Suggestion {
|
|
56
65
|
city: String
|
57
66
|
countryCode: ValidationSupportedCountry
|
58
67
|
id: String!
|
68
|
+
line2: String
|
69
|
+
neighborhood: String
|
59
70
|
province: String
|
60
71
|
provinceCode: String
|
72
|
+
streetName: String
|
73
|
+
streetNumber: String
|
61
74
|
zip: String
|
62
75
|
}
|
63
76
|
|
@@ -12,7 +12,11 @@ module AtlasEngine
|
|
12
12
|
description "Address fields used to fulfill a validation request"
|
13
13
|
|
14
14
|
argument :address1, String, required: false
|
15
|
+
argument :street_name, String, required: false
|
16
|
+
argument :street_number, String, required: false
|
15
17
|
argument :address2, String, required: false
|
18
|
+
argument :line2, String, required: false
|
19
|
+
argument :neighborhood, String, required: false
|
16
20
|
argument :city, String, required: false
|
17
21
|
argument :country_code, ValidationSupportedCountry, required: false
|
18
22
|
argument :province_code, String, required: false
|
@@ -1,10 +1,12 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: true
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
module AtlasEngine
|
5
5
|
module Types
|
6
6
|
module AddressValidation
|
7
7
|
class ConcernType < BaseObject
|
8
|
+
extend T::Sig
|
9
|
+
|
8
10
|
description "A piece of relevant information regarding the address validation result." \
|
9
11
|
"They can be categorized as either a Warning or Error."
|
10
12
|
|
@@ -14,6 +16,11 @@ module AtlasEngine
|
|
14
16
|
field :type, Enums::ConcernEnum, null: false
|
15
17
|
field :type_level, Int, null: false
|
16
18
|
field :suggestion_ids, [String], null: false
|
19
|
+
|
20
|
+
sig { returns(T::Array[String]) }
|
21
|
+
def field_names
|
22
|
+
object.field_names.map { |field_name| field_name.to_s.camelize(:lower) }
|
23
|
+
end
|
17
24
|
end
|
18
25
|
end
|
19
26
|
end
|
@@ -9,7 +9,11 @@ module AtlasEngine
|
|
9
9
|
|
10
10
|
field :id, String, null: false
|
11
11
|
field :address1, String, null: true
|
12
|
+
field :street_name, String, null: true
|
13
|
+
field :street_number, String, null: true
|
12
14
|
field :address2, String, null: true
|
15
|
+
field :line2, String, null: true
|
16
|
+
field :neighborhood, String, null: true
|
13
17
|
field :city, String, null: true
|
14
18
|
field :zip, String, null: true
|
15
19
|
field :province_code, String, null: true
|
@@ -10,9 +10,10 @@ module AtlasEngine
|
|
10
10
|
argument :address, AddressValidation::AddressInput, required: true
|
11
11
|
argument :locale, String, required: true
|
12
12
|
argument :matching_strategy, MatchingStrategyType, required: false
|
13
|
+
argument :message_format, MessageFormatType, required: false
|
13
14
|
end
|
14
15
|
|
15
|
-
def validation(address:, locale: "en", matching_strategy: nil)
|
16
|
+
def validation(address:, locale: "en", matching_strategy: nil, message_format: nil)
|
16
17
|
raise build_graphql_error(AtlasEngine::AddressValidation::Errors::MISSING_PARAMETER) if address.blank?
|
17
18
|
|
18
19
|
locale = LocaleFormatHelper.format_locale(locale)
|
@@ -26,6 +27,7 @@ module AtlasEngine
|
|
26
27
|
address: address,
|
27
28
|
locale: locale,
|
28
29
|
matching_strategy: matching_strategy,
|
30
|
+
message_format: message_format,
|
29
31
|
),
|
30
32
|
)
|
31
33
|
end
|
@@ -9,22 +9,27 @@ module AtlasEngine
|
|
9
9
|
|
10
10
|
ParsedComponents = T.type_alias { T::Hash[Symbol, String] }
|
11
11
|
|
12
|
-
sig { returns(T::Array[ParsedComponents]) }
|
13
|
-
attr_reader :parsings
|
14
|
-
|
15
12
|
sig { params(address_input: AddressValidation::AbstractAddress, locale: T.nilable(String)).void }
|
16
13
|
def initialize(address_input:, locale: nil)
|
17
|
-
@
|
14
|
+
@address_input = address_input
|
15
|
+
@locale = locale
|
16
|
+
end
|
17
|
+
|
18
|
+
sig { returns(T::Array[ParsedComponents]) }
|
19
|
+
def parsings
|
20
|
+
@parsings ||= T.let(
|
18
21
|
begin
|
19
|
-
if address_input.country_code.blank?
|
22
|
+
if @address_input.country_code.blank?
|
20
23
|
[]
|
21
|
-
|
22
|
-
parsing_result = AddressParserFactory.create(address: address_input, locale: locale).parse
|
23
|
-
log_unparsable_address(address_input) if parsing_result.empty?
|
24
|
+
elsif @address_input.street_name.nil? && @address_input.street_number.nil?
|
25
|
+
parsing_result = AddressParserFactory.create(address: @address_input, locale: @locale).parse
|
26
|
+
log_unparsable_address(@address_input) if parsing_result.empty?
|
24
27
|
parsing_result
|
28
|
+
else
|
29
|
+
[{ street: @address_input.street_name, building_num: @address_input.street_number }]
|
25
30
|
end
|
26
31
|
end,
|
27
|
-
T::Array[ParsedComponents],
|
32
|
+
T.nilable(T::Array[ParsedComponents]),
|
28
33
|
)
|
29
34
|
end
|
30
35
|
|
@@ -22,7 +22,11 @@ module AtlasEngine
|
|
22
22
|
sig do
|
23
23
|
params(
|
24
24
|
address1: String,
|
25
|
+
street_name: String,
|
26
|
+
street_number: String,
|
25
27
|
address2: String,
|
28
|
+
line2: String,
|
29
|
+
neighborhood: String,
|
26
30
|
city: String,
|
27
31
|
province_code: String,
|
28
32
|
zip: String,
|
@@ -30,10 +34,15 @@ module AtlasEngine
|
|
30
34
|
phone: String,
|
31
35
|
).returns(AddressValidation::Address)
|
32
36
|
end
|
33
|
-
def build_address(address1: "",
|
37
|
+
def build_address(address1: "", street_name: "", street_number: "", address2: "", line2: "", neighborhood: "",
|
38
|
+
city: "", province_code: "", zip: "", country_code: "", phone: "")
|
34
39
|
AddressValidation::Address.new(
|
35
40
|
address1: address1,
|
41
|
+
street_name: street_name,
|
42
|
+
street_number: street_number,
|
36
43
|
address2: address2,
|
44
|
+
line2: line2,
|
45
|
+
neighborhood: neighborhood,
|
37
46
|
city: city,
|
38
47
|
province_code: province_code,
|
39
48
|
zip: zip,
|
@@ -164,7 +164,7 @@ module AtlasEngine
|
|
164
164
|
|
165
165
|
sig { params(value: String).returns(T::Boolean) }
|
166
166
|
def include_fractions?(value)
|
167
|
-
%r{^([0-9]+ )?([0-9]+/[0-9]
|
167
|
+
%r{^([0-9]+ )?([0-9]+/[1-9][0-9]*)?$}.match?(value)
|
168
168
|
end
|
169
169
|
|
170
170
|
sig { params(str: String).returns(String) }
|
@@ -13,9 +13,21 @@ module AtlasEngine
|
|
13
13
|
sig { abstract.returns(ComponentType) }
|
14
14
|
def address1; end
|
15
15
|
|
16
|
+
sig { returns(ComponentType) }
|
17
|
+
def street_name; end
|
18
|
+
|
19
|
+
sig { returns(ComponentType) }
|
20
|
+
def street_number; end
|
21
|
+
|
16
22
|
sig { abstract.returns(ComponentType) }
|
17
23
|
def address2; end
|
18
24
|
|
25
|
+
sig { returns(ComponentType) }
|
26
|
+
def line2; end
|
27
|
+
|
28
|
+
sig { returns(ComponentType) }
|
29
|
+
def neighborhood; end
|
30
|
+
|
19
31
|
sig { abstract.returns(ComponentType) }
|
20
32
|
def city; end
|
21
33
|
|
@@ -13,7 +13,11 @@ module AtlasEngine
|
|
13
13
|
AddressInput = T.type_alias { Types::AddressValidation::AddressInput }
|
14
14
|
|
15
15
|
const :address1, ComponentType
|
16
|
+
const :street_name, ComponentType
|
17
|
+
const :street_number, ComponentType
|
16
18
|
const :address2, ComponentType
|
19
|
+
const :line2, ComponentType
|
20
|
+
const :neighborhood, ComponentType
|
17
21
|
const :city, ComponentType
|
18
22
|
const :province_code, ComponentType
|
19
23
|
const :phone, ComponentType
|
@@ -33,7 +37,11 @@ module AtlasEngine
|
|
33
37
|
def from_address(address:)
|
34
38
|
new(
|
35
39
|
address1: address.address1,
|
40
|
+
street_name: address.street_name,
|
41
|
+
street_number: address.street_number,
|
36
42
|
address2: address.address2,
|
43
|
+
line2: address.line2,
|
44
|
+
neighborhood: address.neighborhood,
|
37
45
|
city: address.city,
|
38
46
|
country_code: address.country_code,
|
39
47
|
province_code: address.province_code,
|
@@ -9,9 +9,21 @@ module AtlasEngine
|
|
9
9
|
sig { returns(String) }
|
10
10
|
attr_reader :address1
|
11
11
|
|
12
|
+
sig { returns(String) }
|
13
|
+
attr_reader :street_name
|
14
|
+
|
15
|
+
sig { returns(String) }
|
16
|
+
attr_reader :street_number
|
17
|
+
|
12
18
|
sig { returns(String) }
|
13
19
|
attr_reader :address2
|
14
20
|
|
21
|
+
sig { returns(String) }
|
22
|
+
attr_reader :line2
|
23
|
+
|
24
|
+
sig { returns(String) }
|
25
|
+
attr_reader :neighborhood
|
26
|
+
|
15
27
|
sig { returns(String) }
|
16
28
|
attr_reader :city
|
17
29
|
|
@@ -73,7 +85,11 @@ module AtlasEngine
|
|
73
85
|
timestamp: Time,
|
74
86
|
origin: String,
|
75
87
|
address1: String,
|
88
|
+
street_name: String,
|
89
|
+
street_number: String,
|
76
90
|
address2: String,
|
91
|
+
line2: String,
|
92
|
+
neighborhood: String,
|
77
93
|
city: String,
|
78
94
|
province_code: String,
|
79
95
|
country_code: String,
|
@@ -87,7 +103,11 @@ module AtlasEngine
|
|
87
103
|
timestamp: Time.zone.now,
|
88
104
|
origin: "",
|
89
105
|
address1: "",
|
106
|
+
street_name: "",
|
107
|
+
street_number: "",
|
90
108
|
address2: "",
|
109
|
+
line2: "",
|
110
|
+
neighborhood: "",
|
91
111
|
city: "",
|
92
112
|
province_code: "",
|
93
113
|
country_code: "",
|
@@ -100,7 +120,11 @@ module AtlasEngine
|
|
100
120
|
@timestamp = timestamp
|
101
121
|
@origin = origin
|
102
122
|
@address1 = address1
|
123
|
+
@street_name = street_name
|
124
|
+
@street_number = street_number
|
103
125
|
@address2 = address2
|
126
|
+
@line2 = line2
|
127
|
+
@neighborhood = neighborhood
|
104
128
|
@city = city
|
105
129
|
@province_code = province_code
|
106
130
|
@country_code = country_code
|
@@ -114,7 +138,11 @@ module AtlasEngine
|
|
114
138
|
def address_attributes
|
115
139
|
{
|
116
140
|
address1: address1,
|
141
|
+
street_name: street_name,
|
142
|
+
street_number: street_number,
|
117
143
|
address2: address2,
|
144
|
+
line2: line2,
|
145
|
+
neighborhood: neighborhood,
|
118
146
|
city: city,
|
119
147
|
province_code: province_code,
|
120
148
|
zip: zip,
|
@@ -8,12 +8,13 @@ module AtlasEngine
|
|
8
8
|
class FullAddress < FullAddressValidatorBase
|
9
9
|
include LogHelper
|
10
10
|
|
11
|
-
attr_reader :address, :result
|
11
|
+
attr_reader :address, :result, :message_format
|
12
12
|
|
13
|
-
sig { params(address: TAddress, result: Result).void }
|
14
|
-
def initialize(address:, result: Result.new)
|
13
|
+
sig { params(address: TAddress, result: Result, message_format: MessageFormat).void }
|
14
|
+
def initialize(address:, result: Result.new, message_format: MessageFormat::Instructional)
|
15
15
|
super
|
16
16
|
@matching_strategy = MatchingStrategies::Es
|
17
|
+
@message_format = message_format
|
17
18
|
end
|
18
19
|
|
19
20
|
sig { override.returns(Result) }
|
@@ -29,16 +30,23 @@ module AtlasEngine
|
|
29
30
|
sig { returns(AddressValidation::Validators::FullAddress::CandidateResultBase) }
|
30
31
|
def build_candidate_result
|
31
32
|
unless supported_address?(address)
|
32
|
-
return AddressValidation::Validators::FullAddress::UnsupportedScriptResult.new(
|
33
|
+
return AddressValidation::Validators::FullAddress::UnsupportedScriptResult.new(
|
34
|
+
address:,
|
35
|
+
result:,
|
36
|
+
message_format:,
|
37
|
+
)
|
33
38
|
end
|
34
39
|
|
35
40
|
if best_candidate.nil?
|
36
|
-
AddressValidation::Validators::FullAddress::NoCandidateResult.new(
|
41
|
+
AddressValidation::Validators::FullAddress::NoCandidateResult.new(
|
42
|
+
address:, result:, message_format:,
|
43
|
+
)
|
37
44
|
else
|
38
45
|
AddressValidation::Validators::FullAddress::CandidateResult.new(
|
39
46
|
address_comparison: T.must(best_candidate),
|
40
47
|
matching_strategy: @matching_strategy,
|
41
48
|
result: result,
|
49
|
+
message_format:,
|
42
50
|
)
|
43
51
|
end
|
44
52
|
end
|
@@ -100,6 +108,10 @@ module AtlasEngine
|
|
100
108
|
:zip,
|
101
109
|
:address1,
|
102
110
|
:address2,
|
111
|
+
:street_name,
|
112
|
+
:street_number,
|
113
|
+
:neighborhood,
|
114
|
+
:line2,
|
103
115
|
])
|
104
116
|
end
|
105
117
|
|
@@ -108,6 +120,7 @@ module AtlasEngine
|
|
108
120
|
result.concerns.flat_map(&:code).intersect?([
|
109
121
|
:address1_contains_too_many_words,
|
110
122
|
:address2_contains_too_many_words,
|
123
|
+
:street_name_contains_too_many_words,
|
111
124
|
])
|
112
125
|
end
|
113
126
|
|
@@ -6,8 +6,8 @@ module AtlasEngine
|
|
6
6
|
module Es
|
7
7
|
module Validators
|
8
8
|
class FullAddressStreet < FullAddress
|
9
|
-
sig { params(address: TAddress, result: Result).void }
|
10
|
-
def initialize(address:, result: Result.new)
|
9
|
+
sig { params(address: TAddress, message_format: MessageFormat, result: Result).void }
|
10
|
+
def initialize(address:, message_format:, result: Result.new)
|
11
11
|
super
|
12
12
|
@matching_strategy = MatchingStrategies::EsStreet
|
13
13
|
end
|
@@ -14,10 +14,14 @@ module AtlasEngine
|
|
14
14
|
sig { returns(AbstractAddress) }
|
15
15
|
attr_reader :address
|
16
16
|
|
17
|
-
sig {
|
18
|
-
|
17
|
+
sig { returns(MessageFormat) }
|
18
|
+
attr_reader :message_format
|
19
|
+
|
20
|
+
sig { params(address: AbstractAddress, result: Result, message_format: MessageFormat).void }
|
21
|
+
def initialize(address:, result:, message_format: MessageFormat::Instructional)
|
19
22
|
@address = address
|
20
23
|
@result = result
|
24
|
+
@message_format = message_format
|
21
25
|
end
|
22
26
|
|
23
27
|
sig { abstract.returns(Result) }
|