-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #175 from friendlycart/ship-engine-ltl/request-quote
Request quotes from ShipEngine LTL API
- Loading branch information
Showing
20 changed files
with
1,306 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
9 changes: 9 additions & 0 deletions
9
lib/friendly_shipping/services/ship_engine_ltl/bad_request.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# frozen_string_literal: true | ||
|
||
module FriendlyShipping | ||
module Services | ||
class ShipEngineLTL | ||
class BadRequest < ShipEngine::BadRequest; end | ||
end | ||
end | ||
end |
33 changes: 33 additions & 0 deletions
33
lib/friendly_shipping/services/ship_engine_ltl/bad_request_handler.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'friendly_shipping/services/ship_engine_ltl/bad_request' | ||
|
||
module FriendlyShipping | ||
module Services | ||
class ShipEngineLTL | ||
class BadRequestHandler | ||
extend Dry::Monads::Result::Mixin | ||
|
||
def self.call(error, original_request: nil, original_response: nil) | ||
if error.http_code == 400 | ||
Failure( | ||
ApiFailure.new( | ||
BadRequest.new(error), | ||
original_request: original_request, | ||
original_response: original_response | ||
) | ||
) | ||
else | ||
Failure( | ||
ApiFailure.new( | ||
error, | ||
original_request: original_request, | ||
original_response: original_response | ||
) | ||
) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
31 changes: 31 additions & 0 deletions
31
lib/friendly_shipping/services/ship_engine_ltl/item_options.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# frozen_string_literal: true | ||
|
||
module FriendlyShipping | ||
module Services | ||
class ShipEngineLTL | ||
class ItemOptions < FriendlyShipping::ItemOptions | ||
attr_reader :packaging_code, | ||
:freight_class, | ||
:nmfc_code, | ||
:stackable, | ||
:hazardous_materials | ||
|
||
def initialize( | ||
packaging_code: nil, | ||
freight_class: nil, | ||
nmfc_code: nil, | ||
stackable: true, | ||
hazardous_materials: false, | ||
**kwargs | ||
) | ||
@packaging_code = packaging_code | ||
@freight_class = freight_class | ||
@nmfc_code = nmfc_code | ||
@stackable = stackable | ||
@hazardous_materials = hazardous_materials | ||
super(**kwargs) | ||
end | ||
end | ||
end | ||
end | ||
end |
15 changes: 15 additions & 0 deletions
15
lib/friendly_shipping/services/ship_engine_ltl/package_options.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'friendly_shipping/services/ups/label_item_options' | ||
|
||
module FriendlyShipping | ||
module Services | ||
class ShipEngineLTL | ||
class PackageOptions < FriendlyShipping::PackageOptions | ||
def initialize(**kwargs) | ||
super(**kwargs.merge(item_options_class: ItemOptions)) | ||
end | ||
end | ||
end | ||
end | ||
end |
72 changes: 72 additions & 0 deletions
72
lib/friendly_shipping/services/ship_engine_ltl/parse_quote_response.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'json' | ||
|
||
module FriendlyShipping | ||
module Services | ||
class ShipEngineLTL | ||
class ParseQuoteResponse | ||
extend Dry::Monads::Result::Mixin | ||
|
||
class << self | ||
def call(request:, response:) | ||
parsed_json = JSON.parse(response.body) | ||
rates = build_rates(parsed_json) | ||
if rates.any? | ||
Success( | ||
ApiResult.new( | ||
rates, | ||
original_request: request, | ||
original_response: response | ||
) | ||
) | ||
else | ||
errors = parsed_json.fetch('errors', [{ 'message' => 'Unknown error' }]) | ||
Failure( | ||
ApiResult.new( | ||
errors.map { |e| e['message'] }, | ||
original_request: request, | ||
original_response: response | ||
) | ||
) | ||
end | ||
end | ||
|
||
private | ||
|
||
def build_rates(parsed_json) | ||
total = build_total(parsed_json) | ||
return [] unless total.positive? | ||
|
||
[ | ||
FriendlyShipping::Rate.new( | ||
shipping_method: build_shipping_method(parsed_json), | ||
amounts: { total: total } | ||
) | ||
] | ||
end | ||
|
||
def build_shipping_method(parsed_json) | ||
description = parsed_json.dig("service", "carrier_description") | ||
code = parsed_json.dig("service", "code") | ||
|
||
FriendlyShipping::ShippingMethod.new( | ||
name: description, | ||
service_code: code, | ||
multi_package: true | ||
) | ||
end | ||
|
||
def build_total(parsed_json) | ||
total_charges = parsed_json.fetch("charges", []).detect { |e| e['type'] == "total" } | ||
return 0 unless total_charges | ||
|
||
currency = Money::Currency.new(total_charges.dig("amount", "currency")) | ||
value = total_charges.dig("amount", "value") | ||
Money.new(value * currency.subunit_to_unit, currency) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
34 changes: 34 additions & 0 deletions
34
lib/friendly_shipping/services/ship_engine_ltl/quote_options.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'friendly_shipping/shipment_options' | ||
|
||
module FriendlyShipping | ||
module Services | ||
class ShipEngineLTL | ||
class QuoteOptions < ShipmentOptions | ||
attr_reader :service_code, | ||
:pickup_date, | ||
:accessorial_service_codes, | ||
:packages_serializer_class | ||
|
||
# @param [String] service_code | ||
# @param [Time] pickup_date | ||
# @param [Array<String>] accessorial_service_codes | ||
# @param [Class] packages_serializer_class | ||
def initialize( | ||
service_code: nil, | ||
pickup_date: nil, | ||
accessorial_service_codes: [], | ||
packages_serializer_class: SerializePackages, | ||
**kwargs | ||
) | ||
@service_code = service_code | ||
@pickup_date = pickup_date | ||
@accessorial_service_codes = accessorial_service_codes | ||
@packages_serializer_class = packages_serializer_class | ||
super(**kwargs.merge(package_options_class: PackageOptions)) | ||
end | ||
end | ||
end | ||
end | ||
end |
41 changes: 41 additions & 0 deletions
41
lib/friendly_shipping/services/ship_engine_ltl/serialize_packages.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# frozen_string_literal: true | ||
|
||
module FriendlyShipping | ||
module Services | ||
class ShipEngineLTL | ||
class SerializePackages | ||
class << self | ||
# @param [Array<Physical::Package>] packages | ||
# @param [FriendlyShipping::Services::ShipEngineLTL::QuoteOptions] options | ||
def call(packages:, options:) | ||
packages.flat_map do |package| | ||
package_options = options.options_for_package(package) | ||
package.items.map do |item| | ||
item_options = package_options.options_for_item(item) | ||
{ | ||
code: item_options.packaging_code, | ||
freight_class: item_options.freight_class, | ||
nmfc_code: item_options.nmfc_code, | ||
description: item.description || "Commodities", | ||
dimensions: { | ||
width: item.width.convert_to(:inches).value.ceil, | ||
height: item.height.convert_to(:inches).value.ceil, | ||
length: item.length.convert_to(:inches).value.ceil, | ||
unit: "inches" | ||
}, | ||
weight: { | ||
value: item.weight.convert_to(:pounds).value.ceil, | ||
unit: "pounds" | ||
}, | ||
quantity: 1, # we don't support this yet | ||
stackable: item_options.stackable, | ||
hazardous_materials: item_options.hazardous_materials | ||
} | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
Oops, something went wrong.