tracking_number 1.0.3 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -3
- data/README.md +4 -3
- data/lib/tracking_number.rb +3 -62
- data/lib/tracking_number/base.rb +17 -5
- data/lib/tracking_number/checksum_validations.rb +65 -0
- data/lib/tracking_number/info.rb +8 -0
- data/lib/tracking_number/loader.rb +73 -0
- data/lib/tracking_number/version.rb +1 -1
- data/test/tracking_number_meta_test.rb +39 -40
- data/test/tracking_number_test.rb +15 -0
- metadata +9 -4
- data/lib/checksum_validations.rb +0 -63
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c982bd19b169cb2d7c3451f310d0408185e3ca3da9056dfd7f08f6d70194d9f1
|
4
|
+
data.tar.gz: ead95abd691ee8572fd295b3e8aed206b44cbb791437c8d40c90702c1e8cd5e7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '086856f2923929118bd32f6e6ccd9725c0099c9d274273a9ac5ff072fb2f561460cd940d6b95506ca3ea2685b998310cba8534ef3404732353bdb8a2452094e4'
|
7
|
+
data.tar.gz: 2280018d8645ce2181819c7cc35a53e8ea857ef7e785a335ed03c6bac6b813e47f6bcb5ac6831e251e77b7f17ffc5451680fea15d69cbaec84bb753dacef3f1e
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -9,6 +9,10 @@ It detects tracking numbers from UPS, FedEx, DHL, USPS, OnTrac, Amazon Logistics
|
|
9
9
|
|
10
10
|
This gem does not do tracking. That is left up to you.
|
11
11
|
|
12
|
+
#### New in 1.0
|
13
|
+
|
14
|
+
Starting with the 1.0 release the specifications for detecting tracking numbers have been moved into a separate repository ([tracking_number_data](http://github.com/jkeen/tracking_number_data)) that this gem relies on. I did this so a) we can have a single place to document all tracking number types and it can be more of a crowdsourced effort, and b) so clients can be written in other languages easier.
|
15
|
+
|
12
16
|
## Usage
|
13
17
|
|
14
18
|
#### Checking an individual tracking number
|
@@ -119,9 +123,6 @@ class Shipment < ActiveRecord::Base
|
|
119
123
|
end
|
120
124
|
```
|
121
125
|
|
122
|
-
## Where the data comes from
|
123
|
-
Starting with the 1.0 release of this gem the data for tracking numbers has been extracted into a separate repository ([tracking_number_data](http://github.com/jkeen/tracking_number_data)) so non-ruby clients can benefit from the detection/documentation that used to be contained deep in the code of this gem. If you want to write a client in some other language, that's the stuff you want.
|
124
|
-
|
125
126
|
## Contributing to tracking_number
|
126
127
|
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
127
128
|
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
data/lib/tracking_number.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# Identify if tracking numbers are valid, and which service they belong to
|
2
2
|
|
3
3
|
require 'json'
|
4
|
+
require 'tracking_number/checksum_validations'
|
5
|
+
require 'tracking_number/loader'
|
4
6
|
require 'tracking_number/base'
|
5
7
|
require 'tracking_number/info'
|
6
8
|
require 'tracking_number/unknown'
|
7
|
-
require 'checksum_validations'
|
8
9
|
require 'active_support/core_ext/string'
|
9
10
|
require 'active_support/core_ext/hash'
|
10
11
|
|
@@ -12,67 +13,7 @@ if defined?(ActiveModel::EachValidator)
|
|
12
13
|
require 'tracking_number/active_model_validator'
|
13
14
|
end
|
14
15
|
|
15
|
-
|
16
|
-
return tracking[:test_numbers] && tracking[:test_numbers][:valid]
|
17
|
-
end
|
18
|
-
|
19
|
-
def test_numbers_return_required_groups?(tracking, regex)
|
20
|
-
test_number = tracking[:test_numbers][:valid][0]
|
21
|
-
matches = test_number.match(regex)
|
22
|
-
|
23
|
-
return matches["SerialNumber"]
|
24
|
-
end
|
25
|
-
|
26
|
-
def read_courier_info(file)
|
27
|
-
return JSON.parse(File.read(file)).deep_symbolize_keys!
|
28
|
-
end
|
29
|
-
|
30
|
-
def create_class(klass, courier_info, tracking_info)
|
31
|
-
klass = Class.new(TrackingNumber::Base)
|
32
|
-
klass.const_set("COURIER_CODE", courier_info[:courier_code])
|
33
|
-
info = courier_info.dup
|
34
|
-
info.delete(:tracking_numbers)
|
35
|
-
klass.const_set("COURIER_INFO", info)
|
36
|
-
|
37
|
-
pattern = tracking_info[:regex]
|
38
|
-
pattern = tracking_info[:regex].join if tracking_info[:regex].is_a?(Array)
|
39
|
-
|
40
|
-
verify_pattern = "^#{pattern}$"
|
41
|
-
search_pattern = "\\b#{pattern}\\b"
|
42
|
-
|
43
|
-
klass.const_set("SEARCH_PATTERN", Regexp.new(search_pattern))
|
44
|
-
klass.const_set("VERIFY_PATTERN", Regexp.new(verify_pattern))
|
45
|
-
|
46
|
-
klass.const_set("VALIDATION", tracking_info[:validation])
|
47
|
-
klass.const_set("ADDITIONAL", tracking_info[:additional])
|
48
|
-
|
49
|
-
return klass
|
50
|
-
end
|
51
|
-
|
52
|
-
def register_class(klass, tracking_name)
|
53
|
-
klass_name = tracking_name.gsub(/[^0-9A-Za-z]/, '')
|
54
|
-
return TrackingNumber.const_set(klass_name, klass)
|
55
|
-
end
|
56
|
-
|
57
|
-
tracking_number_types = []
|
58
|
-
|
59
|
-
Dir.glob(File.join(File.dirname(__FILE__), "data/couriers/*.json")).each do |file|
|
60
|
-
courier_info = read_courier_info(file)
|
61
|
-
|
62
|
-
courier_info[:tracking_numbers].each do |tracking_info|
|
63
|
-
tracking_name = tracking_info[:name]
|
64
|
-
klass = create_class(klass, courier_info, tracking_info)
|
65
|
-
|
66
|
-
# Do some basic checks on the data file
|
67
|
-
throw 'missing test numbers' unless has_test_numbers?(tracking_info)
|
68
|
-
throw 'missing regex match groups' unless test_numbers_return_required_groups?(tracking_info, Regexp.new(klass::VERIFY_PATTERN))
|
69
|
-
|
70
|
-
const = register_class(klass, tracking_name)
|
71
|
-
tracking_number_types.push(const)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
TrackingNumber.const_set("TYPES", tracking_number_types)
|
16
|
+
TrackingNumber::Loader.load_tracking_number_data
|
76
17
|
|
77
18
|
module TrackingNumber
|
78
19
|
def self.search(body)
|
data/lib/tracking_number/base.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'checksum_validations'
|
2
|
-
|
3
1
|
module TrackingNumber
|
4
2
|
class Base
|
5
3
|
attr_accessor :tracking_number
|
@@ -95,7 +93,7 @@ module TrackingNumber
|
|
95
93
|
name = checksum_info[:name]
|
96
94
|
method_name = "validates_#{name}?"
|
97
95
|
|
98
|
-
ChecksumValidations.send(method_name, serial_number, check_digit, checksum_info)
|
96
|
+
TrackingNumber::ChecksumValidations.send(method_name, serial_number, check_digit, checksum_info)
|
99
97
|
end
|
100
98
|
|
101
99
|
def to_s
|
@@ -113,8 +111,7 @@ module TrackingNumber
|
|
113
111
|
:service_description => service_description,
|
114
112
|
:destination_zip => destination_zip,
|
115
113
|
:shipper_id => shipper_id,
|
116
|
-
:package_type => package_type
|
117
|
-
:package_description => package_description
|
114
|
+
:package_type => package_type
|
118
115
|
})
|
119
116
|
end
|
120
117
|
|
@@ -172,6 +169,21 @@ module TrackingNumber
|
|
172
169
|
match_group("ShipperId")
|
173
170
|
end
|
174
171
|
|
172
|
+
def tracking_url
|
173
|
+
url = nil
|
174
|
+
if matching_additional["Courier"]
|
175
|
+
url = matching_additional["Courier"][:tracking_url]
|
176
|
+
else
|
177
|
+
if self.class.const_defined?(:TRACKING_URL)
|
178
|
+
url = self.class.const_get(:TRACKING_URL)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
if url
|
183
|
+
url.sub('%s', self.tracking_number)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
175
187
|
def matching_additional
|
176
188
|
additional = self.class.const_get(:ADDITIONAL) || []
|
177
189
|
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module TrackingNumber
|
2
|
+
module ChecksumValidations
|
3
|
+
class << self
|
4
|
+
def validates_s10?(sequence, check_digit, extras = {})
|
5
|
+
weighting = [8,6,4,2,3,5,9,7]
|
6
|
+
|
7
|
+
total = 0
|
8
|
+
sequence.chars.to_a.zip(weighting).each do |(a,b)|
|
9
|
+
total += a.to_i * b.to_i
|
10
|
+
end
|
11
|
+
|
12
|
+
remainder = total % 11
|
13
|
+
check = case remainder
|
14
|
+
when 1
|
15
|
+
0
|
16
|
+
when 0
|
17
|
+
5
|
18
|
+
else
|
19
|
+
11 - remainder
|
20
|
+
end
|
21
|
+
|
22
|
+
return check.to_i == check_digit.to_i
|
23
|
+
end
|
24
|
+
|
25
|
+
def validates_sum_product_with_weightings_and_modulo?(sequence, check_digit, extras = {})
|
26
|
+
weighting = extras[:weightings] || []
|
27
|
+
|
28
|
+
total = 0
|
29
|
+
sequence.chars.to_a.zip(weighting).each do |(a,b)|
|
30
|
+
total += a.to_i * b
|
31
|
+
end
|
32
|
+
return (total % extras[:modulo1] % extras[:modulo2]) == check_digit.to_i
|
33
|
+
end
|
34
|
+
|
35
|
+
def validates_mod10?(sequence, check_digit, extras = {})
|
36
|
+
total = 0
|
37
|
+
sequence.chars.each_with_index do |c, i|
|
38
|
+
x = if c[/[0-9]/] # numeric
|
39
|
+
c.to_i
|
40
|
+
else
|
41
|
+
(c[0].ord - 3) % 10
|
42
|
+
end
|
43
|
+
|
44
|
+
if extras[:odds_multiplier] && i.odd?
|
45
|
+
x *= extras[:odds_multiplier].to_i
|
46
|
+
elsif extras[:evens_multiplier] && i.even?
|
47
|
+
x *= extras[:evens_multiplier].to_i
|
48
|
+
end
|
49
|
+
|
50
|
+
total += x
|
51
|
+
end
|
52
|
+
|
53
|
+
check = (total % 10)
|
54
|
+
check = (10 - check) unless (check.zero?)
|
55
|
+
|
56
|
+
return (check.to_i == check_digit.to_i)
|
57
|
+
end
|
58
|
+
|
59
|
+
def validates_mod7?(sequence, check_digit, extras = {})
|
60
|
+
# standard mod 7 check
|
61
|
+
return true if sequence.to_i % 7 == check_digit.to_i
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/tracking_number/info.rb
CHANGED
@@ -0,0 +1,73 @@
|
|
1
|
+
|
2
|
+
module TrackingNumber
|
3
|
+
module Loader
|
4
|
+
class << self
|
5
|
+
def load_tracking_number_data
|
6
|
+
tracking_number_types = []
|
7
|
+
|
8
|
+
Dir.glob(File.join(File.dirname(__FILE__), "../data/couriers/*.json")).each do |file|
|
9
|
+
courier_info = read_courier_info(file)
|
10
|
+
|
11
|
+
courier_info[:tracking_numbers].each do |tracking_info|
|
12
|
+
tracking_name = tracking_info[:name]
|
13
|
+
klass = create_class(klass, courier_info, tracking_info)
|
14
|
+
|
15
|
+
# Do some basic checks on the data file
|
16
|
+
throw 'missing test numbers' unless has_test_numbers?(tracking_info)
|
17
|
+
throw 'missing regex match groups' unless test_numbers_return_required_groups?(tracking_info, Regexp.new(klass::VERIFY_PATTERN))
|
18
|
+
|
19
|
+
const = register_class(klass, tracking_name)
|
20
|
+
tracking_number_types.push(const)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
TrackingNumber.const_set("TYPES", tracking_number_types)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def has_test_numbers?(tracking)
|
30
|
+
return tracking[:test_numbers] && tracking[:test_numbers][:valid]
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_numbers_return_required_groups?(tracking, regex)
|
34
|
+
test_number = tracking[:test_numbers][:valid][0]
|
35
|
+
matches = test_number.match(regex)
|
36
|
+
|
37
|
+
return matches["SerialNumber"]
|
38
|
+
end
|
39
|
+
|
40
|
+
def read_courier_info(file)
|
41
|
+
return JSON.parse(File.read(file)).deep_symbolize_keys!
|
42
|
+
end
|
43
|
+
|
44
|
+
def create_class(klass, courier_info, tracking_info)
|
45
|
+
klass = Class.new(TrackingNumber::Base)
|
46
|
+
klass.const_set("COURIER_CODE", courier_info[:courier_code])
|
47
|
+
info = courier_info.dup
|
48
|
+
info.delete(:tracking_numbers)
|
49
|
+
klass.const_set("COURIER_INFO", info)
|
50
|
+
|
51
|
+
pattern = tracking_info[:regex]
|
52
|
+
pattern = tracking_info[:regex].join if tracking_info[:regex].is_a?(Array)
|
53
|
+
|
54
|
+
verify_pattern = "^#{pattern}$"
|
55
|
+
search_pattern = "\\b#{pattern}\\b"
|
56
|
+
|
57
|
+
klass.const_set("SEARCH_PATTERN", Regexp.new(search_pattern))
|
58
|
+
klass.const_set("VERIFY_PATTERN", Regexp.new(verify_pattern))
|
59
|
+
|
60
|
+
klass.const_set("VALIDATION", tracking_info[:validation])
|
61
|
+
klass.const_set("ADDITIONAL", tracking_info[:additional])
|
62
|
+
klass.const_set("TRACKING_URL", tracking_info[:tracking_url])
|
63
|
+
|
64
|
+
return klass
|
65
|
+
end
|
66
|
+
|
67
|
+
def register_class(klass, tracking_name)
|
68
|
+
klass_name = tracking_name.gsub(/[^0-9A-Za-z]/, '')
|
69
|
+
return TrackingNumber.const_set(klass_name, klass)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -21,13 +21,6 @@ class TrackingNumberMetaTest < Minitest::Test
|
|
21
21
|
|
22
22
|
describe "[#{tracking_info[:name]}]" do
|
23
23
|
tracking_info[:test_numbers][:valid].each do |valid_number|
|
24
|
-
|
25
|
-
should "validate #{valid_number} with #{klass_name}" do
|
26
|
-
t = klass.new(valid_number)
|
27
|
-
assert_equal courier_code, t.carrier
|
28
|
-
assert t.valid?, "should be valid"
|
29
|
-
end
|
30
|
-
|
31
24
|
should "detect #{valid_number} as #{klass_name}" do
|
32
25
|
#TODO fix this multiple matching thing
|
33
26
|
matches = TrackingNumber.search(valid_number)
|
@@ -45,47 +38,53 @@ class TrackingNumberMetaTest < Minitest::Test
|
|
45
38
|
should_detect_number_variants(valid_number, "TrackingNumber::#{klass_name}".constantize)
|
46
39
|
end
|
47
40
|
|
48
|
-
|
49
|
-
|
50
|
-
assert_equal courier_info[:courier_code].to_sym, t.courier_code
|
51
|
-
assert_equal courier_info[:courier_code].to_sym, t.courier_code
|
52
|
-
end
|
41
|
+
context "number test" do
|
42
|
+
tracking_number = klass.new(valid_number)
|
53
43
|
|
54
|
-
|
55
|
-
|
44
|
+
should "validate #{valid_number} with #{klass_name}" do
|
45
|
+
assert_equal courier_code, tracking_number.carrier
|
46
|
+
assert tracking_number.valid?, "should be valid"
|
47
|
+
end
|
56
48
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
assert_equal
|
49
|
+
should "return correct courier code on #{valid_number} when calling #courier_code" do
|
50
|
+
tracking_number = klass.new(valid_number)
|
51
|
+
assert_equal courier_info[:courier_code].to_sym, tracking_number.courier_code
|
52
|
+
assert_equal courier_info[:courier_code].to_sym,tracking_number.courier_code
|
61
53
|
end
|
62
|
-
end
|
63
54
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
55
|
+
should "return correct courier name on #{valid_number} when calling #courier_name" do
|
56
|
+
if (tracking_number.matching_additional["Courier"])
|
57
|
+
assert_equal tracking_number.matching_additional["Courier"][:courier], tracking_number.courier_name
|
58
|
+
else
|
59
|
+
assert_equal courier_name, tracking_number.courier_name
|
60
|
+
end
|
61
|
+
end
|
69
62
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
63
|
+
should "not throw an error when calling #service_type on #{valid_number}" do
|
64
|
+
service_type = tracking_number.service_type
|
65
|
+
assert service_type.is_a?(String) || service_type.nil?
|
66
|
+
end
|
74
67
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
end
|
68
|
+
should "not throw an error when calling #destination on #{valid_number}" do
|
69
|
+
assert tracking_number.destination_zip.is_a?(String) || tracking_number.destination_zip.nil?
|
70
|
+
end
|
79
71
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
72
|
+
should "not throw an error when calling #shipper on #{valid_number}" do
|
73
|
+
t = klass.new(valid_number)
|
74
|
+
assert tracking_number.shipper_id.is_a?(String) || tracking_number.shipper_id.nil?
|
75
|
+
end
|
76
|
+
|
77
|
+
should "not throw an error when calling #package_type on #{valid_number}" do
|
78
|
+
t = klass.new(valid_number)
|
79
|
+
assert tracking_number.package_type.is_a?(String) || tracking_number.package_type.nil?
|
80
|
+
end
|
81
|
+
|
82
|
+
should "not throw an error when calling #decode on #{valid_number}" do
|
83
|
+
t = klass.new(valid_number)
|
84
|
+
decode = tracking_number.decode
|
85
|
+
assert decode.is_a?(Hash)
|
86
|
+
end
|
84
87
|
|
85
|
-
should "not throw an error when calling #decode on #{valid_number}" do
|
86
|
-
t = klass.new(valid_number)
|
87
|
-
decode = t.decode
|
88
|
-
assert decode.is_a?(Hash)
|
89
88
|
end
|
90
89
|
end
|
91
90
|
|
@@ -64,6 +64,11 @@ class TrackingNumberTest < Minitest::Test
|
|
64
64
|
should "report correct no package info" do
|
65
65
|
assert_nil tracking_number.package_type
|
66
66
|
end
|
67
|
+
|
68
|
+
should "have valid tracking url" do
|
69
|
+
assert tracking_number.tracking_url, "Tracking url should not be blank"
|
70
|
+
assert tracking_number.tracking_url.include?(tracking_number.tracking_number), "Should include tracking number in the url"
|
71
|
+
end
|
67
72
|
end
|
68
73
|
|
69
74
|
context "tracking number additional data for s10" do
|
@@ -112,6 +117,11 @@ class TrackingNumberTest < Minitest::Test
|
|
112
117
|
should "report correct no package info" do
|
113
118
|
assert_nil tracking_number.package_type
|
114
119
|
end
|
120
|
+
|
121
|
+
should "have valid tracking url" do
|
122
|
+
assert tracking_number.tracking_url, "Tracking url should not be blank"
|
123
|
+
assert tracking_number.tracking_url.include?(tracking_number.tracking_number), "Should include tracking number in the url"
|
124
|
+
end
|
115
125
|
end
|
116
126
|
|
117
127
|
context "tracking number additional data for USPS 34v2" do
|
@@ -136,5 +146,10 @@ class TrackingNumberTest < Minitest::Test
|
|
136
146
|
should "report correct no package info" do
|
137
147
|
assert_nil tracking_number.package_type
|
138
148
|
end
|
149
|
+
|
150
|
+
should "have valid tracking url" do
|
151
|
+
assert tracking_number.tracking_url, "Tracking url should not be blank"
|
152
|
+
assert tracking_number.tracking_url.include?(tracking_number.tracking_number), "Should include tracking number in the url"
|
153
|
+
end
|
139
154
|
end
|
140
155
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tracking_number
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeff Keen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-09-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -139,7 +139,6 @@ files:
|
|
139
139
|
- LICENSE.txt
|
140
140
|
- README.md
|
141
141
|
- Rakefile
|
142
|
-
- lib/checksum_validations.rb
|
143
142
|
- lib/data/couriers/amazon.json
|
144
143
|
- lib/data/couriers/dhl.json
|
145
144
|
- lib/data/couriers/fedex.json
|
@@ -150,7 +149,9 @@ files:
|
|
150
149
|
- lib/tracking_number.rb
|
151
150
|
- lib/tracking_number/active_model_validator.rb
|
152
151
|
- lib/tracking_number/base.rb
|
152
|
+
- lib/tracking_number/checksum_validations.rb
|
153
153
|
- lib/tracking_number/info.rb
|
154
|
+
- lib/tracking_number/loader.rb
|
154
155
|
- lib/tracking_number/unknown.rb
|
155
156
|
- lib/tracking_number/version.rb
|
156
157
|
- test/active_model_validator_test.rb
|
@@ -182,4 +183,8 @@ rubygems_version: 2.7.4
|
|
182
183
|
signing_key:
|
183
184
|
specification_version: 4
|
184
185
|
summary: Identifies valid tracking numbers
|
185
|
-
test_files:
|
186
|
+
test_files:
|
187
|
+
- test/active_model_validator_test.rb
|
188
|
+
- test/test_helper.rb
|
189
|
+
- test/tracking_number_meta_test.rb
|
190
|
+
- test/tracking_number_test.rb
|
data/lib/checksum_validations.rb
DELETED
@@ -1,63 +0,0 @@
|
|
1
|
-
module ChecksumValidations
|
2
|
-
class << self
|
3
|
-
def validates_s10?(sequence, check_digit, extras = {})
|
4
|
-
weighting = [8,6,4,2,3,5,9,7]
|
5
|
-
|
6
|
-
total = 0
|
7
|
-
sequence.chars.to_a.zip(weighting).each do |(a,b)|
|
8
|
-
total += a.to_i * b.to_i
|
9
|
-
end
|
10
|
-
|
11
|
-
remainder = total % 11
|
12
|
-
check = case remainder
|
13
|
-
when 1
|
14
|
-
0
|
15
|
-
when 0
|
16
|
-
5
|
17
|
-
else
|
18
|
-
11 - remainder
|
19
|
-
end
|
20
|
-
|
21
|
-
return check.to_i == check_digit.to_i
|
22
|
-
end
|
23
|
-
|
24
|
-
def validates_sum_product_with_weightings_and_modulo?(sequence, check_digit, extras = {})
|
25
|
-
weighting = extras[:weightings] || []
|
26
|
-
|
27
|
-
total = 0
|
28
|
-
sequence.chars.to_a.zip(weighting).each do |(a,b)|
|
29
|
-
total += a.to_i * b
|
30
|
-
end
|
31
|
-
return (total % extras[:modulo1] % extras[:modulo2]) == check_digit.to_i
|
32
|
-
end
|
33
|
-
|
34
|
-
def validates_mod10?(sequence, check_digit, extras = {})
|
35
|
-
total = 0
|
36
|
-
sequence.chars.each_with_index do |c, i|
|
37
|
-
x = if c[/[0-9]/] # numeric
|
38
|
-
c.to_i
|
39
|
-
else
|
40
|
-
(c[0].ord - 3) % 10
|
41
|
-
end
|
42
|
-
|
43
|
-
if extras[:odds_multiplier] && i.odd?
|
44
|
-
x *= extras[:odds_multiplier].to_i
|
45
|
-
elsif extras[:evens_multiplier] && i.even?
|
46
|
-
x *= extras[:evens_multiplier].to_i
|
47
|
-
end
|
48
|
-
|
49
|
-
total += x
|
50
|
-
end
|
51
|
-
|
52
|
-
check = (total % 10)
|
53
|
-
check = (10 - check) unless (check.zero?)
|
54
|
-
|
55
|
-
return (check.to_i == check_digit.to_i)
|
56
|
-
end
|
57
|
-
|
58
|
-
def validates_mod7?(sequence, check_digit, extras = {})
|
59
|
-
# standard mod 7 check
|
60
|
-
return true if sequence.to_i % 7 == check_digit.to_i
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|