class ReactiveShipping::Carrier

Carrier is the abstract base class for all supported carriers.

To implement support for a carrier, you should subclass this class and implement all the methods that the carrier supports.

@see find_rates @see create_shipment @see cancel_shipment @see find_tracking_info

@!attribute test_mode

Whether to interact with the carrier's sandbox environment.
@return [Boolean]

@!attribute last_request

The last request performed against the carrier's API.
@see #save_request

Attributes

last_request[R]
test_mode[RW]
test_mode?[RW]

Public Class Methods

new(options = {}) click to toggle source

Credentials should be in options hash under keys :login, :password and/or :key. @param options [Hash] The details needed to connect to the carrier's API. @option options [Boolean] :test Set this to true to connect to the carrier's

sandbox environment instead of the production environment.
# File lib/reactive_shipping/carrier.rb, line 29
def initialize(options = {})
  requirements.each { |key| requires!(options, key) }
  @options = options
  @last_request = nil
  @test_mode = @options[:test]
end

Protected Class Methods

default_location() click to toggle source

The default location to use for {#valid_credentials?}. @note Override for non-U.S.-based carriers. @return [ReactiveShipping::Location]

# File lib/reactive_shipping/carrier.rb, line 149
def self.default_location
  Location.new( :country => 'US',
                :state => 'CA',
                :city => 'Beverly Hills',
                :address1 => '455 N. Rexford Dr.',
                :address2 => '3rd Floor',
                :zip => '90210',
                :phone => '1-310-285-1013',
                :fax => '1-310-275-8159')
end

Public Instance Methods

available_services(origin_country_code, destination_country_code, options = {}) click to toggle source

Get a list of services available for the a specific route

@param origin_country_code [String] The country of origin @param destination_country_code [String] The destination country @return [Array<String>] A list of names of the available services

# File lib/reactive_shipping/carrier.rb, line 101
def available_services(origin_country_code, destination_country_code, options = {})
  raise NotImplementedError, "#available_services is not supported by #{self.class.name}."
end
cancel_shipment(shipment_id, options = {}) click to toggle source

Cancels a shipment with a carrier.

@note Override with whatever you need to cancel a shipping label

@param shipment_id [String] The unique identifier of the shipment to cancel.

This can be shipment_id or tracking number depending on carrier. Up to you and
the carrier

@param options [Hash] Carrier-specific parameters. @return [ReactiveShipping::ShipmentResponse] The response from the carrier. This

response in most cases has a cancellation id.
# File lib/reactive_shipping/carrier.rb, line 79
def cancel_shipment(shipment_id, options = {})
  raise NotImplementedError, "#cancel_shipment is not supported by #{self.class.name}."
end
create_shipment(origin, destination, packages, options = {}) click to toggle source

Registers a new shipment with the carrier, to get a tracking number and potentially shipping labels

@note Override with whatever you need to register a shipment, and obtain

shipping labels if supported by the carrier.

@param origin [ReactiveShipping::Location] Where the shipment will originate from. @param destination [ReactiveShipping::Location] Where the package will go. @param packages [Array<ReactiveShipping::Package>] The list of packages that will

be in the shipment.

@param options [Hash] Carrier-specific parameters. @return [ReactiveShipping::ShipmentResponse] The response from the carrier. This

response should include a shipment identifier or tracking_number if successful,
and potentially shipping labels.
# File lib/reactive_shipping/carrier.rb, line 65
def create_shipment(origin, destination, packages, options = {})
  raise NotImplementedError, "#create_shipment is not supported by #{self.class.name}."
end
find_rates(origin, destination, packages, options = {}) click to toggle source

Asks the carrier for rate estimates for a given shipment.

@note Override with whatever you need to get the rates from the carrier.

@param origin [ReactiveShipping::Location] Where the shipment will originate from. @param destination [ReactiveShipping::Location] Where the package will go. @param packages [Array<ReactiveShipping::Package>] The list of packages that will

be in the shipment.

@param options [Hash] Carrier-specific parameters. @return [ReactiveShipping::RateResponse] The response from the carrier, which

includes 0 or more rate estimates for different shipping products
# File lib/reactive_shipping/carrier.rb, line 47
def find_rates(origin, destination, packages, options = {})
  raise NotImplementedError, "#find_rates is not supported by #{self.class.name}."
end
find_tracking_info(tracking_number, options = {}) click to toggle source

Retrieves tracking information for a previous shipment

@note Override with whatever you need to get a shipping label

@param tracking_number [String] The unique identifier of the shipment to track. @param options [Hash] Carrier-specific parameters. @return [ReactiveShipping::TrackingResponse] The response from the carrier. This

response should a list of shipment tracking events if successful.
# File lib/reactive_shipping/carrier.rb, line 91
def find_tracking_info(tracking_number, options = {})
  raise NotImplementedError, "#find_tracking_info is not supported by #{self.class.name}."
end
maximum_address_field_length() click to toggle source

The address field maximum length accepted by the carrier @return [Integer]

# File lib/reactive_shipping/carrier.rb, line 130
def maximum_address_field_length
  255
end
maximum_weight() click to toggle source

The maximum weight the carrier will accept. @return [Measured::Weight]

# File lib/reactive_shipping/carrier.rb, line 124
def maximum_weight
  Measured::Weight.new(150, :pounds)
end
valid_credentials?() click to toggle source

Validate credentials with a call to the API.

By default this just does a `find_rates` call with the origin and destination both as the carrier's default_location. Override to provide alternate functionality, such as checking for `test_mode` to use test servers, etc.

@return [Boolean] Should return `true` if the provided credentials proved to work,

`false` otherswise.
# File lib/reactive_shipping/carrier.rb, line 113
def valid_credentials?
  location = self.class.default_location
  find_rates(location, location, Package.new(100, [5, 15, 30]), :test => test_mode)
rescue ReactiveShipping::ResponseError
  false
else
  true
end

Protected Instance Methods

requirements() click to toggle source

Returns the keys that are required to be passed to the options hash @note Override to return required keys in options hash for initialize method. @return [Array<Symbol>]

# File lib/reactive_shipping/carrier.rb, line 142
def requirements
  []
end
save_request(r) click to toggle source

Use after building the request to save for later inspection. @return [void]

# File lib/reactive_shipping/carrier.rb, line 162
def save_request(r)
  @last_request = r
end
timestamp_from_business_day(days) click to toggle source

Calculates a timestamp that corresponds a given number of business days in the future

@param days [Integer] The number of business days from now. @return [DateTime] A timestamp, the provided number of business days in the future.

# File lib/reactive_shipping/carrier.rb, line 170
def timestamp_from_business_day(days)
  return unless days
  date = DateTime.now.utc

  days.times do
    date += 1.day

    date += 2.days if date.saturday?
    date += 1.day if date.sunday?
  end

  date.to_datetime
end