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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop-relaxed.yml +3 -4
  4. data/.rubocop.yml +9 -0
  5. data/CHANGELOG.md +32 -1
  6. data/friendly_shipping.gemspec +12 -12
  7. data/lib/friendly_shipping/api_failure.rb +2 -15
  8. data/lib/friendly_shipping/http_client.rb +16 -9
  9. data/lib/friendly_shipping/services/ship_engine/bad_request_handler.rb +15 -3
  10. data/lib/friendly_shipping/services/ups/parse_address_classification_response.rb +5 -2
  11. data/lib/friendly_shipping/services/ups/parse_address_validation_response.rb +5 -2
  12. data/lib/friendly_shipping/services/ups/parse_city_state_lookup_response.rb +5 -2
  13. data/lib/friendly_shipping/services/ups/parse_money_element.rb +2 -2
  14. data/lib/friendly_shipping/services/ups/parse_rate_response.rb +5 -1
  15. data/lib/friendly_shipping/services/ups/parse_shipment_accept_response.rb +5 -1
  16. data/lib/friendly_shipping/services/ups/parse_shipment_confirm_response.rb +5 -1
  17. data/lib/friendly_shipping/services/ups/parse_time_in_transit_response.rb +6 -2
  18. data/lib/friendly_shipping/services/ups/parse_void_shipment_response.rb +5 -1
  19. data/lib/friendly_shipping/services/ups/parse_xml_response.rb +16 -7
  20. data/lib/friendly_shipping/services/ups_freight.rb +44 -13
  21. data/lib/friendly_shipping/services/ups_freight/generate_delivery_options_hash.rb +21 -0
  22. data/lib/friendly_shipping/services/ups_freight/generate_document_options_hash.rb +28 -0
  23. data/lib/friendly_shipping/services/ups_freight/generate_email_options_hash.rb +25 -0
  24. data/lib/friendly_shipping/services/ups_freight/generate_freight_rate_request_hash.rb +2 -10
  25. data/lib/friendly_shipping/services/ups_freight/generate_freight_ship_request_hash.rb +81 -0
  26. data/lib/friendly_shipping/services/ups_freight/generate_location_hash.rb +5 -2
  27. data/lib/friendly_shipping/services/ups_freight/generate_pickup_options_hash.rb +21 -0
  28. data/lib/friendly_shipping/services/ups_freight/generate_pickup_request_hash.rb +31 -0
  29. data/lib/friendly_shipping/services/ups_freight/label_delivery_options.rb +29 -0
  30. data/lib/friendly_shipping/services/ups_freight/label_document_options.rb +56 -0
  31. data/lib/friendly_shipping/services/ups_freight/label_email_options.rb +40 -0
  32. data/lib/friendly_shipping/services/ups_freight/label_item_options.rb +10 -0
  33. data/lib/friendly_shipping/services/ups_freight/label_options.rb +37 -0
  34. data/lib/friendly_shipping/services/ups_freight/label_package_options.rb +10 -0
  35. data/lib/friendly_shipping/services/ups_freight/label_pickup_options.rb +29 -0
  36. data/lib/friendly_shipping/services/ups_freight/parse_freight_label_response.rb +57 -0
  37. data/lib/friendly_shipping/services/ups_freight/parse_freight_rate_response.rb +29 -32
  38. data/lib/friendly_shipping/services/ups_freight/parse_shipment_document.rb +24 -0
  39. data/lib/friendly_shipping/services/ups_freight/pickup_request_options.rb +29 -0
  40. data/lib/friendly_shipping/services/ups_freight/rates_options.rb +3 -6
  41. data/lib/friendly_shipping/services/ups_freight/restful_api_error_handler.rb +30 -0
  42. data/lib/friendly_shipping/services/ups_freight/shipment_document.rb +21 -0
  43. data/lib/friendly_shipping/services/ups_freight/shipment_information.rb +35 -0
  44. data/lib/friendly_shipping/services/usps/parse_address_validation_response.rb +5 -1
  45. data/lib/friendly_shipping/services/usps/parse_city_state_lookup_response.rb +5 -1
  46. data/lib/friendly_shipping/services/usps/parse_package_rate.rb +25 -15
  47. data/lib/friendly_shipping/services/usps/parse_rate_response.rb +5 -2
  48. data/lib/friendly_shipping/services/usps/parse_time_in_transit_response.rb +6 -2
  49. data/lib/friendly_shipping/services/usps/parse_xml_response.rb +15 -5
  50. data/lib/friendly_shipping/services/usps/rate_estimate_package_options.rb +7 -5
  51. data/lib/friendly_shipping/services/usps/shipping_methods.rb +23 -12
  52. data/lib/friendly_shipping/shipping_method.rb +5 -2
  53. data/lib/friendly_shipping/version.rb +1 -1
  54. metadata +75 -40
  55. data/lib/friendly_shipping/services/ups_freight/generate_ups_security_hash.rb +0 -23
  56. data/lib/friendly_shipping/services/ups_freight/parse_json_response.rb +0 -38
@@ -8,18 +8,18 @@ module FriendlyShipping
8
8
  ERROR_TAG = 'Error'
9
9
 
10
10
  class << self
11
- def call(response_body, expected_root_tag)
12
- xml = Nokogiri.XML(response_body, &:strict)
11
+ def call(request:, response:, expected_root_tag:)
12
+ xml = Nokogiri.XML(response.body, &:strict)
13
13
 
14
14
  if xml.root.nil? || ![expected_root_tag, 'Error'].include?(xml.root.name)
15
- Failure('Invalid document')
15
+ wrap_failure('Invalid document', request, response)
16
16
  elsif request_successful?(xml)
17
17
  Success(xml)
18
18
  else
19
- Failure(error_message(xml))
19
+ wrap_failure(error_message(xml), request, response)
20
20
  end
21
21
  rescue Nokogiri::XML::SyntaxError => e
22
- Failure(e)
22
+ wrap_failure(e, request, response)
23
23
  end
24
24
 
25
25
  private
@@ -33,6 +33,16 @@ module FriendlyShipping
33
33
  desc = xml.xpath('//Error/Description')&.text
34
34
  [number, desc].select(&:present?).join(': ').presence&.strip || 'USPS could not process the request.'
35
35
  end
36
+
37
+ def wrap_failure(failure, request, response)
38
+ Failure(
39
+ FriendlyShipping::ApiFailure.new(
40
+ failure,
41
+ original_request: request,
42
+ original_response: response
43
+ )
44
+ )
45
+ end
36
46
  end
37
47
  end
38
48
  end
@@ -49,11 +49,13 @@ module FriendlyShipping
49
49
  def service_code
50
50
  return 'ALL' unless shipping_method
51
51
 
52
- if commercial_pricing
53
- "#{shipping_method.service_code} COMMERCIAL"
54
- else
55
- shipping_method.service_code
56
- end
52
+ # Cubic shipping methods don't have HFP or COMMERCIAL modifiers
53
+ return shipping_method.service_code if shipping_method.service_code =~ /CUBIC/
54
+
55
+ service_code = [shipping_method.service_code]
56
+ service_code << 'HFP' if hold_for_pickup
57
+ service_code << 'COMMERCIAL' if commercial_pricing
58
+ service_code.join(' ')
57
59
  end
58
60
  end
59
61
  end
@@ -29,22 +29,33 @@ module FriendlyShipping
29
29
  package_service_retail: 'PACKAGE SERVICE RETAIL'
30
30
  }.freeze
31
31
 
32
+ CLASS_IDS = {
33
+ priority_mail_express: {
34
+ standard: '3',
35
+ hold_for_pickup: '2',
36
+ sunday_holiday_delivery: '23'
37
+ },
38
+ priority_mail_cubic: '999'
39
+ }.freeze
40
+
32
41
  SHIPPING_METHODS = [
33
- 'First-Class',
34
- 'Package Services',
35
- 'Priority',
36
- 'Priority Mail Express',
37
- 'Standard Post',
38
- 'Retail Ground',
39
- 'Media Mail',
40
- 'Library Mail',
41
- ].map do |shipping_method_name|
42
+ ['FIRST CLASS', 'First-Class'],
43
+ ['PACKAGE SERVICES', 'Package Services'],
44
+ ['PRIORITY', 'Priority Mail'],
45
+ ['PRIORITY MAIL EXPRESS', 'Priority Mail Express', CLASS_IDS[:priority_mail_express].values],
46
+ ['PRIORITY MAIL CUBIC', 'Priority Mail Cubic', CLASS_IDS[:priority_mail_cubic]],
47
+ ['STANDARD POST', 'Standard Post'],
48
+ ['RETAIL GROUND', 'Retail Ground'],
49
+ ['MEDIA MAIL', 'Media Mail'],
50
+ ['LIBRARY MAIL', 'Library Mail'],
51
+ ].map do |code, name, class_ids|
42
52
  FriendlyShipping::ShippingMethod.new(
43
53
  origin_countries: [Carmen::Country.coded('US')],
44
- name: shipping_method_name,
45
- service_code: shipping_method_name.tr('-', ' ').upcase,
54
+ name: name,
55
+ service_code: code,
46
56
  domestic: true,
47
- international: false
57
+ international: false,
58
+ data: { class_ids: class_ids }
48
59
  )
49
60
  end.freeze
50
61
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module FriendlyShipping
4
4
  class ShippingMethod
5
- attr_reader :name, :service_code, :carrier, :origin_countries
5
+ attr_reader :name, :service_code, :carrier, :origin_countries, :data
6
6
 
7
7
  # @param [String] name The shipping method's name
8
8
  # @param [String] service_code The shipping method's service code
@@ -11,6 +11,7 @@ module FriendlyShipping
11
11
  # @param [Boolean] multi_package Whether this is a multi-package shipping method
12
12
  # @param [FriendlyShipping::Carrier] carrier This shipping method's carrier
13
13
  # @param [Array] origin_countries Countries this shipping method ships from
14
+ # @param [Hash] data Additional carrier-specific data for this shipping method
14
15
  def initialize(
15
16
  name: nil,
16
17
  service_code: nil,
@@ -18,7 +19,8 @@ module FriendlyShipping
18
19
  international: nil,
19
20
  multi_package: nil,
20
21
  carrier: nil,
21
- origin_countries: []
22
+ origin_countries: [],
23
+ data: {}
22
24
  )
23
25
  @name = name
24
26
  @service_code = service_code
@@ -27,6 +29,7 @@ module FriendlyShipping
27
29
  @multi_package = multi_package
28
30
  @carrier = carrier
29
31
  @origin_countries = origin_countries
32
+ @data = data
30
33
  end
31
34
 
32
35
  def domestic?
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FriendlyShipping
4
- VERSION = "0.5.2"
4
+ VERSION = "0.6.3"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: friendly_shipping
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Meyerhoff
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-01-31 00:00:00.000000000 Z
11
+ date: 2020-10-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: data_uri
@@ -42,34 +42,37 @@ dependencies:
42
42
  name: money
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 6.0.0
47
+ version: '6.0'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 6.0.0
54
+ version: '6.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: nokogiri
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
61
  version: '1.6'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '1.6'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: physical
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.4'
73
76
  - - ">="
74
77
  - !ruby/object:Gem::Version
75
78
  version: 0.4.4
@@ -77,6 +80,9 @@ dependencies:
77
80
  prerelease: false
78
81
  version_requirements: !ruby/object:Gem::Requirement
79
82
  requirements:
83
+ - - "~>"
84
+ - !ruby/object:Gem::Version
85
+ version: '0.4'
80
86
  - - ">="
81
87
  - !ruby/object:Gem::Version
82
88
  version: 0.4.4
@@ -100,28 +106,34 @@ dependencies:
100
106
  requirements:
101
107
  - - ">="
102
108
  - !ruby/object:Gem::Version
103
- version: '0'
109
+ version: '1.17'
110
+ - - "<"
111
+ - !ruby/object:Gem::Version
112
+ version: '3'
104
113
  type: :development
105
114
  prerelease: false
106
115
  version_requirements: !ruby/object:Gem::Requirement
107
116
  requirements:
108
117
  - - ">="
109
118
  - !ruby/object:Gem::Version
110
- version: '0'
119
+ version: '1.17'
120
+ - - "<"
121
+ - !ruby/object:Gem::Version
122
+ version: '3'
111
123
  - !ruby/object:Gem::Dependency
112
124
  name: dotenv
113
125
  requirement: !ruby/object:Gem::Requirement
114
126
  requirements:
115
- - - ">="
127
+ - - "~>"
116
128
  - !ruby/object:Gem::Version
117
- version: '0'
129
+ version: '2.7'
118
130
  type: :development
119
131
  prerelease: false
120
132
  version_requirements: !ruby/object:Gem::Requirement
121
133
  requirements:
122
- - - ">="
134
+ - - "~>"
123
135
  - !ruby/object:Gem::Version
124
- version: '0'
136
+ version: '2.7'
125
137
  - !ruby/object:Gem::Dependency
126
138
  name: factory_bot
127
139
  requirement: !ruby/object:Gem::Requirement
@@ -140,30 +152,30 @@ dependencies:
140
152
  name: pry
141
153
  requirement: !ruby/object:Gem::Requirement
142
154
  requirements:
143
- - - ">="
155
+ - - "~>"
144
156
  - !ruby/object:Gem::Version
145
- version: '0'
157
+ version: '0.12'
146
158
  type: :development
147
159
  prerelease: false
148
160
  version_requirements: !ruby/object:Gem::Requirement
149
161
  requirements:
150
- - - ">="
162
+ - - "~>"
151
163
  - !ruby/object:Gem::Version
152
- version: '0'
164
+ version: '0.12'
153
165
  - !ruby/object:Gem::Dependency
154
166
  name: rake
155
167
  requirement: !ruby/object:Gem::Requirement
156
168
  requirements:
157
- - - "~>"
169
+ - - ">="
158
170
  - !ruby/object:Gem::Version
159
- version: '10.0'
171
+ version: 12.3.3
160
172
  type: :development
161
173
  prerelease: false
162
174
  version_requirements: !ruby/object:Gem::Requirement
163
175
  requirements:
164
- - - "~>"
176
+ - - ">="
165
177
  - !ruby/object:Gem::Version
166
- version: '10.0'
178
+ version: 12.3.3
167
179
  - !ruby/object:Gem::Dependency
168
180
  name: rspec
169
181
  requirement: !ruby/object:Gem::Requirement
@@ -198,56 +210,62 @@ dependencies:
198
210
  requirements:
199
211
  - - ">="
200
212
  - !ruby/object:Gem::Version
201
- version: '0'
213
+ version: '0.80'
214
+ - - "<"
215
+ - !ruby/object:Gem::Version
216
+ version: '1'
202
217
  type: :development
203
218
  prerelease: false
204
219
  version_requirements: !ruby/object:Gem::Requirement
205
220
  requirements:
206
221
  - - ">="
207
222
  - !ruby/object:Gem::Version
208
- version: '0'
223
+ version: '0.80'
224
+ - - "<"
225
+ - !ruby/object:Gem::Version
226
+ version: '1'
209
227
  - !ruby/object:Gem::Dependency
210
228
  name: simplecov
211
229
  requirement: !ruby/object:Gem::Requirement
212
230
  requirements:
213
- - - ">="
231
+ - - "~>"
214
232
  - !ruby/object:Gem::Version
215
- version: '0'
233
+ version: '0.17'
216
234
  type: :development
217
235
  prerelease: false
218
236
  version_requirements: !ruby/object:Gem::Requirement
219
237
  requirements:
220
- - - ">="
238
+ - - "~>"
221
239
  - !ruby/object:Gem::Version
222
- version: '0'
240
+ version: '0.17'
223
241
  - !ruby/object:Gem::Dependency
224
242
  name: vcr
225
243
  requirement: !ruby/object:Gem::Requirement
226
244
  requirements:
227
- - - ">="
245
+ - - "~>"
228
246
  - !ruby/object:Gem::Version
229
- version: '0'
247
+ version: '5.0'
230
248
  type: :development
231
249
  prerelease: false
232
250
  version_requirements: !ruby/object:Gem::Requirement
233
251
  requirements:
234
- - - ">="
252
+ - - "~>"
235
253
  - !ruby/object:Gem::Version
236
- version: '0'
254
+ version: '5.0'
237
255
  - !ruby/object:Gem::Dependency
238
256
  name: webmock
239
257
  requirement: !ruby/object:Gem::Requirement
240
258
  requirements:
241
- - - ">="
259
+ - - "~>"
242
260
  - !ruby/object:Gem::Version
243
- version: '0'
261
+ version: '3.6'
244
262
  type: :development
245
263
  prerelease: false
246
264
  version_requirements: !ruby/object:Gem::Requirement
247
265
  requirements:
248
- - - ">="
266
+ - - "~>"
249
267
  - !ruby/object:Gem::Version
250
- version: '0'
268
+ version: '3.6'
251
269
  description: Allows you to quote or ship a Physical::Shipment object
252
270
  email:
253
271
  - mamhoff@gmail.com
@@ -326,14 +344,31 @@ files:
326
344
  - lib/friendly_shipping/services/ups/timing_options.rb
327
345
  - lib/friendly_shipping/services/ups_freight.rb
328
346
  - lib/friendly_shipping/services/ups_freight/generate_commodity_information.rb
347
+ - lib/friendly_shipping/services/ups_freight/generate_delivery_options_hash.rb
348
+ - lib/friendly_shipping/services/ups_freight/generate_document_options_hash.rb
349
+ - lib/friendly_shipping/services/ups_freight/generate_email_options_hash.rb
329
350
  - lib/friendly_shipping/services/ups_freight/generate_freight_rate_request_hash.rb
351
+ - lib/friendly_shipping/services/ups_freight/generate_freight_ship_request_hash.rb
330
352
  - lib/friendly_shipping/services/ups_freight/generate_location_hash.rb
331
- - lib/friendly_shipping/services/ups_freight/generate_ups_security_hash.rb
353
+ - lib/friendly_shipping/services/ups_freight/generate_pickup_options_hash.rb
354
+ - lib/friendly_shipping/services/ups_freight/generate_pickup_request_hash.rb
355
+ - lib/friendly_shipping/services/ups_freight/label_delivery_options.rb
356
+ - lib/friendly_shipping/services/ups_freight/label_document_options.rb
357
+ - lib/friendly_shipping/services/ups_freight/label_email_options.rb
358
+ - lib/friendly_shipping/services/ups_freight/label_item_options.rb
359
+ - lib/friendly_shipping/services/ups_freight/label_options.rb
360
+ - lib/friendly_shipping/services/ups_freight/label_package_options.rb
361
+ - lib/friendly_shipping/services/ups_freight/label_pickup_options.rb
362
+ - lib/friendly_shipping/services/ups_freight/parse_freight_label_response.rb
332
363
  - lib/friendly_shipping/services/ups_freight/parse_freight_rate_response.rb
333
- - lib/friendly_shipping/services/ups_freight/parse_json_response.rb
364
+ - lib/friendly_shipping/services/ups_freight/parse_shipment_document.rb
365
+ - lib/friendly_shipping/services/ups_freight/pickup_request_options.rb
334
366
  - lib/friendly_shipping/services/ups_freight/rates_item_options.rb
335
367
  - lib/friendly_shipping/services/ups_freight/rates_options.rb
336
368
  - lib/friendly_shipping/services/ups_freight/rates_package_options.rb
369
+ - lib/friendly_shipping/services/ups_freight/restful_api_error_handler.rb
370
+ - lib/friendly_shipping/services/ups_freight/shipment_document.rb
371
+ - lib/friendly_shipping/services/ups_freight/shipment_information.rb
337
372
  - lib/friendly_shipping/services/ups_freight/shipping_methods.rb
338
373
  - lib/friendly_shipping/services/usps.rb
339
374
  - lib/friendly_shipping/services/usps/choose_package_rate.rb
@@ -357,7 +392,7 @@ files:
357
392
  - lib/friendly_shipping/timing.rb
358
393
  - lib/friendly_shipping/types.rb
359
394
  - lib/friendly_shipping/version.rb
360
- homepage: https://github.com/friendly_cart/friendly_shipping
395
+ homepage: https://github.com/friendlycart/friendly_shipping
361
396
  licenses:
362
397
  - MIT
363
398
  metadata: {}
@@ -376,7 +411,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
376
411
  - !ruby/object:Gem::Version
377
412
  version: '0'
378
413
  requirements: []
379
- rubygems_version: 3.0.6
414
+ rubygems_version: 3.0.3
380
415
  signing_key:
381
416
  specification_version: 4
382
417
  summary: An integration layer for shipping services
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module FriendlyShipping
4
- module Services
5
- class UpsFreight
6
- class GenerateUpsSecurityHash
7
- def self.call(login:, password:, key:)
8
- {
9
- UPSSecurity: {
10
- UsernameToken: {
11
- Username: login,
12
- Password: password
13
- },
14
- ServiceAccessToken: {
15
- AccessLicenseNumber: key
16
- }
17
- }
18
- }
19
- end
20
- end
21
- end
22
- end
23
- end
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module FriendlyShipping
4
- module Services
5
- class UpsFreight
6
- class ParseJSONResponse
7
- extend Dry::Monads::Result::Mixin
8
-
9
- class << self
10
- def call(response_body, expected_root_tag)
11
- json = JSON.parse(response_body)
12
-
13
- if request_successful?(json, expected_root_tag)
14
- Success(json)
15
- else
16
- Failure(error_message(json))
17
- end
18
- rescue JSON::ParserError => e
19
- Failure(e)
20
- end
21
-
22
- private
23
-
24
- def request_successful?(json, expected_root_tag)
25
- json[expected_root_tag].present?
26
- end
27
-
28
- def error_message(json)
29
- detailed_error = json.dig('Fault', 'detail', 'Errors', 'ErrorDetail', 'PrimaryErrorCode')
30
- status = detailed_error['Code']
31
- desc = detailed_error['Description']
32
- [status, desc].compact.join(": ").presence || 'UPS could not process the request.'
33
- end
34
- end
35
- end
36
- end
37
- end
38
- end