spree_core 4.1.5 → 4.2.0.beta

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 (86) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/spree/base_controller.rb +1 -0
  3. data/app/finders/spree/products/find.rb +46 -11
  4. data/app/helpers/spree/base_helper.rb +26 -3
  5. data/app/helpers/spree/mail_helper.rb +24 -0
  6. data/app/helpers/spree/products_helper.rb +15 -14
  7. data/app/mailers/spree/base_mailer.rb +17 -3
  8. data/app/mailers/spree/order_mailer.rb +11 -2
  9. data/app/mailers/spree/reimbursement_mailer.rb +4 -2
  10. data/app/mailers/spree/shipment_mailer.rb +4 -2
  11. data/app/models/concerns/spree/default_price.rb +2 -1
  12. data/app/models/concerns/spree/product_scopes.rb +2 -2
  13. data/app/models/concerns/spree/user_methods.rb +11 -5
  14. data/app/models/spree/app_configuration.rb +6 -0
  15. data/app/models/spree/line_item.rb +10 -1
  16. data/app/models/spree/option_type.rb +5 -1
  17. data/app/models/spree/order.rb +26 -5
  18. data/app/models/spree/price.rb +26 -2
  19. data/app/models/spree/product.rb +19 -9
  20. data/app/models/spree/promotion/actions/create_item_adjustments.rb +1 -1
  21. data/app/models/spree/promotion_handler/coupon.rb +1 -1
  22. data/app/models/spree/reimbursement.rb +2 -0
  23. data/app/models/spree/shipment.rb +2 -5
  24. data/app/models/spree/stock_location.rb +13 -2
  25. data/app/models/spree/store.rb +19 -2
  26. data/app/models/spree/taxon.rb +6 -0
  27. data/app/models/spree/variant.rb +29 -2
  28. data/app/presenters/spree/variant_presenter.rb +7 -0
  29. data/app/presenters/spree/variants/option_types_presenter.rb +1 -0
  30. data/app/services/spree/checkout/get_shipping_rates.rb +7 -10
  31. data/app/views/layouts/spree/base_mailer.html.erb +45 -40
  32. data/app/views/spree/order_mailer/cancel_email.html.erb +19 -25
  33. data/app/views/spree/order_mailer/cancel_email.text.erb +24 -2
  34. data/app/views/spree/order_mailer/confirm_email.html.erb +18 -65
  35. data/app/views/spree/order_mailer/confirm_email.text.erb +2 -1
  36. data/app/views/spree/order_mailer/store_owner_notification_email.html.erb +23 -0
  37. data/app/views/spree/order_mailer/store_owner_notification_email.text.erb +38 -0
  38. data/app/views/spree/reimbursement_mailer/reimbursement_email.html.erb +53 -58
  39. data/app/views/spree/reimbursement_mailer/reimbursement_email.text.erb +3 -1
  40. data/app/views/spree/shared/_base_mailer_footer.html.erb +6 -14
  41. data/app/views/spree/shared/_base_mailer_header.html.erb +12 -32
  42. data/app/views/spree/shared/_base_mailer_stylesheets.html.erb +293 -625
  43. data/app/views/spree/shared/_purchased_items_table.html.erb +60 -0
  44. data/app/views/spree/shared/purchased_items_table/_adjustment.html.erb +13 -0
  45. data/app/views/spree/shared/purchased_items_table/_line_item.html.erb +27 -0
  46. data/app/views/spree/shared/purchased_items_table/_subtotal.html.erb +13 -0
  47. data/app/views/spree/shared/purchased_items_table/_total.html.erb +13 -0
  48. data/app/views/spree/shipment_mailer/shipped_email.html.erb +31 -36
  49. data/app/views/spree/shipment_mailer/shipped_email.text.erb +2 -1
  50. data/config/initializers/assets.rb +1 -0
  51. data/config/locales/en.yml +113 -13
  52. data/db/default/spree/stores.rb +11 -10
  53. data/db/migrate/20140309033438_create_store_from_preferences.rb +1 -1
  54. data/db/migrate/20191017121054_add_supported_currencies_to_store.rb +10 -0
  55. data/db/migrate/20200102141311_add_social_to_spree_stores.rb +3 -0
  56. data/db/migrate/20200308210757_add_default_locale_to_spree_store.rb +7 -0
  57. data/db/migrate/20200310145140_add_customer_support_email_to_spree_store.rb +7 -0
  58. data/db/migrate/20200421095017_add_compare_at_amount_to_spree_prices.rb +7 -0
  59. data/db/migrate/20200423123001_add_default_country_id_to_spree_store.rb +9 -0
  60. data/db/migrate/20200430072209_add_footer_fields_to_spree_stores.rb +8 -0
  61. data/db/migrate/20200513154939_add_show_property_to_spree_product_properties.rb +5 -0
  62. data/db/migrate/20200607161221_add_store_owner_order_notification_delivered_to_spree_orders.rb +7 -0
  63. data/db/migrate/20200607161222_add_new_order_notifications_email_to_spree_stores.rb +7 -0
  64. data/db/migrate/20200826075557_add_unique_index_on_taxon_id_and_product_id_to_spree_products_taxons.rb +5 -0
  65. data/lib/generators/spree/install/templates/config/initializers/spree.rb +1 -0
  66. data/lib/generators/spree/install/templates/vendor/assets/javascripts/spree/backend/all.js +0 -2
  67. data/lib/generators/spree/install/templates/vendor/assets/javascripts/spree/frontend/all.js +0 -2
  68. data/lib/generators/spree/mailers_preview/mailers_preview_generator.rb +23 -0
  69. data/lib/generators/spree/mailers_preview/templates/mailers/previews/order_preview.rb +13 -0
  70. data/lib/generators/spree/mailers_preview/templates/mailers/previews/reimbursement_preview.rb +5 -0
  71. data/lib/generators/spree/mailers_preview/templates/mailers/previews/shipment_preview.rb +5 -0
  72. data/lib/generators/spree/mailers_preview/templates/mailers/previews/user_preview.rb +11 -0
  73. data/lib/spree/core.rb +1 -0
  74. data/lib/spree/core/controller_helpers/common.rb +1 -0
  75. data/lib/spree/core/controller_helpers/currency_helpers.rb +15 -0
  76. data/lib/spree/core/controller_helpers/store.rb +12 -1
  77. data/lib/spree/core/version.rb +1 -1
  78. data/lib/spree/permitted_attributes.rb +7 -4
  79. data/lib/spree/testing_support/authorization_helpers.rb +7 -4
  80. data/lib/spree/testing_support/factories/store_factory.rb +11 -8
  81. data/spree_core.gemspec +14 -8
  82. data/vendor/assets/javascripts/cleave.js +1669 -0
  83. metadata +43 -22
  84. data/app/views/spree/order_mailer/_adjustment.html.erb +0 -8
  85. data/app/views/spree/order_mailer/_subtotal.html.erb +0 -8
  86. data/app/views/spree/order_mailer/_total.html.erb +0 -8
@@ -57,7 +57,16 @@ module Spree
57
57
  end
58
58
 
59
59
  def update_price
60
- self.price = variant.price_including_vat_for(tax_zone: tax_zone)
60
+ if Spree::Config.allow_currency_change == true
61
+ currency_price = Spree::Price.where(
62
+ currency: order.currency,
63
+ variant_id: variant_id
64
+ ).first
65
+
66
+ self.price = currency_price.price_including_vat_for(tax_zone: tax_zone)
67
+ else
68
+ self.price = variant.price_including_vat_for(tax_zone: tax_zone)
69
+ end
61
70
  end
62
71
 
63
72
  def copy_tax_category
@@ -24,7 +24,11 @@ module Spree
24
24
  after_touch :touch_all_products
25
25
 
26
26
  def filter_param
27
- presentation.titleize.delete(' ').downcase
27
+ name.titleize.delete(' ').downcase
28
+ end
29
+
30
+ def self.color
31
+ find_by(name: 'color')
28
32
  end
29
33
 
30
34
  private
@@ -297,15 +297,15 @@ module Spree
297
297
  def outstanding_balance
298
298
  if canceled?
299
299
  -1 * payment_total
300
- elsif refunds.exists?
301
- # If refund has happened add it back to total to prevent balance_due payment state
302
- # See: https://github.com/spree/spree/issues/6229 & https://github.com/spree/spree/issues/8136
303
- total - (payment_total + refunds.sum(:amount))
304
300
  else
305
- total - payment_total
301
+ total - (payment_total + reimbursement_paid_total)
306
302
  end
307
303
  end
308
304
 
305
+ def reimbursement_paid_total
306
+ reimbursements.sum(&:paid_amount)
307
+ end
308
+
309
309
  def outstanding_balance?
310
310
  outstanding_balance != 0
311
311
  end
@@ -351,6 +351,8 @@ module Spree
351
351
 
352
352
  deliver_order_confirmation_email unless confirmation_delivered?
353
353
 
354
+ deliver_store_owner_order_notification_email if deliver_store_owner_order_notification_email?
355
+
354
356
  consider_risk
355
357
  end
356
358
 
@@ -641,6 +643,13 @@ module Spree
641
643
  sum(:amount)
642
644
  end
643
645
 
646
+ def has_free_shipping?
647
+ promotions.
648
+ joins(:promotion_actions).
649
+ where(spree_promotion_actions: { type: 'Spree::Promotion::Actions::FreeShipping' }).
650
+ exists?
651
+ end
652
+
644
653
  private
645
654
 
646
655
  def link_by_email
@@ -706,5 +715,17 @@ module Spree
706
715
  def credit_card_nil_payment?(attributes)
707
716
  payments.store_credits.present? && attributes[:amount].to_f.zero?
708
717
  end
718
+
719
+ # Returns true if:
720
+ # 1. an email address is set for new order notifications AND
721
+ # 2. no notification for this order has been sent yet.
722
+ def deliver_store_owner_order_notification_email?
723
+ store.new_order_notifications_email.present? && !store_owner_notification_delivered?
724
+ end
725
+
726
+ def deliver_store_owner_order_notification_email
727
+ OrderMailer.store_owner_notification_email(id).deliver_later
728
+ update_column(:store_owner_notification_delivered, true)
729
+ end
709
730
  end
710
731
  end
@@ -15,10 +15,16 @@ module Spree
15
15
  less_than_or_equal_to: MAXIMUM_AMOUNT
16
16
  }
17
17
 
18
+ validates :compare_at_amount, allow_nil: true, numericality: {
19
+ greater_than_or_equal_to: 0,
20
+ less_than_or_equal_to: MAXIMUM_AMOUNT
21
+ }
22
+
18
23
  extend DisplayMoney
19
- money_methods :amount, :price
24
+ money_methods :amount, :price, :compare_at_amount
25
+ alias display_compare_at_price display_compare_at_amount
20
26
 
21
- self.whitelisted_ransackable_attributes = ['amount']
27
+ self.whitelisted_ransackable_attributes = ['amount', 'compare_at_amount']
22
28
 
23
29
  def money
24
30
  Spree::Money.new(amount || 0, currency: currency)
@@ -28,17 +34,35 @@ module Spree
28
34
  self[:amount] = Spree::LocalizedNumber.parse(amount)
29
35
  end
30
36
 
37
+ def compare_at_money
38
+ Spree::Money.new(compare_at_amount || 0, currency: currency)
39
+ end
40
+
41
+ def compare_at_amount=(compare_at_amount)
42
+ self[:compare_at_amount] = Spree::LocalizedNumber.parse(compare_at_amount)
43
+ end
44
+
31
45
  alias_attribute :price, :amount
46
+ alias_attribute :compare_at_price, :compare_at_amount
32
47
 
33
48
  def price_including_vat_for(price_options)
34
49
  options = price_options.merge(tax_category: variant.tax_category)
35
50
  gross_amount(price, options)
36
51
  end
37
52
 
53
+ def compare_at_price_including_vat_for(price_options)
54
+ options = price_options.merge(tax_category: variant.tax_category)
55
+ gross_amount(compare_at_price, options)
56
+ end
57
+
38
58
  def display_price_including_vat_for(price_options)
39
59
  Spree::Money.new(price_including_vat_for(price_options), currency: currency)
40
60
  end
41
61
 
62
+ def display_compare_at_price_including_vat_for(price_options)
63
+ Spree::Money.new(compare_at_price_including_vat_for(price_options), currency: currency)
64
+ end
65
+
42
66
  # Remove variant default_scope `deleted_at: nil`
43
67
  def variant
44
68
  Spree::Variant.unscoped { super }
@@ -111,19 +111,19 @@ module Spree
111
111
 
112
112
  alias options product_option_types
113
113
 
114
- self.whitelisted_ransackable_associations = %w[stores variants_including_master master variants]
114
+ self.whitelisted_ransackable_associations = %w[taxons stores variants_including_master master variants]
115
115
  self.whitelisted_ransackable_attributes = %w[description name slug discontinue_on]
116
- self.whitelisted_ransackable_scopes = %w[not_discontinued]
116
+ self.whitelisted_ransackable_scopes = %w[not_discontinued search_by_name]
117
117
 
118
118
  [
119
119
  :sku, :price, :currency, :weight, :height, :width, :depth, :is_master,
120
- :cost_currency, :price_in, :amount_in, :cost_price
120
+ :cost_currency, :price_in, :amount_in, :cost_price, :compare_at_price
121
121
  ].each do |method_name|
122
122
  delegate method_name, :"#{method_name}=", to: :find_or_build_master
123
123
  end
124
124
 
125
125
  delegate :display_amount, :display_price, :has_default_price?,
126
- :images, to: :find_or_build_master
126
+ :display_compare_at_price, :images, to: :find_or_build_master
127
127
 
128
128
  alias master_images images
129
129
 
@@ -160,10 +160,8 @@ module Spree
160
160
  #
161
161
  # @return [Spree::Variant]
162
162
  def default_variant
163
- track_inventory = Spree::Config[:track_inventory_levels]
164
-
165
- Rails.cache.fetch("spree/default-variant/#{cache_key_with_version}/#{track_inventory}") do
166
- if track_inventory && variants.in_stock_or_backorderable.any?
163
+ Rails.cache.fetch(default_variant_cache_key) do
164
+ if Spree::Config[:track_inventory_levels] && variants.in_stock_or_backorderable.any?
167
165
  variants.in_stock_or_backorderable.first
168
166
  else
169
167
  has_variants? ? variants.first : master
@@ -252,6 +250,14 @@ module Spree
252
250
  where conditions.inject(:or)
253
251
  end
254
252
 
253
+ def self.search_by_name(query)
254
+ if defined?(SpreeGlobalize)
255
+ joins(:translations).order(:name).where("LOWER(#{Product::Translation.table_name}.name) LIKE LOWER(:query)", query: "%#{query}%").distinct
256
+ else
257
+ where("LOWER(#{Product.table_name}.name) LIKE LOWER(:query)", query: "%#{query}%")
258
+ end
259
+ end
260
+
255
261
  # Suitable for displaying only variants that has at least one option value.
256
262
  # There may be scenarios where an option type is removed and along with it
257
263
  # all option values. At that point all variants associated with only those
@@ -341,7 +347,11 @@ module Spree
341
347
  price: master.price
342
348
  )
343
349
  end
344
- throw(:abort) unless save
350
+ save
351
+ end
352
+
353
+ def default_variant_cache_key
354
+ "spree/default-variant/#{cache_key_with_version}/#{Spree::Config[:track_inventory_levels]}"
345
355
  end
346
356
 
347
357
  def ensure_master
@@ -23,7 +23,7 @@ module Spree
23
23
  order = line_item.order
24
24
 
25
25
  # Prevent negative order totals
26
- amounts << order.amount - order.adjustments.sum(:amount).abs if order.adjustments.any?
26
+ amounts << order.amount - order.adjustments.eligible.sum(:amount).abs if order.adjustments.eligible.any?
27
27
 
28
28
  amounts.min * -1
29
29
  end
@@ -28,7 +28,7 @@ module Spree
28
28
 
29
29
  if promotion.present?
30
30
  # Order promotion has to be destroyed before line item removing
31
- order.order_promotions.find_by!(promotion_id: promotion.id).destroy
31
+ order.order_promotions.where(promotion_id: promotion.id).destroy_all
32
32
 
33
33
  remove_promotion_adjustments(promotion)
34
34
  remove_promotion_line_items(promotion)
@@ -60,6 +60,8 @@ module Spree
60
60
  class_attribute :reimbursement_failure_hooks
61
61
  self.reimbursement_failure_hooks = []
62
62
 
63
+ delegate :store, :currency, to: :order
64
+
63
65
  state_machine :reimbursement_status, initial: :pending do
64
66
  event :errored do
65
67
  transition to: :errored, from: :pending
@@ -42,6 +42,8 @@ module Spree
42
42
  scope :reverse_chronological, -> { order(Arel.sql('coalesce(spree_shipments.shipped_at, spree_shipments.created_at) desc'), id: :desc) }
43
43
  scope :valid, -> { where.not(state: :canceled) }
44
44
 
45
+ delegate :store, :currency, to: :order
46
+
45
47
  # shipment state machine (see http://github.com/pluginaweek/state_machine/tree/master for details)
46
48
  state_machine initial: :pending, use_transactions: false do
47
49
  event :ready do
@@ -104,11 +106,6 @@ module Spree
104
106
  inventory_units.any?(&:backordered?)
105
107
  end
106
108
 
107
- # TODO: delegate currency to Order, order.currency is mandatory
108
- def currency
109
- order ? order.currency : Spree::Config[:currency]
110
- end
111
-
112
109
  # Determines the appropriate +state+ according to the following logic:
113
110
  #
114
111
  # pending unless order is complete and +order.payment_state+ is +paid+
@@ -106,8 +106,19 @@ module Spree
106
106
  private
107
107
 
108
108
  def create_stock_items
109
- Variant.includes(:product).find_each do |variant|
110
- propagate_variant(variant)
109
+ variants_scope = Spree::Variant
110
+ prepared_stock_items = variants_scope.ids.map do |variant_id|
111
+ Hash[
112
+ 'stock_location_id', id,
113
+ 'variant_id', variant_id,
114
+ 'backorderable', backorderable_default,
115
+ 'created_at', Time.current,
116
+ 'updated_at', Time.current
117
+ ]
118
+ end
119
+ if prepared_stock_items.any?
120
+ stock_items.insert_all(prepared_stock_items)
121
+ variants_scope.touch_all
111
122
  end
112
123
  end
113
124
 
@@ -2,12 +2,23 @@ module Spree
2
2
  class Store < Spree::Base
3
3
  has_many :orders, class_name: 'Spree::Order'
4
4
  has_many :payment_methods, class_name: 'Spree::PaymentMethod'
5
+ belongs_to :default_country, class_name: 'Spree::Country'
5
6
 
6
7
  with_options presence: true do
7
- validates :name, :url, :mail_from_address
8
- validates :default_currency
8
+ validates :name, :url, :mail_from_address, :default_currency, :code
9
9
  end
10
10
 
11
+ validates :code, uniqueness: true
12
+
13
+ if !ENV['SPREE_DISABLE_DB_CONNECTION'] &&
14
+ connected? &&
15
+ table_exists? &&
16
+ connection.column_exists?(:spree_stores, :new_order_notifications_email)
17
+ validates :new_order_notifications_email, email: { allow_blank: true }
18
+ end
19
+
20
+ has_one_attached :logo
21
+
11
22
  before_save :ensure_default_exists_and_is_unique
12
23
  before_destroy :validate_not_default
13
24
 
@@ -26,6 +37,12 @@ module Spree
26
37
  end
27
38
  end
28
39
 
40
+ def supported_currencies_list
41
+ (read_attribute(:supported_currencies).to_s.split(',') << default_currency).map(&:to_s).map do |code|
42
+ ::Money::Currency.find(code.strip)
43
+ end.uniq.compact
44
+ end
45
+
29
46
  private
30
47
 
31
48
  def ensure_default_exists_and_is_unique
@@ -74,6 +74,12 @@ module Spree
74
74
  ancestor_chain + name.to_s
75
75
  end
76
76
 
77
+ def cached_self_and_descendants_ids
78
+ Rails.cache.fetch("#{cache_key_with_version}/descendant-ids") do
79
+ self_and_descendants.ids
80
+ end
81
+ end
82
+
77
83
  # awesome_nested_set sorts by :lft and :rgt. This call re-inserts the child
78
84
  # node so that its resulting position matches the observable 0-indexed position.
79
85
  # ** Note ** no :position column needed - a_n_s doesn't handle the reordering if
@@ -48,7 +48,8 @@ module Spree
48
48
  validates :cost_price
49
49
  validates :price
50
50
  end
51
- validates :sku, uniqueness: { conditions: -> { where(deleted_at: nil) }, case_sensitive: false }, allow_blank: true
51
+ validates :sku, uniqueness: { conditions: -> { where(deleted_at: nil) }, case_sensitive: false },
52
+ allow_blank: true, unless: :disable_sku_validation?
52
53
 
53
54
  after_create :create_stock_items
54
55
  after_create :set_master_out_of_stock, unless: :is_master?
@@ -102,6 +103,20 @@ module Spree
102
103
 
103
104
  self.whitelisted_ransackable_associations = %w[option_values product prices default_price]
104
105
  self.whitelisted_ransackable_attributes = %w[weight sku]
106
+ self.whitelisted_ransackable_scopes = %i(product_name_or_sku_cont search_by_product_name_or_sku)
107
+
108
+ def self.product_name_or_sku_cont(query)
109
+ joins(:product).where("LOWER(#{Product.table_name}.name) LIKE LOWER(:query) OR LOWER(sku) LIKE LOWER(:query)", query: "%#{query}%")
110
+ end
111
+
112
+ def self.search_by_product_name_or_sku(query)
113
+ if defined?(SpreeGlobalize)
114
+ joins(product: :translations).where("LOWER(#{Product::Translation.table_name}.name) LIKE LOWER(:query) OR LOWER(sku) LIKE LOWER(:query)",
115
+ query: "%#{query}%")
116
+ else
117
+ product_name_or_sku_cont(query)
118
+ end
119
+ end
105
120
 
106
121
  def available?
107
122
  !discontinued? && product.available?
@@ -217,6 +232,10 @@ module Spree
217
232
  end.sum
218
233
  end
219
234
 
235
+ def compare_at_price
236
+ price_in(cost_currency).try(:compare_at_amount)
237
+ end
238
+
220
239
  def name_and_sku
221
240
  "#{name} - #{sku}"
222
241
  end
@@ -226,7 +245,11 @@ module Spree
226
245
  end
227
246
 
228
247
  def in_stock?
229
- Rails.cache.fetch(in_stock_cache_key) do
248
+ # Issue 10280
249
+ # Check if model responds to cache version and fall back to updated_at for older rails versions
250
+ # This makes sure a version is supplied when recyclable cache keys are disabled.
251
+ version = respond_to?(:cache_version) ? cache_version : updated_at.to_i
252
+ Rails.cache.fetch(in_stock_cache_key, version: version) do
230
253
  total_on_hand > 0
231
254
  end
232
255
  end
@@ -319,5 +342,9 @@ module Spree
319
342
  def clear_in_stock_cache
320
343
  Rails.cache.delete(in_stock_cache_key)
321
344
  end
345
+
346
+ def disable_sku_validation?
347
+ Spree::Config[:disable_sku_validation]
348
+ end
322
349
  end
323
350
  end
@@ -16,6 +16,9 @@ module Spree
16
16
  @variants.map do |variant|
17
17
  {
18
18
  display_price: display_price(variant),
19
+ price: variant.price_in(current_currency),
20
+ display_compare_at_price: display_compare_at_price(variant),
21
+ should_display_compare_at_price: should_display_compare_at_price(variant),
19
22
  is_product_available_in_currency: @is_product_available_in_currency,
20
23
  backorderable: backorderable?(variant),
21
24
  in_stock: in_stock?(variant),
@@ -71,5 +74,9 @@ module Spree
71
74
  purchasable: variant.purchasable?
72
75
  }
73
76
  end
77
+
78
+ def should_display_compare_at_price(variant)
79
+ variant.compare_at_price.present? && variant.compare_at_price > variant.price
80
+ end
74
81
  end
75
82
  end
@@ -76,6 +76,7 @@ module Spree
76
76
  id: option_value.id,
77
77
  position: option_value.position,
78
78
  presentation: option_value.presentation,
79
+ name: option_value.name,
79
80
  variant_id: option_value.variants.where(id: @variant_ids).order(:position).first.id,
80
81
  is_default: option_value == default_variant_data[:option_value]
81
82
  }
@@ -7,9 +7,7 @@ module Spree
7
7
  run :reload_order
8
8
  run :ensure_shipping_address
9
9
  run :ensure_line_items_present
10
- run :move_order_to_delivery_state
11
- run :generate_shipping_rates
12
- run :return_shipments
10
+ run :generate_or_return_shipping_rates
13
11
  end
14
12
 
15
13
  private
@@ -31,6 +29,11 @@ module Spree
31
29
  success(order: order)
32
30
  end
33
31
 
32
+ def generate_or_return_shipping_rates(order:)
33
+ generate_shipping_rates(order: order) if order.shipments.empty?
34
+ return_shipments(order: order)
35
+ end
36
+
34
37
  def generate_shipping_rates(order:)
35
38
  ApplicationRecord.transaction do
36
39
  order.create_proposed_shipments
@@ -42,13 +45,7 @@ module Spree
42
45
  end
43
46
 
44
47
  def return_shipments(order:)
45
- success(order.shipments.includes([shipping_rates: :shipping_method]))
46
- end
47
-
48
- def move_order_to_delivery_state(order:)
49
- Spree::Dependencies.checkout_next_service.constantize.call(order: order) until order.state == 'delivery'
50
-
51
- success(order: order)
48
+ success(order.reload.shipments.includes([shipping_rates: :shipping_method]))
52
49
  end
53
50
  end
54
51
  end