lib/tracking_number/usps.rb in tracking_number-0.5.0 vs lib/tracking_number/usps.rb in tracking_number-0.6.0
- old
+ new
@@ -2,58 +2,58 @@
class USPS < Base
def carrier
:usps
end
end
-
+
class USPS91 < USPS
SEARCH_PATTERN = [/(\b9\s*[14]\s*(([0-9]\s*){20,20}\b))/, /(\b([0-9]\s*){20,20}\b)/]
VERIFY_PATTERN = /^(9[14][0-9]{19,19})([0-9])$/
-
+
# Sometimes these numbers will appear without the leading 91 or 94, though, so we need to account for that case
-
- def decode
+
+ def decode
# Application ID: 91 or 94
# Service Code: 2 Digits
# Mailer Id: 8 Digits
# Package Id: 9 Digits
# Checksum: 1 Digit
{:application_id => self.tracking_number.to_s.slice(0...2),
- :service_code => self.tracking_number.to_s.slice(2...4),
+ :service_code => self.tracking_number.to_s.slice(2...4),
:mailer_id => self.tracking_number.to_s.slice(4...12),
:package_identifier => self.tracking_number.to_s.slice(12...21),
:check_digit => self.tracking_number.slice(21...22)
}
end
-
+
def matches
if self.tracking_number =~ /^9[14]/
self.tracking_number.scan(VERIFY_PATTERN).flatten
else
"91#{self.tracking_number}".scan(VERIFY_PATTERN).flatten
end
end
-
+
def valid_checksum?
- if self.tracking_number =~ /^9[14]/
- return true if weighted_usps_checksum_valid?(tracking_number)
+ if self.tracking_number =~ /^9[14]/
+ return true if weighted_usps_checksum_valid?(tracking_number)
else
if weighted_usps_checksum_valid?("91#{self.tracking_number}")
# set the tracking number to the 91 format if it passes this test
self.tracking_number = "91#{self.tracking_number}"
return true
end
end
end
-
+
private
-
+
def weighted_usps_checksum_valid?(sequence)
chars = sequence.chars.to_a
check_digit = chars.pop
-
+
total = 0
chars.reverse.each_with_index do |c, i|
x = c.to_i
x *= 3 if i.even?
@@ -63,30 +63,30 @@
check = total % 10
check = 10 - check unless (check.zero?)
return true if check == check_digit.to_i
end
end
-
+
class USPS20 < USPS
# http://www.usps.com/cpim/ftp/pubs/pub109.pdf (Publication 109. Extra Services Technical Guide, pg. 19)
# http://www.usps.com/cpim/ftp/pubs/pub91.pdf (Publication 91. Confirmation Services Technical Guide pg. 38)
-
+
SEARCH_PATTERN = /(\b([0-9]\s*){20,20}\b)/
VERIFY_PATTERN = /^([0-9]{2,2})([0-9]{9,9})([0-9]{8,8})([0-9])$/
def matches
self.tracking_number.scan(VERIFY_PATTERN).flatten
end
-
+
def decode
- {:service_code => self.tracking_number.to_s.slice(0...2),
+ {:service_code => self.tracking_number.to_s.slice(0...2),
:mailer_id => self.tracking_number.to_s.slice(2...11),
:package_identifier => self.tracking_number.to_s.slice(11...19),
:check_digit => self.tracking_number.slice(19...20)
}
end
-
+
def service_type
case decode[:service_code]
when "71"
"Certified Mail"
when "73"
@@ -95,15 +95,15 @@
"Registered Mail"
when "81"
"Return Receipt for Merchandise"
end
end
-
+
def valid_checksum?
chars = tracking_number.chars.to_a
check_digit = chars.pop
-
+
total = 0
chars.reverse.each_with_index do |c, i|
x = c.to_i
x *= 3 if i.even?
total += x
@@ -112,38 +112,38 @@
check = total % 10
check = 10 - check unless (check.zero?)
return true if check == check_digit.to_i
end
end
-
+
class USPS13 < USPS
SEARCH_PATTERN = /(\b([A-Z]\s*){2,2}([0-9]\s*){9,9}([A-Z]\s*){2,2}\b)/
VERIFY_PATTERN = /^([A-Z]{2,2})([0-9]{9,9})([A-Z]{2,2})$/
-
+
def matches
self.tracking_number.scan(VERIFY_PATTERN).flatten
end
def valid_checksum?
sequence = tracking_number.scan(/[0-9]+/).flatten.join
chars = sequence.chars.to_a
check_digit = chars.pop.to_i
-
+
sum = 0
chars.zip([8,6,4,2,3,5,9,7]).each do |pair|
sum += (pair[0].to_i * pair[1].to_i)
end
-
+
remainder = sum % 11
check = case remainder
when 1
0
when 0
5
else
11 - remainder
end
-
+
return check == check_digit
end
end
end
\ No newline at end of file