Class: ShipmentTrackingNumber

Inherits:
Object
  • Object
show all
Defined in:
app/models/shipment_tracking_number.rb

Overview

A simple ruby object to provide parsing and interpretation of tracking numbers
normalizes courier code
parses tracking number and extract information when possible
offers access to tracking link

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(tracking_number, options = {}) ⇒ ShipmentTrackingNumber

Returns a new instance of ShipmentTrackingNumber.

Parameters:

  • tracking_number (String)

    raw tracking number

  • options (Hash) (defaults to: {})

Options Hash (options):

  • courier_code (Symbol, String)

    courier code override;
    when present the tracking number is not parsed for the courier



14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'app/models/shipment_tracking_number.rb', line 14

def initialize(tracking_number, options = {})
  @tracking_number = tracking_number
  if options[:courier_code].present?
    @shipment_courier = ShipmentCourier.new(options[:courier_code])
    @courier_code = @shipment_courier.courier_code
  elsif @tracking_number.present? && (@tn = Heatwave::TrackingNumber.parse(@tracking_number)).valid?
    @courier_code = tn.courier_code
    @courier_name = tn.courier_name
    @service_type = tn.service_type
    @shipment_courier = ShipmentCourier.new(@courier_code)
  end
  @options = options
end

Instance Attribute Details

#courier_codeObject (readonly)

Returns the value of attribute courier_code.



8
9
10
# File 'app/models/shipment_tracking_number.rb', line 8

def courier_code
  @courier_code
end

#courier_nameObject (readonly)

Returns the value of attribute courier_name.



8
9
10
# File 'app/models/shipment_tracking_number.rb', line 8

def courier_name
  @courier_name
end

#optionsObject (readonly)

Returns the value of attribute options.



8
9
10
# File 'app/models/shipment_tracking_number.rb', line 8

def options
  @options
end

#service_typeObject (readonly)

Returns the value of attribute service_type.



8
9
10
# File 'app/models/shipment_tracking_number.rb', line 8

def service_type
  @service_type
end

#shipment_courierObject (readonly)

Returns the value of attribute shipment_courier.



8
9
10
# File 'app/models/shipment_tracking_number.rb', line 8

def shipment_courier
  @shipment_courier
end

#tnObject (readonly)

Returns the value of attribute tn.



8
9
10
# File 'app/models/shipment_tracking_number.rb', line 8

def tn
  @tn
end

#tracking_numberObject (readonly)

Returns the value of attribute tracking_number.



8
9
10
# File 'app/models/shipment_tracking_number.rb', line 8

def tracking_number
  @tracking_number
end

Instance Method Details

#==(other) ⇒ Boolean

Returns true when courier and tracking number match.

Parameters:

Returns:

  • (Boolean)

    true when courier and tracking number match



79
80
81
# File 'app/models/shipment_tracking_number.rb', line 79

def ==(other)
  tracking_number == other.tracking_number && courier_code == other.courier_code
end

#tracking_urlObject

Prefer the hardcoded CRM URLs; fall through to the catalog template
for couriers we have not given a first-party link.



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'app/models/shipment_tracking_number.rb', line 30

def tracking_url
  # We use our own if we have it
  case courier_code
  when :fedex, :fedexfreight
    "https://www.fedex.com/fedextrack/?trknbr=#{tracking_number}"
  when :ups
    "http://wwwapps.ups.com/WebTracking/processInputRequest?sort_by=status&tracknums_displayed=1&TypeOfInquiryNumber=T&loc=en_US&track.x=0&track.y=0&InquiryNumber1=#{tracking_number}"
  when :purolator
    "https://www.purolator.com/purolator/ship-track/tracking-details.page?pin=#{tracking_number}"
  when :canada_post
    "https://www.canadapost-postescanada.ca/track-reperage/en#/details/#{tracking_number}"
  when :canpar
    "https://www.canpar.com/en/track/TrackingAction.do?locale=en&type=0&reference=#{tracking_number}"
  when :usps
    "https://tools.usps.com/go/TrackConfirmAction.action?tRef=fullpage&tLc=1&text28777=&tLabels=#{tracking_number}"
  when :freightquote
    "https://online.chrobinson.com/tracking/#/#{tracking_number}"
  when :curri
    # DERIVED, not stored. Curri's bookDelivery response returns a live
    # trackingUrl, but it is always app.curri.com/track/<trackingId> and that
    # trackingId IS the tracking_number Shipping::Curri#label writes (three
    # sandbox bookings, 2026-08-06). Deriving it gives every Curri shipment a
    # working link — including any booked before this branch existed — where
    # persisting the returned URL would need a column, a Delivery::GenerateLabels
    # change, and would still leave older shipments at '#'.
    "https://app.curri.com/track/#{tracking_number}"
  when :speedee
    "http://speedeedelivery.com/track-a-shipment/?v=detail&barcode=#{tracking_number}"
  when :rlcarriers
    "https://www.rlcarriers.com/freight/shipping/shipment-tracing?pro=#{tracking_number}&docType=PRO&source=web"
  when :roadrunner
    "https://tools.rrts.com/LTLTrack/?searchValues=#{tracking_number}"
  when :xpo
    "https://ext-web.ltl-xpo.com/public-app/shipments?referenceNumber=#{tracking_number}"
  when :saia
    "https://www.saia.com/track/details;pro=#{tracking_number}"
  when :yrc
    "https://my.yrc.com/tools/track/shipments?referenceNumberType=PRO&referenceNumber=#{tracking_number}"
  else
    if @tn&.valid?
      @tn.tracking_url
    else
      '#'
    end
  end
end