Class: Edi::MftGateway::ShipCodeMapper

Inherits:
Object
  • Object
show all
Defined in:
app/services/edi/mft_gateway/ship_code_mapper.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(orchestrator) ⇒ ShipCodeMapper

Returns a new instance of ShipCodeMapper.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'app/services/edi/mft_gateway/ship_code_mapper.rb', line 10

def initialize(orchestrator)
  @orchestrator = orchestrator # Right now this is not used but might be in the future

  # from: https://developercenter.spscommerce.com/#/rsx/docs/fields-qualifiers/7.7.6/Orders/ServiceLevelCode
  # 3D Three Day Service AM A.M. Service
  # CG Ground
  # CX Express Service
  # DC Delivery Confirmation
  # DS Door Service
  # ES Expedited Service - Domestic
  # ET Proof of Delivery[POD] with Signature
  # FC First Class
  # G2 Standard Service
  # IDL Inside Delivery
  # IE Expedited Service - Worldwide
  # IS International Service
  # IX Express Service - Worldwide
  # LM Last Mile Delivery Delivery service offered by some couriers where courier delivers to local post office, who performs the final delivery
  # LT Economy
  # ME Metro
  # ND Next Day Air
  # NF Next Flight Out
  # NH Next Day Hundred Weight
  # NM Next Morning
  # NXD Next Day
  # ON Overnight
  # PA Primary Service Area - Next Day by 10:30 A.M.
  # PB Priority Mail
  # PC Primary Service Area - Next Day by 9:30 A.M.
  # PI Priority Mail Insured
  # PM P.M. Service
  # PN Primary Service Area - Next Day by Noon
  # PO P.O. Box/Zip Code
  # PR Primary Service Area - Next Day by 5:00 P.M.
  # PS Primary Service Area - Second Day by Noon
  # PT Pooled Shipment Consolidated shipment from multiple entities
  # PX Premium Service
  # RE Return Service
  # SA Same Day
  # SC Second Day Air
  # SD Saturday Service
  # SE Second Day
  # SG Standard Ground
  # SH Second Day Hundred Weight
  # SI Standard Ground Hundred Weight
  # SM Small Package Service

  # Also, from the  documentation spreadsheet they sent us:

  # UPS-General (CarrierAlphaCode=UPSN)
  # UPS-Ground (CarrierAlphaCode=UPSG)
  # UPS-3 Day Select (CarrierAlphaCode=UPS3)
  # UPS-Next Day Air (CarrierAlphaCode=UPS1)
  # UPS-Air-2nd Day Air (CarrierAlphaCode=UPS2)
  # FedEx Express (CarrierAlphaCode=FDE)
  # FedEx Ground (CarrierAlphaCode=FDEG)
  # FedEx Freight (CarrierAlphaCode=FXFE)
  # FedEx Custom Critical (CarrierAlphaCode=FDCC)
  # FedEx Office (CarrierAlphaCode=FXO)
  # FedEx Same Day City (CarrierAlphaCode=FSDC)
  # FEDEX-Air (CarrierAlphaCode=FDEN)
  # Purolator International (CarrierAlphaCode=PURL)
  # Purolator Freight (CarrierAlphaCode=PRLA)
  # Purolator Courier (CarrierAlphaCode=PRLA)
  # Loomis (CarrierAlphaCode=LOOM)
  # Canada Post Xpresspost (CarrierAlphaCode=CPXP)
  # Canada Post Expedited (CarrierAlphaCode=CPEX)
  # Other (CarrierAlphaCode=OTHR)



  case @orchestrator.partner
  when :mft_gateway_canadian_tire
    @shipping_map = [
      # Purolator is the default carrier, ground is the default method
      ShippingOptionResult.new(code: 'DEFAULT', name: 'purolator_ground', sps_scac: 'PRLG'),
      ShippingOptionResult.new(code: 'UNSF', name: 'purolator_ground'), # unspecified
      ShippingOptionResult.new(code: 'PRLG', name: 'purolator_ground'), # DSCO https://app.dsco.io/account/mapping-settings
      ShippingOptionResult.new(code: 'PRLE', name: 'purolator_express'), # DSCO https://app.dsco.io/account/mapping-settings
      ShippingOptionResult.new(code: 'GCG', name: 'purolator_ground'), # equivalent Purolator for generic 'Ground' # DSCO https://app.dsco.io/account/mapping-settings
      ShippingOptionResult.new(code: 'GND', name: 'purolator_express'), # equivalent Purolator for generic 'Next Day' # DSCO https://app.dsco.io/account/mapping-settings
      # ShippingOptionResult.new(code: 'GNM', name: 'purolator_express_evening'), # ?? No equivalent Purolator ship method for generic 'Priority' so use this? # DSCO https://app.dsco.io/account/mapping-settings
      # ShippingOptionResult.new(code: 'GSE', name: 'purolator_express_evening'), # ?? No equivalent Purolator ship method for generic 'Second Day' so use this? # DSCO https://app.dsco.io/account/mapping-settings
      # ShippingOptionResult.new(code: 'G3D', name: 'purolator_ground'), # ?? No equivalent Purolator ship method for generic 'Three Day' so use this? # DSCO https://app.dsco.io/account/mapping-settings

      # Canadian Tire only had a Purolator account on file, but these other carriers may come eventually:
      ShippingOptionResult.new(code: 'CGEX', name: 'canada_post_expedited_parcel'), # DSCO https://app.dsco.io/account/mapping-settings
      ShippingOptionResult.new(code: 'CGXP', name: 'canada_post_xpresspost'), # DSCO https://app.dsco.io/account/mapping-settings
      ShippingOptionResult.new(code: 'FEHD', name: 'fedex_ground_residential_ca'), # DSCO https://app.dsco.io/account/mapping-settings
      ShippingOptionResult.new(code: 'FECG', name: 'fedex_ground_ca'), # DSCO https://app.dsco.io/account/mapping-settings
      ShippingOptionResult.new(code: 'FE2D', name: 'fedex_twoday_ca'), # DSCO https://app.dsco.io/account/mapping-settings
      ShippingOptionResult.new(code: 'FESO', name: 'fedex_standard_overnight_ca'), # DSCO https://app.dsco.io/account/mapping-settings
      ShippingOptionResult.new(code: 'FEFE', name: 'fedex_freight_economy'), # DSCO https://app.dsco.io/account/mapping-settings
      ShippingOptionResult.new(code: 'UPCG', name: 'standard'), # DSCO https://app.dsco.io/account/mapping-settings
      ShippingOptionResult.new(code: 'UPSS', name: 'standard'), # DSCO https://app.dsco.io/account/mapping-settings
      ShippingOptionResult.new(code: 'U2DA', name: 'expedited'), # DSCO https://app.dsco.io/account/mapping-settings
      ShippingOptionResult.new(code: 'U3DS', name: 'threedayselectcanada'), # DSCO https://app.dsco.io/account/mapping-settings
      ShippingOptionResult.new(code: 'UNDA', name: 'express'), # DSCO https://app.dsco.io/account/mapping-settings
      ShippingOptionResult.new(code: 'UNAS', name: 'expresssaver'), # DSCO https://app.dsco.io/account/mapping-settings

      # Old SPS Commerce codes, TBD remove when we are sure about DSCO

      ShippingOptionResult.new(code: 'CG', name: 'purolator_ground', sps_scac: 'PRLA'),
      ShippingOptionResult.new(code: 'G2', name: 'purolator_ground', sps_scac: 'PRLA'),
      ShippingOptionResult.new(code: 'GR', name: 'purolator_ground', sps_scac: 'PRLA'),
      ShippingOptionResult.new(code: 'IDL', name: 'purolator_ground', sps_scac: 'PRLA'),
      ShippingOptionResult.new(code: 'SG', name: 'purolator_ground', sps_scac: 'PRLA'),
      ShippingOptionResult.new(code: 'SI', name: 'purolator_ground', sps_scac: 'PRLA'),
      ShippingOptionResult.new(code: 'SM', name: 'purolator_ground', sps_scac: 'PRLA'),
      ShippingOptionResult.new(code: 'PB', name: 'purolator_ground', sps_scac: 'PRLA'),
      ShippingOptionResult.new(code: 'PI', name: 'purolator_ground', sps_scac: 'PRLA'),
      ShippingOptionResult.new(code: 'PT', name: 'purolator_ground', sps_scac: 'PRLA'),
      ShippingOptionResult.new(code: 'ET', name: 'purolator_ground', sps_scac: 'PRLA', signature: true),
      ShippingOptionResult.new(code: 'SD', name: 'purolator_ground', sps_scac: 'PRLA', saturday: true),
      ShippingOptionResult.new(code: '3D', name: 'purolator_express', sps_scac: 'PRLA'), # Purolator doesn't have 3 day
      ShippingOptionResult.new(code: 'CX', name: 'purolator_express', sps_scac: 'PRLA'),
      ShippingOptionResult.new(code: 'ES', name: 'purolator_express', sps_scac: 'PRLA'),
      ShippingOptionResult.new(code: 'ND', name: 'purolator_express', sps_scac: 'PRLA'),
      ShippingOptionResult.new(code: 'NH', name: 'purolator_express', sps_scac: 'PRLA'),
      ShippingOptionResult.new(code: 'NXD', name: 'purolator_express', sps_scac: 'PRLA'),
      ShippingOptionResult.new(code: 'ON', name: 'purolator_express', sps_scac: 'PRLA'),
      ShippingOptionResult.new(code: 'PA', name: 'purolator_express_10_30_am', sps_scac: 'PRLA'),
      ShippingOptionResult.new(code: 'PN', name: 'purolator_express_10_30_am', sps_scac: 'PRLA'),
      ShippingOptionResult.new(code: 'NM', name: 'purolator_express_10_30_am', sps_scac: 'PRLA'),
      ShippingOptionResult.new(code: 'NF', name: 'purolator_express_9_am', sps_scac: 'PRLA'),
      ShippingOptionResult.new(code: 'PC', name: 'purolator_express_9_am', sps_scac: 'PRLA'),
      ShippingOptionResult.new(code: 'PR', name: 'purolator_express', sps_scac: 'PRLA'),
      ShippingOptionResult.new(code: 'PS', name: 'purolator_express', sps_scac: 'PRLA'), # Purolator doesn't have 2 day
      ShippingOptionResult.new(code: 'SC', name: 'purolator_express', sps_scac: 'PRLA'), # Purolator doesn't have 2 day
      ShippingOptionResult.new(code: 'SH', name: 'purolator_express', sps_scac: 'PRLA'), # Purolator doesn't have 2 day
    ]
  when :mft_gateway_zoro_tools
    @shipping_map = [
      # FedEx is the default carrier, ground is the default method
      ShippingOptionResult.new(code: 'DEFAULT', name: 'fedex_ground', sps_scac: 'FDEG'),
      ShippingOptionResult.new(code: 'CG', name: 'fedex_ground', sps_scac: 'FDEG'),
      ShippingOptionResult.new(code: 'G2', name: 'fedex_ground', sps_scac: 'FDEG'),
      ShippingOptionResult.new(code: 'GR', name: 'fedex_ground', sps_scac: 'FDEG'),
      ShippingOptionResult.new(code: 'IDL', name: 'fedex_ground', sps_scac: 'FDEG'),
      ShippingOptionResult.new(code: 'SG', name: 'fedex_ground', sps_scac: 'FDEG'),
      ShippingOptionResult.new(code: 'SI', name: 'fedex_ground', sps_scac: 'FDEG'),
      ShippingOptionResult.new(code: 'SM', name: 'fedex_ground', sps_scac: 'FDEG'),
      ShippingOptionResult.new(code: 'PB', name: 'fedex_ground', sps_scac: 'FDEG'),
      ShippingOptionResult.new(code: 'PI', name: 'fedex_ground', sps_scac: 'FDEG'),
      ShippingOptionResult.new(code: 'PT', name: 'fedex_ground', sps_scac: 'FDEG'),
      ShippingOptionResult.new(code: 'ET', name: 'fedex_ground', sps_scac: 'FDEG', signature: true),
      ShippingOptionResult.new(code: 'SD', name: 'fedex_ground', sps_scac: 'FDEG', saturday: true),
      ShippingOptionResult.new(code: 'DEFAULT', name: 'fedex_ground_residential', sps_scac: 'FDEG'),
      ShippingOptionResult.new(code: 'CG', name: 'fedex_ground_residential', sps_scac: 'FDEG'),
      ShippingOptionResult.new(code: 'G2', name: 'fedex_ground_residential', sps_scac: 'FDEG'),
      ShippingOptionResult.new(code: 'GR', name: 'fedex_ground_residential', sps_scac: 'FDEG'),
      ShippingOptionResult.new(code: 'IDL', name: 'fedex_ground_residential', sps_scac: 'FDEG'),
      ShippingOptionResult.new(code: 'SG', name: 'fedex_ground_residential', sps_scac: 'FDEG'),
      ShippingOptionResult.new(code: 'SI', name: 'fedex_ground_residential', sps_scac: 'FDEG'),
      ShippingOptionResult.new(code: 'SM', name: 'fedex_ground_residential', sps_scac: 'FDEG'),
      ShippingOptionResult.new(code: 'PB', name: 'fedex_ground_residential', sps_scac: 'FDEG'),
      ShippingOptionResult.new(code: 'PI', name: 'fedex_ground_residential', sps_scac: 'FDEG'),
      ShippingOptionResult.new(code: 'PT', name: 'fedex_ground_residential', sps_scac: 'FDEG'),
      ShippingOptionResult.new(code: 'ET', name: 'fedex_ground_residential', sps_scac: 'FDEG', signature: true),
      ShippingOptionResult.new(code: 'SD', name: 'fedex_ground_residential', sps_scac: 'FDEG', saturday: true),
      ShippingOptionResult.new(code: '3D', name: 'fedex_express_saver', sps_scac: 'FDE'), # FedEx doesn't have 3 day
      ShippingOptionResult.new(code: 'CX', name: 'fedex_standard_overnight', sps_scac: 'FDE'),
      ShippingOptionResult.new(code: 'ES', name: 'fedex_standard_overnight', sps_scac: 'FDE'),
      ShippingOptionResult.new(code: 'ND', name: 'fedex_standard_overnight', sps_scac: 'FDE'),
      ShippingOptionResult.new(code: 'NH', name: 'fedex_standard_overnight', sps_scac: 'FDE'),
      ShippingOptionResult.new(code: 'NXD', name: 'fedex_standard_overnight', sps_scac: 'FDE'),
      ShippingOptionResult.new(code: 'ON', name: 'fedex_standard_overnight', sps_scac: 'FDE'),
      ShippingOptionResult.new(code: 'PA', name: 'fedex_priority_overnight', sps_scac: 'FDE'),
      ShippingOptionResult.new(code: 'PN', name: 'fedex_priority_overnight', sps_scac: 'FDE'),
      ShippingOptionResult.new(code: 'NM', name: 'fedex_priority_overnight', sps_scac: 'FDE'),
      ShippingOptionResult.new(code: 'NF', name: 'fedex_priority_overnight', sps_scac: 'FDE'),
      ShippingOptionResult.new(code: 'PC', name: 'fedex_priority_overnight', sps_scac: 'FDE'),
      ShippingOptionResult.new(code: 'PR', name: 'fedex_standard_overnight', sps_scac: 'FDE'),
      ShippingOptionResult.new(code: 'PS', name: 'fedex_twoday', sps_scac: 'FDE'),
      ShippingOptionResult.new(code: 'SC', name: 'fedex_twoday', sps_scac: 'FDE'),
      ShippingOptionResult.new(code: 'SH', name: 'fedex_twoday', sps_scac: 'FDE'),
      ShippingOptionResult.new(code: '2D', name: 'fedex_twoday', sps_scac: 'FDE'),
    ]
  when :mft_gateway_build_com
    @shipping_map = [
      # UPS is the default carrier, ground is the default method
      ShippingOptionResult.new(code: 'DEFAULT', name: 'ground', sps_scac: 'UPSG', sps_code: 'GR'),
      ShippingOptionResult.new(code: 'CG', name: 'ground', sps_scac: 'UPSG', sps_code: 'GR'),
      ShippingOptionResult.new(code: 'G2', name: 'ground', sps_scac: 'UPSG', sps_code: 'GR'),
      ShippingOptionResult.new(code: 'GR', name: 'ground', sps_scac: 'UPSG', sps_code: 'GR'),
      ShippingOptionResult.new(code: 'IDL', name: 'ground', sps_scac: 'UPSG', sps_code: 'GR'),
      ShippingOptionResult.new(code: 'SG', name: 'ground', sps_scac: 'UPSG', sps_code: 'GR'),
      ShippingOptionResult.new(code: 'SI', name: 'ground', sps_scac: 'UPSG', sps_code: 'GR'),
      ShippingOptionResult.new(code: 'SM', name: 'ground', sps_scac: 'UPSG', sps_code: 'GR'),
      ShippingOptionResult.new(code: 'PB', name: 'ground', sps_scac: 'UPSG', sps_code: 'GR'),
      ShippingOptionResult.new(code: 'PI', name: 'ground', sps_scac: 'UPSG', sps_code: 'GR'),
      ShippingOptionResult.new(code: 'PT', name: 'ground', sps_scac: 'UPSG', sps_code: 'GR'),
      ShippingOptionResult.new(code: 'ET', name: 'ground', sps_scac: 'UPSG', signature: true, sps_code: 'SD'),
      ShippingOptionResult.new(code: 'SD', name: 'ground', sps_scac: 'UPSG', saturday: true, sps_code: 'SD'),
      ShippingOptionResult.new(code: '3D', name: 'threedayselect', sps_scac: 'UPS3', sps_code: 'ND'),
      ShippingOptionResult.new(code: 'CX', name: 'nextdayairsaver', sps_scac: 'UPS1', sps_code: 'ND'),
      ShippingOptionResult.new(code: 'ES', name: 'nextdayairsaver', sps_scac: 'UPS1', sps_code: 'ND'),
      ShippingOptionResult.new(code: 'ND', name: 'nextdayairsaver', sps_scac: 'UPS1', sps_code: 'ND'),
      ShippingOptionResult.new(code: 'NH', name: 'nextdayairsaver', sps_scac: 'UPS1', sps_code: 'ND'),
      ShippingOptionResult.new(code: 'NXD', name: 'nextdayairsaver', sps_scac: 'UPS1', sps_code: 'ND'),
      ShippingOptionResult.new(code: 'ON', name: 'nextdayairsaver', sps_scac: 'UPS1', sps_code: 'ND'),
      ShippingOptionResult.new(code: 'PA', name: 'nextdayair', sps_scac: 'UPS1', sps_code: 'ND'),
      ShippingOptionResult.new(code: 'PN', name: 'nextdayair', sps_scac: 'UPS1', sps_code: 'ND'),
      ShippingOptionResult.new(code: 'NM', name: 'nextdayair', sps_scac: 'UPS1', sps_code: 'ND'),
      ShippingOptionResult.new(code: 'NF', name: 'nextdayair', sps_scac: 'UPS1', sps_code: 'ND'),
      ShippingOptionResult.new(code: 'PC', name: 'nextdayair', sps_scac: 'UPS1', sps_code: 'ND'),
      ShippingOptionResult.new(code: 'PR', name: 'nextdayairsaver', sps_scac: 'UPS1', sps_code: 'ND'),
      ShippingOptionResult.new(code: 'PS', name: 'seconddayair', sps_scac: 'UPS2', sps_code: '2D'),
      ShippingOptionResult.new(code: 'SC', name: 'seconddayair', sps_scac: 'UPS2', sps_code: '2D'),
      ShippingOptionResult.new(code: 'SH', name: 'seconddayair', sps_scac: 'UPS2', sps_code: '2D'),
      ShippingOptionResult.new(code: '2D', name: 'seconddayair', sps_scac: 'UPS2', sps_code: '2D'),
      ShippingOptionResult.new(code: 'FR', name: 'build_com_convey_freight') # Here we basically use the Convey Freight shopping portal that Build.com uses for freight, see below:
      # On Wed, Jul 26, 2023 at 6:30 PM <Joey.LeBlanc@ferguson.com> wrote:
      # ... We use Convey for our LTL shipments. When using Convey, you would put in all of the shipping information, item information for the order & Convey would create a BOL for the best rate possible between all of the carriers that we use. It's a very easy process with great results. It's a very easy process with great results. I put in your email ...[orders@warmlyyours.com]... for the onboarding process...
    ]
  else
    @shipping_map = []
  end
end

Instance Attribute Details

#orchestratorObject (readonly)

Returns the value of attribute orchestrator.



8
9
10
# File 'app/services/edi/mft_gateway/ship_code_mapper.rb', line 8

def orchestrator
  @orchestrator
end

#shipping_mapObject (readonly)

Returns the value of attribute shipping_map.



8
9
10
# File 'app/services/edi/mft_gateway/ship_code_mapper.rb', line 8

def shipping_map
  @shipping_map
end

Instance Method Details

#ch_to_hw(shipping_code) ⇒ Object

Pass an SPS Commerce shipping code, e.g ET, and retrieves a shipping option result object describing the service requested



231
232
233
234
235
236
237
238
239
240
241
# File 'app/services/edi/mft_gateway/ship_code_mapper.rb', line 231

def ch_to_hw(shipping_code)
  sor_match = shipping_map.detect { |sor| sor.code == shipping_code }
  unless sor_match
    carrier_by_scac = Carrier.where(scac: shipping_code.to_s.upcase).first # *&^%&^* SPS Commerce can apparently send their 2 digit code or an SCAC code so handle both
    sor_match = convert_to_shipping_option_result(carrier_by_scac, shipping_code) if carrier_by_scac
  end

  raise "Unmatched shipping code #{shipping_code}" unless sor_match

  sor_match
end

#convert_to_shipping_option_result(carrier_by_scac, shipping_code) ⇒ Object



253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
# File 'app/services/edi/mft_gateway/ship_code_mapper.rb', line 253

def convert_to_shipping_option_result(carrier_by_scac, shipping_code)
  res = nil
  cn = carrier_by_scac.full_name.to_s.downcase
  # Here we use the entirely crappy NMFA SCAC data to get a carrier and use basic default shipping method if the data doesn't have a clear enough shipping method
  if cn.index('fedex')
    res = ShippingOptionResult.new(code: shipping_code, name: 'fedex_ground')
  elsif (cn.index('ups ') || cn.index('united parcel service'))
    if cn.index('second day')
      res = ShippingOptionResult.new(code: shipping_code, name: 'seconddayair')
    elsif cn.index('express')
      res = ShippingOptionResult.new(code: shipping_code, name: 'nextdayairsaver')
    elsif cn.index('freight')
      res = ShippingOptionResult.new(code: shipping_code, name: 'ups_freight_ltl')
    else
    end
  elsif cn.index('purolator')
    res = ShippingOptionResult.new(code: shipping_code, name: 'purolator_ground')
  end
  res
end

#hw_to_ch(shipping_method_name, signature: false, saturday: false) ⇒ Object

Translates a heatwave shipping option parameters into an SPS Commerce shipping code



244
245
246
# File 'app/services/edi/mft_gateway/ship_code_mapper.rb', line 244

def hw_to_ch(shipping_method_name, signature: false, saturday: false)
  shipping_map.detect { |sor| sor.name == shipping_method_name && sor.signature == signature.to_b && sor.saturday == saturday.to_b }&.code || 'DEFAULT'
end

#hw_to_sps_code_or_scac(shipping_method_name) ⇒ Object



248
249
250
251
# File 'app/services/edi/mft_gateway/ship_code_mapper.rb', line 248

def hw_to_sps_code_or_scac(shipping_method_name)
  # handle the very different way Build.com (sps_code) vs Zoro (sps_scac) handle these
  shipping_map.detect { |sor| sor.name == shipping_method_name }&.sps_code || shipping_map.detect { |sor| sor.name == shipping_method_name }&.sps_scac || 'OTHR'
end