freight_kit 0.1.20 → 0.1.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +0 -2
- data/README.md +6 -5
- data/Rakefile +4 -0
- data/VERSION +1 -1
- data/configuration/locations/amazon_warehouses.yml +3330 -0
- data/freight_kit-0.1.21.gem +0 -0
- data/freight_kit.gemspec +11 -22
- data/lib/freight_kit/address_normalizer.rb +24 -0
- data/lib/freight_kit/amazon_warehouse.rb +33 -0
- data/lib/freight_kit/api_clients/soap_client.rb +33 -10
- data/lib/freight_kit/carrier.rb +248 -302
- data/lib/freight_kit/carriers/a1_express.rb +25 -0
- data/lib/freight_kit/carriers/a_duie_pyle.rb +30 -0
- data/lib/freight_kit/carriers/aaa_cooper.rb +11 -0
- data/lib/freight_kit/carriers/aaa_expedited_services.rb +10 -0
- data/lib/freight_kit/carriers/ab_brothers_usa_inc.rb +12 -0
- data/lib/freight_kit/carriers/aberdeen_express_inc.rb +28 -0
- data/lib/freight_kit/carriers/abf_freight_system.rb +475 -0
- data/lib/freight_kit/carriers/access_transport.rb +10 -0
- data/lib/freight_kit/carriers/action_express.rb +10 -0
- data/lib/freight_kit/carriers/adams_and_companies.rb +10 -0
- data/lib/freight_kit/carriers/advance_distribution.rb +28 -0
- data/lib/freight_kit/carriers/alcon_transport.rb +10 -0
- data/lib/freight_kit/carriers/all_freight.rb +10 -0
- data/lib/freight_kit/carriers/alliance_transportation_group.rb +10 -0
- data/lib/freight_kit/carriers/allstate_transport.rb +10 -0
- data/lib/freight_kit/carriers/aloha_freight_forwarders.rb +31 -0
- data/lib/freight_kit/carriers/amado_trucking.rb +31 -0
- data/lib/freight_kit/carriers/american_fast_freight.rb +28 -0
- data/lib/freight_kit/carriers/amigos_service_transportation.rb +10 -0
- data/lib/freight_kit/carriers/anderson_towing_and_transport.rb +10 -0
- data/lib/freight_kit/carriers/apex_transporting.rb +10 -0
- data/lib/freight_kit/carriers/archer_cargo.rb +35 -0
- data/lib/freight_kit/carriers/armstrong_transport_group.rb +10 -0
- data/lib/freight_kit/carriers/autobahn_logistics.rb +10 -0
- data/lib/freight_kit/carriers/averitt_express.rb +30 -0
- data/lib/freight_kit/carriers/ba_transportation.rb +10 -0
- data/lib/freight_kit/carriers/balkin_express.rb +10 -0
- data/lib/freight_kit/carriers/bay_area_express.rb +10 -0
- data/lib/freight_kit/carriers/bc_freightways.rb +11 -0
- data/lib/freight_kit/carriers/benjamin_best_freight_inc.rb +37 -0
- data/lib/freight_kit/carriers/bennett_trucking.rb +10 -0
- data/lib/freight_kit/carriers/best_overnite_express.rb +78 -0
- data/lib/freight_kit/carriers/best_trucking.rb +10 -0
- data/lib/freight_kit/carriers/bestway_transport.rb +10 -0
- data/lib/freight_kit/carriers/bryan_systems.rb +10 -0
- data/lib/freight_kit/carriers/c_and_w_express.rb +10 -0
- data/lib/freight_kit/carriers/campbell_trucking.rb +10 -0
- data/lib/freight_kit/carriers/carde_transportation.rb +10 -0
- data/lib/freight_kit/carriers/cardinal_logistics.rb +28 -0
- data/lib/freight_kit/carriers/cdc_transport.rb +10 -0
- data/lib/freight_kit/carriers/cdo_express_diversified.rb +10 -0
- data/lib/freight_kit/carriers/cedar_supply_trucking.rb +10 -0
- data/lib/freight_kit/carriers/central_freight_lines.rb +12 -0
- data/lib/freight_kit/carriers/central_transport.rb +12 -0
- data/lib/freight_kit/carriers/chicago_suburban_express.rb +28 -0
- data/lib/freight_kit/carriers/city_logistics.rb +11 -0
- data/lib/freight_kit/carriers/clear_lane_freight_systems.rb +474 -0
- data/lib/freight_kit/carriers/cleopatra_trucking.rb +10 -0
- data/lib/freight_kit/carriers/clifford_transportation.rb +10 -0
- data/lib/freight_kit/carriers/cms_domestic.rb +25 -0
- data/lib/freight_kit/carriers/cnd_logistics.rb +10 -0
- data/lib/freight_kit/carriers/coast_to_coast_transport.rb +27 -0
- data/lib/freight_kit/carriers/countrywide_carriers.rb +10 -0
- data/lib/freight_kit/carriers/cpl_express.rb +31 -0
- data/lib/freight_kit/carriers/crosby_trucking_service.rb +29 -0
- data/lib/freight_kit/carriers/cross_country_freight_solutions.rb +408 -0
- data/lib/freight_kit/carriers/crowley.rb +10 -0
- data/lib/freight_kit/carriers/csa_transportation.rb +40 -0
- data/lib/freight_kit/carriers/csx_transportation.rb +40 -0
- data/lib/freight_kit/carriers/custom_global_logistics.rb +14 -0
- data/lib/freight_kit/carriers/d_and_a_transport.rb +10 -0
- data/lib/freight_kit/carriers/dak_transport.rb +10 -0
- data/lib/freight_kit/carriers/dash_courier_and_logistics_north_carolina.rb +10 -0
- data/lib/freight_kit/carriers/daylight_transport.rb +29 -0
- data/lib/freight_kit/carriers/dayton_freight_lines.rb +30 -0
- data/lib/freight_kit/carriers/dbr_logistics.rb +10 -0
- data/lib/freight_kit/carriers/deep_south_freight.rb +27 -0
- data/lib/freight_kit/carriers/delta_express.rb +10 -0
- data/lib/freight_kit/carriers/delta_transport.rb +10 -0
- data/lib/freight_kit/carriers/delta_trucking_logistics.rb +10 -0
- data/lib/freight_kit/carriers/demco_express.rb +10 -0
- data/lib/freight_kit/carriers/dependable_global_express.rb +10 -0
- data/lib/freight_kit/carriers/dependable_hawaiian_express.rb +24 -0
- data/lib/freight_kit/carriers/dependable_highway_express.rb +573 -0
- data/lib/freight_kit/carriers/desert_coastal_transport.rb +10 -0
- data/lib/freight_kit/carriers/dhl.rb +11 -0
- data/lib/freight_kit/carriers/diamond_line_delivery.rb +174 -0
- data/lib/freight_kit/carriers/ding_tai_trucking.rb +10 -0
- data/lib/freight_kit/carriers/diversified_transfer_and_storage.rb +29 -0
- data/lib/freight_kit/carriers/dohrn_transfer_company.rb +30 -0
- data/lib/freight_kit/carriers/dot_line_transportation.rb +29 -0
- data/lib/freight_kit/carriers/drt_transportation.rb +13 -0
- data/lib/freight_kit/carriers/dugan_truck_line.rb +29 -0
- data/lib/freight_kit/carriers/dupont.rb +10 -0
- data/lib/freight_kit/carriers/e_transport_carriers.rb +29 -0
- data/lib/freight_kit/carriers/echo_global_logistics.rb +13 -0
- data/lib/freight_kit/carriers/ecklund_logistics.rb +10 -0
- data/lib/freight_kit/carriers/el_emplumado_transport.rb +10 -0
- data/lib/freight_kit/carriers/elite_carriers.rb +28 -0
- data/lib/freight_kit/carriers/emerald_express.rb +10 -0
- data/lib/freight_kit/carriers/era_transport.rb +10 -0
- data/lib/freight_kit/carriers/estes_express_lines.rb +25 -0
- data/lib/freight_kit/carriers/euro_kam.rb +28 -0
- data/lib/freight_kit/carriers/ew_riverside_trucking.rb +10 -0
- data/lib/freight_kit/carriers/express_2000_inc.rb +12 -0
- data/lib/freight_kit/carriers/express_services_international.rb +10 -0
- data/lib/freight_kit/carriers/f_and_a_express.rb +27 -0
- data/lib/freight_kit/carriers/fairmont_logistics.rb +13 -0
- data/lib/freight_kit/carriers/fargo_cargo.rb +10 -0
- data/lib/freight_kit/carriers/fast_freight_transportation.rb +10 -0
- data/lib/freight_kit/carriers/fast_load_transport.rb +10 -0
- data/lib/freight_kit/carriers/fed_ex_express.rb +30 -0
- data/lib/freight_kit/carriers/fed_ex_ground.rb +24 -0
- data/lib/freight_kit/carriers/fed_ex_ltl_economy.rb +11 -0
- data/lib/freight_kit/carriers/fed_ex_ltl_priority.rb +11 -0
- data/lib/freight_kit/carriers/first_trucking_express.rb +10 -0
- data/lib/freight_kit/carriers/flash_trucking.rb +10 -0
- data/lib/freight_kit/carriers/fort_transportation_and_service_company_inc.rb +37 -0
- data/lib/freight_kit/carriers/forward_air.rb +781 -0
- data/lib/freight_kit/carriers/frahtex.rb +10 -0
- data/lib/freight_kit/carriers/frozen_food_express.rb +10 -0
- data/lib/freight_kit/carriers/gholia_bros_trucking.rb +36 -0
- data/lib/freight_kit/carriers/global_cargo.rb +10 -0
- data/lib/freight_kit/carriers/global_logistics_and_transportation.rb +10 -0
- data/lib/freight_kit/carriers/gls_freight.rb +32 -0
- data/lib/freight_kit/carriers/go_trucking_services.rb +10 -0
- data/lib/freight_kit/carriers/gold_eagle_transportation.rb +11 -0
- data/lib/freight_kit/carriers/golden_drop_trucking.rb +10 -0
- data/lib/freight_kit/carriers/gonzalez_transportation.rb +10 -0
- data/lib/freight_kit/carriers/gps_transport.rb +10 -0
- data/lib/freight_kit/carriers/greene_enterprise.rb +10 -0
- data/lib/freight_kit/carriers/gsa_international.rb +10 -0
- data/lib/freight_kit/carriers/gsp_express.rb +24 -0
- data/lib/freight_kit/carriers/gsv_transportation.rb +10 -0
- data/lib/freight_kit/carriers/gta_transportation.rb +10 -0
- data/lib/freight_kit/carriers/guam_freight_services.rb +10 -0
- data/lib/freight_kit/carriers/harrah_transportation.rb +23 -0
- data/lib/freight_kit/carriers/her_trucking.rb +10 -0
- data/lib/freight_kit/carriers/hercules_freight.rb +20 -0
- data/lib/freight_kit/carriers/highlander_xpress.rb +36 -0
- data/lib/freight_kit/carriers/hn_transport.rb +10 -0
- data/lib/freight_kit/carriers/honolulu_freight_service.rb +10 -0
- data/lib/freight_kit/carriers/hot_line_freight_system_inc.rb +12 -0
- data/lib/freight_kit/carriers/hotshot_freight_of_texas.rb +13 -0
- data/lib/freight_kit/carriers/houser_transport.rb +27 -0
- data/lib/freight_kit/carriers/infiniti_freight_logistics.rb +28 -0
- data/lib/freight_kit/carriers/infinity_trucking.rb +10 -0
- data/lib/freight_kit/carriers/interstate_tma.rb +10 -0
- data/lib/freight_kit/carriers/intrade_industries.rb +10 -0
- data/lib/freight_kit/carriers/jasper_trucking.rb +28 -0
- data/lib/freight_kit/carriers/jb_hunt.rb +11 -0
- data/lib/freight_kit/carriers/jfj_transportation.rb +8 -8
- data/lib/freight_kit/carriers/jkb_express.rb +10 -0
- data/lib/freight_kit/carriers/jlm_transport.rb +10 -0
- data/lib/freight_kit/carriers/johansson_transport.rb +10 -0
- data/lib/freight_kit/carriers/jones_express.rb +10 -0
- data/lib/freight_kit/carriers/jp_logistics.rb +41 -0
- data/lib/freight_kit/carriers/just_in_time_cargo.rb +29 -0
- data/lib/freight_kit/carriers/kengkok_times.rb +10 -0
- data/lib/freight_kit/carriers/kings_express.rb +10 -0
- data/lib/freight_kit/carriers/klc_transportation.rb +10 -0
- data/lib/freight_kit/carriers/km_trucking.rb +10 -0
- data/lib/freight_kit/carriers/kma_logistics.rb +10 -0
- data/lib/freight_kit/carriers/krc_logistics.rb +10 -0
- data/lib/freight_kit/carriers/ktx.rb +10 -0
- data/lib/freight_kit/carriers/landstar.rb +25 -0
- data/lib/freight_kit/carriers/lanter_distributing_llc.rb +30 -0
- data/lib/freight_kit/carriers/ld_trucking.rb +10 -0
- data/lib/freight_kit/carriers/legacy_logistics_solutions.rb +10 -0
- data/lib/freight_kit/carriers/leonards_express.rb +10 -0
- data/lib/freight_kit/carriers/liberty_linehaul_west.rb +28 -0
- data/lib/freight_kit/carriers/liberty_transport.rb +10 -0
- data/lib/freight_kit/carriers/lightning_express.rb +10 -0
- data/lib/freight_kit/carriers/lj_express.rb +24 -0
- data/lib/freight_kit/carriers/lkp_enterprises.rb +10 -0
- data/lib/freight_kit/carriers/ltl_pros.rb +28 -0
- data/lib/freight_kit/carriers/m_and_m_and_sons.rb +10 -0
- data/lib/freight_kit/carriers/mag_lines_transport.rb +10 -0
- data/lib/freight_kit/carriers/magic_messenger.rb +24 -0
- data/lib/freight_kit/carriers/majors_transit.rb +10 -0
- data/lib/freight_kit/carriers/map_global_logistics.rb +10 -0
- data/lib/freight_kit/carriers/matths_trucking.rb +11 -0
- data/lib/freight_kit/carriers/mav_canadian_transport.rb +13 -0
- data/lib/freight_kit/carriers/mc_systems.rb +35 -0
- data/lib/freight_kit/carriers/mega_fleet.rb +10 -0
- data/lib/freight_kit/carriers/mega_trans_group.rb +28 -0
- data/lib/freight_kit/carriers/meta_express.rb +10 -0
- data/lib/freight_kit/carriers/mia_transportation.rb +10 -0
- data/lib/freight_kit/carriers/midwest_motor_express.rb +14 -0
- data/lib/freight_kit/carriers/midwest_transport_and_trucking.rb +10 -0
- data/lib/freight_kit/carriers/mikade_delivery_service.rb +10 -0
- data/lib/freight_kit/carriers/mohoff_freight_lines.rb +23 -0
- data/lib/freight_kit/carriers/montata_travelers_express.rb +10 -0
- data/lib/freight_kit/carriers/morgan_van_lines.rb +29 -0
- data/lib/freight_kit/carriers/moto_transportation.rb +24 -0
- data/lib/freight_kit/carriers/mountain_valley_express.rb +197 -0
- data/lib/freight_kit/carriers/ms_freight.rb +27 -0
- data/lib/freight_kit/carriers/mvg_transport.rb +10 -0
- data/lib/freight_kit/carriers/n_and_m_transfer_co_inc.rb +29 -0
- data/lib/freight_kit/carriers/nabot_transport_solutions.rb +10 -0
- data/lib/freight_kit/carriers/national_freight_xpress.rb +10 -0
- data/lib/freight_kit/carriers/navigation_group.rb +10 -0
- data/lib/freight_kit/carriers/nelson_trucking.rb +10 -0
- data/lib/freight_kit/carriers/network_1_transportation.rb +10 -0
- data/lib/freight_kit/carriers/new_century_transport.rb +28 -0
- data/lib/freight_kit/carriers/new_penn_motor_express.rb +11 -0
- data/lib/freight_kit/carriers/nieves_transportation.rb +10 -0
- data/lib/freight_kit/carriers/nolan_transportation_group.rb +26 -0
- data/lib/freight_kit/carriers/northland_trucking.rb +10 -0
- data/lib/freight_kit/carriers/northwest_carrier_logistics.rb +27 -0
- data/lib/freight_kit/carriers/nt_usa.rb +10 -0
- data/lib/freight_kit/carriers/nu_line_transportation.rb +10 -0
- data/lib/freight_kit/carriers/numark_transportation.rb +80 -0
- data/lib/freight_kit/carriers/nvk_transport.rb +10 -0
- data/lib/freight_kit/carriers/ny_transport.rb +10 -0
- data/lib/freight_kit/carriers/oak_harbor.rb +28 -0
- data/lib/freight_kit/carriers/oakline_transportation.rb +10 -0
- data/lib/freight_kit/carriers/old_dominion_freight_line.rb +30 -0
- data/lib/freight_kit/carriers/on_trac.rb +555 -0
- data/lib/freight_kit/carriers/one_hundred_one_transport.rb +10 -0
- data/lib/freight_kit/carriers/one_way_delivery.rb +10 -0
- data/lib/freight_kit/carriers/oracle_transportation_solutions.rb +10 -0
- data/lib/freight_kit/carriers/orange_courier.rb +27 -0
- data/lib/freight_kit/carriers/ortas_trucking.rb +10 -0
- data/lib/freight_kit/carriers/pac_trux_transportation.rb +10 -0
- data/lib/freight_kit/carriers/pacer.rb +10 -0
- data/lib/freight_kit/carriers/pacific_logistics.rb +10 -0
- data/lib/freight_kit/carriers/pacific_states_truck_lines.rb +10 -0
- data/lib/freight_kit/carriers/paradise_distributing.rb +10 -0
- data/lib/freight_kit/carriers/paramount_freight_systems.rb +10 -0
- data/lib/freight_kit/carriers/peninsula_truck_lines.rb +206 -0
- data/lib/freight_kit/carriers/pg_transport.rb +10 -0
- data/lib/freight_kit/carriers/pgs_360.rb +10 -0
- data/lib/freight_kit/carriers/pilot_freight_services.rb +10 -0
- data/lib/freight_kit/carriers/pious_trans.rb +27 -0
- data/lib/freight_kit/carriers/pitt_ohio_express.rb +30 -0
- data/lib/freight_kit/carriers/pki_logistics.rb +12 -0
- data/lib/freight_kit/carriers/plana_transportation.rb +28 -0
- data/lib/freight_kit/carriers/prestige.rb +10 -0
- data/lib/freight_kit/carriers/pro_trans_solutions.rb +28 -0
- data/lib/freight_kit/carriers/puma_logistics.rb +10 -0
- data/lib/freight_kit/carriers/pwc_international.rb +10 -0
- data/lib/freight_kit/carriers/quality_logistics.rb +10 -0
- data/lib/freight_kit/carriers/queen_star_trucking.rb +27 -0
- data/lib/freight_kit/carriers/r_and_l_carriers.rb +11 -0
- data/lib/freight_kit/carriers/rac_transport.rb +10 -0
- data/lib/freight_kit/carriers/re_logistics.rb +23 -0
- data/lib/freight_kit/carriers/reddaway.rb +11 -0
- data/lib/freight_kit/carriers/reefer_van_network.rb +13 -0
- data/lib/freight_kit/carriers/refrigerated_trucking_and_ltl_transportation_services.rb +10 -0
- data/lib/freight_kit/carriers/ridgeline_express.rb +10 -0
- data/lib/freight_kit/carriers/rist_transport.rb +29 -0
- data/lib/freight_kit/carriers/river_city_transport.rb +10 -0
- data/lib/freight_kit/carriers/roadrunner_transportation_services.rb +669 -0
- data/lib/freight_kit/carriers/roadtex.rb +13 -0
- data/lib/freight_kit/carriers/ronald_transport_services.rb +10 -0
- data/lib/freight_kit/carriers/rose_trucking.rb +24 -0
- data/lib/freight_kit/carriers/rp_and_j_transport.rb +24 -0
- data/lib/freight_kit/carriers/rpm_transportation.rb +11 -0
- data/lib/freight_kit/carriers/rude_transportation.rb +30 -0
- data/lib/freight_kit/carriers/s_and_s_logistics.rb +10 -0
- data/lib/freight_kit/carriers/saia.rb +456 -362
- data/lib/freight_kit/carriers/sb_transportation.rb +27 -0
- data/lib/freight_kit/carriers/schneider_national.rb +29 -0
- data/lib/freight_kit/carriers/schwarz_trucking.rb +10 -0
- data/lib/freight_kit/carriers/sewell_motor_express.rb +29 -0
- data/lib/freight_kit/carriers/shawnee_trucking.rb +28 -0
- data/lib/freight_kit/carriers/shi_logistics.rb +10 -0
- data/lib/freight_kit/carriers/sinbad_transport.rb +10 -0
- data/lib/freight_kit/carriers/skyway.rb +10 -0
- data/lib/freight_kit/carriers/smith_cargo_transportation_services.rb +23 -0
- data/lib/freight_kit/carriers/sna_transportation.rb +10 -0
- data/lib/freight_kit/carriers/solid_group.rb +10 -0
- data/lib/freight_kit/carriers/solution_carrier_express.rb +10 -0
- data/lib/freight_kit/carriers/southeastern_freight_lines.rb +441 -0
- data/lib/freight_kit/carriers/southwestern_motor_transport.rb +30 -0
- data/lib/freight_kit/carriers/span_alaska.rb +10 -0
- data/lib/freight_kit/carriers/specialize_transportation.rb +27 -0
- data/lib/freight_kit/carriers/ssi_refrigerated_express.rb +10 -0
- data/lib/freight_kit/carriers/standard_forwarding_llc.rb +28 -0
- data/lib/freight_kit/carriers/star_american_enterprise.rb +10 -0
- data/lib/freight_kit/carriers/sterling_transportation.rb +10 -0
- data/lib/freight_kit/carriers/stg.rb +163 -0
- data/lib/freight_kit/carriers/supervan_service.rb +10 -0
- data/lib/freight_kit/carriers/sutton_transport_inc.rb +12 -0
- data/lib/freight_kit/carriers/swift_transportation.rb +28 -0
- data/lib/freight_kit/carriers/t_force_worldwide.rb +605 -0
- data/lib/freight_kit/carriers/tax_airfreight_inc.rb +35 -0
- data/lib/freight_kit/carriers/tforce_freight_inc.rb +30 -0
- data/lib/freight_kit/carriers/the_custom_companies.rb +162 -0
- data/lib/freight_kit/carriers/thk_trucking.rb +28 -0
- data/lib/freight_kit/carriers/tiger_cool_express.rb +11 -0
- data/lib/freight_kit/carriers/tili_logistics.rb +10 -0
- data/lib/freight_kit/carriers/tmt_industries.rb +10 -0
- data/lib/freight_kit/carriers/top_ten_express.rb +28 -0
- data/lib/freight_kit/carriers/total_quality_logistics.rb +339 -0
- data/lib/freight_kit/carriers/total_transportation.rb +258 -0
- data/lib/freight_kit/carriers/trans_international_trucking.rb +29 -0
- data/lib/freight_kit/carriers/treasure_transportation.rb +10 -0
- data/lib/freight_kit/carriers/tri_state_services.rb +10 -0
- data/lib/freight_kit/carriers/tritex_freighters.rb +10 -0
- data/lib/freight_kit/carriers/triways.rb +10 -0
- data/lib/freight_kit/carriers/tsi_kansas.rb +29 -0
- data/lib/freight_kit/carriers/u_and_r_transportation.rb +23 -0
- data/lib/freight_kit/carriers/union_pacific.rb +11 -0
- data/lib/freight_kit/carriers/united_freight_logistics.rb +10 -0
- data/lib/freight_kit/carriers/unlimited_distance_transportation.rb +10 -0
- data/lib/freight_kit/carriers/up_streamline.rb +10 -0
- data/lib/freight_kit/carriers/ups_freight.rb +12 -0
- data/lib/freight_kit/carriers/us_freightways.rb +10 -0
- data/lib/freight_kit/carriers/usa_truck.rb +28 -0
- data/lib/freight_kit/carriers/usf_holland.rb +11 -0
- data/lib/freight_kit/carriers/valley_cartage.rb +11 -0
- data/lib/freight_kit/carriers/vc_transport.rb +10 -0
- data/lib/freight_kit/carriers/vision_express.rb +11 -0
- data/lib/freight_kit/carriers/vision_logistics_group.rb +10 -0
- data/lib/freight_kit/carriers/vmg_transportation_group.rb +10 -0
- data/lib/freight_kit/carriers/volpe_express.rb +10 -0
- data/lib/freight_kit/carriers/ward_trucking.rb +29 -0
- data/lib/freight_kit/carriers/wdwb.rb +10 -0
- data/lib/freight_kit/carriers/western_flyer_express.rb +28 -0
- data/lib/freight_kit/carriers/western_regional_delivery_service.rb +265 -0
- data/lib/freight_kit/carriers/western_specialized_trucking.rb +22 -0
- data/lib/freight_kit/carriers/win_distribution.rb +28 -0
- data/lib/freight_kit/carriers/wlb_transport.rb +10 -0
- data/lib/freight_kit/carriers/x_trux.rb +29 -0
- data/lib/freight_kit/carriers/xpo_logistics.rb +415 -0
- data/lib/freight_kit/carriers/xpress_global_systems.rb +30 -0
- data/lib/freight_kit/carriers/xylo_trucking.rb +10 -0
- data/lib/freight_kit/carriers/yrc_freight.rb +24 -0
- data/lib/freight_kit/carriers/zentner_transportation.rb +28 -0
- data/lib/freight_kit/carriers.rb +331 -34
- data/lib/freight_kit/countries.rb +22 -0
- data/lib/freight_kit/error.rb +0 -2
- data/lib/freight_kit/errors/document_not_found_error.rb +0 -2
- data/lib/freight_kit/errors/expired_credentials_error.rb +0 -2
- data/lib/freight_kit/errors/http_error.rb +0 -2
- data/lib/freight_kit/errors/invalid_credentials_error.rb +0 -2
- data/lib/freight_kit/errors/rate_limit_error.rb +12 -0
- data/lib/freight_kit/errors/response_error.rb +0 -2
- data/lib/freight_kit/errors/shipment_not_found_error.rb +0 -2
- data/lib/freight_kit/errors/unserviceable_accessorials_error.rb +1 -5
- data/lib/freight_kit/errors/unserviceable_error.rb +0 -2
- data/lib/freight_kit/helpers/documentable.rb +0 -2
- data/lib/freight_kit/helpers/pickupable.rb +3 -14
- data/lib/freight_kit/helpers/rateable.rb +0 -2
- data/lib/freight_kit/helpers/trackable.rb +0 -2
- data/lib/freight_kit/http_client/cache_store.rb +2 -4
- data/lib/freight_kit/http_client/httpi_adapter.rb +37 -0
- data/lib/freight_kit/http_client/log_device.rb +0 -2
- data/lib/freight_kit/http_client/response.rb +0 -2
- data/lib/freight_kit/http_client/revalidation.rb +0 -2
- data/lib/freight_kit/http_client/safe_retries.rb +17 -3
- data/lib/freight_kit/http_client/zstd.rb +2 -4
- data/lib/freight_kit/http_client.rb +21 -21
- data/lib/freight_kit/model.rb +1 -3
- data/lib/freight_kit/models/address.rb +15 -0
- data/lib/freight_kit/models/contact.rb +3 -4
- data/lib/freight_kit/models/country.rb +20 -0
- data/lib/freight_kit/models/credential.rb +3 -18
- data/lib/freight_kit/models/date_time.rb +0 -2
- data/lib/freight_kit/models/document_response.rb +0 -2
- data/lib/freight_kit/models/label.rb +0 -2
- data/lib/freight_kit/models/location.rb +10 -25
- data/lib/freight_kit/models/pickup_response.rb +0 -2
- data/lib/freight_kit/models/price.rb +0 -2
- data/lib/freight_kit/models/rate.rb +0 -2
- data/lib/freight_kit/models/rate_response.rb +0 -2
- data/lib/freight_kit/models/region.rb +19 -0
- data/lib/freight_kit/models/response.rb +0 -2
- data/lib/freight_kit/models/shipment.rb +5 -14
- data/lib/freight_kit/models/shipment_event.rb +0 -2
- data/lib/freight_kit/models/terminal.rb +10 -0
- data/lib/freight_kit/models/tracking_response.rb +0 -2
- data/lib/freight_kit/package.rb +52 -64
- data/lib/freight_kit/package_item.rb +14 -14
- data/lib/freight_kit/packaging.rb +6 -26
- data/lib/freight_kit/platform.rb +0 -32
- data/lib/freight_kit/platforms/carrier_logistics.rb +326 -345
- data/lib/freight_kit/platforms/dsdc.rb +82 -0
- data/lib/freight_kit/platforms/next_tms/graphql_client/mutation/quote_create.rb +32 -0
- data/lib/freight_kit/platforms/next_tms/graphql_client/mutation/shipment_create.rb +29 -0
- data/lib/freight_kit/platforms/next_tms/graphql_client/query/broker_carrier.rb +37 -0
- data/lib/freight_kit/platforms/next_tms/graphql_client/query/broker_carriers.rb +45 -0
- data/lib/freight_kit/platforms/next_tms/graphql_client/query/broker_customer.rb +54 -0
- data/lib/freight_kit/platforms/next_tms/graphql_client/query/broker_customers.rb +62 -0
- data/lib/freight_kit/platforms/next_tms/graphql_client/query/carrier.rb +22 -0
- data/lib/freight_kit/platforms/next_tms/graphql_client/query/carriers.rb +30 -0
- data/lib/freight_kit/platforms/next_tms/graphql_client/query/customer.rb +20 -0
- data/lib/freight_kit/platforms/next_tms/graphql_client/query/customers.rb +28 -0
- data/lib/freight_kit/platforms/next_tms/graphql_client/query/invoice.rb +31 -0
- data/lib/freight_kit/platforms/next_tms/graphql_client/query/invoices.rb +39 -0
- data/lib/freight_kit/platforms/next_tms/graphql_client/query/shipment.rb +102 -0
- data/lib/freight_kit/platforms/next_tms/graphql_client/query/shipment_documents.rb +29 -0
- data/lib/freight_kit/platforms/next_tms/graphql_client/query/shipments.rb +110 -0
- data/lib/freight_kit/platforms/next_tms/graphql_client.rb +22 -0
- data/lib/freight_kit/platforms/next_tms/orm/address.rb +22 -0
- data/lib/freight_kit/platforms/next_tms/orm/base.rb +120 -0
- data/lib/freight_kit/platforms/next_tms/orm/broker_carrier.rb +18 -0
- data/lib/freight_kit/platforms/next_tms/orm/broker_customer.rb +22 -0
- data/lib/freight_kit/platforms/next_tms/orm/carrier.rb +14 -0
- data/lib/freight_kit/platforms/next_tms/orm/collection.rb +335 -0
- data/lib/freight_kit/platforms/next_tms/orm/customer.rb +12 -0
- data/lib/freight_kit/platforms/next_tms/orm/invoice.rb +21 -0
- data/lib/freight_kit/platforms/next_tms/orm/record_not_found_error.rb +9 -0
- data/lib/freight_kit/platforms/next_tms/orm/shipment.rb +50 -0
- data/lib/freight_kit/platforms/next_tms/orm.rb +38 -0
- data/lib/freight_kit/platforms/next_tms.rb +452 -0
- data/lib/freight_kit/platforms/the_great_information_factory.rb +492 -425
- data/lib/freight_kit/regions.rb +27 -0
- data/lib/freight_kit/shipment_packer.rb +36 -38
- data/lib/freight_kit/tariff/overlength_rule.rb +1 -5
- data/lib/freight_kit/tariff.rb +0 -2
- data/lib/freight_kit.rb +103 -11
- data/schemas/next_tms.json +110710 -0
- metadata +443 -55
- data/configuration/carriers/abfs.yml +0 -124
- data/configuration/carriers/btvp.yml +0 -84
- data/configuration/carriers/ccyq.yml +0 -121
- data/configuration/carriers/clni.yml +0 -113
- data/configuration/carriers/cnwy.yml +0 -113
- data/configuration/carriers/ctbv.yml +0 -117
- data/configuration/carriers/dcha.yml +0 -105
- data/configuration/carriers/dlds.yml +0 -111
- data/configuration/carriers/dphe.yml +0 -130
- data/configuration/carriers/drrq.yml +0 -131
- data/configuration/carriers/fcsy.yml +0 -102
- data/configuration/carriers/fwda.yml +0 -137
- data/configuration/carriers/jfj_transportation.yml +0 -2
- data/configuration/carriers/mtvl.yml +0 -12
- data/configuration/carriers/numk.yml +0 -14
- data/configuration/carriers/otcl.yml +0 -124
- data/configuration/carriers/pens.yml +0 -22
- data/configuration/carriers/rdfs.yml +0 -142
- data/configuration/carriers/saia.yml +0 -129
- data/configuration/carriers/sefl.yml +0 -115
- data/configuration/carriers/totl.yml +0 -111
- data/configuration/carriers/tqyl.yml +0 -28
- data/configuration/carriers/wrds.yml +0 -20
- data/configuration/platforms/carrier_logistics.yml +0 -25
- data/configuration/platforms/next.yml +0 -12
- data/configuration/platforms/the_great_information_factory.yml +0 -122
- data/lib/freight_kit/carriers/abfs.rb +0 -421
- data/lib/freight_kit/carriers/btvp.rb +0 -29
- data/lib/freight_kit/carriers/ccyq.rb +0 -310
- data/lib/freight_kit/carriers/clni.rb +0 -396
- data/lib/freight_kit/carriers/cnwy.rb +0 -327
- data/lib/freight_kit/carriers/ctbv.rb +0 -53
- data/lib/freight_kit/carriers/dcha.rb +0 -76
- data/lib/freight_kit/carriers/dlds.rb +0 -49
- data/lib/freight_kit/carriers/dphe.rb +0 -472
- data/lib/freight_kit/carriers/drrq.rb +0 -580
- data/lib/freight_kit/carriers/fcsy.rb +0 -57
- data/lib/freight_kit/carriers/fwda.rb +0 -744
- data/lib/freight_kit/carriers/mtvl.rb +0 -34
- data/lib/freight_kit/carriers/numk.rb +0 -58
- data/lib/freight_kit/carriers/otcl.rb +0 -520
- data/lib/freight_kit/carriers/pens.rb +0 -204
- data/lib/freight_kit/carriers/rdfs.rb +0 -521
- data/lib/freight_kit/carriers/sefl.rb +0 -342
- data/lib/freight_kit/carriers/totl.rb +0 -172
- data/lib/freight_kit/carriers/tqyl.rb +0 -337
- data/lib/freight_kit/carriers/wrds.rb +0 -246
- data/lib/freight_kit/platforms/next.rb +0 -101
data/lib/freight_kit/carrier.rb
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
1
|
module FreightKit
|
|
4
2
|
# Carrier is the abstract base class for all supported carriers.
|
|
5
3
|
#
|
|
@@ -7,7 +5,6 @@ module FreightKit
|
|
|
7
5
|
# implement all the methods that the carrier supports.
|
|
8
6
|
#
|
|
9
7
|
# @see #create_pickup
|
|
10
|
-
# @see #cancel_shipment
|
|
11
8
|
# @see #find_tracking_info
|
|
12
9
|
# @see #find_rates
|
|
13
10
|
#
|
|
@@ -16,32 +13,45 @@ module FreightKit
|
|
|
16
13
|
# @see #save_request
|
|
17
14
|
class Carrier
|
|
18
15
|
class << self
|
|
16
|
+
# Whether the carrier is a broker that hands shipments to other carriers.
|
|
17
|
+
# @return [Boolean]
|
|
18
|
+
def acts_as_broker? = false
|
|
19
|
+
|
|
19
20
|
# Whether bill of lading (BOL) requires tracking number at time of pickup.
|
|
20
21
|
# @return [Boolean]
|
|
21
|
-
def bol_requires_tracking_number?
|
|
22
|
-
false
|
|
23
|
-
end
|
|
22
|
+
def bol_requires_tracking_number? = false
|
|
24
23
|
|
|
25
|
-
# The
|
|
26
|
-
# @return [FreightKit::
|
|
27
|
-
def
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
24
|
+
# The carrier's addresses for mailing checks, so applications need not enter them for each customer.
|
|
25
|
+
# @return [Array<FreightKit::Address>]
|
|
26
|
+
def check_mailing_addresses = []
|
|
27
|
+
|
|
28
|
+
# Whether the carrier's bill of lading (BOL) and proof of delivery (POD) are the same document.
|
|
29
|
+
# @return [Boolean]
|
|
30
|
+
def consider_bol_and_pod_documents_same? = false
|
|
31
|
+
|
|
32
|
+
# The carrier's department contacts, so applications need not enter them for each customer.
|
|
33
|
+
# @return [Array<FreightKit::Contact>]
|
|
34
|
+
def contacts = []
|
|
35
|
+
|
|
36
|
+
# Whether {#create_pickup} is implemented.
|
|
37
|
+
# @return [Boolean]
|
|
38
|
+
def create_pickup_implemented? = implemented?(:create_pickup)
|
|
39
|
+
|
|
40
|
+
# Whether {#find_rates} is implemented.
|
|
41
|
+
# @return [Boolean]
|
|
42
|
+
def find_rates_implemented? = implemented?(:find_rates)
|
|
39
43
|
|
|
40
44
|
# Whether finding rates with declared value (thus insurance) is implemented.
|
|
41
45
|
# @return [Boolean]
|
|
42
|
-
def find_rates_with_declared_value?
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
def find_rates_with_declared_value? = false
|
|
47
|
+
|
|
48
|
+
# The carrier's main office, from its public FMCSA registration.
|
|
49
|
+
# @return [FreightKit::Address, nil]
|
|
50
|
+
def headquarters = nil
|
|
51
|
+
|
|
52
|
+
# The carrier's permanent UUID. Applications store it to refer to the carrier, so never change or reuse one.
|
|
53
|
+
# @return [String]
|
|
54
|
+
def id = nil
|
|
45
55
|
|
|
46
56
|
# Whether instance method is supported
|
|
47
57
|
# @return [Boolean]
|
|
@@ -51,53 +61,111 @@ module FreightKit
|
|
|
51
61
|
false
|
|
52
62
|
end
|
|
53
63
|
|
|
54
|
-
# The
|
|
55
|
-
#
|
|
56
|
-
|
|
57
|
-
|
|
64
|
+
# The carrier's registered legal name, with its entity suffix (e.g. "Saia Motor Freight Line LLC"), when known.
|
|
65
|
+
# {.name} is the name the carrier does business as.
|
|
66
|
+
# @return [String, nil]
|
|
67
|
+
def legal_name = nil
|
|
68
|
+
|
|
69
|
+
# The package's longest horizontal dimension (length or width), as a
|
|
70
|
+
# Measured::Length so comparisons stay unit-agnostic.
|
|
71
|
+
#
|
|
72
|
+
# @param package [FreightKit::Package]
|
|
73
|
+
# @return [Measured::Length]
|
|
74
|
+
def longest_dimension(package)
|
|
75
|
+
[Measured::Length.new(package.length(:inches), :inches), Measured::Length.new(package.width(:inches), :inches)].max
|
|
58
76
|
end
|
|
59
77
|
|
|
78
|
+
# FreightKit accessorials the carrier prices, mapped to the carrier's codes.
|
|
79
|
+
# @return [Hash{Symbol => Object}]
|
|
80
|
+
def mappable_accessorials = {}
|
|
81
|
+
|
|
60
82
|
# The maximum height the carrier will accept.
|
|
61
83
|
# @return [Measured::Length]
|
|
62
|
-
def maximum_height
|
|
63
|
-
Measured::Length.new(105, :inches)
|
|
64
|
-
end
|
|
84
|
+
def maximum_height = Measured::Length.new(105, :inches)
|
|
65
85
|
|
|
66
86
|
# The maximum weight the carrier will accept.
|
|
67
87
|
# @return [Measured::Weight]
|
|
68
|
-
def maximum_weight
|
|
69
|
-
Measured::Weight.new(10_000, :pounds)
|
|
70
|
-
end
|
|
88
|
+
def maximum_weight = Measured::Weight.new(10_000, :pounds)
|
|
71
89
|
|
|
72
90
|
# What length overlength fees the carrier begins charging at.
|
|
73
91
|
# @return [Measured::Length]
|
|
74
|
-
def minimum_length_for_overlength_fees
|
|
75
|
-
|
|
92
|
+
def minimum_length_for_overlength_fees = Measured::Length.new(48, :inches)
|
|
93
|
+
|
|
94
|
+
# @param package [FreightKit::Package]
|
|
95
|
+
# @return [Boolean] whether the package is long enough to incur overlength fees.
|
|
96
|
+
def overlength?(package) = longest_dimension(package) >= minimum_length_for_overlength_fees
|
|
97
|
+
|
|
98
|
+
def overlength_fee(tariff, package)
|
|
99
|
+
overlength_rule = overlength_rule_for(tariff, package)
|
|
100
|
+
return 0 if overlength_rule.nil?
|
|
101
|
+
|
|
102
|
+
package.quantity * overlength_rule.fee_cents
|
|
76
103
|
end
|
|
77
104
|
|
|
78
105
|
# Whether or not the carrier quotes overlength fees via API.
|
|
79
106
|
# @note Should the API not calculate these fees, they should be calculated some other way outside of FreightKit.
|
|
80
107
|
# @return [Boolean]
|
|
81
|
-
def overlength_fees_require_tariff?
|
|
82
|
-
|
|
108
|
+
def overlength_fees_require_tariff? = true
|
|
109
|
+
|
|
110
|
+
# Returns the overlength rule from +tariff+ that applies to +package+, or
|
|
111
|
+
# +nil+ when the package is not overlength, or no configured rule covers it.
|
|
112
|
+
#
|
|
113
|
+
# This is the single source of truth for "does a rule cover this package?"
|
|
114
|
+
# shared by {#overlength_fee} and {#validate_packages} so the two can never
|
|
115
|
+
# disagree (e.g. a package quoting $0 overlength while also being treated as
|
|
116
|
+
# serviceable).
|
|
117
|
+
#
|
|
118
|
+
# @param tariff [FreightKit::Tariff, nil]
|
|
119
|
+
# @param package [FreightKit::Package]
|
|
120
|
+
# @return [FreightKit::Tariff::OverlengthRule, nil]
|
|
121
|
+
def overlength_rule_for(tariff, package)
|
|
122
|
+
return unless tariff.is_a?(FreightKit::Tariff) && overlength?(package)
|
|
123
|
+
|
|
124
|
+
tariff.overlength_rules.find { |overlength_rule| overlength_rule.cover?(longest_dimension(package)) }
|
|
83
125
|
end
|
|
84
126
|
|
|
85
127
|
# Whether carrier considers pickup number the same as the tracking number.
|
|
86
|
-
def pickup_number_is_tracking_number?
|
|
87
|
-
|
|
88
|
-
|
|
128
|
+
def pickup_number_is_tracking_number? = false
|
|
129
|
+
|
|
130
|
+
# Whether the rates the carrier's API returns include excessive length fees. Carriers without rates, or that need
|
|
131
|
+
# a tariff to price overlength fees, return rates without them.
|
|
132
|
+
# @return [Boolean]
|
|
133
|
+
def rates_with_excessive_length_fees? = find_rates_implemented? && requirements.exclude?(:tariff)
|
|
134
|
+
|
|
135
|
+
# Returns the `Credential` methods (passed to `#initialize`) that cannot respond with blank values.
|
|
136
|
+
# @return [Array<Symbol>]
|
|
137
|
+
def required_credential_types = []
|
|
89
138
|
|
|
90
139
|
# Returns the keywords passed to `#initialize` that cannot be blank.
|
|
91
140
|
# @return [Array<Symbol>]
|
|
92
|
-
def requirements
|
|
93
|
-
|
|
141
|
+
def requirements = []
|
|
142
|
+
|
|
143
|
+
# @return [String, nil]
|
|
144
|
+
def scac = nil
|
|
145
|
+
|
|
146
|
+
# Raises {UnserviceableAccessorialsError} for accessorials the carrier refuses, or that it neither maps nor serves
|
|
147
|
+
# unpriced. Returns false when the carrier maps no accessorials.
|
|
148
|
+
# @return [Boolean]
|
|
149
|
+
def serviceable_accessorials?(accessorials)
|
|
150
|
+
return true if accessorials.blank?
|
|
151
|
+
return false if mappable_accessorials.blank?
|
|
152
|
+
|
|
153
|
+
refused = accessorials.select do |accessorial|
|
|
154
|
+
unserviceable_accessorials.include?(accessorial) ||
|
|
155
|
+
(mappable_accessorials.keys.exclude?(accessorial) && unquotable_accessorials.exclude?(accessorial))
|
|
156
|
+
end
|
|
157
|
+
raise FreightKit::UnserviceableAccessorialsError.new(accessorials: refused) if refused.any?
|
|
158
|
+
|
|
159
|
+
true
|
|
94
160
|
end
|
|
95
161
|
|
|
96
|
-
#
|
|
162
|
+
# The services {#find_rates} quotes (e.g. `:standard`, `:guaranteed_delivery`).
|
|
97
163
|
# @return [Array<Symbol>]
|
|
98
|
-
def
|
|
99
|
-
|
|
100
|
-
|
|
164
|
+
def services = []
|
|
165
|
+
|
|
166
|
+
# The carrier's terminals, so applications need not enter them for each customer.
|
|
167
|
+
# @return [Array<FreightKit::Terminal>]
|
|
168
|
+
def terminals = []
|
|
101
169
|
|
|
102
170
|
# The template URL for tracking one of carrier's `NUMBERS` publicly. A template URL is a URL containing the token
|
|
103
171
|
# "%s" that can be replaced to generate a valid URL.
|
|
@@ -112,11 +180,29 @@ module FreightKit
|
|
|
112
180
|
# @raise [ArgumentError]
|
|
113
181
|
# @return [String, nil] The template URL or nil if no template is available for the given key.
|
|
114
182
|
def tracking_url_template(key)
|
|
115
|
-
raise ArgumentError, "key must be one of: #{NUMBERS.join(
|
|
183
|
+
raise ArgumentError, "key must be one of: #{NUMBERS.join(', ')}" if NUMBERS.exclude?(key)
|
|
116
184
|
|
|
117
|
-
|
|
185
|
+
tracking_url_templates[key]
|
|
118
186
|
end
|
|
119
187
|
|
|
188
|
+
# The template URLs for {.tracking_url_template}, by `NUMBERS` key.
|
|
189
|
+
# @return [Hash{Symbol => String}]
|
|
190
|
+
def tracking_url_templates = {}
|
|
191
|
+
|
|
192
|
+
# FreightKit accessorials the carrier serves but does not price.
|
|
193
|
+
# @return [Array<Symbol>]
|
|
194
|
+
def unquotable_accessorials = []
|
|
195
|
+
|
|
196
|
+
# FreightKit accessorials the carrier refuses.
|
|
197
|
+
# @return [Array<Symbol>]
|
|
198
|
+
def unserviceable_accessorials = []
|
|
199
|
+
|
|
200
|
+
# @return [Integer, nil]
|
|
201
|
+
def us_dot_number = nil
|
|
202
|
+
|
|
203
|
+
# @return [Integer, nil]
|
|
204
|
+
def us_mc_number = nil
|
|
205
|
+
|
|
120
206
|
# Regular expression to use for validating carrier's `NUMBERS`.
|
|
121
207
|
#
|
|
122
208
|
# Returns the regular expression used for validating the carrier's number based on the provided `key`.
|
|
@@ -125,30 +211,85 @@ module FreightKit
|
|
|
125
211
|
# @see `NUMBERS`
|
|
126
212
|
# @param [Symbol] key The symbol representing the carrier number type for which the regular expression is needed.
|
|
127
213
|
# @raise [ArgumentError] Raised if the provided key is not one of the specified carrier number types.
|
|
128
|
-
# @return [Regexp] The regular expression for validating the specified carrier number type.
|
|
214
|
+
# @return [Regexp, nil] The regular expression for validating the specified carrier number type.
|
|
129
215
|
def valid_number_regex(key)
|
|
130
|
-
raise ArgumentError, "key must be one of: #{NUMBERS.join(
|
|
216
|
+
raise ArgumentError, "key must be one of: #{NUMBERS.join(', ')}" if NUMBERS.exclude?(key)
|
|
131
217
|
|
|
132
|
-
|
|
218
|
+
valid_number_regexes[key]
|
|
133
219
|
end
|
|
134
|
-
end
|
|
135
220
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
221
|
+
# The regular expressions for {.valid_number_regex}, by `NUMBERS` key.
|
|
222
|
+
# @return [Hash{Symbol => Regexp}]
|
|
223
|
+
def valid_number_regexes = {}
|
|
224
|
+
|
|
225
|
+
# Determine whether the carrier will accept the packages based on credentials and/or tariff.
|
|
226
|
+
# @param packages [Array<FreightKit::Package>]
|
|
227
|
+
# @param tariff [FreightKit::Tariff]
|
|
228
|
+
# @return [Boolean]
|
|
229
|
+
def validate_packages(packages, tariff = nil)
|
|
230
|
+
return false if packages.blank?
|
|
231
|
+
|
|
232
|
+
message = []
|
|
233
|
+
|
|
234
|
+
max_height_inches = maximum_height.convert_to(:inches).value
|
|
235
|
+
if packages.map { |p| p.height(:inches) }.max > max_height_inches
|
|
236
|
+
message << "items must be #{max_height_inches.to_f} inches tall or less"
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
max_weight_pounds = maximum_weight.convert_to(:pounds).value
|
|
240
|
+
message << "items must weigh #{max_weight_pounds.to_f} lbs or less" if packages.sum { |p| p.pounds(:total) } > max_weight_pounds
|
|
241
|
+
|
|
242
|
+
# Carriers that don't quote overlength fees via their API rely on the
|
|
243
|
+
# tariff to price them. Fail closed rather than silently under-quoting: a
|
|
244
|
+
# missing, empty, or non-covering tariff for an overlength package must
|
|
245
|
+
# make the carrier unserviceable. We key off rule *coverage* (via
|
|
246
|
+
# #overlength_rule_for) rather than the tariff object's mere presence,
|
|
247
|
+
# because a present-but-empty FreightKit::Tariff is not `blank?` and would
|
|
248
|
+
# otherwise slip past this check.
|
|
249
|
+
if overlength_fees_require_tariff?
|
|
250
|
+
missing_dimensions = packages.any? do |package|
|
|
251
|
+
[package.height(:inches), package.length(:inches), package.width(:inches)].any?(&:zero?)
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
uncovered_overlength = packages.any? { |package| overlength?(package) && overlength_rule_for(tariff, package).nil? }
|
|
255
|
+
|
|
256
|
+
if missing_dimensions
|
|
257
|
+
message << 'item dimensions are required'
|
|
258
|
+
elsif uncovered_overlength
|
|
259
|
+
message << 'tariff must be defined to calculate overlength fees'
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
raise UnserviceableError, message.join(', ').capitalize if message.present?
|
|
264
|
+
|
|
265
|
+
true
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
# The carrier's homepage, verified to load over HTTPS and to name the carrier (e.g. "https://abf.com").
|
|
269
|
+
# @return [String, nil]
|
|
270
|
+
def website_url = nil
|
|
271
|
+
end
|
|
146
272
|
|
|
147
|
-
NUMBERS = %i[bol_number order_number pickup_number po_number tracking_number]
|
|
273
|
+
NUMBERS = %i[bol_number order_number pickup_number po_number tracking_number].freeze
|
|
148
274
|
|
|
149
|
-
attr_accessor :conf, :rates_with_excessive_length_fees, :tmpdir
|
|
150
275
|
attr_reader :credentials, :customer_location, :last_request, :tariff
|
|
151
276
|
|
|
277
|
+
delegate :id,
|
|
278
|
+
:longest_dimension,
|
|
279
|
+
:mappable_accessorials,
|
|
280
|
+
:name,
|
|
281
|
+
:overlength?,
|
|
282
|
+
:overlength_fee,
|
|
283
|
+
:overlength_rule_for,
|
|
284
|
+
:rates_with_excessive_length_fees?,
|
|
285
|
+
:scac,
|
|
286
|
+
:serviceable_accessorials?,
|
|
287
|
+
:unquotable_accessorials,
|
|
288
|
+
:unserviceable_accessorials,
|
|
289
|
+
:valid_number_regex,
|
|
290
|
+
:validate_packages,
|
|
291
|
+
to: :class
|
|
292
|
+
|
|
152
293
|
# @param credentials [Array<Credential>]
|
|
153
294
|
# @param customer_location [Location]
|
|
154
295
|
# @param tariff [Tariff]
|
|
@@ -156,14 +297,14 @@ module FreightKit
|
|
|
156
297
|
credentials = [credentials] if credentials.is_a?(Credential)
|
|
157
298
|
|
|
158
299
|
if credentials.map(&:class).uniq != [Credential]
|
|
159
|
-
message = "#{
|
|
300
|
+
message = "#{name}#new: `credentials` must be a Credential or Array of Credential"
|
|
160
301
|
raise ArgumentError, message
|
|
161
302
|
end
|
|
162
303
|
|
|
163
304
|
missing_credential_types = self.class.required_credential_types.uniq - credentials.map(&:type).uniq
|
|
164
305
|
|
|
165
306
|
if missing_credential_types.any?
|
|
166
|
-
message = "#{
|
|
307
|
+
message = "#{name}#new: `Credential` of type(s) missing: #{missing_credential_types.join(', ')}"
|
|
167
308
|
raise ArgumentError, message
|
|
168
309
|
end
|
|
169
310
|
|
|
@@ -171,38 +312,17 @@ module FreightKit
|
|
|
171
312
|
|
|
172
313
|
if customer_location.present?
|
|
173
314
|
unless customer_location.is_a?(Location)
|
|
174
|
-
message = "#{
|
|
315
|
+
message = "#{name}#new: `customer_location` must be a Location"
|
|
175
316
|
raise ArgumentError, message
|
|
176
317
|
end
|
|
177
318
|
|
|
178
319
|
@customer_location = customer_location
|
|
179
320
|
end
|
|
180
321
|
|
|
181
|
-
if tariff.
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
@tariff = tariff
|
|
185
|
-
end
|
|
186
|
-
|
|
187
|
-
conf_path = File
|
|
188
|
-
.join(
|
|
189
|
-
File.expand_path(
|
|
190
|
-
'../../../../configuration/carriers',
|
|
191
|
-
self.class.const_source_location(:REACTIVE_FREIGHT_CARRIER).first,
|
|
192
|
-
),
|
|
193
|
-
"#{self.class.to_s.split("::")[1].underscore}.yml",
|
|
194
|
-
)
|
|
195
|
-
@conf = YAML.safe_load_file(conf_path, permitted_classes: [Symbol])
|
|
196
|
-
|
|
197
|
-
@rates_with_excessive_length_fees = @conf.dig(:attributes, :rates, :with_excessive_length_fees)
|
|
198
|
-
end
|
|
322
|
+
return if tariff.blank?
|
|
323
|
+
raise ArgumentError, "#{name}#new: `tariff` must be a Tariff" unless tariff.is_a?(Tariff)
|
|
199
324
|
|
|
200
|
-
|
|
201
|
-
#
|
|
202
|
-
# @param [String] tracking_number Tracking number.
|
|
203
|
-
# @return [DocumentResponse]
|
|
204
|
-
def pod(tracking_number)
|
|
205
|
-
raise NotImplementedError, "#{self.class.name}: #pod not supported"
|
|
325
|
+
@tariff = tariff
|
|
206
326
|
end
|
|
207
327
|
|
|
208
328
|
# Asks the carrier for the bill of lading that the carrier would provide before shipping.
|
|
@@ -211,46 +331,7 @@ module FreightKit
|
|
|
211
331
|
#
|
|
212
332
|
# @param [String] tracking_number Tracking number.
|
|
213
333
|
# @return [DocumentResponse]
|
|
214
|
-
def bol(tracking_number)
|
|
215
|
-
raise NotImplementedError, "#{self.class.name}: #bol not supported"
|
|
216
|
-
end
|
|
217
|
-
|
|
218
|
-
# Asks the carrier for the scanned bill of lading that the carrier would provide after shipping.
|
|
219
|
-
#
|
|
220
|
-
# @see #bol
|
|
221
|
-
#
|
|
222
|
-
# @param [String] tracking_number Tracking number.
|
|
223
|
-
# @return [DocumentResponse]
|
|
224
|
-
def scanned_bol(tracking_number)
|
|
225
|
-
raise NotImplementedError, "#{self.class.name}: #scanned_bol not supported"
|
|
226
|
-
end
|
|
227
|
-
|
|
228
|
-
def find_estimate(*)
|
|
229
|
-
raise NotImplementedError, "#{self.class.name}: #find_estimate not supported"
|
|
230
|
-
end
|
|
231
|
-
|
|
232
|
-
# Asks the carrier for a list of locations (terminals) for a given country
|
|
233
|
-
#
|
|
234
|
-
# @param [ActiveUtils::Country] country
|
|
235
|
-
# @return [Array<Location>]
|
|
236
|
-
def find_locations(country)
|
|
237
|
-
raise NotImplementedError, "#{self.class.name}: #find_locations not supported"
|
|
238
|
-
end
|
|
239
|
-
|
|
240
|
-
def find_tracking_number_from_pickup_number(pickup_number, date)
|
|
241
|
-
raise NotImplementedError, "#{self.class.name}: #find_tracking_number_from_pickup_number not supported"
|
|
242
|
-
end
|
|
243
|
-
|
|
244
|
-
# Asks the carrier for rate estimates for a given shipment.
|
|
245
|
-
#
|
|
246
|
-
# @note Override with whatever you need to get the rates from the carrier.
|
|
247
|
-
#
|
|
248
|
-
# @param shipment [FreightKit::Shipment] Shipment details.
|
|
249
|
-
# @return [FreightKit::RateResponse] The response from the carrier, which
|
|
250
|
-
# includes 0 or more rate estimates for different shipping products
|
|
251
|
-
def find_rates(shipment:)
|
|
252
|
-
raise NotImplementedError, "#find_rates is not supported by #{self.class.name}."
|
|
253
|
-
end
|
|
334
|
+
def bol(tracking_number) = raise NotImplementedError, "#{name}: #bol not supported"
|
|
254
335
|
|
|
255
336
|
# Registers a new pickup with the carrier, to get a tracking number and
|
|
256
337
|
# potentially shipping labels
|
|
@@ -283,19 +364,29 @@ module FreightKit
|
|
|
283
364
|
service:,
|
|
284
365
|
shipment:
|
|
285
366
|
)
|
|
286
|
-
raise NotImplementedError, "#create_pickup is not supported by #{
|
|
367
|
+
raise NotImplementedError, "#create_pickup is not supported by #{name}."
|
|
287
368
|
end
|
|
288
369
|
|
|
289
|
-
#
|
|
370
|
+
# Fetch credential of given type.
|
|
290
371
|
#
|
|
291
|
-
# @
|
|
372
|
+
# @param type [Symbol] Type of credential to find, should be one of: `:api`, `:selenoid`, `:website`.
|
|
373
|
+
# @return [FreightKit::Credential|NilClass]
|
|
374
|
+
def fetch_credential(type) = credentials.find { |credential| credential.type == type }
|
|
375
|
+
|
|
376
|
+
# Asks the carrier for a list of locations (terminals) for a given country
|
|
292
377
|
#
|
|
293
|
-
# @param
|
|
294
|
-
# @return [
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
378
|
+
# @param [ActiveUtils::Country] country
|
|
379
|
+
# @return [Array<Location>]
|
|
380
|
+
def find_locations(country) = raise NotImplementedError, "#{name}: #find_locations not supported"
|
|
381
|
+
|
|
382
|
+
# Asks the carrier for rate estimates for a given shipment.
|
|
383
|
+
#
|
|
384
|
+
# @note Override with whatever you need to get the rates from the carrier.
|
|
385
|
+
#
|
|
386
|
+
# @param shipment [FreightKit::Shipment] Shipment details.
|
|
387
|
+
# @return [FreightKit::RateResponse] The response from the carrier, which
|
|
388
|
+
# includes 0 or more rate estimates for different shipping products
|
|
389
|
+
def find_rates(shipment:) = raise NotImplementedError, "#find_rates is not supported by #{name}."
|
|
299
390
|
|
|
300
391
|
# Retrieves tracking information for a previous shipment
|
|
301
392
|
#
|
|
@@ -305,189 +396,44 @@ module FreightKit
|
|
|
305
396
|
# @return [FreightKit::TrackingResponse] The response from the carrier. This
|
|
306
397
|
# response should a list of shipment tracking events if successful.
|
|
307
398
|
def find_tracking_info(tracking_number)
|
|
308
|
-
raise NotImplementedError, "#find_tracking_info is not supported by #{
|
|
399
|
+
raise NotImplementedError, "#find_tracking_info is not supported by #{name}."
|
|
309
400
|
end
|
|
310
401
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
# @param origin [Location] The origin location.
|
|
314
|
-
# @param destination [Location] The destination location.
|
|
315
|
-
# @return [Array<Symbol>] A list of service type symbols for the available services.
|
|
316
|
-
#
|
|
317
|
-
def available_services(origin, destination)
|
|
318
|
-
raise NotImplementedError, "#available_services is not supported by #{self.class.name}."
|
|
402
|
+
def find_tracking_number_from_pickup_number(pickup_number, date)
|
|
403
|
+
raise NotImplementedError, "#{name}: #find_tracking_number_from_pickup_number not supported"
|
|
319
404
|
end
|
|
320
405
|
|
|
321
|
-
#
|
|
406
|
+
# Asks the carrier for the scanned proof of delivery that the carrier would provide after delivery.
|
|
322
407
|
#
|
|
323
|
-
# @param
|
|
324
|
-
# @return [
|
|
325
|
-
def
|
|
326
|
-
@fetch_credentials ||= {}
|
|
327
|
-
return @fetch_credentials[type] if @fetch_credentials[type].present?
|
|
328
|
-
|
|
329
|
-
@fetch_credentials[type] ||= credentials.find { |credential| credential.type == type }
|
|
330
|
-
end
|
|
408
|
+
# @param [String] tracking_number Tracking number.
|
|
409
|
+
# @return [DocumentResponse]
|
|
410
|
+
def pod(tracking_number) = raise NotImplementedError, "#{name}: #pod not supported"
|
|
331
411
|
|
|
332
|
-
#
|
|
412
|
+
# Asks the carrier for the scanned bill of lading that the carrier would provide after shipping.
|
|
333
413
|
#
|
|
334
|
-
#
|
|
335
|
-
# the carrier's default_location. Override to provide alternate functionality.
|
|
414
|
+
# @see #bol
|
|
336
415
|
#
|
|
337
|
-
# @
|
|
338
|
-
#
|
|
339
|
-
def
|
|
340
|
-
location = self.class.default_location
|
|
341
|
-
find_rates(location, location, Package.new(100, [5, 15, 30]))
|
|
342
|
-
rescue FreightKit::ResponseError
|
|
343
|
-
false
|
|
344
|
-
else
|
|
345
|
-
true
|
|
346
|
-
end
|
|
416
|
+
# @param [String] tracking_number Tracking number.
|
|
417
|
+
# @return [DocumentResponse]
|
|
418
|
+
def scanned_bol(tracking_number) = raise NotImplementedError, "#{name}: #scanned_bol not supported"
|
|
347
419
|
|
|
348
420
|
# Validate the tracking number (may call API).
|
|
349
421
|
#
|
|
350
422
|
# @param [String] tracking_number Tracking number.
|
|
351
423
|
# @return [Boolean] Should return `true` if the provided pro is valid.
|
|
352
424
|
def valid_tracking_number?(tracking_number)
|
|
353
|
-
raise NotImplementedError, "#
|
|
354
|
-
end
|
|
355
|
-
|
|
356
|
-
# The package's longest horizontal dimension (length or width), as a
|
|
357
|
-
# Measured::Length so comparisons stay unit-agnostic.
|
|
358
|
-
#
|
|
359
|
-
# @param package [FreightKit::Package]
|
|
360
|
-
# @return [Measured::Length]
|
|
361
|
-
def longest_dimension(package)
|
|
362
|
-
[
|
|
363
|
-
Measured::Length.new(package.length(:inches), :inches),
|
|
364
|
-
Measured::Length.new(package.width(:inches), :inches),
|
|
365
|
-
].max
|
|
366
|
-
end
|
|
367
|
-
|
|
368
|
-
# @param package [FreightKit::Package]
|
|
369
|
-
# @return [Boolean] whether the package is long enough to incur overlength fees.
|
|
370
|
-
def overlength?(package) = longest_dimension(package) >= self.class.minimum_length_for_overlength_fees
|
|
371
|
-
|
|
372
|
-
def overlength_fee(tariff, package)
|
|
373
|
-
overlength_rule = overlength_rule_for(tariff, package)
|
|
374
|
-
return 0 if overlength_rule.nil?
|
|
375
|
-
|
|
376
|
-
package.quantity * overlength_rule.fee_cents
|
|
377
|
-
end
|
|
378
|
-
|
|
379
|
-
# Returns the overlength rule from +tariff+ that applies to +package+, or
|
|
380
|
-
# +nil+ when the package is not overlength, or no configured rule covers it.
|
|
381
|
-
#
|
|
382
|
-
# This is the single source of truth for "does a rule cover this package?"
|
|
383
|
-
# shared by {#overlength_fee} and {#validate_packages} so the two can never
|
|
384
|
-
# disagree (e.g. a package quoting $0 overlength while also being treated as
|
|
385
|
-
# serviceable).
|
|
386
|
-
#
|
|
387
|
-
# @param tariff [FreightKit::Tariff, nil]
|
|
388
|
-
# @param package [FreightKit::Package]
|
|
389
|
-
# @return [FreightKit::Tariff::OverlengthRule, nil]
|
|
390
|
-
def overlength_rule_for(tariff, package)
|
|
391
|
-
return unless tariff.is_a?(FreightKit::Tariff) && overlength?(package)
|
|
392
|
-
|
|
393
|
-
tariff.overlength_rules.find { |overlength_rule| overlength_rule.cover?(longest_dimension(package)) }
|
|
394
|
-
end
|
|
395
|
-
|
|
396
|
-
# Determine whether the carrier will accept the packages based on credentials and/or tariff.
|
|
397
|
-
# @param packages [Array<FreightKit::Package>]
|
|
398
|
-
# @param tariff [FreightKit::Tariff]
|
|
399
|
-
# @return [Boolean]
|
|
400
|
-
def validate_packages(packages, tariff = nil)
|
|
401
|
-
return false if packages.blank?
|
|
402
|
-
|
|
403
|
-
message = []
|
|
404
|
-
|
|
405
|
-
max_height_inches = self.class.maximum_height.convert_to(:inches).value
|
|
406
|
-
if packages.map { |p| p.height(:inches) }.max > max_height_inches
|
|
407
|
-
message << "items must be #{max_height_inches.to_f} inches tall or less"
|
|
408
|
-
end
|
|
409
|
-
|
|
410
|
-
max_weight_pounds = self.class.maximum_weight.convert_to(:pounds).value
|
|
411
|
-
if packages.sum { |p| p.pounds(:total) } > max_weight_pounds
|
|
412
|
-
message << "items must weigh #{max_weight_pounds.to_f} lbs or less"
|
|
413
|
-
end
|
|
414
|
-
|
|
415
|
-
# Carriers that don't quote overlength fees via their API rely on the
|
|
416
|
-
# tariff to price them. Fail closed rather than silently under-quoting: a
|
|
417
|
-
# missing, empty, or non-covering tariff for an overlength package must
|
|
418
|
-
# make the carrier unserviceable. We key off rule *coverage* (via
|
|
419
|
-
# #overlength_rule_for) rather than the tariff object's mere presence,
|
|
420
|
-
# because a present-but-empty FreightKit::Tariff is not `blank?` and would
|
|
421
|
-
# otherwise slip past this check.
|
|
422
|
-
if self.class.overlength_fees_require_tariff?
|
|
423
|
-
missing_dimensions = packages.any? do |package|
|
|
424
|
-
[
|
|
425
|
-
package.height(:inches),
|
|
426
|
-
package.length(:inches),
|
|
427
|
-
package.width(:inches),
|
|
428
|
-
].any?(&:zero?)
|
|
429
|
-
end
|
|
430
|
-
|
|
431
|
-
uncovered_overlength = packages.any? do |package|
|
|
432
|
-
overlength?(package) && overlength_rule_for(tariff, package).nil?
|
|
433
|
-
end
|
|
434
|
-
|
|
435
|
-
if missing_dimensions
|
|
436
|
-
message << 'item dimensions are required'
|
|
437
|
-
elsif uncovered_overlength
|
|
438
|
-
message << 'tariff must be defined to calculate overlength fees'
|
|
439
|
-
end
|
|
440
|
-
end
|
|
441
|
-
|
|
442
|
-
raise UnserviceableError, message.join(', ').capitalize if message.present?
|
|
443
|
-
|
|
444
|
-
true
|
|
445
|
-
end
|
|
446
|
-
|
|
447
|
-
def serviceable_accessorials?(accessorials)
|
|
448
|
-
return true if accessorials.blank?
|
|
449
|
-
|
|
450
|
-
unless self.class::REACTIVE_FREIGHT_CARRIER
|
|
451
|
-
raise NotImplementedError, "#{self.class.name}: #serviceable_accessorials? not supported"
|
|
452
|
-
end
|
|
453
|
-
|
|
454
|
-
return false if @conf.dig(:accessorials, :mappable).blank?
|
|
455
|
-
|
|
456
|
-
conf_mappable_accessorials = @conf.dig(:accessorials, :mappable)
|
|
457
|
-
conf_unquotable_accessorials = @conf.dig(:accessorials, :unquotable)
|
|
458
|
-
conf_unserviceable_accessorials = @conf.dig(:accessorials, :unserviceable)
|
|
459
|
-
|
|
460
|
-
unserviceable_accessorials = []
|
|
461
|
-
|
|
462
|
-
accessorials.each do |accessorial|
|
|
463
|
-
if conf_unserviceable_accessorials.present? && conf_unserviceable_accessorials.any?(accessorial)
|
|
464
|
-
unserviceable_accessorials << accessorial
|
|
465
|
-
next
|
|
466
|
-
end
|
|
467
|
-
|
|
468
|
-
next if conf_mappable_accessorials.present? && conf_mappable_accessorials.keys.any?(accessorial)
|
|
469
|
-
next if conf_unquotable_accessorials.present? && conf_unquotable_accessorials.any?(accessorial)
|
|
470
|
-
|
|
471
|
-
unserviceable_accessorials << accessorial
|
|
472
|
-
end
|
|
473
|
-
|
|
474
|
-
if unserviceable_accessorials.present?
|
|
475
|
-
raise FreightKit::UnserviceableAccessorialsError.new(accessorials: unserviceable_accessorials)
|
|
476
|
-
end
|
|
477
|
-
|
|
478
|
-
true
|
|
425
|
+
raise NotImplementedError, "#valid_tracking_number? is not supported by #{name}."
|
|
479
426
|
end
|
|
480
427
|
|
|
481
428
|
protected
|
|
482
429
|
|
|
483
|
-
|
|
484
|
-
|
|
430
|
+
# Proxy for HTTP requests, from the optional `:api_proxy` credential.
|
|
431
|
+
# @return [String|NilClass]
|
|
432
|
+
def proxy_url = fetch_credential(:api_proxy)&.proxy_url
|
|
485
433
|
|
|
486
434
|
# Use after building the request to save for later inspection.
|
|
487
435
|
# @return [void]
|
|
488
|
-
def save_request(request)
|
|
489
|
-
@last_request = request
|
|
490
|
-
end
|
|
436
|
+
def save_request(request) = @last_request = request
|
|
491
437
|
|
|
492
438
|
# Calculates a timestamp that corresponds a given number of business days in the future
|
|
493
439
|
#
|