friendly_shipping 0.9.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +1 -1
  3. data/.rubocop.yml +6 -0
  4. data/README.md +1 -1
  5. data/friendly_shipping.gemspec +7 -7
  6. data/lib/friendly_shipping/access_token.rb +24 -0
  7. data/lib/friendly_shipping/api_error.rb +4 -2
  8. data/lib/friendly_shipping/api_error_handler.rb +4 -6
  9. data/lib/friendly_shipping/api_failure.rb +2 -11
  10. data/lib/friendly_shipping/api_result.rb +10 -0
  11. data/lib/friendly_shipping/http_client.rb +4 -10
  12. data/lib/friendly_shipping/label.rb +0 -2
  13. data/lib/friendly_shipping/services/rl/api_error.rb +0 -2
  14. data/lib/friendly_shipping/services/rl/bol_options.rb +0 -4
  15. data/lib/friendly_shipping/services/rl/item_options.rb +0 -2
  16. data/lib/friendly_shipping/services/rl/package_options.rb +0 -2
  17. data/lib/friendly_shipping/services/rl/parse_create_bol_response.rb +0 -3
  18. data/lib/friendly_shipping/services/rl/parse_invoice_response.rb +0 -3
  19. data/lib/friendly_shipping/services/rl/parse_print_bol_response.rb +0 -3
  20. data/lib/friendly_shipping/services/rl/parse_print_shipping_labels_response.rb +0 -3
  21. data/lib/friendly_shipping/services/rl/parse_rate_quote_response.rb +31 -4
  22. data/lib/friendly_shipping/services/rl/parse_transit_times_response.rb +0 -3
  23. data/lib/friendly_shipping/services/rl/rate_quote_options.rb +0 -4
  24. data/lib/friendly_shipping/services/rl/serialize_location.rb +9 -2
  25. data/lib/friendly_shipping/services/rl/shipment_options.rb +0 -2
  26. data/lib/friendly_shipping/services/rl.rb +4 -21
  27. data/lib/friendly_shipping/services/ship_engine/api_error.rb +0 -2
  28. data/lib/friendly_shipping/services/ship_engine/label_item_options.rb +0 -2
  29. data/lib/friendly_shipping/services/ship_engine/label_options.rb +0 -4
  30. data/lib/friendly_shipping/services/ship_engine/label_package_options.rb +0 -3
  31. data/lib/friendly_shipping/services/ship_engine/parse_address_validation_response.rb +3 -5
  32. data/lib/friendly_shipping/services/ship_engine/parse_carrier_response.rb +0 -2
  33. data/lib/friendly_shipping/services/ship_engine/parse_label_response.rb +0 -2
  34. data/lib/friendly_shipping/services/ship_engine/parse_rate_estimates_response.rb +2 -4
  35. data/lib/friendly_shipping/services/ship_engine/parse_rates_response.rb +2 -4
  36. data/lib/friendly_shipping/services/ship_engine/parse_void_response.rb +2 -2
  37. data/lib/friendly_shipping/services/ship_engine/rate_estimates_options.rb +0 -2
  38. data/lib/friendly_shipping/services/ship_engine/rates_item_options.rb +0 -2
  39. data/lib/friendly_shipping/services/ship_engine/rates_options.rb +0 -2
  40. data/lib/friendly_shipping/services/ship_engine/rates_package_options.rb +0 -2
  41. data/lib/friendly_shipping/services/ship_engine.rb +11 -28
  42. data/lib/friendly_shipping/services/ship_engine_ltl/parse_carrier_response.rb +1 -3
  43. data/lib/friendly_shipping/services/ship_engine_ltl/parse_quote_response.rb +1 -3
  44. data/lib/friendly_shipping/services/ship_engine_ltl.rb +5 -17
  45. data/lib/friendly_shipping/services/tforce_freight/access_token.rb +3 -18
  46. data/lib/friendly_shipping/services/tforce_freight/api_error.rb +0 -2
  47. data/lib/friendly_shipping/services/tforce_freight/generate_create_bol_request_hash.rb +2 -14
  48. data/lib/friendly_shipping/services/tforce_freight/generate_pickup_request_hash.rb +0 -2
  49. data/lib/friendly_shipping/services/tforce_freight/generate_rates_request_hash.rb +0 -2
  50. data/lib/friendly_shipping/services/tforce_freight/package_options.rb +0 -2
  51. data/lib/friendly_shipping/services/tforce_freight/parse_create_bol_response.rb +0 -4
  52. data/lib/friendly_shipping/services/tforce_freight/parse_rates_response.rb +4 -12
  53. data/lib/friendly_shipping/services/tforce_freight/parse_shipment_document.rb +0 -2
  54. data/lib/friendly_shipping/services/tforce_freight/rates_item_options.rb +0 -2
  55. data/lib/friendly_shipping/services/tforce_freight/rates_options.rb +0 -3
  56. data/lib/friendly_shipping/services/tforce_freight/rates_package_options.rb +0 -2
  57. data/lib/friendly_shipping/services/tforce_freight/shipment_options.rb +0 -2
  58. data/lib/friendly_shipping/services/tforce_freight.rb +1 -27
  59. data/lib/friendly_shipping/services/ups/label_item_options.rb +0 -2
  60. data/lib/friendly_shipping/services/ups/label_options.rb +0 -3
  61. data/lib/friendly_shipping/services/ups/label_package_options.rb +0 -2
  62. data/lib/friendly_shipping/services/ups/parse_address_validation_response.rb +1 -1
  63. data/lib/friendly_shipping/services/ups/parse_rate_response.rb +0 -4
  64. data/lib/friendly_shipping/services/ups/parse_shipment_accept_response.rb +0 -3
  65. data/lib/friendly_shipping/services/ups/parse_shipment_confirm_response.rb +0 -2
  66. data/lib/friendly_shipping/services/ups/parse_void_shipment_response.rb +0 -2
  67. data/lib/friendly_shipping/services/ups/parse_xml_response.rb +1 -1
  68. data/lib/friendly_shipping/services/ups/rate_estimate_options.rb +0 -2
  69. data/lib/friendly_shipping/services/ups/rate_estimate_package_options.rb +0 -2
  70. data/lib/friendly_shipping/services/ups/serialize_access_request.rb +0 -2
  71. data/lib/friendly_shipping/services/ups/serialize_rating_service_selection_request.rb +0 -4
  72. data/lib/friendly_shipping/services/ups/serialize_shipment_confirm_request.rb +0 -3
  73. data/lib/friendly_shipping/services/ups.rb +1 -23
  74. data/lib/friendly_shipping/services/ups_freight/api_error.rb +0 -2
  75. data/lib/friendly_shipping/services/ups_freight/generate_freight_rate_request_hash.rb +0 -4
  76. data/lib/friendly_shipping/services/ups_freight/generate_freight_ship_request_hash.rb +0 -8
  77. data/lib/friendly_shipping/services/ups_freight/parse_freight_label_response.rb +0 -3
  78. data/lib/friendly_shipping/services/ups_freight/parse_freight_rate_response.rb +0 -4
  79. data/lib/friendly_shipping/services/ups_freight/parse_shipment_document.rb +0 -2
  80. data/lib/friendly_shipping/services/ups_freight/rates_options.rb +0 -4
  81. data/lib/friendly_shipping/services/ups_freight/rates_package_options.rb +0 -2
  82. data/lib/friendly_shipping/services/ups_freight/rates_structure_options.rb +0 -2
  83. data/lib/friendly_shipping/services/ups_freight/shipment_options.rb +0 -2
  84. data/lib/friendly_shipping/services/ups_freight.rb +1 -21
  85. data/lib/friendly_shipping/services/ups_json/access_token.rb +3 -12
  86. data/lib/friendly_shipping/services/ups_json/api_error.rb +0 -2
  87. data/lib/friendly_shipping/services/ups_json/generate_city_state_lookup_payload.rb +23 -0
  88. data/lib/friendly_shipping/services/ups_json/generate_labels_payload.rb +0 -3
  89. data/lib/friendly_shipping/services/ups_json/generate_rates_payload.rb +2 -4
  90. data/lib/friendly_shipping/services/ups_json/label_item_options.rb +0 -2
  91. data/lib/friendly_shipping/services/ups_json/label_options.rb +0 -3
  92. data/lib/friendly_shipping/services/ups_json/label_package_options.rb +0 -2
  93. data/lib/friendly_shipping/services/ups_json/parse_city_state_lookup_response.rb +44 -0
  94. data/lib/friendly_shipping/services/ups_json/parse_json_response.rb +13 -6
  95. data/lib/friendly_shipping/services/ups_json/parse_labels_response.rb +4 -4
  96. data/lib/friendly_shipping/services/ups_json/parse_money_hash.rb +1 -1
  97. data/lib/friendly_shipping/services/ups_json/parse_rate_modifier_hash.rb +2 -2
  98. data/lib/friendly_shipping/services/ups_json/parse_rates_response.rb +19 -17
  99. data/lib/friendly_shipping/services/ups_json/rates_item_options.rb +0 -2
  100. data/lib/friendly_shipping/services/ups_json/rates_options.rb +0 -2
  101. data/lib/friendly_shipping/services/ups_json.rb +23 -23
  102. data/lib/friendly_shipping/services/usps/parse_rate_response.rb +0 -4
  103. data/lib/friendly_shipping/services/usps/parse_time_in_transit_response.rb +0 -3
  104. data/lib/friendly_shipping/services/usps/parse_xml_response.rb +1 -1
  105. data/lib/friendly_shipping/services/usps/rate_estimate_options.rb +0 -2
  106. data/lib/friendly_shipping/services/usps/rate_estimate_package_options.rb +0 -2
  107. data/lib/friendly_shipping/services/usps/serialize_rate_request.rb +0 -2
  108. data/lib/friendly_shipping/services/usps.rb +1 -12
  109. data/lib/friendly_shipping/services/usps_international/parse_rate_response.rb +0 -3
  110. data/lib/friendly_shipping/services/usps_international/rate_estimate_options.rb +0 -2
  111. data/lib/friendly_shipping/services/usps_international/rate_estimate_package_options.rb +0 -2
  112. data/lib/friendly_shipping/services/usps_international/serialize_rate_request.rb +0 -2
  113. data/lib/friendly_shipping/services/usps_international.rb +1 -5
  114. data/lib/friendly_shipping/services/usps_ship/access_token.rb +3 -18
  115. data/lib/friendly_shipping/services/usps_ship/api_error.rb +0 -2
  116. data/lib/friendly_shipping/services/usps_ship/machinable_package.rb +6 -4
  117. data/lib/friendly_shipping/services/usps_ship/parse_rate_estimates_response.rb +3 -3
  118. data/lib/friendly_shipping/services/usps_ship/parse_timings_response.rb +14 -12
  119. data/lib/friendly_shipping/services/usps_ship/rate_estimate_package_options.rb +0 -2
  120. data/lib/friendly_shipping/services/usps_ship/serialize_rate_estimates_request.rb +0 -2
  121. data/lib/friendly_shipping/services/usps_ship.rb +1 -15
  122. data/lib/friendly_shipping/version.rb +1 -1
  123. data/lib/friendly_shipping.rb +20 -21
  124. metadata +7 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: efe62f43bc8306cc3541524c1be0a3746ce29e460c14903ae57e1f9ee16b3b69
4
- data.tar.gz: 4750fdcb3fd536ca2b37ab6c70d0dd289172337cd1b2a430148b8beb2ac47b47
3
+ metadata.gz: b2dc4925fb6a2975dc8e0bdee5699d442d0812639f888277666920ea521afda0
4
+ data.tar.gz: e6a08197f058379eb9c487badf3cfceea0a6b89be15ca6cb9e11c8cafcf0c39d
5
5
  SHA512:
6
- metadata.gz: 348556eb9f2e12e2bdbf66ddb48bbb6ef9c97500ddfea4b9530294be1faf255d95248856a6d83bd5a9b533b878a5e277e1e1d62ca5a575859caec7e38ef77f7e
7
- data.tar.gz: 84e0a0cd96e0535a881225a17dfa0d443a52411495b410c5a02719327dc665a77f0109d562024908810d81ab324cc4ec67ae94e0d2dfbfadd9f8a9d3c0060503
6
+ metadata.gz: 73bfbaa0235441beb5d84564b7297308e531fc33ac04f45eb0dbe1fc3526ca1aa0fdd44a88232b2f695649dcfa05adc3cc199a53dab392f061b60e591b9cb4a5
7
+ data.tar.gz: 5cd65e2f58074223cf4c87c18054362dfb533d31095e5d6cc46fc4b55f344335c6d4ae4e6cc98afcfb0837fda6caedaed3816f5a98817974aeaf477bd04efab6
data/.circleci/config.yml CHANGED
@@ -72,4 +72,4 @@ workflows:
72
72
  parameters:
73
73
  # https://github.com/CircleCI-Public/cimg-ruby
74
74
  # only supports the last three ruby versions
75
- ruby-version: ["3.2", "3.1", "3.0"]
75
+ ruby-version: ["3.3", "3.2", "3.1"]
data/.rubocop.yml CHANGED
@@ -13,6 +13,9 @@ Metrics/BlockLength:
13
13
  Style/AccessorGrouping:
14
14
  Enabled: false
15
15
 
16
+ Style/ArgumentsForwarding:
17
+ Enabled: false
18
+
16
19
  Style/HashEachMethods:
17
20
  Enabled: true
18
21
 
@@ -25,5 +28,8 @@ Style/HashTransformKeys:
25
28
  Style/HashTransformValues:
26
29
  Enabled: true
27
30
 
31
+ Style/SuperArguments:
32
+ Enabled: false
33
+
28
34
  Naming/VariableNumber:
29
35
  Enabled: false
data/README.md CHANGED
@@ -33,7 +33,7 @@ The individual API endpoints can be reached through the public methods of the re
33
33
 
34
34
  ### Return values
35
35
 
36
- All calls to `FriendlyShipping` will return a `Dry::Monads::Result` instance, so either a `Success` or `Failure`. Wrapped inside this monad is a `FriendlyShipping::ApiResult` (in the success case) or a `FriendlyShipping::ApiFailure` object that contains the desired data under `#data` `ApiResult` and `ApiFailure` also contain the original request generated by this gem and the response returned by the respective service.
36
+ All calls to `FriendlyShipping` will return a `Dry::Monads::Result` instance, so either a `Success` or `Failure`. Wrapped inside this monad is a `FriendlyShipping::ApiResult` object that contains the desired data under `#data`. `ApiResult` also contains the original request generated by this gem and the response returned by the respective service.
37
37
 
38
38
  ### Supported Services
39
39
 
@@ -22,13 +22,13 @@ Gem::Specification.new do |spec|
22
22
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
23
  spec.require_paths = ["lib"]
24
24
 
25
- spec.add_runtime_dependency "dry-monads", "~> 1.0"
26
- spec.add_runtime_dependency "jwt", "~> 2.7"
27
- spec.add_runtime_dependency "money", "~> 6.0"
28
- spec.add_runtime_dependency "nokogiri", "~> 1.6"
29
- spec.add_runtime_dependency "physical", "~> 0.5", ">= 0.5.1"
30
- spec.add_runtime_dependency "rest-client", "~> 2.0"
25
+ spec.add_dependency "dry-monads", "~> 1.0"
26
+ spec.add_dependency "jwt", "~> 2.7"
27
+ spec.add_dependency "money", "~> 6.0"
28
+ spec.add_dependency "nokogiri", "~> 1.6"
29
+ spec.add_dependency "physical", "~> 0.5", ">= 0.5.1"
30
+ spec.add_dependency "rest-client", "~> 2.0"
31
31
 
32
- spec.required_ruby_version = '>= 3.0'
32
+ spec.required_ruby_version = '>= 3.1'
33
33
  spec.metadata['rubygems_mfa_required'] = 'true'
34
34
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FriendlyShipping
4
+ # Represents an access token returned by a carrier.
5
+ class AccessToken
6
+ # @return [Integer] the token's expiration
7
+ attr_reader :expires_in
8
+
9
+ # @return [String] the raw token
10
+ attr_reader :raw_token
11
+
12
+ # @param expires_in [Integer] the token's expiration
13
+ def initialize(expires_in:, raw_token:)
14
+ @expires_in = expires_in
15
+ @raw_token = raw_token
16
+ end
17
+
18
+ # Decodes and returns the raw token (only applicable to JWT tokens).
19
+ # @return [Array<Hash>] the decoded token
20
+ def decoded_token
21
+ @_decoded_token = JWT.decode(raw_token, nil, false)
22
+ end
23
+ end
24
+ end
@@ -6,11 +6,13 @@ module FriendlyShipping
6
6
  # @return [RestClient::Exception] the cause of the error
7
7
  attr_reader :cause
8
8
 
9
- # @param cause [RestClient::Exception] the cause of the error
9
+ # @param cause [RestClient::Exception, nil] the cause of the error
10
10
  # @param message [String] optional descriptive message
11
11
  def initialize(cause, message = nil)
12
+ raise ArgumentError, "Must provide either a cause or a message" if cause.nil? && message.nil?
13
+
12
14
  @cause = cause
13
- super(message || cause.message)
15
+ super(message || cause&.message)
14
16
  end
15
17
  end
16
18
  end
@@ -1,11 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'friendly_shipping/api_error'
4
-
5
3
  module FriendlyShipping
6
4
  # Handles API errors by wrapping them in an API error class ({ApiError} by default) which
7
- # is then wrapped in an {ApiFailure} (along with the original API request and response).
8
- # Finally, the {ApiFailure} is then wrapped in a `Dry::Monads::Failure`.
5
+ # is then wrapped in an {ApiResult} (along with the original API request and response).
6
+ # Finally, the {ApiResult} is then wrapped in a `Dry::Monads::Failure`.
9
7
  class ApiErrorHandler
10
8
  include Dry::Monads::Result::Mixin
11
9
 
@@ -20,10 +18,10 @@ module FriendlyShipping
20
18
  # @param error [StandardError] the error to handle
21
19
  # @param original_request [Request] the API request which triggered the error
22
20
  # @param original_response [RestClient::Response] the API response containing the error
23
- # @return [Failure<ApiFailure>]
21
+ # @return [Failure<ApiResult>]
24
22
  def call(error, original_request: nil, original_response: nil)
25
23
  Failure(
26
- ApiFailure.new(
24
+ ApiResult.new(
27
25
  api_error_class.new(error),
28
26
  original_request: original_request,
29
27
  original_response: Response.new_from_rest_client_response(original_response)
@@ -1,15 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FriendlyShipping
4
- # Wraps an API result from a request that failed.
5
- class ApiFailure < ApiResult
6
- # @!attribute [r] data
7
- # The API failure (typically an exception)
8
- alias_method :failure, :data
9
-
10
- # @return [#to_s] a string representation of the failure
11
- def to_s
12
- failure.to_s
13
- end
14
- end
4
+ # @deprecated Use {ApiResult} instead
5
+ ApiFailure = ApiResult
15
6
  end
@@ -7,6 +7,11 @@ module FriendlyShipping
7
7
  # @return [Object] the API result (typically the response body)
8
8
  attr_reader :data
9
9
 
10
+ # @!attribute [r] data
11
+ # The API failure (typically an exception). This is here to maintain
12
+ # backwards compatibility with the deprecated {ApiResult} class.
13
+ alias_method :failure, :data
14
+
10
15
  # @return [Request] the original API request (if debugging is enabled)
11
16
  attr_reader :original_request
12
17
 
@@ -28,5 +33,10 @@ module FriendlyShipping
28
33
  @original_request = original_request
29
34
  @original_response = original_response
30
35
  end
36
+
37
+ # @return [#to_s] a string representation of the data
38
+ def to_s
39
+ data.to_s
40
+ end
31
41
  end
32
42
  end
@@ -1,11 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/monads'
4
- require 'rest-client'
5
-
6
- require 'friendly_shipping/api_failure'
7
- require 'friendly_shipping/api_error_handler'
8
-
9
3
  module FriendlyShipping
10
4
  # A façade for `RestClient` which constructs requests, wraps responses in `Dry::Monad`
11
5
  # results, and calls the API error handler with failures.
@@ -22,7 +16,7 @@ module FriendlyShipping
22
16
 
23
17
  # Makes a GET request and handles the response.
24
18
  # @param request [Request] the request to GET
25
- # @return [Success<Response>, Failure<ApiFailure>]
19
+ # @return [Success<Response>, Failure<ApiResult>]
26
20
  def get(request)
27
21
  http_response = ::RestClient.get(
28
22
  request.url, request.headers
@@ -35,7 +29,7 @@ module FriendlyShipping
35
29
 
36
30
  # Makes a DELETE request and handles the response.
37
31
  # @param request [Request] the request to DELETE
38
- # @return [Success<Response>, Failure<ApiFailure>]
32
+ # @return [Success<Response>, Failure<ApiResult>]
39
33
  def delete(request)
40
34
  http_response = ::RestClient.delete(request.url, request.headers)
41
35
 
@@ -46,7 +40,7 @@ module FriendlyShipping
46
40
 
47
41
  # Makes a POST request and handles the response.
48
42
  # @param request [Request] the request to POST
49
- # @return [Success<Response>, Failure<ApiFailure>]
43
+ # @return [Success<Response>, Failure<ApiResult>]
50
44
  def post(request)
51
45
  http_response = ::RestClient.post(
52
46
  request.url,
@@ -61,7 +55,7 @@ module FriendlyShipping
61
55
 
62
56
  # Makes a PUT request and handles the response.
63
57
  # @param request [Request] the request to PUT
64
- # @return [Success<Response>, Failure<ApiFailure>]
58
+ # @return [Success<Response>, Failure<ApiResult>]
65
59
  def put(request)
66
60
  http_response = ::RestClient.put(
67
61
  request.url,
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'friendly_shipping/types'
4
-
5
3
  module FriendlyShipping
6
4
  # Base class for a shipping label returned by a carrier API.
7
5
  class Label
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'friendly_shipping/api_error'
4
-
5
3
  module FriendlyShipping
6
4
  module Services
7
5
  class RL
@@ -1,9 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'friendly_shipping/services/rl/shipment_options'
4
- require 'friendly_shipping/services/rl/bol_structures_serializer'
5
- require 'friendly_shipping/services/rl/bol_packages_serializer'
6
-
7
3
  module FriendlyShipping
8
4
  module Services
9
5
  class RL
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'friendly_shipping/item_options'
4
-
5
3
  module FriendlyShipping
6
4
  module Services
7
5
  class RL
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'friendly_shipping/package_options'
4
-
5
3
  module FriendlyShipping
6
4
  module Services
7
5
  class RL
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json'
4
- require 'friendly_shipping/services/rl/shipment_information'
5
-
6
3
  module FriendlyShipping
7
4
  module Services
8
5
  class RL
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json'
4
- require 'friendly_shipping/services/rl/shipment_document'
5
-
6
3
  module FriendlyShipping
7
4
  module Services
8
5
  class RL
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json'
4
- require 'friendly_shipping/services/rl/shipment_document'
5
-
6
3
  module FriendlyShipping
7
4
  module Services
8
5
  class RL
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json'
4
- require 'friendly_shipping/services/rl/shipment_document'
5
-
6
3
  module FriendlyShipping
7
4
  module Services
8
5
  class RL
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json'
4
- require 'friendly_shipping/services/rl/shipping_methods'
5
-
6
3
  module FriendlyShipping
7
4
  module Services
8
5
  class RL
@@ -53,12 +50,42 @@ module FriendlyShipping
53
50
  service_levels.map do |service_level|
54
51
  shipping_method = SHIPPING_METHODS.detect { |sm| sm.service_code == service_level['Code'] }
55
52
  total = Money.new(service_level['NetCharge'].delete('$,.'), CURRENCY)
53
+
54
+ charges = parsed_json.dig('RateQuote', 'Charges')
55
+ cost_breakdown = build_cost_breakdown(charges, service_level)
56
+
56
57
  FriendlyShipping::Rate.new(
57
58
  shipping_method: shipping_method,
58
- amounts: { total: total }
59
+ amounts: { total: total },
60
+ data: {
61
+ cost_breakdown: cost_breakdown
62
+ }
59
63
  )
60
64
  end
61
65
  end
66
+
67
+ # @param [Array<Hash>] charges
68
+ # @param [Hash] service_level
69
+ # @return [Array<Hash>]
70
+ def build_cost_breakdown(charges, service_level)
71
+ result = charges.map do |charge|
72
+ {
73
+ "Type" => charge['Type'].presence,
74
+ "Description" => charge['Title'],
75
+ "Weight" => charge['Weight'].presence,
76
+ "Rate" => charge['Rate'].presence,
77
+ "Amount" => charge['Amount'].presence
78
+ }.compact
79
+ end
80
+ if service_level['Code'] != 'STD'
81
+ result << {
82
+ "Type" => service_level['Code'],
83
+ "Description" => service_level['Name'],
84
+ "Amount" => service_level['Charge']
85
+ }
86
+ end
87
+ result
88
+ end
62
89
  end
63
90
  end
64
91
  end
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json'
4
- require 'friendly_shipping/services/rl/shipping_methods'
5
-
6
3
  module FriendlyShipping
7
4
  module Services
8
5
  class RL
@@ -1,9 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'friendly_shipping/services/rl/shipment_options'
4
- require 'friendly_shipping/services/rl/rate_quote_structures_serializer'
5
- require 'friendly_shipping/services/rl/rate_quote_packages_serializer'
6
-
7
3
  module FriendlyShipping
8
4
  module Services
9
5
  class RL
@@ -11,8 +11,8 @@ module FriendlyShipping
11
11
  def call(location)
12
12
  {
13
13
  CompanyName: location.company_name.presence || location.name,
14
- AddressLine1: location.address1,
15
- AddressLine2: location.address2,
14
+ AddressLine1: truncate(location.address1),
15
+ AddressLine2: truncate(location.address2),
16
16
  City: clean_city(location.city),
17
17
  StateOrProvince: location.region.code,
18
18
  ZipOrPostalCode: location.zip,
@@ -39,6 +39,13 @@ module FriendlyShipping
39
39
  def clean_phone(phone)
40
40
  phone.gsub(/^1-/, "").strip
41
41
  end
42
+
43
+ # @param value [String]
44
+ # @param length [Integer]
45
+ # @return [String]
46
+ def truncate(value, length: 30)
47
+ value && value[0..(length - 1)].strip
48
+ end
42
49
  end
43
50
  end
44
51
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'friendly_shipping/shipment_options'
4
-
5
3
  module FriendlyShipping
6
4
  module Services
7
5
  class RL
@@ -1,23 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/monads'
4
- require 'friendly_shipping/http_client'
5
- require 'friendly_shipping/services/rl/api_error'
6
- require 'friendly_shipping/services/rl/parse_create_bol_response'
7
- require 'friendly_shipping/services/rl/parse_invoice_response'
8
- require 'friendly_shipping/services/rl/parse_print_bol_response'
9
- require 'friendly_shipping/services/rl/parse_print_shipping_labels_response'
10
- require 'friendly_shipping/services/rl/parse_rate_quote_response'
11
- require 'friendly_shipping/services/rl/parse_transit_times_response'
12
- require 'friendly_shipping/services/rl/serialize_create_bol_request'
13
- require 'friendly_shipping/services/rl/serialize_location'
14
- require 'friendly_shipping/services/rl/serialize_rate_quote_request'
15
- require 'friendly_shipping/services/rl/serialize_transit_times_request'
16
- require 'friendly_shipping/services/rl/rate_quote_options'
17
- require 'friendly_shipping/services/rl/bol_options'
18
- require 'friendly_shipping/services/rl/structure_options'
19
- require 'friendly_shipping/services/rl/package_options'
20
- require 'friendly_shipping/services/rl/item_options'
3
+ require "json"
21
4
 
22
5
  module FriendlyShipping
23
6
  module Services
@@ -66,7 +49,7 @@ module FriendlyShipping
66
49
  #
67
50
  # @param shipment [Physical::Shipment] the shipment for the BOL
68
51
  # @param options [BOLOptions] the options for the BOL
69
- # @return [Success<ApiResult<ShipmentInformation>>, Failure<ApiFailure>] the BOL from R+L Carriers
52
+ # @return [Success<ApiResult<ShipmentInformation>>, Failure<ApiResult>] the BOL from R+L Carriers
70
53
  def create_bill_of_lading(shipment, options:, debug: false)
71
54
  request = FriendlyShipping::Request.new(
72
55
  url: api_base + API_PATHS[:bill_of_lading],
@@ -84,7 +67,7 @@ module FriendlyShipping
84
67
  # to the {ShipmentInformation} object's documents array.
85
68
  #
86
69
  # @param shipment_info [ShipmentInformation] the shipment for the BOL
87
- # @return [Success<ApiResult<ShipmentDocument>>, Failure<ApiFailure>] the binary BOL document from R+L Carriers
70
+ # @return [Success<ApiResult<ShipmentDocument>>, Failure<ApiResult>] the binary BOL document from R+L Carriers
88
71
  def print_bill_of_lading(shipment_info, debug: false)
89
72
  request = FriendlyShipping::Request.new(
90
73
  url: api_base + API_PATHS[:print_bol] + "?ProNumber=#{shipment_info.pro_number}",
@@ -108,7 +91,7 @@ module FriendlyShipping
108
91
  # @see https://rl-cdn.com/docs/rlc/shipping-forms/shipping-label-select.pdf Shipping label styles
109
92
  # @param start_position [Integer] the R+L Carriers start position for the first label (between 1 and 10)
110
93
  # @param num_labels [Integer] number of labels to print (between 1 and 100)
111
- # @return [Success<ApiResult<ShipmentDocument>>, Failure<ApiFailure>] the binary shipping labels from R+L Carriers
94
+ # @return [Success<ApiResult<ShipmentDocument>>, Failure<ApiResult>] the binary shipping labels from R+L Carriers
112
95
  def print_shipping_labels(shipment_info, style: 1, start_position: 1, num_labels: 4, debug: false)
113
96
  request = FriendlyShipping::Request.new(
114
97
  url: api_base + API_PATHS[:print_shipping_labels] +
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'friendly_shipping/api_error'
4
-
5
3
  module FriendlyShipping
6
4
  module Services
7
5
  class ShipEngine
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'friendly_shipping/item_options'
4
-
5
3
  module FriendlyShipping
6
4
  module Services
7
5
  class ShipEngine
@@ -1,9 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'friendly_shipping/shipment_options'
4
- require 'friendly_shipping/services/ship_engine/label_customs_options'
5
- require 'friendly_shipping/services/ship_engine/customs_items_serializer'
6
-
7
3
  module FriendlyShipping
8
4
  module Services
9
5
  class ShipEngine
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'friendly_shipping/package_options'
4
- require 'friendly_shipping/services/ship_engine/label_item_options'
5
-
6
3
  module FriendlyShipping
7
4
  module Services
8
5
  class ShipEngine
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json'
4
-
5
3
  module FriendlyShipping
6
4
  module Services
7
5
  class ShipEngine
@@ -11,13 +9,13 @@ module FriendlyShipping
11
9
  class << self
12
10
  # @param [FriendlyShipping::Request] request
13
11
  # @param [FriendlyShipping::Response] response
14
- # @return [Success<ApiResult<Array<Physical::Location>>>, Failure<ApiFailure>]
12
+ # @return [Success<ApiResult<Array<Physical::Location>>>, Failure<ApiResult>]
15
13
  def call(request:, response:)
16
14
  parsed_json = JSON.parse(response.body)
17
15
  if parsed_json.first['status'] == "error"
18
16
  errors = parsed_json.first['messages'].map { |message| message['message'] }.join(", ")
19
17
  Failure(
20
- ApiFailure.new(
18
+ ApiResult.new(
21
19
  errors,
22
20
  original_request: request,
23
21
  original_response: response
@@ -51,7 +49,7 @@ module FriendlyShipping
51
49
  end
52
50
  rescue JSON::ParserError => e
53
51
  Failure(
54
- FriendlyShipping::ApiFailure.new(
52
+ FriendlyShipping::ApiResult.new(
55
53
  e,
56
54
  original_request: request,
57
55
  original_response: response
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json'
4
-
5
3
  module FriendlyShipping
6
4
  module Services
7
5
  class ShipEngine
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json'
4
-
5
3
  module FriendlyShipping
6
4
  module Services
7
5
  class ShipEngine
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json'
4
-
5
3
  module FriendlyShipping
6
4
  module Services
7
5
  class ShipEngine
@@ -13,7 +11,7 @@ module FriendlyShipping
13
11
  # @param request [Request] the request to attach to the API result
14
12
  # @param response [Response] the response to parse
15
13
  # @param options [RateEstimatesOptions] the options to use when parsing
16
- # @return [Success<ApiResult<Array<Rate>>>, Failure<ApiFailure<Array<String>>>] the parsed rate estimates or errors
14
+ # @return [Success<ApiResult<Array<Rate>>>, Failure<ApiResult<Array<String>>>] the parsed rate estimates or errors
17
15
  def call(response:, request:, options:)
18
16
  error_messages = []
19
17
  parsed_json = JSON.parse(response.body)
@@ -63,7 +61,7 @@ module FriendlyShipping
63
61
  )
64
62
  else
65
63
  Failure(
66
- ApiFailure.new(
64
+ ApiResult.new(
67
65
  error_messages,
68
66
  original_request: request,
69
67
  original_response: response
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json'
4
-
5
3
  module FriendlyShipping
6
4
  module Services
7
5
  class ShipEngine
@@ -13,7 +11,7 @@ module FriendlyShipping
13
11
  # @param request [Request] the request to attach to the API result
14
12
  # @param response [Response] the response to parse
15
13
  # @param options [RatesOptions] the options to use when parsing
16
- # @return [Success<ApiResult<Array<Rate>>>, Failure<ApiFailure<String>>] the parsed rates or error
14
+ # @return [Success<ApiResult<Array<Rate>>>, Failure<ApiResult<String>>] the parsed rates or error
17
15
  def call(request:, response:, options:)
18
16
  parsed_json = JSON.parse(response.body)
19
17
  rates = build_rates(parsed_json, options)
@@ -28,7 +26,7 @@ module FriendlyShipping
28
26
  else
29
27
  error = parsed_json.dig("rate_response", "errors", 0, "message") || "Unknown error"
30
28
  Failure(
31
- ApiFailure.new(
29
+ ApiResult.new(
32
30
  error,
33
31
  original_request: request,
34
32
  original_response: response
@@ -9,7 +9,7 @@ module FriendlyShipping
9
9
 
10
10
  # @param request [Request] the request to attach to the API result
11
11
  # @param response [Response] the response to parse
12
- # @return [Success<ApiResult<String>>, Failure<ApiFailure<String>>] the success or failure message
12
+ # @return [Success<ApiResult<String>>, Failure<ApiResult<String>>] the success or failure message
13
13
  def self.call(request:, response:)
14
14
  parsed_json = JSON.parse(response.body)
15
15
  approved, message = parsed_json["approved"], parsed_json["message"]
@@ -19,7 +19,7 @@ module FriendlyShipping
19
19
  )
20
20
  else
21
21
  Failure(
22
- ApiFailure.new(message, original_request: request, original_response: response)
22
+ ApiResult.new(message, original_request: request, original_response: response)
23
23
  )
24
24
  end
25
25
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'friendly_shipping/shipment_options'
4
-
5
3
  module FriendlyShipping
6
4
  module Services
7
5
  class ShipEngine