class ReactiveShipping::SEFL
Constants
- JSON_HEADERS
- REACTIVE_FREIGHT_CARRIER
Public Instance Methods
find_rates(origin, destination, packages, options = {})
click to toggle source
Rates
# File lib/reactive_freight/carriers/sefl.rb, line 20 def find_rates(origin, destination, packages, options = {}) options = @options.merge(options) origin = Location.from(origin) destination = Location.from(destination) packages = Array(packages) request = build_rate_request(origin, destination, packages, options) parse_rate_response(origin, destination, commit(request)) end
Protected Instance Methods
auth_header(options = {})
click to toggle source
# File lib/reactive_freight/carriers/sefl.rb, line 43 def auth_header(options = {}) options = @options.merge(options) if !options[:username].blank? && !options[:password].blank? auth = Base64.strict_encode64("#{options[:username]}:#{options[:password]}") return { 'Authorization': "Basic #{auth}" } end {} end
base_url()
click to toggle source
# File lib/reactive_freight/carriers/sefl.rb, line 39 def base_url "https://#{@conf.dig(:api, :domain)}" end
build_rate_request(origin, destination, packages, options = {})
click to toggle source
Rates
# File lib/reactive_freight/carriers/sefl.rb, line 90 def build_rate_request(origin, destination, packages, options = {}) options = @options.merge(options) accessorials = [] unless options[:accessorials].blank? serviceable_accessorials?(options[:accessorials]) options[:accessorials].each do |a| unless @conf.dig(:accessorials, :unserviceable).include?(a) accessorials << @conf.dig(:accessorials, :mappable)[a] end end end longest_dimension = packages.inject([]) { |_arr, p| [p.length(:in), p.width(:in)] }.max.ceil accessorials << 'chkOD' if longest_dimension >= 96 accessorials = accessorials.uniq pickup_on = options[:pickup_on].blank? ? Date.current : options[:pickup_on] body = { returnX: 'Y', rateXML: 'Y', CustomerAccount: options[:account].to_i.to_s.rjust(9, '0'), CustomerName: options[:customer_name], CustomerStreet: options.dig(:customer_address, :street), CustomerCity: options.dig(:customer_address, :city), CustomerState: options.dig(:customer_address, :state), CustomerZip: options.dig(:customer_address, :zip_code), Description: 'Freight All Kinds', Option: 'T', Terms: 'P', allowSpot: packages.inject(0) { |_sum, p| _sum += [p.length(:in), p.width(:in)].max.ceil } >= 120 ? 'Y' : 'N', DimsOption: 'I', EmailAddress: options[:customer_email].blank? ? 'unknown@fake.fake' : options[:customer_email], PickupMonth: pickup_on.strftime('%_m'), PickupDay: pickup_on.strftime('%_d'), PickupYear: pickup_on.strftime('%Y'), OriginCity: origin.to_hash[:city], OriginState: origin.to_hash[:province], OriginZip: origin.to_hash[:postal_code], OrigCountry: 'U', DestinationCity: destination.to_hash[:city], DestinationState: destination.to_hash[:province], DestinationZip: destination.to_hash[:postal_code], DestCountry: 'U' } if longest_dimension >= 96 body = body.deep_merge( { ODLength: longest_dimension, ODLengthUnit: 'I' } ) end i = 0 packages.each do |package| i += 1 body = body.deep_merge({ "Class#{i}": package.freight_class.to_s.sub('.', '').to_i }) body = body.deep_merge({ "CubicFt#{i}": package.cubic_ft }) if destination.to_hash[:province].upcase == 'PR' body = body.deep_merge({ "Description#{i}": 'Freight All Kinds' }) body = body.deep_merge({ "PieceLength#{i}": package.length(:in).ceil }) body = body.deep_merge({ "PieceWidth#{i}": package.width(:in).ceil }) body = body.deep_merge({ "PieceHeight#{i}": package.height(:in).ceil }) body = body.deep_merge({ "Weight#{i}": package.pounds.ceil }) end unless accessorials.blank? accessorials.each do |_accessorial| body = body.deep_merge({ accessorial: 'on' }) end end request = build_request(:rates, body: body) save_request(request) request end
build_request(action, options = {})
click to toggle source
# File lib/reactive_freight/carriers/sefl.rb, line 53 def build_request(action, options = {}) options = @options.merge(options) headers = JSON_HEADERS headers = headers.merge(auth_header) headers = headers.merge(options[:headers]) unless options[:headers].blank? body = URI.encode_www_form(options[:body]) unless options[:body].blank? request = { url: options[:url].blank? ? build_url(action, options) : options[:url], headers: headers, method: @conf.dig(:api, :methods, action), body: body } save_request(request) request end
build_url(action, options = {})
click to toggle source
Tracking
# File lib/reactive_freight/carriers/sefl.rb, line 34 def build_url(action, options = {}) options = @options.merge(options) "#{base_url}#{@conf.dig(:api, :endpoints, action)}" end
commit(request)
click to toggle source
# File lib/reactive_freight/carriers/sefl.rb, line 71 def commit(request) url = request[:url] headers = request[:headers] method = request[:method] body = request[:body] response = case method when :post HTTParty.post(url, headers: headers, body: body) else HTTParty.get(url, headers: headers) end JSON.parse(response.body) if response&.body end
parse_rate_response(origin, destination, response)
click to toggle source
# File lib/reactive_freight/carriers/sefl.rb, line 171 def parse_rate_response(origin, destination, response) success = true message = '' if !response success = false message = 'API Error: Unknown response' elsif !response.dig('errorMessage').blank? success = false message = response.dig('errorMessage') else sleep(5) # TODO: Maybe improve this? url = response.dig('detailQuoteLocation').gsub('\\', '') request = build_request(:get_rate, url: url) save_request(request) response = commit(request) if !response success = false message = 'API Error: Unknown response' elsif !response.dig('errorMessage').blank? success = false message = response.dig('errorMessage') else cost = response.dig('rateQuote') if cost cost = cost.sub('.', '').to_i estimate_reference = response.dig('quoteNumber') transit_days = response.dig('transitTime').to_i rate_estimates = [ RateEstimate.new( origin, destination, { scac: self.class.scac.upcase, name: self.class.name }, :standard, transit_days: transit_days, estimate_reference: estimate_reference, total_cost: cost, total_price: cost, currency: 'USD', with_excessive_length_fees: @conf.dig(:attributes, :rates, :with_excessive_length_fees) ) ] else success = false message = 'API Error: Cost is emtpy' end end end RateResponse.new( success, message, response.to_hash, rates: rate_estimates, response: response, request: last_request ) end