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