friendly_shipping 0.8.1 → 0.9.0

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 (200) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +1 -1
  3. data/.env.template +3 -0
  4. data/.env.test.local.template +6 -0
  5. data/.gitignore +1 -0
  6. data/.rubocop-relaxed.yml +7 -23
  7. data/.rubocop.yml +11 -2
  8. data/.rubocop_todo.yml +21 -0
  9. data/.yardopts +6 -0
  10. data/CHANGELOG.md +71 -0
  11. data/Gemfile +17 -0
  12. data/friendly_shipping.gemspec +4 -13
  13. data/lib/friendly_shipping/api_error.rb +6 -4
  14. data/lib/friendly_shipping/api_error_handler.rb +10 -6
  15. data/lib/friendly_shipping/api_failure.rb +4 -0
  16. data/lib/friendly_shipping/api_result.rb +16 -4
  17. data/lib/friendly_shipping/carrier.rb +28 -8
  18. data/lib/friendly_shipping/http_client.rb +25 -2
  19. data/lib/friendly_shipping/inflections.rb +10 -0
  20. data/lib/friendly_shipping/item_options.rb +3 -0
  21. data/lib/friendly_shipping/label.rb +41 -20
  22. data/lib/friendly_shipping/package_options.rb +21 -2
  23. data/lib/friendly_shipping/rate.rb +50 -15
  24. data/lib/friendly_shipping/request.rb +23 -7
  25. data/lib/friendly_shipping/response.rb +21 -6
  26. data/lib/friendly_shipping/services/rl/api_error.rb +33 -0
  27. data/lib/friendly_shipping/services/rl/bol_options.rb +107 -0
  28. data/lib/friendly_shipping/services/rl/bol_packages_serializer.rb +32 -0
  29. data/lib/friendly_shipping/services/rl/bol_structures_serializer.rb +31 -0
  30. data/lib/friendly_shipping/services/rl/item_options.rb +38 -0
  31. data/lib/friendly_shipping/services/rl/package_options.rb +40 -0
  32. data/lib/friendly_shipping/services/rl/parse_create_bol_response.rb +46 -0
  33. data/lib/friendly_shipping/services/rl/parse_invoice_response.rb +50 -0
  34. data/lib/friendly_shipping/services/rl/parse_print_bol_response.rb +47 -0
  35. data/lib/friendly_shipping/services/rl/parse_print_shipping_labels_response.rb +47 -0
  36. data/lib/friendly_shipping/services/rl/parse_rate_quote_response.rb +66 -0
  37. data/lib/friendly_shipping/services/rl/parse_transit_times_response.rb +76 -0
  38. data/lib/friendly_shipping/services/rl/rate_quote_options.rb +86 -0
  39. data/lib/friendly_shipping/services/rl/rate_quote_packages_serializer.rb +54 -0
  40. data/lib/friendly_shipping/services/rl/rate_quote_structures_serializer.rb +53 -0
  41. data/lib/friendly_shipping/services/rl/serialize_create_bol_request.rb +86 -0
  42. data/lib/friendly_shipping/services/rl/serialize_location.rb +46 -0
  43. data/lib/friendly_shipping/services/rl/serialize_rate_quote_request.rb +69 -0
  44. data/lib/friendly_shipping/services/rl/serialize_transit_times_request.rb +38 -0
  45. data/lib/friendly_shipping/services/rl/shipment_document.rb +40 -0
  46. data/lib/friendly_shipping/services/rl/shipment_information.rb +41 -0
  47. data/lib/friendly_shipping/services/rl/shipment_options.rb +50 -0
  48. data/lib/friendly_shipping/services/rl/shipping_methods.rb +28 -0
  49. data/lib/friendly_shipping/services/rl/structure_options.rb +13 -0
  50. data/lib/friendly_shipping/services/rl.rb +204 -0
  51. data/lib/friendly_shipping/services/ship_engine/api_error.rb +33 -0
  52. data/lib/friendly_shipping/services/ship_engine/customs_items_serializer.rb +36 -0
  53. data/lib/friendly_shipping/services/ship_engine/label_customs_options.rb +10 -7
  54. data/lib/friendly_shipping/services/ship_engine/label_item_options.rb +10 -5
  55. data/lib/friendly_shipping/services/ship_engine/label_options.rb +31 -14
  56. data/lib/friendly_shipping/services/ship_engine/label_package_options.rb +18 -11
  57. data/lib/friendly_shipping/services/ship_engine/parse_address_validation_response.rb +77 -0
  58. data/lib/friendly_shipping/services/ship_engine/parse_carrier_response.rb +9 -0
  59. data/lib/friendly_shipping/services/ship_engine/parse_label_response.rb +4 -0
  60. data/lib/friendly_shipping/services/ship_engine/{parse_rate_estimate_response.rb → parse_rate_estimates_response.rb} +26 -6
  61. data/lib/friendly_shipping/services/ship_engine/parse_rates_response.rb +101 -0
  62. data/lib/friendly_shipping/services/ship_engine/parse_void_response.rb +4 -0
  63. data/lib/friendly_shipping/services/ship_engine/rate_estimates_options.rb +17 -4
  64. data/lib/friendly_shipping/services/ship_engine/rates_item_options.rb +28 -0
  65. data/lib/friendly_shipping/services/ship_engine/rates_options.rb +61 -0
  66. data/lib/friendly_shipping/services/ship_engine/rates_package_options.rb +20 -0
  67. data/lib/friendly_shipping/services/ship_engine/serialize_address_residential_indicator.rb +27 -0
  68. data/lib/friendly_shipping/services/ship_engine/serialize_address_validation_request.rb +31 -0
  69. data/lib/friendly_shipping/services/ship_engine/serialize_label_shipment.rb +22 -27
  70. data/lib/friendly_shipping/services/ship_engine/serialize_rate_estimate_request.rb +41 -16
  71. data/lib/friendly_shipping/services/ship_engine/serialize_rates_request.rb +126 -0
  72. data/lib/friendly_shipping/services/ship_engine.rb +94 -21
  73. data/lib/friendly_shipping/services/ship_engine_ltl/api_error.rb +12 -0
  74. data/lib/friendly_shipping/services/ship_engine_ltl/item_options.rb +24 -5
  75. data/lib/friendly_shipping/services/ship_engine_ltl/package_options.rb +39 -4
  76. data/lib/friendly_shipping/services/ship_engine_ltl/parse_carrier_response.rb +4 -0
  77. data/lib/friendly_shipping/services/ship_engine_ltl/parse_quote_response.rb +10 -0
  78. data/lib/friendly_shipping/services/ship_engine_ltl/quote_options.rb +29 -11
  79. data/lib/friendly_shipping/services/ship_engine_ltl/serialize_packages.rb +7 -2
  80. data/lib/friendly_shipping/services/ship_engine_ltl/serialize_quote_request.rb +50 -16
  81. data/lib/friendly_shipping/services/ship_engine_ltl/serialize_structures.rb +42 -0
  82. data/lib/friendly_shipping/services/ship_engine_ltl/shipment_options.rb +47 -0
  83. data/lib/friendly_shipping/services/ship_engine_ltl/structure_options.rb +17 -0
  84. data/lib/friendly_shipping/services/ship_engine_ltl.rb +50 -30
  85. data/lib/friendly_shipping/services/tforce_freight/access_token.rb +43 -0
  86. data/lib/friendly_shipping/services/tforce_freight/api_error.rb +42 -0
  87. data/lib/friendly_shipping/services/tforce_freight/bol_options.rb +180 -0
  88. data/lib/friendly_shipping/services/tforce_freight/document_options.rb +100 -0
  89. data/lib/friendly_shipping/services/tforce_freight/generate_commodity_information.rb +92 -0
  90. data/lib/friendly_shipping/services/tforce_freight/generate_create_bol_request_hash.rb +165 -0
  91. data/lib/friendly_shipping/services/tforce_freight/generate_document_options_hash.rb +36 -0
  92. data/lib/friendly_shipping/services/tforce_freight/generate_handling_units_hash.rb +51 -0
  93. data/lib/friendly_shipping/services/tforce_freight/generate_location_hash.rb +25 -0
  94. data/lib/friendly_shipping/services/tforce_freight/generate_pickup_request_hash.rb +113 -0
  95. data/lib/friendly_shipping/services/tforce_freight/generate_rates_request_hash.rb +65 -0
  96. data/lib/friendly_shipping/services/tforce_freight/generate_reference_hash.rb +28 -0
  97. data/lib/friendly_shipping/services/tforce_freight/item_options.rb +93 -0
  98. data/lib/friendly_shipping/services/tforce_freight/package_options.rb +121 -0
  99. data/lib/friendly_shipping/services/tforce_freight/parse_create_bol_response.rb +94 -0
  100. data/lib/friendly_shipping/services/tforce_freight/parse_pickup_response.rb +45 -0
  101. data/lib/friendly_shipping/services/tforce_freight/parse_rates_response.rb +58 -0
  102. data/lib/friendly_shipping/services/tforce_freight/parse_shipment_document.rb +31 -0
  103. data/lib/friendly_shipping/services/tforce_freight/pickup_options.rb +82 -0
  104. data/lib/friendly_shipping/services/tforce_freight/rates_item_options.rb +12 -0
  105. data/lib/friendly_shipping/services/tforce_freight/rates_options.rb +162 -0
  106. data/lib/friendly_shipping/services/tforce_freight/rates_package_options.rb +12 -0
  107. data/lib/friendly_shipping/services/tforce_freight/shipment_document.rb +38 -0
  108. data/lib/friendly_shipping/services/tforce_freight/shipment_information.rb +104 -0
  109. data/lib/friendly_shipping/services/tforce_freight/shipment_options.rb +49 -0
  110. data/lib/friendly_shipping/services/tforce_freight/shipping_methods.rb +25 -0
  111. data/lib/friendly_shipping/services/tforce_freight/structure_options.rb +44 -0
  112. data/lib/friendly_shipping/services/tforce_freight.rb +202 -0
  113. data/lib/friendly_shipping/services/ups/label_options.rb +14 -2
  114. data/lib/friendly_shipping/services/ups/label_package_options.rb +1 -1
  115. data/lib/friendly_shipping/services/ups/parse_modifier_element.rb +29 -0
  116. data/lib/friendly_shipping/services/ups/parse_rate_response.rb +12 -0
  117. data/lib/friendly_shipping/services/ups/parse_time_in_transit_response.rb +1 -1
  118. data/lib/friendly_shipping/services/ups/rate_estimate_options.rb +14 -1
  119. data/lib/friendly_shipping/services/ups/serialize_rating_service_selection_request.rb +10 -1
  120. data/lib/friendly_shipping/services/ups/serialize_shipment_accept_request.rb +1 -1
  121. data/lib/friendly_shipping/services/ups/serialize_shipment_confirm_request.rb +2 -1
  122. data/lib/friendly_shipping/services/ups/shipping_methods.rb +1 -1
  123. data/lib/friendly_shipping/services/ups.rb +1 -1
  124. data/lib/friendly_shipping/services/ups_freight/api_error.rb +8 -5
  125. data/lib/friendly_shipping/services/ups_freight/generate_commodity_information.rb +65 -19
  126. data/lib/friendly_shipping/services/ups_freight/generate_freight_rate_request_hash.rb +3 -20
  127. data/lib/friendly_shipping/services/ups_freight/generate_freight_ship_request_hash.rb +2 -20
  128. data/lib/friendly_shipping/services/ups_freight/generate_handling_units_hash.rb +54 -0
  129. data/lib/friendly_shipping/services/ups_freight/label_options.rb +36 -10
  130. data/lib/friendly_shipping/services/ups_freight/label_structure_options.rb +13 -0
  131. data/lib/friendly_shipping/services/ups_freight/parse_freight_label_response.rb +2 -2
  132. data/lib/friendly_shipping/services/ups_freight/parse_shipment_document.rb +1 -1
  133. data/lib/friendly_shipping/services/ups_freight/rates_item_options.rb +18 -9
  134. data/lib/friendly_shipping/services/ups_freight/rates_options.rb +31 -21
  135. data/lib/friendly_shipping/services/ups_freight/rates_package_options.rb +79 -8
  136. data/lib/friendly_shipping/services/ups_freight/rates_structure_options.rb +46 -0
  137. data/lib/friendly_shipping/services/ups_freight/shipment_information.rb +7 -3
  138. data/lib/friendly_shipping/services/ups_freight/shipment_options.rb +49 -0
  139. data/lib/friendly_shipping/services/ups_freight.rb +3 -1
  140. data/lib/friendly_shipping/services/ups_json/access_token.rb +29 -0
  141. data/lib/friendly_shipping/services/ups_json/api_error.rb +29 -0
  142. data/lib/friendly_shipping/services/ups_json/generate_address_classification_payload.rb +29 -0
  143. data/lib/friendly_shipping/services/ups_json/generate_address_hash.rb +30 -0
  144. data/lib/friendly_shipping/services/ups_json/generate_labels_payload.rb +211 -0
  145. data/lib/friendly_shipping/services/ups_json/generate_package_hash.rb +76 -0
  146. data/lib/friendly_shipping/services/ups_json/generate_rates_payload.rb +86 -0
  147. data/lib/friendly_shipping/services/ups_json/generate_timings_payload.rb +44 -0
  148. data/lib/friendly_shipping/services/ups_json/label.rb +20 -0
  149. data/lib/friendly_shipping/services/ups_json/label_billing_options.rb +41 -0
  150. data/lib/friendly_shipping/services/ups_json/label_item_options.rb +77 -0
  151. data/lib/friendly_shipping/services/ups_json/label_options.rb +177 -0
  152. data/lib/friendly_shipping/services/ups_json/label_package_options.rb +51 -0
  153. data/lib/friendly_shipping/services/ups_json/parse_address_classification_response.rb +31 -0
  154. data/lib/friendly_shipping/services/ups_json/parse_json_response.rb +44 -0
  155. data/lib/friendly_shipping/services/ups_json/parse_labels_response.rb +71 -0
  156. data/lib/friendly_shipping/services/ups_json/parse_money_hash.rb +128 -0
  157. data/lib/friendly_shipping/services/ups_json/parse_rate_modifier_hash.rb +28 -0
  158. data/lib/friendly_shipping/services/ups_json/parse_rates_response.rb +105 -0
  159. data/lib/friendly_shipping/services/ups_json/parse_timings_response.rb +56 -0
  160. data/lib/friendly_shipping/services/ups_json/parse_void_response.rb +32 -0
  161. data/lib/friendly_shipping/services/ups_json/rates_item_options.rb +22 -0
  162. data/lib/friendly_shipping/services/ups_json/rates_options.rb +113 -0
  163. data/lib/friendly_shipping/services/ups_json/rates_package_options.rb +17 -0
  164. data/lib/friendly_shipping/services/ups_json/shipping_methods.rb +111 -0
  165. data/lib/friendly_shipping/services/ups_json/timings_options.rb +33 -0
  166. data/lib/friendly_shipping/services/ups_json.rb +216 -0
  167. data/lib/friendly_shipping/services/usps/choose_package_rate.rb +3 -3
  168. data/lib/friendly_shipping/services/usps/machinable_package.rb +1 -1
  169. data/lib/friendly_shipping/services/usps/parse_package_rate.rb +6 -6
  170. data/lib/friendly_shipping/services/usps/parse_time_in_transit_response.rb +6 -6
  171. data/lib/friendly_shipping/services/usps/rate_estimate_options.rb +1 -1
  172. data/lib/friendly_shipping/services/usps/rate_estimate_package_options.rb +6 -1
  173. data/lib/friendly_shipping/services/usps/serialize_rate_request.rb +2 -2
  174. data/lib/friendly_shipping/services/usps/shipping_methods.rb +4 -3
  175. data/lib/friendly_shipping/services/usps.rb +1 -1
  176. data/lib/friendly_shipping/services/usps_international/parse_package_rate.rb +3 -3
  177. data/lib/friendly_shipping/services/usps_international/rate_estimate_options.rb +1 -1
  178. data/lib/friendly_shipping/services/usps_international/serialize_rate_request.rb +1 -1
  179. data/lib/friendly_shipping/services/usps_international.rb +1 -1
  180. data/lib/friendly_shipping/services/usps_ship/access_token.rb +37 -0
  181. data/lib/friendly_shipping/services/usps_ship/api_error.rb +29 -0
  182. data/lib/friendly_shipping/services/usps_ship/machinable_package.rb +53 -0
  183. data/lib/friendly_shipping/services/usps_ship/parse_rate_estimates_response.rb +80 -0
  184. data/lib/friendly_shipping/services/usps_ship/parse_timings_response.rb +80 -0
  185. data/lib/friendly_shipping/services/usps_ship/rate_estimate_options.rb +45 -0
  186. data/lib/friendly_shipping/services/usps_ship/rate_estimate_package_options.rb +124 -0
  187. data/lib/friendly_shipping/services/usps_ship/serialize_rate_estimates_request.rb +55 -0
  188. data/lib/friendly_shipping/services/usps_ship/shipping_methods.rb +38 -0
  189. data/lib/friendly_shipping/services/{ship_engine_ltl/bad_request.rb → usps_ship/timing_options.rb} +2 -2
  190. data/lib/friendly_shipping/services/usps_ship.rb +199 -0
  191. data/lib/friendly_shipping/shipment_options.rb +13 -1
  192. data/lib/friendly_shipping/shipping_method.rb +38 -11
  193. data/lib/friendly_shipping/structure_options.rb +38 -0
  194. data/lib/friendly_shipping/timing.rb +42 -7
  195. data/lib/friendly_shipping/version.rb +1 -1
  196. data/lib/friendly_shipping.rb +6 -0
  197. metadata +140 -174
  198. data/lib/friendly_shipping/services/ship_engine/bad_request.rb +0 -29
  199. data/lib/friendly_shipping/services/ship_engine/bad_request_handler.rb +0 -33
  200. data/lib/friendly_shipping/services/ship_engine_ltl/bad_request_handler.rb +0 -33
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7bc054d44e12f0d44f1240a8c831918fa7eec158f8cc66ffb104586a2a2f4180
4
- data.tar.gz: 900e8bb08f94858c0b147d886f9eaeae72c3db74efe04b7cbe8a3d9e7184f4fe
3
+ metadata.gz: efe62f43bc8306cc3541524c1be0a3746ce29e460c14903ae57e1f9ee16b3b69
4
+ data.tar.gz: 4750fdcb3fd536ca2b37ab6c70d0dd289172337cd1b2a430148b8beb2ac47b47
5
5
  SHA512:
6
- metadata.gz: db80927fd83629f29a503512672dd39566e758b20e16d29d92332427e9eabd22aef9f9f03d286468fd36c78ea74dd06906a63b9e631bd7304f3f4cfa372e8718
7
- data.tar.gz: 99930e58a990bc2e4a50027cbb5a4a379062f86ca21a897edb3761d594843444f54de3b1ac09b65b4b454c46f52d75941cee688f09f86e8230cb97ae73d0d76a
6
+ metadata.gz: 348556eb9f2e12e2bdbf66ddb48bbb6ef9c97500ddfea4b9530294be1faf255d95248856a6d83bd5a9b533b878a5e277e1e1d62ca5a575859caec7e38ef77f7e
7
+ data.tar.gz: 84e0a0cd96e0535a881225a17dfa0d443a52411495b410c5a02719327dc665a77f0109d562024908810d81ab324cc4ec67ae94e0d2dfbfadd9f8a9d3c0060503
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.1", "3.0", "2.7"]
75
+ ruby-version: ["3.2", "3.1", "3.0"]
data/.env.template CHANGED
@@ -1,7 +1,10 @@
1
1
  # .env.template
2
+
2
3
  # NO PASSWORDS OR SENSITIVE INFORMATION SHOULD BE STORED HERE
3
4
  # Only pass along how those passwords/info are reference via ENV VARS
4
5
 
6
+ RL_API_KEY=RL API Key
7
+
5
8
  SHIPENGINE_API_KEY=ShipEngine API key
6
9
  SHIPENGINE_CARRIER_ID=Carrier ID from your ShipEngine account to run test labels with
7
10
 
@@ -0,0 +1,6 @@
1
+ # .env.test.local.template
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.
5
+
6
+ ACCESS_TOKEN=secret_token
data/.gitignore CHANGED
@@ -18,4 +18,5 @@
18
18
  # Gemfile.lock
19
19
  Gemfile.lock
20
20
  .env
21
+ .env.test.local
21
22
  coverage
data/.rubocop-relaxed.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  # Relaxed.Ruby.Style
2
- ## Version 2.2
2
+ ## Version 2.5
3
3
 
4
4
  Style/Alias:
5
5
  Enabled: false
@@ -65,6 +65,10 @@ Style/NegatedWhile:
65
65
  Enabled: false
66
66
  StyleGuide: https://relaxed.ruby.style/#stylenegatedwhile
67
67
 
68
+ Style/NumericPredicate:
69
+ Enabled: false
70
+ StyleGuide: https://relaxed.ruby.style/#stylenumericpredicate
71
+
68
72
  Style/ParallelAssignment:
69
73
  Enabled: false
70
74
  StyleGuide: https://relaxed.ruby.style/#styleparallelassignment
@@ -133,9 +137,6 @@ Style/WordArray:
133
137
  Enabled: false
134
138
  StyleGuide: https://relaxed.ruby.style/#stylewordarray
135
139
 
136
- Layout/LineLength:
137
- Enabled: false
138
-
139
140
  Lint/AmbiguousRegexpLiteral:
140
141
  Enabled: false
141
142
  StyleGuide: https://relaxed.ruby.style/#lintambiguousregexpliteral
@@ -144,26 +145,9 @@ Lint/AssignmentInCondition:
144
145
  Enabled: false
145
146
  StyleGuide: https://relaxed.ruby.style/#lintassignmentincondition
146
147
 
147
- Metrics/AbcSize:
148
- Enabled: false
149
-
150
- Metrics/BlockNesting:
151
- Enabled: false
152
-
153
- Metrics/ClassLength:
154
- Enabled: false
155
-
156
- Metrics/ModuleLength:
157
- Enabled: false
158
-
159
- Metrics/CyclomaticComplexity:
160
- Enabled: false
161
-
162
- Metrics/MethodLength:
148
+ Layout/LineLength:
163
149
  Enabled: false
164
150
 
165
- Metrics/ParameterLists:
151
+ Metrics:
166
152
  Enabled: false
167
153
 
168
- Metrics/PerceivedComplexity:
169
- Enabled: false
data/.rubocop.yml CHANGED
@@ -1,15 +1,24 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.7
2
+ NewCops: enable
3
+ SuggestExtensions: false
4
+ TargetRubyVersion: 3.2
3
5
 
4
6
  inherit_from:
5
- - .rubocop-relaxed.yml
7
+ - .rubocop_todo.yml
8
+ - .rubocop-relaxed.yml
6
9
 
7
10
  Metrics/BlockLength:
8
11
  Enabled: false
9
12
 
13
+ Style/AccessorGrouping:
14
+ Enabled: false
15
+
10
16
  Style/HashEachMethods:
11
17
  Enabled: true
12
18
 
19
+ Style/HashSyntax:
20
+ Enabled: false
21
+
13
22
  Style/HashTransformKeys:
14
23
  Enabled: true
15
24
 
data/.rubocop_todo.yml ADDED
@@ -0,0 +1,21 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2024-02-09 08:53:15 UTC using RuboCop version 1.60.2.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 1
10
+ # Configuration parameters: Severity, Include.
11
+ # Include: **/*.gemspec
12
+ Gemspec/RequiredRubyVersion:
13
+ Exclude:
14
+ - 'friendly_shipping.gemspec'
15
+
16
+ # Offense count: 3
17
+ # This cop supports safe autocorrection (--autocorrect).
18
+ # Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods.
19
+ Lint/UnusedMethodArgument:
20
+ Exclude:
21
+ - 'lib/friendly_shipping/services/ups_json.rb'
data/.yardopts ADDED
@@ -0,0 +1,6 @@
1
+ --protected
2
+ --no-private
3
+ --readme README.md
4
+ --markup markdown
5
+ --exclude friendly_shipping/types
6
+ 'lib/**/*.rb' - '*.md'
data/CHANGELOG.md CHANGED
@@ -4,6 +4,77 @@ 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.9.0] - 2024-05-02
8
+ - Implement R&L service with rates and timings (#177)
9
+ - Add R&L Freight API call to create BOL and schedule pickup (#178)
10
+ - Add R&L Freight API calls to print BOL and shipping labels (#179)
11
+ - Add universal PRO option for R&L Freight (#180)
12
+ - Extract R&L Freight package serializer classes (#181)
13
+ - Refactor R+L BOL creation to return new `ShipmentInformation` object (#182)
14
+ - Add reference numbers to R+L BOL options class (#183)
15
+ - Add sub-version option to UPS rate/shipping requests (#184)
16
+ - Parse modifiers from UPS rates response XML (#185)
17
+ - R+L Shipping outside of Domestic USA & Canada requires dimensions (#187)
18
+ - Use R+L Carriers sandbox API for test mode (#188)
19
+ - Add optional pickup date to UPS rate requests (#189)
20
+ - Replace `BadRequestHandler` with `ApiErrorHandler` (#190)
21
+ - Update ShipEngine to support APC (#191)
22
+ - Rename `ShipmentInformation#number` (#196)
23
+ - Allow setting `ShipmentInformation#number` value (#197)
24
+ - Add declaration statement to UPS intl labels (#195)
25
+ - Add additional instructions to R+L BOL requests (#198)
26
+ - Add special instructions to R+L BOL requests (#199)
27
+ - Add TForce API rates endpoint (#194)
28
+ - Update physical gem to v0.5.1 (#200)
29
+ - Extract UPS Freight handling units generator class (#203)
30
+ - Fix options to allow option class args to actually override the default (#204)
31
+ - Add TForce endpoint to create access token (#206)
32
+ - Adjust TForce error parser for API errors (#208)
33
+ - Truncate zips to 5 digits for TForce (#210)
34
+ - Add comments to TForce rating call type codes (#207)
35
+ - Consolidate customs items for ShipEngine (#209)
36
+ - Add TForce pickup request service method (#211)
37
+ - Add TForce create BOL service method (#212)
38
+ - UPS json api rates and timings (#213)
39
+ - RL Invoice (#214)
40
+ - Add ups json api address classification api (#215)
41
+ - Stripe leading/trailing whitespace from R+L phone (#222)
42
+ - Update dotenv requirement from ~> 2.7 to ~> 3.0 (#223)
43
+ - Parse TForce shipment documents (#218)
44
+ - Ups json api labels (#221)
45
+ - ShipEngine address validation service method (#224)
46
+ - Fix ShipEngine address validation serializer (#225)
47
+ - Fix ShipEngine address validation return value (#227)
48
+ - Add timing details to ShipEngine rates (#226)
49
+ - Add additional response data to ShipEngine rates (#228)
50
+ - Exclude dimensions from ShipEngine rate estimates when zero (#229)
51
+ - Fix rates path and remove ignored attributes (#230)
52
+ - Add `comparison_rate_type` to ShipEngine rates requests (#231)
53
+ - Fix YARD docs for ShipEngine rates options (#232)
54
+ - Add YARD docs to R+L, ShipEngine, and TForce (#205)
55
+ - Rename TForce item/package options classes (#235)
56
+ - Remove periods from city names for R+L requests (#236)
57
+ - Use new `Physical::Structure` class for LTL/freight services (#201)
58
+ - Update TForce handling units class to use structures instead of packages (#238)
59
+ - Fix Poland's ISO code (#237)
60
+ - Remove duplicate package deprecation warnings (#239)
61
+ - Use UPS response header to determine errors (#240)
62
+ - Deprecate legacy First Class mail types (#242)
63
+ - Add reference numbers to packages (#243)
64
+ - Use error description when UPS returns bad json (#245)
65
+ - Add address validation query param (#241)
66
+ - Add city validation to UPS json label request (#246)
67
+ - TForce Freight: Parse pickup confirmation numbers (#248)
68
+ - Fix TForce shipping label codes (#249)
69
+ - TForce Freight: Fix parsing of BOL creation error responses (#250)
70
+ - Add `.env.test.local.template` file (#251)
71
+ - Add service class for new USPS Ship API (#244)
72
+ - Append request/response to USPS Ship API result (#253)
73
+ - Better error message on 400 from UPS json api (#254)
74
+ - Truncate long values in TForce API requests (#252)
75
+ - Escape special chars in TForce BOL API request (#255)
76
+ - Change USPS Ship package option default value (#256)
77
+
7
78
  ## [0.8.1] - 2023-08-03
8
79
  - USPS Service: Fix international ounces remainder (#166)
9
80
  - UPS Service: Fix bug causing inflated international product costs (#167)
data/Gemfile CHANGED
@@ -6,3 +6,20 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
6
 
7
7
  # Specify your gem's dependencies in friendly_shipping.gemspec
8
8
  gemspec
9
+
10
+ group :development do
11
+ gem "bundler", ">= 2.1.4", "< 3"
12
+ gem "dotenv", "~> 3.0"
13
+ gem "factory_bot", "~> 6.2"
14
+ gem "pry", "~> 0.12"
15
+ gem "rack"
16
+ gem "rake", ">= 12.3.3"
17
+ gem "rspec", "~> 3.0"
18
+ gem "rspec_junit_formatter", "~> 0.4"
19
+ gem "rubocop"
20
+ gem "simplecov", "~> 0.17"
21
+ gem "vcr", "~> 6.0"
22
+ gem "webmock", "~> 3.6"
23
+ gem "webrick"
24
+ gem "yard"
25
+ end
@@ -23,21 +23,12 @@ Gem::Specification.new do |spec|
23
23
  spec.require_paths = ["lib"]
24
24
 
25
25
  spec.add_runtime_dependency "dry-monads", "~> 1.0"
26
+ spec.add_runtime_dependency "jwt", "~> 2.7"
26
27
  spec.add_runtime_dependency "money", "~> 6.0"
27
28
  spec.add_runtime_dependency "nokogiri", "~> 1.6"
28
- spec.add_runtime_dependency "physical", "~> 0.4", ">= 0.4.5"
29
+ spec.add_runtime_dependency "physical", "~> 0.5", ">= 0.5.1"
29
30
  spec.add_runtime_dependency "rest-client", "~> 2.0"
30
- spec.required_ruby_version = '>= 2.7'
31
31
 
32
- spec.add_development_dependency "bundler", ">= 2.1.4", "< 3"
33
- spec.add_development_dependency "dotenv", "~> 2.7"
34
- spec.add_development_dependency "factory_bot", "~> 6.2"
35
- spec.add_development_dependency "pry", "~> 0.12"
36
- spec.add_development_dependency "rake", ">= 12.3.3"
37
- spec.add_development_dependency "rspec", "~> 3.0"
38
- spec.add_development_dependency "rspec_junit_formatter", "~> 0.4"
39
- spec.add_development_dependency "rubocop"
40
- spec.add_development_dependency "simplecov", "~> 0.17"
41
- spec.add_development_dependency "vcr", "~> 6.0"
42
- spec.add_development_dependency "webmock", "~> 3.6"
32
+ spec.required_ruby_version = '>= 3.0'
33
+ spec.metadata['rubygems_mfa_required'] = 'true'
43
34
  end
@@ -1,14 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FriendlyShipping
4
+ # Raised when an API error is returned. Parent of carrier-specific API error classes.
4
5
  class ApiError < StandardError
6
+ # @return [RestClient::Exception] the cause of the error
5
7
  attr_reader :cause
6
8
 
7
- # @param [RestClient::Exception] cause
8
- # @param [String] msg
9
- def initialize(cause, msg = nil)
9
+ # @param cause [RestClient::Exception] the cause of the error
10
+ # @param message [String] optional descriptive message
11
+ def initialize(cause, message = nil)
10
12
  @cause = cause
11
- super msg || cause.message
13
+ super(message || cause.message)
12
14
  end
13
15
  end
14
16
  end
@@ -3,20 +3,24 @@
3
3
  require 'friendly_shipping/api_error'
4
4
 
5
5
  module FriendlyShipping
6
+ # 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`.
6
9
  class ApiErrorHandler
7
- include Dry::Monads[:result]
10
+ include Dry::Monads::Result::Mixin
8
11
 
12
+ # @return [Class] the class used to wrap the API error
9
13
  attr_reader :api_error_class
10
14
 
11
- # @param [Class] api_error_class
15
+ # @param api_error_class [Class] the class used to wrap the API error
12
16
  def initialize(api_error_class: FriendlyShipping::ApiError)
13
17
  @api_error_class = api_error_class
14
18
  end
15
19
 
16
- # @param [StandardError] error
17
- # @param [FriendlyShipping::Request] original_request
18
- # @param [RestClient::Response] original_response
19
- # @return [Dry::Monads::Failure<FriendlyShipping::ApiFailure>]
20
+ # @param error [StandardError] the error to handle
21
+ # @param original_request [Request] the API request which triggered the error
22
+ # @param original_response [RestClient::Response] the API response containing the error
23
+ # @return [Failure<ApiFailure>]
20
24
  def call(error, original_request: nil, original_response: nil)
21
25
  Failure(
22
26
  ApiFailure.new(
@@ -1,9 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FriendlyShipping
4
+ # Wraps an API result from a request that failed.
4
5
  class ApiFailure < ApiResult
6
+ # @!attribute [r] data
7
+ # The API failure (typically an exception)
5
8
  alias_method :failure, :data
6
9
 
10
+ # @return [#to_s] a string representation of the failure
7
11
  def to_s
8
12
  failure.to_s
9
13
  end
@@ -1,12 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FriendlyShipping
4
+ # Wraps an API result (a response body, for example) along with the
5
+ # original request and response objects.
4
6
  class ApiResult
5
- attr_reader :data, :original_request, :original_response
7
+ # @return [Object] the API result (typically the response body)
8
+ attr_reader :data
6
9
 
7
- # @param [Object] data The API result
8
- # @param [FriendlyShipping::Request] original_request The HTTP request (when debugging is enabled)
9
- # @param [FriendlyShipping::Response] original_response The HTTP response (when debugging is enabled)
10
+ # @return [Request] the original API request (if debugging is enabled)
11
+ attr_reader :original_request
12
+
13
+ # @return [Response] the original API response (if debugging is enabled)
14
+ attr_reader :original_response
15
+
16
+ # Returns a new instance of `ApiResult`. The original request and response are only attached
17
+ # to this object if debugging is enabled. See {FriendlyShipping::Request#debug}
18
+ #
19
+ # @param data [Object] the API result (typically the response body)
20
+ # @param original_request [Request] the original API request
21
+ # @param original_response [Response] the original API response
10
22
  def initialize(data, original_request: nil, original_response: nil)
11
23
  @data = data
12
24
 
@@ -1,15 +1,32 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FriendlyShipping
4
+ # Represents a carrier (UPS, FedEx, etc.) and its {ShippingMethod} objects.
4
5
  class Carrier
5
- attr_reader :id, :name, :code, :shipping_methods, :balance, :data
6
-
7
- # @param [Integer] id The carrier's ID
8
- # @param [String] name The carrier's name
9
- # @param [String] code The carrier's unique code
10
- # @param [Array] shipping_methods The shipping methods available on this carrier
11
- # @param [Float] balance The remaining balance for this carrier
12
- # @param [Hash] data Additional data related to this carrier
6
+ # @return [String] a unique identifier for this carrier
7
+ attr_reader :id
8
+
9
+ # @return [String] the carrier's name
10
+ attr_reader :name
11
+
12
+ # @return [String] the carrier's unique code
13
+ attr_reader :code
14
+
15
+ # @return [Array<ShippingMethod>] the shipping methods available on this carrier
16
+ attr_reader :shipping_methods
17
+
18
+ # @return [Float] the remaining balance for this carrier
19
+ attr_reader :balance
20
+
21
+ # @return [Hash] additional data related to this carrier
22
+ attr_reader :data
23
+
24
+ # @param id [Integer, String] a unique identifier for this carrier
25
+ # @param name [String] the carrier's name
26
+ # @param code [String] the carrier's unique code
27
+ # @param shipping_methods [Array<ShippingMethod>] the shipping methods available on this carrier
28
+ # @param balance [Float] the remaining balance for this carrier
29
+ # @param data [Hash] additional data related to this carrier
13
30
  def initialize(id: nil, name: nil, code: nil, shipping_methods: [], balance: nil, data: {})
14
31
  @id = id
15
32
  @name = name
@@ -19,6 +36,9 @@ module FriendlyShipping
19
36
  @data = data
20
37
  end
21
38
 
39
+ # Returns true if the given object shares the same ID with this carrier.
40
+ # @param [Object] other
41
+ # @return [Boolean]
22
42
  def ==(other)
23
43
  id == other.id
24
44
  end
@@ -7,16 +7,22 @@ require 'friendly_shipping/api_failure'
7
7
  require 'friendly_shipping/api_error_handler'
8
8
 
9
9
  module FriendlyShipping
10
+ # A façade for `RestClient` which constructs requests, wraps responses in `Dry::Monad`
11
+ # results, and calls the API error handler with failures.
10
12
  class HttpClient
11
- include Dry::Monads[:result]
13
+ include Dry::Monads::Result::Mixin
12
14
 
15
+ # @return [.call] the API error handler
13
16
  attr_reader :error_handler
14
17
 
15
- # @param [Proc] error_handler Called to handle an error if one occurs
18
+ # @param error_handler [.call] called if an API error occurs
16
19
  def initialize(error_handler: FriendlyShipping::ApiErrorHandler.new)
17
20
  @error_handler = error_handler
18
21
  end
19
22
 
23
+ # Makes a GET request and handles the response.
24
+ # @param request [Request] the request to GET
25
+ # @return [Success<Response>, Failure<ApiFailure>]
20
26
  def get(request)
21
27
  http_response = ::RestClient.get(
22
28
  request.url, request.headers
@@ -27,6 +33,20 @@ module FriendlyShipping
27
33
  error_handler.call(e, original_request: request, original_response: e.response)
28
34
  end
29
35
 
36
+ # Makes a DELETE request and handles the response.
37
+ # @param request [Request] the request to DELETE
38
+ # @return [Success<Response>, Failure<ApiFailure>]
39
+ def delete(request)
40
+ http_response = ::RestClient.delete(request.url, request.headers)
41
+
42
+ Success(Response.new_from_rest_client_response(http_response))
43
+ rescue ::RestClient::Exception => e
44
+ error_handler.call(e, original_request: request, original_response: e.response)
45
+ end
46
+
47
+ # Makes a POST request and handles the response.
48
+ # @param request [Request] the request to POST
49
+ # @return [Success<Response>, Failure<ApiFailure>]
30
50
  def post(request)
31
51
  http_response = ::RestClient.post(
32
52
  request.url,
@@ -39,6 +59,9 @@ module FriendlyShipping
39
59
  error_handler.call(e, original_request: request, original_response: e.response)
40
60
  end
41
61
 
62
+ # Makes a PUT request and handles the response.
63
+ # @param request [Request] the request to PUT
64
+ # @return [Success<Response>, Failure<ApiFailure>]
42
65
  def put(request)
43
66
  http_response = ::RestClient.put(
44
67
  request.url,
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This is necessary for classes with acronyms to autoload in Rails
4
+ if Object.const_defined?('ActiveSupport::Inflector')
5
+ ActiveSupport::Inflector.inflections(:en) do |inflect|
6
+ inflect.acronym 'BOL'
7
+ inflect.acronym 'RL'
8
+ inflect.acronym 'TForce'
9
+ end
10
+ end
@@ -1,9 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FriendlyShipping
4
+ # Base class for item options. Used when serializing API requests.
4
5
  class ItemOptions
6
+ # @return [String] the ID for the item that belongs to these options
5
7
  attr_reader :item_id
6
8
 
9
+ # @param item_id [String] the ID for the item that belongs to these options
7
10
  def initialize(item_id:)
8
11
  @item_id = item_id
9
12
  end
@@ -3,27 +3,48 @@
3
3
  require 'friendly_shipping/types'
4
4
 
5
5
  module FriendlyShipping
6
+ # Base class for a shipping label returned by a carrier API.
6
7
  class Label
7
- attr_reader :id,
8
- :shipment_id,
9
- :tracking_number,
10
- :service_code,
11
- :label_href,
12
- :data,
13
- :label_format,
14
- :cost,
15
- :shipment_cost,
16
- :label_data
17
-
18
- # @param [Integer] id The label's ID
19
- # @param [Integer] shipment_id The label's shipment ID
20
- # @param [String] tracking_number The label's tracking number
21
- # @param [String] service_code The label's service code
22
- # @param [String] label_href The URL for the label
23
- # @param [String] label_format The label's format
24
- # @param [String] label_data The raw label data
25
- # @param [Float] shipment_cost The cost of the shipment
26
- # @param [Hash] data Additional data related to the label
8
+ # @return [String] the label's unique ID
9
+ attr_reader :id
10
+
11
+ # @return [String] the label's shipment ID
12
+ attr_reader :shipment_id
13
+
14
+ # @return [String] the label's tracking number
15
+ attr_reader :tracking_number
16
+
17
+ # @return [String] the label's service code
18
+ attr_reader :service_code
19
+
20
+ # @return [String] the URL for the label
21
+ attr_reader :label_href
22
+
23
+ # @return [String] the label's format
24
+ attr_reader :label_format
25
+
26
+ # @return [String] the raw label data
27
+ attr_reader :label_data
28
+
29
+ # @return [Money] the label's cost
30
+ attr_reader :cost
31
+
32
+ # @return [Money] the overall cost of the shipment
33
+ attr_reader :shipment_cost
34
+
35
+ # @return [Hash] additional data related to the label
36
+ attr_reader :data
37
+
38
+ # @param id [String] the label's unique ID
39
+ # @param shipment_id [String] the label's shipment ID
40
+ # @param tracking_number [String] the label's tracking number
41
+ # @param service_code [String] the label's service code
42
+ # @param label_href [String] the URL for the label
43
+ # @param label_format [String] the label's format
44
+ # @param label_data [String] the raw label data
45
+ # @param cost [Money] the label's cost
46
+ # @param shipment_cost [Money] the overall cost of the shipment
47
+ # @param data [Hash] additional data related to the label
27
48
  def initialize(
28
49
  id: nil,
29
50
  shipment_id: nil,
@@ -1,9 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FriendlyShipping
4
+ # Base class for package options. Used when serializing API requests.
4
5
  class PackageOptions
6
+ # @return [String] the ID for the package that belongs to these options
5
7
  attr_reader :package_id
6
8
 
9
+ # @param package_id [String] the ID for the package that belongs to these options
10
+ # @param item_options [Array<ItemOptions>] the options for items in this package
11
+ # @param item_options_class [Class] the class to use for item options when none are provided
7
12
  def initialize(
8
13
  package_id:,
9
14
  item_options: Set.new,
@@ -14,6 +19,11 @@ module FriendlyShipping
14
19
  @item_options_class = item_options_class
15
20
  end
16
21
 
22
+ # Finds and returns item options for the given item. If options cannot be
23
+ # found, the `item_options_class` is used to construct new options.
24
+ #
25
+ # @param item [#id] the item for which to get options
26
+ # @return [ItemOptions]
17
27
  def options_for_item(item)
18
28
  item_options.detect do |item_option|
19
29
  item_option.item_id == item.id
@@ -22,9 +32,18 @@ module FriendlyShipping
22
32
 
23
33
  private
24
34
 
25
- attr_reader :item_options,
26
- :item_options_class
35
+ # @return [Array<ItemOptions>]
36
+ attr_reader :item_options
27
37
 
38
+ # @return [Class]
39
+ attr_reader :item_options_class
40
+
41
+ # Attempts to find a hash value for the given key. If no value is found, the
42
+ # default value is returned.
43
+ #
44
+ # @param key [Symbol] the key to use
45
+ # @param default [Object] the default value
46
+ # @param kwargs [Hash] the hash to search
28
47
  def value_or_default(key, default, kwargs)
29
48
  kwargs.key?(key) ? kwargs.delete(key) : default
30
49
  end