# FreightKit This library interfaces with the web services of various shipping carriers. The goal is to abstract the features that are most frequently used into a pleasant and consistent Ruby API. FreightKit supports: - Downloading scanned documents - Finding shipping rates - Tracking shipments On a technical level it supports: - Abstracted accessorials - Abstracted tracking events - Cubic feet and density calculations - Freight class calculations (and manual overriding) ## Definitions Carrier: Has unique web services pertaining to whatever real-world services they provide. Platform: Provides web-accessible services for many carriers at once. __Note:__ `Carrier`s may extend `Platform`s and override them when their behavior differs from the `Platform`. ## Plug-in System FreightKit relies on plug-ins (gems) to define how it connects to individual `Carrier`s and `Platform`s. ## Installation Using bundler, add to the `Gemfile`: ```ruby gem 'freight_kit' ``` Or standalone: ``` $ gem install freight_kit ``` __Note__: Plug-ins are required to connect to `Carrier`s and `Platforms` (see above). ## Standard Usage Start off by initializing the `Carrier` provided by a `Carrier` plug-in: ```ruby require 'freight_kit' # Typically just one `Credential` is required credentials = [ FreightKit::Credential.new( type: :api, account: 'account_number', username: 'username', password: 'password', tariff: FreightKit::Tariff.new # optional ), FreightKit::Credential.new( type: :oauth2, access_token: 'token', expires_at: DateTime.current + 1.day, # DateTime scope: 'scope' ), FreightKit::Credential.new( type: :website, username: 'username', password: 'password' ), FreightKit::Credential.new( type: :selenoid, base_url: URI.parse('http://domain:4444'), browser: :chrome ) ] carrier = FreightKit::SCAC.new(credentials) ``` ### Documents ```ruby carrier.bol(tracking_number) # BOL generated by carrier carrier.scanned_bol(tracking_number) # BOL scanned by carrier carrier.pod(tracking_number) ``` ### Tracking ```ruby tracking = carrier.find_tracking_info(tracking_number) tracking.delivered? tracking.status tracking.shipment_events.each do |event| puts "#{event.name} at #{event.location.city}, #{event.location.state} on #{event.time}. #{event.message}" end ``` ### Quoting ```ruby packages = [ FreightKit::Package.new( 371 * 16, # 371 lbs { length: 40, # inches width: 48, height: 47 }, units: :imperial ), FreightKit::Package.new( 371 * 16, # 371 lbs { length: 40, # inches width: 48, height: 47 }, freight_class: 125, # override calculated freight class units: :imperial ) ] origin = FreightKit::Location.new( country: 'US', state: 'CA', city: 'Los Angeles', zip: '90001' ) destination = FreightKit::Location.new( country: 'US', state: 'IL', city: 'Chicago', zip: '60007' ) accessorials = %i[ appointment_delivery liftgate_delivery residential_delivery ] response = carrier.find_rates(origin, destination, packages, accessorials: accessorials) rates = response.rates rates = response.rates.sort_by(&:price).collect { |rate| [rate.service_name, rate.price] } ```