spree_core 5.0.4 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8dad7a44435e17f7a0b717356dfe3f8f70cac0e9a18f38f505ded42f3908faf5
4
- data.tar.gz: 109859dd8b1790ab9c0a22c1457e03e81708d79007664f0c8afae841573dd43e
3
+ metadata.gz: f19fd414a37bad67d13a4a491582f6c391ab2677a3ee2a93952e7e8cd52d94d0
4
+ data.tar.gz: 98d87831e0aeed0b5165eb4a38c6198a66423a4b2102a91f529eb2c9941db059
5
5
  SHA512:
6
- metadata.gz: f09637caac881e203c1ff4f1104c2035c89df6cf671d619b7b9e4786a82a4d65332e6537fa4932545e1782203c82f1b41bb6e4c416674df57de95ccbb014410f
7
- data.tar.gz: 2e499043d9f6393d208ce6cdb823059e734748e79924612d408e6de48d5e36c89cb1799405dd62da06e53aa6b8df3693033a267948fb3e6a4fc2077d4efbce2d
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
@@ -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
@@ -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
@@ -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
 
@@ -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
@@ -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
@@ -1481,7 +1487,7 @@ en:
1481
1487
  password_protected: Password protected
1482
1488
  paste: Paste
1483
1489
  path: Path
1484
- pay: pay
1490
+ pay: Pay
1485
1491
  payment: Payment
1486
1492
  payment_amount: Payment amount
1487
1493
  payment_attempts: failed attempts
@@ -1498,11 +1504,11 @@ en:
1498
1504
  payment_source: Payment source
1499
1505
  payment_state: Payment State
1500
1506
  payment_states:
1501
- balance_due: Balance due
1507
+ balance_due: Balance Due
1502
1508
  checkout: Checkout
1503
1509
  complete: Complete
1504
1510
  completed: Completed
1505
- credit_owed: Credit owed
1511
+ credit_owed: Credit Owed
1506
1512
  failed: Failed
1507
1513
  paid: Paid
1508
1514
  partially_refunded: Partially Refunded
@@ -1526,8 +1532,6 @@ en:
1526
1532
  please_check_back_soon: Please check back soon.
1527
1533
  please_define_payment_methods: Please define some payment methods first.
1528
1534
  please_enter_reasonable_quantity: Please enter a reasonable quantity.
1529
- please_select: Please select
1530
- please_select_all_options: Please select all options
1531
1535
  policies: Policies
1532
1536
  populate_get_error: Something went wrong. Please try adding the item again.
1533
1537
  post_categories: Post categories
@@ -1878,6 +1882,7 @@ en:
1878
1882
  show_store_selector:
1879
1883
  long: Display the Store selector in the main nav bar of Storefront and allow users to change Store and Currency
1880
1884
  short: Show Store selector
1885
+ sign_in_with_provider: Sign in with %{provider}
1881
1886
  sign_out: Sign out
1882
1887
  sign_up: Sign Up
1883
1888
  site_name: Site name
@@ -2098,6 +2103,7 @@ en:
2098
2103
  timezone: Timezone
2099
2104
  title: Title
2100
2105
  title_link: Title link
2106
+ to: To
2101
2107
  to_add_variants_you_must_first_define: To add variants, you must first define
2102
2108
  toggle_menu: Toggle menu
2103
2109
  top_suggestions: Top suggestions
@@ -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.4'.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,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
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.4
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-22 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.4
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.4
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: