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.



8
9
10
11
# File 'lib/tracking_number/base.rb', line 8

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.



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

def original_number
  @original_number
end

#tracking_numberObject

Returns the value of attribute tracking_number.



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

def tracking_number
  @tracking_number
end

Class Method Details

.scan(body) ⇒ Object



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

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



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

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



57
58
59
# File 'lib/tracking_number/base.rb', line 57

def check_digit
  match_group("CheckDigit")
end

#courier_codeObject Also known as: carrier, carrier_code



121
122
123
# File 'lib/tracking_number/base.rb', line 121

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

#courier_infoObject



139
140
141
142
143
144
145
146
147
# File 'lib/tracking_number/base.rb', line 139

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



125
126
127
128
129
130
131
132
133
# File 'lib/tracking_number/base.rb', line 125

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



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

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



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

def destination_zip
  match_group("DestinationZip")
end

#infoObject



109
110
111
112
113
114
115
116
117
118
119
# File 'lib/tracking_number/base.rb', line 109

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,
    :package_description => package_description
  })
end

#inspectObject



105
106
107
# File 'lib/tracking_number/base.rb', line 105

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

#matching_additionalObject



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/tracking_number/base.rb', line 175

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



161
162
163
164
165
# File 'lib/tracking_number/base.rb', line 161

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

#serial_numberObject



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

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



155
156
157
158
159
# File 'lib/tracking_number/base.rb', line 155

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

#service_typeObject



149
150
151
152
153
# File 'lib/tracking_number/base.rb', line 149

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

#shipper_idObject



171
172
173
# File 'lib/tracking_number/base.rb', line 171

def shipper_id
  match_group("ShipperId")
end

#to_sObject



101
102
103
# File 'lib/tracking_number/base.rb', line 101

def to_s
  self.tracking_number
end

#valid?Boolean

Returns:

  • (Boolean)


71
72
73
74
75
76
# File 'lib/tracking_number/base.rb', line 71

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)


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

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}?"

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

#valid_format?Boolean

Returns:

  • (Boolean)


78
79
80
# File 'lib/tracking_number/base.rb', line 78

def valid_format?
  !matches.nil?
end

#valid_optional_checks?Boolean

Returns:

  • (Boolean)


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

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