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.
Files changed (466) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -2
  3. data/README.md +6 -5
  4. data/Rakefile +4 -0
  5. data/VERSION +1 -1
  6. data/configuration/locations/amazon_warehouses.yml +3330 -0
  7. data/freight_kit-0.1.21.gem +0 -0
  8. data/freight_kit.gemspec +11 -22
  9. data/lib/freight_kit/address_normalizer.rb +24 -0
  10. data/lib/freight_kit/amazon_warehouse.rb +33 -0
  11. data/lib/freight_kit/api_clients/soap_client.rb +33 -10
  12. data/lib/freight_kit/carrier.rb +248 -302
  13. data/lib/freight_kit/carriers/a1_express.rb +25 -0
  14. data/lib/freight_kit/carriers/a_duie_pyle.rb +30 -0
  15. data/lib/freight_kit/carriers/aaa_cooper.rb +11 -0
  16. data/lib/freight_kit/carriers/aaa_expedited_services.rb +10 -0
  17. data/lib/freight_kit/carriers/ab_brothers_usa_inc.rb +12 -0
  18. data/lib/freight_kit/carriers/aberdeen_express_inc.rb +28 -0
  19. data/lib/freight_kit/carriers/abf_freight_system.rb +475 -0
  20. data/lib/freight_kit/carriers/access_transport.rb +10 -0
  21. data/lib/freight_kit/carriers/action_express.rb +10 -0
  22. data/lib/freight_kit/carriers/adams_and_companies.rb +10 -0
  23. data/lib/freight_kit/carriers/advance_distribution.rb +28 -0
  24. data/lib/freight_kit/carriers/alcon_transport.rb +10 -0
  25. data/lib/freight_kit/carriers/all_freight.rb +10 -0
  26. data/lib/freight_kit/carriers/alliance_transportation_group.rb +10 -0
  27. data/lib/freight_kit/carriers/allstate_transport.rb +10 -0
  28. data/lib/freight_kit/carriers/aloha_freight_forwarders.rb +31 -0
  29. data/lib/freight_kit/carriers/amado_trucking.rb +31 -0
  30. data/lib/freight_kit/carriers/american_fast_freight.rb +28 -0
  31. data/lib/freight_kit/carriers/amigos_service_transportation.rb +10 -0
  32. data/lib/freight_kit/carriers/anderson_towing_and_transport.rb +10 -0
  33. data/lib/freight_kit/carriers/apex_transporting.rb +10 -0
  34. data/lib/freight_kit/carriers/archer_cargo.rb +35 -0
  35. data/lib/freight_kit/carriers/armstrong_transport_group.rb +10 -0
  36. data/lib/freight_kit/carriers/autobahn_logistics.rb +10 -0
  37. data/lib/freight_kit/carriers/averitt_express.rb +30 -0
  38. data/lib/freight_kit/carriers/ba_transportation.rb +10 -0
  39. data/lib/freight_kit/carriers/balkin_express.rb +10 -0
  40. data/lib/freight_kit/carriers/bay_area_express.rb +10 -0
  41. data/lib/freight_kit/carriers/bc_freightways.rb +11 -0
  42. data/lib/freight_kit/carriers/benjamin_best_freight_inc.rb +37 -0
  43. data/lib/freight_kit/carriers/bennett_trucking.rb +10 -0
  44. data/lib/freight_kit/carriers/best_overnite_express.rb +78 -0
  45. data/lib/freight_kit/carriers/best_trucking.rb +10 -0
  46. data/lib/freight_kit/carriers/bestway_transport.rb +10 -0
  47. data/lib/freight_kit/carriers/bryan_systems.rb +10 -0
  48. data/lib/freight_kit/carriers/c_and_w_express.rb +10 -0
  49. data/lib/freight_kit/carriers/campbell_trucking.rb +10 -0
  50. data/lib/freight_kit/carriers/carde_transportation.rb +10 -0
  51. data/lib/freight_kit/carriers/cardinal_logistics.rb +28 -0
  52. data/lib/freight_kit/carriers/cdc_transport.rb +10 -0
  53. data/lib/freight_kit/carriers/cdo_express_diversified.rb +10 -0
  54. data/lib/freight_kit/carriers/cedar_supply_trucking.rb +10 -0
  55. data/lib/freight_kit/carriers/central_freight_lines.rb +12 -0
  56. data/lib/freight_kit/carriers/central_transport.rb +12 -0
  57. data/lib/freight_kit/carriers/chicago_suburban_express.rb +28 -0
  58. data/lib/freight_kit/carriers/city_logistics.rb +11 -0
  59. data/lib/freight_kit/carriers/clear_lane_freight_systems.rb +474 -0
  60. data/lib/freight_kit/carriers/cleopatra_trucking.rb +10 -0
  61. data/lib/freight_kit/carriers/clifford_transportation.rb +10 -0
  62. data/lib/freight_kit/carriers/cms_domestic.rb +25 -0
  63. data/lib/freight_kit/carriers/cnd_logistics.rb +10 -0
  64. data/lib/freight_kit/carriers/coast_to_coast_transport.rb +27 -0
  65. data/lib/freight_kit/carriers/countrywide_carriers.rb +10 -0
  66. data/lib/freight_kit/carriers/cpl_express.rb +31 -0
  67. data/lib/freight_kit/carriers/crosby_trucking_service.rb +29 -0
  68. data/lib/freight_kit/carriers/cross_country_freight_solutions.rb +408 -0
  69. data/lib/freight_kit/carriers/crowley.rb +10 -0
  70. data/lib/freight_kit/carriers/csa_transportation.rb +40 -0
  71. data/lib/freight_kit/carriers/csx_transportation.rb +40 -0
  72. data/lib/freight_kit/carriers/custom_global_logistics.rb +14 -0
  73. data/lib/freight_kit/carriers/d_and_a_transport.rb +10 -0
  74. data/lib/freight_kit/carriers/dak_transport.rb +10 -0
  75. data/lib/freight_kit/carriers/dash_courier_and_logistics_north_carolina.rb +10 -0
  76. data/lib/freight_kit/carriers/daylight_transport.rb +29 -0
  77. data/lib/freight_kit/carriers/dayton_freight_lines.rb +30 -0
  78. data/lib/freight_kit/carriers/dbr_logistics.rb +10 -0
  79. data/lib/freight_kit/carriers/deep_south_freight.rb +27 -0
  80. data/lib/freight_kit/carriers/delta_express.rb +10 -0
  81. data/lib/freight_kit/carriers/delta_transport.rb +10 -0
  82. data/lib/freight_kit/carriers/delta_trucking_logistics.rb +10 -0
  83. data/lib/freight_kit/carriers/demco_express.rb +10 -0
  84. data/lib/freight_kit/carriers/dependable_global_express.rb +10 -0
  85. data/lib/freight_kit/carriers/dependable_hawaiian_express.rb +24 -0
  86. data/lib/freight_kit/carriers/dependable_highway_express.rb +573 -0
  87. data/lib/freight_kit/carriers/desert_coastal_transport.rb +10 -0
  88. data/lib/freight_kit/carriers/dhl.rb +11 -0
  89. data/lib/freight_kit/carriers/diamond_line_delivery.rb +174 -0
  90. data/lib/freight_kit/carriers/ding_tai_trucking.rb +10 -0
  91. data/lib/freight_kit/carriers/diversified_transfer_and_storage.rb +29 -0
  92. data/lib/freight_kit/carriers/dohrn_transfer_company.rb +30 -0
  93. data/lib/freight_kit/carriers/dot_line_transportation.rb +29 -0
  94. data/lib/freight_kit/carriers/drt_transportation.rb +13 -0
  95. data/lib/freight_kit/carriers/dugan_truck_line.rb +29 -0
  96. data/lib/freight_kit/carriers/dupont.rb +10 -0
  97. data/lib/freight_kit/carriers/e_transport_carriers.rb +29 -0
  98. data/lib/freight_kit/carriers/echo_global_logistics.rb +13 -0
  99. data/lib/freight_kit/carriers/ecklund_logistics.rb +10 -0
  100. data/lib/freight_kit/carriers/el_emplumado_transport.rb +10 -0
  101. data/lib/freight_kit/carriers/elite_carriers.rb +28 -0
  102. data/lib/freight_kit/carriers/emerald_express.rb +10 -0
  103. data/lib/freight_kit/carriers/era_transport.rb +10 -0
  104. data/lib/freight_kit/carriers/estes_express_lines.rb +25 -0
  105. data/lib/freight_kit/carriers/euro_kam.rb +28 -0
  106. data/lib/freight_kit/carriers/ew_riverside_trucking.rb +10 -0
  107. data/lib/freight_kit/carriers/express_2000_inc.rb +12 -0
  108. data/lib/freight_kit/carriers/express_services_international.rb +10 -0
  109. data/lib/freight_kit/carriers/f_and_a_express.rb +27 -0
  110. data/lib/freight_kit/carriers/fairmont_logistics.rb +13 -0
  111. data/lib/freight_kit/carriers/fargo_cargo.rb +10 -0
  112. data/lib/freight_kit/carriers/fast_freight_transportation.rb +10 -0
  113. data/lib/freight_kit/carriers/fast_load_transport.rb +10 -0
  114. data/lib/freight_kit/carriers/fed_ex_express.rb +30 -0
  115. data/lib/freight_kit/carriers/fed_ex_ground.rb +24 -0
  116. data/lib/freight_kit/carriers/fed_ex_ltl_economy.rb +11 -0
  117. data/lib/freight_kit/carriers/fed_ex_ltl_priority.rb +11 -0
  118. data/lib/freight_kit/carriers/first_trucking_express.rb +10 -0
  119. data/lib/freight_kit/carriers/flash_trucking.rb +10 -0
  120. data/lib/freight_kit/carriers/fort_transportation_and_service_company_inc.rb +37 -0
  121. data/lib/freight_kit/carriers/forward_air.rb +781 -0
  122. data/lib/freight_kit/carriers/frahtex.rb +10 -0
  123. data/lib/freight_kit/carriers/frozen_food_express.rb +10 -0
  124. data/lib/freight_kit/carriers/gholia_bros_trucking.rb +36 -0
  125. data/lib/freight_kit/carriers/global_cargo.rb +10 -0
  126. data/lib/freight_kit/carriers/global_logistics_and_transportation.rb +10 -0
  127. data/lib/freight_kit/carriers/gls_freight.rb +32 -0
  128. data/lib/freight_kit/carriers/go_trucking_services.rb +10 -0
  129. data/lib/freight_kit/carriers/gold_eagle_transportation.rb +11 -0
  130. data/lib/freight_kit/carriers/golden_drop_trucking.rb +10 -0
  131. data/lib/freight_kit/carriers/gonzalez_transportation.rb +10 -0
  132. data/lib/freight_kit/carriers/gps_transport.rb +10 -0
  133. data/lib/freight_kit/carriers/greene_enterprise.rb +10 -0
  134. data/lib/freight_kit/carriers/gsa_international.rb +10 -0
  135. data/lib/freight_kit/carriers/gsp_express.rb +24 -0
  136. data/lib/freight_kit/carriers/gsv_transportation.rb +10 -0
  137. data/lib/freight_kit/carriers/gta_transportation.rb +10 -0
  138. data/lib/freight_kit/carriers/guam_freight_services.rb +10 -0
  139. data/lib/freight_kit/carriers/harrah_transportation.rb +23 -0
  140. data/lib/freight_kit/carriers/her_trucking.rb +10 -0
  141. data/lib/freight_kit/carriers/hercules_freight.rb +20 -0
  142. data/lib/freight_kit/carriers/highlander_xpress.rb +36 -0
  143. data/lib/freight_kit/carriers/hn_transport.rb +10 -0
  144. data/lib/freight_kit/carriers/honolulu_freight_service.rb +10 -0
  145. data/lib/freight_kit/carriers/hot_line_freight_system_inc.rb +12 -0
  146. data/lib/freight_kit/carriers/hotshot_freight_of_texas.rb +13 -0
  147. data/lib/freight_kit/carriers/houser_transport.rb +27 -0
  148. data/lib/freight_kit/carriers/infiniti_freight_logistics.rb +28 -0
  149. data/lib/freight_kit/carriers/infinity_trucking.rb +10 -0
  150. data/lib/freight_kit/carriers/interstate_tma.rb +10 -0
  151. data/lib/freight_kit/carriers/intrade_industries.rb +10 -0
  152. data/lib/freight_kit/carriers/jasper_trucking.rb +28 -0
  153. data/lib/freight_kit/carriers/jb_hunt.rb +11 -0
  154. data/lib/freight_kit/carriers/jfj_transportation.rb +8 -8
  155. data/lib/freight_kit/carriers/jkb_express.rb +10 -0
  156. data/lib/freight_kit/carriers/jlm_transport.rb +10 -0
  157. data/lib/freight_kit/carriers/johansson_transport.rb +10 -0
  158. data/lib/freight_kit/carriers/jones_express.rb +10 -0
  159. data/lib/freight_kit/carriers/jp_logistics.rb +41 -0
  160. data/lib/freight_kit/carriers/just_in_time_cargo.rb +29 -0
  161. data/lib/freight_kit/carriers/kengkok_times.rb +10 -0
  162. data/lib/freight_kit/carriers/kings_express.rb +10 -0
  163. data/lib/freight_kit/carriers/klc_transportation.rb +10 -0
  164. data/lib/freight_kit/carriers/km_trucking.rb +10 -0
  165. data/lib/freight_kit/carriers/kma_logistics.rb +10 -0
  166. data/lib/freight_kit/carriers/krc_logistics.rb +10 -0
  167. data/lib/freight_kit/carriers/ktx.rb +10 -0
  168. data/lib/freight_kit/carriers/landstar.rb +25 -0
  169. data/lib/freight_kit/carriers/lanter_distributing_llc.rb +30 -0
  170. data/lib/freight_kit/carriers/ld_trucking.rb +10 -0
  171. data/lib/freight_kit/carriers/legacy_logistics_solutions.rb +10 -0
  172. data/lib/freight_kit/carriers/leonards_express.rb +10 -0
  173. data/lib/freight_kit/carriers/liberty_linehaul_west.rb +28 -0
  174. data/lib/freight_kit/carriers/liberty_transport.rb +10 -0
  175. data/lib/freight_kit/carriers/lightning_express.rb +10 -0
  176. data/lib/freight_kit/carriers/lj_express.rb +24 -0
  177. data/lib/freight_kit/carriers/lkp_enterprises.rb +10 -0
  178. data/lib/freight_kit/carriers/ltl_pros.rb +28 -0
  179. data/lib/freight_kit/carriers/m_and_m_and_sons.rb +10 -0
  180. data/lib/freight_kit/carriers/mag_lines_transport.rb +10 -0
  181. data/lib/freight_kit/carriers/magic_messenger.rb +24 -0
  182. data/lib/freight_kit/carriers/majors_transit.rb +10 -0
  183. data/lib/freight_kit/carriers/map_global_logistics.rb +10 -0
  184. data/lib/freight_kit/carriers/matths_trucking.rb +11 -0
  185. data/lib/freight_kit/carriers/mav_canadian_transport.rb +13 -0
  186. data/lib/freight_kit/carriers/mc_systems.rb +35 -0
  187. data/lib/freight_kit/carriers/mega_fleet.rb +10 -0
  188. data/lib/freight_kit/carriers/mega_trans_group.rb +28 -0
  189. data/lib/freight_kit/carriers/meta_express.rb +10 -0
  190. data/lib/freight_kit/carriers/mia_transportation.rb +10 -0
  191. data/lib/freight_kit/carriers/midwest_motor_express.rb +14 -0
  192. data/lib/freight_kit/carriers/midwest_transport_and_trucking.rb +10 -0
  193. data/lib/freight_kit/carriers/mikade_delivery_service.rb +10 -0
  194. data/lib/freight_kit/carriers/mohoff_freight_lines.rb +23 -0
  195. data/lib/freight_kit/carriers/montata_travelers_express.rb +10 -0
  196. data/lib/freight_kit/carriers/morgan_van_lines.rb +29 -0
  197. data/lib/freight_kit/carriers/moto_transportation.rb +24 -0
  198. data/lib/freight_kit/carriers/mountain_valley_express.rb +197 -0
  199. data/lib/freight_kit/carriers/ms_freight.rb +27 -0
  200. data/lib/freight_kit/carriers/mvg_transport.rb +10 -0
  201. data/lib/freight_kit/carriers/n_and_m_transfer_co_inc.rb +29 -0
  202. data/lib/freight_kit/carriers/nabot_transport_solutions.rb +10 -0
  203. data/lib/freight_kit/carriers/national_freight_xpress.rb +10 -0
  204. data/lib/freight_kit/carriers/navigation_group.rb +10 -0
  205. data/lib/freight_kit/carriers/nelson_trucking.rb +10 -0
  206. data/lib/freight_kit/carriers/network_1_transportation.rb +10 -0
  207. data/lib/freight_kit/carriers/new_century_transport.rb +28 -0
  208. data/lib/freight_kit/carriers/new_penn_motor_express.rb +11 -0
  209. data/lib/freight_kit/carriers/nieves_transportation.rb +10 -0
  210. data/lib/freight_kit/carriers/nolan_transportation_group.rb +26 -0
  211. data/lib/freight_kit/carriers/northland_trucking.rb +10 -0
  212. data/lib/freight_kit/carriers/northwest_carrier_logistics.rb +27 -0
  213. data/lib/freight_kit/carriers/nt_usa.rb +10 -0
  214. data/lib/freight_kit/carriers/nu_line_transportation.rb +10 -0
  215. data/lib/freight_kit/carriers/numark_transportation.rb +80 -0
  216. data/lib/freight_kit/carriers/nvk_transport.rb +10 -0
  217. data/lib/freight_kit/carriers/ny_transport.rb +10 -0
  218. data/lib/freight_kit/carriers/oak_harbor.rb +28 -0
  219. data/lib/freight_kit/carriers/oakline_transportation.rb +10 -0
  220. data/lib/freight_kit/carriers/old_dominion_freight_line.rb +30 -0
  221. data/lib/freight_kit/carriers/on_trac.rb +555 -0
  222. data/lib/freight_kit/carriers/one_hundred_one_transport.rb +10 -0
  223. data/lib/freight_kit/carriers/one_way_delivery.rb +10 -0
  224. data/lib/freight_kit/carriers/oracle_transportation_solutions.rb +10 -0
  225. data/lib/freight_kit/carriers/orange_courier.rb +27 -0
  226. data/lib/freight_kit/carriers/ortas_trucking.rb +10 -0
  227. data/lib/freight_kit/carriers/pac_trux_transportation.rb +10 -0
  228. data/lib/freight_kit/carriers/pacer.rb +10 -0
  229. data/lib/freight_kit/carriers/pacific_logistics.rb +10 -0
  230. data/lib/freight_kit/carriers/pacific_states_truck_lines.rb +10 -0
  231. data/lib/freight_kit/carriers/paradise_distributing.rb +10 -0
  232. data/lib/freight_kit/carriers/paramount_freight_systems.rb +10 -0
  233. data/lib/freight_kit/carriers/peninsula_truck_lines.rb +206 -0
  234. data/lib/freight_kit/carriers/pg_transport.rb +10 -0
  235. data/lib/freight_kit/carriers/pgs_360.rb +10 -0
  236. data/lib/freight_kit/carriers/pilot_freight_services.rb +10 -0
  237. data/lib/freight_kit/carriers/pious_trans.rb +27 -0
  238. data/lib/freight_kit/carriers/pitt_ohio_express.rb +30 -0
  239. data/lib/freight_kit/carriers/pki_logistics.rb +12 -0
  240. data/lib/freight_kit/carriers/plana_transportation.rb +28 -0
  241. data/lib/freight_kit/carriers/prestige.rb +10 -0
  242. data/lib/freight_kit/carriers/pro_trans_solutions.rb +28 -0
  243. data/lib/freight_kit/carriers/puma_logistics.rb +10 -0
  244. data/lib/freight_kit/carriers/pwc_international.rb +10 -0
  245. data/lib/freight_kit/carriers/quality_logistics.rb +10 -0
  246. data/lib/freight_kit/carriers/queen_star_trucking.rb +27 -0
  247. data/lib/freight_kit/carriers/r_and_l_carriers.rb +11 -0
  248. data/lib/freight_kit/carriers/rac_transport.rb +10 -0
  249. data/lib/freight_kit/carriers/re_logistics.rb +23 -0
  250. data/lib/freight_kit/carriers/reddaway.rb +11 -0
  251. data/lib/freight_kit/carriers/reefer_van_network.rb +13 -0
  252. data/lib/freight_kit/carriers/refrigerated_trucking_and_ltl_transportation_services.rb +10 -0
  253. data/lib/freight_kit/carriers/ridgeline_express.rb +10 -0
  254. data/lib/freight_kit/carriers/rist_transport.rb +29 -0
  255. data/lib/freight_kit/carriers/river_city_transport.rb +10 -0
  256. data/lib/freight_kit/carriers/roadrunner_transportation_services.rb +669 -0
  257. data/lib/freight_kit/carriers/roadtex.rb +13 -0
  258. data/lib/freight_kit/carriers/ronald_transport_services.rb +10 -0
  259. data/lib/freight_kit/carriers/rose_trucking.rb +24 -0
  260. data/lib/freight_kit/carriers/rp_and_j_transport.rb +24 -0
  261. data/lib/freight_kit/carriers/rpm_transportation.rb +11 -0
  262. data/lib/freight_kit/carriers/rude_transportation.rb +30 -0
  263. data/lib/freight_kit/carriers/s_and_s_logistics.rb +10 -0
  264. data/lib/freight_kit/carriers/saia.rb +456 -362
  265. data/lib/freight_kit/carriers/sb_transportation.rb +27 -0
  266. data/lib/freight_kit/carriers/schneider_national.rb +29 -0
  267. data/lib/freight_kit/carriers/schwarz_trucking.rb +10 -0
  268. data/lib/freight_kit/carriers/sewell_motor_express.rb +29 -0
  269. data/lib/freight_kit/carriers/shawnee_trucking.rb +28 -0
  270. data/lib/freight_kit/carriers/shi_logistics.rb +10 -0
  271. data/lib/freight_kit/carriers/sinbad_transport.rb +10 -0
  272. data/lib/freight_kit/carriers/skyway.rb +10 -0
  273. data/lib/freight_kit/carriers/smith_cargo_transportation_services.rb +23 -0
  274. data/lib/freight_kit/carriers/sna_transportation.rb +10 -0
  275. data/lib/freight_kit/carriers/solid_group.rb +10 -0
  276. data/lib/freight_kit/carriers/solution_carrier_express.rb +10 -0
  277. data/lib/freight_kit/carriers/southeastern_freight_lines.rb +441 -0
  278. data/lib/freight_kit/carriers/southwestern_motor_transport.rb +30 -0
  279. data/lib/freight_kit/carriers/span_alaska.rb +10 -0
  280. data/lib/freight_kit/carriers/specialize_transportation.rb +27 -0
  281. data/lib/freight_kit/carriers/ssi_refrigerated_express.rb +10 -0
  282. data/lib/freight_kit/carriers/standard_forwarding_llc.rb +28 -0
  283. data/lib/freight_kit/carriers/star_american_enterprise.rb +10 -0
  284. data/lib/freight_kit/carriers/sterling_transportation.rb +10 -0
  285. data/lib/freight_kit/carriers/stg.rb +163 -0
  286. data/lib/freight_kit/carriers/supervan_service.rb +10 -0
  287. data/lib/freight_kit/carriers/sutton_transport_inc.rb +12 -0
  288. data/lib/freight_kit/carriers/swift_transportation.rb +28 -0
  289. data/lib/freight_kit/carriers/t_force_worldwide.rb +605 -0
  290. data/lib/freight_kit/carriers/tax_airfreight_inc.rb +35 -0
  291. data/lib/freight_kit/carriers/tforce_freight_inc.rb +30 -0
  292. data/lib/freight_kit/carriers/the_custom_companies.rb +162 -0
  293. data/lib/freight_kit/carriers/thk_trucking.rb +28 -0
  294. data/lib/freight_kit/carriers/tiger_cool_express.rb +11 -0
  295. data/lib/freight_kit/carriers/tili_logistics.rb +10 -0
  296. data/lib/freight_kit/carriers/tmt_industries.rb +10 -0
  297. data/lib/freight_kit/carriers/top_ten_express.rb +28 -0
  298. data/lib/freight_kit/carriers/total_quality_logistics.rb +339 -0
  299. data/lib/freight_kit/carriers/total_transportation.rb +258 -0
  300. data/lib/freight_kit/carriers/trans_international_trucking.rb +29 -0
  301. data/lib/freight_kit/carriers/treasure_transportation.rb +10 -0
  302. data/lib/freight_kit/carriers/tri_state_services.rb +10 -0
  303. data/lib/freight_kit/carriers/tritex_freighters.rb +10 -0
  304. data/lib/freight_kit/carriers/triways.rb +10 -0
  305. data/lib/freight_kit/carriers/tsi_kansas.rb +29 -0
  306. data/lib/freight_kit/carriers/u_and_r_transportation.rb +23 -0
  307. data/lib/freight_kit/carriers/union_pacific.rb +11 -0
  308. data/lib/freight_kit/carriers/united_freight_logistics.rb +10 -0
  309. data/lib/freight_kit/carriers/unlimited_distance_transportation.rb +10 -0
  310. data/lib/freight_kit/carriers/up_streamline.rb +10 -0
  311. data/lib/freight_kit/carriers/ups_freight.rb +12 -0
  312. data/lib/freight_kit/carriers/us_freightways.rb +10 -0
  313. data/lib/freight_kit/carriers/usa_truck.rb +28 -0
  314. data/lib/freight_kit/carriers/usf_holland.rb +11 -0
  315. data/lib/freight_kit/carriers/valley_cartage.rb +11 -0
  316. data/lib/freight_kit/carriers/vc_transport.rb +10 -0
  317. data/lib/freight_kit/carriers/vision_express.rb +11 -0
  318. data/lib/freight_kit/carriers/vision_logistics_group.rb +10 -0
  319. data/lib/freight_kit/carriers/vmg_transportation_group.rb +10 -0
  320. data/lib/freight_kit/carriers/volpe_express.rb +10 -0
  321. data/lib/freight_kit/carriers/ward_trucking.rb +29 -0
  322. data/lib/freight_kit/carriers/wdwb.rb +10 -0
  323. data/lib/freight_kit/carriers/western_flyer_express.rb +28 -0
  324. data/lib/freight_kit/carriers/western_regional_delivery_service.rb +265 -0
  325. data/lib/freight_kit/carriers/western_specialized_trucking.rb +22 -0
  326. data/lib/freight_kit/carriers/win_distribution.rb +28 -0
  327. data/lib/freight_kit/carriers/wlb_transport.rb +10 -0
  328. data/lib/freight_kit/carriers/x_trux.rb +29 -0
  329. data/lib/freight_kit/carriers/xpo_logistics.rb +415 -0
  330. data/lib/freight_kit/carriers/xpress_global_systems.rb +30 -0
  331. data/lib/freight_kit/carriers/xylo_trucking.rb +10 -0
  332. data/lib/freight_kit/carriers/yrc_freight.rb +24 -0
  333. data/lib/freight_kit/carriers/zentner_transportation.rb +28 -0
  334. data/lib/freight_kit/carriers.rb +331 -34
  335. data/lib/freight_kit/countries.rb +22 -0
  336. data/lib/freight_kit/error.rb +0 -2
  337. data/lib/freight_kit/errors/document_not_found_error.rb +0 -2
  338. data/lib/freight_kit/errors/expired_credentials_error.rb +0 -2
  339. data/lib/freight_kit/errors/http_error.rb +0 -2
  340. data/lib/freight_kit/errors/invalid_credentials_error.rb +0 -2
  341. data/lib/freight_kit/errors/rate_limit_error.rb +12 -0
  342. data/lib/freight_kit/errors/response_error.rb +0 -2
  343. data/lib/freight_kit/errors/shipment_not_found_error.rb +0 -2
  344. data/lib/freight_kit/errors/unserviceable_accessorials_error.rb +1 -5
  345. data/lib/freight_kit/errors/unserviceable_error.rb +0 -2
  346. data/lib/freight_kit/helpers/documentable.rb +0 -2
  347. data/lib/freight_kit/helpers/pickupable.rb +3 -14
  348. data/lib/freight_kit/helpers/rateable.rb +0 -2
  349. data/lib/freight_kit/helpers/trackable.rb +0 -2
  350. data/lib/freight_kit/http_client/cache_store.rb +2 -4
  351. data/lib/freight_kit/http_client/httpi_adapter.rb +37 -0
  352. data/lib/freight_kit/http_client/log_device.rb +0 -2
  353. data/lib/freight_kit/http_client/response.rb +0 -2
  354. data/lib/freight_kit/http_client/revalidation.rb +0 -2
  355. data/lib/freight_kit/http_client/safe_retries.rb +17 -3
  356. data/lib/freight_kit/http_client/zstd.rb +2 -4
  357. data/lib/freight_kit/http_client.rb +21 -21
  358. data/lib/freight_kit/model.rb +1 -3
  359. data/lib/freight_kit/models/address.rb +15 -0
  360. data/lib/freight_kit/models/contact.rb +3 -4
  361. data/lib/freight_kit/models/country.rb +20 -0
  362. data/lib/freight_kit/models/credential.rb +3 -18
  363. data/lib/freight_kit/models/date_time.rb +0 -2
  364. data/lib/freight_kit/models/document_response.rb +0 -2
  365. data/lib/freight_kit/models/label.rb +0 -2
  366. data/lib/freight_kit/models/location.rb +10 -25
  367. data/lib/freight_kit/models/pickup_response.rb +0 -2
  368. data/lib/freight_kit/models/price.rb +0 -2
  369. data/lib/freight_kit/models/rate.rb +0 -2
  370. data/lib/freight_kit/models/rate_response.rb +0 -2
  371. data/lib/freight_kit/models/region.rb +19 -0
  372. data/lib/freight_kit/models/response.rb +0 -2
  373. data/lib/freight_kit/models/shipment.rb +5 -14
  374. data/lib/freight_kit/models/shipment_event.rb +0 -2
  375. data/lib/freight_kit/models/terminal.rb +10 -0
  376. data/lib/freight_kit/models/tracking_response.rb +0 -2
  377. data/lib/freight_kit/package.rb +52 -64
  378. data/lib/freight_kit/package_item.rb +14 -14
  379. data/lib/freight_kit/packaging.rb +6 -26
  380. data/lib/freight_kit/platform.rb +0 -32
  381. data/lib/freight_kit/platforms/carrier_logistics.rb +326 -345
  382. data/lib/freight_kit/platforms/dsdc.rb +82 -0
  383. data/lib/freight_kit/platforms/next_tms/graphql_client/mutation/quote_create.rb +32 -0
  384. data/lib/freight_kit/platforms/next_tms/graphql_client/mutation/shipment_create.rb +29 -0
  385. data/lib/freight_kit/platforms/next_tms/graphql_client/query/broker_carrier.rb +37 -0
  386. data/lib/freight_kit/platforms/next_tms/graphql_client/query/broker_carriers.rb +45 -0
  387. data/lib/freight_kit/platforms/next_tms/graphql_client/query/broker_customer.rb +54 -0
  388. data/lib/freight_kit/platforms/next_tms/graphql_client/query/broker_customers.rb +62 -0
  389. data/lib/freight_kit/platforms/next_tms/graphql_client/query/carrier.rb +22 -0
  390. data/lib/freight_kit/platforms/next_tms/graphql_client/query/carriers.rb +30 -0
  391. data/lib/freight_kit/platforms/next_tms/graphql_client/query/customer.rb +20 -0
  392. data/lib/freight_kit/platforms/next_tms/graphql_client/query/customers.rb +28 -0
  393. data/lib/freight_kit/platforms/next_tms/graphql_client/query/invoice.rb +31 -0
  394. data/lib/freight_kit/platforms/next_tms/graphql_client/query/invoices.rb +39 -0
  395. data/lib/freight_kit/platforms/next_tms/graphql_client/query/shipment.rb +102 -0
  396. data/lib/freight_kit/platforms/next_tms/graphql_client/query/shipment_documents.rb +29 -0
  397. data/lib/freight_kit/platforms/next_tms/graphql_client/query/shipments.rb +110 -0
  398. data/lib/freight_kit/platforms/next_tms/graphql_client.rb +22 -0
  399. data/lib/freight_kit/platforms/next_tms/orm/address.rb +22 -0
  400. data/lib/freight_kit/platforms/next_tms/orm/base.rb +120 -0
  401. data/lib/freight_kit/platforms/next_tms/orm/broker_carrier.rb +18 -0
  402. data/lib/freight_kit/platforms/next_tms/orm/broker_customer.rb +22 -0
  403. data/lib/freight_kit/platforms/next_tms/orm/carrier.rb +14 -0
  404. data/lib/freight_kit/platforms/next_tms/orm/collection.rb +335 -0
  405. data/lib/freight_kit/platforms/next_tms/orm/customer.rb +12 -0
  406. data/lib/freight_kit/platforms/next_tms/orm/invoice.rb +21 -0
  407. data/lib/freight_kit/platforms/next_tms/orm/record_not_found_error.rb +9 -0
  408. data/lib/freight_kit/platforms/next_tms/orm/shipment.rb +50 -0
  409. data/lib/freight_kit/platforms/next_tms/orm.rb +38 -0
  410. data/lib/freight_kit/platforms/next_tms.rb +452 -0
  411. data/lib/freight_kit/platforms/the_great_information_factory.rb +492 -425
  412. data/lib/freight_kit/regions.rb +27 -0
  413. data/lib/freight_kit/shipment_packer.rb +36 -38
  414. data/lib/freight_kit/tariff/overlength_rule.rb +1 -5
  415. data/lib/freight_kit/tariff.rb +0 -2
  416. data/lib/freight_kit.rb +103 -11
  417. data/schemas/next_tms.json +110710 -0
  418. metadata +443 -55
  419. data/configuration/carriers/abfs.yml +0 -124
  420. data/configuration/carriers/btvp.yml +0 -84
  421. data/configuration/carriers/ccyq.yml +0 -121
  422. data/configuration/carriers/clni.yml +0 -113
  423. data/configuration/carriers/cnwy.yml +0 -113
  424. data/configuration/carriers/ctbv.yml +0 -117
  425. data/configuration/carriers/dcha.yml +0 -105
  426. data/configuration/carriers/dlds.yml +0 -111
  427. data/configuration/carriers/dphe.yml +0 -130
  428. data/configuration/carriers/drrq.yml +0 -131
  429. data/configuration/carriers/fcsy.yml +0 -102
  430. data/configuration/carriers/fwda.yml +0 -137
  431. data/configuration/carriers/jfj_transportation.yml +0 -2
  432. data/configuration/carriers/mtvl.yml +0 -12
  433. data/configuration/carriers/numk.yml +0 -14
  434. data/configuration/carriers/otcl.yml +0 -124
  435. data/configuration/carriers/pens.yml +0 -22
  436. data/configuration/carriers/rdfs.yml +0 -142
  437. data/configuration/carriers/saia.yml +0 -129
  438. data/configuration/carriers/sefl.yml +0 -115
  439. data/configuration/carriers/totl.yml +0 -111
  440. data/configuration/carriers/tqyl.yml +0 -28
  441. data/configuration/carriers/wrds.yml +0 -20
  442. data/configuration/platforms/carrier_logistics.yml +0 -25
  443. data/configuration/platforms/next.yml +0 -12
  444. data/configuration/platforms/the_great_information_factory.yml +0 -122
  445. data/lib/freight_kit/carriers/abfs.rb +0 -421
  446. data/lib/freight_kit/carriers/btvp.rb +0 -29
  447. data/lib/freight_kit/carriers/ccyq.rb +0 -310
  448. data/lib/freight_kit/carriers/clni.rb +0 -396
  449. data/lib/freight_kit/carriers/cnwy.rb +0 -327
  450. data/lib/freight_kit/carriers/ctbv.rb +0 -53
  451. data/lib/freight_kit/carriers/dcha.rb +0 -76
  452. data/lib/freight_kit/carriers/dlds.rb +0 -49
  453. data/lib/freight_kit/carriers/dphe.rb +0 -472
  454. data/lib/freight_kit/carriers/drrq.rb +0 -580
  455. data/lib/freight_kit/carriers/fcsy.rb +0 -57
  456. data/lib/freight_kit/carriers/fwda.rb +0 -744
  457. data/lib/freight_kit/carriers/mtvl.rb +0 -34
  458. data/lib/freight_kit/carriers/numk.rb +0 -58
  459. data/lib/freight_kit/carriers/otcl.rb +0 -520
  460. data/lib/freight_kit/carriers/pens.rb +0 -204
  461. data/lib/freight_kit/carriers/rdfs.rb +0 -521
  462. data/lib/freight_kit/carriers/sefl.rb +0 -342
  463. data/lib/freight_kit/carriers/totl.rb +0 -172
  464. data/lib/freight_kit/carriers/tqyl.rb +0 -337
  465. data/lib/freight_kit/carriers/wrds.rb +0 -246
  466. data/lib/freight_kit/platforms/next.rb +0 -101
@@ -1,436 +1,530 @@
1
- # frozen_string_literal: true
2
-
3
1
  module FreightKit
4
- class SAIA < FreightKit::Carrier
5
- REACTIVE_FREIGHT_CARRIER = true
2
+ module Carriers
3
+ class Saia < FreightKit::Carrier
4
+ class << self
5
+ def check_mailing_addresses
6
+ [
7
+ Address.new(
8
+ city: 'Dallas',
9
+ country: Countries.find_by(iso31661_alpha2: 'US'),
10
+ id: '85c2c731-88c3-4768-808a-858fff783fa2',
11
+ postal_code: '75373',
12
+ region_abbreviation: 'TX',
13
+ street: 'PO Box 730532',
14
+ street2: '800 765 7242'
15
+ )
16
+ ]
17
+ end
6
18
 
7
- include FreightKit::Rateable
8
- include FreightKit::Trackable
19
+ def contacts
20
+ [Contact.new(department: 'Main', id: '8c2b4da9-b91a-4b72-a7df-6e21c3f12018', phone: '+17702325067')]
21
+ end
9
22
 
10
- class << self
11
- attr_reader :name, :scac
12
- end
13
- @name = 'Saia'
14
- @scac = 'SAIA'
23
+ def find_rates_with_declared_value? = true
24
+
25
+ def headquarters
26
+ Address.new(
27
+ city: 'Johns Creek',
28
+ country: Countries.find_by(iso31661_alpha2: 'US'),
29
+ id: '6d40ce8f-c88a-418e-b29d-db4c3239c945',
30
+ postal_code: '30097',
31
+ region_abbreviation: 'GA',
32
+ street: '11465 Johns Creek Pkwy Ste 400'
33
+ )
34
+ end
15
35
 
16
- class << self
17
- def find_rates_with_declared_value?
18
- true
19
- end
36
+ def id = '26a6a0c0-2e95-4835-ad73-4a3c8bb38cdd'
37
+ def legal_name = 'Saia Motor Freight Line LLC'
20
38
 
21
- def maximum_height
22
- Measured::Length.new(105, :inches)
23
- end
39
+ def mappable_accessorials
40
+ {
41
+ airport_delivery: 'LimitedAccessLocation',
42
+ airport_pickup: 'LimitedAccessLocationPU',
43
+ amusement_park_delivery: 'LimitedAccessLocation',
44
+ amusement_park_pickup: 'LimitedAccessLocationPU',
45
+ appointment_delivery: 'ArrivalNotice/Appointment',
46
+ cemetery_delivery: 'LimitedAccessLocation',
47
+ cemetery_pickup: 'LimitedAccessLocationPU',
48
+ church_delivery: 'LimitedAccessLocation',
49
+ church_pickup: 'LimitedAccessLocationPU',
50
+ construction_delivery: 'LimitedAccessLocation',
51
+ construction_pickup: 'LimitedAccessLocationPU',
52
+ convention_delivery: 'TradeShowDelivery',
53
+ convention_pickup: 'TradeShowPickup',
54
+ driver_assist: 'WhiteGlove',
55
+ fair_delivery: 'LimitedAccessLocation',
56
+ fair_pickup: 'LimitedAccessLocationPU',
57
+ government_delivery: 'LimitedAccessLocation',
58
+ government_pickup: 'LimitedAccessLocationPU',
59
+ inside_delivery: 'InsideDelivery',
60
+ inside_pickup: 'InsidePickup',
61
+ jobsite_delivery: 'LimitedAccessLocation',
62
+ jobsite_pickup: 'LimitedAccessLocationPU',
63
+ liftgate_delivery: 'LiftgateService',
64
+ liftgate_pickup: 'LiftgateServicePU',
65
+ marina_delivery: 'LimitedAccessLocation',
66
+ marina_pickup: 'LimitedAccessLocationPU',
67
+ military_site_delivery: 'LimitedAccessLocation',
68
+ military_site_pickup: 'LimitedAccessLocationPU',
69
+ mine_site_delivery: 'LimitedAccessLocation',
70
+ mine_site_pickup: 'LimitedAccessLocationPU',
71
+ prison_delivery: 'LimitedAccessLocation',
72
+ prison_pickup: 'LimitedAccessLocationPU',
73
+ residential_delivery: 'ResidentialDelivery',
74
+ residential_pickup: 'ResidentialPickup',
75
+ school_delivery: 'LimitedAccessLocation',
76
+ school_pickup: 'LimitedAccessLocationPU',
77
+ steel_mill_delivery: 'LimitedAccessLocation',
78
+ steel_mill_pickup: 'LimitedAccessLocationPU',
79
+ storage_facility_delivery: 'LimitedAccessLocation',
80
+ storage_facility_pickup: 'LimitedAccessLocationPU',
81
+ university_delivery: 'LimitedAccessLocation',
82
+ university_pickup: 'LimitedAccessLocationPU',
83
+ utility_site_delivery: 'LimitedAccessLocation',
84
+ utility_site_pickup: 'LimitedAccessLocationPU'
85
+ }
86
+ end
24
87
 
25
- def maximum_weight
26
- Measured::Weight.new(10_000, :pounds)
27
- end
88
+ def maximum_height = Measured::Length.new(105, :inches)
89
+ def maximum_weight = Measured::Weight.new(10_000, :pounds)
90
+ def minimum_length_for_overlength_fees = Measured::Length.new(8, :feet)
91
+ def name = 'Saia'
92
+ def overlength_fees_require_tariff? = false
93
+ def required_credential_types = %i[api]
94
+ def requirements = %i[credentials]
95
+ def scac = 'SAIA'
96
+ def services = %i[standard guaranteed_delivery guaranteed_delivery_am guaranteed_delivery_pm]
97
+
98
+ def unquotable_accessorials
99
+ %i[
100
+ athletic_facility_delivery
101
+ athletic_facility_pickup
102
+ brewery_delivery
103
+ brewery_pickup
104
+ dock_dropoff
105
+ dock_pickup
106
+ farm_delivery
107
+ farm_pickup
108
+ fitness_center_delivery
109
+ fitness_center_pickup
110
+ golf_course_delivery
111
+ golf_course_pickup
112
+ grocery_store_delivery
113
+ grocery_store_pickup
114
+ grocery_warehouse_delivery
115
+ grocery_warehouse_pickup
116
+ hospital_delivery
117
+ hospital_pickup
118
+ hotel_delivery
119
+ hotel_pickup
120
+ inspection_site_delivery
121
+ inspection_site_pickup
122
+ mall_delivery
123
+ mall_pickup
124
+ motel_delivery
125
+ motel_pickup
126
+ nursing_home_delivery
127
+ nursing_home_pickup
128
+ park_delivery
129
+ park_pickup
130
+ ranch_delivery
131
+ ranch_pickup
132
+ reservation_delivery
133
+ reservation_pickup
134
+ resort_delivery
135
+ resort_pickup
136
+ restaurant_delivery
137
+ restaurant_pickup
138
+ winery_delivery
139
+ winery_pickup
140
+ ]
141
+ end
28
142
 
29
- def minimum_length_for_overlength_fees
30
- Measured::Length.new(8, :feet)
31
- end
143
+ def unserviceable_accessorials
144
+ %i[
145
+ afterhours_delivery
146
+ afterhours_pickup
147
+ appointment_pickup
148
+ customs_brokerage
149
+ early_morning_delivery
150
+ early_morning_pickup
151
+ flatbed_delivery
152
+ flatbed_pickup
153
+ guaranteed_delivery
154
+ guaranteed_delivery_am
155
+ guaranteed_delivery_pm
156
+ ]
157
+ end
32
158
 
33
- def overlength_fees_require_tariff?
34
- false
35
- end
159
+ def us_dot_number = 29_124
160
+ def us_mc_number = 87_511
36
161
 
37
- def required_credential_types
38
- %i[api]
39
- end
162
+ def validate_packages(packages, _tariff = nil)
163
+ raise UnserviceableError, 'Must be fewer than 10 items altogether' if packages.sum(&:quantity) > 10
40
164
 
41
- def requirements
42
- %i[credentials]
43
- end
44
- end
165
+ super
166
+ end
45
167
 
46
- # Documents
168
+ def website_url = 'https://www.saia.com'
169
+ end
47
170
 
48
- # Rates
171
+ include FreightKit::Rateable
172
+ include FreightKit::Trackable
173
+
174
+ API = {
175
+ actions: { rates: :create, track: :get_by_pro_number },
176
+ domain: 'www.saiasecure.com',
177
+ endpoints: { rates: '/webservice/ratequote/soap.asmx?wsdl', track: '/webservice/shipment/soap.asmx?wsdl' },
178
+ use_ssl: true
179
+ }.freeze
180
+ EVENTS = {
181
+ types: {
182
+ arrived_at_terminal: 'arrived',
183
+ delivered: 'delivered',
184
+ departed: 'departed from terminal',
185
+ located: 'arrived at breakbulk terminal',
186
+ out_for_delivery: 'dispatched for delivery',
187
+ picked_up: 'pickup from customer',
188
+ trailer_unloaded: 'unload trailer',
189
+ trailer_closed: 'load trailer'
190
+ }
191
+ }.freeze
192
+
193
+ # Documents
194
+
195
+ # Rates
196
+
197
+ protected
198
+
199
+ # Rates
200
+ def build_rate_request(shipment:)
201
+ accessorials = [{ AccessorialItem: { Code: 'SingleShipment' } }]
202
+ if shipment.accessorials.present?
203
+ serviceable_accessorials?(shipment.accessorials)
204
+ shipment.accessorials.each do |a|
205
+ accessorials << { AccessorialItem: { Code: mappable_accessorials[a] } } if unserviceable_accessorials.exclude?(a)
206
+ end
207
+ end
49
208
 
50
- def validate_packages(packages, _tariff = nil)
51
- raise UnserviceableError, 'Must be fewer than 10 items altogether' if packages.sum(&:quantity) > 10
209
+ longest_dimension = shipment.packages.map { |p| [p.width(:inches), p.length(:inches)].max }.max.ceil
210
+ accessorials << { AccessorialItem: { Code: 'ExcessiveLength' } } if longest_dimension >= 96
211
+
212
+ accessorials = accessorials.uniq
213
+
214
+ details = []
215
+ dimensions = []
216
+ shipment.packages.each do |package|
217
+ package.quantity.times do
218
+ details << {
219
+ DetailItem: {
220
+ Weight: package.pounds(:each).ceil,
221
+ Class: package.freight_class.to_s,
222
+ Length: package.length(:in).ceil,
223
+ Width: package.width(:in).ceil,
224
+ Height: package.height(:in).ceil
225
+ }
226
+ }
227
+
228
+ # Keeping this one at a time to match with "details"
229
+ dimensions << {
230
+ DimensionItem: {
231
+ Units: 1,
232
+ Length: package.length(:in).round(2),
233
+ Width: package.width(:in).round(2),
234
+ Height: package.height(:in).round(2),
235
+ Type: 'IN' # inches
236
+ }
237
+ }
238
+ end
239
+ end
52
240
 
53
- super
54
- end
241
+ request = {
242
+ request: {
243
+ Application: 'ThirdParty',
244
+ BillingTerms: 'Prepaid',
245
+ OriginCity: shipment.origin.city,
246
+ OriginState: shipment.origin.province,
247
+ OriginZipcode: shipment.origin.postal_code.to_s.upcase,
248
+ DestinationCity: shipment.destination.city,
249
+ DestinationState: shipment.destination.province,
250
+ DestinationZipcode: shipment.destination.postal_code.to_s.upcase,
251
+ WeightUnits: 'LBS',
252
+ TotalCube: shipment.packages.sum { |p| p.cubic_ft(:each) }.round(2),
253
+ TotalCubeUnits: 'CUFT', # cubic ft
254
+ ExcessiveLengthTotalInches: longest_dimension.to_s,
255
+ Details: details,
256
+ Dimensions: dimensions,
257
+ Accessorials: accessorials
258
+ }
259
+ }
260
+
261
+ declared_value = if shipment.declared_value_cents.blank?
262
+ nil
263
+ else
264
+ (shipment.declared_value_cents.to_f / 100).ceil
265
+ end
266
+
267
+ if declared_value.present?
268
+ request = request.deep_merge({ request: { DeclaredValue: declared_value, FullValueCoverage: declared_value } })
269
+ end
55
270
 
56
- protected
57
-
58
- def commit(action, request)
59
- client_args = {
60
- wsdl: request_url(action),
61
- convert_request_keys_to: :none,
62
- env_namespace: :soap,
63
- element_form_default: :qualified
64
- }
65
-
66
- call_args = { message: request_blueprint.deep_merge(request) }
67
-
68
- ::FreightKit::SoapClient.new(
69
- carrier: self,
70
- action:,
71
- client_args:,
72
- call_args:,
73
- soap_operation: @conf.dig(:api, :actions, action),
74
- ).call&.to_hash&.with_indifferent_access
75
- end
271
+ save_request(request)
272
+ request
273
+ end
76
274
 
77
- def request_blueprint
78
- api_credentials = fetch_credential(:api)
79
-
80
- {
81
- request: {
82
- AccountNumber: api_credentials.account,
83
- Application: 'ThirdParty',
84
- Password: api_credentials.password,
85
- TestMode: 'N',
86
- UserID: api_credentials.username
87
- }
88
- }
89
- end
275
+ def build_tracking_request(tracking_number)
276
+ request = { request: { ProNumber: tracking_number } }
277
+ save_request(request)
278
+ request
279
+ end
90
280
 
91
- def request_url(action)
92
- scheme = @conf.dig(:api, :use_ssl) ? 'https://' : 'http://'
93
- "#{scheme}#{@conf.dig(:api, :domain)}#{@conf.dig(:api, :endpoints, action)}"
94
- end
281
+ def commit(action, request)
282
+ client_args = { wsdl: request_url(action), convert_request_keys_to: :none, env_namespace: :soap, element_form_default: :qualified }
95
283
 
96
- # Documents
284
+ call_args = { message: request_blueprint.deep_merge(request) }
97
285
 
98
- # Rates
99
- def build_rate_request(shipment:)
100
- accessorials = [{ AccessorialItem: { Code: 'SingleShipment' } }]
101
- if shipment.accessorials.present?
102
- serviceable_accessorials?(shipment.accessorials)
103
- shipment.accessorials.each do |a|
104
- if @conf.dig(:accessorials, :unserviceable).exclude?(a)
105
- accessorials << { AccessorialItem: { Code: @conf.dig(:accessorials, :mappable)[a] } }
106
- end
107
- end
286
+ ::FreightKit::SoapClient.new(
287
+ carrier: self,
288
+ action:,
289
+ client_args:,
290
+ call_args:,
291
+ soap_operation: API.dig(:actions, action)
292
+ ).call&.to_hash&.with_indifferent_access
108
293
  end
109
294
 
110
- longest_dimension = shipment.packages.map { |p| [p.width(:inches), p.length(:inches)].max }.max.ceil
111
- accessorials << { AccessorialItem: { Code: 'ExcessiveLength' } } if longest_dimension >= 96
112
-
113
- accessorials = accessorials.uniq
114
-
115
- details = []
116
- dimensions = []
117
- shipment.packages.each do |package|
118
- package.quantity.times do
119
- details << {
120
- DetailItem: {
121
- Weight: package.pounds(:each).ceil,
122
- Class: package.freight_class.to_s,
123
- Length: package.length(:in).ceil,
124
- Width: package.width(:in).ceil,
125
- Height: package.height(:in).ceil
126
- }
127
- }
128
-
129
- # Keeping this one at a time to match with "details"
130
- dimensions << {
131
- DimensionItem: {
132
- Units: 1,
133
- Length: package.length(:in).round(2),
134
- Width: package.width(:in).round(2),
135
- Height: package.height(:in).round(2),
136
- Type: 'IN' # inches
137
- }
138
- }
139
- end
295
+ def parse_api_date_time(date_time, location)
296
+ return if date_time.blank?
297
+
298
+ local_date_time = ::Time.strptime(date_time, '%Y-%m-%d %H:%M:%S').to_fs(:db)
299
+ ::FreightKit::DateTime.new(local_date_time:, location:)
140
300
  end
141
301
 
142
- request = {
143
- request: {
144
- Application: 'ThirdParty',
145
- BillingTerms: 'Prepaid',
146
- OriginCity: shipment.origin.city,
147
- OriginState: shipment.origin.province,
148
- OriginZipcode: shipment.origin.postal_code.to_s.upcase,
149
- DestinationCity: shipment.destination.city,
150
- DestinationState: shipment.destination.province,
151
- DestinationZipcode: shipment.destination.postal_code.to_s.upcase,
152
- WeightUnits: 'LBS',
153
- TotalCube: shipment.packages.sum { |p| p.cubic_ft(:each) }.round(2),
154
- TotalCubeUnits: 'CUFT', # cubic ft
155
- ExcessiveLengthTotalInches: longest_dimension.to_s,
156
- Details: details,
157
- Dimensions: dimensions,
158
- Accessorials: accessorials
159
- }
160
- }
161
-
162
- declared_value = if shipment.declared_value_cents.blank?
163
- nil
164
- else
165
- (shipment.declared_value_cents.to_f / 100).ceil
166
- end
167
-
168
- if declared_value.present?
169
- request = request.deep_merge(
170
- {
171
- request: {
172
- DeclaredValue: declared_value,
173
- FullValueCoverage: declared_value
174
- }
175
- },
176
- )
302
+ def parse_api_location(api_event)
303
+ Location.new(city: api_event[:city]&.titleize, province: api_event[:state]&.upcase, country: ActiveUtils::Country.find('USA'))
177
304
  end
178
305
 
179
- save_request(request)
180
- request
181
- end
306
+ def parse_rate_response(shipment:, response:)
307
+ rate_response = RateResponse.new(request: last_request, response:)
182
308
 
183
- def parse_rate_response(shipment:, response:)
184
- rate_response = RateResponse.new(request: last_request, response:)
309
+ if response.blank?
310
+ rate_response.error = ResponseError.new('Unknown response')
311
+ return rate_response
312
+ end
185
313
 
186
- if response.blank?
187
- rate_response.error = ResponseError.new('Unknown response')
188
- return rate_response
189
- end
314
+ error = response.dig(:create_response, :create_result, :code)
190
315
 
191
- error = response.dig(:create_response, :create_result, :code)
316
+ if error.present?
317
+ message = response.dig(:create_response, :create_result, :message)
192
318
 
193
- if error.present?
194
- message = response.dig(:create_response, :create_result, :message)
319
+ case error
320
+ when 'DNF'
321
+ rate_response.error = UnserviceableError.new("#{error}: #{message}")
322
+ return rate_response
323
+ when 'S10'
324
+ rate_response.error = UnserviceableError.new("#{error}: #{message}")
325
+ return rate_response
326
+ end
195
327
 
196
- case error
197
- when 'DNF'
198
- rate_response.error = UnserviceableError.new("#{error}: #{message}")
199
- return rate_response
200
- when 'S10'
201
- rate_response.error = UnserviceableError.new("#{error}: #{message}")
328
+ if message.downcase.include?('must not exceed 10 lines')
329
+ rate_response.error = UnserviceableError.new("#{error}: #{message}")
330
+ return rate_response
331
+ end
332
+
333
+ rate_response.error = ResponseError.new("#{error}: #{message}")
202
334
  return rate_response
203
335
  end
204
336
 
205
- if message.downcase.include?('must not exceed 10 lines')
206
- rate_response.error = UnserviceableError.new("#{error}: #{message}")
337
+ result = response.dig(:create_response, :create_result)
338
+
339
+ if result.blank?
340
+ rate_response.error = ResponseError.new('Unknown result')
207
341
  return rate_response
208
342
  end
209
343
 
210
- rate_response.error = ResponseError.new("#{error}: #{message}")
211
- return rate_response
212
- end
344
+ if result[:total_invoice].blank?
345
+ rate_response.error = ResponseError.new('Cost is blank')
346
+ return rate_response
347
+ end
213
348
 
214
- result = response.dig(:create_response, :create_result)
349
+ transit_days = result[:standard_service_days].to_i
350
+ estimate_reference = result[:quote_number]
215
351
 
216
- if result.blank?
217
- rate_response.error = ResponseError.new('Unknown result')
218
- return rate_response
219
- end
220
-
221
- if result[:total_invoice].blank?
222
- rate_response.error = ResponseError.new('Cost is blank')
223
- return rate_response
224
- end
352
+ rate_accessorial_items = result.dig(:rate_accessorials, :rate_accessorial_item)
353
+ rate_accessorial_items = [rate_accessorial_items] if rate_accessorial_items.is_a?(Hash)
225
354
 
226
- transit_days = result[:standard_service_days].to_i
227
- estimate_reference = result[:quote_number]
355
+ prices = rate_accessorial_items.map do |rate_accessorial_item|
356
+ Price.new(
357
+ blame: :api,
358
+ cents: (rate_accessorial_item[:amount].to_f * 100).to_i,
359
+ description: rate_accessorial_item[:description]&.titleize&.squish
360
+ )
361
+ end
228
362
 
229
- rate_accessorial_items = result.dig(:rate_accessorials, :rate_accessorial_item)
230
- rate_accessorial_items = [rate_accessorial_items] if rate_accessorial_items.is_a?(Hash)
363
+ standard_ltl_cents = (result[:total_invoice].to_f * 100).to_i - prices.sum(&:cents)
231
364
 
232
- prices = rate_accessorial_items.map do |rate_accessorial_item|
233
- Price.new(
234
- blame: :api,
235
- cents: (rate_accessorial_item[:amount].to_f * 100).to_i,
236
- description: rate_accessorial_item[:description]&.titleize&.squish,
237
- )
238
- end
239
-
240
- standard_ltl_cents = (result[:total_invoice].to_f * 100).to_i - prices.sum(&:cents)
241
-
242
- rates = []
243
-
244
- rates << Rate.new(
245
- carrier: self,
246
- carrier_name: self.class.name,
247
- currency: 'USD',
248
- estimate_reference:,
249
- scac: self.class.scac.upcase,
250
- service_name: :standard,
251
- shipment:,
252
- prices: [
253
- Price.new(
254
- blame: :api,
255
- cents: standard_ltl_cents,
256
- description: 'Freight',
257
- ),
258
- ] + prices,
259
- transit_days:,
260
- with_excessive_length_fees: @conf.dig(:attributes, :rates, :with_excessive_length_fees),
261
- )
262
-
263
- [
264
- { guaranteed_ltl: result[:guarantee_amount] },
265
- { guaranteed_ltl_am: result[:guarantee_amount12pm] },
266
- { guaranteed_ltl_pm: result[:guarantee_amount2pm] },
267
- ].each do |service|
268
- next if service.values[0] == '0' || service.values[0].blank?
269
-
270
- cents = (service.values[0].to_f * 100).to_i
365
+ rates = []
271
366
 
272
367
  rates << Rate.new(
273
- carrier_name: self.class.name,
274
368
  carrier: self,
369
+ carrier_name: name,
275
370
  currency: 'USD',
276
371
  estimate_reference:,
277
- scac: self.class.scac.upcase,
278
- service_name: service.keys[0],
372
+ scac:,
373
+ service_name: :standard,
279
374
  shipment:,
280
- prices: [
281
- Price.new(
282
- blame: :api,
283
- cents: standard_ltl_cents + cents,
284
- description: 'Freight',
285
- ),
286
- ] + prices,
287
- with_excessive_length_fees: @conf.dig(:attributes, :rates, :with_excessive_length_fees),
375
+ prices: [Price.new(blame: :api, cents: standard_ltl_cents, description: 'Freight')] + prices,
376
+ transit_days:,
377
+ with_excessive_length_fees: rates_with_excessive_length_fees?
288
378
  )
379
+
380
+ [
381
+ { guaranteed_ltl: result[:guarantee_amount] },
382
+ { guaranteed_ltl_am: result[:guarantee_amount12pm] },
383
+ { guaranteed_ltl_pm: result[:guarantee_amount2pm] }
384
+ ].each do |service|
385
+ next if service.values[0] == '0' || service.values[0].blank?
386
+
387
+ cents = (service.values[0].to_f * 100).to_i
388
+
389
+ rates << Rate.new(
390
+ carrier_name: name,
391
+ carrier: self,
392
+ currency: 'USD',
393
+ estimate_reference:,
394
+ scac:,
395
+ service_name: service.keys[0],
396
+ shipment:,
397
+ prices: [Price.new(blame: :api, cents: standard_ltl_cents + cents, description: 'Freight')] + prices,
398
+ with_excessive_length_fees: rates_with_excessive_length_fees?
399
+ )
400
+ end
401
+
402
+ rate_response.rates = rates
403
+ rate_response
289
404
  end
290
405
 
291
- rate_response.rates = rates
292
- rate_response
293
- end
406
+ def parse_tracking_response(response)
407
+ tracking_response = TrackingResponse.new(carrier: self, request: last_request, response:)
294
408
 
295
- # Tracking
409
+ error = if response
410
+ response.dig(:get_by_pro_number_response, :get_by_pro_number_result, :code)
411
+ else
412
+ 'API Error: Unknown response'
413
+ end
296
414
 
297
- def build_tracking_request(tracking_number)
298
- request = {
299
- request: {
300
- ProNumber: tracking_number
301
- }
302
- }
303
- save_request(request)
304
- request
305
- end
415
+ if error.present?
416
+ tracking_response.error = ResponseError.new(error)
417
+ return tracking_response
418
+ end
306
419
 
307
- def parse_api_date_time(date_time, location)
308
- return if date_time.blank?
420
+ search_result = response.dig(:get_by_pro_number_response, :get_by_pro_number_result)
309
421
 
310
- local_date_time = ::Time.strptime(date_time, '%Y-%m-%d %H:%M:%S').to_fs(:db)
311
- ::FreightKit::DateTime.new(local_date_time:, location:)
312
- end
422
+ if search_result.blank?
423
+ tracking_response.error = ShipmentNotFoundError.new
424
+ return tracking_response
425
+ end
313
426
 
314
- def parse_api_location(api_event)
315
- Location.new(
316
- city: api_event[:city]&.titleize,
317
- province: api_event[:state]&.upcase,
318
- country: ActiveUtils::Country.find('USA'),
319
- )
320
- end
427
+ address1 = [search_result.dig(:shipper, :address1), search_result.dig(:shipper, :address2)]
428
+ .select(&:present?)
429
+ .map { |line| line.squish.strip.titleize }
430
+ .join(', ')
431
+
432
+ shipper_location = Location.new(
433
+ address1:,
434
+ city: search_result.dig(:shipper, :city)&.squish&.titleize,
435
+ province: search_result.dig(:shipper, :state)&.strip&.upcase,
436
+ postal_code: search_result.dig(:shipper, :zipcode)&.strip,
437
+ country: ActiveUtils::Country.find('USA')
438
+ )
439
+
440
+ address1 = [search_result.dig(:consignee, :address1), search_result.dig(:consignee, :address2)]
441
+ .select(&:present?)
442
+ .map { |line| line.squish.strip.titleize }
443
+ .join(', ')
444
+
445
+ receiver_location = Location.new(
446
+ address1:,
447
+ city: search_result.dig(:consignee, :city)&.squish&.titleize,
448
+ province: search_result.dig(:consignee, :state)&.strip&.upcase,
449
+ postal_code: search_result.dig(:consignee, :zipcode)&.strip,
450
+ country: ActiveUtils::Country.find('USA')
451
+ )
321
452
 
322
- def parse_tracking_response(response)
323
- tracking_response = TrackingResponse.new(carrier: self, request: last_request, response:)
453
+ api_date_time = search_result[:delivery_date_time_arrive]
454
+ actual_delivery_date = parse_api_date_time(api_date_time, receiver_location)
324
455
 
325
- error = if response
326
- response.dig(:get_by_pro_number_response, :get_by_pro_number_result, :code)
327
- else
328
- 'API Error: Unknown response'
329
- end
456
+ api_date_time = search_result[:pickup_date_time]
457
+ pickup_date = parse_api_date_time(api_date_time, shipper_location)
330
458
 
331
- if error.present?
332
- tracking_response.error = ResponseError.new(error)
333
- return tracking_response
334
- end
459
+ api_date_time = search_result[:delivery_appointment_date_time]
460
+ scheduled_delivery_date = parse_api_date_time(api_date_time, receiver_location)
335
461
 
336
- search_result = response.dig(:get_by_pro_number_response, :get_by_pro_number_result)
462
+ tracking_number = search_result[:pro_number]
337
463
 
338
- if search_result.blank?
339
- tracking_response.error = ShipmentNotFoundError.new
340
- return tracking_response
341
- end
464
+ shipment_events = []
342
465
 
343
- address1 = [
344
- search_result.dig(:shipper, :address1),
345
- search_result.dig(:shipper, :address2),
346
- ]
347
- .select(&:present?)
348
- .map { |line| line.squish.strip.titleize }
349
- .join(', ')
350
-
351
- shipper_location = Location.new(
352
- address1:,
353
- city: search_result.dig(:shipper, :city)&.squish&.titleize,
354
- province: search_result.dig(:shipper, :state)&.strip&.upcase,
355
- postal_code: search_result.dig(:shipper, :zipcode)&.strip,
356
- country: ActiveUtils::Country.find('USA'),
357
- )
358
-
359
- address1 = [
360
- search_result.dig(:consignee, :address1),
361
- search_result.dig(:consignee, :address2),
362
- ]
363
- .select(&:present?)
364
- .map { |line| line.squish.strip.titleize }
365
- .join(', ')
366
-
367
- receiver_location = Location.new(
368
- address1:,
369
- city: search_result.dig(:consignee, :city)&.squish&.titleize,
370
- province: search_result.dig(:consignee, :state)&.strip&.upcase,
371
- postal_code: search_result.dig(:consignee, :zipcode)&.strip,
372
- country: ActiveUtils::Country.find('USA'),
373
- )
374
-
375
- api_date_time = search_result[:delivery_date_time_arrive]
376
- actual_delivery_date = parse_api_date_time(api_date_time, receiver_location)
377
-
378
- api_date_time = search_result[:pickup_date_time]
379
- pickup_date = parse_api_date_time(api_date_time, shipper_location)
380
-
381
- api_date_time = search_result[:delivery_appointment_date_time]
382
- scheduled_delivery_date = parse_api_date_time(api_date_time, receiver_location)
383
-
384
- tracking_number = search_result[:pro_number]
385
-
386
- shipment_events = []
387
-
388
- api_events = search_result.dig(:history, :history_item)
389
-
390
- if api_events.blank?
391
- shipment_events << ShipmentEvent.new(
392
- date_time: pickup_date,
393
- location: shipper_location,
394
- type_code: :picked_up,
395
- )
396
- else
397
- api_events = [api_events] if api_events.is_a?(Hash)
466
+ api_events = search_result.dig(:history, :history_item)
398
467
 
399
- api_events.each do |api_event|
400
- event_key = nil
401
- comment = api_event[:activity]
468
+ if api_events.blank?
469
+ shipment_events << ShipmentEvent.new(date_time: pickup_date, location: shipper_location, type_code: :picked_up)
470
+ else
471
+ api_events = [api_events] if api_events.is_a?(Hash)
402
472
 
403
- @conf.dig(:events, :types).each do |key, val|
404
- if comment.downcase.include?(val)
405
- event_key = key
406
- break
473
+ api_events.each do |api_event|
474
+ event_key = nil
475
+ comment = api_event[:activity]
476
+
477
+ EVENTS[:types].each do |key, val|
478
+ if comment.downcase.include?(val)
479
+ event_key = key
480
+ break
481
+ end
407
482
  end
408
- end
409
- next if event_key.blank?
483
+ next if event_key.blank?
410
484
 
411
- api_date_time = api_event[:activity_date_time]
485
+ api_date_time = api_event[:activity_date_time]
412
486
 
413
- location = parse_api_location(api_event)
414
- date_time = parse_api_date_time(api_date_time, location)
487
+ location = parse_api_location(api_event)
488
+ date_time = parse_api_date_time(api_date_time, location)
415
489
 
416
- shipment_events << ShipmentEvent.new(date_time:, location:, type_code: event_key)
490
+ shipment_events << ShipmentEvent.new(date_time:, location:, type_code: event_key)
491
+ end
417
492
  end
418
- end
419
493
 
420
- status = shipment_events.last&.type_code
494
+ status = shipment_events.last&.type_code
495
+
496
+ tracking_response.assign_attributes(
497
+ actual_delivery_date:,
498
+ destination: receiver_location,
499
+ origin: shipper_location,
500
+ scheduled_delivery_date:,
501
+ ship_time: pickup_date,
502
+ shipment_events:,
503
+ status:,
504
+ tracking_number:
505
+ )
421
506
 
422
- tracking_response.assign_attributes(
423
- actual_delivery_date:,
424
- destination: receiver_location,
425
- origin: shipper_location,
426
- scheduled_delivery_date:,
427
- ship_time: pickup_date,
428
- shipment_events:,
429
- status:,
430
- tracking_number:,
431
- )
507
+ tracking_response
508
+ end
432
509
 
433
- tracking_response
510
+ def request_blueprint
511
+ api_credentials = fetch_credential(:api)
512
+
513
+ {
514
+ request: {
515
+ AccountNumber: api_credentials.account,
516
+ Application: 'ThirdParty',
517
+ Password: api_credentials.password,
518
+ TestMode: 'N',
519
+ UserID: api_credentials.username
520
+ }
521
+ }
522
+ end
523
+
524
+ def request_url(action)
525
+ scheme = API[:use_ssl] ? 'https://' : 'http://'
526
+ "#{scheme}#{API[:domain]}#{API.dig(:endpoints, action)}"
527
+ end
434
528
  end
435
529
  end
436
530
  end