friendly_shipping 0.10.2 → 0.10.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d1947b72c921f913cd7e75eaf62c82e9453caa017eedd05f3bef555d202d28a9
4
- data.tar.gz: 757e4ae6beaf55c89ad726ecf1c7b0609603b033908c7975ba47c436d059f306
3
+ metadata.gz: 1ea046468f58d0fcb1b73a5a412d1196ba22b5196772bdc09167f085bdad718e
4
+ data.tar.gz: cdb2ae78f0a244358795e3a695cbb837c5199b16e1b1ea62d35fc3c2db7593ed
5
5
  SHA512:
6
- metadata.gz: b0091e092439cb74e7d1f34d6342dedbcf15e8d6e451bea5782eda11129df3c94dcb224bb6a319ba859545f090899f0c51f8beb16dbd0de0a91078d57be5521d
7
- data.tar.gz: 40d1c62b73125f662061e22c7100d9fa9aa0ec061b18b13066bc3f171e4b60c499ab57aecb77e1a79dc693849ba50fc3391e843bc7626dee6b5563f35039450c
6
+ metadata.gz: ab58d07654f00ad218e80582bf9ebdc242074e9e10d062d6d89dea04125b71785c05e496800da635805be221b61b544dad233258e78cfe2b633590788b401930
7
+ data.tar.gz: ccfae1ca937d3f1c93223a40d8a0193943720be569403565795a70cf7457cd010950d4dfef271bfa5e52145c05cffd004f307566485874baa30c864189fc7e4e
@@ -1,6 +1,6 @@
1
1
  # .env.test.local.template
2
2
 
3
- # When recording VCR cassettes for TForce and UPS JSON service classes, this env var
4
- # should be set to a valid token for either service.
3
+ # When recording VCR cassettes for TForce, UPS, and USPS Ship service classes, this env var
4
+ # should be set to a valid token for the service being tested.
5
5
 
6
6
  ACCESS_TOKEN=secret_token
data/CHANGELOG.md CHANGED
@@ -4,6 +4,37 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [0.10.3] - 2025
8
+ - Add USPS Ship city/state lookup request (#279)
9
+
10
+ ## [0.10.2] - 2025
11
+ - Remove legacy UPS integration (#275)
12
+ - Add observer gem to Gemfile (#276)
13
+ - Remove legacy USPS integration (#277)
14
+ - Add UPS surcharge code 495 to money hash parser (#278)
15
+
16
+ ## [0.10.1] - 2025-01-03
17
+ - Remove Inflections file (#274)
18
+
19
+ ## [0.10.0] - 2025-01-03
20
+ - Bump version to 0.9.0 and log changes (#257)
21
+ - USPS Ship: Fix machinable criteria (#258)
22
+ - Add debug param to ShipEngine labels method (#259)
23
+ - Truncate R+L BOL address lines to 30 chars (#260)
24
+ - Fix UPS json rate details, add specs (#261)
25
+ - Fix ups label cost breakdown (#262)
26
+ - Remove TForce company name sanitization (#263)
27
+ - Update payload location of NegotiatedRatesIndicator within UPS JSON (#264)
28
+ - Attach cost breakdown to R+L rates data (#265)
29
+ - Expand TForce cost breakdown detail (#266)
30
+ - Never send empty UPS ShipmentRatingOptions (#267)
31
+ - Bump required Ruby version to 3.1 or greater (#269)
32
+ - Add city/state lookup endpoint for UPS JSON API (#268)
33
+ - Extract AccessToken parent class (#270)
34
+ - Return errors in ApiFailures for USPS timings, UPS json parsing (#271)
35
+ - Deprecate ApiFailure class (#272)
36
+ - Use Zeitwerk to load FriendlyShipping (#273)
37
+
7
38
  ## [0.9.0] - 2024-05-02
8
39
  - Implement R&L service with rates and timings (#177)
9
40
  - Add R&L Freight API call to create BOL and schedule pickup (#178)
@@ -29,13 +29,13 @@ module FriendlyShipping
29
29
 
30
30
  # @return [Boolean]
31
31
  def machinable?
32
- at_least_minimum && at_most_maximum
32
+ at_least_minimum? && at_most_maximum?
33
33
  end
34
34
 
35
35
  private
36
36
 
37
37
  # @return [Boolean]
38
- def at_least_minimum
38
+ def at_least_minimum?
39
39
  package.length >= MIN_LENGTH &&
40
40
  package.width >= MIN_WIDTH &&
41
41
  package.height >= MIN_HEIGHT &&
@@ -43,7 +43,7 @@ module FriendlyShipping
43
43
  end
44
44
 
45
45
  # @return [Boolean]
46
- def at_most_maximum
46
+ def at_most_maximum?
47
47
  package.length <= MAX_LENGTH &&
48
48
  package.width <= MAX_WIDTH &&
49
49
  package.height <= MAX_HEIGHT &&
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FriendlyShipping
4
+ module Services
5
+ class USPSShip
6
+ class ParseCityStateResponse
7
+ extend Dry::Monads::Result::Mixin
8
+ USA = Carmen::Country.coded("USA")
9
+
10
+ class << self
11
+ # Parse a city/state response.
12
+ #
13
+ # @param request [Request] the request that was used to obtain this response
14
+ # @param response [Response] the response that USPS returned
15
+ # @return [Success<ApiResult<Physical::Location>>, Failure<ApiResult<String>>]
16
+ def call(request:, response:)
17
+ city_state = JSON.parse(response.body)
18
+
19
+ if city_state['error']
20
+ failure(
21
+ api_error("Error: #{city_state.dig('error', 'message')}"),
22
+ request,
23
+ response
24
+ )
25
+ else
26
+ success(
27
+ Physical::Location.new(
28
+ city: city_state['city'],
29
+ region: city_state['state'],
30
+ zip: city_state['ZIPCode'],
31
+ country: USA
32
+ ),
33
+ request,
34
+ response
35
+ )
36
+ end
37
+ rescue JSON::ParserError => e
38
+ failure(e, request, response)
39
+ end
40
+
41
+ # @param location [Physical::Location]
42
+ # @param request [Request]
43
+ # @param response [Response]
44
+ # @return [Success<ApiResult<Physical::Location>>]
45
+ def success(location, request, response)
46
+ Success(
47
+ ApiResult.new(
48
+ location,
49
+ original_request: request,
50
+ original_response: response
51
+ )
52
+ )
53
+ end
54
+
55
+ # @param error [JSON::ParserError, FriendlyShipping::ApiError]
56
+ # @param request [Request]
57
+ # @param response [Response]
58
+ # @return [Failure<ApiResult>]
59
+ def failure(error, request, response)
60
+ Failure(
61
+ ApiResult.new(
62
+ error,
63
+ original_request: request,
64
+ original_response: response
65
+ )
66
+ )
67
+ end
68
+
69
+ private
70
+
71
+ def api_error(message)
72
+ FriendlyShipping::ApiError.new(nil, message)
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -32,7 +32,8 @@ module FriendlyShipping
32
32
  RESOURCES = {
33
33
  token: 'oauth2/v3/token',
34
34
  rates: 'prices/v3/base-rates/search',
35
- timings: 'service-standards/v3/estimates'
35
+ timings: 'service-standards/v3/estimates',
36
+ city_state: 'addresses/v3/city-state'
36
37
  }.freeze
37
38
 
38
39
  # @param access_token [AccessToken] the access token
@@ -161,6 +162,31 @@ module FriendlyShipping
161
162
  end
162
163
  end
163
164
 
165
+ # Get city and state for given ZIP code.
166
+ # @see https://developer.usps.com/addressesv3#tag/Resources/operation/get-city-state API documentation
167
+ #
168
+ # @param location [Physical::Location] the location with ZIP code we want to complete
169
+ # @return [Result<ApiResult<Array<Timing>>>] the {Timing}s wrapped in an {ApiResult} object
170
+ # @return [Result<ApiResult<Physical::Location>>] The response data from USPS encoded in a
171
+ # `Physical::Location` object. Country, City and ZIP code will be set, everything else nil.
172
+ def city_state(location, debug: false)
173
+ request = FriendlyShipping::Request.new(
174
+ url: "#{BASE_URL}/#{RESOURCES[:city_state]}?ZIPCode=#{location.zip}",
175
+ http_method: "GET",
176
+ debug: debug,
177
+ headers: {
178
+ Accept: "application/json",
179
+ Authorization: "Bearer #{access_token.raw_token}"
180
+ }
181
+ )
182
+
183
+ client.get(request).bind do |response|
184
+ ParseCityStateResponse.call(response: response, request: request)
185
+ end
186
+ end
187
+
188
+ alias_method :city_state_lookup, :city_state
189
+
164
190
  private
165
191
 
166
192
  # @param api [Symbol]
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FriendlyShipping
4
- VERSION = "0.10.2"
4
+ VERSION = "0.10.3"
5
5
  end
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: friendly_shipping
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.2
4
+ version: 0.10.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Meyerhoff
8
8
  - Matthew Bass
9
- autorequire:
10
9
  bindir: exe
11
10
  cert_chain: []
12
- date: 2025-05-27 00:00:00.000000000 Z
11
+ date: 1980-01-02 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: dry-monads
@@ -304,6 +303,7 @@ files:
304
303
  - lib/friendly_shipping/services/usps_ship/access_token.rb
305
304
  - lib/friendly_shipping/services/usps_ship/api_error.rb
306
305
  - lib/friendly_shipping/services/usps_ship/machinable_package.rb
306
+ - lib/friendly_shipping/services/usps_ship/parse_city_state_response.rb
307
307
  - lib/friendly_shipping/services/usps_ship/parse_rate_estimates_response.rb
308
308
  - lib/friendly_shipping/services/usps_ship/parse_timings_response.rb
309
309
  - lib/friendly_shipping/services/usps_ship/rate_estimate_options.rb
@@ -322,7 +322,6 @@ licenses:
322
322
  - MIT
323
323
  metadata:
324
324
  rubygems_mfa_required: 'true'
325
- post_install_message:
326
325
  rdoc_options: []
327
326
  require_paths:
328
327
  - lib
@@ -337,8 +336,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
337
336
  - !ruby/object:Gem::Version
338
337
  version: '0'
339
338
  requirements: []
340
- rubygems_version: 3.5.22
341
- signing_key:
339
+ rubygems_version: 3.6.9
342
340
  specification_version: 4
343
341
  summary: An integration layer for shipping services
344
342
  test_files: []