friendly_shipping 0.5.2 → 0.6.3
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop-relaxed.yml +3 -4
- data/.rubocop.yml +9 -0
- data/CHANGELOG.md +32 -1
- data/friendly_shipping.gemspec +12 -12
- data/lib/friendly_shipping/api_failure.rb +2 -15
- data/lib/friendly_shipping/http_client.rb +16 -9
- data/lib/friendly_shipping/services/ship_engine/bad_request_handler.rb +15 -3
- data/lib/friendly_shipping/services/ups/parse_address_classification_response.rb +5 -2
- data/lib/friendly_shipping/services/ups/parse_address_validation_response.rb +5 -2
- data/lib/friendly_shipping/services/ups/parse_city_state_lookup_response.rb +5 -2
- data/lib/friendly_shipping/services/ups/parse_money_element.rb +2 -2
- data/lib/friendly_shipping/services/ups/parse_rate_response.rb +5 -1
- data/lib/friendly_shipping/services/ups/parse_shipment_accept_response.rb +5 -1
- data/lib/friendly_shipping/services/ups/parse_shipment_confirm_response.rb +5 -1
- data/lib/friendly_shipping/services/ups/parse_time_in_transit_response.rb +6 -2
- data/lib/friendly_shipping/services/ups/parse_void_shipment_response.rb +5 -1
- data/lib/friendly_shipping/services/ups/parse_xml_response.rb +16 -7
- data/lib/friendly_shipping/services/ups_freight.rb +44 -13
- data/lib/friendly_shipping/services/ups_freight/generate_delivery_options_hash.rb +21 -0
- data/lib/friendly_shipping/services/ups_freight/generate_document_options_hash.rb +28 -0
- data/lib/friendly_shipping/services/ups_freight/generate_email_options_hash.rb +25 -0
- data/lib/friendly_shipping/services/ups_freight/generate_freight_rate_request_hash.rb +2 -10
- data/lib/friendly_shipping/services/ups_freight/generate_freight_ship_request_hash.rb +81 -0
- data/lib/friendly_shipping/services/ups_freight/generate_location_hash.rb +5 -2
- data/lib/friendly_shipping/services/ups_freight/generate_pickup_options_hash.rb +21 -0
- data/lib/friendly_shipping/services/ups_freight/generate_pickup_request_hash.rb +31 -0
- data/lib/friendly_shipping/services/ups_freight/label_delivery_options.rb +29 -0
- data/lib/friendly_shipping/services/ups_freight/label_document_options.rb +56 -0
- data/lib/friendly_shipping/services/ups_freight/label_email_options.rb +40 -0
- data/lib/friendly_shipping/services/ups_freight/label_item_options.rb +10 -0
- data/lib/friendly_shipping/services/ups_freight/label_options.rb +37 -0
- data/lib/friendly_shipping/services/ups_freight/label_package_options.rb +10 -0
- data/lib/friendly_shipping/services/ups_freight/label_pickup_options.rb +29 -0
- data/lib/friendly_shipping/services/ups_freight/parse_freight_label_response.rb +57 -0
- data/lib/friendly_shipping/services/ups_freight/parse_freight_rate_response.rb +29 -32
- data/lib/friendly_shipping/services/ups_freight/parse_shipment_document.rb +24 -0
- data/lib/friendly_shipping/services/ups_freight/pickup_request_options.rb +29 -0
- data/lib/friendly_shipping/services/ups_freight/rates_options.rb +3 -6
- data/lib/friendly_shipping/services/ups_freight/restful_api_error_handler.rb +30 -0
- data/lib/friendly_shipping/services/ups_freight/shipment_document.rb +21 -0
- data/lib/friendly_shipping/services/ups_freight/shipment_information.rb +35 -0
- data/lib/friendly_shipping/services/usps/parse_address_validation_response.rb +5 -1
- data/lib/friendly_shipping/services/usps/parse_city_state_lookup_response.rb +5 -1
- data/lib/friendly_shipping/services/usps/parse_package_rate.rb +25 -15
- data/lib/friendly_shipping/services/usps/parse_rate_response.rb +5 -2
- data/lib/friendly_shipping/services/usps/parse_time_in_transit_response.rb +6 -2
- data/lib/friendly_shipping/services/usps/parse_xml_response.rb +15 -5
- data/lib/friendly_shipping/services/usps/rate_estimate_package_options.rb +7 -5
- data/lib/friendly_shipping/services/usps/shipping_methods.rb +23 -12
- data/lib/friendly_shipping/shipping_method.rb +5 -2
- data/lib/friendly_shipping/version.rb +1 -1
- metadata +75 -40
- data/lib/friendly_shipping/services/ups_freight/generate_ups_security_hash.rb +0 -23
- data/lib/friendly_shipping/services/ups_freight/parse_json_response.rb +0 -38
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module FriendlyShipping
|
4
|
+
module Services
|
5
|
+
class UpsFreight
|
6
|
+
class LabelPickupOptions
|
7
|
+
attr_reader :holiday_pickup,
|
8
|
+
:inside_pickup,
|
9
|
+
:weekend_pickup,
|
10
|
+
:lift_gate_required,
|
11
|
+
:limited_access_pickup
|
12
|
+
|
13
|
+
def initialize(
|
14
|
+
holiday_pickup: nil,
|
15
|
+
inside_pickup: nil,
|
16
|
+
weekend_pickup: nil,
|
17
|
+
lift_gate_required: nil,
|
18
|
+
limited_access_pickup: nil
|
19
|
+
)
|
20
|
+
@holiday_pickup = holiday_pickup
|
21
|
+
@inside_pickup = inside_pickup
|
22
|
+
@weekend_pickup = weekend_pickup
|
23
|
+
@lift_gate_required = lift_gate_required
|
24
|
+
@limited_access_pickup = limited_access_pickup
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'friendly_shipping/services/ups_freight/parse_shipment_document'
|
4
|
+
require 'friendly_shipping/services/ups_freight/shipment_information'
|
5
|
+
|
6
|
+
module FriendlyShipping
|
7
|
+
module Services
|
8
|
+
class UpsFreight
|
9
|
+
class ParseFreightLabelResponse
|
10
|
+
class << self
|
11
|
+
def call(request:, response:)
|
12
|
+
json = JSON.parse(response.body)
|
13
|
+
|
14
|
+
warnings_json = Array.wrap(json.dig("FreightShipResponse", "Response", "Alert"))
|
15
|
+
warnings = warnings_json.map do |detailed_warning|
|
16
|
+
status = detailed_warning['Code']
|
17
|
+
desc = detailed_warning['Description']
|
18
|
+
[status, desc].compact.join(": ")
|
19
|
+
end.join("\n")
|
20
|
+
|
21
|
+
shipment_results = json.dig("FreightShipResponse", "ShipmentResults")
|
22
|
+
|
23
|
+
service_code = shipment_results.dig("Service", "Code")
|
24
|
+
shipping_method = SHIPPING_METHODS.detect { |sm| sm.service_code == service_code }
|
25
|
+
|
26
|
+
total_shipment_charge = shipment_results.dig("TotalShipmentCharge")
|
27
|
+
currency = Money::Currency.new(total_shipment_charge['CurrencyCode'])
|
28
|
+
amount = total_shipment_charge['MonetaryValue'].to_f
|
29
|
+
total_money = Money.new(amount * currency.subunit_to_unit, currency)
|
30
|
+
|
31
|
+
images_data = Array.wrap(shipment_results.dig("Documents", "Image"))
|
32
|
+
|
33
|
+
bol_id = shipment_results.dig("BOLID")
|
34
|
+
shipment_number = shipment_results.dig("ShipmentNumber")
|
35
|
+
pickup_request_number = shipment_results.dig("PickupRequestConfirmationNumber")
|
36
|
+
|
37
|
+
documents = images_data.map { |image_data| ParseShipmentDocument.call(image_data: image_data) }
|
38
|
+
|
39
|
+
FriendlyShipping::ApiResult.new(
|
40
|
+
ShipmentInformation.new(
|
41
|
+
total: total_money,
|
42
|
+
bol_id: bol_id,
|
43
|
+
number: shipment_number,
|
44
|
+
pickup_request_number: pickup_request_number,
|
45
|
+
shipping_method: shipping_method,
|
46
|
+
warnings: warnings,
|
47
|
+
documents: documents
|
48
|
+
),
|
49
|
+
original_request: request,
|
50
|
+
original_response: response
|
51
|
+
)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
require 'friendly_shipping/rate'
|
4
4
|
require 'friendly_shipping/api_result'
|
5
|
-
require 'friendly_shipping/services/ups_freight/parse_json_response'
|
6
5
|
require 'friendly_shipping/services/ups_freight/shipping_methods'
|
7
6
|
|
8
7
|
module FriendlyShipping
|
@@ -11,40 +10,38 @@ module FriendlyShipping
|
|
11
10
|
class ParseFreightRateResponse
|
12
11
|
class << self
|
13
12
|
def call(request:, response:)
|
14
|
-
|
13
|
+
json = JSON.parse(response.body)
|
15
14
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
}
|
15
|
+
service_code = json.dig("FreightRateResponse", "Service", "Code")
|
16
|
+
shipping_method = SHIPPING_METHODS.detect { |sm| sm.service_code == service_code }
|
17
|
+
total_shipment_charge = json.dig("FreightRateResponse", "TotalShipmentCharge")
|
18
|
+
currency = Money::Currency.new(total_shipment_charge['CurrencyCode'])
|
19
|
+
amount = total_shipment_charge['MonetaryValue'].to_f
|
20
|
+
total_money = Money.new(amount * currency.subunit_to_unit, currency)
|
21
|
+
data = {
|
22
|
+
customer_context: json.dig("FreightRateResponse", "TransactionReference", "TransactionIdentifier"),
|
23
|
+
commodities: Array.wrap(json.dig("FreightRateResponse", "Commodity")),
|
24
|
+
response_body: json
|
25
|
+
}
|
28
26
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
|
-
FriendlyShipping::ApiResult.new(
|
35
|
-
[
|
36
|
-
FriendlyShipping::Rate.new(
|
37
|
-
amounts: {
|
38
|
-
total: total_money
|
39
|
-
},
|
40
|
-
shipping_method: shipping_method,
|
41
|
-
data: data
|
42
|
-
)
|
43
|
-
],
|
44
|
-
original_request: request,
|
45
|
-
original_response: response
|
46
|
-
)
|
27
|
+
days_in_transit = json.dig("FreightRateResponse", "TimeInTransit", "DaysInTransit")
|
28
|
+
if days_in_transit
|
29
|
+
data[:days_in_transit] = days_in_transit.to_i
|
47
30
|
end
|
31
|
+
|
32
|
+
FriendlyShipping::ApiResult.new(
|
33
|
+
[
|
34
|
+
FriendlyShipping::Rate.new(
|
35
|
+
amounts: {
|
36
|
+
total: total_money
|
37
|
+
},
|
38
|
+
shipping_method: shipping_method,
|
39
|
+
data: data
|
40
|
+
)
|
41
|
+
],
|
42
|
+
original_request: request,
|
43
|
+
original_response: response
|
44
|
+
)
|
48
45
|
end
|
49
46
|
end
|
50
47
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'friendly_shipping/services/ups_freight/shipment_document'
|
4
|
+
|
5
|
+
module FriendlyShipping
|
6
|
+
module Services
|
7
|
+
class UpsFreight
|
8
|
+
class ParseShipmentDocument
|
9
|
+
REVERSE_DOCUMENT_TYPES = LabelDocumentOptions::DOCUMENT_TYPES.map(&:reverse_each).map(&:to_a).to_h
|
10
|
+
|
11
|
+
def self.call(image_data:)
|
12
|
+
format_code = image_data.dig("Type", "Code")
|
13
|
+
graphic_image_b64 = image_data.dig("GraphicImage")
|
14
|
+
|
15
|
+
ShipmentDocument.new(
|
16
|
+
format: image_data.dig("Format", "Code").downcase.to_sym,
|
17
|
+
binary: Base64.decode64(graphic_image_b64),
|
18
|
+
document_type: REVERSE_DOCUMENT_TYPES.fetch(format_code)
|
19
|
+
)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module FriendlyShipping
|
4
|
+
module Services
|
5
|
+
class UpsFreight
|
6
|
+
class PickupRequestOptions
|
7
|
+
attr_reader :pickup_time_window,
|
8
|
+
:requester,
|
9
|
+
:third_party_requester,
|
10
|
+
:requester_email,
|
11
|
+
:comments
|
12
|
+
|
13
|
+
def initialize(
|
14
|
+
pickup_time_window:,
|
15
|
+
requester:,
|
16
|
+
requester_email:,
|
17
|
+
comments: nil,
|
18
|
+
third_party_requester: false
|
19
|
+
)
|
20
|
+
@pickup_time_window = pickup_time_window
|
21
|
+
@requester = requester
|
22
|
+
@third_party_requester = third_party_requester
|
23
|
+
@requester_email = requester_email
|
24
|
+
@comments = comments
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -31,8 +31,7 @@ module FriendlyShipping
|
|
31
31
|
:billing_code,
|
32
32
|
:customer_context,
|
33
33
|
:shipping_method,
|
34
|
-
:
|
35
|
-
:pickup_comments,
|
34
|
+
:pickup_request_options,
|
36
35
|
:commodity_information_generator
|
37
36
|
|
38
37
|
def initialize(
|
@@ -41,8 +40,7 @@ module FriendlyShipping
|
|
41
40
|
shipping_method:,
|
42
41
|
billing: :prepaid,
|
43
42
|
customer_context: nil,
|
44
|
-
|
45
|
-
pickup_comments: nil,
|
43
|
+
pickup_request_options: nil,
|
46
44
|
commodity_information_generator: GenerateCommodityInformation,
|
47
45
|
**kwargs
|
48
46
|
)
|
@@ -51,8 +49,7 @@ module FriendlyShipping
|
|
51
49
|
@shipping_method = shipping_method
|
52
50
|
@billing_code = BILLING_CODES.fetch(billing)
|
53
51
|
@customer_context = customer_context
|
54
|
-
@
|
55
|
-
@pickup_comments = pickup_comments
|
52
|
+
@pickup_request_options = pickup_request_options
|
56
53
|
@commodity_information_generator = commodity_information_generator
|
57
54
|
super(**kwargs.merge(package_options_class: RatesPackageOptions))
|
58
55
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module FriendlyShipping
|
4
|
+
module Services
|
5
|
+
class UpsFreight
|
6
|
+
class RestfulApiErrorHandler
|
7
|
+
extend Dry::Monads::Result::Mixin
|
8
|
+
|
9
|
+
def self.call(error, original_request: nil, original_response: nil)
|
10
|
+
parsed_json = JSON.parse(error.response.body)
|
11
|
+
errors = parsed_json.dig('response', 'errors')
|
12
|
+
|
13
|
+
failure_string = errors.map do |err|
|
14
|
+
status = err['code']
|
15
|
+
desc = err['message']
|
16
|
+
[status, desc].compact.join(": ").presence || 'UPS could not process the request.'
|
17
|
+
end.join("\n")
|
18
|
+
|
19
|
+
Failure(
|
20
|
+
ApiFailure.new(
|
21
|
+
failure_string,
|
22
|
+
original_request: original_request,
|
23
|
+
original_response: original_response
|
24
|
+
)
|
25
|
+
)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module FriendlyShipping
|
4
|
+
module Services
|
5
|
+
class UpsFreight
|
6
|
+
class ShipmentDocument
|
7
|
+
attr_reader :format, :document_type, :binary
|
8
|
+
|
9
|
+
def initialize(
|
10
|
+
format:,
|
11
|
+
document_type:,
|
12
|
+
binary:
|
13
|
+
)
|
14
|
+
@format = format
|
15
|
+
@document_type = document_type
|
16
|
+
@binary = binary
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module FriendlyShipping
|
4
|
+
module Services
|
5
|
+
class UpsFreight
|
6
|
+
class ShipmentInformation
|
7
|
+
attr_reader :documents,
|
8
|
+
:number,
|
9
|
+
:pickup_request_number,
|
10
|
+
:total,
|
11
|
+
:bol_id,
|
12
|
+
:shipping_method,
|
13
|
+
:warnings
|
14
|
+
|
15
|
+
def initialize(
|
16
|
+
total:,
|
17
|
+
bol_id:,
|
18
|
+
number:,
|
19
|
+
pickup_request_number: nil,
|
20
|
+
documents: [],
|
21
|
+
shipping_method: nil,
|
22
|
+
warnings: nil
|
23
|
+
)
|
24
|
+
@total = total
|
25
|
+
@bol_id = bol_id
|
26
|
+
@number = number
|
27
|
+
@pickup_request_number = pickup_request_number
|
28
|
+
@documents = documents
|
29
|
+
@shipping_method = shipping_method
|
30
|
+
@warnings = warnings
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -12,7 +12,11 @@ module FriendlyShipping
|
|
12
12
|
# @return [Result<FriendlyShipping::AddressValidationResult>]
|
13
13
|
def call(request:, response:)
|
14
14
|
# Filter out error responses and directly return a failure
|
15
|
-
parsing_result = ParseXMLResponse.call(
|
15
|
+
parsing_result = ParseXMLResponse.call(
|
16
|
+
request: request,
|
17
|
+
response: response,
|
18
|
+
expected_root_tag: 'AddressValidateResponse'
|
19
|
+
)
|
16
20
|
parsing_result.fmap do |xml|
|
17
21
|
address = xml.root.at('Address')
|
18
22
|
suggestions = [
|
@@ -12,7 +12,11 @@ module FriendlyShipping
|
|
12
12
|
# @return [Result<FriendlyShipping::AddressValidationResult>]
|
13
13
|
def call(request:, response:)
|
14
14
|
# Filter out error responses and directly return a failure
|
15
|
-
parsing_result = ParseXMLResponse.call(
|
15
|
+
parsing_result = ParseXMLResponse.call(
|
16
|
+
request: request,
|
17
|
+
response: response,
|
18
|
+
expected_root_tag: 'CityStateLookupResponse'
|
19
|
+
)
|
16
20
|
parsing_result.fmap do |xml|
|
17
21
|
address = xml.root.at('ZipCode')
|
18
22
|
suggestions = [
|
@@ -54,6 +54,7 @@ module FriendlyShipping
|
|
54
54
|
SERVICE_NAME_TAG = 'MailService'
|
55
55
|
RATE_TAG = 'Rate'
|
56
56
|
COMMERCIAL_RATE_TAG = 'CommercialRate'
|
57
|
+
COMMERCIAL_PLUS_RATE_TAG = 'CommercialPlusRate'
|
57
58
|
CURRENCY = Money::Currency.new('USD').freeze
|
58
59
|
|
59
60
|
class << self
|
@@ -82,27 +83,36 @@ module FriendlyShipping
|
|
82
83
|
|
83
84
|
# Some USPS services only offer commercial pricing. Unfortunately, USPS then returns a retail rate of 0.
|
84
85
|
# In these cases, return the commercial rate instead of the normal rate.
|
86
|
+
#
|
85
87
|
# Some rates are available in both commercial and retail pricing - if we want the commercial pricing here,
|
86
88
|
# we need to specify the commercial_pricing property on the `Physical::Package`.
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
89
|
+
#
|
90
|
+
commercial_rate_requested_or_rate_is_zero = package_options.commercial_pricing || rate_node.at(RATE_TAG).text.to_d.zero?
|
91
|
+
commercial_rate_available = rate_node.at(COMMERCIAL_RATE_TAG) || rate_node.at(COMMERCIAL_PLUS_RATE_TAG)
|
92
|
+
|
93
|
+
rate_value =
|
94
|
+
if commercial_rate_requested_or_rate_is_zero && commercial_rate_available
|
95
|
+
rate_node.at(COMMERCIAL_RATE_TAG)&.text&.to_d || rate_node.at(COMMERCIAL_PLUS_RATE_TAG).text.to_d
|
96
|
+
else
|
97
|
+
rate_node.at(RATE_TAG).text.to_d
|
98
|
+
end
|
92
99
|
|
93
100
|
# The rate expressed as a RubyMoney objext
|
94
101
|
rate = Money.new(rate_value * CURRENCY.subunit_to_unit, CURRENCY)
|
95
102
|
|
96
|
-
# Which shipping method does this rate belong to?
|
97
|
-
#
|
98
|
-
#
|
99
|
-
#
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
103
|
+
# Which shipping method does this rate belong to? We first try to match a rate to a shipping method
|
104
|
+
# by class ID (the CLASSID attribute in the USPS API rate response). Not every shipping method
|
105
|
+
# has a class ID defined, and a shipping method can have multiple class IDs (for example, Priority
|
106
|
+
# Express has different class IDs for standard, hold for pickup, and Sunday/Holiday delivery).
|
107
|
+
#
|
108
|
+
# If we don't find a match for class ID, we next try to match a rate to a shipping method using the
|
109
|
+
# shipping method's service code. The USPS API rate response includes a name for each rate in the
|
110
|
+
# MailService element. We match to see if the name starts with the given value. For example:
|
111
|
+
# `Priority Mail Express 2-day™`
|
112
|
+
#
|
113
|
+
shipping_method =
|
114
|
+
SHIPPING_METHODS.detect { |sm| sm.data[:class_ids]&.include?(service_code) } ||
|
115
|
+
SHIPPING_METHODS.detect { |sm| service_name.tr('-', ' ').upcase.starts_with?(sm.service_code) }
|
106
116
|
|
107
117
|
# We find out the box name using a bit of Regex magic using named captures. See the `BOX_REGEX`
|
108
118
|
# constant above.
|
@@ -20,8 +20,11 @@ module FriendlyShipping
|
|
20
20
|
# @return [Result<ApiResult<Array<FriendlyShipping::Rate>>>] When successfully parsing, an array of rates in a Success Monad.
|
21
21
|
def call(request:, response:, shipment:, options:)
|
22
22
|
# Filter out error responses and directly return a failure
|
23
|
-
parsing_result = ParseXMLResponse.call(
|
24
|
-
|
23
|
+
parsing_result = ParseXMLResponse.call(
|
24
|
+
request: request,
|
25
|
+
response: response,
|
26
|
+
expected_root_tag: 'RateV4Response'
|
27
|
+
)
|
25
28
|
parsing_result.fmap do |xml|
|
26
29
|
# Get all the possible rates for each package
|
27
30
|
rates_by_package = rates_from_response_node(xml, shipment, options)
|
@@ -15,7 +15,11 @@ module FriendlyShipping
|
|
15
15
|
# @return [Result<ApiResult<Array<FriendlyShipping::Timing>>>] When successfully parsing, an array of timings in a Success Monad.
|
16
16
|
def call(request:, response:)
|
17
17
|
# Filter out error responses and directly return a failure
|
18
|
-
parsing_result = ParseXMLResponse.call(
|
18
|
+
parsing_result = ParseXMLResponse.call(
|
19
|
+
request: request,
|
20
|
+
response: response,
|
21
|
+
expected_root_tag: 'SDCGetLocationsResponse'
|
22
|
+
)
|
19
23
|
parsing_result.fmap do |xml|
|
20
24
|
expedited_commitments = xml.xpath('//Expedited')
|
21
25
|
expedited_timings = parse_expedited_commitment_nodes(expedited_commitments)
|
@@ -111,7 +115,7 @@ module FriendlyShipping
|
|
111
115
|
# This will likely be somewhat more work in the future.
|
112
116
|
MAIL_CLASSES = {
|
113
117
|
'1' => 'Priority Mail Express',
|
114
|
-
'2' => 'Priority',
|
118
|
+
'2' => 'Priority Mail',
|
115
119
|
'3' => 'First-Class',
|
116
120
|
'6' => 'Package Services'
|
117
121
|
}.freeze
|