solidus_core 2.11.2 → 2.11.7

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.

Potentially problematic release.


This version of solidus_core might be problematic. Click here for more details.

Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/app/models/spree/address.rb +28 -5
  3. data/app/models/spree/base.rb +9 -2
  4. data/app/models/spree/calculator.rb +4 -4
  5. data/app/models/spree/calculator/free_shipping.rb +1 -0
  6. data/app/models/spree/calculator/percent_per_item.rb +2 -0
  7. data/app/models/spree/calculator/price_sack.rb +1 -0
  8. data/app/models/spree/order/payments.rb +2 -2
  9. data/app/models/spree/order_merger.rb +1 -1
  10. data/app/models/spree/payment.rb +10 -3
  11. data/app/models/spree/payment/cancellation.rb +3 -22
  12. data/app/models/spree/payment_source.rb +2 -2
  13. data/app/models/spree/product.rb +8 -2
  14. data/app/models/spree/product/scopes.rb +0 -1
  15. data/app/models/spree/shipping_method.rb +1 -1
  16. data/app/models/spree/stock/availability_validator.rb +2 -2
  17. data/app/models/spree/stock/inventory_validator.rb +2 -2
  18. data/app/models/spree/taxon/active_storage_attachment.rb +1 -2
  19. data/app/models/spree/taxon/paperclip_attachment.rb +1 -0
  20. data/db/migrate/20180416083007_add_apply_to_all_to_variant_property_rule.rb +1 -1
  21. data/db/migrate/20210122110141_add_name_to_spree_addresses.rb +13 -0
  22. data/lib/generators/spree/dummy/templates/rails/test.rb +4 -1
  23. data/lib/spree/app_configuration.rb +1 -1
  24. data/lib/spree/core.rb +1 -4
  25. data/lib/spree/core/engine.rb +7 -8
  26. data/lib/spree/core/version.rb +1 -1
  27. data/lib/spree/permitted_attributes.rb +5 -5
  28. data/lib/spree/testing_support.rb +31 -0
  29. data/lib/spree/testing_support/dummy_app.rb +4 -2
  30. data/lib/spree/testing_support/dummy_app/mailer_previews/test_mailer_preview.rb +4 -0
  31. data/lib/spree/testing_support/factories.rb +8 -4
  32. data/lib/spree/testing_support/factories/address_factory.rb +6 -2
  33. data/lib/spree/testing_support/factories/adjustment_factory.rb +10 -5
  34. data/lib/spree/testing_support/factories/adjustment_reason_factory.rb +5 -0
  35. data/lib/spree/testing_support/factories/calculator_factory.rb +5 -0
  36. data/lib/spree/testing_support/factories/carton_factory.rb +7 -2
  37. data/lib/spree/testing_support/factories/country_factory.rb +5 -0
  38. data/lib/spree/testing_support/factories/credit_card_factory.rb +5 -0
  39. data/lib/spree/testing_support/factories/customer_return_factory.rb +8 -3
  40. data/lib/spree/testing_support/factories/image_factory.rb +5 -0
  41. data/lib/spree/testing_support/factories/inventory_unit_factory.rb +9 -4
  42. data/lib/spree/testing_support/factories/line_item_factory.rb +7 -2
  43. data/lib/spree/testing_support/factories/option_type_factory.rb +8 -0
  44. data/lib/spree/testing_support/factories/option_value_factory.rb +5 -0
  45. data/lib/spree/testing_support/factories/order_factory.rb +11 -6
  46. data/lib/spree/testing_support/factories/order_promotion_factory.rb +7 -2
  47. data/lib/spree/testing_support/factories/payment_factory.rb +9 -4
  48. data/lib/spree/testing_support/factories/payment_method_factory.rb +5 -0
  49. data/lib/spree/testing_support/factories/price_factory.rb +6 -1
  50. data/lib/spree/testing_support/factories/product_factory.rb +10 -5
  51. data/lib/spree/testing_support/factories/product_option_type_factory.rb +7 -2
  52. data/lib/spree/testing_support/factories/product_property_factory.rb +7 -2
  53. data/lib/spree/testing_support/factories/promotion_category_factory.rb +5 -0
  54. data/lib/spree/testing_support/factories/promotion_code_factory.rb +7 -2
  55. data/lib/spree/testing_support/factories/promotion_factory.rb +7 -2
  56. data/lib/spree/testing_support/factories/property_factory.rb +5 -0
  57. data/lib/spree/testing_support/factories/refund_factory.rb +7 -2
  58. data/lib/spree/testing_support/factories/refund_reason_factory.rb +5 -0
  59. data/lib/spree/testing_support/factories/reimbursement_factory.rb +6 -1
  60. data/lib/spree/testing_support/factories/reimbursement_type_factory.rb +5 -0
  61. data/lib/spree/testing_support/factories/return_authorization_factory.rb +8 -3
  62. data/lib/spree/testing_support/factories/return_item_factory.rb +8 -3
  63. data/lib/spree/testing_support/factories/return_reason_factory.rb +5 -0
  64. data/lib/spree/testing_support/factories/role_factory.rb +5 -0
  65. data/lib/spree/testing_support/factories/shipment_factory.rb +9 -3
  66. data/lib/spree/testing_support/factories/shipping_category_factory.rb +5 -0
  67. data/lib/spree/testing_support/factories/shipping_method_factory.rb +8 -3
  68. data/lib/spree/testing_support/factories/shipping_rate_factory.rb +7 -2
  69. data/lib/spree/testing_support/factories/state_factory.rb +7 -1
  70. data/lib/spree/testing_support/factories/stock_item_factory.rb +7 -2
  71. data/lib/spree/testing_support/factories/stock_location_factory.rb +8 -3
  72. data/lib/spree/testing_support/factories/stock_movement_factory.rb +6 -1
  73. data/lib/spree/testing_support/factories/stock_package_factory.rb +7 -2
  74. data/lib/spree/testing_support/factories/store_credit_category_factory.rb +5 -0
  75. data/lib/spree/testing_support/factories/store_credit_event_factory.rb +7 -2
  76. data/lib/spree/testing_support/factories/store_credit_factory.rb +8 -3
  77. data/lib/spree/testing_support/factories/store_credit_reason_factory.rb +5 -0
  78. data/lib/spree/testing_support/factories/store_credit_type_factory.rb +5 -0
  79. data/lib/spree/testing_support/factories/store_factory.rb +6 -1
  80. data/lib/spree/testing_support/factories/tax_category_factory.rb +7 -1
  81. data/lib/spree/testing_support/factories/tax_rate_factory.rb +8 -3
  82. data/lib/spree/testing_support/factories/taxon_factory.rb +6 -1
  83. data/lib/spree/testing_support/factories/taxonomy_factory.rb +5 -0
  84. data/lib/spree/testing_support/factories/user_factory.rb +8 -3
  85. data/lib/spree/testing_support/factories/variant_factory.rb +9 -4
  86. data/lib/spree/testing_support/factories/variant_property_rule_condition_factory.rb +7 -2
  87. data/lib/spree/testing_support/factories/variant_property_rule_factory.rb +8 -3
  88. data/lib/spree/testing_support/factories/variant_property_rule_value_factory.rb +7 -2
  89. data/lib/spree/testing_support/factories/zone_factory.rb +7 -2
  90. data/lib/spree/testing_support/factory_bot.rb +68 -0
  91. data/lib/spree/testing_support/order_walkthrough.rb +10 -10
  92. data/lib/spree/testing_support/sequences.rb +4 -1
  93. data/{app/models → lib}/spree/user_class_handle.rb +0 -0
  94. data/lib/tasks/email.rake +3 -2
  95. data/lib/tasks/migrations/migrate_address_names.rake +158 -0
  96. data/lib/tasks/migrations/migrate_default_billing_addresses_to_address_book.rake +38 -0
  97. data/lib/tasks/upgrade.rake +13 -0
  98. data/solidus_core.gemspec +24 -2
  99. metadata +48 -23
  100. data/lib/spree/awesome_nested_set_override.rb +0 -44
@@ -1,8 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spree/testing_support/sequences'
4
- require 'spree/testing_support/factories/role_factory'
5
- require 'spree/testing_support/factories/address_factory'
3
+ require 'spree/testing_support/factory_bot'
4
+ Spree::TestingSupport::FactoryBot.when_cherry_picked do
5
+ Spree::TestingSupport::FactoryBot.deprecate_cherry_picking
6
+
7
+ require 'spree/testing_support/sequences'
8
+ require 'spree/testing_support/factories/role_factory'
9
+ require 'spree/testing_support/factories/address_factory'
10
+ end
6
11
 
7
12
  FactoryBot.define do
8
13
  factory :user, class: Spree::UserClassHandle.new do
@@ -1,9 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spree/testing_support/sequences'
4
- require 'spree/testing_support/factories/option_value_factory'
5
- require 'spree/testing_support/factories/option_type_factory'
6
- require 'spree/testing_support/factories/product_factory'
3
+ require 'spree/testing_support/factory_bot'
4
+ Spree::TestingSupport::FactoryBot.when_cherry_picked do
5
+ Spree::TestingSupport::FactoryBot.deprecate_cherry_picking
6
+
7
+ require 'spree/testing_support/sequences'
8
+ require 'spree/testing_support/factories/option_value_factory'
9
+ require 'spree/testing_support/factories/option_type_factory'
10
+ require 'spree/testing_support/factories/product_factory'
11
+ end
7
12
 
8
13
  FactoryBot.define do
9
14
  sequence(:random_float) { BigDecimal("#{rand(200)}.#{rand(99)}") }
@@ -1,7 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spree/testing_support/factories/option_value_factory'
4
- require 'spree/testing_support/factories/variant_property_rule_factory'
3
+ require 'spree/testing_support/factory_bot'
4
+ Spree::TestingSupport::FactoryBot.when_cherry_picked do
5
+ Spree::TestingSupport::FactoryBot.deprecate_cherry_picking
6
+
7
+ require 'spree/testing_support/factories/option_value_factory'
8
+ require 'spree/testing_support/factories/variant_property_rule_factory'
9
+ end
5
10
 
6
11
  FactoryBot.define do
7
12
  factory :variant_property_rule_condition, class: 'Spree::VariantPropertyRuleCondition' do
@@ -1,8 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spree/testing_support/factories/product_factory'
4
- require 'spree/testing_support/factories/property_factory'
5
- require 'spree/testing_support/factories/option_value_factory'
3
+ require 'spree/testing_support/factory_bot'
4
+ Spree::TestingSupport::FactoryBot.when_cherry_picked do
5
+ Spree::TestingSupport::FactoryBot.deprecate_cherry_picking
6
+
7
+ require 'spree/testing_support/factories/product_factory'
8
+ require 'spree/testing_support/factories/property_factory'
9
+ require 'spree/testing_support/factories/option_value_factory'
10
+ end
6
11
 
7
12
  FactoryBot.define do
8
13
  factory :variant_property_rule, class: 'Spree::VariantPropertyRule' do
@@ -1,7 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spree/testing_support/factories/variant_property_rule_factory'
4
- require 'spree/testing_support/factories/property_factory'
3
+ require 'spree/testing_support/factory_bot'
4
+ Spree::TestingSupport::FactoryBot.when_cherry_picked do
5
+ Spree::TestingSupport::FactoryBot.deprecate_cherry_picking
6
+
7
+ require 'spree/testing_support/factories/variant_property_rule_factory'
8
+ require 'spree/testing_support/factories/property_factory'
9
+ end
5
10
 
6
11
  FactoryBot.define do
7
12
  factory :variant_property_rule_value, class: 'Spree::VariantPropertyRuleValue' do
@@ -1,7 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spree/testing_support/sequences'
4
- require 'spree/testing_support/factories/country_factory'
3
+ require 'spree/testing_support/factory_bot'
4
+ Spree::TestingSupport::FactoryBot.when_cherry_picked do
5
+ Spree::TestingSupport::FactoryBot.deprecate_cherry_picking
6
+
7
+ require 'spree/testing_support/sequences'
8
+ require 'spree/testing_support/factories/country_factory'
9
+ end
5
10
 
6
11
  FactoryBot.define do
7
12
  factory :global_zone, class: 'Spree::Zone' do
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "factory_bot"
4
+ begin
5
+ require "factory_bot_rails"
6
+ rescue LoadError
7
+ end
8
+
9
+ module Spree
10
+ module TestingSupport
11
+ module FactoryBot
12
+ SEQUENCES = ["#{::Spree::Core::Engine.root}/lib/spree/testing_support/sequences.rb"]
13
+ FACTORIES = Dir["#{::Spree::Core::Engine.root}/lib/spree/testing_support/factories/**/*_factory.rb"].sort
14
+ PATHS = SEQUENCES + FACTORIES
15
+
16
+ def self.definition_file_paths
17
+ @paths ||= PATHS.map { |path| path.sub(/.rb\z/, '') }
18
+ end
19
+
20
+ def self.when_cherry_picked
21
+ callsites = caller
22
+
23
+ # All good if the factory is being loaded by FactoryBot or from `testing_support/factories.rb`.
24
+ return if callsites.find do |line|
25
+ line.include?("/factory_bot/find_definitions.rb") ||
26
+ line.include?("/spree/testing_support/factories.rb")
27
+ end
28
+
29
+ yield
30
+ end
31
+
32
+ def self.deprecate_cherry_picking
33
+ callsites = caller
34
+ core_root = Spree::Core::Engine.root.to_s
35
+ index = callsites.index { |line| !line.start_with? core_root }
36
+
37
+ Spree::Deprecation.warn(
38
+ "Please do not cherry-pick factories, this is not well supported by FactoryBot, " \
39
+ 'follow the changelog instructions on how to migrate your current setup.',
40
+ callsites[index..-1]
41
+ )
42
+ end
43
+
44
+ def self.check_version
45
+ require "factory_bot/version"
46
+
47
+ requirement = Gem::Requirement.new("~> 4.8")
48
+ version = Gem::Version.new(::FactoryBot::VERSION)
49
+
50
+ unless requirement.satisfied_by? version
51
+ Spree::Deprecation.warn(
52
+ "Please be aware that the supported version of FactoryBot is #{requirement}, " \
53
+ "using version #{version} could lead to factory loading issues.", caller(2)
54
+ )
55
+ end
56
+ end
57
+
58
+ def self.add_definitions!
59
+ ::FactoryBot.definition_file_paths.unshift(*definition_file_paths).uniq!
60
+ end
61
+
62
+ def self.add_paths_and_load!
63
+ add_definitions!
64
+ ::FactoryBot.reload
65
+ end
66
+ end
67
+ end
68
+ end
@@ -9,22 +9,22 @@ module Spree
9
9
 
10
10
  def up_to(state)
11
11
  # Need to create a valid zone too...
12
- @zone = FactoryBot.create(:zone)
13
- @country = FactoryBot.create(:country)
14
- @state = FactoryBot.create(:state, country: @country)
12
+ @zone = ::FactoryBot.create(:zone)
13
+ @country = ::FactoryBot.create(:country)
14
+ @state = ::FactoryBot.create(:state, country: @country)
15
15
 
16
16
  @zone.members << Spree::ZoneMember.create(zoneable: @country)
17
17
 
18
18
  # A shipping method must exist for rates to be displayed on checkout page
19
- FactoryBot.create(:shipping_method, zones: [@zone]).tap do |sm|
19
+ ::FactoryBot.create(:shipping_method, zones: [@zone]).tap do |sm|
20
20
  sm.calculator.preferred_amount = 10
21
21
  sm.calculator.preferred_currency = Spree::Config[:currency]
22
22
  sm.calculator.save
23
23
  end
24
24
 
25
25
  order = Spree::Order.create!(
26
- email: "spree@example.com",
27
- store: Spree::Store.first || FactoryBot.create(:store)
26
+ email: "solidus@example.com",
27
+ store: Spree::Store.first || ::FactoryBot.create(:store)
28
28
  )
29
29
  add_line_item!(order)
30
30
  order.next!
@@ -46,13 +46,13 @@ module Spree
46
46
  private
47
47
 
48
48
  def add_line_item!(order)
49
- FactoryBot.create(:line_item, order: order)
49
+ ::FactoryBot.create(:line_item, order: order)
50
50
  order.reload
51
51
  end
52
52
 
53
53
  def address(order)
54
- order.bill_address = FactoryBot.create(:address, country: @country, state: @state)
55
- order.ship_address = FactoryBot.create(:address, country: @country, state: @state)
54
+ order.bill_address = ::FactoryBot.create(:address, country: @country, state: @state)
55
+ order.ship_address = ::FactoryBot.create(:address, country: @country, state: @state)
56
56
  order.next!
57
57
  end
58
58
 
@@ -61,7 +61,7 @@ module Spree
61
61
  end
62
62
 
63
63
  def payment(order)
64
- credit_card = FactoryBot.create(:credit_card)
64
+ credit_card = ::FactoryBot.create(:credit_card)
65
65
  order.payments.create!(payment_method: credit_card.payment_method, amount: order.total, source: credit_card)
66
66
  # TODO: maybe look at some way of making this payment_state change automatic
67
67
  order.payment_state = 'paid'
@@ -1,6 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'factory_bot'
3
+ require 'spree/testing_support/factory_bot'
4
+ Spree::TestingSupport::FactoryBot.when_cherry_picked do
5
+ Spree::TestingSupport::FactoryBot.deprecate_cherry_picking
6
+ end
4
7
 
5
8
  FactoryBot.define do
6
9
  sequence(:sku) { |n| "SKU-#{n}" }
File without changes
data/lib/tasks/email.rake CHANGED
@@ -1,11 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  namespace :email do
4
- desc 'Sends test email to specified address - Example: EMAIL=spree@example.com bundle exec rake email:test'
4
+ desc 'Sends test email to specified address - Example: EMAIL=solidus@example.com bundle exec rake email:test'
5
5
  task test: :environment do
6
6
  Spree::Deprecation.warn("rake email:test has been deprecated and will be removed with Solidus 3.0")
7
7
 
8
- raise ArgumentError, "Must pass EMAIL environment variable. Example: EMAIL=spree@example.com bundle exec rake email:test" unless ENV['EMAIL'].present?
8
+ raise ArgumentError, "Must pass EMAIL environment variable. Example: EMAIL=solidus@example.com bundle exec rake email:test" if ENV['EMAIL'].blank?
9
+
9
10
  Spree::TestMailer.test_email(ENV['EMAIL']).deliver!
10
11
  end
11
12
  end
@@ -0,0 +1,158 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'thor'
4
+
5
+ namespace :solidus do
6
+ namespace :migrations do
7
+ namespace :migrate_address_names do
8
+ desc 'Backfills Spree::Address name attribute using firstname and lastname
9
+ concatenation in order to retain historical data when upgrading to new
10
+ address name format'
11
+ task up: :environment do
12
+ puts "Combining addresses' firstname and lastname into name ... "
13
+ class Spree::AddressForMigration < ApplicationRecord
14
+ self.table_name = 'spree_addresses'
15
+ end
16
+
17
+ records = Spree::AddressForMigration.unscoped.where(name: [nil, ''])
18
+ count = records.count
19
+ connection = ActiveRecord::Base.connection
20
+ adapter_name = connection.adapter_name.downcase
21
+ shell = Thor::Shell::Basic.new
22
+ puts " Your DB contains #{count} addresses that may be affected by this task."
23
+ # `trim` is not needed for pg or mysql when using `concat_ws`:
24
+ # select concat_ws('joinstring', 'foo', null);
25
+ # concat_ws
26
+ # -----------
27
+ # foo
28
+ # (1 row)
29
+ # select concat_ws('joinstring', 'foo', null) = trim(concat_ws('joinstring', 'foo', null));
30
+ # ?column?
31
+ # ----------
32
+ # t
33
+ # (1 row)
34
+ unless count.zero?
35
+ concat_statement = begin
36
+ case adapter_name
37
+ when /sqlite/
38
+ "name = TRIM(COALESCE(firstname, '') || ' ' || COALESCE(lastname, ''))"
39
+ when /postgres/, /mysql2/
40
+ "name = CONCAT_WS(' ', firstname, lastname)"
41
+ else
42
+ abort " No migration path available for adapter #{adapter_name}. Please write your own."
43
+ end
44
+ end
45
+
46
+ # The batch size should be limited to avoid locking the table records for too long. These are
47
+ # the numbers I got with 1_000_000 records in `spree_addresses`, all with different name and
48
+ # surname, with postgresql:
49
+ #
50
+ # Updating 1000000 records in one shot
51
+ # batch took 178 seconds
52
+ #
53
+ # Updating 1000000 addresses in batches of 200000
54
+ # batch took 36 seconds
55
+ # batch took 31 seconds
56
+ # batch took 31 seconds
57
+ # batch took 31 seconds
58
+ # batch took 30 seconds
59
+ #
60
+ # Updating 1000000 addresses in batches of 150000
61
+ # batch took 29 seconds
62
+ # batch took 27 seconds
63
+ # batch took 27 seconds
64
+ # batch took 27 seconds
65
+ # batch took 26 seconds
66
+ # batch took 26 seconds
67
+ # batch took 19 seconds
68
+ #
69
+ # Updating 1000000 addresses in batches of 100000
70
+ # batch took 17 seconds
71
+ # batch took 15 seconds
72
+ # batch took 17 seconds
73
+ # batch took 17 seconds
74
+ # batch took 17 seconds
75
+ # batch took 17 seconds
76
+ # batch took 17 seconds
77
+ # batch took 17 seconds
78
+ # batch took 17 seconds
79
+ # batch took 17 seconds
80
+ #
81
+ # This is with mysql:
82
+ # Updating 1000000 records in one shot
83
+ # batch updated in 153 seconds
84
+ #
85
+ # Updating 1000000 records in batches of 200000, this may take a while...
86
+ # batch took 41 seconds
87
+ # batch took 37 seconds
88
+ # batch took 35 seconds
89
+ # batch took 28 seconds
90
+ # batch took 27 seconds
91
+ #
92
+ # Updating 1000000 records in batches of 150000, this may take a while...
93
+ # batch took 30 seconds
94
+ # batch took 29 seconds
95
+ # batch took 18 seconds
96
+ # batch took 18 seconds
97
+ # batch took 17 seconds
98
+ # batch took 29 seconds
99
+ # batch took 12 seconds
100
+ #
101
+ # Updating 1000000 records in batches of 100000, this may take a while...
102
+ # batch took 10 seconds
103
+ # batch took 11 seconds
104
+ # batch took 12 seconds
105
+ # batch took 13 seconds
106
+ # batch took 12 seconds
107
+ # batch took 12 seconds
108
+ # batch took 14 seconds
109
+ # batch took 19 seconds
110
+ # batch took 20 seconds
111
+ # batch took 21 seconds
112
+ #
113
+ # Please note that the migration will be much faster when there's no index
114
+ # on the `name` column. For example, with mysql each batch takes exactly
115
+ # the same time:
116
+ #
117
+ # Updating 1000000 records in batches of 200000, this may take a while...
118
+ # batch took 17 seconds
119
+ # batch took 17 seconds
120
+ # batch took 17 seconds
121
+ # batch took 16 seconds
122
+ # batch took 17 seconds
123
+ #
124
+ # So, if special need arise, one can drop the index added with migration
125
+ # 20210122110141_add_name_to_spree_addresses.rb and add the index later,
126
+ # in non blocking ways. For postgresql:
127
+ # add_index(:spree_addresses, :name, algorithm: :concurrently)
128
+ #
129
+ # For mysql 5.6:
130
+ # sql = "ALTER TABLE spree_addresses ADD INDEX index_spree_addresses_on_name (name), ALGORITHM=INPLACE, LOCK=NONE;"
131
+ # ActiveRecord::Base.connection.execute sql
132
+ #
133
+ puts ' Data migration will happen in batches. The default value is 100_000, which should take less than 20 seconds on mysql or postgresql.'
134
+ size = shell.ask(' Please enter a different batch size, or press return to confirm the default: ')
135
+ size = (size.presence || 100_000).to_i
136
+
137
+ abort " Invalid batch size number #{size}, please run the task again." unless size.positive?
138
+
139
+ batches_total = (count / size).ceil
140
+ puts " We're going to migrate #{count} records in #{batches_total} batches of #{size}."
141
+
142
+ answer = shell.ask(' Do you want to proceed?', limited_to: ['Y', 'N'], case_insensitive: true)
143
+ if answer == 'Y'
144
+ puts " Updating #{count} records in batches of #{size}, this may take a while..."
145
+
146
+ records.in_batches(of: size).each.with_index(1) do |batch, index|
147
+ now = Time.zone.now
148
+ batch.update_all(concat_statement)
149
+ puts " Batch #{index}/#{batches_total} done in #{(Time.zone.now - now).to_i} seconds."
150
+ end
151
+ else
152
+ puts " Database not migrated. Please, make sure to fill address's name field on your own."
153
+ end
154
+ end
155
+ end
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :solidus do
4
+ namespace :migrations do
5
+ namespace :migrate_default_billing_addresses_to_address_book do
6
+ task up: :environment do
7
+ print "Migrating default billing addresses to address book ... "
8
+ if Spree::UserAddress.where(default_billing: true).any?
9
+ Spree.user_class.joins(:bill_address).update_all(bill_address_id: nil) # rubocop:disable Rails/SkipsModelValidations
10
+ end
11
+ adapter_type = Spree::Base.connection.adapter_name.downcase.to_sym
12
+ if adapter_type == :mysql2
13
+ sql = <<~SQL
14
+ UPDATE spree_user_addresses
15
+ JOIN spree_users ON spree_user_addresses.user_id = spree_users.id
16
+ AND spree_user_addresses.address_id = spree_users.bill_address_id
17
+ SET spree_user_addresses.default_billing = true
18
+ SQL
19
+ else
20
+ sql = <<~SQL
21
+ UPDATE spree_user_addresses
22
+ SET default_billing = true
23
+ FROM spree_users
24
+ WHERE spree_user_addresses.address_id = spree_users.bill_address_id
25
+ AND spree_user_addresses.user_id = spree_users.id;
26
+ SQL
27
+ end
28
+ Spree::Base.connection.execute sql
29
+ puts "Success"
30
+ end
31
+
32
+ task down: :environment do
33
+ Spree::UserAddress.update_all(default_billing: false) # rubocop:disable Rails/SkipsModelValidations
34
+ puts "Rolled back default billing address migration to address book"
35
+ end
36
+ end
37
+ end
38
+ end