solidus_easypost 1.0.5 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +35 -0
  3. data/.gem_release.yml +5 -0
  4. data/.github/stale.yml +17 -0
  5. data/.gitignore +20 -0
  6. data/.rspec +2 -0
  7. data/.rubocop.yml +4 -0
  8. data/.rubocop_todo.yml +71 -0
  9. data/Gemfile +33 -0
  10. data/LICENSE +26 -0
  11. data/README.md +104 -0
  12. data/Rakefile +6 -0
  13. data/app/decorators/models/solidus_easypost/spree/address_decorator.rb +30 -0
  14. data/app/decorators/models/solidus_easypost/spree/shipment_decorator.rb +52 -0
  15. data/app/decorators/models/solidus_easypost/spree/shipping_rate_decorator.rb +13 -0
  16. data/app/decorators/models/solidus_easypost/spree/stock/estimator_decorator.rb +15 -0
  17. data/app/decorators/models/solidus_easypost/spree/stock/package_decorator.rb +27 -0
  18. data/app/decorators/models/solidus_easypost/spree/stock_location_decorator.rb +26 -0
  19. data/app/models/solidus_easypost/estimator.rb +51 -0
  20. data/app/models/solidus_easypost/return_authorization.rb +38 -0
  21. data/bin/console +17 -0
  22. data/bin/rails +8 -0
  23. data/bin/rails-engine +15 -0
  24. data/bin/rails-sandbox +17 -0
  25. data/bin/rake +7 -0
  26. data/bin/sandbox +84 -0
  27. data/bin/setup +8 -0
  28. data/config/locales/en.yml +5 -0
  29. data/config/routes.rb +5 -0
  30. data/db/migrate/20140515024440_add_easy_post_fields_to_shipping_rate.rb +9 -0
  31. data/lib/generators/solidus_easypost/install/install_generator.rb +22 -0
  32. data/lib/solidus_easypost.rb +21 -0
  33. data/lib/solidus_easypost/configuration.rb +11 -0
  34. data/lib/solidus_easypost/engine.rb +19 -0
  35. data/lib/solidus_easypost/factories.rb +24 -0
  36. data/lib/solidus_easypost/version.rb +5 -0
  37. data/solidus_easypost.gemspec +38 -0
  38. data/spec/cassettes/SolidusEasypost_ReturnAuthorization/_easypost_shipment/is_an_EasyPost_Shipment_object.yml +271 -0
  39. data/spec/cassettes/SolidusEasypost_ReturnAuthorization/_return_label/has_the_correct_fields.yml +336 -0
  40. data/spec/cassettes/SolidusEasypost_ReturnAuthorization/_return_label/is_an_EasyPost_PackageLabel_object.yml +336 -0
  41. data/spec/cassettes/Spree_Address/_easypost_address/has_the_correct_attributes.yml +69 -0
  42. data/spec/cassettes/Spree_Address/_easypost_address/is_an_EasyPost_Address_object.yml +69 -0
  43. data/spec/cassettes/Spree_Order/_refresh_shipment_rates/can_get_rates_from_easy_post.yml +271 -0
  44. data/spec/cassettes/Spree_Order/_refresh_shipment_rates/create_shipping_methods_for_the_rates.yml +269 -0
  45. data/spec/cassettes/Spree_Shipment/_buys_a_shipping_rate_after_transitioning_to_ship.yml +403 -0
  46. data/spec/cassettes/Spree_Shipment/_easypost_shipment/when_it_is_a_new_shipment/behaves_like_an_easypost_shipment/is_an_EasyPost_Shipment_object.yml +271 -0
  47. data/spec/cassettes/Spree_Shipment/_easypost_shipment/when_it_is_a_new_shipment/calls_the_api.yml +200 -0
  48. data/spec/cassettes/Spree_Shipment/_easypost_shipment/when_it_is_an_existing_shipment/behaves_like_an_easypost_shipment/is_an_EasyPost_Shipment_object.yml +334 -0
  49. data/spec/cassettes/Spree_Shipment/_easypost_shipment/when_it_is_an_existing_shipment/loads_the_existing_shipment.yml +271 -0
  50. data/spec/cassettes/Spree_StockLocation/_easypost_address/has_the_correct_attributes.yml +69 -0
  51. data/spec/cassettes/Spree_StockLocation/_easypost_address/is_an_EasyPost_Address_object.yml +69 -0
  52. data/spec/cassettes/Spree_Stock_Estimator/_shipping_rates/when_rates_are_found/when_shipping_methods_dont_exist/creates_new_shipping_methods.yml +269 -0
  53. data/spec/cassettes/Spree_Stock_Estimator/_shipping_rates/when_rates_are_found/when_shipping_methods_dont_exist/is_empty.yml +269 -0
  54. data/spec/cassettes/Spree_Stock_Estimator/_shipping_rates/when_rates_are_found/when_shipping_methods_exist/create_no_new_shipping_methods.yml +269 -0
  55. data/spec/cassettes/Spree_Stock_Estimator/_shipping_rates/when_rates_are_found/when_shipping_methods_exist/when_shipping_methods_are_front_end_visible/has_the_correct_costs.yml +269 -0
  56. data/spec/cassettes/Spree_Stock_Estimator/_shipping_rates/when_rates_are_found/when_shipping_methods_exist/when_shipping_methods_are_front_end_visible/has_the_correct_names.yml +269 -0
  57. data/spec/cassettes/Spree_Stock_Estimator/_shipping_rates/when_rates_are_found/when_shipping_methods_exist/when_shipping_methods_are_not_front_end_visible/is_empty.yml +269 -0
  58. data/spec/cassettes/Spree_Stock_Package/_easypost_parcel/has_the_correct_attributes.yml +68 -0
  59. data/spec/cassettes/Spree_Stock_Package/_easypost_parcel/is_an_EasyPost_Parcel_object.yml +68 -0
  60. data/spec/cassettes/Spree_Stock_Package/_easypost_shipment/calls_the_api.yml +200 -0
  61. data/spec/cassettes/Spree_Stock_Package/_easypost_shipment/is_an_EasyPost_Shipment_object.yml +269 -0
  62. data/spec/factories/spree_modification.rb +25 -0
  63. data/spec/models/solidus_easypost/return_authorization_spec.rb +50 -0
  64. data/spec/models/spree/address_spec.rb +31 -0
  65. data/spec/models/spree/order_spec.rb +31 -0
  66. data/spec/models/spree/shipment_spec.rb +80 -0
  67. data/spec/models/spree/shipping_rate_spec.rb +16 -0
  68. data/spec/models/spree/stock/estimator_spec.rb +80 -0
  69. data/spec/models/spree/stock/package_spec.rb +35 -0
  70. data/spec/models/spree/stock_location_spec.rb +31 -0
  71. data/spec/solidus_easypost_spec.rb +19 -0
  72. data/spec/spec_helper.rb +27 -0
  73. data/spec/support/easypost.rb +3 -0
  74. data/spec/support/factory_bot.rb +3 -0
  75. data/spec/support/shipping_method_helpers.rb +43 -0
  76. data/spec/support/vcr.rb +11 -0
  77. metadata +145 -170
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: bd2fbbbe3195c88f863d4d2c4ed379f31a76a46d
4
- data.tar.gz: c48efd0eab44b9dedc80d3ecbb3f616ee872c45a
2
+ SHA256:
3
+ metadata.gz: d31b734374e49e27bb7f182577cd2f1693b716299d8419e0d9b9d456bdfe9d50
4
+ data.tar.gz: 603ca168bb0c4a460af1fa498c7b5448316e4986cb285b5fe9eb442f9a3fa11d
5
5
  SHA512:
6
- metadata.gz: 533a53e70be4f0e6ab23325d2034e9fd1d0774b82f7e530b6c7bcad36feed79d47a147a485048e4f5ef925f18b7d3aa4ca61d83739a440fff10271406f1eda8b
7
- data.tar.gz: 88b11c8f12232b88079117f71ba9cc5cf797903d12bfdd5448a1ee92c527049549f965099ab08382a6a605056a627a8ec77974852d585633eaf343dcbc266c60
6
+ metadata.gz: 3b0c53d359fd325783c1e4646cfd8a8f97c392ae5ddfcba384c79b05efcf755fa7ed8f06c62fac7bfea0dc41471243327f6e62c916ba463efe1dccccc625c36b
7
+ data.tar.gz: 21cd54816073d19859d1077002237ebf4b2c302f29e7fc3cc0e1d567ddc96a78ce69dcea6d461e207b46e67697d37a9f2f8d4f25b49f431fbc668e45a156efea
@@ -0,0 +1,35 @@
1
+ version: 2.1
2
+
3
+ orbs:
4
+ # Always take the latest version of the orb, this allows us to
5
+ # run specs against Solidus supported versions only without the need
6
+ # to change this configuration every time a Solidus version is released
7
+ # or goes EOL.
8
+ solidusio_extensions: solidusio/extensions@volatile
9
+
10
+ jobs:
11
+ run-specs-with-postgres:
12
+ executor: solidusio_extensions/postgres
13
+ steps:
14
+ - solidusio_extensions/run-tests
15
+ run-specs-with-mysql:
16
+ executor: solidusio_extensions/mysql
17
+ steps:
18
+ - solidusio_extensions/run-tests
19
+
20
+ workflows:
21
+ "Run specs on supported Solidus versions":
22
+ jobs:
23
+ - run-specs-with-postgres
24
+ - run-specs-with-mysql
25
+ "Weekly run specs against master":
26
+ triggers:
27
+ - schedule:
28
+ cron: "0 0 * * 4" # every Thursday
29
+ filters:
30
+ branches:
31
+ only:
32
+ - master
33
+ jobs:
34
+ - run-specs-with-postgres
35
+ - run-specs-with-mysql
@@ -0,0 +1,5 @@
1
+ bump:
2
+ recurse: false
3
+ file: 'lib/solidus_easypost/version.rb'
4
+ message: Bump SolidusEasypost to %{version}
5
+ tag: true
@@ -0,0 +1,17 @@
1
+ # Number of days of inactivity before an issue becomes stale
2
+ daysUntilStale: 60
3
+ # Number of days of inactivity before a stale issue is closed
4
+ daysUntilClose: 7
5
+ # Issues with these labels will never be considered stale
6
+ exemptLabels:
7
+ - pinned
8
+ - security
9
+ # Label to use when marking an issue as stale
10
+ staleLabel: wontfix
11
+ # Comment to post when marking an issue as stale. Set to `false` to disable
12
+ markComment: >
13
+ This issue has been automatically marked as stale because it has not had
14
+ recent activity. It will be closed if no further activity occurs. Thank you
15
+ for your contributions.
16
+ # Comment to post when closing a stale issue. Set to `false` to disable
17
+ closeComment: false
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ \#*
3
+ *~
4
+ .#*
5
+ .DS_Store
6
+ .idea
7
+ .project
8
+ .sass-cache
9
+ coverage
10
+ Gemfile.lock
11
+ tmp
12
+ nbproject
13
+ pkg
14
+ *.swp
15
+ spec/dummy
16
+ spec/examples.txt
17
+ /sandbox
18
+ .rvmrc
19
+ .ruby-version
20
+ .ruby-gemset
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
@@ -0,0 +1,4 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
3
+ require:
4
+ - solidus_dev_support/rubocop
@@ -0,0 +1,71 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2020-07-24 11:17:48 +0200 using RuboCop version 0.76.0.
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
+ # Cop supports --auto-correct.
11
+ # Configuration parameters: EnforcedStyleAlignWith, AutoCorrect, Severity.
12
+ # SupportedStylesAlignWith: keyword, variable, start_of_line
13
+ Layout/EndAlignment:
14
+ Exclude:
15
+ - 'app/decorators/models/solidus_easypost/spree/address_decorator.rb'
16
+
17
+ # Offense count: 1
18
+ # Cop supports --auto-correct.
19
+ Lint/RedundantCopDisableDirective:
20
+ Exclude:
21
+ - 'lib/generators/solidus_easypost/install/install_generator.rb'
22
+
23
+ # Offense count: 1
24
+ # Cop supports --auto-correct.
25
+ RSpec/EmptyLineAfterFinalLet:
26
+ Exclude:
27
+ - 'spec/models/solidus_easypost/return_authorization_spec.rb'
28
+
29
+ # Offense count: 3
30
+ # Configuration parameters: .
31
+ # SupportedStyles: have_received, receive
32
+ RSpec/MessageSpies:
33
+ EnforcedStyle: receive
34
+
35
+ # Offense count: 1
36
+ RSpec/MultipleExpectations:
37
+ Max: 3
38
+
39
+ # Offense count: 22
40
+ # Configuration parameters: IgnoreSharedExamples.
41
+ RSpec/NamedSubject:
42
+ Exclude:
43
+ - 'spec/models/solidus_easypost/return_authorization_spec.rb'
44
+ - 'spec/models/spree/address_spec.rb'
45
+ - 'spec/models/spree/shipment_spec.rb'
46
+ - 'spec/models/spree/shipping_rate_spec.rb'
47
+ - 'spec/models/spree/stock/estimator_spec.rb'
48
+ - 'spec/models/spree/stock/package_spec.rb'
49
+ - 'spec/models/spree/stock_location_spec.rb'
50
+
51
+ # Offense count: 4
52
+ RSpec/NestedGroups:
53
+ Max: 5
54
+
55
+ # Offense count: 2
56
+ RSpec/ScatteredSetup:
57
+ Exclude:
58
+ - 'spec/models/solidus_easypost/return_authorization_spec.rb'
59
+
60
+ # Offense count: 1
61
+ # Configuration parameters: IgnoreNameless, IgnoreSymbolicNames.
62
+ RSpec/VerifiedDoubles:
63
+ Exclude:
64
+ - 'spec/models/spree/stock/estimator_spec.rb'
65
+
66
+ # Offense count: 1
67
+ # Cop supports --auto-correct.
68
+ # Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
69
+ # URISchemes: http, https
70
+ Metrics/LineLength:
71
+ Max: 137
data/Gemfile ADDED
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
5
+
6
+ branch = ENV.fetch('SOLIDUS_BRANCH', 'master')
7
+ gem 'solidus', github: 'solidusio/solidus', branch: branch
8
+
9
+ # Needed to help Bundler figure out how to resolve dependencies,
10
+ # otherwise it takes forever to resolve them.
11
+ # See https://github.com/bundler/bundler/issues/6677
12
+ gem 'rails', '>0.a'
13
+
14
+ # Provides basic authentication functionality for testing parts of your engine
15
+ gem 'solidus_auth_devise'
16
+
17
+ case ENV['DB']
18
+ when 'mysql'
19
+ gem 'mysql2'
20
+ when 'postgresql'
21
+ gem 'pg'
22
+ else
23
+ gem 'sqlite3'
24
+ end
25
+
26
+ gemspec
27
+
28
+ # Use a local Gemfile to include development dependencies that might not be
29
+ # relevant for the project or for other contributors, e.g. pry-byebug.
30
+ #
31
+ # We use `send` instead of calling `eval_gemfile` to work around an issue with
32
+ # how Dependabot parses projects: https://github.com/dependabot/dependabot-core/issues/1658.
33
+ send(:eval_gemfile, 'Gemfile-local') if File.exist? 'Gemfile-local'
data/LICENSE ADDED
@@ -0,0 +1,26 @@
1
+ Copyright (c) 2020 Brendan Deere
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+ * Neither the name Solidus nor the names of its contributors may be used to
13
+ endorse or promote products derived from this software without specific
14
+ prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,104 @@
1
+ # solidus_easypost
2
+
3
+ [![CircleCI](https://circleci.com/gh/solidusio-contrib/solidus_easypost.svg?style=svg)](https://circleci.com/gh/solidusio-contrib/solidus_easypost)
4
+
5
+ This is an extension to integrate EasyPost with Solidus.
6
+
7
+ Due to how it works, you will not be able to use any other extension for shipping methods. Your own
8
+ shipping methods will not work, either. But the good thing is that you won't have to worry about
9
+ that, because EasyPost handles it all for you.
10
+
11
+ You will need to [sign up for an account](https://www.easypost.com/) to use this extension.
12
+
13
+ ## Installation
14
+
15
+ Add solidus_easypost to your Gemfile:
16
+
17
+ ```ruby
18
+ gem 'solidus_easypost'
19
+ ```
20
+
21
+ Bundle your dependencies and run the installation generator:
22
+
23
+ ```shell
24
+ bin/rails generate solidus_easypost:install
25
+ ```
26
+
27
+ Create an initializer at `config/initializers/solidus_easypost.rb`:
28
+
29
+ ```ruby
30
+ EasyPost.api_key = 'YOUR_API_KEY_HERE'
31
+ ```
32
+
33
+ ## Usage
34
+
35
+ This extension hijacks `Spree::Stock::Estimator#shipping_rates` to calculate shipping rates for your
36
+ orders. This call happens during the checkout process, once the order's address information has been
37
+ provided.
38
+
39
+ The extension also adds a callback to the `ship` event on the `Spree::Shipment` model, telling
40
+ EasyPost which rate was selected and "buying" that rate. This can be disabled by setting:
41
+
42
+ ```ruby
43
+ # config/initializers/solidus_easypost.rb
44
+ SolidusEasypost.configure do |config|
45
+ config.purchase_labels = false
46
+ end
47
+ ```
48
+
49
+ This gem will create shipping methods for each type of carrier/service for which it receives a rate
50
+ from the EasyPost API. These are set to `display_on: back_end` by default and must be set to
51
+ `front_end` or `both` before the rate will be visible on the delivery page of the checkout.
52
+
53
+ ## Development
54
+
55
+ ### Testing the extension
56
+
57
+ First bundle your dependencies, then run `bin/rake`. `bin/rake` will default to building the dummy
58
+ app if it does not exist, then it will run specs. The dummy app can be regenerated by using
59
+ `bin/rake extension:test_app`.
60
+
61
+ ```console
62
+ $ bin/rake
63
+ ```
64
+
65
+ To run [Rubocop](https://github.com/bbatsov/rubocop) static code analysis run
66
+
67
+ ```console
68
+ $ bundle exec rubocop
69
+ ```
70
+
71
+ When testing your application's integration with this extension you may use its factories.
72
+ Simply add this require statement to your spec_helper:
73
+
74
+ ```ruby
75
+ require 'solidus_easypost/factories'
76
+ ```
77
+
78
+ ### Running the sandbox
79
+
80
+ To run this extension in a sandboxed Solidus application, you can run `bin/sandbox`. The path for
81
+ the sandbox app is `./sandbox` and `bin/rails` will forward any Rails commands to
82
+ `sandbox/bin/rails`.
83
+
84
+ Here's an example:
85
+
86
+ ```console
87
+ $ bin/rails server
88
+ => Booting Puma
89
+ => Rails 6.0.2.1 application starting in development
90
+ * Listening on tcp://127.0.0.1:3000
91
+ Use Ctrl-C to stop
92
+ ```
93
+
94
+ ### Releasing new versions
95
+
96
+ Your new extension version can be released using `gem-release` like this:
97
+
98
+ ```console
99
+ $ bundle exec gem bump -v VERSION --tag --push --remote upstream && gem release
100
+ ```
101
+
102
+ ## License
103
+
104
+ Copyright (c) 2020 Brendan Deere, released under the New BSD License.
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'solidus_dev_support/rake_tasks'
4
+ SolidusDevSupport::RakeTasks.install
5
+
6
+ task default: 'extension:specs'
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusEasypost
4
+ module Spree
5
+ module AddressDecorator
6
+ def easypost_address
7
+ attributes = {
8
+ street1: address1,
9
+ street2: address2,
10
+ city: city,
11
+ zip: zipcode,
12
+ phone: phone
13
+ }
14
+
15
+ attributes[:company] = company if respond_to?(:company)
16
+ attributes[:name] = if respond_to?(:name)
17
+ name
18
+ elsif respond_to?(:full_name)
19
+ full_name
20
+ end
21
+ attributes[:state] = state ? state.abbr : state_name
22
+ attributes[:country] = country&.iso
23
+
24
+ ::EasyPost::Address.create attributes
25
+ end
26
+
27
+ ::Spree::Address.prepend self
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusEasypost
4
+ module Spree
5
+ module ShipmentDecorator
6
+ def self.prepended(mod)
7
+ mod.state_machine.before_transition(
8
+ to: :shipped,
9
+ do: :buy_easypost_rate,
10
+ if: -> { SolidusEasypost.configuration.purchase_labels }
11
+ )
12
+ end
13
+
14
+ def easypost_shipment
15
+ if selected_easy_post_shipment_id
16
+ @ep_shipment ||= ::EasyPost::Shipment.retrieve(selected_easy_post_shipment_id)
17
+ else
18
+ @ep_shipment = build_easypost_shipment
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def selected_easy_post_rate_id
25
+ selected_shipping_rate.easy_post_rate_id
26
+ end
27
+
28
+ def selected_easy_post_shipment_id
29
+ selected_shipping_rate.easy_post_shipment_id
30
+ end
31
+
32
+ def build_easypost_shipment
33
+ ::EasyPost::Shipment.create(
34
+ to_address: order.ship_address.easypost_address,
35
+ from_address: stock_location.easypost_address,
36
+ parcel: to_package.easypost_parcel
37
+ )
38
+ end
39
+
40
+ def buy_easypost_rate
41
+ rate = easypost_shipment.rates.find do |sr|
42
+ sr.id == selected_easy_post_rate_id
43
+ end
44
+
45
+ easypost_shipment.buy(rate)
46
+ self.tracking = easypost_shipment.tracking_code
47
+ end
48
+
49
+ ::Spree::Shipment.prepend self
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusEasypost
4
+ module Spree
5
+ module ShippingRateDecorator
6
+ def name
7
+ read_attribute(:name) || super
8
+ end
9
+
10
+ ::Spree::ShippingRate.prepend self
11
+ end
12
+ end
13
+ end