Class: ActiveMerchant::Shipping::UPS

Inherits:
Carrier show all
Defined in:
lib/active_shipping/shipping/carriers/ups.rb

Constant Summary collapse

TEST_URL =
'https://wwwcie.ups.com'
LIVE_URL =
'https://onlinetools.ups.com'
RESOURCES =
{
  :rates => 'ups.app/xml/Rate',
  :track => 'ups.app/xml/Track',
  :ship_confirm => 'ups.app/xml/ShipConfirm',
  :ship_accept => 'ups.app/xml/ShipAccept'
}
PICKUP_CODES =
HashWithIndifferentAccess.new(
  :daily_pickup => "01",
  :customer_counter => "03",
  :one_time_pickup => "06",
  :on_call_air => "07",
  :suggested_retail_rates => "11",
  :letter_center => "19",
  :air_service_center => "20"
)
CUSTOMER_CLASSIFICATIONS =
HashWithIndifferentAccess.new(
  :wholesale => "01",
  :occasional => "03",
  :retail => "04"
)
DEFAULT_CUSTOMER_CLASSIFICATIONS =

these are the defaults described in the UPS API docs, but they don't seem to apply them under all circumstances, so we need to take matters into our own hands

Hash.new do |hash, key|
  hash[key] = case key.to_sym
  when :daily_pickup then :wholesale
  when :customer_counter then :retail
  else
    :occasional
  end
end
DEFAULT_SERVICES =
{
  "01" => "UPS Next Day Air",
  "02" => "UPS Second Day Air",
  "03" => "UPS Ground",
  "07" => "UPS Worldwide Express",
  "08" => "UPS Worldwide Expedited",
  "11" => "UPS Standard",
  "12" => "UPS Three-Day Select",
  "13" => "UPS Next Day Air Saver",
  "14" => "UPS Next Day Air Early A.M.",
  "54" => "UPS Worldwide Express Plus",
  "59" => "UPS Second Day Air A.M.",
  "65" => "UPS Saver",
  "82" => "UPS Today Standard",
  "83" => "UPS Today Dedicated Courier",
  "84" => "UPS Today Intercity",
  "85" => "UPS Today Express",
  "86" => "UPS Today Express Saver"
}
CANADA_ORIGIN_SERVICES =
{
  "01" => "UPS Express",
  "02" => "UPS Expedited",
  "14" => "UPS Express Early A.M."
}
MEXICO_ORIGIN_SERVICES =
{
  "07" => "UPS Express",
  "08" => "UPS Expedited",
  "54" => "UPS Express Plus"
}
EU_ORIGIN_SERVICES =
{
  "07" => "UPS Express",
  "08" => "UPS Expedited"
}
OTHER_NON_US_ORIGIN_SERVICES =
{
  "07" => "UPS Express"
}
TRACKING_STATUS_CODES =
HashWithIndifferentAccess.new(
  'I' => :in_transit,
  'D' => :delivered,
  'X' => :exception,
  'P' => :pickup,
  'M' => :manifest_pickup
)
EU_COUNTRY_CODES =
%w(GB AT BE BG CY CZ DK EE FI FR DE GR HU IE IT LV LT LU MT NL PL PT RO SK SI ES SE)
US_TERRITORIES_TREATED_AS_COUNTRIES =
%w(AS FM GU MH MP PW PR VI)
IMPERIAL_COUNTRIES =
%w(US LR MM)
@@name =
"UPS"

Instance Attribute Summary

Attributes inherited from Carrier

#last_request, #test_mode

Instance Method Summary collapse

Methods inherited from Carrier

#initialize, #maximum_weight, #valid_credentials?

Constructor Details

This class inherits a constructor from ActiveMerchant::Shipping::Carrier

Instance Method Details

#create_shipment(origin, destination, packages, options = {}) ⇒ Object


128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/active_shipping/shipping/carriers/ups.rb', line 128

def create_shipment(origin, destination, packages, options = {})
  options = @options.merge(options)
  packages = Array(packages)
  access_request = build_access_request

  begin

    # STEP 1: Confirm.  Validation step, important for verifying price.
    confirm_request = build_shipment_request(origin, destination, packages, options)
    logger.debug(confirm_request) if logger

    confirm_response = commit(:ship_confirm, save_request(access_request + confirm_request), (options[:test] || false))
    logger.debug(confirm_response) if logger

    # ... now, get the digest, it's needed to get the label.  In theory,
    # one could make decisions based on the price or some such to avoid
    # surprises.  This also has *no* error handling yet.
    xml = parse_ship_confirm(confirm_response)
    success = response_success?(xml)
    message = response_message(xml)
    digest  = response_digest(xml)
    raise message unless success

    # STEP 2: Accept. Use shipment digest in first response to get the actual label.
    accept_request = build_accept_request(digest, options)
    logger.debug(accept_request) if logger

    accept_response = commit(:ship_accept, save_request(access_request + accept_request), (options[:test] || false))
    logger.debug(accept_response) if logger

    # ...finally, build a map from the response that contains
    # the label data and tracking information.
    parse_ship_accept(accept_response)

  rescue RuntimeError => e
    raise "Could not obtain shipping label. #{e.message}."

  end
end

#find_rates(origin, destination, packages, options = {}) ⇒ Object


110
111
112
113
114
115
116
117
118
# File 'lib/active_shipping/shipping/carriers/ups.rb', line 110

def find_rates(origin, destination, packages, options = {})
  origin, destination = upsified_location(origin), upsified_location(destination)
  options = @options.merge(options)
  packages = Array(packages)
  access_request = build_access_request
  rate_request = build_rate_request(origin, destination, packages, options)
  response = commit(:rates, save_request(access_request + rate_request), (options[:test] || false))
  parse_rate_response(origin, destination, packages, response, options)
end

#find_tracking_info(tracking_number, options = {}) ⇒ Object


120
121
122
123
124
125
126
# File 'lib/active_shipping/shipping/carriers/ups.rb', line 120

def find_tracking_info(tracking_number, options = {})
  options = @options.update(options)
  access_request = build_access_request
  tracking_request = build_tracking_request(tracking_number, options)
  response = commit(:track, save_request(access_request + tracking_request), (options[:test] || false))
  parse_tracking_response(response, options)
end

#requirementsObject


106
107
108
# File 'lib/active_shipping/shipping/carriers/ups.rb', line 106

def requirements
  [:key, :login, :password]
end