spree_core 5.0.0 → 5.0.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7dc7cce417107635f46c74c979366413643377d2998d7af5654b8ec7a6e7403b
4
- data.tar.gz: 94ed7a5b9cb4018aa68943bd8f313fb2f18ea3b9a47071b58b3e7ea0a38edc61
3
+ metadata.gz: 5a60d5a6d4ba0fd4d7e223de06835389a8c4c39572dabe07e29a4fb5312d2548
4
+ data.tar.gz: 1163cb99eaca807157669cc6ae77f3c2eae58c8b63de520b27c329244c870d22
5
5
  SHA512:
6
- metadata.gz: dec7666d5d8e9d72480f079b5ec0e23d5dae63063378d4151919494b89ba07c104c46150d13a9c25b3edb90901bc3c1e290ffb9c5812b2b277df15cbe20daa46
7
- data.tar.gz: 60484eb5165486926e268c6cc155f8e4930356c28050b1f98868c701fd0660f06cd028ddce4ad8971e491b7e9cc60f4c14ede124aa151efe5c8d5c4c2a702153
6
+ metadata.gz: d69a80bb1326c8f17f29c299701c20b372736a16002688a51cb0f9cef9f95a650ef3f2eb860e5d671e3fda54745fc2eace0b54a534e746d0b12e0337ea7cb547
7
+ data.tar.gz: 20864a616e90144196cf5b3d8a4b4d8ef35bed9bf85415a1ed07361b1c4451fd77716adfdfbb9a122ac0284eee6b2b00e2d9b24f5dddf825167eb7fe2f5e97c7
@@ -163,6 +163,15 @@ module Spree
163
163
  Spree::Core::Engine.frontend_available?
164
164
  end
165
165
 
166
+ # returns the URL of an object on the storefront
167
+ # @param resource [Spree::Product, Spree::Post, Spree::Taxon, Spree::Page] the resource to get the URL for
168
+ # @param options [Hash] the options for the URL
169
+ # @option options [String] :locale the locale of the resource, defaults to I18n.locale
170
+ # @option options [String] :store the store of the resource, defaults to current_store
171
+ # @option options [String] :relative whether to use the relative URL, defaults to false
172
+ # @option options [String] :preview_id the preview ID of the resource, usually the ID of the resource
173
+ # @option options [String] :variant_id the variant ID of the resource, usually the ID of the variant (only used for products)
174
+ # @return [String] the URL of the resource
166
175
  def spree_storefront_resource_url(resource, options = {})
167
176
  options.merge!(locale: locale_param) if defined?(locale_param) && locale_param.present?
168
177
 
@@ -1,6 +1,77 @@
1
1
  module Spree
2
2
  module ImagesHelper
3
+ # render an image tag with a spree image variant
4
+ # it also automatically scales the width and height by 2x to look great on retina screens
5
+ #
6
+ # @param image [ActiveStorage::Attachment] the image to render
7
+ # @param options [Hash] options for the image tag
8
+ # @option options [Integer] :width the width of the image
9
+ # @option options [Integer] :height the height of the image
10
+ def spree_image_tag(image, options = {})
11
+ image_tag(
12
+ spree_image_url(image, { width: options[:width], height: options[:height] }),
13
+ options
14
+ )
15
+ end
16
+
17
+ def spree_image_url(image, options = {})
18
+ width = options[:width]
19
+ height = options[:height]
20
+
21
+ width = width * 2 if width.present?
22
+ height = height * 2 if height.present?
23
+
24
+ return unless image.attached?
25
+ return unless image.variable?
26
+
27
+ if width.present? && height.present?
28
+ main_app.cdn_image_url(
29
+ image.variant(spree_image_variant_options(resize_to_fill: [width, height]))
30
+ )
31
+ else
32
+ main_app.cdn_image_url(
33
+ image.variant(spree_image_variant_options(resize_to_limit: [width, height]))
34
+ )
35
+ end
36
+ end
37
+
38
+ def spree_asset_aspect_ratio(attachment)
39
+ return unless attachment.present?
40
+ return unless attachment.analyzed?
41
+
42
+ metadata = attachment.metadata
43
+ aspect_ratio = metadata['aspect_ratio'].presence
44
+
45
+ return aspect_ratio if aspect_ratio
46
+
47
+ width = metadata['width']&.to_f
48
+ return unless width
49
+
50
+ height = metadata['height']&.to_f
51
+ return unless height
52
+ return if height.zero?
53
+
54
+ w, h = width.to_f, height.to_f
55
+
56
+ # Always return width / height, flipping if needed
57
+ if h > w
58
+ ratio = h / w
59
+ elsif h < w
60
+ ratio = w / h
61
+ else
62
+ # h == w, square image
63
+ ratio = 1.0
64
+ end
65
+
66
+ ratio.round(3)
67
+ end
68
+
3
69
  # convert images to webp with some sane optimization defaults
70
+ # it also automatically scales the width and height by 2x to look great on retina screens
71
+ #
72
+ # @param options [Hash] options for the image variant
73
+ # @option options [Integer] :width the width of the image
74
+ # @option options [Integer] :height the height of the image
4
75
  def spree_image_variant_options(options = {})
5
76
  {
6
77
  saver: {
@@ -121,10 +121,7 @@ export default class extends Controller {
121
121
 
122
122
  async fillAddress(placeID) {
123
123
  const placeDetails =
124
- await this.googlePlacesSuggestionsProvider.getPlaceDetails(
125
- placeID,
126
- this.address1Target
127
- )
124
+ await this.googlePlacesSuggestionsProvider.getPlaceDetails(placeID)
128
125
 
129
126
  if (placeDetails) {
130
127
  this.address1Target.value = placeDetails.fullAddress
@@ -6,139 +6,115 @@ export default class {
6
6
  }
7
7
  this.placesApi = await google.maps.importLibrary('places')
8
8
  this.googleSessionToken = new this.placesApi.AutocompleteSessionToken()
9
- this.autocompleteSevice = new this.placesApi.AutocompleteService()
10
9
  }
11
10
 
12
11
  async getSuggestions(input, country) {
13
- return new Promise((resolve, reject) => {
14
- if (this.placesApi === undefined) {
15
- reject('You must call connect() before getSuggestions()')
16
- return
17
- }
12
+ if (this.placesApi === undefined) {
13
+ throw new Error('You must call connect() before getSuggestions()')
14
+ }
18
15
 
19
- this.autocompleteSevice.getPlacePredictions(
20
- {
21
- input,
22
- // We can use `address`, `street_address`
23
- // `street_address` is the most accurate and specific, but sometimes it returns no results, even if the address is valid
24
- // Since we are validating the address on the server, we can use `address`
25
- types: [],
26
- componentRestrictions: {
27
- country
28
- },
29
- sessionToken: this.googleSessionToken
30
- },
31
- (predictions, status) => {
32
- if (status !== this.placesApi.PlacesServiceStatus.OK) {
33
- resolve([])
34
- } else {
35
- resolve(predictions.map(this.parsePrediction.bind(this)))
36
- }
37
- }
38
- )
39
- })
16
+ const request = {
17
+ input,
18
+ // We can use `address`, `street_address`
19
+ // `street_address` is the most accurate and specific, but sometimes it returns no results, even if the address is valid
20
+ // Since we are validating the address on the server, we can use `address`
21
+ includedRegionCodes: [country],
22
+ sessionToken: this.googleSessionToken
23
+ }
24
+
25
+ try {
26
+ const response = await this.placesApi.AutocompleteSuggestion.fetchAutocompleteSuggestions(request)
27
+ return response.suggestions.map((element, index) => this.parsePrediction(element.placePrediction, index))
28
+ } catch (error) {
29
+ console.error('Error fetching autocomplete suggestions', error)
30
+ return []
31
+ }
40
32
  }
41
33
 
42
- async getPlaceDetails(placeID, target) {
43
- return new Promise((resolve, reject) => {
44
- if (this.placesApi === undefined) {
45
- reject('You must call connect() before getPlaceDetails()')
46
- return
47
- }
34
+ async getPlaceDetails(placeID) {
35
+ if (this.placesApi === undefined) {
36
+ throw new Error('You must call connect() before getPlaceDetails()')
37
+ }
48
38
 
49
- const service = new this.placesApi.PlacesService(target)
50
- service.getDetails(
51
- {
52
- placeId: placeID,
53
- fields: ['address_components'],
54
- sessionToken: this.googleSessionToken
55
- },
56
- (place, status) => {
57
- if (status !== this.placesApi.PlacesServiceStatus.OK) {
58
- resolve(null)
59
- return
60
- }
39
+ try {
40
+ const service = new this.placesApi.Place({ id: placeID })
61
41
 
62
- this.sessionToken = new this.placesApi.AutocompleteSessionToken()
42
+ const { place } = await service.fetchFields({ fields: ["addressComponents"] })
63
43
 
64
- const fullAddress = []
65
- let hasStreetNumber = false
44
+ const fullAddress = []
45
+ let hasStreetNumber = false
66
46
 
67
- const details = {
68
- fullAddress: '',
69
- city: '',
70
- stateAbbr: '',
71
- zipcode: '',
72
- hasStreetNumber: false
73
- }
47
+ const details = {
48
+ fullAddress: '',
49
+ city: '',
50
+ stateAbbr: '',
51
+ zipcode: '',
52
+ hasStreetNumber: false
53
+ }
74
54
 
75
- let locality = undefined
76
- let postal_town = undefined
77
- let sublocality = undefined
78
- let administrative_area_level_3 = undefined
79
- let premise = undefined
80
- let subpremise = undefined
55
+ let locality, postal_town, sublocality, administrative_area_level_3, premise, subpremise
81
56
 
82
- place.address_components.forEach((component) => {
83
- if (component.types.includes('street_number')) {
84
- fullAddress.push(component.long_name)
85
- hasStreetNumber = true
86
- }
87
- if (component.types.includes('subpremise')) {
88
- subpremise = component.long_name
89
- }
90
- if (component.types.includes('premise')) {
91
- premise = component.long_name
92
- }
93
- if (component.types.includes('route')) {
94
- fullAddress.push(component.long_name)
95
- }
96
- if (component.types.includes('locality')) {
97
- locality = component.long_name
98
- }
99
- if (component.types.includes('postal_town')) {
100
- postal_town = component.long_name
101
- }
102
- if (component.types.includes('sublocality')) {
103
- sublocality = component.long_name
104
- }
105
- if (component.types.includes('administrative_area_level_1')) {
106
- details.stateAbbr = component.short_name
107
- }
108
- if (component.types.includes('postal_code')) {
109
- details.zipcode = component.long_name
110
- }
111
- if (component.types.includes('administrative_area_level_3')) {
112
- administrative_area_level_3 = component.long_name
113
- }
114
- })
115
- // City is tricky, because it can be in different fields
116
- details.city =
117
- locality ||
118
- postal_town ||
119
- sublocality ||
120
- administrative_area_level_3 ||
121
- ''
122
- if (premise && !hasStreetNumber) {
123
- fullAddress.unshift(premise)
124
- hasStreetNumber = true
125
- }
126
- if (subpremise) {
127
- fullAddress.push(subpremise)
128
- }
129
- details.hasStreetNumber = hasStreetNumber
130
- details.fullAddress = fullAddress.join(' ')
131
- resolve(details)
57
+ place.addressComponents.forEach((component) => {
58
+ if (component.types.includes('street_number')) {
59
+ fullAddress.push(component.longText)
60
+ hasStreetNumber = true
132
61
  }
133
- )
134
- })
62
+ if (component.types.includes('subpremise')) {
63
+ subpremise = component.longText
64
+ }
65
+ if (component.types.includes('premise')) {
66
+ premise = component.longText
67
+ }
68
+ if (component.types.includes('route')) {
69
+ fullAddress.push(component.longText)
70
+ }
71
+ if (component.types.includes('locality')) {
72
+ locality = component.longText
73
+ }
74
+ if (component.types.includes('postal_town')) {
75
+ postal_town = component.longText
76
+ }
77
+ if (component.types.includes('sublocality')) {
78
+ sublocality = component.longText
79
+ }
80
+ if (component.types.includes('administrative_area_level_1')) {
81
+ details.stateAbbr = component.shortText
82
+ }
83
+ if (component.types.includes('postal_code')) {
84
+ details.zipcode = component.longText
85
+ }
86
+ if (component.types.includes('administrative_area_level_3')) {
87
+ administrative_area_level_3 = component.longText
88
+ }
89
+ })
90
+ // City is tricky, because it can be in different fields
91
+ details.city =
92
+ locality ||
93
+ postal_town ||
94
+ sublocality ||
95
+ administrative_area_level_3 ||
96
+ ''
97
+ if (premise && !hasStreetNumber) {
98
+ fullAddress.unshift(premise)
99
+ hasStreetNumber = true
100
+ }
101
+ if (subpremise) {
102
+ fullAddress.push(subpremise)
103
+ }
104
+ details.hasStreetNumber = hasStreetNumber
105
+ details.fullAddress = fullAddress.join(' ')
106
+ return details
107
+ } catch (error) {
108
+ console.error('Error fetching autocomplete details', error)
109
+ return null
110
+ }
135
111
  }
136
112
 
137
113
  parsePrediction(prediction, index) {
138
114
  const suggestion = {
139
115
  index: index,
140
- placeID: prediction.place_id,
141
- description: prediction.description
116
+ placeID: prediction.placeId,
117
+ description: prediction.text.text
142
118
  }
143
119
 
144
120
  const splittedText = this.splitTextForMarks(prediction)
@@ -155,12 +131,18 @@ export default class {
155
131
 
156
132
  // This function takes the prediction and splits the description into an array of objects with the text and a boolean indicating if it should be highlighted
157
133
  splitTextForMarks(prediction) {
158
- let markedAreas = [...prediction.matched_substrings.sort((m) => m.offset)]
134
+ const description = prediction.text.text;
135
+ let markedAreas = prediction.text.matches
136
+ .map(({ startOffset, endOffset }) => ({
137
+ offset: startOffset,
138
+ length: endOffset - startOffset
139
+ }))
140
+ .sort((a, b) => a.offset - b.offset);
159
141
  const textAreas = []
160
- for (let i = 0; i < prediction.description.length; i++) {
142
+ for (let i = 0; i < description.length; i++) {
161
143
  if (markedAreas[0]?.offset === i) {
162
144
  textAreas.push({
163
- text: prediction.description.substring(i, i + markedAreas[0].length),
145
+ text: description.substring(i, i + markedAreas[0].length),
164
146
  marked: true
165
147
  })
166
148
  i += markedAreas[0].length - 1
@@ -168,7 +150,7 @@ export default class {
168
150
  markedAreas = [...markedAreas.sort((m) => m.offset)]
169
151
  } else {
170
152
  textAreas.push({
171
- text: prediction.description.charAt(i),
153
+ text: description.charAt(i),
172
154
  marked: false
173
155
  })
174
156
  }
@@ -12,7 +12,7 @@ module Spree
12
12
  acts_as_paranoid
13
13
 
14
14
  belongs_to :payment_method
15
- belongs_to :user, class_name: "::#{Spree.user_class}", foreign_key: 'user_id', optional: true
15
+ belongs_to :user, class_name: Spree.user_class.to_s, foreign_key: 'user_id', optional: true
16
16
  belongs_to :gateway_customer, class_name: 'Spree::GatewayCustomer', optional: true
17
17
 
18
18
  has_many :payments, as: :source
@@ -504,6 +504,7 @@ module Spree
504
504
  end
505
505
 
506
506
  def available_payment_methods(store = nil)
507
+ Spree::Deprecation.warn('`Order#available_payment_methods` is deprecated and will be removed in Spree 6. Use `collect_frontend_payment_methods` instead.')
507
508
  if store.present?
508
509
  Spree::Deprecation.warn('The `store` parameter is deprecated and will be removed in Spree 5. Order is already associated with Store')
509
510
  end
@@ -754,7 +755,11 @@ module Spree
754
755
  end
755
756
 
756
757
  def collect_backend_payment_methods
757
- PaymentMethod.active.available_on_back_end.select { |pm| pm.available_for_order?(self) }
758
+ store.payment_methods.active.available_on_back_end.select { |pm| pm.available_for_order?(self) }
759
+ end
760
+
761
+ def collect_frontend_payment_methods
762
+ store.payment_methods.active.available_on_front_end.select { |pm| pm.available_for_order?(self) }
758
763
  end
759
764
 
760
765
  # determines whether the inventory is fully discounted
@@ -771,19 +776,6 @@ module Spree
771
776
  Spree::CouponCode.find_by(order: self, promotion: promotions).try(:code) || promotions.pluck(:code).compact.first
772
777
  end
773
778
 
774
- def validate_payments_attributes(attributes)
775
- Spree::Deprecation.warn('`Order#validate_payments_attributes` is deprecated and will be removed in Spree 5')
776
-
777
- # Ensure the payment methods specified are allowed for this user
778
- payment_method_ids = available_payment_methods.map(&:id).map(&:to_s)
779
-
780
- attributes.each do |payment_attributes|
781
- payment_method_id = payment_attributes[:payment_method_id].to_s
782
-
783
- raise ActiveRecord::RecordNotFound unless payment_method_ids.include?(payment_method_id)
784
- end
785
- end
786
-
787
779
  def valid_promotions
788
780
  order_promotions.where(promotion_id: valid_promotion_ids).uniq(&:promotion_id)
789
781
  end
@@ -887,6 +879,7 @@ module Spree
887
879
  end
888
880
 
889
881
  def collect_payment_methods(store = nil)
882
+ Spree::Deprecation.warn('`Order#collect_payment_methods` is deprecated and will be removed in Spree 6. Use `collect_frontend_payment_methods` instead.')
890
883
  if store.present?
891
884
  Spree::Deprecation.warn('The `store` parameter is deprecated and will be removed in Spree 5. Order is already associated with Store')
892
885
  end
@@ -98,7 +98,7 @@ module Spree
98
98
  end
99
99
 
100
100
  def create_default_pages
101
- Rails.application.config.spree.pages.each do |page_class|
101
+ Rails.application.config.spree.pages.map(&:to_s).map(&:constantize).each do |page_class|
102
102
  next if page_class == Spree::Pages::Custom
103
103
 
104
104
  page_class.where(pageable: self).first_or_create!
@@ -107,7 +107,7 @@ module Spree
107
107
 
108
108
  def create_layout_sections
109
109
  ApplicationRecord.transaction do
110
- available_layout_sections.each do |section_class|
110
+ available_layout_sections.map(&:to_s).map(&:constantize).each do |section_class|
111
111
  section_class.where(pageable: self).first_or_create!
112
112
  end
113
113
  end
@@ -9,8 +9,16 @@ module Spree
9
9
  bill_changed = address_with_country_iso_present?(params, 'bill')
10
10
  params[:order][:ship_address_attributes] = replace_country_iso_with_id(params[:order][:ship_address_attributes]) if ship_changed
11
11
  params[:order][:bill_address_attributes] = replace_country_iso_with_id(params[:order][:bill_address_attributes]) if bill_changed
12
- order.state = 'address' if (ship_changed || bill_changed) && order.has_checkout_step?('address')
13
- order.state = 'delivery' if selected_shipping_rate_present?(params) && order.has_checkout_step?('delivery')
12
+
13
+ # for quick checkouts we cannot revert to previous states
14
+ # we already have the address and delivery steps completed
15
+ # however we need to update the shipping address with missing data
16
+ # as previously we didn't have access to first/last name and street
17
+ unless params[:do_not_change_state]
18
+ order.state = 'address' if (ship_changed || bill_changed || quick_checkout_cancelled?(params)) && order.has_checkout_step?('address')
19
+ order.state = 'delivery' if selected_shipping_rate_present?(params) && order.has_checkout_step?('delivery')
20
+ end
21
+
14
22
  return success(order) if order.update_from_params(params, permitted_attributes, request_env)
15
23
 
16
24
  failure(order)
@@ -31,6 +39,10 @@ module Spree
31
39
 
32
40
  shipments_attributes.any? { |s| s.dig(:selected_shipping_rate_id) }
33
41
  end
42
+
43
+ def quick_checkout_cancelled?(params)
44
+ params.dig(:order, :ship_address_id) == 'CLEAR'
45
+ end
34
46
  end
35
47
  end
36
48
  end
@@ -14,7 +14,7 @@ module Spree
14
14
  protected
15
15
 
16
16
  def prepare_payment_attributes(order:, params:)
17
- payment_method = order.available_payment_methods.find { |pm| pm.id.to_s == params[:payment_method_id]&.to_s }
17
+ payment_method = order.collect_frontend_payment_methods.find { |pm| pm.id.to_s == params[:payment_method_id]&.to_s }
18
18
 
19
19
  payment_attributes = {
20
20
  amount: params[:amount] || order.order_total_after_store_credit,
@@ -130,8 +130,10 @@ module Spree
130
130
  option_value_variant_params = {}
131
131
 
132
132
  option_value_params.each_with_index do |opt, index|
133
- option_type = Spree::OptionType.where(name: opt[:name].parameterize).first_or_initialize do |o|
133
+ option_type = Spree::OptionType.find_by(id: opt[:id]) if opt.fetch(:id)
134
+ option_type ||= Spree::OptionType.where(name: opt[:name].parameterize).first_or_initialize do |o|
134
135
  o.name = o.presentation = opt[:name]
136
+ o.position = opt[:position]
135
137
  o.save!
136
138
  end
137
139
  option_value = option_type.option_values.where(name: opt[:value].parameterize).first_or_initialize do |o|
@@ -1,12 +1,6 @@
1
1
  <figure class="attachment attachment--<%= blob.representable? ? "preview" : "file" %> attachment--<%= blob.filename.extension %>">
2
2
  <% if blob.representable? %>
3
- <%= image_tag main_app.cdn_image_url(
4
- blob.variant(
5
- spree_image_variant_options(
6
- resize_to_limit: local_assigns[:in_gallery] ? [ 800, 600 ] : [ 1024, 768 ]
7
- )
8
- )
9
- ) %>
3
+ <%= spree_image_tag(blob, width: local_assigns[:in_gallery] ? 400 : 512, height: local_assigns[:in_gallery] ? 300 : 400) %>
10
4
  <% end %>
11
5
 
12
6
  <figcaption class="attachment__caption">
@@ -5,7 +5,7 @@
5
5
  <%= link_to current_store.url_or_custom_domain, id: 'site-logo', style: "text-decoration: none;" do %>
6
6
  <span style="display: none;"><%= current_store.name %></span>
7
7
  <% if logo.present? && logo.attached? && logo.variable? %>
8
- <% aspect_ratio = as_aspect_ratio(logo) %>
8
+ <% aspect_ratio = spree_asset_aspect_ratio(logo) %>
9
9
  <% logo_style = "aspect-ratio: #{aspect_ratio};" %>
10
10
 
11
11
  <% if aspect_ratio.to_f > 10 %>
@@ -310,6 +310,9 @@ en:
310
310
  spree/address:
311
311
  one: Address
312
312
  other: Addresses
313
+ spree/classification:
314
+ one: Classification
315
+ other: Classifications
313
316
  spree/cms_page:
314
317
  one: Page
315
318
  other: Pages
@@ -328,6 +331,9 @@ en:
328
331
  spree/digital:
329
332
  one: Digital asset
330
333
  other: Digital assets
334
+ spree/export:
335
+ one: Export
336
+ other: Exports
331
337
  spree/inventory_unit:
332
338
  one: Inventory Unit
333
339
  other: Inventory Units
@@ -349,6 +355,9 @@ en:
349
355
  spree/payment_method:
350
356
  one: Payment Method
351
357
  other: Payment Methods
358
+ spree/price:
359
+ one: Price
360
+ other: Prices
352
361
  spree/product:
353
362
  one: Product
354
363
  other: Products
@@ -397,6 +406,9 @@ en:
397
406
  spree/state_change:
398
407
  one: State Change
399
408
  other: State Changes
409
+ spree/stock_item:
410
+ one: Stock Item
411
+ other: Stock Items
400
412
  spree/stock_location:
401
413
  one: Stock Location
402
414
  other: Stock Locations
@@ -406,6 +418,9 @@ en:
406
418
  spree/stock_transfer:
407
419
  one: Stock Transfer
408
420
  other: Stock Transfers
421
+ spree/store:
422
+ one: Store
423
+ other: Stores
409
424
  spree/store_credit:
410
425
  one: Store Credit
411
426
  other: Store Credits
@@ -424,6 +439,9 @@ en:
424
439
  spree/taxonomy:
425
440
  one: Taxonomy
426
441
  other: Taxonomies
442
+ spree/theme:
443
+ one: Theme
444
+ other: Themes
427
445
  spree/tracker:
428
446
  one: Tracker
429
447
  other: Trackers
@@ -1741,7 +1759,6 @@ en:
1741
1759
  sales_totals: Sales Totals
1742
1760
  same_as_shipping_address: Same as shipping address
1743
1761
  save_and_continue: Save and Continue
1744
- save_changes: Save changes
1745
1762
  save_my_address: Save my address
1746
1763
  saving: Saving
1747
1764
  say_no: 'No'
@@ -7,8 +7,10 @@ class AddMultiCodeToSpreePromotions < ActiveRecord::Migration[6.1]
7
7
 
8
8
  add_index :spree_promotions, :kind, if_not_exists: true
9
9
 
10
- Spree::Promotion.reset_column_information
11
- # set all promotions without a code to automatic
12
- Spree::Promotion.where(code: [nil, '']).update_all(kind: 1)
10
+ unless Rails.env.test?
11
+ Spree::Promotion.reset_column_information
12
+ # set all promotions without a code to automatic
13
+ Spree::Promotion.where(code: [nil, '']).update_all(kind: 1)
14
+ end
13
15
  end
14
16
  end
@@ -1,5 +1,5 @@
1
1
  module Spree
2
- VERSION = '5.0.0'.freeze
2
+ VERSION = '5.0.1'.freeze
3
3
 
4
4
  def self.version
5
5
  VERSION
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spree_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.0
4
+ version: 5.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Schofield
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2025-04-03 00:00:00.000000000 Z
13
+ date: 2025-04-09 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: i18n-tasks
@@ -1308,9 +1308,9 @@ licenses:
1308
1308
  - BSD-3-Clause
1309
1309
  metadata:
1310
1310
  bug_tracker_uri: https://github.com/spree/spree/issues
1311
- changelog_uri: https://github.com/spree/spree/releases/tag/v5.0.0
1311
+ changelog_uri: https://github.com/spree/spree/releases/tag/v5.0.1
1312
1312
  documentation_uri: https://docs.spreecommerce.org/
1313
- source_code_uri: https://github.com/spree/spree/tree/v5.0.0
1313
+ source_code_uri: https://github.com/spree/spree/tree/v5.0.1
1314
1314
  post_install_message:
1315
1315
  rdoc_options: []
1316
1316
  require_paths: