Class: TrackingNumber::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/tracking_number/base.rb

Direct Known Subclasses

Unknown

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(tracking_number) ⇒ Base

Returns a new instance of Base.



6
7
8
9
# File 'lib/tracking_number/base.rb', line 6

def initialize(tracking_number)
  @original_number = tracking_number
  @tracking_number = tracking_number.strip.gsub(" ", "").upcase
end

Instance Attribute Details

#original_numberObject

Returns the value of attribute original_number.



4
5
6
# File 'lib/tracking_number/base.rb', line 4

def original_number
  @original_number
end

#tracking_numberObject

Returns the value of attribute tracking_number.



3
4
5
# File 'lib/tracking_number/base.rb', line 3

def tracking_number
  @tracking_number
end

Class Method Details

.scan(body) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/tracking_number/base.rb', line 22

def self.scan(body)
  # matches with match groups within the match data
  matches = []

  body.scan(self.const_get(:SEARCH_PATTERN)){
    #get the match data instead, which is needed with these types of regexes
    matches << $~
  }

  if matches
    matches.collect { |m| m[0] }
  else
    []
  end
end

.search(body) ⇒ Object



11
12
13
14
15
16
17
18
19
20
# File 'lib/tracking_number/base.rb', line 11

def self.search(body)
  valids = self.scan(body).uniq.collect { |possible| new(possible) }.select { |t| t.valid? }

  uniques = {}
  valids.each do |t|
    uniques[t.tracking_number] = t unless uniques.has_key?(t.tracking_number)
  end

  uniques.values
end

Instance Method Details

#check_digitObject



55
56
57
# File 'lib/tracking_number/base.rb', line 55

def check_digit
  match_group("CheckDigit")
end

#courier_codeObject Also known as: carrier, carrier_code



118
119
120
# File 'lib/tracking_number/base.rb', line 118

def courier_code
  self.class.const_get(:COURIER_CODE).to_sym
end

#courier_infoObject



136
137
138
139
140
141
142
143
144
# File 'lib/tracking_number/base.rb', line 136

def courier_info
  basics = {:name => courier_name, :code => courier_code}

  if info = matching_additional["Courier"]
    basics.merge!(:name => info[:courier], :url => info[:courier_url], :country => info[:country])
  end

  @courier ||= Info.new(basics)
end

#courier_nameObject Also known as: carrier_name



122
123
124
125
126
127
128
129
130
# File 'lib/tracking_number/base.rb', line 122

def courier_name
  if matching_additional["Courier"]
    matching_additional["Courier"][:courier]
  else
    if self.class.constants.include?(:COURIER_INFO)
      self.class.const_get(:COURIER_INFO)[:name]
    end
  end
end

#decodeObject



59
60
61
62
63
64
65
66
67
# File 'lib/tracking_number/base.rb', line 59

def decode
  decoded = {}
  (self.matches.try(:names) || []).each do |name|
    sym = name.underscore.to_sym
    decoded[sym] = self.matches[name]
  end

  decoded
end

#destination_zipObject



164
165
166
# File 'lib/tracking_number/base.rb', line 164

def destination_zip
  match_group("DestinationZip")
end

#infoObject



107
108
109
110
111
112
113
114
115
116
# File 'lib/tracking_number/base.rb', line 107

def info
  Info.new({
    :courier => courier_info,
    :service_type => service_type,
    :service_description => service_description,
    :destination_zip => destination_zip,
    :shipper_id => shipper_id,
    :package_type => package_type
  })
end

#inspectObject



103
104
105
# File 'lib/tracking_number/base.rb', line 103

def inspect
  "#<%s:%#0x %s>" % [self.class.to_s, self.object_id, tracking_number]
end

#matching_additionalObject



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/tracking_number/base.rb', line 187

def matching_additional
  additional = self.class.const_get(:ADDITIONAL) || []

  relevant_sections = {}

  additional.each do |info|
    if self.matches && self.matches.length > 0
      if value = self.matches[info[:regex_group_name]].gsub(/\s/, "")
        # has matching value
        matches = info[:lookup].find do |i|
          if i[:matches]
            value == i[:matches]
          elsif i[:matches_regex]
            value =~ Regexp.new(i[:matches_regex])
          end
        end

        relevant_sections[info[:name]] = matches
      end
    end
  end

  relevant_sections
end

#package_typeObject



158
159
160
161
162
# File 'lib/tracking_number/base.rb', line 158

def package_type
  if matching_additional["Container Type"]
    @package_type ||= Info.new(matching_additional["Container Type"]).name
  end
end

#serial_numberObject



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/tracking_number/base.rb', line 38

def serial_number
  return match_group("SerialNumber") unless self.class.const_get("VALIDATION")

  format_info   = self.class.const_get(:VALIDATION)[:serial_number_format]
  raw_serial    = match_group("SerialNumber")

  if format_info
    if format_info[:prepend_if] && raw_serial.match(Regexp.new(format_info[:prepend_if][:matches_regex]))
      return "#{format_info[:prepend_if][:content]}#{raw_serial}"
    elsif format_info[:prepend_if_missing]

    end
  end

  return raw_serial
end

#service_descriptionObject



152
153
154
155
156
# File 'lib/tracking_number/base.rb', line 152

def service_description
  if matching_additional["Service Type"]
    @service_description ||= Info.new(matching_additional["Service Type"]).description
  end
end

#service_typeObject



146
147
148
149
150
# File 'lib/tracking_number/base.rb', line 146

def service_type
  if matching_additional["Service Type"]
    @service_type ||= Info.new(matching_additional["Service Type"]).name
  end
end

#shipper_idObject



168
169
170
# File 'lib/tracking_number/base.rb', line 168

def shipper_id
  match_group("ShipperId")
end

#to_sObject



99
100
101
# File 'lib/tracking_number/base.rb', line 99

def to_s
  self.tracking_number
end

#tracking_urlObject



172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/tracking_number/base.rb', line 172

def tracking_url
  url = nil
  if matching_additional["Courier"]
    url = matching_additional["Courier"][:tracking_url]
  else
    if self.class.const_defined?(:TRACKING_URL)
      url = self.class.const_get(:TRACKING_URL)
    end
  end

  if url
    url.sub('%s', self.tracking_number)
  end
end

#valid?Boolean

Returns:

  • (Boolean)


69
70
71
72
73
74
# File 'lib/tracking_number/base.rb', line 69

def valid?
  return false unless valid_format?
  return false unless valid_checksum?
  return false unless valid_optional_checks?
  return true
end

#valid_checksum?Boolean

Returns:

  • (Boolean)


88
89
90
91
92
93
94
95
96
97
# File 'lib/tracking_number/base.rb', line 88

def valid_checksum?
  return false unless self.valid_format?
  checksum_info   = self.class.const_get(:VALIDATION)[:checksum]
  return true unless checksum_info

  name            = checksum_info[:name]
  method_name     = "validates_#{name}?"

  TrackingNumber::ChecksumValidations.send(method_name, serial_number, check_digit, checksum_info)
end

#valid_format?Boolean

Returns:

  • (Boolean)


76
77
78
# File 'lib/tracking_number/base.rb', line 76

def valid_format?
  !matches.nil?
end

#valid_optional_checks?Boolean

Returns:

  • (Boolean)


80
81
82
83
84
85
86
# File 'lib/tracking_number/base.rb', line 80

def valid_optional_checks?
  additional_check = self.class.const_get("VALIDATION")[:additional]
  return true unless additional_check

  exist_checks = (additional_check[:exists] ||= [])
  exist_checks.all? { |w| matching_additional[w] }
end