freight_kit 0.1.20 → 0.1.21

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.
Files changed (434) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -2
  3. data/README.md +1 -2
  4. data/Rakefile +6 -0
  5. data/VERSION +1 -1
  6. data/configuration/locations/amazon_warehouses.yml +3330 -0
  7. data/freight_kit.gemspec +13 -13
  8. data/lib/freight_kit/address_normalizer.rb +26 -0
  9. data/lib/freight_kit/amazon_warehouse.rb +33 -0
  10. data/lib/freight_kit/api_clients/soap_client.rb +7 -9
  11. data/lib/freight_kit/carrier.rb +250 -303
  12. data/lib/freight_kit/carriers/a1_express.rb +25 -0
  13. data/lib/freight_kit/carriers/a_duie_pyle.rb +30 -0
  14. data/lib/freight_kit/carriers/aaa_cooper.rb +11 -0
  15. data/lib/freight_kit/carriers/aaa_expedited_services.rb +10 -0
  16. data/lib/freight_kit/carriers/ab_brothers_usa_inc.rb +12 -0
  17. data/lib/freight_kit/carriers/aberdeen_express_inc.rb +28 -0
  18. data/lib/freight_kit/carriers/abf_freight_system.rb +492 -0
  19. data/lib/freight_kit/carriers/access_transport.rb +10 -0
  20. data/lib/freight_kit/carriers/action_express.rb +10 -0
  21. data/lib/freight_kit/carriers/adams_and_companies.rb +10 -0
  22. data/lib/freight_kit/carriers/advance_distribution.rb +28 -0
  23. data/lib/freight_kit/carriers/alcon_transport.rb +10 -0
  24. data/lib/freight_kit/carriers/all_freight.rb +10 -0
  25. data/lib/freight_kit/carriers/alliance_transportation_group.rb +10 -0
  26. data/lib/freight_kit/carriers/allstate_transport.rb +10 -0
  27. data/lib/freight_kit/carriers/aloha_freight_forwarders.rb +35 -0
  28. data/lib/freight_kit/carriers/amado_trucking.rb +35 -0
  29. data/lib/freight_kit/carriers/american_fast_freight.rb +28 -0
  30. data/lib/freight_kit/carriers/amigos_service_transportation.rb +10 -0
  31. data/lib/freight_kit/carriers/anderson_towing_and_transport.rb +10 -0
  32. data/lib/freight_kit/carriers/apex_transporting.rb +10 -0
  33. data/lib/freight_kit/carriers/archer_cargo.rb +35 -0
  34. data/lib/freight_kit/carriers/armstrong_transport_group.rb +10 -0
  35. data/lib/freight_kit/carriers/autobahn_logistics.rb +10 -0
  36. data/lib/freight_kit/carriers/averitt_express.rb +30 -0
  37. data/lib/freight_kit/carriers/ba_transportation.rb +10 -0
  38. data/lib/freight_kit/carriers/balkin_express.rb +10 -0
  39. data/lib/freight_kit/carriers/bay_area_express.rb +10 -0
  40. data/lib/freight_kit/carriers/bc_freightways.rb +11 -0
  41. data/lib/freight_kit/carriers/benjamin_best_freight_inc.rb +37 -0
  42. data/lib/freight_kit/carriers/bennett_trucking.rb +10 -0
  43. data/lib/freight_kit/carriers/best_overnite_express.rb +78 -0
  44. data/lib/freight_kit/carriers/best_trucking.rb +10 -0
  45. data/lib/freight_kit/carriers/bestway_transport.rb +10 -0
  46. data/lib/freight_kit/carriers/bryan_systems.rb +10 -0
  47. data/lib/freight_kit/carriers/c_and_w_express.rb +10 -0
  48. data/lib/freight_kit/carriers/campbell_trucking.rb +10 -0
  49. data/lib/freight_kit/carriers/carde_transportation.rb +10 -0
  50. data/lib/freight_kit/carriers/cardinal_logistics.rb +28 -0
  51. data/lib/freight_kit/carriers/cdc_transport.rb +10 -0
  52. data/lib/freight_kit/carriers/cdo_express_diversified.rb +10 -0
  53. data/lib/freight_kit/carriers/cedar_supply_trucking.rb +10 -0
  54. data/lib/freight_kit/carriers/central_freight_lines.rb +12 -0
  55. data/lib/freight_kit/carriers/central_transport.rb +12 -0
  56. data/lib/freight_kit/carriers/chicago_suburban_express.rb +28 -0
  57. data/lib/freight_kit/carriers/city_logistics.rb +11 -0
  58. data/lib/freight_kit/carriers/clear_lane_freight_systems.rb +483 -0
  59. data/lib/freight_kit/carriers/cleopatra_trucking.rb +10 -0
  60. data/lib/freight_kit/carriers/clifford_transportation.rb +10 -0
  61. data/lib/freight_kit/carriers/cms_domestic.rb +25 -0
  62. data/lib/freight_kit/carriers/cnd_logistics.rb +10 -0
  63. data/lib/freight_kit/carriers/coast_to_coast_transport.rb +27 -0
  64. data/lib/freight_kit/carriers/countrywide_carriers.rb +10 -0
  65. data/lib/freight_kit/carriers/cpl_express.rb +35 -0
  66. data/lib/freight_kit/carriers/crosby_trucking_service.rb +29 -0
  67. data/lib/freight_kit/carriers/cross_country_freight_solutions.rb +419 -0
  68. data/lib/freight_kit/carriers/crowley.rb +10 -0
  69. data/lib/freight_kit/carriers/csa_transportation.rb +40 -0
  70. data/lib/freight_kit/carriers/csx_transportation.rb +40 -0
  71. data/lib/freight_kit/carriers/custom_global_logistics.rb +14 -0
  72. data/lib/freight_kit/carriers/d_and_a_transport.rb +10 -0
  73. data/lib/freight_kit/carriers/dak_transport.rb +10 -0
  74. data/lib/freight_kit/carriers/dash_courier_and_logistics_north_carolina.rb +10 -0
  75. data/lib/freight_kit/carriers/daylight_transport.rb +29 -0
  76. data/lib/freight_kit/carriers/dayton_freight_lines.rb +30 -0
  77. data/lib/freight_kit/carriers/dbr_logistics.rb +10 -0
  78. data/lib/freight_kit/carriers/deep_south_freight.rb +27 -0
  79. data/lib/freight_kit/carriers/delta_express.rb +10 -0
  80. data/lib/freight_kit/carriers/delta_transport.rb +10 -0
  81. data/lib/freight_kit/carriers/delta_trucking_logistics.rb +10 -0
  82. data/lib/freight_kit/carriers/demco_express.rb +10 -0
  83. data/lib/freight_kit/carriers/dependable_global_express.rb +10 -0
  84. data/lib/freight_kit/carriers/dependable_hawaiian_express.rb +24 -0
  85. data/lib/freight_kit/carriers/dependable_highway_express.rb +585 -0
  86. data/lib/freight_kit/carriers/desert_coastal_transport.rb +10 -0
  87. data/lib/freight_kit/carriers/dhl.rb +11 -0
  88. data/lib/freight_kit/carriers/diamond_line_delivery.rb +174 -0
  89. data/lib/freight_kit/carriers/ding_tai_trucking.rb +10 -0
  90. data/lib/freight_kit/carriers/diversified_transfer_and_storage.rb +29 -0
  91. data/lib/freight_kit/carriers/dohrn_transfer_company.rb +30 -0
  92. data/lib/freight_kit/carriers/dot_line_transportation.rb +29 -0
  93. data/lib/freight_kit/carriers/drt_transportation.rb +13 -0
  94. data/lib/freight_kit/carriers/dugan_truck_line.rb +29 -0
  95. data/lib/freight_kit/carriers/dupont.rb +10 -0
  96. data/lib/freight_kit/carriers/e_transport_carriers.rb +29 -0
  97. data/lib/freight_kit/carriers/echo_global_logistics.rb +13 -0
  98. data/lib/freight_kit/carriers/ecklund_logistics.rb +10 -0
  99. data/lib/freight_kit/carriers/el_emplumado_transport.rb +10 -0
  100. data/lib/freight_kit/carriers/elite_carriers.rb +28 -0
  101. data/lib/freight_kit/carriers/emerald_express.rb +10 -0
  102. data/lib/freight_kit/carriers/era_transport.rb +10 -0
  103. data/lib/freight_kit/carriers/estes_express_lines.rb +25 -0
  104. data/lib/freight_kit/carriers/euro_kam.rb +28 -0
  105. data/lib/freight_kit/carriers/ew_riverside_trucking.rb +10 -0
  106. data/lib/freight_kit/carriers/express_2000_inc.rb +12 -0
  107. data/lib/freight_kit/carriers/express_services_international.rb +10 -0
  108. data/lib/freight_kit/carriers/f_and_a_express.rb +27 -0
  109. data/lib/freight_kit/carriers/fairmont_logistics.rb +13 -0
  110. data/lib/freight_kit/carriers/fargo_cargo.rb +10 -0
  111. data/lib/freight_kit/carriers/fast_freight_transportation.rb +10 -0
  112. data/lib/freight_kit/carriers/fast_load_transport.rb +10 -0
  113. data/lib/freight_kit/carriers/fed_ex_express.rb +30 -0
  114. data/lib/freight_kit/carriers/fed_ex_ground.rb +24 -0
  115. data/lib/freight_kit/carriers/fed_ex_ltl_economy.rb +11 -0
  116. data/lib/freight_kit/carriers/fed_ex_ltl_priority.rb +11 -0
  117. data/lib/freight_kit/carriers/first_trucking_express.rb +10 -0
  118. data/lib/freight_kit/carriers/flash_trucking.rb +10 -0
  119. data/lib/freight_kit/carriers/fort_transportation_and_service_company_inc.rb +37 -0
  120. data/lib/freight_kit/carriers/forward_air.rb +789 -0
  121. data/lib/freight_kit/carriers/frahtex.rb +10 -0
  122. data/lib/freight_kit/carriers/frozen_food_express.rb +10 -0
  123. data/lib/freight_kit/carriers/gholia_bros_trucking.rb +36 -0
  124. data/lib/freight_kit/carriers/global_cargo.rb +10 -0
  125. data/lib/freight_kit/carriers/global_logistics_and_transportation.rb +10 -0
  126. data/lib/freight_kit/carriers/gls_freight.rb +32 -0
  127. data/lib/freight_kit/carriers/go_trucking_services.rb +10 -0
  128. data/lib/freight_kit/carriers/gold_eagle_transportation.rb +11 -0
  129. data/lib/freight_kit/carriers/golden_drop_trucking.rb +10 -0
  130. data/lib/freight_kit/carriers/gonzalez_transportation.rb +10 -0
  131. data/lib/freight_kit/carriers/gps_transport.rb +10 -0
  132. data/lib/freight_kit/carriers/greene_enterprise.rb +10 -0
  133. data/lib/freight_kit/carriers/gsa_international.rb +10 -0
  134. data/lib/freight_kit/carriers/gsp_express.rb +24 -0
  135. data/lib/freight_kit/carriers/gsv_transportation.rb +10 -0
  136. data/lib/freight_kit/carriers/gta_transportation.rb +10 -0
  137. data/lib/freight_kit/carriers/guam_freight_services.rb +10 -0
  138. data/lib/freight_kit/carriers/harrah_transportation.rb +23 -0
  139. data/lib/freight_kit/carriers/her_trucking.rb +10 -0
  140. data/lib/freight_kit/carriers/hercules_freight.rb +20 -0
  141. data/lib/freight_kit/carriers/highlander_xpress.rb +36 -0
  142. data/lib/freight_kit/carriers/hn_transport.rb +10 -0
  143. data/lib/freight_kit/carriers/honolulu_freight_service.rb +10 -0
  144. data/lib/freight_kit/carriers/hot_line_freight_system_inc.rb +12 -0
  145. data/lib/freight_kit/carriers/hotshot_freight_of_texas.rb +13 -0
  146. data/lib/freight_kit/carriers/houser_transport.rb +27 -0
  147. data/lib/freight_kit/carriers/infiniti_freight_logistics.rb +28 -0
  148. data/lib/freight_kit/carriers/infinity_trucking.rb +10 -0
  149. data/lib/freight_kit/carriers/interstate_tma.rb +10 -0
  150. data/lib/freight_kit/carriers/intrade_industries.rb +10 -0
  151. data/lib/freight_kit/carriers/jasper_trucking.rb +28 -0
  152. data/lib/freight_kit/carriers/jb_hunt.rb +11 -0
  153. data/lib/freight_kit/carriers/jfj_transportation.rb +8 -8
  154. data/lib/freight_kit/carriers/jkb_express.rb +10 -0
  155. data/lib/freight_kit/carriers/jlm_transport.rb +10 -0
  156. data/lib/freight_kit/carriers/johansson_transport.rb +10 -0
  157. data/lib/freight_kit/carriers/jones_express.rb +10 -0
  158. data/lib/freight_kit/carriers/jp_logistics.rb +41 -0
  159. data/lib/freight_kit/carriers/just_in_time_cargo.rb +29 -0
  160. data/lib/freight_kit/carriers/kengkok_times.rb +10 -0
  161. data/lib/freight_kit/carriers/kings_express.rb +10 -0
  162. data/lib/freight_kit/carriers/klc_transportation.rb +10 -0
  163. data/lib/freight_kit/carriers/km_trucking.rb +10 -0
  164. data/lib/freight_kit/carriers/kma_logistics.rb +10 -0
  165. data/lib/freight_kit/carriers/krc_logistics.rb +10 -0
  166. data/lib/freight_kit/carriers/ktx.rb +10 -0
  167. data/lib/freight_kit/carriers/landstar.rb +25 -0
  168. data/lib/freight_kit/carriers/lanter_distributing_llc.rb +30 -0
  169. data/lib/freight_kit/carriers/ld_trucking.rb +10 -0
  170. data/lib/freight_kit/carriers/legacy_logistics_solutions.rb +10 -0
  171. data/lib/freight_kit/carriers/leonards_express.rb +10 -0
  172. data/lib/freight_kit/carriers/liberty_linehaul_west.rb +28 -0
  173. data/lib/freight_kit/carriers/liberty_transport.rb +10 -0
  174. data/lib/freight_kit/carriers/lightning_express.rb +10 -0
  175. data/lib/freight_kit/carriers/lj_express.rb +24 -0
  176. data/lib/freight_kit/carriers/lkp_enterprises.rb +10 -0
  177. data/lib/freight_kit/carriers/ltl_pros.rb +28 -0
  178. data/lib/freight_kit/carriers/m_and_m_and_sons.rb +10 -0
  179. data/lib/freight_kit/carriers/mag_lines_transport.rb +10 -0
  180. data/lib/freight_kit/carriers/magic_messenger.rb +24 -0
  181. data/lib/freight_kit/carriers/majors_transit.rb +10 -0
  182. data/lib/freight_kit/carriers/map_global_logistics.rb +10 -0
  183. data/lib/freight_kit/carriers/matths_trucking.rb +11 -0
  184. data/lib/freight_kit/carriers/mav_canadian_transport.rb +13 -0
  185. data/lib/freight_kit/carriers/mc_systems.rb +35 -0
  186. data/lib/freight_kit/carriers/mega_fleet.rb +10 -0
  187. data/lib/freight_kit/carriers/mega_trans_group.rb +28 -0
  188. data/lib/freight_kit/carriers/meta_express.rb +10 -0
  189. data/lib/freight_kit/carriers/mia_transportation.rb +10 -0
  190. data/lib/freight_kit/carriers/midwest_motor_express.rb +14 -0
  191. data/lib/freight_kit/carriers/midwest_transport_and_trucking.rb +10 -0
  192. data/lib/freight_kit/carriers/mikade_delivery_service.rb +10 -0
  193. data/lib/freight_kit/carriers/mohoff_freight_lines.rb +23 -0
  194. data/lib/freight_kit/carriers/montata_travelers_express.rb +10 -0
  195. data/lib/freight_kit/carriers/morgan_van_lines.rb +29 -0
  196. data/lib/freight_kit/carriers/moto_transportation.rb +24 -0
  197. data/lib/freight_kit/carriers/mountain_valley_express.rb +197 -0
  198. data/lib/freight_kit/carriers/ms_freight.rb +27 -0
  199. data/lib/freight_kit/carriers/mvg_transport.rb +10 -0
  200. data/lib/freight_kit/carriers/n_and_m_transfer_co_inc.rb +29 -0
  201. data/lib/freight_kit/carriers/nabot_transport_solutions.rb +10 -0
  202. data/lib/freight_kit/carriers/national_freight_xpress.rb +10 -0
  203. data/lib/freight_kit/carriers/navigation_group.rb +10 -0
  204. data/lib/freight_kit/carriers/nelson_trucking.rb +10 -0
  205. data/lib/freight_kit/carriers/network_1_transportation.rb +10 -0
  206. data/lib/freight_kit/carriers/new_century_transport.rb +28 -0
  207. data/lib/freight_kit/carriers/new_penn_motor_express.rb +11 -0
  208. data/lib/freight_kit/carriers/nieves_transportation.rb +10 -0
  209. data/lib/freight_kit/carriers/nolan_transportation_group.rb +26 -0
  210. data/lib/freight_kit/carriers/northland_trucking.rb +10 -0
  211. data/lib/freight_kit/carriers/northwest_carrier_logistics.rb +27 -0
  212. data/lib/freight_kit/carriers/nt_usa.rb +10 -0
  213. data/lib/freight_kit/carriers/nu_line_transportation.rb +10 -0
  214. data/lib/freight_kit/carriers/numark_transportation.rb +80 -0
  215. data/lib/freight_kit/carriers/nvk_transport.rb +10 -0
  216. data/lib/freight_kit/carriers/ny_transport.rb +10 -0
  217. data/lib/freight_kit/carriers/oak_harbor.rb +28 -0
  218. data/lib/freight_kit/carriers/oakline_transportation.rb +10 -0
  219. data/lib/freight_kit/carriers/old_dominion_freight_line.rb +30 -0
  220. data/lib/freight_kit/carriers/on_trac.rb +573 -0
  221. data/lib/freight_kit/carriers/one_hundred_one_transport.rb +10 -0
  222. data/lib/freight_kit/carriers/one_way_delivery.rb +10 -0
  223. data/lib/freight_kit/carriers/oracle_transportation_solutions.rb +10 -0
  224. data/lib/freight_kit/carriers/orange_courier.rb +27 -0
  225. data/lib/freight_kit/carriers/ortas_trucking.rb +10 -0
  226. data/lib/freight_kit/carriers/pac_trux_transportation.rb +10 -0
  227. data/lib/freight_kit/carriers/pacer.rb +10 -0
  228. data/lib/freight_kit/carriers/pacific_logistics.rb +10 -0
  229. data/lib/freight_kit/carriers/pacific_states_truck_lines.rb +10 -0
  230. data/lib/freight_kit/carriers/paradise_distributing.rb +10 -0
  231. data/lib/freight_kit/carriers/paramount_freight_systems.rb +10 -0
  232. data/lib/freight_kit/carriers/peninsula_truck_lines.rb +222 -0
  233. data/lib/freight_kit/carriers/pg_transport.rb +10 -0
  234. data/lib/freight_kit/carriers/pgs_360.rb +10 -0
  235. data/lib/freight_kit/carriers/pilot_freight_services.rb +10 -0
  236. data/lib/freight_kit/carriers/pious_trans.rb +27 -0
  237. data/lib/freight_kit/carriers/pitt_ohio_express.rb +30 -0
  238. data/lib/freight_kit/carriers/pki_logistics.rb +12 -0
  239. data/lib/freight_kit/carriers/plana_transportation.rb +28 -0
  240. data/lib/freight_kit/carriers/prestige.rb +10 -0
  241. data/lib/freight_kit/carriers/pro_trans_solutions.rb +28 -0
  242. data/lib/freight_kit/carriers/puma_logistics.rb +10 -0
  243. data/lib/freight_kit/carriers/pwc_international.rb +10 -0
  244. data/lib/freight_kit/carriers/quality_logistics.rb +10 -0
  245. data/lib/freight_kit/carriers/queen_star_trucking.rb +27 -0
  246. data/lib/freight_kit/carriers/r_and_l_carriers.rb +11 -0
  247. data/lib/freight_kit/carriers/rac_transport.rb +10 -0
  248. data/lib/freight_kit/carriers/re_logistics.rb +23 -0
  249. data/lib/freight_kit/carriers/reddaway.rb +11 -0
  250. data/lib/freight_kit/carriers/reefer_van_network.rb +13 -0
  251. data/lib/freight_kit/carriers/refrigerated_trucking_and_ltl_transportation_services.rb +10 -0
  252. data/lib/freight_kit/carriers/ridgeline_express.rb +10 -0
  253. data/lib/freight_kit/carriers/rist_transport.rb +29 -0
  254. data/lib/freight_kit/carriers/river_city_transport.rb +10 -0
  255. data/lib/freight_kit/carriers/roadrunner_transportation_services.rb +675 -0
  256. data/lib/freight_kit/carriers/roadtex.rb +13 -0
  257. data/lib/freight_kit/carriers/ronald_transport_services.rb +10 -0
  258. data/lib/freight_kit/carriers/rose_trucking.rb +24 -0
  259. data/lib/freight_kit/carriers/rp_and_j_transport.rb +24 -0
  260. data/lib/freight_kit/carriers/rpm_transportation.rb +11 -0
  261. data/lib/freight_kit/carriers/rude_transportation.rb +30 -0
  262. data/lib/freight_kit/carriers/s_and_s_logistics.rb +10 -0
  263. data/lib/freight_kit/carriers/saia.rb +470 -361
  264. data/lib/freight_kit/carriers/sb_transportation.rb +27 -0
  265. data/lib/freight_kit/carriers/schneider_national.rb +29 -0
  266. data/lib/freight_kit/carriers/schwarz_trucking.rb +10 -0
  267. data/lib/freight_kit/carriers/sewell_motor_express.rb +29 -0
  268. data/lib/freight_kit/carriers/shawnee_trucking.rb +28 -0
  269. data/lib/freight_kit/carriers/shi_logistics.rb +10 -0
  270. data/lib/freight_kit/carriers/sinbad_transport.rb +10 -0
  271. data/lib/freight_kit/carriers/skyway.rb +10 -0
  272. data/lib/freight_kit/carriers/smith_cargo_transportation_services.rb +23 -0
  273. data/lib/freight_kit/carriers/sna_transportation.rb +10 -0
  274. data/lib/freight_kit/carriers/solid_group.rb +10 -0
  275. data/lib/freight_kit/carriers/solution_carrier_express.rb +10 -0
  276. data/lib/freight_kit/carriers/southeastern_freight_lines.rb +450 -0
  277. data/lib/freight_kit/carriers/southwestern_motor_transport.rb +30 -0
  278. data/lib/freight_kit/carriers/span_alaska.rb +10 -0
  279. data/lib/freight_kit/carriers/specialize_transportation.rb +27 -0
  280. data/lib/freight_kit/carriers/ssi_refrigerated_express.rb +10 -0
  281. data/lib/freight_kit/carriers/standard_forwarding_llc.rb +28 -0
  282. data/lib/freight_kit/carriers/star_american_enterprise.rb +10 -0
  283. data/lib/freight_kit/carriers/sterling_transportation.rb +10 -0
  284. data/lib/freight_kit/carriers/stg.rb +163 -0
  285. data/lib/freight_kit/carriers/supervan_service.rb +10 -0
  286. data/lib/freight_kit/carriers/sutton_transport_inc.rb +12 -0
  287. data/lib/freight_kit/carriers/swift_transportation.rb +28 -0
  288. data/lib/freight_kit/carriers/t_force_worldwide.rb +617 -0
  289. data/lib/freight_kit/carriers/tax_airfreight_inc.rb +35 -0
  290. data/lib/freight_kit/carriers/tforce_freight_inc.rb +30 -0
  291. data/lib/freight_kit/carriers/the_custom_companies.rb +162 -0
  292. data/lib/freight_kit/carriers/thk_trucking.rb +28 -0
  293. data/lib/freight_kit/carriers/tiger_cool_express.rb +11 -0
  294. data/lib/freight_kit/carriers/tili_logistics.rb +10 -0
  295. data/lib/freight_kit/carriers/tmt_industries.rb +10 -0
  296. data/lib/freight_kit/carriers/top_ten_express.rb +28 -0
  297. data/lib/freight_kit/carriers/total_quality_logistics.rb +338 -0
  298. data/lib/freight_kit/carriers/total_transportation.rb +258 -0
  299. data/lib/freight_kit/carriers/trans_international_trucking.rb +29 -0
  300. data/lib/freight_kit/carriers/treasure_transportation.rb +10 -0
  301. data/lib/freight_kit/carriers/tri_state_services.rb +10 -0
  302. data/lib/freight_kit/carriers/tritex_freighters.rb +10 -0
  303. data/lib/freight_kit/carriers/triways.rb +10 -0
  304. data/lib/freight_kit/carriers/tsi_kansas.rb +29 -0
  305. data/lib/freight_kit/carriers/u_and_r_transportation.rb +23 -0
  306. data/lib/freight_kit/carriers/union_pacific.rb +11 -0
  307. data/lib/freight_kit/carriers/united_freight_logistics.rb +10 -0
  308. data/lib/freight_kit/carriers/unlimited_distance_transportation.rb +10 -0
  309. data/lib/freight_kit/carriers/up_streamline.rb +10 -0
  310. data/lib/freight_kit/carriers/ups_freight.rb +12 -0
  311. data/lib/freight_kit/carriers/us_freightways.rb +10 -0
  312. data/lib/freight_kit/carriers/usa_truck.rb +28 -0
  313. data/lib/freight_kit/carriers/usf_holland.rb +11 -0
  314. data/lib/freight_kit/carriers/valley_cartage.rb +11 -0
  315. data/lib/freight_kit/carriers/vc_transport.rb +10 -0
  316. data/lib/freight_kit/carriers/vision_express.rb +11 -0
  317. data/lib/freight_kit/carriers/vision_logistics_group.rb +10 -0
  318. data/lib/freight_kit/carriers/vmg_transportation_group.rb +10 -0
  319. data/lib/freight_kit/carriers/volpe_express.rb +10 -0
  320. data/lib/freight_kit/carriers/ward_trucking.rb +29 -0
  321. data/lib/freight_kit/carriers/wdwb.rb +10 -0
  322. data/lib/freight_kit/carriers/western_flyer_express.rb +28 -0
  323. data/lib/freight_kit/carriers/western_regional_delivery_service.rb +271 -0
  324. data/lib/freight_kit/carriers/western_specialized_trucking.rb +22 -0
  325. data/lib/freight_kit/carriers/win_distribution.rb +28 -0
  326. data/lib/freight_kit/carriers/wlb_transport.rb +10 -0
  327. data/lib/freight_kit/carriers/x_trux.rb +29 -0
  328. data/lib/freight_kit/carriers/xpo_logistics.rb +427 -0
  329. data/lib/freight_kit/carriers/xpress_global_systems.rb +30 -0
  330. data/lib/freight_kit/carriers/xylo_trucking.rb +10 -0
  331. data/lib/freight_kit/carriers/yrc_freight.rb +24 -0
  332. data/lib/freight_kit/carriers/zentner_transportation.rb +28 -0
  333. data/lib/freight_kit/carriers.rb +331 -34
  334. data/lib/freight_kit/countries.rb +22 -0
  335. data/lib/freight_kit/error.rb +0 -2
  336. data/lib/freight_kit/errors/document_not_found_error.rb +0 -2
  337. data/lib/freight_kit/errors/expired_credentials_error.rb +0 -2
  338. data/lib/freight_kit/errors/http_error.rb +0 -2
  339. data/lib/freight_kit/errors/invalid_credentials_error.rb +0 -2
  340. data/lib/freight_kit/errors/response_error.rb +0 -2
  341. data/lib/freight_kit/errors/shipment_not_found_error.rb +0 -2
  342. data/lib/freight_kit/errors/unserviceable_accessorials_error.rb +2 -4
  343. data/lib/freight_kit/errors/unserviceable_error.rb +0 -2
  344. data/lib/freight_kit/helpers/documentable.rb +0 -2
  345. data/lib/freight_kit/helpers/pickupable.rb +3 -5
  346. data/lib/freight_kit/helpers/rateable.rb +0 -2
  347. data/lib/freight_kit/helpers/trackable.rb +0 -2
  348. data/lib/freight_kit/http_client/cache_store.rb +2 -4
  349. data/lib/freight_kit/http_client/log_device.rb +0 -2
  350. data/lib/freight_kit/http_client/response.rb +0 -2
  351. data/lib/freight_kit/http_client/revalidation.rb +0 -2
  352. data/lib/freight_kit/http_client/safe_retries.rb +0 -2
  353. data/lib/freight_kit/http_client/zstd.rb +2 -4
  354. data/lib/freight_kit/http_client.rb +8 -12
  355. data/lib/freight_kit/model.rb +1 -3
  356. data/lib/freight_kit/models/address.rb +15 -0
  357. data/lib/freight_kit/models/contact.rb +3 -4
  358. data/lib/freight_kit/models/country.rb +20 -0
  359. data/lib/freight_kit/models/credential.rb +14 -16
  360. data/lib/freight_kit/models/date_time.rb +0 -2
  361. data/lib/freight_kit/models/document_response.rb +0 -2
  362. data/lib/freight_kit/models/label.rb +0 -2
  363. data/lib/freight_kit/models/location.rb +10 -25
  364. data/lib/freight_kit/models/pickup_response.rb +0 -2
  365. data/lib/freight_kit/models/price.rb +0 -2
  366. data/lib/freight_kit/models/rate.rb +0 -2
  367. data/lib/freight_kit/models/rate_response.rb +0 -2
  368. data/lib/freight_kit/models/region.rb +19 -0
  369. data/lib/freight_kit/models/response.rb +0 -2
  370. data/lib/freight_kit/models/shipment.rb +4 -6
  371. data/lib/freight_kit/models/shipment_event.rb +0 -2
  372. data/lib/freight_kit/models/terminal.rb +10 -0
  373. data/lib/freight_kit/models/tracking_response.rb +0 -2
  374. data/lib/freight_kit/package.rb +51 -53
  375. data/lib/freight_kit/package_item.rb +14 -14
  376. data/lib/freight_kit/packaging.rb +21 -26
  377. data/lib/freight_kit/platform.rb +0 -32
  378. data/lib/freight_kit/platforms/carrier_logistics.rb +331 -345
  379. data/lib/freight_kit/platforms/next_tms.rb +93 -0
  380. data/lib/freight_kit/platforms/the_great_information_factory.rb +500 -425
  381. data/lib/freight_kit/regions.rb +27 -0
  382. data/lib/freight_kit/shipment_packer.rb +36 -38
  383. data/lib/freight_kit/tariff/overlength_rule.rb +1 -5
  384. data/lib/freight_kit/tariff.rb +0 -2
  385. data/lib/freight_kit.rb +84 -11
  386. metadata +361 -51
  387. data/configuration/carriers/abfs.yml +0 -124
  388. data/configuration/carriers/btvp.yml +0 -84
  389. data/configuration/carriers/ccyq.yml +0 -121
  390. data/configuration/carriers/clni.yml +0 -113
  391. data/configuration/carriers/cnwy.yml +0 -113
  392. data/configuration/carriers/ctbv.yml +0 -117
  393. data/configuration/carriers/dcha.yml +0 -105
  394. data/configuration/carriers/dlds.yml +0 -111
  395. data/configuration/carriers/dphe.yml +0 -130
  396. data/configuration/carriers/drrq.yml +0 -131
  397. data/configuration/carriers/fcsy.yml +0 -102
  398. data/configuration/carriers/fwda.yml +0 -137
  399. data/configuration/carriers/jfj_transportation.yml +0 -2
  400. data/configuration/carriers/mtvl.yml +0 -12
  401. data/configuration/carriers/numk.yml +0 -14
  402. data/configuration/carriers/otcl.yml +0 -124
  403. data/configuration/carriers/pens.yml +0 -22
  404. data/configuration/carriers/rdfs.yml +0 -142
  405. data/configuration/carriers/saia.yml +0 -129
  406. data/configuration/carriers/sefl.yml +0 -115
  407. data/configuration/carriers/totl.yml +0 -111
  408. data/configuration/carriers/tqyl.yml +0 -28
  409. data/configuration/carriers/wrds.yml +0 -20
  410. data/configuration/platforms/carrier_logistics.yml +0 -25
  411. data/configuration/platforms/next.yml +0 -12
  412. data/configuration/platforms/the_great_information_factory.yml +0 -122
  413. data/lib/freight_kit/carriers/abfs.rb +0 -421
  414. data/lib/freight_kit/carriers/btvp.rb +0 -29
  415. data/lib/freight_kit/carriers/ccyq.rb +0 -310
  416. data/lib/freight_kit/carriers/clni.rb +0 -396
  417. data/lib/freight_kit/carriers/cnwy.rb +0 -327
  418. data/lib/freight_kit/carriers/ctbv.rb +0 -53
  419. data/lib/freight_kit/carriers/dcha.rb +0 -76
  420. data/lib/freight_kit/carriers/dlds.rb +0 -49
  421. data/lib/freight_kit/carriers/dphe.rb +0 -472
  422. data/lib/freight_kit/carriers/drrq.rb +0 -580
  423. data/lib/freight_kit/carriers/fcsy.rb +0 -57
  424. data/lib/freight_kit/carriers/fwda.rb +0 -744
  425. data/lib/freight_kit/carriers/mtvl.rb +0 -34
  426. data/lib/freight_kit/carriers/numk.rb +0 -58
  427. data/lib/freight_kit/carriers/otcl.rb +0 -520
  428. data/lib/freight_kit/carriers/pens.rb +0 -204
  429. data/lib/freight_kit/carriers/rdfs.rb +0 -521
  430. data/lib/freight_kit/carriers/sefl.rb +0 -342
  431. data/lib/freight_kit/carriers/totl.rb +0 -172
  432. data/lib/freight_kit/carriers/tqyl.rb +0 -337
  433. data/lib/freight_kit/carriers/wrds.rb +0 -246
  434. data/lib/freight_kit/platforms/next.rb +0 -101
@@ -0,0 +1,675 @@
1
+ module FreightKit
2
+ module Carriers
3
+ class RoadrunnerTransportationServices < Carrier
4
+ class << self
5
+ def check_mailing_addresses
6
+ [
7
+ Address.new(
8
+ city: 'Chicago',
9
+ country: Countries.find_by(iso31661_alpha2: 'US'),
10
+ id: 'f436b32e-7ae2-4fe8-a8a7-f410d75d9cfc',
11
+ postal_code: '60694',
12
+ region_abbreviation: 'IL',
13
+ street: 'PO Box 74857'
14
+ )
15
+ ]
16
+ end
17
+
18
+ def contacts
19
+ [
20
+ Contact.new(
21
+ department: 'Dispatch - Mira Loma, CA',
22
+ id: 'dc14714f-e381-4b8b-97a6-f002c0897409',
23
+ phone: '+19513615900'
24
+ ),
25
+ Contact.new(department: 'Main', id: '22203680-060c-41db-ba65-9925e8fa381d', phone: '+14146151696')
26
+ ]
27
+ end
28
+
29
+ def headquarters
30
+ Address.new(
31
+ city: 'Milwaukee',
32
+ country: Countries.find_by(iso31661_alpha2: 'US'),
33
+ id: 'a9baff89-6ef0-4c88-9dd5-05c53e355a9c',
34
+ postal_code: '53224',
35
+ region_abbreviation: 'WI',
36
+ street: '9160 N 107th'
37
+ )
38
+ end
39
+
40
+ def id = '62f7ca47-7577-4ad0-a54a-e37d2ffa6696'
41
+ def legal_name = 'Roadrunner Transportation Services Inc'
42
+
43
+ def mappable_accessorials
44
+ {
45
+ afterhours_delivery: 'NBD',
46
+ airport_delivery: 'AID',
47
+ airport_pickup: 'AIP',
48
+ amusement_park_delivery: 'AMD',
49
+ amusement_park_pickup: 'AMP',
50
+ appointment_delivery: 'APT',
51
+ church_delivery: 'CHD',
52
+ church_pickup: 'CHP',
53
+ construction_delivery: 'CSD',
54
+ construction_pickup: 'CSP',
55
+ farm_delivery: 'FAD',
56
+ farm_pickup: 'FAP',
57
+ golf_course_delivery: 'CCD',
58
+ golf_course_pickup: 'CCP',
59
+ government_delivery: 'GSD',
60
+ grocery_warehouse_delivery: 'GWD',
61
+ grocery_warehouse_pickup: 'GWP',
62
+ hotel_delivery: 'HHD',
63
+ hotel_pickup: 'HHP',
64
+ inside_delivery: 'ID',
65
+ inside_pickup: 'IP',
66
+ jobsite_delivery: 'CSD',
67
+ jobsite_pickup: 'CSP',
68
+ liftgate_delivery: 'LGD',
69
+ liftgate_pickup: 'LGP',
70
+ military_site_delivery: 'GSD',
71
+ mine_site_delivery: 'MSD',
72
+ nursing_home_delivery: 'NHD',
73
+ nursing_home_pickup: 'NHP',
74
+ park_delivery: 'CPD',
75
+ park_pickup: 'CPP',
76
+ prison_delivery: 'PSD',
77
+ ranch_delivery: 'FAD',
78
+ ranch_pickup: 'FAP',
79
+ reservation_delivery: 'IRD',
80
+ reservation_pickup: 'IRP',
81
+ residential_delivery: 'RSD',
82
+ residential_pickup: 'RSP',
83
+ resort_delivery: 'CPD',
84
+ resort_pickup: 'CPP',
85
+ school_delivery: 'SHD',
86
+ school_pickup: 'SHP',
87
+ university_delivery: 'SHD',
88
+ university_pickup: 'SHP',
89
+ storage_facility_delivery: 'STD',
90
+ storage_facility_pickup: 'STP',
91
+ utility_site_delivery: 'USD',
92
+ utility_site_pickup: 'USP'
93
+ }
94
+ end
95
+
96
+ def maximum_height = Measured::Length.new(105, :inches)
97
+ def maximum_weight = Measured::Weight.new(10_000, :pounds)
98
+ def minimum_length_for_overlength_fees = Measured::Length.new(8, :feet)
99
+ def name = 'Roadrunner Transportation Services'
100
+ def overlength_fees_require_tariff? = false
101
+ def required_credential_types = %i[website]
102
+ def requirements = %i[credentials]
103
+ def scac = 'RDFS'
104
+ def services = %i[standard]
105
+
106
+ def terminals
107
+ [
108
+ Terminal.new(
109
+ address: Address.new(
110
+ city: 'Los Angeles',
111
+ country: Countries.find_by(iso31661_alpha2: 'US'),
112
+ id: '8fcc2577-d11e-4f1b-baf0-eeb092ce78fa',
113
+ postal_code: '90040',
114
+ region_abbreviation: 'CA',
115
+ street: '4501 E Washington Blvd #2'
116
+ ),
117
+ id: '37649eaf-fcb1-4917-993a-cd82099b86ad',
118
+ phone: '+13237803488'
119
+ ),
120
+ Terminal.new(
121
+ address: Address.new(
122
+ city: 'Memphis',
123
+ country: Countries.find_by(iso31661_alpha2: 'US'),
124
+ id: 'ae6dd9b3-46b6-433d-b1d9-ba80cad25ce3',
125
+ postal_code: '38118',
126
+ region_abbreviation: 'TN',
127
+ street: '3845 Crowfarn Dr'
128
+ ),
129
+ id: 'b6d14db7-d645-491f-b205-7b2b0e2d6a95',
130
+ phone: '+19013007860'
131
+ ),
132
+ Terminal.new(
133
+ address: Address.new(
134
+ city: 'Indianapolis',
135
+ country: Countries.find_by(iso31661_alpha2: 'US'),
136
+ id: 'da0296b5-7dba-4e3d-8fb2-cbe9ac368511',
137
+ postal_code: '46241',
138
+ region_abbreviation: 'IN',
139
+ street: '5751 Dividend Rd'
140
+ ),
141
+ id: '56f382aa-cc26-462c-8bcb-0f5de30b190b',
142
+ phone: '+13177918978'
143
+ )
144
+ ]
145
+ end
146
+
147
+ def unquotable_accessorials
148
+ %i[
149
+ athletic_facility_delivery
150
+ athletic_facility_pickup
151
+ cemetery_delivery
152
+ cemetery_pickup
153
+ dock_dropoff
154
+ dock_pickup
155
+ fitness_center_delivery
156
+ fitness_center_pickup
157
+ government_pickup
158
+ grocery_store_delivery
159
+ grocery_store_pickup
160
+ hospital_delivery
161
+ hospital_pickup
162
+ inspection_site_delivery
163
+ inspection_site_pickup
164
+ mall_delivery
165
+ mall_pickup
166
+ marina_delivery
167
+ marina_pickup
168
+ military_site_pickup
169
+ mine_site_pickup
170
+ motel_delivery
171
+ motel_pickup
172
+ prison_pickup
173
+ restaurant_delivery
174
+ restaurant_pickup
175
+ steel_mill_delivery
176
+ steel_mill_pickup
177
+ ]
178
+ end
179
+
180
+ def unserviceable_accessorials
181
+ %i[
182
+ appointment_pickup
183
+ brewery_delivery
184
+ brewery_pickup
185
+ convention_delivery
186
+ convention_pickup
187
+ customs_brokerage
188
+ driver_assist
189
+ early_morning_delivery
190
+ fair_delivery
191
+ fair_pickup
192
+ flatbed_delivery
193
+ flatbed_pickup
194
+ guaranteed_delivery_am
195
+ guaranteed_delivery_pm
196
+ guaranteed_delivery
197
+ winery_delivery
198
+ winery_pickup
199
+ ]
200
+ end
201
+
202
+ def us_dot_number = 242_009
203
+ def us_mc_number = 170_247
204
+ def website_url = 'https://freight.rrts.com'
205
+ end
206
+
207
+ include FreightKit::Rateable
208
+
209
+ API = {
210
+ actions: { rates: :rate_quote_by_account },
211
+ domains: {
212
+ bol: 'tools.rrts.com',
213
+ pod: 'tools.rrts.com',
214
+ rates: 'webservices.rrts.com',
215
+ track: 'webservices.rrts.com',
216
+ tracking_number_from_pickup_number: 'tools.rrts.com'
217
+ },
218
+ endpoints: {
219
+ bol: '/LTLTrack/Home/ShowImage?proNumber=%%TRACKING_NUMBER%%&imageType=BOL',
220
+ pod: '/LTLTrack/Home/ShowImage?proNumber=%%TRACKING_NUMBER%%&imageType=POD',
221
+ rates: '/rating/ratequote.asmx?wsdl',
222
+ track: '/TrackWebApi/api/values',
223
+ tracking_number_from_pickup_number: '/LTLTrack/?searchValues=%%PICKUP_NUMBER%%'
224
+ },
225
+ soap: { namespaces: { rates: 'https://webservices.rrts.com/ratequote/' } },
226
+ use_ssl: { bol: false, pod: false, rates: false, track: true, tracking_number_from_pickup_number: false }
227
+ }.freeze
228
+ EVENTS = {
229
+ types: {
230
+ arrived_at_terminal: 'ARV',
231
+ delayed_due_to_weather: 'WTR',
232
+ delivered: 'DEL',
233
+ delivery_appointment_scheduled: 'APT',
234
+ departed: 'DSP',
235
+ located: 'ENR',
236
+ out_for_delivery: 'OFD',
237
+ pending_delivery_appointment: 'CFA',
238
+ picked_up: 'PU',
239
+ trailer_closed: 'CLO',
240
+ trailer_unloaded: 'UNL'
241
+ }
242
+ }.freeze
243
+
244
+ # Documents
245
+
246
+ def find_tracking_info(tracking_number)
247
+ response = commit_tracking_request(tracking_number)
248
+
249
+ parse_tracking_response(response)
250
+ end
251
+
252
+ def find_tracking_number_from_pickup_number(pickup_number, _date)
253
+ parse_tracking_number_from_pickup_number_response(pickup_number)
254
+ end
255
+
256
+ def pod(tracking_number) = parse_document_response(:pod, tracking_number)
257
+ def scanned_bol(tracking_number) = parse_document_response(:bol, tracking_number)
258
+
259
+ protected
260
+
261
+ def build_rate_request(shipment:)
262
+ api_credential = fetch_credential(:website)
263
+ validate_api_credential!(api_credential)
264
+
265
+ service_delivery_options = [
266
+ # API calls this invalid now
267
+ # service_options: { service_code: 'SS' }
268
+ ]
269
+
270
+ if shipment.accessorials.present?
271
+ serviceable_accessorials?(shipment.accessorials)
272
+
273
+ service_delivery_options = shipment.accessorials.excluding(*unquotable_accessorials).map do |accessorial|
274
+ { service_options: { service_code: mappable_accessorials[accessorial] } }
275
+ end
276
+ end
277
+
278
+ shipment.packages.each do |package|
279
+ longest_dimension = [package.width(:inches), package.length(:inches)].max.ceil
280
+
281
+ next if longest_dimension < 96
282
+
283
+ package.quantity.times do
284
+ if longest_dimension >= 240
285
+ service_delivery_options << { service_options: { service_code: 'EXX' } }
286
+ elsif longest_dimension >= 144
287
+ service_delivery_options << { service_options: { service_code: 'EXL' } }
288
+ elsif longest_dimension >= 96
289
+ service_delivery_options << { service_options: { service_code: 'EXM' } }
290
+ end
291
+ end
292
+ end
293
+
294
+ shipment_detail = []
295
+ shipment_box_count = 0
296
+ shipment_pallet_count = 0
297
+
298
+ shipment.packages.each do |package|
299
+ if package.packaging.type == 'pallet'
300
+ shipment_pallet_count += package.quantity
301
+ else
302
+ shipment_box_count += package.quantity
303
+ end
304
+
305
+ package.quantity.times do
306
+ shipment_detail << { 'ActualClass' => package.freight_class, 'Weight' => package.pounds(:each).ceil }
307
+ end
308
+ end
309
+
310
+ cubic_feet = if shipment.packages.map { |package| package.cubic_ft(:each) }.any?(nil)
311
+ nil
312
+ else
313
+ shipment.packages.sum { |package| package.cubic_ft(:total) }.ceil
314
+ end
315
+
316
+ request = {
317
+ 'request' => {
318
+ account: api_credential.account,
319
+ cubic_feet:,
320
+ destination_zip: shipment.destination.postal_code.gsub(/\s+/, '').upcase,
321
+ # linear_feet: linear_ft(packages),
322
+ origin_type: 'B', # O for shipper, I for consignee, B for third party
323
+ origin_zip: shipment.origin.postal_code.gsub(/\s+/, '').upcase,
324
+ pallet_count: shipment_pallet_count,
325
+ payment_type: 'P', # prepaid
326
+ pieces: shipment_box_count,
327
+ service_delivery_options:,
328
+ shipment_details: { shipment_detail: }
329
+ }
330
+ }
331
+
332
+ save_request(request)
333
+ request
334
+ end
335
+
336
+ def build_soap_header(action)
337
+ api_credential = fetch_credential(:website)
338
+ validate_api_credential!(api_credential)
339
+
340
+ {
341
+ authentication_header: {
342
+ :@xmlns => API.dig(:soap, :namespaces, action),
343
+ password: api_credential.password,
344
+ user_name: api_credential.username
345
+ }
346
+ }
347
+ end
348
+
349
+ def commit(action, request)
350
+ client_args = {
351
+ wsdl: request_url(action),
352
+ convert_request_keys_to: :camelcase,
353
+ env_namespace: :soap,
354
+ element_form_default: :qualified
355
+ }
356
+
357
+ call_args = { soap_header: build_soap_header(action), message: request }
358
+
359
+ soap_operation = API.dig(:actions, action)
360
+
361
+ client = ::FreightKit::SoapClient.new(carrier: self, action:, client_args:, call_args:, soap_operation:)
362
+ client.call(handle_soap_fault_error: false)
363
+ rescue Savon::SOAPFault => e
364
+ invalid_user = e.message.include?('RRTS.Common.BLL.InvalidUserException')
365
+ raise InvalidCredentialsError, 'Invalid credentials' if invalid_user
366
+
367
+ error = if e.respond_to?(:to_hash)
368
+ error_hash = e.to_hash
369
+
370
+ {
371
+ message: error_hash.dig(:fault, :detail, :error, :error_message),
372
+ number: error_hash.dig(:fault, :detail, :error, :error_number)
373
+ }
374
+ else
375
+ {}
376
+ end
377
+
378
+ if error[:message].blank?
379
+ erorr[:message] = if error[:number].present?
380
+ "Error #{error[:number]}"
381
+ else
382
+ 'Unknown error'
383
+ end
384
+ end
385
+
386
+ { error: }
387
+ end
388
+
389
+ def commit_tracking_request(tracking_number)
390
+ uri = URI.parse("#{request_url(:track)}/#{tracking_number}")
391
+ save_request(uri)
392
+
393
+ uri.open
394
+ rescue OpenURI::HTTPError, Errno::EHOSTUNREACH
395
+ nil
396
+ end
397
+
398
+ def parse_amount(amount)
399
+ negative = amount.start_with?('-$') || amount.start_with?('-')
400
+
401
+ ['$', '-', ','].each do |char|
402
+ amount = amount.sub(char, '')
403
+ end
404
+
405
+ return 0 if amount.blank?
406
+
407
+ amount = (amount.to_f * 100).to_i
408
+ return amount unless negative
409
+
410
+ amount * -1
411
+ end
412
+
413
+ def parse_api_date_time(date_time, location)
414
+ return if date_time.blank? || date_time == '0001-01-01T00:00:00'
415
+
416
+ local_date_time = ::Time.strptime(date_time, '%Y-%m-%dT%H:%M:%S').to_fs(:db)
417
+ ::FreightKit::DateTime.new(local_date_time:, location:)
418
+ end
419
+
420
+ def parse_api_location(comment, delimiters)
421
+ return if comment.blank? || !comment.include?(delimiters[0])
422
+
423
+ parts = if delimiters.size == 2
424
+ comment.split(delimiters[0])[0].split(delimiters[1])[1].split(',')
425
+ else
426
+ comment.split(delimiters[0])[1].split(',')
427
+ end
428
+
429
+ if parts.size == 1
430
+ str = parts[0].downcase
431
+ return Location.new(city: 'Long Beach', province: 'CA', country: ActiveUtils::Country.find('USA')) if str.include?('long beach')
432
+
433
+ return
434
+ end
435
+
436
+ city = parts[0].squish.strip.titleize
437
+ province = parts[1].gsub('.', '').squish.strip.upcase
438
+ country = ActiveUtils::Country.find('USA')
439
+
440
+ Location.new(city:, province:, country:)
441
+ end
442
+
443
+ def parse_document_response(type, tracking_number)
444
+ url = request_url(type).sub('%%TRACKING_NUMBER%%', tracking_number.to_s)
445
+ document_response = DocumentResponse.new(request: url)
446
+
447
+ begin
448
+ doc = Nokogiri::HTML(URI.parse(url).open)
449
+ rescue OpenURI::HTTPError
450
+ document_response.error = FreightKit::DocumentNotFoundError.new
451
+ return document_response
452
+ end
453
+
454
+ if doc.css('img').blank?
455
+ document_response.error = FreightKit::DocumentNotFoundError.new
456
+ return document_response
457
+ end
458
+
459
+ data = Base64.decode64(doc.css('img').first['src'].split('data:image/jpg;base64,').last)
460
+
461
+ document_response.assign_attributes(content_type: 'image/jpeg', data:)
462
+ document_response
463
+ end
464
+
465
+ def parse_rate_response(shipment:, response:)
466
+ rate_response = RateResponse.new(request: last_request, response:)
467
+
468
+ error_number = response.dig(:error, :number)&.to_i
469
+ error_message = response.dig(:error, :message)
470
+
471
+ if error_number.present?
472
+ case error_number
473
+ when 99_991
474
+ rate_response.error = UnserviceableError.new(error_message)
475
+ return rate_response
476
+ end
477
+ end
478
+
479
+ # @todo Don't rely on error_message
480
+
481
+ if error_message.present? && error_message.downcase.include?('not in the standard pickup area')
482
+ rate_response.error = UnserviceableError
483
+ return rate_response
484
+ end
485
+
486
+ if error_message.present? || error_number.present?
487
+ parts = [error_message]
488
+ parts << "(#{error_number})" if error_number.present?
489
+
490
+ message = parts.compact_blank.join(' ')
491
+
492
+ rate_response.error = ResponseError.new(message)
493
+ return rate_response
494
+ end
495
+
496
+ result = response.dig(:rate_quote_by_account_response, :rate_quote_by_account_result)
497
+
498
+ if result[:net_charge].blank?
499
+ rate_response.error = ResponseError.new('Cost is empty')
500
+ return rate_response
501
+ end
502
+
503
+ estimate_reference = result[:quote_number]
504
+ rate_details = result.dig(:rate_details, :quote_detail)
505
+ transit_days = result.dig(:routing_info, :estimated_transit_days).to_i
506
+
507
+ prices = []
508
+
509
+ rate_details.each do |rate_detail|
510
+ if rate_detail[:description].blank?
511
+ prices << Price.new(blame: :api, cents: parse_amount(rate_detail[:charge]), description: 'Freight')
512
+
513
+ next
514
+ end
515
+
516
+ prices << FreightKit::Price.new(
517
+ blame: :api,
518
+ cents: parse_amount(rate_detail[:charge]),
519
+ description: rate_detail[:description]&.capitalize
520
+ )
521
+ end
522
+
523
+ rate = Rate.new(
524
+ carrier: self,
525
+ carrier_name: name,
526
+ currency: 'USD',
527
+ estimate_reference:,
528
+ scac:,
529
+ service_name: :standard,
530
+ shipment:,
531
+ prices:,
532
+ transit_days:,
533
+ with_excessive_length_fees: rates_with_excessive_length_fees?
534
+ )
535
+
536
+ rate_response.rates = [rate]
537
+ rate_response
538
+ end
539
+
540
+ def parse_tracking_number_from_pickup_number_response(pickup_number)
541
+ url = request_url(:tracking_number_from_pickup_number).sub('%%PICKUP_NUMBER%%', pickup_number.to_s)
542
+
543
+ begin
544
+ doc = Nokogiri::HTML(URI.parse(url).open)
545
+ rescue OpenURI::HTTPError, Errno::EHOSTUNREACH
546
+ return
547
+ end
548
+
549
+ pro = doc.css('#lblProNumber')&.text
550
+
551
+ return if pro.blank? || pro.downcase.include?('not available')
552
+
553
+ pro
554
+ end
555
+
556
+ def parse_tracking_response(response)
557
+ tracking_response = TrackingResponse.new(carrier: self, request: last_request, response:)
558
+
559
+ json = JSON.parse(response&.read || '{}')
560
+
561
+ if json['SearchResults'].blank? || response.status[0] != '200'
562
+ tracking_response.error = ShipmentNotFoundError.new
563
+ return tracking_response
564
+ end
565
+
566
+ search_result = json['SearchResults']&.first
567
+
568
+ pro = search_result.dig('Shipment', 'ProNumber')&.downcase
569
+ if pro.blank? || pro.downcase.include?('not available')
570
+ tracking_response.error = ShipmentNotFoundError.new
571
+ return tracking_response
572
+ end
573
+
574
+ receiver_location = Location.new(
575
+ city: search_result.dig('Shipment', 'Consignee', 'City').titleize,
576
+ province: search_result.dig('Shipment', 'Consignee', 'State').upcase,
577
+ country: ActiveUtils::Country.find('USA')
578
+ )
579
+
580
+ shipper_location = Location.new(
581
+ city: search_result.dig('Shipment', 'Origin', 'City').titleize,
582
+ province: search_result.dig('Shipment', 'Origin', 'State').upcase,
583
+ country: ActiveUtils::Country.find('USA')
584
+ )
585
+
586
+ api_date_time = search_result.dig('Shipment', 'DeliveredDateTime')
587
+ actual_delivery_date = parse_api_date_time(api_date_time, receiver_location)
588
+
589
+ api_date_time = search_result.dig('Shipment', 'ApptDateTime')
590
+ scheduled_delivery_date = parse_api_date_time(api_date_time, receiver_location)
591
+
592
+ tracking_number = search_result.dig('Shipment', 'SearchItem')
593
+
594
+ api_date_time = search_result.dig('Shipment', 'ProDateTime')
595
+ ship_time = parse_api_date_time(api_date_time, shipper_location)
596
+
597
+ last_location = nil
598
+ shipment_events = []
599
+
600
+ search_result.dig('Shipment', 'Comments').each do |api_event|
601
+ type_code = api_event['ActivityCode']
602
+ next if !type_code || type_code == 'ARQ'
603
+
604
+ event = EVENTS[:types].key(type_code)
605
+ next if event.blank?
606
+
607
+ comment = strip_date(api_event['StatusComment'])
608
+
609
+ location = case event
610
+ when :arrived_at_terminal
611
+ parse_api_location(comment, [' terminal in '])
612
+ when :delayed_due_to_weather,
613
+ :delivery_appointment_scheduled,
614
+ :pending_delivery_appointment,
615
+ :trailer_closed,
616
+ :trailer_unloaded
617
+ last_location
618
+ when :delivered
619
+ receiver_location
620
+ when :departed, :out_for_delivery
621
+ parse_api_location(comment, [' to ', 'from '])
622
+ when :located
623
+ parse_api_location(comment, [' currently at '])
624
+ when :picked_up
625
+ shipper_location
626
+ end
627
+
628
+ date_time = parse_api_date_time(api_event['StatusDateTime'], location)
629
+
630
+ last_location = location
631
+
632
+ shipment_events << ShipmentEvent.new(date_time:, location:, type_code: event)
633
+ end
634
+
635
+ status = shipment_events.last&.type_code
636
+
637
+ tracking_response.assign_attributes(
638
+ actual_delivery_date:,
639
+ destination: receiver_location,
640
+ origin: shipper_location,
641
+ scheduled_delivery_date:,
642
+ ship_time:,
643
+ shipment_events:,
644
+ status:,
645
+ tracking_number:
646
+ )
647
+
648
+ tracking_response
649
+ end
650
+
651
+ def request_url(action)
652
+ scheme = API.dig(:use_ssl, action) ? 'https://' : 'http://'
653
+ "#{scheme}#{API.dig(:domains, action)}#{API.dig(:endpoints, action)}"
654
+ end
655
+
656
+ def strip_date(str) = str ? str.split(/[A|P]M /)[1] : nil
657
+
658
+ def validate_api_credential!(api_credential)
659
+ %i[account password username].each do |attribute|
660
+ if !api_credential.respond_to?(attribute) || api_credential.public_send(attribute).blank?
661
+ raise InvalidCredentialsError, "Invalid #{attribute}"
662
+ end
663
+
664
+ next unless attribute == :account
665
+
666
+ # Raises vague input exception from API if we don't handle ourselves
667
+ next if api_credential.account.gsub(/\D/, '') == api_credential.account &&
668
+ api_credential.account.length >= 6
669
+
670
+ raise InvalidCredentialsError, 'Invalid account'
671
+ end
672
+ end
673
+ end
674
+ end
675
+ end
@@ -0,0 +1,13 @@
1
+ module FreightKit
2
+ module Carriers
3
+ class Roadtex < Carrier
4
+ class << self
5
+ def id = 'ba150145-1415-4b0d-8b52-120a1db0de8d'
6
+ def legal_name = 'Roadtex, LLC'
7
+ def name = 'Roadtex'
8
+ def us_dot_number = 2_221_701
9
+ def us_mc_number = 291_713
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,10 @@
1
+ module FreightKit
2
+ module Carriers
3
+ class RonaldTransportServices < Carrier
4
+ class << self
5
+ def id = '05c7f3e1-71ae-41ce-b3bb-5ab6842b4b9f'
6
+ def name = 'Ronald Transport Services'
7
+ end
8
+ end
9
+ end
10
+ end