tracking_number 0.8.6 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/VERSION +1 -1
- data/lib/tracking_number.rb +1 -1
- data/lib/tracking_number/fedex.rb +28 -2
- data/lib/tracking_number/usps.rb +14 -12
- data/lib/tracking_number/version.rb +1 -1
- data/test/fedex_tracking_number_test.rb +9 -0
- data/test/usps_tracking_number_test.rb +6 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 36b4c229dbfddaac959991ac1cfb463a551eeb17
|
4
|
+
data.tar.gz: 267399613e49a562ff130331812f667a5f9344ed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b1268047c9ba4b8ad7092a18351a35d04b073cd83f06e9892afb3e21dbbe8b47e74a067f90612750a2b141b49e8a3f4b4ce5a4b136597a85e96e2e4dacd3c25e
|
7
|
+
data.tar.gz: c47873fc7eaf0f37c5a1c4dfb85c7887fbdc40a2b0a6b9c56fee8a402fb35b1fea37f51e7a1a920cf0b55fed284030039e2cd0d63457f00506ad172e51c4fd0c
|
data/Gemfile.lock
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.9.0
|
data/lib/tracking_number.rb
CHANGED
@@ -15,7 +15,7 @@ if defined?(ActiveModel::EachValidator)
|
|
15
15
|
end
|
16
16
|
|
17
17
|
module TrackingNumber
|
18
|
-
TYPES = [UPS, FedExExpress, FedExGround, FedExGround18, FedExGround96, USPS91, USPS20, USPS13, DHL, OnTrac]
|
18
|
+
TYPES = [UPS, FedExExpress, FedExSmartPost, FedExGround, FedExGround18, FedExGround96, USPS91, USPS20, USPS13, DHL, OnTrac]
|
19
19
|
|
20
20
|
def self.search(body)
|
21
21
|
TYPES.collect { |type| type.search(body) }.flatten
|
@@ -24,6 +24,33 @@ module TrackingNumber
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
+
class FedExSmartPost < FedEx
|
28
|
+
SEARCH_PATTERN = /(\b([0-9]\s*){20}\b)/
|
29
|
+
VERIFY_PATTERN = /^([0-9]{5}[0-9]{14})([0-9])$/
|
30
|
+
LENGTH = 20
|
31
|
+
|
32
|
+
def matches
|
33
|
+
self.tracking_number.scan(VERIFY_PATTERN).flatten
|
34
|
+
end
|
35
|
+
|
36
|
+
def valid_checksum?
|
37
|
+
# http://stackoverflow.com/questions/15744704/how-to-calculate-a-fedex-smartpost-tracking-number-check-digit
|
38
|
+
|
39
|
+
sequence = "92#{tracking_number}".chars.to_a.map(&:to_i)
|
40
|
+
check_digit = sequence.pop
|
41
|
+
total = 0
|
42
|
+
|
43
|
+
sequence.reverse.each_with_index do |x, i|
|
44
|
+
x *= 3 if i.even?
|
45
|
+
total += x
|
46
|
+
end
|
47
|
+
check = total % 10
|
48
|
+
check = (10 - check) unless (check.zero?)
|
49
|
+
|
50
|
+
return true if check == check_digit.to_i
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
27
54
|
#TODO Fix these FedEx ground numberss
|
28
55
|
|
29
56
|
class FedExGround96 < FedEx
|
@@ -127,5 +154,4 @@ module TrackingNumber
|
|
127
154
|
return true if check == check_digit.to_i
|
128
155
|
end
|
129
156
|
end
|
130
|
-
|
131
|
-
end
|
157
|
+
end
|
data/lib/tracking_number/usps.rb
CHANGED
@@ -6,28 +6,30 @@ module TrackingNumber
|
|
6
6
|
end
|
7
7
|
|
8
8
|
class USPS91 < USPS
|
9
|
-
SEARCH_PATTERN = [/(\
|
10
|
-
VERIFY_PATTERN = /^(9[
|
9
|
+
SEARCH_PATTERN = [/(\b(?:420\s*\d{5})?9\s*[1-5]\s*(?:(?:[0-9]\s*){20}\b))/, /(\b([0-9]\s*){20}\b)/]
|
10
|
+
VERIFY_PATTERN = /^(?:420\d{5})?(9[1-5][0-9]{19})([0-9])$/
|
11
11
|
|
12
|
-
# Sometimes these numbers will appear without the leading 91 or 94, though, so we need to account for that case
|
12
|
+
# Sometimes these numbers will appear without the leading 91, 93, or 94, though, so we need to account for that case
|
13
13
|
|
14
14
|
def decode
|
15
|
-
# Application ID: 91
|
15
|
+
# Application ID: 91, 93, 94 or 95
|
16
16
|
# Service Code: 2 Digits
|
17
17
|
# Mailer Id: 8 Digits
|
18
18
|
# Package Id: 9 Digits
|
19
19
|
# Checksum: 1 Digit
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
:
|
25
|
-
:
|
21
|
+
base_tracking_number = self.tracking_number.to_s.gsub(/^420\d{5}/, '')
|
22
|
+
|
23
|
+
{:application_id => base_tracking_number.to_s.slice(0...2),
|
24
|
+
:service_code => base_tracking_number.to_s.slice(2...4),
|
25
|
+
:mailer_id => base_tracking_number.to_s.slice(4...12),
|
26
|
+
:package_identifier => base_tracking_number.to_s.slice(12...21),
|
27
|
+
:check_digit => base_tracking_number.slice(21...22)
|
26
28
|
}
|
27
29
|
end
|
28
30
|
|
29
31
|
def matches
|
30
|
-
if self.tracking_number =~ /^9[
|
32
|
+
if self.tracking_number =~ /^(420\d{5})?9[1-5]/
|
31
33
|
self.tracking_number.scan(VERIFY_PATTERN).flatten
|
32
34
|
else
|
33
35
|
"91#{self.tracking_number}".scan(VERIFY_PATTERN).flatten
|
@@ -35,7 +37,7 @@ module TrackingNumber
|
|
35
37
|
end
|
36
38
|
|
37
39
|
def valid_checksum?
|
38
|
-
if self.tracking_number =~ /^9[
|
40
|
+
if self.tracking_number =~ /^(420\d{5})?9[1-5]/
|
39
41
|
return true if weighted_usps_checksum_valid?(tracking_number)
|
40
42
|
else
|
41
43
|
if weighted_usps_checksum_valid?("91#{self.tracking_number}")
|
@@ -49,7 +51,7 @@ module TrackingNumber
|
|
49
51
|
private
|
50
52
|
|
51
53
|
def weighted_usps_checksum_valid?(sequence)
|
52
|
-
chars = sequence.chars.to_a
|
54
|
+
chars = sequence.gsub(/^420\d{5}/, '').chars.to_a
|
53
55
|
check_digit = chars.pop
|
54
56
|
|
55
57
|
total = 0
|
@@ -42,5 +42,14 @@ class FedExTrackingNumberTest < Minitest::Test
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
+
["61299998820821171811"].each do |valid_number|
|
46
|
+
should "return fedex smart post for #{valid_number}" do
|
47
|
+
should_be_valid_number(valid_number, TrackingNumber::FedExSmartPost, :fedex)
|
48
|
+
end
|
49
|
+
|
50
|
+
should "detect #{valid_number} regardless of spacing" do
|
51
|
+
should_detect_number_variants(valid_number, TrackingNumber::FedExSmartPost)
|
52
|
+
end
|
53
|
+
end
|
45
54
|
end
|
46
55
|
end
|
@@ -31,5 +31,11 @@ class USPSTrackingNumberTest < Minitest::Test
|
|
31
31
|
should_detect_number_variants(valid_number, TrackingNumber::USPS13)
|
32
32
|
end
|
33
33
|
end
|
34
|
+
|
35
|
+
["420221539101026837331000039521"].each do |valid_number|
|
36
|
+
should "return usps with valid 30 digit number: #{valid_number}" do
|
37
|
+
should_be_valid_number(valid_number, TrackingNumber::USPS91, :usps)
|
38
|
+
end
|
39
|
+
end
|
34
40
|
end
|
35
41
|
end
|