class FriendlyShipping::Services::Ups

Option container for a generating UPS labels for a shipment

Required:

@param shipping_method [FriendlyShipping::ShippingMethod] The shipping method to use. We only need the

service_code to be set.

@param shipper_number [String] account number for the shipper

Optional:

@param shipper [Physical::Location] The company sending the shipment. Defaults to the shipment's origin. @param customer_context [String ] Optional element to identify transactions between client and server @param validate_address [Boolean] Validate the city field with ZIP code and state. If false, only ZIP code

and state are validated. Default: true

@param negotiated_rates [Boolean] if truthy negotiated rates will be requested from ups. Only valid if

shipper account has negotiated rates. Default: false

@option sold_to [Physical::Location] The person or company who imports and pays any duties due on the

current shipment. Default: The shipment's destination

@option saturday_delivery [Boolean] should we request Saturday delivery?. Default: false @option label_format [String] GIF, EPL, ZPL, STARPL and SPL @option label_size [Array<Integer>] Dimensions of the label. Default: [4, 6] @option delivery_confirmation [Symbol] Can be set to any key from SHIPMENT_DELIVERY_CONFIRMATION_CODES.

Only possible for international shipments that are not between the US and Puerto Rico.

@option carbon_neutral [Boolean] Ship with UPS' carbon neutral program @option return_service_code [Symbol] If present, marks this a return label. The kind

of return label is specified by the symbol, one of the keys in RETURN_SERVICE_CODES. Default: nil

Shipment options for international shipping:

@option paperless_invoice [Boolean] set to truthy if using paperless invoice to ship internationally. Default false @option terms_of_shipment [Symbol] used with paperless invoice to specify who pays duties and taxes.

See TERMS_OF_SHIPMENT constant for possible options.

@option reason_for_export [String] A reason to export the current shipment. Possible values: 'SALE', 'GIFT', 'SAMPLE',

'RETURN', 'REPAIR', 'INTERCOMPANYDATA', Any other reason. Default: 'SALE'.

@option invoice_date [Date] The invoice date for the shipment

Option container for rating a shipment via UPS

Required:

@option shipper_number [String] The shipper number of the origin of the shipment.

Optional:

@option carbon_neutral [Boolean] Ship with UPS' carbon neutral program @option customer_context [String ] Optional element to identify transactions between client and server @option customer_classification [Symbol] Which kind of rates to request. See UPS docs for more details. Default: `shipper_number` @option negotiated_rates [Boolean] if truthy negotiated rates will be requested from ups. Only valid if

shipper account has negotiated rates. Default: false

@option saturday_delivery [Boolean] should we request Saturday delivery?. Default: false @option saturday_pickup [Boolean] should we request Saturday pickup?. Default: false @option shipping_method [FriendlyShipping::ShippingMethod] Request rates for a particular shipping method only?

Default is `nil`, which translates to 'All shipping methods' (The "Shop" option in UPS parlance)

@option with_time_in_transit [Boolean] Whether to request timing information alongside the rates @option package_options_class [Class] See FriendlyShipping::ShipmentOptions

Constants

CARRIER
EU_COUNTRIES
LIVE_URL
RESOURCES
SHIPPING_METHODS
TEST_URL

Attributes

client[R]
key[R]
login[R]
password[R]
test[R]

Public Class Methods

new(key:, login:, password:, test: true, client: HttpClient.new) click to toggle source
# File lib/friendly_shipping/services/ups.rb, line 53
def initialize(key:, login:, password:, test: true, client: HttpClient.new)
  @key = key
  @login = login
  @password = password
  @test = test
  @client = client
end

Private Class Methods

countries_by_code(code) click to toggle source
# File lib/friendly_shipping/services/ups/shipping_methods.rb, line 13
def countries_by_code(code)
  all_countries = Carmen::Country.all
  covered_countries = EU_COUNTRIES + %w(US PR CA PL MX).map do |country_code|
    Carmen::Country.coded(country_code)
  end
  other_countries = Carmen::Country.all - covered_countries
  case code
  when 'EU' then EU_COUNTRIES
  when 'OTHER' then other_countries
  when 'ALL' then all_countries
  else
    [Carmen::Country.coded(code)]
  end
end

Public Instance Methods

address_classification(location, debug: false) click to toggle source

Classify an address. @param [Physical::Location] location The address we want to classify @return [Result<ApiResult<String>>] Either `“commercial”`, `“residential”`, or `“unknown”`

# File lib/friendly_shipping/services/ups.rb, line 172
def address_classification(location, debug: false)
  address_validation_request_xml = SerializeAddressValidationRequest.call(location: location)
  url = base_url + RESOURCES[:address_validation]
  request = FriendlyShipping::Request.new(
    url: url,
    body: access_request_xml + address_validation_request_xml,
    readable_body: address_validation_request_xml,
    debug: debug
  )

  client.post(request).bind do |response|
    ParseAddressClassificationResponse.call(response: response, request: request)
  end
end
address_validation(location, debug: false) click to toggle source

Validate an address. @param [Physical::Location] location The address we want to verify @return [Result<ApiResult<Array<Physical::Location>>>] The response data from UPS encoded in a

`Physical::Location` object. Name and Company name are always nil, the
address lines will be made conformant to what UPS considers right. The returned location will
have the address_type set if possible.
# File lib/friendly_shipping/services/ups.rb, line 154
def address_validation(location, debug: false)
  address_validation_request_xml = SerializeAddressValidationRequest.call(location: location)
  url = base_url + RESOURCES[:address_validation]
  request = FriendlyShipping::Request.new(
    url: url,
    body: access_request_xml + address_validation_request_xml,
    readable_body: address_validation_request_xml,
    debug: debug
  )

  client.post(request).bind do |response|
    ParseAddressValidationResponse.call(response: response, request: request)
  end
end
carriers() click to toggle source
# File lib/friendly_shipping/services/ups.rb, line 61
def carriers
  Success([CARRIER])
end
city_state_lookup(location, debug: false) click to toggle source

Find city and state for a given ZIP code @param [Physical::Location] location A location object with country and ZIP code set @return [Result<ApiResult<Array<Physical::Location>>>] The response data from UPS encoded in a

`Physical::Location` object. Country, City and ZIP code will be set, everything else nil.
# File lib/friendly_shipping/services/ups.rb, line 191
def city_state_lookup(location, debug: false)
  city_state_lookup_request_xml = SerializeCityStateLookupRequest.call(location: location)
  url = base_url + RESOURCES[:city_state_lookup]
  request = FriendlyShipping::Request.new(
    url: url,
    body: access_request_xml + city_state_lookup_request_xml,
    readable_body: city_state_lookup_request_xml,
    debug: debug
  )

  client.post(request).bind do |response|
    ParseCityStateLookupResponse.call(response: response, request: request, location: location)
  end
end
labels(shipment, options:, debug: false) click to toggle source
# File lib/friendly_shipping/services/ups.rb, line 108
def labels(shipment, options:, debug: false)
  ## Method body starts
  ship_confirm_request_xml = SerializeShipmentConfirmRequest.call(
    shipment: shipment,
    options: options
  )
  ship_confirm_url = base_url + RESOURCES[:ship_confirm]

  ship_confirm_request = FriendlyShipping::Request.new(
    url: ship_confirm_url,
    body: access_request_xml + ship_confirm_request_xml,
    readable_body: ship_confirm_request_xml,
    debug: debug
  )

  client.post(ship_confirm_request).bind do |ship_confirm_response|
    ParseShipmentConfirmResponse.call(
      request: ship_confirm_request,
      response: ship_confirm_response
    )
  end.bind do |ship_confirm_result|
    ship_accept_url = base_url + RESOURCES[:ship_accept]
    ship_accept_request_xml = SerializeShipmentAcceptRequest.call(
      digest: ship_confirm_result.data,
      options: options
    )

    ship_accept_request = FriendlyShipping::Request.new(
      url: ship_accept_url,
      body: access_request_xml + ship_accept_request_xml,
      readable_body: ship_accept_request_xml,
      debug: debug
    )

    client.post(ship_accept_request).bind do |ship_accept_response|
      ParseShipmentAcceptResponse.call(request: ship_accept_request, response: ship_accept_response)
    end
  end
end
rate_estimates(shipment, options:, debug: false) click to toggle source

Get rates for a shipment @param [Physical::Shipment] shipment The shipment we want to get rates for @param [FriendlyShipping::Services::Ups::RateEstimateOptions] options What options

to use for this rate estimate call

@return [Result<ApiResult<Array<Rate>>>] The rates returned from UPS encoded in a

`FriendlyShipping::ApiResult` object.
# File lib/friendly_shipping/services/ups.rb, line 71
def rate_estimates(shipment, options:, debug: false)
  rate_request_xml = SerializeRatingServiceSelectionRequest.call(shipment: shipment, options: options)
  url = base_url + RESOURCES[:rates]
  request = FriendlyShipping::Request.new(
    url: url,
    body: access_request_xml + rate_request_xml,
    readable_body: rate_request_xml,
    debug: debug
  )

  client.post(request).bind do |response|
    ParseRateResponse.call(response: response, request: request, shipment: shipment)
  end
end
timings(shipment, options:, debug: false) click to toggle source

Get timing information for a shipment @param [Physical::Shipment] shipment The shipment we want to estimate timings for @param [FriendlyShipping::Services::Ups::TimingOptions] options Options for this call

# File lib/friendly_shipping/services/ups.rb, line 89
def timings(shipment, options:, debug: false)
  time_in_transit_request_xml = SerializeTimeInTransitRequest.call(
    shipment: shipment,
    options: options
  )
  time_in_transit_url = base_url + RESOURCES[:timings]

  request = FriendlyShipping::Request.new(
    url: time_in_transit_url,
    body: access_request_xml + time_in_transit_request_xml,
    readable_body: time_in_transit_request_xml,
    debug: debug
  )

  client.post(request).bind do |response|
    ParseTimeInTransitResponse.call(response: response, request: request)
  end
end
void(label, debug: false) click to toggle source
# File lib/friendly_shipping/services/ups.rb, line 206
def void(label, debug: false)
  url = base_url + RESOURCES[:void]
  void_request_xml = SerializeVoidShipmentRequest.call(label: label)
  request = FriendlyShipping::Request.new(
    url: url,
    body: access_request_xml + void_request_xml,
    readable_body: void_request_xml,
    debug: debug
  )
  client.post(request).bind do |response|
    ParseVoidShipmentResponse.call(request: request, response: response)
  end
end

Private Instance Methods

access_request_xml() click to toggle source
# File lib/friendly_shipping/services/ups.rb, line 222
def access_request_xml
  SerializeAccessRequest.call(key: key, login: login, password: password)
end
base_url() click to toggle source
# File lib/friendly_shipping/services/ups.rb, line 226
def base_url
  test ? TEST_URL : LIVE_URL
end