active_validation 3.0.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.DS_Store +0 -0
- data/.fasterer.yml +19 -0
- data/.reek +36 -0
- data/.rubocop.yml +54 -0
- data/Gemfile +1 -1
- data/Rakefile +1 -1
- data/active_validation.gemspec +21 -18
- data/bin/console +4 -4
- data/bin/rake +6 -7
- data/config/locales/en.yml +83 -83
- data/lib/.DS_Store +0 -0
- data/lib/active_validation.rb +12 -83
- data/lib/active_validation/.DS_Store +0 -0
- data/lib/active_validation/railtie.rb +19 -0
- data/lib/active_validation/validators/alpha_numeric_validator.rb +11 -10
- data/lib/active_validation/validators/alpha_validator.rb +11 -10
- data/lib/active_validation/validators/base64_validator.rb +2 -1
- data/lib/active_validation/validators/boolean_validator.rb +4 -6
- data/lib/active_validation/validators/coordinate_validator.rb +8 -5
- data/lib/active_validation/validators/credit_card_validator.rb +35 -36
- data/lib/active_validation/validators/currency_validator.rb +3 -2
- data/lib/active_validation/validators/cusip_validator.rb +9 -6
- data/lib/active_validation/validators/email_validator.rb +4 -3
- data/lib/active_validation/validators/equality_validator.rb +14 -13
- data/lib/active_validation/validators/hex_validator.rb +2 -1
- data/lib/active_validation/validators/imei_validator.rb +7 -6
- data/lib/active_validation/validators/ip_validator.rb +4 -1
- data/lib/active_validation/validators/isbn_validator.rb +5 -4
- data/lib/active_validation/validators/isin_validator.rb +12 -9
- data/lib/active_validation/validators/mac_address_validator.rb +7 -3
- data/lib/active_validation/validators/name_validator.rb +3 -2
- data/lib/active_validation/validators/password_validator.rb +7 -2
- data/lib/active_validation/validators/phone_validator.rb +3 -2
- data/lib/active_validation/validators/sedol_validator.rb +4 -3
- data/lib/active_validation/validators/slug_validator.rb +2 -1
- data/lib/active_validation/validators/ssn_validator.rb +2 -1
- data/lib/active_validation/validators/tracking_number_validator.rb +73 -68
- data/lib/active_validation/validators/type_validator.rb +3 -2
- data/lib/active_validation/validators/url_validator.rb +12 -11
- data/lib/active_validation/validators/username_validator.rb +2 -1
- data/lib/active_validation/validators/uuid_validator.rb +12 -11
- data/lib/active_validation/version.rb +1 -1
- metadata +51 -29
- data/lib/active_validation/matchers/ensure_valid_alpha_format_of.rb +0 -26
- data/lib/active_validation/matchers/ensure_valid_alpha_numeric_format_of.rb +0 -26
- data/lib/active_validation/matchers/ensure_valid_base64_format_of.rb +0 -26
- data/lib/active_validation/matchers/ensure_valid_boolean_format_of.rb +0 -26
- data/lib/active_validation/matchers/ensure_valid_coordinate_format_of.rb +0 -26
- data/lib/active_validation/matchers/ensure_valid_credit_card_format_of.rb +0 -26
- data/lib/active_validation/matchers/ensure_valid_currency_format_of.rb +0 -26
- data/lib/active_validation/matchers/ensure_valid_cusip_format_of.rb +0 -26
- data/lib/active_validation/matchers/ensure_valid_email_format_of.rb +0 -26
- data/lib/active_validation/matchers/ensure_valid_equality_matcher_of.rb +0 -40
- data/lib/active_validation/matchers/ensure_valid_hex_format_of.rb +0 -26
- data/lib/active_validation/matchers/ensure_valid_imei_format_of.rb +0 -26
- data/lib/active_validation/matchers/ensure_valid_ip_format_of.rb +0 -26
- data/lib/active_validation/matchers/ensure_valid_isbn_format_of.rb +0 -26
- data/lib/active_validation/matchers/ensure_valid_isin_format_of.rb +0 -26
- data/lib/active_validation/matchers/ensure_valid_mac_address_format_of.rb +0 -26
- data/lib/active_validation/matchers/ensure_valid_name_format_of.rb +0 -26
- data/lib/active_validation/matchers/ensure_valid_password_format_of.rb +0 -26
- data/lib/active_validation/matchers/ensure_valid_phone_format_of.rb +0 -26
- data/lib/active_validation/matchers/ensure_valid_sedol_format_of.rb +0 -26
- data/lib/active_validation/matchers/ensure_valid_slug_format_of.rb +0 -26
- data/lib/active_validation/matchers/ensure_valid_ssn_format_of.rb +0 -26
- data/lib/active_validation/matchers/ensure_valid_tracking_number_format_of.rb +0 -26
- data/lib/active_validation/matchers/ensure_valid_type_format_of.rb +0 -26
- data/lib/active_validation/matchers/ensure_valid_url_format_of.rb +0 -26
- data/lib/active_validation/matchers/ensure_valid_username_format_of.rb +0 -26
- data/lib/active_validation/matchers/ensure_valid_uuid_format_of.rb +0 -26
@@ -2,15 +2,18 @@ class IpValidator < ActiveModel::EachValidator
|
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
4
|
unless valid?(value.to_s)
|
5
|
-
record.errors[attribute] <<
|
5
|
+
record.errors[attribute] <<
|
6
|
+
(options[:message] || I18n.t('active_validation.errors.messages.ip'))
|
6
7
|
end
|
7
8
|
end
|
8
9
|
|
9
10
|
private
|
10
11
|
|
12
|
+
# rubocop:disable Metrics/LineLength
|
11
13
|
def valid_format?(value)
|
12
14
|
value =~ /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
|
13
15
|
end
|
16
|
+
# rubocop:enable Metrics/LineLength
|
14
17
|
|
15
18
|
def valid_length?(value)
|
16
19
|
value.present?
|
@@ -2,19 +2,20 @@ class IsbnValidator < ActiveModel::EachValidator
|
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
4
|
unless valid?(value.to_s)
|
5
|
-
record.errors[attribute] <<
|
5
|
+
record.errors[attribute] <<
|
6
|
+
(options[:message] || I18n.t('active_validation.errors.messages.isbn'))
|
6
7
|
end
|
7
8
|
end
|
8
9
|
|
9
10
|
private
|
10
11
|
|
11
|
-
CHARS_VALUES =
|
12
|
+
CHARS_VALUES = %w(0 1 2 3 4 5 6 7 8 9 0 x).freeze
|
12
13
|
|
13
14
|
def valid_format?(value)
|
14
15
|
return(false) if value.empty?
|
15
|
-
value = value.gsub(/-| /,
|
16
|
+
value = value.gsub(/-| /, '').downcase.chars
|
16
17
|
|
17
|
-
[10, 13].include?(value.size) && value.all? { |
|
18
|
+
[10, 13].include?(value.size) && value.all? { |chr| CHARS_VALUES.include?(chr) }
|
18
19
|
end
|
19
20
|
|
20
21
|
def valid_length?(value)
|
@@ -2,7 +2,8 @@ class IsinValidator < ActiveModel::EachValidator
|
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
4
|
unless valid?(value.to_s)
|
5
|
-
record.errors[attribute] <<
|
5
|
+
record.errors[attribute] <<
|
6
|
+
(options[:message] || I18n.t('active_validation.errors.messages.isin'))
|
6
7
|
end
|
7
8
|
end
|
8
9
|
|
@@ -10,26 +11,28 @@ class IsinValidator < ActiveModel::EachValidator
|
|
10
11
|
|
11
12
|
def valid_checksum?(value)
|
12
13
|
characters = value.chars
|
13
|
-
digits = characters.map { |
|
14
|
-
even_values = digits.values_at(*digits.each_index.select
|
15
|
-
odd_values = digits.values_at(*digits.each_index.select
|
14
|
+
digits = characters.map { |chr| chr =~ /[A-Z]/ ? (chr.ord - 55) : chr.to_i }
|
15
|
+
even_values = digits.values_at(*digits.each_index.select(&:even?))
|
16
|
+
odd_values = digits.values_at(*digits.each_index.select(&:odd?))
|
16
17
|
|
17
18
|
longest, shortest = if even_values.last == characters.map(&:to_i)
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
[even_values, odd_values]
|
20
|
+
else
|
21
|
+
[odd_values, even_values]
|
22
|
+
end
|
22
23
|
|
23
|
-
longest = longest.map { |
|
24
|
+
longest = longest.map { |int| int * 2 }
|
24
25
|
values = longest.concat(shortest).to_s.scan(/./).map(&:to_i)
|
25
26
|
total = values.inject(&:+)
|
26
27
|
|
27
28
|
(10 - (total % 10)) % 10
|
28
29
|
end
|
29
30
|
|
31
|
+
# rubocop:disable Metrics/LineLength
|
30
32
|
def valid_format?(value)
|
31
33
|
value =~ /^((AF|AX|AL|DZ|AS|AD|AO|AI|AQ|AG|AR|AM|AW|AU|AT|AZ|BS|BH|BD|BB|BY|BE|BZ|BJ|BM|BT|BO|BQ|BA|BW|BV|BR|IO|BN|BG|BF|BI|KH|CM|CA|CV|KY|CF|TD|CL|CN|CX|CC|CO|KM|CG|CD|CK|CR|CI|HR|CU|CW|CY|CZ|DK|DJ|DM|DO|EC|EG|SV|GQ|ER|EE|ET|FK|FO|FJ|FI|FR|GF|PF|TF|GA|GM|GE|DE|GH|GI|GR|GL|GD|GP|GU|GT|GG|GN|GW|GY|HT|HM|VA|HN|HK|HU|IS|IN|ID|IR|IQ|IE|IM|IL|IT|JM|JP|JE|JO|KZ|KE|KI|KP|KR|KW|KG|LA|LV|LB|LS|LR|LY|LI|LT|LU|MO|MK|MG|MW|MY|MV|ML|MT|MH|MQ|MR|MU|YT|MX|FM|MD|MC|MN|ME|MS|MA|MZ|MM|NA|NR|NP|NL|NC|NZ|NI|NE|NG|NU|NF|MP|NO|OM|PK|PW|PS|PA|PG|PY|PE|PH|PN|PL|PT|PR|QA|RE|RO|RU|RW|BL|SH|KN|LC|MF|PM|VC|WS|SM|ST|SA|SN|RS|SC|SL|SG|SX|SK|SI|SB|SO|ZA|GS|SS|ES|LK|SD|SR|SJ|SZ|SE|CH|SY|TW|TJ|TZ|TH|TL|TG|TK|TO|TT|TN|TR|TM|TC|TV|UG|UA|AE|GB|US|UM|UY|UZ|VU|VE|VN|VG|VI|WF|EH|YE|ZM|ZW{2})([A-Z0-9]{9}))(\d{1})$/
|
32
34
|
end
|
35
|
+
# rubocop:enable Metrics/LineLength
|
33
36
|
|
34
37
|
def valid_length?(value)
|
35
38
|
value.present?
|
@@ -2,7 +2,8 @@ class MacAddressValidator < ActiveModel::EachValidator
|
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
4
|
unless valid?(value.to_s)
|
5
|
-
record.errors[attribute] <<
|
5
|
+
record.errors[attribute] <<
|
6
|
+
(options[:message] || I18n.t('active_validation.errors.messages.mac_address'))
|
6
7
|
end
|
7
8
|
end
|
8
9
|
|
@@ -12,11 +13,14 @@ class MacAddressValidator < ActiveModel::EachValidator
|
|
12
13
|
/^([\h]{2}:){5}[\h]{2}?$/i, /^([\h]{2}[-|\.|\s]){5}[\h]{2}?$/i,
|
13
14
|
/^([\h]{6})[-|\.][\h]{6}?$/i, /^([\h]{6}):[\h]{6}?$/i,
|
14
15
|
/^([\h]{4}[-|\.|\s]){2}[\h]{4}?$/i, /^[\h]{12}?$/i
|
15
|
-
]
|
16
|
+
].freeze
|
16
17
|
|
17
18
|
def valid_format?(value)
|
18
19
|
result = false
|
19
|
-
DEFAULT_FORMATS.each
|
20
|
+
DEFAULT_FORMATS.each do |pat|
|
21
|
+
result = (value =~ pat)
|
22
|
+
break if result
|
23
|
+
end
|
20
24
|
result
|
21
25
|
end
|
22
26
|
|
@@ -2,14 +2,15 @@ class NameValidator < ActiveModel::EachValidator
|
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
4
|
unless valid?(value.to_s)
|
5
|
-
record.errors[attribute] <<
|
5
|
+
record.errors[attribute] <<
|
6
|
+
(options[:message] || I18n.t('active_validation.errors.messages.name'))
|
6
7
|
end
|
7
8
|
end
|
8
9
|
|
9
10
|
private
|
10
11
|
|
11
12
|
def valid_format?(value)
|
12
|
-
value =~ /\A([a-zA-Z"-]+\s+){1,4}[a-zA-Z"-]*\z/i
|
13
|
+
value =~ /\A([a-zA-Z'"-]+\s+){1,4}[a-zA-Z'"-]*\z/i
|
13
14
|
end
|
14
15
|
|
15
16
|
def valid_length?(value)
|
@@ -2,14 +2,19 @@ class PasswordValidator < ActiveModel::EachValidator
|
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
4
|
unless valid?(value.to_s, options)
|
5
|
-
record.errors[attribute] <<
|
5
|
+
record.errors[attribute] <<
|
6
|
+
(options[:message] || I18n.t('active_validation.errors.messages.password'))
|
6
7
|
end
|
7
8
|
end
|
8
9
|
|
9
10
|
private
|
10
11
|
|
11
12
|
def valid_format?(value, options)
|
12
|
-
value =~
|
13
|
+
value =~ if options[:strict]
|
14
|
+
/^(?=^.{1,255}$)((?=.*[A-Za-z0-9])(?=.*[A-Z])(?=.*[a-z]))^.*$/
|
15
|
+
else
|
16
|
+
/^[A-Za-z0-9!@#$%^&*_-]{1,255}$/
|
17
|
+
end
|
13
18
|
end
|
14
19
|
|
15
20
|
def valid_length?(value)
|
@@ -2,14 +2,15 @@ class PhoneValidator < ActiveModel::EachValidator
|
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
4
|
unless valid?(value.to_s)
|
5
|
-
record.errors[attribute] <<
|
5
|
+
record.errors[attribute] <<
|
6
|
+
(options[:message] || I18n.t('active_validation.errors.messages.phone'))
|
6
7
|
end
|
7
8
|
end
|
8
9
|
|
9
10
|
private
|
10
11
|
|
11
12
|
def valid_format?(value)
|
12
|
-
value =~
|
13
|
+
value =~ %r{^[0-9+\(\)#\.\s\/ext-]+$}
|
13
14
|
end
|
14
15
|
|
15
16
|
def valid_length?(value)
|
@@ -2,18 +2,19 @@ class SedolValidator < ActiveModel::EachValidator
|
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
4
|
unless valid?(value.to_s)
|
5
|
-
record.errors[attribute] <<
|
5
|
+
record.errors[attribute] <<
|
6
|
+
(options[:message] || I18n.t('active_validation.errors.messages.sedol'))
|
6
7
|
end
|
7
8
|
end
|
8
9
|
|
9
10
|
private
|
10
11
|
|
11
12
|
def valid_checksum?(value)
|
12
|
-
digits = value.chars.map { |
|
13
|
+
digits = value.chars.map { |dgt| dgt =~ /[A-Z]/ ? (dgt.ord - 55) : dgt.to_i }
|
13
14
|
weights = [1, 3, 1, 7, 3, 9, 1]
|
14
15
|
|
15
16
|
total = 0
|
16
|
-
digits.each_with_index { |
|
17
|
+
digits.each_with_index { |dgt, idx| total += (weights[idx] * dgt) }
|
17
18
|
|
18
19
|
(10 - total % 10) % 10
|
19
20
|
end
|
@@ -2,7 +2,8 @@ class SlugValidator < ActiveModel::EachValidator
|
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
4
|
unless valid?(value.to_s)
|
5
|
-
record.errors[attribute] <<
|
5
|
+
record.errors[attribute] <<
|
6
|
+
(options[:message] || I18n.t('active_validation.errors.messages.slug'))
|
6
7
|
end
|
7
8
|
end
|
8
9
|
|
@@ -2,7 +2,8 @@ class SsnValidator < ActiveModel::EachValidator
|
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
4
|
unless valid?(value.to_s)
|
5
|
-
record.errors[attribute] <<
|
5
|
+
record.errors[attribute] <<
|
6
|
+
(options[:message] || I18n.t('active_validation.errors.messages.ssn'))
|
6
7
|
end
|
7
8
|
end
|
8
9
|
|
@@ -2,7 +2,8 @@ class TrackingNumberValidator < ActiveModel::EachValidator
|
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
4
|
unless valid?(value.to_s, options)
|
5
|
-
record.errors[attribute] <<
|
5
|
+
record.errors[attribute] <<
|
6
|
+
(options[:message] || I18n.t('active_validation.errors.messages.tracking_number'))
|
6
7
|
end
|
7
8
|
end
|
8
9
|
|
@@ -23,10 +24,10 @@ class TrackingNumberValidator < ActiveModel::EachValidator
|
|
23
24
|
usps20: /^([0-9]{2,2})([0-9]{9,9})([0-9]{8,8})([0-9])$/,
|
24
25
|
usps91: /^(?:420\d{5})?(9[1-5](?:[0-9]{19}|[0-9]{23}))([0-9])$/
|
25
26
|
}
|
26
|
-
}
|
27
|
+
}.freeze
|
27
28
|
|
28
29
|
# DHL
|
29
|
-
DEFAULT_CARRIERS_AND_SERVICES
|
30
|
+
DEFAULT_CARRIERS_AND_SERVICES[:dhl].each do |service, pattern|
|
30
31
|
define_method("valid_dhl_#{service}_checksum?") do |value|
|
31
32
|
formula = value.scan(pattern).flatten.compact
|
32
33
|
return(false) if formula.empty?
|
@@ -40,53 +41,55 @@ class TrackingNumberValidator < ActiveModel::EachValidator
|
|
40
41
|
def valid_fedex_express_checksum?(value)
|
41
42
|
return(false) unless value.size == 12
|
42
43
|
|
43
|
-
pattern = DEFAULT_CARRIERS_AND_SERVICES
|
44
|
+
pattern = DEFAULT_CARRIERS_AND_SERVICES[:fedex][:express]
|
44
45
|
formula = value.scan(pattern).flatten.compact
|
45
46
|
return(false) if formula.empty?
|
46
47
|
sequence, check_digit = formula
|
47
48
|
|
48
49
|
total = 0
|
49
|
-
sequence.chars.zip([3, 1, 7, 3, 1, 7, 3, 1, 7, 3, 1]).each do |
|
50
|
-
total += (
|
50
|
+
sequence.chars.zip([3, 1, 7, 3, 1, 7, 3, 1, 7, 3, 1]).each do |chr, chrx|
|
51
|
+
total += (chr.to_i * chrx)
|
51
52
|
end
|
52
53
|
|
53
54
|
(total % 11 % 10) == check_digit.to_i
|
54
55
|
end
|
55
56
|
|
56
|
-
DEFAULT_CARRIERS_AND_SERVICES
|
57
|
-
|
58
|
-
|
57
|
+
DEFAULT_CARRIERS_AND_SERVICES[:fedex]
|
58
|
+
.select { |key, _| [:ground, :ground18, :ground96].include?(key) }
|
59
|
+
.each_with_index do |(srv, pat), idx|
|
60
|
+
define_method("valid_fedex_#{srv}_checksum?") do |val|
|
61
|
+
return(false) unless val.size == [15, 18, 22].at(idx)
|
59
62
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
+
formula = val.scan(pat).flatten.compact
|
64
|
+
return(false) if formula.empty?
|
65
|
+
sequence, check_digit = formula
|
63
66
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
67
|
+
total = 0
|
68
|
+
sequence.chars.reverse.each_with_index do |chr, idxx|
|
69
|
+
result = chr.to_i
|
70
|
+
result *= 3 if idxx.even?
|
71
|
+
total += result
|
72
|
+
end
|
70
73
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
+
check = total % 10
|
75
|
+
check = (10 - check) unless check.zero?
|
76
|
+
check == check_digit.to_i
|
77
|
+
end
|
74
78
|
end
|
75
|
-
end
|
76
79
|
|
77
80
|
def valid_fedex_smart_post_checksum?(value)
|
78
81
|
value = "92#{value}" unless value =~ /^92/
|
79
82
|
return(false) unless value.size == 22
|
80
83
|
|
81
|
-
pattern = DEFAULT_CARRIERS_AND_SERVICES
|
84
|
+
pattern = DEFAULT_CARRIERS_AND_SERVICES[:fedex][:smart_post]
|
82
85
|
formula = value.scan(pattern).flatten.compact
|
83
86
|
return(false) if formula.empty?
|
84
87
|
sequence, check_digit = formula
|
85
88
|
|
86
89
|
total = 0
|
87
|
-
sequence.chars.reverse.each_with_index do |character,
|
90
|
+
sequence.chars.reverse.each_with_index do |character, idx|
|
88
91
|
result = character.to_i
|
89
|
-
result *= 3 if
|
92
|
+
result *= 3 if idx.even?
|
90
93
|
total += result
|
91
94
|
end
|
92
95
|
|
@@ -96,34 +99,36 @@ class TrackingNumberValidator < ActiveModel::EachValidator
|
|
96
99
|
end
|
97
100
|
|
98
101
|
# Ontrac & UPS
|
99
|
-
DEFAULT_CARRIERS_AND_SERVICES
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
102
|
+
DEFAULT_CARRIERS_AND_SERVICES
|
103
|
+
.select { |key, _| [:ontrac, :ups].include?(key) }
|
104
|
+
.each_with_index do |(cars, sers), idx|
|
105
|
+
sers.each do |ser, pat|
|
106
|
+
define_method("valid_#{cars}_#{ser}_checksum?") do |value|
|
107
|
+
return(false) unless value.size == [15, 18].at(idx)
|
108
|
+
|
109
|
+
formula = value.scan(pat).flatten.compact
|
110
|
+
return(false) if formula.empty?
|
111
|
+
sequence, check_digit = formula
|
112
|
+
|
113
|
+
total = 0
|
114
|
+
sequence.chars.each_with_index do |chr, idxx|
|
115
|
+
result = chr[/[0-9]/] ? chr.to_i : ((chr[0].ord - 3) % 10)
|
116
|
+
result *= 2 if idxx.odd?
|
117
|
+
total += result
|
118
|
+
end
|
119
|
+
|
120
|
+
check = total % 10
|
121
|
+
check = 10 - check unless check.zero?
|
122
|
+
check == check_digit.to_i
|
113
123
|
end
|
114
|
-
|
115
|
-
check = total % 10
|
116
|
-
check = 10 - check unless check.zero?
|
117
|
-
check == check_digit.to_i
|
118
124
|
end
|
119
125
|
end
|
120
|
-
end
|
121
126
|
|
122
127
|
# USPS
|
123
128
|
def valid_usps_usps13_checksum?(value)
|
124
129
|
return(false) unless value.size == 13
|
125
130
|
|
126
|
-
pattern = DEFAULT_CARRIERS_AND_SERVICES
|
131
|
+
pattern = DEFAULT_CARRIERS_AND_SERVICES[:usps][:usps13]
|
127
132
|
sequence = value.scan(pattern).flatten.compact
|
128
133
|
return(false) if sequence.empty?
|
129
134
|
|
@@ -131,17 +136,17 @@ class TrackingNumberValidator < ActiveModel::EachValidator
|
|
131
136
|
check_digit = characters.pop.to_i
|
132
137
|
|
133
138
|
total = 0
|
134
|
-
characters.zip([8, 6, 4, 2, 3, 5, 9, 7]).each do |
|
135
|
-
total += (
|
139
|
+
characters.zip([8, 6, 4, 2, 3, 5, 9, 7]).each do |par|
|
140
|
+
total += (par[0].to_i * par[1].to_i)
|
136
141
|
end
|
137
142
|
|
138
143
|
remainder = total % 11
|
139
144
|
check = case remainder
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
+
when 1 then 0
|
146
|
+
when 0 then 5
|
147
|
+
else
|
148
|
+
11 - remainder
|
149
|
+
end
|
145
150
|
|
146
151
|
check == check_digit
|
147
152
|
end
|
@@ -149,7 +154,7 @@ class TrackingNumberValidator < ActiveModel::EachValidator
|
|
149
154
|
def valid_usps_usps20_checksum?(value)
|
150
155
|
return(false) unless value.size == 20
|
151
156
|
|
152
|
-
pattern = DEFAULT_CARRIERS_AND_SERVICES
|
157
|
+
pattern = DEFAULT_CARRIERS_AND_SERVICES[:usps][:usps20]
|
153
158
|
sequence = value.scan(pattern).flatten.compact
|
154
159
|
return(false) if sequence.empty?
|
155
160
|
|
@@ -157,9 +162,9 @@ class TrackingNumberValidator < ActiveModel::EachValidator
|
|
157
162
|
check_digit = sequence.last.to_i
|
158
163
|
|
159
164
|
total = 0
|
160
|
-
characters.reverse.each_with_index do |
|
161
|
-
result =
|
162
|
-
result *= 3 if
|
165
|
+
characters.reverse.each_with_index do |chr, idx|
|
166
|
+
result = chr.to_i
|
167
|
+
result *= 3 if idx.even?
|
163
168
|
total += result
|
164
169
|
end
|
165
170
|
|
@@ -172,7 +177,7 @@ class TrackingNumberValidator < ActiveModel::EachValidator
|
|
172
177
|
value = "91#{value}" unless value =~ /^(420\d{5})?9[1-5]/
|
173
178
|
return(false) unless value.size == 22
|
174
179
|
|
175
|
-
pattern = DEFAULT_CARRIERS_AND_SERVICES
|
180
|
+
pattern = DEFAULT_CARRIERS_AND_SERVICES[:usps][:usps91]
|
176
181
|
sequence = value.scan(pattern).flatten.compact
|
177
182
|
return(false) if sequence.empty?
|
178
183
|
|
@@ -180,9 +185,9 @@ class TrackingNumberValidator < ActiveModel::EachValidator
|
|
180
185
|
check_digit = sequence.last.to_i
|
181
186
|
|
182
187
|
total = 0
|
183
|
-
characters.reverse.each_with_index do |
|
184
|
-
result =
|
185
|
-
result *= 3 if
|
188
|
+
characters.reverse.each_with_index do |chr, idx|
|
189
|
+
result = chr.to_i
|
190
|
+
result *= 3 if idx.even?
|
186
191
|
total += result
|
187
192
|
end
|
188
193
|
|
@@ -193,28 +198,28 @@ class TrackingNumberValidator < ActiveModel::EachValidator
|
|
193
198
|
|
194
199
|
# Base
|
195
200
|
def valid_checksum?(value, options)
|
196
|
-
carrier = options
|
197
|
-
service = options
|
201
|
+
carrier = options[:carrier]
|
202
|
+
service = options[:service]
|
198
203
|
result = false
|
199
204
|
|
200
205
|
if carrier.nil? && service.nil?
|
201
|
-
DEFAULT_CARRIERS_AND_SERVICES.each do |
|
202
|
-
|
203
|
-
result = send("valid_#{
|
206
|
+
DEFAULT_CARRIERS_AND_SERVICES.each do |car, ser|
|
207
|
+
ser.each_key do |car_ser|
|
208
|
+
result = send("valid_#{car}_#{car_ser}_checksum?", value)
|
204
209
|
break if result
|
205
210
|
end
|
206
211
|
break if result
|
207
212
|
end
|
208
213
|
elsif service.nil?
|
209
|
-
DEFAULT_CARRIERS_AND_SERVICES
|
210
|
-
result = send("valid_#{carrier}_#{
|
214
|
+
DEFAULT_CARRIERS_AND_SERVICES[carrier].each_key do |car_ser|
|
215
|
+
result = send("valid_#{carrier}_#{car_ser}_checksum?", value)
|
211
216
|
break if result
|
212
217
|
end
|
213
218
|
else
|
214
219
|
result = send("valid_#{carrier}_#{service}_checksum?", value)
|
215
220
|
end
|
216
221
|
|
217
|
-
|
222
|
+
result
|
218
223
|
end
|
219
224
|
|
220
225
|
def valid_length?(value)
|