Class: Shipping::LtlShippingInsurance

Inherits:
BaseService show all
Defined in:
app/services/shipping/ltl_shipping_insurance.rb

Overview

Books or voids Loadsurance shipping insurance for LTL deliveries.

WarmlyYours self-insures LTL freight as of 2025-01-30, so the public
process entry point short-circuits and most integration code is
currently defensive. Carrier metadata and threshold helpers remain for
re-enabling the Loadsurance integration later.

See Also:

Defined Under Namespace

Classes: Result

Constant Summary collapse

LOADSURE_API_HASH =

Loadsurance integration is currently disabled. When re-enabled, fetch
credentials from Heatwave::Configuration.fetch(:loadsurance_api)
rather than re-introducing top-level LOADSURE_* constants.

{}.freeze
INSURED_VALUE_MIN =

Insured value min.

5000.0
INSURANCE_FEE_MAX_PERCENT =

Insurance fee max percent.

0.05
INSURANCE_FEE_MAX_AMOUNT =

Insurance fee max amount.

250.0
INSURANCE_DED_MAX_PERCENT =

Insurance ded max percent.

0.2
INSURANCE_DED_MAX_AMOUNT =

Insurance ded max amount.

1000.0
INSURANCE_FEE_MIN_AMOUNT =

Insurance fee min amount.

5.0
LOADSURANCE_CARRIER_DATA_BY_CARRIER =

here we only populate parcel carriers that we know are covered by our Shipsurance contract
we do not cover freight carriers per Shipsurance contract

{
  FedExFreight: {
    mode: 'ROAD',
    name: 'FedEx Freight',
    email: 'mark.lackinger@fedex.com',
    carrierId: {
      type: 'SCAC',
      value: 'FXFS'
    },
    phone: '+12242422831',
    address: {
      address1: '5600 9TH ST',
      city: 'Zion',
      state: 'IL',
      postal: '60099',
      country: 'US'
    }
  },
  Freightquote: {
    mode: 'ROAD',
    name: 'Freightquote.com Inc',
    email: 'brian.dougherty@freightquote.com',
    carrierId: {
      type: 'SCAC',
      value: 'FQCI'
    },
    phone: '+18169496250',
    address: {
      address1: '901 West Carondelet Drive',
      city: 'Kansas City',
      state: 'MO',
      postal: '64114',
      country: 'US'
    }
  },
  RlCarriers: {
    mode: 'ROAD',
    name: 'R&L Carriers',
    email: 'scott.brighton@rlcarriers.com',
    carrierId: {
      type: 'SCAC',
      value: 'RLCA'
    },
    phone: '+18476953100',
    address: {
      address1: '375 Second Street',
      city: 'Elgin',
      state: 'IL',
      postal: '60123',
      country: 'US'
    }
  },
  ShipengineRoadrunner: {
    mode: 'ROAD',
    name: 'Roadrunner Freight',
    email: 'robert.provost@rrts.com',
    carrierId: {
      type: 'SCAC',
      value: 'RDFS'
    },
    phone: '+18478007768',
    address: {
      address1: '4801 68th Avenue',
      city: 'Kenosha',
      state: 'WI',
      postal: '53144',
      country: 'US'
    }
  },
  ShipengineSaia: {
    mode: 'ROAD',
    name: 'Saia LTL Freight',
    email: 'ssanti@saia.com',
    carrierId: {
      type: 'SCAC',
      value: 'SAIA'
    },
    phone: '+18474716588',
    address: {
      address1: '2260 Midlothian Road',
      city: 'Grayslake',
      state: 'IL',
      postal: '60030',
      country: 'US'
    }
  }
}.then do |h|
  # Legacy carrier-string aliases for historical shipments.carrier rows
  # (Freightquote-brokered Saia/Roadrunner from before the direct
  # ShipEngine LTL integration). Kept so label regen / insurance lookups
  # by old `delivery.carrier` strings still resolve. Loadsurance
  # integration is currently disabled, so this is defensive only.
  h.merge(Saia: h[:ShipengineSaia], Roadrunner: h[:ShipengineRoadrunner]).freeze
end
COVERAGE_LIMIT =

Limit for coverage.

25_000.0
LTL_SELF_INSURED =

Per Christian Billen and Venu Adepu (1/30/2025): WarmlyYours self-insures all LTL freight
after 25+ years of zero claims or losses. When true this constant drives:

  1. qualifies_for_rating? → false (hides Shipsurance/Loadsure UI section)
  2. do_not_ship_insure_via_carrier? → true (zeros carrier declared value)
  3. shipengine_ltl_base insured_value hardcoded to 0.0
    Cross-border customs/commercial invoice values (calculate_declared_value,
    unit_value_for_commercial_invoice) are NOT affected — those are separate concerns.
true

Instance Attribute Summary

Attributes inherited from BaseService

#options

Instance Method Summary collapse

Methods inherited from BaseService

#initialize, #log_debug, #log_error, #log_info, #log_warning, #logger, #tagged_logger

Constructor Details

This class inherits a constructor from BaseService

Instance Method Details

#bill_shipping_to_customer_and_not_a_store_transfer?(delivery) ⇒ Boolean

Whether the customer is billed for shipping and this is not a store transfer.

When billing to the customer, they pay for declared value via the carrier
instead of Loadsurance.

Parameters:

  • delivery (Delivery)

    the delivery to evaluate

Returns:

  • (Boolean)

    true when the customer pays and it is not a store transfer



193
194
195
196
# File 'app/services/shipping/ltl_shipping_insurance.rb', line 193

def bill_shipping_to_customer_and_not_a_store_transfer?(delivery)
  # if billing to customer, let them pay for declared value via carrier
  delivery.bill_shipping_to_customer && !delivery.order&.is_store_transfer? # this is to be readable to me, a human
end

#book_shipping_insurance_for_delivery(delivery, _options) ⇒ Result

Books shipping insurance for the delivery through Loadsurance.

Parameters:

  • delivery (Delivery)

    the delivery to insure

  • _options (Hash)

    unused; reserved for future options

Returns:

  • (Result)

    the booking outcome



271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
# File 'app/services/shipping/ltl_shipping_insurance.rb', line 271

def book_shipping_insurance_for_delivery(delivery, _options)
  status = :ok
  status_message = ''
  insurance_result_hash = {}

  quote_hash = HTTP.use(logging: { logger: Rails.logger }).timeout(60).auth("Bearer #{LOADSURE_API_HASH[:token]}").post("#{LOADSURE_API_HASH[:base_url]}/quote", json: quote_data(delivery)).parse.with_indifferent_access
  if quote_hash[:success] == false
    msgs = (quote_hash[:errors] || []).map { |e| e.dig(:message) }
    status = :error
    status_message = msgs.join('. ')
  else
    quote_cost = quote_hash.dig(:insuranceProduct, :premium).to_f + quote_hash.dig(:insuranceProduct, :serviceFee).to_f
    quote_deductible = quote_hash.dig(:insuranceProduct, :deductible).to_f
    threshhold_exceeded_hash = insurance_quote_exceeds_thresholds?(quote_cost, apply_carrier_coverage_limit(delivery), quote_deductible)
    quote_token = quote_hash.dig(:quoteToken)
    if threshhold_exceeded_hash[:status] != :ok
      status = threshhold_exceeded_hash[:status]
      status_message = threshhold_exceeded_hash[:status_message]
    elsif quote_token.present?
      insurance_result_hash = HTTP.use(logging: { logger: Rails.logger }).timeout(60).auth("Bearer #{LOADSURE_API_HASH[:token]}").post("#{LOADSURE_API_HASH[:base_url]}/purchaseQuote",
                                                                                                                                       json: { quoteToken: quote_token,
                                                                                                                                               additionalAuthorizedUsers: [LOADSURE_API_HASH[:additional_user_id]] }).parse.with_indifferent_access
      if insurance_result_hash[:error].present?
        status = :error
        status_message = insurance_result_hash[:error]
      end
    end
  end

  delivery.shipments.update_all(shipping_insurance_data: { shipping_insurance_record_id: insurance_result_hash[:certificateNumber] }.merge(insurance_result_hash)) if status == :ok
  Result.new(status: status, status_message: status_message)
end

#carrier_present?(carrier) ⇒ Boolean

Whether Loadsurance metadata is configured for the carrier.

Parameters:

  • carrier (String, Symbol, nil)

    carrier identifier

Returns:

  • (Boolean)

    true when carrier data is present



214
215
216
# File 'app/services/shipping/ltl_shipping_insurance.rb', line 214

def carrier_present?(carrier)
  LOADSURANCE_CARRIER_DATA_BY_CARRIER[(carrier || 'none').to_sym].present?
end

#carrier_qualifies_for_rating?(carrier) ⇒ Boolean

Whether the named carrier can be used for Loadsurance rating.

Parameters:

  • carrier (String, Symbol, nil)

    carrier identifier

Returns:

  • (Boolean)

    true when the carrier is present in the Loadsurance data



230
231
232
233
# File 'app/services/shipping/ltl_shipping_insurance.rb', line 230

def carrier_qualifies_for_rating?(carrier)
  # here we want to return a simple TRUE/FALSE boolean, this is to see if we can use this
  carrier_present?(carrier)
end

#cross_border_fedex_freight?(delivery) ⇒ Boolean

Whether the delivery is cross-border FedEx Freight.

Cross-border FedEx Freight shipments are not insured via Loadsurance
because the declared value must still be passed to the carrier.

Parameters:

  • delivery (Delivery)

    the delivery to evaluate

Returns:

  • (Boolean)

    true for cross-border FedEx Freight



205
206
207
208
# File 'app/services/shipping/ltl_shipping_insurance.rb', line 205

def cross_border_fedex_freight?(delivery)
  # we do not ship insure cross border FedEx Freight via Loadsurance because we need to pass declared value
  delivery.carrier == 'FedExFreight' && delivery.is_cross_border? # this is to be readable to me, a human
end

#delivery_carrier_present?(delivery) ⇒ Boolean

Whether the delivery's carrier is supported by Loadsurance.

Parameters:

  • delivery (Delivery)

    the delivery to evaluate

Returns:

  • (Boolean)

    true when the carrier is present in the Loadsurance data



222
223
224
# File 'app/services/shipping/ltl_shipping_insurance.rb', line 222

def delivery_carrier_present?(delivery)
  carrier_present?(delivery.carrier)
end

#get_shipping_insurance_cost_for_delivery(delivery) ⇒ Float

Returns the total shipping insurance premium stored on the delivery.

Parameters:

  • delivery (Delivery)

    the delivery to inspect

Returns:

  • (Float)

    the premium amount



327
328
329
330
# File 'app/services/shipping/ltl_shipping_insurance.rb', line 327

def get_shipping_insurance_cost_for_delivery(delivery)
  delivery.shipments.first&.shipping_insurance_data&.dig('premium').to_f
  # cost = delivery.shipments.where("carrier IS NOT NULL").sum{|s| get_shipping_insurance_cost_for_shipment(s)}
end

#get_shipping_insurance_cost_for_shipment(shipment) ⇒ Float

Returns the per-shipment share of the insurance premium.

Parameters:

  • shipment (Shipment)

    the shipment to price

Returns:

  • (Float)

    the premium allocated to this shipment



336
337
338
# File 'app/services/shipping/ltl_shipping_insurance.rb', line 336

def get_shipping_insurance_cost_for_shipment(shipment)
  (get_shipping_insurance_cost_for_delivery(shipment.delivery) / [shipment.delivery.shipments.size, 1].max).round(2)
end

#get_shipping_insurance_insured_value_for_delivery(delivery) ⇒ Float

Returns the absolute declared value used to insure the delivery.

Parameters:

  • delivery (Delivery)

    the delivery to evaluate

Returns:

  • (Float)

    the insured value



344
345
346
# File 'app/services/shipping/ltl_shipping_insurance.rb', line 344

def get_shipping_insurance_insured_value_for_delivery(delivery)
  delivery.calculate_declared_value.to_f.abs
end

#get_shipping_insurance_insured_value_for_shipment(shipment) ⇒ Float

Returns the per-shipment share of the insured value.

Parameters:

  • shipment (Shipment)

    the shipment to evaluate

Returns:

  • (Float)

    the insured value allocated to this shipment



352
353
354
# File 'app/services/shipping/ltl_shipping_insurance.rb', line 352

def get_shipping_insurance_insured_value_for_shipment(shipment)
  (shipment.delivery.calculate_declared_value.to_f.abs / [shipment.delivery.shipments.size, 1].max).round(2)
end

Returns an HTML link to the Loadsurance certificate and claim page.

Parameters:

  • shipment (Shipment)

    the shipment whose certificate to link

Returns:

  • (ActiveSupport::SafeBuffer)

    HTML anchor tags



360
361
362
# File 'app/services/shipping/ltl_shipping_insurance.rb', line 360

def get_shipping_insurance_link_for_shipment(shipment)
  %(<a href='https://portal.loadsure.net/certificates/details/?certificateNumber=#{shipment.shipping_insurance_record_id}' target='_blank' rel='noopener'>#{shipment.shipping_insurance_record_id}</a> <small>(file claim <a href='https://portal.loadsure.net/claims/file?id=#{shipment.shipping_insurance_record_id}' target='_blank' rel='noopener' onclick='return confirm("Are you sure you want to file a claim?")'>here</a>)</small>).html_safe
end

#process(delivery, _options = {}) ⇒ Result

Service entry point. Currently self-insures all LTL deliveries.

Parameters:

  • delivery (Delivery)

    the delivery to evaluate or insure

  • _options (Hash) (defaults to: {})

    unused; reserved for future options

Returns:

  • (Result)

    the outcome of the insurance request



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'app/services/shipping/ltl_shipping_insurance.rb', line 157

def process(delivery, _options = {})
  status = :ok
  status_message = 'WarmlyYours Self Insures all LTL Shipping'
  qualifies(delivery)
  # 03/18/24 Here we have decided per Venu and Christian to discontinue our Shipping Insurance with Loadsure, and self-insure after seeing no record of any claims or losses for LTL shipments in our history.
  # So we want to qualify all LTL shipments i.e. return TRUE, so we don't pass declared value to the LTL carriers, but then do nothing when it is ship insurance time
  # if qualifies_res.status == :ok
  #   r = book_shipping_insurance_for_delivery(delivery, options)
  #   unless r.status == :ok
  #     status = :error
  #     status_message = "Shipping insurance for delivery #{delivery.name} cannot be booked: #{r.status_message}"
  #   end
  # else
  #   status = qualifies_res.status
  #   status_message = qualifies_res.status_message
  # end
  Result.new(status: status, status_message: status_message)
end

#qualifies(_delivery) ⇒ Result

Evaluates whether the delivery can be insured.

Currently returns an error because LTL shipping insurance is disabled.

Parameters:

  • _delivery (Delivery)

    unused; reserved for future qualification logic

Returns:

  • (Result)

    qualification outcome



241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
# File 'app/services/shipping/ltl_shipping_insurance.rb', line 241

def qualifies(_delivery)
  # status = :ok
  # status_message = ''
  # any_labeled_shipments = delivery.shipments.label_complete.any?
  # all_labeled_shipments_have_tracking_number = delivery.shipments.label_complete.all?{|s| s.tracking_number.present?}
  # unless qualifies_for_rating?(delivery) && any_labeled_shipments && all_labeled_shipments_have_tracking_number
  #   status = :error
  #   status_message_arr = []
  #   status_message_arr << "Order #{delivery.order&.reference_number} does not qualify for Loadsurance shipping insurance"
  #   status_message_arr << "Carrier #{delivery.carrier} is not one of our covered Loadsurance carriers" if !delivery_carrier_present?(delivery)
  #   status_message_arr << "When customer pays for shipping we do not ship insure via Loadsurance" if bill_shipping_to_customer_and_not_a_store_transfer?(delivery)
  #   status_message_arr << "When delivery value is less than $#{INSURED_VALUE_MIN.round(2)} we do not ship insure via Loadsurance" if delivery.calculate_declared_value.to_f.abs < INSURED_VALUE_MIN
  #   status_message_arr << "When delivery is FedExFreight cross-border, we do not ship insure via Loadsurance" if cross_border_fedex_freight?(delivery)
  #   status_message_arr << "Delivery does not have any labeled shipments" if !any_labeled_shipments
  #   status_message_arr << "Not all shipments have tracking numbers" if !all_labeled_shipments_have_tracking_number
  #   status_message = "#{status_message_arr.join('. ')}."
  # end
  ############################################################################
  # Note that we are disabling LTL shipping insurance for all deliveries based on price increases, lack of claims and an executive decision by Christian Billen and Venu Adepu on 1/30/2025
  ############################################################################
  status = :error
  status_message = 'LTL shipping insurance is now disabled.'
  Result.new(status: status, status_message: status_message)
end

#qualifies_for_rating?(delivery) ⇒ Boolean

Whether the delivery qualifies for Loadsurance rating.

Parameters:

  • delivery (Delivery)

    the delivery to evaluate

Returns:

  • (Boolean)

    true when the carrier, value, and routing constraints pass



180
181
182
183
184
# File 'app/services/shipping/ltl_shipping_insurance.rb', line 180

def qualifies_for_rating?(delivery)
  return false if LTL_SELF_INSURED

  delivery.supported_shipping_carrier? && delivery_carrier_present?(delivery) && (delivery.calculate_declared_value.to_f.abs > INSURED_VALUE_MIN) && !cross_border_fedex_freight?(delivery) && !bill_shipping_to_customer_and_not_a_store_transfer?(delivery)
end

#void_shipping_insurance_for_delivery(delivery) ⇒ Result

Voids the Loadsurance certificate associated with the delivery.

Parameters:

  • delivery (Delivery)

    the delivery whose insurance should be voided

Returns:

  • (Result)

    the void outcome



308
309
310
311
312
313
314
315
316
317
318
319
320
321
# File 'app/services/shipping/ltl_shipping_insurance.rb', line 308

def void_shipping_insurance_for_delivery(delivery)
  status = :ok
  status_message = ''

  void_result_hash = HTTP.use(logging: { logger: Rails.logger }).timeout(60).auth("Bearer #{LOADSURE_API_HASH[:token]}").post("#{LOADSURE_API_HASH[:base_url]}/cancelCertificate", json: void_data(delivery)).parse.with_indifferent_access
  if void_result_hash[:success] == false
    msgs = (void_result_hash[:errors] || []).map { |e| e.dig(:message) }
    status = :error
    status_message = msgs.join('. ')
  end

  delivery.shipments.update_all(shipping_insurance_data: {}.merge(void_result_hash)) if status == :ok
  Result.new(status: status, status_message: status_message)
end