spree_core 5.0.3 → 5.0.5

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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/app/helpers/spree/base_helper.rb +6 -1
  3. data/app/helpers/spree/images_helper.rb +13 -12
  4. data/app/helpers/spree/mail_helper.rb +4 -3
  5. data/app/models/concerns/spree/payment_source_concern.rb +39 -0
  6. data/app/models/spree/credit_card.rb +2 -24
  7. data/app/models/spree/gateway/custom_payment_source_method.rb +33 -0
  8. data/app/models/spree/option_value.rb +2 -2
  9. data/app/models/spree/order.rb +5 -0
  10. data/app/models/spree/page_blocks/products/buy_buttons.rb +8 -0
  11. data/app/models/spree/page_blocks/products/quantity_selector.rb +4 -0
  12. data/app/models/spree/page_blocks/products/variant_picker.rb +4 -0
  13. data/app/models/spree/page_sections/featured_posts.rb +4 -0
  14. data/app/models/spree/page_sections/featured_product.rb +4 -0
  15. data/app/models/spree/page_sections/image_banner.rb +12 -0
  16. data/app/models/spree/page_sections/image_with_text.rb +12 -0
  17. data/app/models/spree/page_sections/newsletter.rb +1 -1
  18. data/app/models/spree/page_sections/rich_text.rb +11 -0
  19. data/app/models/spree/page_sections/video.rb +8 -0
  20. data/app/models/spree/payment.rb +2 -1
  21. data/app/models/spree/payment_source.rb +21 -0
  22. data/app/models/spree/post.rb +1 -0
  23. data/app/models/spree/product.rb +10 -2
  24. data/app/models/spree/shipment.rb +1 -1
  25. data/app/models/spree/shipping_method.rb +1 -1
  26. data/app/models/spree/store.rb +2 -0
  27. data/app/models/spree/taxon.rb +4 -0
  28. data/app/models/spree/theme.rb +1 -1
  29. data/app/models/spree/variant.rb +9 -1
  30. data/app/models/spree/wishlist.rb +7 -0
  31. data/app/services/spree/products/prepare_nested_attributes.rb +9 -2
  32. data/app/views/spree/shared/_payment.html.erb +9 -0
  33. data/config/locales/en.yml +16 -5
  34. data/lib/spree/core/controller_helpers/auth.rb +1 -0
  35. data/lib/spree/core/controller_helpers/order.rb +2 -1
  36. data/lib/spree/core/engine.rb +1 -0
  37. data/lib/spree/core/version.rb +1 -1
  38. data/lib/spree/permitted_attributes.rb +8 -1
  39. data/lib/spree/testing_support/capybara_config.rb +1 -1
  40. data/lib/spree/testing_support/factories/page_section_factory.rb +4 -0
  41. data/lib/spree/testing_support/factories/payment_factory.rb +5 -0
  42. data/lib/spree/testing_support/factories/payment_method_factory.rb +5 -0
  43. data/lib/spree/testing_support/factories/payment_source_factory.rb +5 -0
  44. data/lib/spree/testing_support/factories/stock_item_factory.rb +5 -1
  45. metadata +7 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 61dc753fc9921cc827589519ccd19bdd4db91ff9ba052174e84e6681578b67a3
4
- data.tar.gz: 9e992274856bc445de5a7b4041126721e992e1554aa0d677ff87c908a52c6cc9
3
+ metadata.gz: f19fd414a37bad67d13a4a491582f6c391ab2677a3ee2a93952e7e8cd52d94d0
4
+ data.tar.gz: 98d87831e0aeed0b5165eb4a38c6198a66423a4b2102a91f529eb2c9941db059
5
5
  SHA512:
6
- metadata.gz: 6a6b74d64d7be259de034cfc831f6eaf9877f9f801a3312adda2af3983060948e8434e2ef4d7ad4b3fdbeac7ff366ae6d87a210b27f7172769abbda9243e46b5
7
- data.tar.gz: f31e47f912ee551e853fe190e1acd34009d3c191cc9666797db4986fbecbb445062e6533de35489998dbdea569d85fd9bf0fd54ee3e27047c5c373e6c2a62ad6
6
+ metadata.gz: a6e96c2e6e5ac2c433392016b01fc5aa6a73a719ce766ba3d6619fae46559b9ca25141be70621d0f31d207a8896a1d79de7dc154d474334af02c46fc9dbe9fba
7
+ data.tar.gz: 524ecf14bf52c91ac982cd6c489d45592eab70e68ed8de95f0565be7740a49a04aac9aeacffe94c3d355b480f68e6af051efd32b5ba2bd2334cdea1f1119f9f9
@@ -242,7 +242,7 @@ module Spree
242
242
  end
243
243
 
244
244
  def spree_base_cache_key
245
- [
245
+ @spree_base_cache_key ||= [
246
246
  I18n.locale,
247
247
  (current_currency if defined?(current_currency)),
248
248
  defined?(try_spree_current_user) && try_spree_current_user.present?,
@@ -258,6 +258,11 @@ module Spree
258
258
  Spree::DatabaseTypeUtilities.maximum_value_for(:integer)
259
259
  end
260
260
 
261
+ def payment_method_icon_tag(payment_method, opts = {})
262
+ image_tag "payment_icons/#{payment_method}.svg", opts
263
+ rescue Sprockets::Rails::Helper::AssetNotFound
264
+ end
265
+
261
266
  private
262
267
 
263
268
  def create_product_image_tag(image, product, options, style)
@@ -18,10 +18,10 @@ module Spree
18
18
  width = options[:width]
19
19
  height = options[:height]
20
20
 
21
- width = width * 2 if width.present?
22
- height = height * 2 if height.present?
21
+ width *= 2 if width.present?
22
+ height *= 2 if height.present?
23
23
 
24
- return unless image.attached?
24
+ return if image.respond_to?(:attached?) && !image.attached?
25
25
  return unless image.variable?
26
26
 
27
27
  if width.present? && height.present?
@@ -51,17 +51,18 @@ module Spree
51
51
  return unless height
52
52
  return if height.zero?
53
53
 
54
- w, h = width.to_f, height.to_f
54
+ w = width.to_f
55
+ h = height.to_f
55
56
 
56
57
  # 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
58
+ ratio = if h > w
59
+ h / w
60
+ elsif h < w
61
+ w / h
62
+ else
63
+ # h == w, square image
64
+ 1.0
65
+ end
65
66
 
66
67
  ratio.round(3)
67
68
  end
@@ -1,10 +1,11 @@
1
1
  module Spree
2
2
  module MailHelper
3
- include BaseHelper
3
+ include Spree::BaseHelper
4
+ include Spree::ImagesHelper
4
5
 
5
6
  def variant_image_url(variant)
6
- image = default_image_for_product_or_variant(variant)
7
- image ? main_app.cdn_image_url(image.url(:small)) : image_url('noimage/small.png')
7
+ image = variant.default_image
8
+ image.present? && image.attached? ? spree_image_url(image, width: 100, height: 100) : image_url('noimage/small.png')
8
9
  end
9
10
 
10
11
  def name_for(order)
@@ -0,0 +1,39 @@
1
+ module Spree
2
+ module PaymentSourceConcern
3
+ extend ActiveSupport::Concern
4
+
5
+ # Available actions for the payment source.
6
+ # @return [Array<String>]
7
+ def actions
8
+ %w{capture void credit}
9
+ end
10
+
11
+ # Indicates whether its possible to capture the payment
12
+ # @param payment [Spree::Payment]
13
+ # @return [Boolean]
14
+ def can_capture?(payment)
15
+ payment.pending? || payment.checkout?
16
+ end
17
+
18
+ # Indicates whether its possible to void the payment.
19
+ # @param payment [Spree::Payment]
20
+ # @return [Boolean]
21
+ def can_void?(payment)
22
+ !payment.failed? && !payment.void?
23
+ end
24
+
25
+ # Indicates whether its possible to credit the payment. Note that most gateways require that the
26
+ # payment be settled first which generally happens within 12-24 hours of the transaction.
27
+ # @param payment [Spree::Payment]
28
+ # @return [Boolean]
29
+ def can_credit?(payment)
30
+ payment.completed? && payment.credit_allowed > 0
31
+ end
32
+
33
+ # Returns true if the payment source has a payment profile.
34
+ # @return [Boolean]
35
+ def has_payment_profile?
36
+ gateway_customer_profile_id.present? || gateway_payment_profile_id.present?
37
+ end
38
+ end
39
+ end
@@ -2,6 +2,8 @@ module Spree
2
2
  class CreditCard < Spree.base_class
3
3
  include ActiveMerchant::Billing::CreditCardMethods
4
4
  include Spree::Metadata
5
+ include Spree::PaymentSourceConcern
6
+
5
7
  if defined?(Spree::Webhooks::HasWebhooks)
6
8
  include Spree::Webhooks::HasWebhooks
7
9
  end
@@ -135,30 +137,6 @@ module Spree
135
137
  brand.present? ? brand.upcase : Spree.t(:no_cc_type)
136
138
  end
137
139
 
138
- def actions
139
- %w{capture void credit}
140
- end
141
-
142
- # Indicates whether its possible to capture the payment
143
- def can_capture?(payment)
144
- payment.pending? || payment.checkout?
145
- end
146
-
147
- # Indicates whether its possible to void the payment.
148
- def can_void?(payment)
149
- !payment.failed? && !payment.void?
150
- end
151
-
152
- # Indicates whether its possible to credit the payment. Note that most gateways require that the
153
- # payment be settled first which generally happens within 12-24 hours of the transaction.
154
- def can_credit?(payment)
155
- payment.completed? && payment.credit_allowed > 0
156
- end
157
-
158
- def has_payment_profile?
159
- gateway_customer_profile_id.present? || gateway_payment_profile_id.present?
160
- end
161
-
162
140
  # ActiveMerchant needs first_name/last_name because we pass it a Spree::CreditCard and it calls those methods on it.
163
141
  # Looking at the ActiveMerchant source code we should probably be calling #to_active_merchant before passing
164
142
  # the object to ActiveMerchant but this should do for now.
@@ -0,0 +1,33 @@
1
+ module Spree
2
+ class Gateway::CustomPaymentSourceMethod < Gateway
3
+ def provider_class
4
+ self.class
5
+ end
6
+
7
+ def payment_source_class
8
+ Spree::PaymentSource
9
+ end
10
+
11
+ def payment_profiles_supported?
12
+ true
13
+ end
14
+
15
+ def show_in_admin?
16
+ false
17
+ end
18
+
19
+ def create_profile(payment)
20
+ return if payment.source.gateway_customer.present?
21
+
22
+ user = payment.source.user || payment.order.user
23
+ return if user.blank?
24
+
25
+ find_or_create_customer(user)
26
+ end
27
+
28
+ # simulate a 3rd party payment gateway api to fetch/or create a customer
29
+ def find_or_create_customer(user)
30
+ gateway_customers.find_or_create_by!(user: user, profile_id: "CUSTOMER-#{user.id}")
31
+ end
32
+ end
33
+ end
@@ -62,9 +62,9 @@ module Spree
62
62
  delegate :name, :presentation, to: :option_type, prefix: true, allow_nil: true
63
63
 
64
64
  def self.to_tom_select_json
65
- all.pluck(:id, :presentation).map do |id, presentation|
65
+ all.pluck(:name, :presentation).map do |name, presentation|
66
66
  {
67
- id: id,
67
+ id: name,
68
68
  name: presentation
69
69
  }
70
70
  end
@@ -443,6 +443,7 @@ module Spree
443
443
  # @return [Array<Spree::Variant>] the backordered variants for the order
444
444
  def backordered_variants
445
445
  variants.
446
+ where(track_inventory: true).
446
447
  joins(:stock_items, :product).
447
448
  where(Spree::StockItem.table_name => { count_on_hand: ..0, backorderable: true })
448
449
  end
@@ -814,6 +815,10 @@ module Spree
814
815
  csv_lines
815
816
  end
816
817
 
818
+ def all_line_items
819
+ line_items
820
+ end
821
+
817
822
  private
818
823
 
819
824
  def link_by_email
@@ -6,6 +6,14 @@ module Spree
6
6
  BOTTOM_PADDING_DEFAULT = 20
7
7
 
8
8
  preference :text_color, :string
9
+
10
+ def icon_name
11
+ 'shopping-cart-plus'
12
+ end
13
+
14
+ def display_name
15
+ Spree.t('page_blocks.products.buy_buttons.display_name')
16
+ end
9
17
  end
10
18
  end
11
19
  end
@@ -6,6 +6,10 @@ module Spree
6
6
  BOTTOM_PADDING_DEFAULT = 20
7
7
 
8
8
  preference :text_color, :string
9
+
10
+ def icon_name
11
+ 'selector'
12
+ end
9
13
  end
10
14
  end
11
15
  end
@@ -3,6 +3,10 @@ module Spree
3
3
  module Products
4
4
  class VariantPicker < Spree::PageBlock
5
5
  preference :text_color, :string
6
+
7
+ def icon_name
8
+ 'select'
9
+ end
6
10
  end
7
11
  end
8
12
  end
@@ -19,6 +19,10 @@ module Spree
19
19
  'news'
20
20
  end
21
21
 
22
+ def posts
23
+ Spree::Post.published.by_newest.limit(preferred_max_posts_to_show)
24
+ end
25
+
22
26
  private
23
27
 
24
28
  def make_posts_to_show_valid
@@ -41,6 +41,10 @@ module Spree
41
41
  def blocks_available?
42
42
  true
43
43
  end
44
+
45
+ def can_sort_blocks?
46
+ true
47
+ end
44
48
  end
45
49
  end
46
50
  end
@@ -26,10 +26,22 @@ module Spree
26
26
  ]
27
27
  end
28
28
 
29
+ def available_blocks_to_add
30
+ [
31
+ Spree::PageBlocks::Buttons,
32
+ Spree::PageBlocks::Heading,
33
+ Spree::PageBlocks::Text
34
+ ]
35
+ end
36
+
29
37
  def blocks_available?
30
38
  true
31
39
  end
32
40
 
41
+ def can_sort_blocks?
42
+ true
43
+ end
44
+
33
45
  def icon_name
34
46
  'slideshow'
35
47
  end
@@ -27,6 +27,14 @@ module Spree
27
27
  ]
28
28
  end
29
29
 
30
+ def available_blocks_to_add
31
+ [
32
+ Spree::PageBlocks::Buttons,
33
+ Spree::PageBlocks::Heading,
34
+ Spree::PageBlocks::Text
35
+ ]
36
+ end
37
+
30
38
  def default_links
31
39
  @default_links.presence || [
32
40
  Spree::PageLink.new(
@@ -40,6 +48,10 @@ module Spree
40
48
  true
41
49
  end
42
50
 
51
+ def can_sort_blocks?
52
+ true
53
+ end
54
+
43
55
  def icon_name
44
56
  'photo'
45
57
  end
@@ -32,7 +32,7 @@ module Spree
32
32
  end
33
33
 
34
34
  def available_blocks_to_add
35
- [Spree::PageBlocks::Image]
35
+ [Spree::PageBlocks::Image, Spree::PageBlocks::Heading, Spree::PageBlocks::Text, Spree::PageBlocks::NewsletterForm]
36
36
  end
37
37
 
38
38
  def can_sort_blocks?
@@ -8,10 +8,21 @@ module Spree
8
8
  ]
9
9
  end
10
10
 
11
+ def available_blocks_to_add
12
+ [
13
+ Spree::PageBlocks::Heading,
14
+ Spree::PageBlocks::Text
15
+ ]
16
+ end
17
+
11
18
  def blocks_available?
12
19
  true
13
20
  end
14
21
 
22
+ def can_sort_blocks?
23
+ true
24
+ end
25
+
15
26
  def icon_name
16
27
  'text-caption'
17
28
  end
@@ -44,6 +44,10 @@ module Spree
44
44
  ]
45
45
  end
46
46
 
47
+ def available_blocks_to_add
48
+ [Spree::PageBlocks::Heading]
49
+ end
50
+
47
51
  def icon_name
48
52
  'movie'
49
53
  end
@@ -52,6 +56,10 @@ module Spree
52
56
  true
53
57
  end
54
58
 
59
+ def can_sort_blocks?
60
+ true
61
+ end
62
+
55
63
  def video_embed
56
64
  @video_embed ||= ::ActionText::VideoEmbed.find_by(id: preferred_youtube_video_embed_id) if preferred_youtube_video_embed_id.present?
57
65
  end
@@ -302,7 +302,8 @@ module Spree
302
302
  # Payment profile cannot be created without source
303
303
  return unless source
304
304
  # Imported payments shouldn't create a payment profile.
305
- return if source.imported
305
+ # Imported is only available on Spree::CreditCard, non-credit card payments should not have this attribute.
306
+ return if source.respond_to?(:imported) && source.imported
306
307
 
307
308
  payment_method.create_profile(self)
308
309
  rescue ActiveMerchant::ConnectionError => e
@@ -1,10 +1,31 @@
1
+ # This model is used to store payment sources for non-credit card payments, eg wallet, account, etc.
1
2
  module Spree
2
3
  class PaymentSource < Spree.base_class
3
4
  include Spree::Metadata
5
+ include Spree::PaymentSourceConcern
4
6
 
7
+ #
8
+ # Associations
9
+ #
5
10
  belongs_to :payment_method, class_name: 'Spree::PaymentMethod'
6
11
  belongs_to :user, class_name: Spree.user_class.to_s, optional: true
7
12
 
13
+ #
14
+ # Validations
15
+ #
8
16
  validates_uniqueness_of :gateway_payment_profile_id, scope: :type
17
+
18
+ #
19
+ # Delegations
20
+ #
21
+ delegate :profile_id, to: :gateway_customer, prefix: true, allow_nil: true
22
+
23
+ # Returns the gateway customer for the user.
24
+ # @return [Spree::GatewayCustomer]
25
+ def gateway_customer
26
+ return if user.blank?
27
+
28
+ payment_method.gateway_customers.find_by(user: user)
29
+ end
9
30
  end
10
31
  end
@@ -54,6 +54,7 @@ module Spree
54
54
  # Scopes
55
55
  #
56
56
  scope :published, -> { where(published_at: [..Time.current]) }
57
+ scope :by_newest, -> { order(created_at: :desc) }
57
58
 
58
59
  delegate :name, to: :author, prefix: true, allow_nil: true
59
60
  delegate :title, to: :post_category, prefix: true, allow_nil: true
@@ -595,7 +595,11 @@ module Spree
595
595
  join_translation_table(Taxonomy).
596
596
  find_by(Taxonomy.translation_table_alias => { name: Spree.t(:taxonomy_brands_name) })
597
597
  else
598
- taxons.joins(:taxonomy).find_by(Taxonomy.table_name => { name: Spree.t(:taxonomy_brands_name) })
598
+ if taxons.loaded?
599
+ taxons.find { |taxon| taxon.taxonomy.name == Spree.t(:taxonomy_brands_name) }
600
+ else
601
+ taxons.joins(:taxonomy).find_by(Taxonomy.table_name => { name: Spree.t(:taxonomy_brands_name) })
602
+ end
599
603
  end
600
604
  end
601
605
 
@@ -606,7 +610,11 @@ module Spree
606
610
  order(depth: :desc).
607
611
  find_by(Taxonomy.translation_table_alias => { name: Spree.t(:taxonomy_categories_name) })
608
612
  else
609
- taxons.joins(:taxonomy).order(depth: :desc).find_by(Taxonomy.table_name => { name: Spree.t(:taxonomy_categories_name) })
613
+ if taxons.loaded?
614
+ taxons.find { |taxon| taxon.taxonomy.name == Spree.t(:taxonomy_categories_name) }
615
+ else
616
+ taxons.joins(:taxonomy).order(depth: :desc).find_by(Taxonomy.table_name => { name: Spree.t(:taxonomy_categories_name) })
617
+ end
610
618
  end
611
619
  end
612
620
 
@@ -430,7 +430,7 @@ module Spree
430
430
  end
431
431
 
432
432
  def manifest_unstock(item)
433
- stock_location.unstock item.variant, item.quantity, self
433
+ stock_location.unstock(item.variant, item.quantity, self) if item.variant.track_inventory?
434
434
  end
435
435
 
436
436
  def recalculate_adjustments
@@ -93,7 +93,7 @@ module Spree
93
93
  if estimated_transit_business_days_min == estimated_transit_business_days_max
94
94
  estimated_transit_business_days_min.to_s
95
95
  else
96
- "#{estimated_transit_business_days_min}-#{estimated_transit_business_days_max}"
96
+ [estimated_transit_business_days_min, estimated_transit_business_days_max].compact.join("-")
97
97
  end
98
98
  end
99
99
 
@@ -338,6 +338,8 @@ module Spree
338
338
  end
339
339
  end
340
340
 
341
+ # Returns the default stock location for the store or creates a new one if it doesn't exist
342
+ # @return [Spree::StockLocation]
341
343
  def default_stock_location
342
344
  @default_stock_location ||= begin
343
345
  stock_location_scope = Spree::StockLocation.order_default
@@ -153,6 +153,10 @@ module Spree
153
153
  sort_order == 'manual'
154
154
  end
155
155
 
156
+ def page_builder_image
157
+ square_image.presence || image
158
+ end
159
+
156
160
  def active_products_with_descendants
157
161
  @active_products_with_descendants ||= store.products.
158
162
  joins(:classifications).
@@ -155,7 +155,7 @@ module Spree
155
155
  end
156
156
  end
157
157
 
158
- # Returns an array of available layout section classes for the theme
158
+ # Returns an array of available layout section classes for the theme, eg. header, footer, newsletter, etc.
159
159
  #
160
160
  # @return [Array<Class>]
161
161
  def available_layout_sections
@@ -73,6 +73,8 @@ module Spree
73
73
  after_create :create_stock_items
74
74
  after_create :set_master_out_of_stock, unless: :is_master?
75
75
  after_commit :clear_line_items_cache, on: :update
76
+
77
+ after_create :create_default_stock_item, unless: :track_inventory?
76
78
  after_update_commit :handle_track_inventory_change
77
79
 
78
80
  after_commit :remove_prices_from_master_variant, on: [:create, :update], unless: :is_master?
@@ -553,11 +555,17 @@ module Spree
553
555
  line_items.update_all(updated_at: Time.current)
554
556
  end
555
557
 
558
+ def create_default_stock_item
559
+ return if stock_items.any?
560
+
561
+ Spree::Store.current.default_stock_location.set_up_stock_item(self)
562
+ end
563
+
556
564
  def handle_track_inventory_change
557
565
  return unless track_inventory_previously_changed?
558
566
  return if track_inventory
559
567
 
560
- stock_items.update_all(backorderable: true, count_on_hand: 0, updated_at: Time.current)
568
+ stock_items.update_all(count_on_hand: 0, updated_at: Time.current)
561
569
  end
562
570
 
563
571
  def remove_prices_from_master_variant
@@ -36,6 +36,13 @@ module Spree
36
36
  @wished_items_count ||= variant_ids.count
37
37
  end
38
38
 
39
+ # returns the variant ids in the wishlist
40
+ #
41
+ # @return [Array<Integer>]
42
+ def variant_ids
43
+ @variant_ids ||= wished_items.pluck(:variant_id)
44
+ end
45
+
39
46
  def self.get_by_param(param)
40
47
  find_by(token: param)
41
48
  end
@@ -136,8 +136,15 @@ module Spree
136
136
  o.position = opt[:position]
137
137
  o.save!
138
138
  end
139
- option_value = option_type.option_values.where(name: opt[:value].parameterize).first_or_initialize do |o|
140
- o.name = o.presentation = opt[:value]
139
+
140
+ option_value_identificator = if opt[:option_value_name].present?
141
+ opt[:option_value_name]
142
+ else
143
+ opt[:option_value_presentation].parameterize
144
+ end
145
+
146
+ option_value = option_type.option_values.where(name: option_value_identificator).first_or_initialize do |o|
147
+ o.name = o.presentation = opt[:option_value_presentation]
141
148
  o.save!
142
149
  end
143
150
 
@@ -30,6 +30,15 @@
30
30
  <div class="flex-shrink-0">
31
31
  <%= payment_method_icon_tag source.class.to_s.demodulize.downcase, height: 30 %>
32
32
  </div>
33
+ <div>
34
+ <% if payment.payment_method.respond_to?(:source_partial_name) %>
35
+ <%= render partial: "spree/payment_sources/#{payment.payment_method.source_partial_name}", locals: { payment: payment, source: source } %>
36
+ <% elsif source.respond_to?(:name) %>
37
+ <%= source.name %>
38
+ <% else %>
39
+ <%= source.class.to_s.demodulize.downcase %>
40
+ <% end %>
41
+ </div>
33
42
  <% else %>
34
43
  <div class="flex-shrink-0">
35
44
  <%= payment_method_icon_tag payment.payment_method.payment_icon_name %>
@@ -716,6 +716,7 @@ en:
716
716
  capture: Capture
717
717
  capture_events: Capture events
718
718
  card_code: Card Verification Code (CVC)
719
+ card_expiration_placeholder: MM/YYYY
719
720
  card_number: Card Number
720
721
  card_type: Brand
721
722
  card_type_is: Card type is
@@ -891,6 +892,8 @@ en:
891
892
  destroy: Destroy
892
893
  details: Details
893
894
  developers: Developers
895
+ didn_t_receive_confirmation_instructions: Didn't receive confirmation instructions?
896
+ didn_t_receive_unlock_instructions: Didn't receive unlock instructions?
894
897
  digital:
895
898
  digital_delivery: Digital Delivery
896
899
  digital_assets: Digital assets
@@ -1208,6 +1211,9 @@ en:
1208
1211
  metadata: Metadata
1209
1212
  min: Min
1210
1213
  minimal_amount: Minimal Amount
1214
+ minimum_password_length:
1215
+ one: "(%{count} character minimum)"
1216
+ other: "(%{count} characters minimum)"
1211
1217
  missing_return_authorization: Missing Return Authorization for %{item_name}.
1212
1218
  month: Month
1213
1219
  more: More
@@ -1429,6 +1435,9 @@ en:
1429
1435
  newsletter_form:
1430
1436
  button_text_default: Submit
1431
1437
  placeholder_default: Enter your email
1438
+ products:
1439
+ buy_buttons:
1440
+ display_name: Add To Cart
1432
1441
  page_not_found: Sorry! Page you are looking can’t be found.
1433
1442
  page_sections:
1434
1443
  announcement_bar:
@@ -1478,7 +1487,7 @@ en:
1478
1487
  password_protected: Password protected
1479
1488
  paste: Paste
1480
1489
  path: Path
1481
- pay: pay
1490
+ pay: Pay
1482
1491
  payment: Payment
1483
1492
  payment_amount: Payment amount
1484
1493
  payment_attempts: failed attempts
@@ -1495,11 +1504,11 @@ en:
1495
1504
  payment_source: Payment source
1496
1505
  payment_state: Payment State
1497
1506
  payment_states:
1498
- balance_due: Balance due
1507
+ balance_due: Balance Due
1499
1508
  checkout: Checkout
1500
1509
  complete: Complete
1501
1510
  completed: Completed
1502
- credit_owed: Credit owed
1511
+ credit_owed: Credit Owed
1503
1512
  failed: Failed
1504
1513
  paid: Paid
1505
1514
  partially_refunded: Partially Refunded
@@ -1523,8 +1532,6 @@ en:
1523
1532
  please_check_back_soon: Please check back soon.
1524
1533
  please_define_payment_methods: Please define some payment methods first.
1525
1534
  please_enter_reasonable_quantity: Please enter a reasonable quantity.
1526
- please_select: Please select
1527
- please_select_all_options: Please select all options
1528
1535
  policies: Policies
1529
1536
  populate_get_error: Something went wrong. Please try adding the item again.
1530
1537
  post_categories: Post categories
@@ -1875,6 +1882,7 @@ en:
1875
1882
  show_store_selector:
1876
1883
  long: Display the Store selector in the main nav bar of Storefront and allow users to change Store and Currency
1877
1884
  short: Show Store selector
1885
+ sign_in_with_provider: Sign in with %{provider}
1878
1886
  sign_out: Sign out
1879
1887
  sign_up: Sign Up
1880
1888
  site_name: Site name
@@ -2095,6 +2103,7 @@ en:
2095
2103
  timezone: Timezone
2096
2104
  title: Title
2097
2105
  title_link: Title link
2106
+ to: To
2098
2107
  to_add_variants_you_must_first_define: To add variants, you must first define
2099
2108
  toggle_menu: Toggle menu
2100
2109
  top_suggestions: Top suggestions
@@ -2119,6 +2128,7 @@ en:
2119
2128
  translations_for: "%{resource_name} translations"
2120
2129
  tree: Tree
2121
2130
  true_label: 'TRUE'
2131
+ try_removing_filters: Try removing some filters to see more products
2122
2132
  twitter: Twitter
2123
2133
  type: Type
2124
2134
  type_to_search: Type to search
@@ -2140,6 +2150,7 @@ en:
2140
2150
  update_contact_information: Update contact information
2141
2151
  update_shipping_address: Update shipping address
2142
2152
  updated: Updated
2153
+ updated_at: Updated at
2143
2154
  updating: Updating
2144
2155
  upload_image: Upload image
2145
2156
  url: URL
@@ -26,6 +26,7 @@ module Spree
26
26
  end
27
27
 
28
28
  def set_token
29
+ Spree::Deprecation.warn('set_token is deprecated and will be removed in Spree 5.2. Please use create_token_cookie(token) instead.')
29
30
  cookies.permanent.signed[:token] ||= cookies.signed[:guest_token]
30
31
  cookies.permanent.signed[:token] ||= {
31
32
  value: generate_token,
@@ -118,7 +118,8 @@ module Spree
118
118
  value: token,
119
119
  expires: 90.days.from_now,
120
120
  secure: Rails.configuration.force_ssl || Rails.application.config.ssl_options[:secure_cookies],
121
- domain: current_store.url_or_custom_domain
121
+ domain: current_store.url_or_custom_domain,
122
+ httponly: true
122
123
  }
123
124
  end
124
125
 
@@ -96,6 +96,7 @@ module Spree
96
96
  Rails.application.config.spree.payment_methods = [
97
97
  Spree::Gateway::Bogus,
98
98
  Spree::Gateway::BogusSimple,
99
+ Spree::Gateway::CustomPaymentSourceMethod,
99
100
  Spree::PaymentMethod::Check,
100
101
  Spree::PaymentMethod::StoreCredit
101
102
  ]
@@ -1,5 +1,5 @@
1
1
  module Spree
2
- VERSION = '5.0.3'.freeze
2
+ VERSION = '5.0.5'.freeze
3
3
 
4
4
  def self.version
5
5
  VERSION
@@ -165,7 +165,14 @@ module Spree
165
165
  :product_id, :product, :option_values_attributes, :price, :compare_at_price,
166
166
  :weight, :height, :width, :depth, :sku, :barcode, :cost_currency,
167
167
  :weight_unit, :dimensions_unit,
168
- { options: [:name, :value], option_value_ids: [] }
168
+ {
169
+ options: [:id, :name, :option_value_presentation, :option_value_name, :position, :_destroy],
170
+ stock_items_attributes: [:id, :count_on_hand, :stock_location_id, :backorderable, :_destroy],
171
+ prices_attributes: [:id, :amount, :compare_at_amount, :currency, :_destroy],
172
+ price: {},
173
+ option_value_variants_attributes: [:id, :option_value_id, :_destroy],
174
+ option_value_ids: []
175
+ }
169
176
  ]
170
177
 
171
178
  @@wishlist_attributes = [:name, :is_default, :is_private]
@@ -20,7 +20,7 @@ Capybara.register_driver :selenium_chrome_headless do |app|
20
20
  options = ::Selenium::WebDriver::Chrome::Options.new
21
21
  options.add_argument '--headless'
22
22
  options.add_argument '--disable-gpu'
23
- options.add_argument '--window-size=1400,900'
23
+ options.add_argument '--window-size=1440,900'
24
24
  options.add_argument '--disable-search-engine-choice-screen'
25
25
 
26
26
  # Disable timers being throttled in background pages/tabs. Useful for parallel test runs.
@@ -20,5 +20,9 @@ FactoryBot.define do
20
20
  factory :newsletter_page_section, class: Spree::PageSections::Newsletter
21
21
 
22
22
  factory :video_page_section, class: Spree::PageSections::Video
23
+
24
+ factory :image_with_text_page_section, class: Spree::PageSections::ImageWithText
25
+
26
+ factory :featured_posts_page_section, class: Spree::PageSections::FeaturedPosts
23
27
  end
24
28
  end
@@ -14,6 +14,11 @@ FactoryBot.define do
14
14
  create(:refund, amount: 5, payment: payment)
15
15
  end
16
16
  end
17
+
18
+ factory :custom_payment, class: Spree::Payment do
19
+ payment_method { create(:custom_payment_method, stores: [order.store]) }
20
+ source { create(:payment_source, user: order.user, payment_method: payment_method) }
21
+ end
17
22
  end
18
23
 
19
24
  factory :check_payment, class: Spree::Payment do
@@ -37,4 +37,9 @@ FactoryBot.define do
37
37
  active { true }
38
38
  auto_capture { true }
39
39
  end
40
+
41
+ factory :custom_payment_method, parent: :payment_method, class: Spree::Gateway::CustomPaymentSourceMethod do
42
+ type { 'Spree::Gateway::CustomPaymentSourceMethod' }
43
+ name { 'Custom' }
44
+ end
40
45
  end
@@ -0,0 +1,5 @@
1
+ FactoryBot.define do
2
+ factory :payment_source, class: Spree::PaymentSource do
3
+ association(:payment_method, factory: :custom_payment_method)
4
+ end
5
+ end
@@ -11,6 +11,10 @@ FactoryBot.define do
11
11
  )&.destroy
12
12
  end
13
13
 
14
- after(:create) { |object| object.adjust_count_on_hand(10) }
14
+ transient do
15
+ adjust_count_on_hand { true }
16
+ end
17
+
18
+ after(:create) { |object, evaluator| object.adjust_count_on_hand(10) if evaluator.adjust_count_on_hand }
15
19
  end
16
20
  end
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.3
4
+ version: 5.0.5
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-05-06 00:00:00.000000000 Z
13
+ date: 2025-06-30 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: i18n-tasks
@@ -603,6 +603,7 @@ files:
603
603
  - app/models/concerns/spree/number_as_param.rb
604
604
  - app/models/concerns/spree/number_identifier.rb
605
605
  - app/models/concerns/spree/parameterizable_name.rb
606
+ - app/models/concerns/spree/payment_source_concern.rb
606
607
  - app/models/concerns/spree/previewable.rb
607
608
  - app/models/concerns/spree/product_scopes.rb
608
609
  - app/models/concerns/spree/ransackable_attributes.rb
@@ -666,6 +667,7 @@ files:
666
667
  - app/models/spree/gateway.rb
667
668
  - app/models/spree/gateway/bogus.rb
668
669
  - app/models/spree/gateway/bogus_simple.rb
670
+ - app/models/spree/gateway/custom_payment_source_method.rb
669
671
  - app/models/spree/gateway_customer.rb
670
672
  - app/models/spree/image.rb
671
673
  - app/models/spree/image/configuration/active_storage.rb
@@ -1229,6 +1231,7 @@ files:
1229
1231
  - lib/spree/testing_support/factories/payment_capture_event_factory.rb
1230
1232
  - lib/spree/testing_support/factories/payment_factory.rb
1231
1233
  - lib/spree/testing_support/factories/payment_method_factory.rb
1234
+ - lib/spree/testing_support/factories/payment_source_factory.rb
1232
1235
  - lib/spree/testing_support/factories/post_category_factory.rb
1233
1236
  - lib/spree/testing_support/factories/post_factory.rb
1234
1237
  - lib/spree/testing_support/factories/price_factory.rb
@@ -1308,9 +1311,9 @@ licenses:
1308
1311
  - BSD-3-Clause
1309
1312
  metadata:
1310
1313
  bug_tracker_uri: https://github.com/spree/spree/issues
1311
- changelog_uri: https://github.com/spree/spree/releases/tag/v5.0.3
1314
+ changelog_uri: https://github.com/spree/spree/releases/tag/v5.0.5
1312
1315
  documentation_uri: https://docs.spreecommerce.org/
1313
- source_code_uri: https://github.com/spree/spree/tree/v5.0.3
1316
+ source_code_uri: https://github.com/spree/spree/tree/v5.0.5
1314
1317
  post_install_message:
1315
1318
  rdoc_options: []
1316
1319
  require_paths: