spree_core 5.4.0.rc5 → 5.4.0.rc6
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.
- checksums.yaml +4 -4
- data/app/mailers/spree/base_mailer.rb +2 -0
- data/app/models/concerns/spree/stores/markets.rb +4 -2
- data/app/models/spree/market.rb +1 -0
- data/app/models/spree/option_type.rb +11 -1
- data/app/models/spree/option_value.rb +8 -0
- data/app/models/spree/order.rb +21 -1
- data/app/models/spree/search_provider/meilisearch.rb +41 -8
- data/app/models/spree/stock_location.rb +1 -1
- data/app/presenters/spree/search_provider/product_presenter.rb +8 -13
- data/app/services/spree/cart/create.rb +1 -0
- data/app/services/spree/carts/create.rb +1 -0
- data/app/services/spree/carts/update.rb +21 -0
- data/app/services/spree/sample_data/loader.rb +18 -20
- data/app/services/spree/seeds/all.rb +22 -20
- data/config/locales/en.yml +11 -0
- data/db/migrate/20250217171018_create_action_text_video_embeds.rb +11 -0
- data/db/migrate/20260402000001_add_kind_to_spree_option_types.rb +13 -0
- data/db/migrate/20260402000002_add_color_code_to_spree_option_values.rb +5 -0
- data/db/migrate/20260403000000_add_market_to_spree_orders.rb +5 -0
- data/db/sample_data/metafield_definitions.rb +2 -2
- data/db/sample_data/options.rb +4 -0
- data/db/sample_data/orders.rb +2 -2
- data/db/sample_data/products.csv +125 -1083
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/permitted_attributes.rb +3 -3
- data/lib/spree/testing_support/factories/options_factory.rb +11 -0
- data/lib/tasks/markets.rake +5 -2
- data/lib/tasks/search.rake +3 -3
- data/lib/tasks/variants.rake +2 -2
- metadata +18 -7
- /data/lib/tasks/{images.rake → media.rake} +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 10b8425a8850b155fa6d2a2d6d452e016fd142d62849ce757e00b4b2db1efcdc
|
|
4
|
+
data.tar.gz: 38b6187ef6b92566261d617d65e3eb59d2e760eca6d3519390189a40858a62c3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 76058003b7c03e556c6f7d035fa6b1283688927ad6102cacd955932440e81054a8ace08032fc593545b897bdc321ca5d6ae2e720170468c9e64adee5b7083a53
|
|
7
|
+
data.tar.gz: 1783fc54faf9da589237ac09af8f665a2d145382eb6246911eecdfc2abdb26fce3d780e47f180fa6644a534164236232b4b30e3d8392c4fb869843405dfd2eaa
|
|
@@ -104,12 +104,14 @@ module Spree
|
|
|
104
104
|
end
|
|
105
105
|
end
|
|
106
106
|
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
# Returns true if the store has markets, false otherwise
|
|
108
|
+
# @return [Boolean]
|
|
109
109
|
def has_markets?
|
|
110
110
|
@has_markets ||= persisted? && (markets.loaded? ? markets.any? : markets.exists?)
|
|
111
111
|
end
|
|
112
112
|
|
|
113
|
+
private
|
|
114
|
+
|
|
113
115
|
def legacy_supported_currencies_list
|
|
114
116
|
([default_currency] + read_attribute(:supported_currencies).to_s.split(',')).uniq.map(&:to_s).map do |code|
|
|
115
117
|
::Money::Currency.find(code.strip)
|
data/app/models/spree/market.rb
CHANGED
|
@@ -13,6 +13,7 @@ module Spree
|
|
|
13
13
|
belongs_to :store, class_name: 'Spree::Store', touch: true
|
|
14
14
|
has_many :market_countries, class_name: 'Spree::MarketCountry', dependent: :destroy
|
|
15
15
|
has_many :countries, through: :market_countries, class_name: 'Spree::Country'
|
|
16
|
+
has_many :orders, class_name: 'Spree::Order', dependent: :nullify
|
|
16
17
|
|
|
17
18
|
#
|
|
18
19
|
# Validations
|
|
@@ -3,6 +3,7 @@ module Spree
|
|
|
3
3
|
has_prefix_id :opt # Spree-specific: option type
|
|
4
4
|
|
|
5
5
|
COLOR_NAMES = %w[color colour].freeze
|
|
6
|
+
KINDS = %w[dropdown color_swatch buttons].freeze
|
|
6
7
|
|
|
7
8
|
include Spree::ParameterizableName
|
|
8
9
|
include Spree::UniqueName
|
|
@@ -40,12 +41,14 @@ module Spree
|
|
|
40
41
|
# Validations
|
|
41
42
|
#
|
|
42
43
|
validates :presentation, presence: true
|
|
44
|
+
validates :kind, presence: true, inclusion: { in: KINDS }
|
|
43
45
|
|
|
44
46
|
#
|
|
45
47
|
# Scopes
|
|
46
48
|
#
|
|
47
49
|
default_scope { order(:position) }
|
|
48
50
|
scope :colors, -> { where(name: COLOR_NAMES) }
|
|
51
|
+
scope :color_swatches, -> { where(kind: 'color_swatch') }
|
|
49
52
|
scope :filterable, -> { where(filterable: true) }
|
|
50
53
|
|
|
51
54
|
#
|
|
@@ -72,8 +75,15 @@ module Spree
|
|
|
72
75
|
colors.first
|
|
73
76
|
end
|
|
74
77
|
|
|
78
|
+
def color_swatch?
|
|
79
|
+
kind == 'color_swatch'
|
|
80
|
+
end
|
|
81
|
+
|
|
75
82
|
def color?
|
|
76
|
-
|
|
83
|
+
Spree::Deprecation.warn(
|
|
84
|
+
'Spree::OptionType#color? is deprecated. Use #color_swatch? instead. Will be removed in Spree 6.0.'
|
|
85
|
+
)
|
|
86
|
+
color_swatch?
|
|
77
87
|
end
|
|
78
88
|
|
|
79
89
|
private
|
|
@@ -20,6 +20,11 @@ module Spree
|
|
|
20
20
|
acts_as_list scope: :option_type
|
|
21
21
|
self.whitelisted_ransackable_attributes = ['presentation']
|
|
22
22
|
|
|
23
|
+
#
|
|
24
|
+
# Attachments
|
|
25
|
+
#
|
|
26
|
+
has_one_attached :image
|
|
27
|
+
|
|
23
28
|
#
|
|
24
29
|
# Associations
|
|
25
30
|
#
|
|
@@ -39,6 +44,9 @@ module Spree
|
|
|
39
44
|
validates :presentation
|
|
40
45
|
end
|
|
41
46
|
|
|
47
|
+
validates :color_code, format: { with: /\A#[0-9A-Fa-f]{6}([0-9A-Fa-f]{2})?\z/, message: 'must be a valid hex color (e.g. #FF0000)' },
|
|
48
|
+
allow_blank: true
|
|
49
|
+
|
|
42
50
|
#
|
|
43
51
|
# Scopes
|
|
44
52
|
#
|
data/app/models/spree/order.rb
CHANGED
|
@@ -140,6 +140,7 @@ module Spree
|
|
|
140
140
|
alias_attribute :shipping_address_id, :ship_address_id
|
|
141
141
|
|
|
142
142
|
belongs_to :store, class_name: 'Spree::Store'
|
|
143
|
+
belongs_to :market, class_name: 'Spree::Market', optional: true
|
|
143
144
|
|
|
144
145
|
with_options dependent: :destroy do
|
|
145
146
|
has_many :state_changes, as: :stateful, class_name: 'Spree::StateChange'
|
|
@@ -181,6 +182,8 @@ module Spree
|
|
|
181
182
|
alias_attribute :fulfillment_status, :shipment_state
|
|
182
183
|
alias_attribute :payment_status, :payment_state
|
|
183
184
|
|
|
185
|
+
delegate :has_markets?, to: :store, prefix: true
|
|
186
|
+
|
|
184
187
|
accepts_nested_attributes_for :line_items
|
|
185
188
|
accepts_nested_attributes_for :bill_address
|
|
186
189
|
accepts_nested_attributes_for :ship_address
|
|
@@ -191,12 +194,14 @@ module Spree
|
|
|
191
194
|
|
|
192
195
|
# Needs to happen before save_permalink is called
|
|
193
196
|
before_validation :ensure_store_presence
|
|
197
|
+
before_validation :ensure_market_presence
|
|
194
198
|
before_validation :ensure_currency_presence
|
|
195
199
|
before_validation :ensure_locale_presence
|
|
200
|
+
before_validation :resolve_market_from_currency, if: -> { persisted? && currency_changed? && !skip_market_resolution }
|
|
196
201
|
|
|
197
202
|
before_validation :clone_billing_address, if: :use_billing?
|
|
198
203
|
before_validation :clone_shipping_address, if: :use_shipping?
|
|
199
|
-
attr_accessor :use_billing, :use_shipping
|
|
204
|
+
attr_accessor :use_billing, :use_shipping, :skip_market_resolution
|
|
200
205
|
|
|
201
206
|
before_create :link_by_email
|
|
202
207
|
before_update :ensure_updated_shipments, :homogenize_line_item_currencies, if: :currency_changed?
|
|
@@ -220,6 +225,7 @@ module Spree
|
|
|
220
225
|
validates :shipment_total, MONEY_VALIDATION
|
|
221
226
|
validates :promo_total, NEGATIVE_MONEY_VALIDATION
|
|
222
227
|
validates :total, MONEY_VALIDATION
|
|
228
|
+
validates :market, presence: true, if: :store_has_markets?
|
|
223
229
|
validate :currency_must_be_supported_by_store
|
|
224
230
|
validate :locale_must_be_supported_by_store
|
|
225
231
|
|
|
@@ -450,6 +456,10 @@ module Spree
|
|
|
450
456
|
self.store ||= Spree::Store.default
|
|
451
457
|
end
|
|
452
458
|
|
|
459
|
+
def ensure_market_presence
|
|
460
|
+
self.market ||= Spree::Current.market || store&.default_market
|
|
461
|
+
end
|
|
462
|
+
|
|
453
463
|
def allow_cancel?
|
|
454
464
|
return false if !completed? || canceled?
|
|
455
465
|
|
|
@@ -1050,6 +1060,16 @@ module Spree
|
|
|
1050
1060
|
end
|
|
1051
1061
|
end
|
|
1052
1062
|
|
|
1063
|
+
# When currency changes, auto-resolve the matching market.
|
|
1064
|
+
# Only applies when the store has markets configured.
|
|
1065
|
+
def resolve_market_from_currency
|
|
1066
|
+
return unless store_has_markets?
|
|
1067
|
+
return if market&.currency == currency
|
|
1068
|
+
|
|
1069
|
+
resolved = store.markets.find_by(currency: currency)
|
|
1070
|
+
self.market = resolved if resolved
|
|
1071
|
+
end
|
|
1072
|
+
|
|
1053
1073
|
def collect_payment_methods
|
|
1054
1074
|
Spree::Deprecation.warn('`Order#collect_payment_methods` is deprecated and will be removed in Spree 5.5. Use `collect_frontend_payment_methods` instead.')
|
|
1055
1075
|
|
|
@@ -103,9 +103,10 @@ module Spree
|
|
|
103
103
|
product_prefixed_ids = ms_result['hits'].map { |h| h['product_id'] }.uniq
|
|
104
104
|
raw_ids = product_prefixed_ids.filter_map { |pid| Spree::Product.decode_prefixed_id(pid) }
|
|
105
105
|
|
|
106
|
-
# Intersect with AR scope for security/visibility.
|
|
106
|
+
# Intersect with AR scope for security/visibility, preserving Meilisearch sort order.
|
|
107
107
|
products = if raw_ids.any?
|
|
108
|
-
scope.where(id: raw_ids).reorder(nil)
|
|
108
|
+
records = scope.where(id: raw_ids).reorder(nil).index_by(&:id)
|
|
109
|
+
raw_ids.filter_map { |id| records[id] }
|
|
109
110
|
else
|
|
110
111
|
scope.none
|
|
111
112
|
end
|
|
@@ -123,8 +124,9 @@ module Spree
|
|
|
123
124
|
end
|
|
124
125
|
|
|
125
126
|
def index(product)
|
|
127
|
+
ensure_index_settings_once!
|
|
126
128
|
documents = presenter_class.new(product, store).call
|
|
127
|
-
client.index(index_name).add_documents(documents, '
|
|
129
|
+
client.index(index_name).add_documents(documents, 'id')
|
|
128
130
|
end
|
|
129
131
|
|
|
130
132
|
def remove(product)
|
|
@@ -132,7 +134,9 @@ module Spree
|
|
|
132
134
|
end
|
|
133
135
|
|
|
134
136
|
def index_batch(documents)
|
|
135
|
-
|
|
137
|
+
return if documents.empty?
|
|
138
|
+
|
|
139
|
+
client.index(index_name).add_documents(documents, 'id')
|
|
136
140
|
end
|
|
137
141
|
|
|
138
142
|
# Remove all documents for a product by its prefixed_id (e.g. 'prod_abc')
|
|
@@ -147,21 +151,44 @@ module Spree
|
|
|
147
151
|
scope ||= store.products
|
|
148
152
|
ensure_index_settings!
|
|
149
153
|
|
|
154
|
+
indexed = 0
|
|
150
155
|
scope.reorder(id: :asc)
|
|
151
156
|
.preload_associations_lazily
|
|
152
157
|
.find_in_batches(batch_size: 500) do |batch|
|
|
153
158
|
documents = batch.flat_map { |product| presenter_class.new(product, store).call }
|
|
159
|
+
next if documents.empty?
|
|
160
|
+
|
|
154
161
|
index_batch(documents)
|
|
162
|
+
indexed += documents.size
|
|
163
|
+
|
|
164
|
+
Rails.logger.info { "[Meilisearch] Enqueued #{documents.size} documents (#{indexed} total) for #{index_name}" }
|
|
155
165
|
end
|
|
166
|
+
|
|
167
|
+
Rails.logger.info { "[Meilisearch] Reindex complete: #{indexed} documents enqueued for #{index_name}" }
|
|
168
|
+
indexed
|
|
156
169
|
end
|
|
157
170
|
|
|
158
171
|
# Configure index settings for filtering, sorting, and faceting.
|
|
159
172
|
# Called automatically by reindex, but can be called separately.
|
|
173
|
+
# Waits for all settings tasks to complete before returning so that
|
|
174
|
+
# subsequent add_documents calls use the correct filterable/sortable attributes.
|
|
160
175
|
def ensure_index_settings!
|
|
161
176
|
index = client.index(index_name)
|
|
162
|
-
|
|
163
|
-
index.
|
|
164
|
-
index.
|
|
177
|
+
tasks = []
|
|
178
|
+
tasks << index.update_filterable_attributes(filterable_attributes)
|
|
179
|
+
tasks << index.update_sortable_attributes(sortable_attributes)
|
|
180
|
+
tasks << index.update_searchable_attributes(searchable_attributes)
|
|
181
|
+
tasks.each { |task| task&.await }
|
|
182
|
+
@index_settings_configured = true
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# Lightweight guard — configures index settings once per provider instance.
|
|
186
|
+
# Meilisearch settings updates are idempotent, so repeated calls are safe
|
|
187
|
+
# but we avoid the overhead by memoizing.
|
|
188
|
+
def ensure_index_settings_once!
|
|
189
|
+
return if @index_settings_configured
|
|
190
|
+
|
|
191
|
+
ensure_index_settings!
|
|
165
192
|
end
|
|
166
193
|
|
|
167
194
|
private
|
|
@@ -359,7 +386,12 @@ module Spree
|
|
|
359
386
|
|
|
360
387
|
ot = ov.option_type
|
|
361
388
|
by_option_type[ot] ||= []
|
|
362
|
-
by_option_type[ot] << {
|
|
389
|
+
by_option_type[ot] << {
|
|
390
|
+
id: ov.prefixed_id, name: ov.name, label: ov.label, position: ov.position,
|
|
391
|
+
color_code: ov.color_code,
|
|
392
|
+
image_url: ov.image.attached? ? Rails.application.routes.url_helpers.cdn_image_url(ov.image) : nil,
|
|
393
|
+
count: count
|
|
394
|
+
}
|
|
363
395
|
end
|
|
364
396
|
|
|
365
397
|
by_option_type.map do |option_type, values|
|
|
@@ -368,6 +400,7 @@ module Spree
|
|
|
368
400
|
type: 'option',
|
|
369
401
|
name: option_type.name,
|
|
370
402
|
label: option_type.label,
|
|
403
|
+
kind: option_type.kind,
|
|
371
404
|
options: values.sort_by { |o| o[:position] }
|
|
372
405
|
}
|
|
373
406
|
end
|
|
@@ -27,7 +27,7 @@ module Spree
|
|
|
27
27
|
after_save :ensure_one_default
|
|
28
28
|
after_update :conditional_touch_records
|
|
29
29
|
|
|
30
|
-
delegate :name, :iso3, :iso, :iso_name, to: :country, prefix: true
|
|
30
|
+
delegate :name, :iso3, :iso, :iso_name, to: :country, prefix: true, allow_nil: true
|
|
31
31
|
|
|
32
32
|
def state_text
|
|
33
33
|
state.try(:abbr) || state.try(:name) || state_name
|
|
@@ -35,10 +35,15 @@ module Spree
|
|
|
35
35
|
|
|
36
36
|
private
|
|
37
37
|
|
|
38
|
+
# Build a document for a given locale and currency
|
|
39
|
+
# @param locale [String] the locale to build the document for
|
|
40
|
+
# @param currency [String] the currency to build the document for
|
|
41
|
+
# @param fallback_locale [String] the fallback locale to use if the product has no translation for the given locale
|
|
42
|
+
# @return [Hash] the document
|
|
38
43
|
def build_document(locale, currency, fallback_locale)
|
|
39
44
|
{
|
|
40
45
|
# Composite ID: product + locale + currency
|
|
41
|
-
|
|
46
|
+
id: "#{product.prefixed_id}_#{locale}_#{currency}",
|
|
42
47
|
product_id: product.prefixed_id,
|
|
43
48
|
locale: locale.to_s,
|
|
44
49
|
currency: currency,
|
|
@@ -53,7 +58,7 @@ module Spree
|
|
|
53
58
|
status: product.status,
|
|
54
59
|
sku: product.sku,
|
|
55
60
|
in_stock: product.in_stock?,
|
|
56
|
-
store_ids:
|
|
61
|
+
store_ids: product.store_ids.map(&:to_s),
|
|
57
62
|
discontinue_on: product.discontinue_on&.to_i || 0,
|
|
58
63
|
category_ids: category_ids_with_ancestors,
|
|
59
64
|
category_names: product.taxons.map { |t| translated(t, :name, fallback_locale) },
|
|
@@ -62,8 +67,7 @@ module Spree
|
|
|
62
67
|
option_value_ids: variant_option_value_ids,
|
|
63
68
|
option_values: variant_option_values_data.map { |ov| translated(ov, :presentation, fallback_locale) }.uniq,
|
|
64
69
|
tags: product.tag_list || [],
|
|
65
|
-
|
|
66
|
-
units_sold_count: cached_units_sold_count,
|
|
70
|
+
units_sold_count: product.store_products.find { |sp| sp.store_id == store.id }&.units_sold_count || 0,
|
|
67
71
|
available_on: product.available_on&.iso8601,
|
|
68
72
|
created_at: product.created_at&.iso8601,
|
|
69
73
|
updated_at: product.updated_at&.iso8601
|
|
@@ -111,15 +115,6 @@ module Spree
|
|
|
111
115
|
}.uniq
|
|
112
116
|
end
|
|
113
117
|
|
|
114
|
-
# Memoized — avoids N+1 when called per document
|
|
115
|
-
def cached_store_ids
|
|
116
|
-
@cached_store_ids ||= product.store_ids.map(&:to_s)
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
def cached_units_sold_count
|
|
120
|
-
@cached_units_sold_count ||= product.store_products.detect { |sp| sp.store_id == store.id }&.units_sold_count || 0
|
|
121
|
-
end
|
|
122
|
-
|
|
123
118
|
def variant_option_value_ids
|
|
124
119
|
variant_option_values_data.map(&:prefixed_id).uniq
|
|
125
120
|
end
|
|
@@ -11,6 +11,7 @@ module Spree
|
|
|
11
11
|
|
|
12
12
|
cart = store.carts.create!(
|
|
13
13
|
user: @params.delete(:user),
|
|
14
|
+
market: @params.delete(:market) || Spree::Current.market,
|
|
14
15
|
currency: @params.delete(:currency) || store.default_currency,
|
|
15
16
|
locale: @params.delete(:locale) || Spree::Current.locale
|
|
16
17
|
)
|
|
@@ -9,6 +9,7 @@ module Spree
|
|
|
9
9
|
|
|
10
10
|
ApplicationRecord.transaction do
|
|
11
11
|
assign_cart_attributes
|
|
12
|
+
clear_shipping_address_if_outside_market
|
|
12
13
|
assign_address(:shipping_address)
|
|
13
14
|
assign_address(:billing_address)
|
|
14
15
|
|
|
@@ -35,6 +36,8 @@ module Spree
|
|
|
35
36
|
def assign_cart_attributes
|
|
36
37
|
cart.email = params[:email] if params[:email].present?
|
|
37
38
|
cart.customer_note = params[:customer_note] if params.key?(:customer_note)
|
|
39
|
+
|
|
40
|
+
assign_market if params[:market_id].present?
|
|
38
41
|
cart.currency = params[:currency].upcase if params[:currency].present?
|
|
39
42
|
cart.locale = params[:locale] if params[:locale].present?
|
|
40
43
|
cart.metadata = cart.metadata.merge(params[:metadata].to_h) if params[:metadata].present?
|
|
@@ -83,6 +86,24 @@ module Spree
|
|
|
83
86
|
decoded ? cart.user.addresses.find_by(id: decoded)&.id : nil
|
|
84
87
|
end
|
|
85
88
|
|
|
89
|
+
def assign_market
|
|
90
|
+
market = cart.store.markets.find_by_prefix_id!(params[:market_id])
|
|
91
|
+
cart.market = market
|
|
92
|
+
cart.skip_market_resolution = true
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# When the market changes, clear the shipping address if its country
|
|
96
|
+
# is not part of the new market. The market dictates which countries
|
|
97
|
+
# are available for checkout.
|
|
98
|
+
def clear_shipping_address_if_outside_market
|
|
99
|
+
return unless cart.market_id_changed? && cart.ship_address&.country
|
|
100
|
+
|
|
101
|
+
unless cart.market.country_ids.include?(cart.ship_address.country_id)
|
|
102
|
+
cart.ship_address = nil
|
|
103
|
+
revert_to_address_state if cart.has_checkout_step?('address')
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
86
107
|
def revert_to_address_state
|
|
87
108
|
return if ['cart', 'address'].include?(cart.state)
|
|
88
109
|
|
|
@@ -6,29 +6,32 @@ module Spree
|
|
|
6
6
|
def call
|
|
7
7
|
Spree::Events.disable do
|
|
8
8
|
without_geocoding do
|
|
9
|
-
|
|
9
|
+
ActiveRecord::Base.no_touching do
|
|
10
|
+
ensure_seeds_loaded
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
puts 'Loading sample configuration data...'
|
|
13
|
+
load_configuration_data
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
puts 'Loading sample metafield definitions...'
|
|
16
|
+
load_ruby_file('metafield_definitions')
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
puts 'Loading sample options...'
|
|
19
|
+
load_ruby_file('options')
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
puts 'Loading sample products...'
|
|
22
|
+
load_products
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
puts 'Loading sample customers...'
|
|
25
|
+
load_customers
|
|
25
26
|
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
puts 'Loading sample orders...'
|
|
28
|
+
load_ruby_file('orders')
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
puts 'Loading sample posts...'
|
|
31
|
+
load_ruby_file('posts')
|
|
30
32
|
|
|
31
|
-
|
|
33
|
+
puts 'Sample data loaded successfully!'
|
|
34
|
+
end
|
|
32
35
|
end
|
|
33
36
|
end
|
|
34
37
|
end
|
|
@@ -75,11 +78,6 @@ module Spree
|
|
|
75
78
|
ensure
|
|
76
79
|
Spree::Config[:geocode_addresses] = previous
|
|
77
80
|
end
|
|
78
|
-
|
|
79
|
-
def clear_jobs_queue
|
|
80
|
-
adapter = ActiveJob::Base.queue_adapter
|
|
81
|
-
adapter.enqueued_jobs.clear if adapter.respond_to?(:enqueued_jobs)
|
|
82
|
-
end
|
|
83
81
|
end
|
|
84
82
|
end
|
|
85
83
|
end
|
|
@@ -5,30 +5,32 @@ module Spree
|
|
|
5
5
|
|
|
6
6
|
def call
|
|
7
7
|
Spree::Events.disable do
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
ActiveRecord::Base.no_touching do
|
|
9
|
+
# GEO
|
|
10
|
+
Countries.call
|
|
11
|
+
States.call
|
|
12
|
+
Zones.call
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
# user roles
|
|
15
|
+
Roles.call
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
# additional data
|
|
18
|
+
ReturnsEnvironment.call
|
|
19
|
+
ShippingCategories.call
|
|
20
|
+
StoreCreditCategories.call
|
|
21
|
+
TaxCategories.call
|
|
22
|
+
DigitalDelivery.call
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
# store & stock location
|
|
25
|
+
Stores.call
|
|
26
|
+
StockLocations.call
|
|
27
|
+
AdminUser.call
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
# add store resources
|
|
30
|
+
PaymentMethods.call
|
|
31
|
+
ApiKeys.call
|
|
32
|
+
AllowedOrigins.call
|
|
33
|
+
end
|
|
32
34
|
end
|
|
33
35
|
end
|
|
34
36
|
end
|
data/config/locales/en.yml
CHANGED
|
@@ -73,8 +73,12 @@ en:
|
|
|
73
73
|
namespace: Namespace
|
|
74
74
|
spree/option_type:
|
|
75
75
|
filterable: Filterable
|
|
76
|
+
kind: Kind
|
|
76
77
|
name: Name
|
|
77
78
|
presentation: Presentation
|
|
79
|
+
spree/option_value:
|
|
80
|
+
color_code: Color Code
|
|
81
|
+
image: Swatch Image
|
|
78
82
|
spree/order:
|
|
79
83
|
checkout_complete: Checkout Complete
|
|
80
84
|
completed_at: Completed At
|
|
@@ -775,6 +779,7 @@ en:
|
|
|
775
779
|
approver: Approver
|
|
776
780
|
are_you_sure: Are you sure?
|
|
777
781
|
are_you_sure_delete: Are you sure you want to delete this record?
|
|
782
|
+
assets: Media
|
|
778
783
|
associated_adjustment_closed: The associated adjustment is closed, and will not be recalculated. Do you want to open it?
|
|
779
784
|
at_symbol: "@"
|
|
780
785
|
attachments: Attachments
|
|
@@ -897,6 +902,7 @@ en:
|
|
|
897
902
|
close_sidebar: Close sidebar
|
|
898
903
|
closed: Closed
|
|
899
904
|
code: Code
|
|
905
|
+
color_code: Color Code
|
|
900
906
|
colors: Colors
|
|
901
907
|
company: Company
|
|
902
908
|
compare_at_amount: Compare at amount
|
|
@@ -1573,6 +1579,11 @@ en:
|
|
|
1573
1579
|
option_name: Option name
|
|
1574
1580
|
option_type: Option Type
|
|
1575
1581
|
option_type_filterable_info: When an option type is set to Filterable, your storefront visitors are presented with the option to filter a taxon of products based on the option type. A typical example of this would be to filter clothing by size and color.<br><br><b>Please Note:</b> Filters will only be visible in the storefront taxons that contain products with this option type set.
|
|
1582
|
+
option_type_kind_info: Controls how the option is displayed on the storefront. Color swatches show color circles, buttons show clickable chips, and dropdown shows a select menu.
|
|
1583
|
+
option_type_kinds:
|
|
1584
|
+
buttons: Buttons
|
|
1585
|
+
color_swatch: Color Swatch
|
|
1586
|
+
dropdown: Dropdown
|
|
1576
1587
|
option_type_placeholder: Choose an option type
|
|
1577
1588
|
option_types: Option Types
|
|
1578
1589
|
option_value: Option Value
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
class CreateActionTextVideoEmbeds < ActiveRecord::Migration[6.1]
|
|
2
|
+
def change
|
|
3
|
+
create_table :action_text_video_embeds, if_not_exists: true do |t|
|
|
4
|
+
t.string :url, null: false
|
|
5
|
+
t.string :thumbnail_url, null: false
|
|
6
|
+
t.text :raw_html, null: false
|
|
7
|
+
|
|
8
|
+
t.timestamps
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
class AddKindToSpreeOptionTypes < ActiveRecord::Migration[7.2]
|
|
2
|
+
def change
|
|
3
|
+
add_column :spree_option_types, :kind, :string, null: false, default: 'dropdown'
|
|
4
|
+
add_index :spree_option_types, :kind
|
|
5
|
+
|
|
6
|
+
# Backfill: option types named 'color'/'colour' get kind 'color_swatch'
|
|
7
|
+
reversible do |dir|
|
|
8
|
+
dir.up do
|
|
9
|
+
execute "UPDATE spree_option_types SET kind = 'color_swatch' WHERE name IN ('color', 'colour')"
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
%w[
|
|
1
|
+
%w[warranty capacity voltage wattage runtime room_coverage noise_level connectivity].each do |key|
|
|
2
2
|
Spree::MetafieldDefinition.find_or_create_by!(
|
|
3
|
-
namespace: '
|
|
3
|
+
namespace: 'custom',
|
|
4
4
|
key: key,
|
|
5
5
|
resource_type: 'Spree::Product'
|
|
6
6
|
)
|
data/db/sample_data/orders.rb
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
store = Spree::Store.default
|
|
2
2
|
|
|
3
3
|
# Find products created by the product import
|
|
4
|
-
product_1 = Spree::Product.find_by(name: '
|
|
5
|
-
product_2 = Spree::Product.find_by(name: '
|
|
4
|
+
product_1 = Spree::Product.find_by(name: 'Automatic Espresso Machine')
|
|
5
|
+
product_2 = Spree::Product.find_by(name: 'Drip Coffee Maker 1.5L')
|
|
6
6
|
|
|
7
7
|
unless product_1 && product_2
|
|
8
8
|
puts ' Skipping orders: required products not found'
|