friendly_shipping 0.5.2 → 0.6.3

Sign up to get free protection for your applications and to get access to all the features.
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