spree_core 5.4.0.beta → 5.4.0.beta3
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/finders/spree/products/find.rb +2 -42
- data/app/helpers/spree/base_helper.rb +1 -54
- data/app/mailers/spree/base_mailer.rb +4 -3
- data/app/models/concerns/spree/adjustment_source.rb +0 -8
- data/app/models/concerns/spree/admin_user_methods.rb +0 -2
- data/app/models/concerns/spree/image_methods.rb +4 -0
- data/app/models/concerns/spree/metadata.rb +10 -0
- data/app/models/concerns/spree/product_scopes.rb +21 -49
- data/app/models/concerns/spree/stores/markets.rb +7 -7
- data/app/models/concerns/spree/vat_price_calculation.rb +2 -2
- data/app/models/spree/ability.rb +5 -5
- data/app/models/spree/address.rb +3 -2
- data/app/models/spree/adjustable/promotion_accumulator.rb +1 -1
- data/app/models/spree/adjustment.rb +1 -20
- data/app/models/spree/api_key.rb +60 -2
- data/app/models/spree/country.rb +7 -3
- data/app/models/spree/credit_card.rb +0 -27
- data/app/models/spree/current.rb +38 -2
- data/app/models/spree/exports/products.rb +0 -6
- data/app/models/spree/gateway/bogus.rb +9 -9
- data/app/models/spree/gateway.rb +0 -3
- data/app/models/spree/gift_card_batch.rb +4 -0
- data/app/models/spree/image/configuration/active_storage.rb +0 -2
- data/app/models/spree/image.rb +7 -31
- data/app/models/spree/log_entry.rb +8 -5
- data/app/models/spree/market.rb +1 -2
- data/app/models/spree/market_country.rb +17 -0
- data/app/models/spree/newsletter_subscriber.rb +0 -3
- data/app/models/spree/order/checkout.rb +0 -18
- data/app/models/spree/order.rb +22 -16
- data/app/models/spree/payment/gateway_options.rb +2 -2
- data/app/models/spree/payment/processing.rb +5 -5
- data/app/models/spree/payment.rb +1 -1
- data/app/models/spree/payment_connection_error.rb +3 -0
- data/app/models/spree/payment_method/check.rb +1 -1
- data/app/models/spree/payment_method/store_credit.rb +5 -5
- data/app/models/spree/payment_response.rb +70 -0
- data/app/models/spree/permission_sets/default_customer.rb +0 -5
- data/app/models/spree/permission_sets/product_display.rb +0 -2
- data/app/models/spree/permission_sets/product_management.rb +0 -2
- data/app/models/spree/product.rb +5 -85
- data/app/models/spree/promotion.rb +2 -14
- data/app/models/spree/promotion_handler/coupon.rb +3 -3
- data/app/models/spree/prototype.rb +0 -3
- data/app/models/spree/refund.rb +6 -2
- data/app/models/spree/reimbursement.rb +0 -2
- data/app/models/spree/shipment.rb +0 -1
- data/app/models/spree/shipment_handler.rb +0 -2
- data/app/models/spree/shipping_category.rb +3 -3
- data/app/models/spree/store.rb +10 -49
- data/app/models/spree/store_credit.rb +4 -0
- data/app/models/spree/tax_category.rb +1 -11
- data/app/models/spree/taxon.rb +0 -16
- data/app/models/spree/variant.rb +2 -40
- data/app/models/spree/zone.rb +1 -4
- data/app/services/spree/cart/add_item.rb +8 -4
- data/app/services/spree/cart/create.rb +13 -2
- data/app/services/spree/newsletter/subscribe.rb +2 -2
- data/app/services/spree/products/duplicator.rb +0 -12
- data/app/services/spree/products/prepare_nested_attributes.rb +0 -12
- data/app/subscribers/spree/invitation_email_subscriber.rb +1 -1
- data/config/locales/en.yml +4 -20
- data/db/migrate/20210914000000_spree_four_three.rb +0 -38
- data/db/migrate/20210915064329_add_metadata_to_spree_multiple_tables.rb +0 -1
- data/db/migrate/20260226000000_add_locale_to_spree_orders.rb +5 -0
- data/db/migrate/20260226100000_add_token_digest_to_spree_api_keys.rb +21 -0
- data/lib/spree/core/configuration.rb +0 -3
- data/lib/spree/core/controller_helpers/strong_parameters.rb +1 -2
- data/lib/spree/core/dependencies.rb +2 -10
- data/lib/spree/core/engine.rb +0 -13
- data/lib/spree/core/pricing/resolver.rb +1 -9
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/core.rb +10 -26
- data/lib/spree/permitted_attributes.rb +2 -14
- data/lib/spree/testing_support/factories/order_factory.rb +1 -0
- data/lib/spree/testing_support/factories/payment_method_factory.rb +1 -6
- data/lib/spree/testing_support/factories/product_factory.rb +0 -7
- data/lib/spree/testing_support/factories/prototype_factory.rb +0 -2
- data/lib/tasks/cli.rake +50 -0
- data/lib/tasks/core.rake +0 -265
- metadata +9 -111
- data/app/finders/spree/posts/find.rb +0 -137
- data/app/finders/spree/product_properties/find_available.rb +0 -20
- data/app/helpers/spree/mail_helper.rb +0 -27
- data/app/jobs/spree/api_key_touch_job.rb +0 -9
- data/app/mailers/spree/test_mailer.rb +0 -8
- data/app/models/action_text/video_embed.rb +0 -13
- data/app/models/concerns/spree/filter_param.rb +0 -21
- data/app/models/concerns/spree/has_one_link.rb +0 -42
- data/app/models/concerns/spree/linkable.rb +0 -9
- data/app/models/concerns/spree/previewable.rb +0 -17
- data/app/models/spree/data_feed/google.rb +0 -15
- data/app/models/spree/data_feed.rb +0 -42
- data/app/models/spree/gateway/bogus_simple.rb +0 -24
- data/app/models/spree/newsletter_subscriber/emails.rb +0 -12
- data/app/models/spree/order/emails.rb +0 -24
- data/app/models/spree/post.rb +0 -108
- data/app/models/spree/post_category.rb +0 -46
- data/app/models/spree/product_property.rb +0 -51
- data/app/models/spree/property.rb +0 -86
- data/app/models/spree/property_prototype.rb +0 -9
- data/app/models/spree/reimbursement/emails.rb +0 -11
- data/app/models/spree/shipment/emails.rb +0 -11
- data/app/models/spree/store_favicon_image.rb +0 -20
- data/app/models/spree/store_logo.rb +0 -4
- data/app/models/spree/store_mailer_logo.rb +0 -7
- data/app/models/spree/taxon_image/configuration/active_storage.rb +0 -26
- data/app/models/spree/taxon_image.rb +0 -28
- data/app/presenters/spree/filters/properties_presenter.rb +0 -23
- data/app/presenters/spree/filters/property_presenter.rb +0 -42
- data/app/services/spree/data_feeds/google/optional_attributes.rb +0 -23
- data/app/services/spree/data_feeds/google/optional_sub_attributes.rb +0 -21
- data/app/services/spree/data_feeds/google/products_list.rb +0 -14
- data/app/services/spree/data_feeds/google/required_attributes.rb +0 -68
- data/app/services/spree/data_feeds/google/rss.rb +0 -109
- data/app/sorters/spree/posts/sort.rb +0 -40
- data/app/views/action_text/video_embeds/_thumbnail.html.erb +0 -1
- data/app/views/action_text/video_embeds/_video_embed.html.erb +0 -3
- data/app/views/layouts/action_text/contents/_content.html.erb +0 -3
- data/app/views/spree/test_mailer/test_email.html.erb +0 -40
- data/app/views/spree/test_mailer/test_email.text.erb +0 -4
- data/config/initializers/oembed.rb +0 -1
- data/db/migrate/20221229132350_create_spree_data_feed_settings.rb +0 -14
- data/db/migrate/20230109084253_create_product_property_translations.rb +0 -24
- data/db/migrate/20230109105943_create_property_translations.rb +0 -24
- data/db/migrate/20230415155958_rename_data_feed_settings_table.rb +0 -5
- data/db/migrate/20230415160828_rename_data_feed_table_columns.rb +0 -7
- data/db/migrate/20230415161226_add_indexes_to_data_feeds_table.rb +0 -5
- data/db/migrate/20230512094803_rename_data_feeds_column_provider_to_type.rb +0 -5
- data/db/migrate/20240914153106_add_display_on_to_spree_properties.rb +0 -5
- data/db/migrate/20240915144935_add_position_to_spree_properties.rb +0 -6
- data/db/migrate/20250121160028_create_spree_posts_and_spree_post_categories.rb +0 -33
- data/db/migrate/20250127083740_add_kind_to_spree_properties.rb +0 -5
- data/db/migrate/20250217171018_create_action_text_video_embeds.rb +0 -11
- data/db/migrate/20250305121657_remove_spree_posts_indices.rb +0 -7
- data/db/migrate/20250730154601_add_unique_index_on_spree_properties_name.rb +0 -24
- data/db/sample_data/posts.rb +0 -7
- data/lib/generators/spree/cursor_rules/cursor_rules_generator.rb +0 -19
- data/lib/generators/spree/cursor_rules/templates/spree_rules.mdc +0 -387
- data/lib/spree/core/controller_helpers/search.rb +0 -17
- data/lib/spree/core/importer/order.rb +0 -244
- data/lib/spree/core/importer/product.rb +0 -67
- data/lib/spree/core/importer.rb +0 -9
- data/lib/spree/core/product_filters.rb +0 -218
- data/lib/spree/core/query_filters/comparable.rb +0 -50
- data/lib/spree/core/query_filters/date.rb +0 -8
- data/lib/spree/core/query_filters/number.rb +0 -8
- data/lib/spree/core/query_filters/text.rb +0 -36
- data/lib/spree/core/query_filters.rb +0 -11
- data/lib/spree/core/search/base.rb +0 -144
- data/lib/spree/testing_support/factories/favicon_image_factory.rb +0 -9
- data/lib/spree/testing_support/factories/google_data_feed_factory.rb +0 -7
- data/lib/spree/testing_support/factories/post_category_factory.rb +0 -7
- data/lib/spree/testing_support/factories/post_factory.rb +0 -22
- data/lib/spree/testing_support/factories/product_property_factory.rb +0 -7
- data/lib/spree/testing_support/factories/property_factory.rb +0 -28
- data/lib/spree/testing_support/factories/taxon_image_factory.rb +0 -9
- data/lib/spree/testing_support/flash.rb +0 -25
- data/lib/spree/testing_support/flatpickr_capybara.rb +0 -124
- data/lib/tasks/exchanges.rake +0 -66
data/app/models/spree/country.rb
CHANGED
|
@@ -43,7 +43,7 @@ module Spree
|
|
|
43
43
|
#
|
|
44
44
|
# @return [String, nil] currency code (e.g., 'USD', 'EUR') or nil if no market found
|
|
45
45
|
def market_currency
|
|
46
|
-
|
|
46
|
+
current_market&.currency
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
# Returns the default locale for this country from its market in the current store.
|
|
@@ -51,14 +51,18 @@ module Spree
|
|
|
51
51
|
#
|
|
52
52
|
# @return [String, nil] locale code (e.g., 'en', 'de') or nil if no market found
|
|
53
53
|
def market_locale
|
|
54
|
-
|
|
54
|
+
current_market&.default_locale
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
# Returns the supported locales for this country from its market in the current store.
|
|
58
58
|
#
|
|
59
59
|
# @return [Array<String>] locale codes (e.g., ['en', 'fr']) or empty array if no market found
|
|
60
60
|
def market_supported_locales
|
|
61
|
-
|
|
61
|
+
current_market&.supported_locales_list || []
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def current_market
|
|
65
|
+
@current_market ||= Spree::Current.store&.market_for_country(self)
|
|
62
66
|
end
|
|
63
67
|
|
|
64
68
|
def <=>(other)
|
|
@@ -2,7 +2,6 @@ module Spree
|
|
|
2
2
|
class CreditCard < Spree.base_class
|
|
3
3
|
has_prefix_id :card # Stripe: card_
|
|
4
4
|
|
|
5
|
-
include ActiveMerchant::Billing::CreditCardMethods
|
|
6
5
|
include Spree::Metafields
|
|
7
6
|
include Spree::Metadata
|
|
8
7
|
include Spree::PaymentSourceConcern
|
|
@@ -48,7 +47,6 @@ module Spree
|
|
|
48
47
|
}
|
|
49
48
|
scope :not_removed, -> { where(deleted_at: nil) }
|
|
50
49
|
|
|
51
|
-
# needed for some of the ActiveMerchant gateways (eg. SagePay)
|
|
52
50
|
alias_attribute :brand, :cc_type
|
|
53
51
|
|
|
54
52
|
store_accessor :private_metadata, :wallet
|
|
@@ -59,14 +57,6 @@ module Spree
|
|
|
59
57
|
wallet&.[]('type')
|
|
60
58
|
end
|
|
61
59
|
|
|
62
|
-
# ActiveMerchant::Billing::CreditCard added this accessor used by some gateways.
|
|
63
|
-
# More info: https://github.com/spree/spree/issues/6209
|
|
64
|
-
#
|
|
65
|
-
# Returns or sets the track data for the card
|
|
66
|
-
#
|
|
67
|
-
# @return [String]
|
|
68
|
-
attr_accessor :track_data
|
|
69
|
-
|
|
70
60
|
CARD_TYPES = {
|
|
71
61
|
visa: /^4\d{12}(\d{3})?(\d{3})?$/,
|
|
72
62
|
master: /^(5[1-5]\d{4}|677189|222[1-9]\d{2}|22[3-9]\d{3}|2[3-6]\d{4}|27[01]\d{3}|2720\d{2})\d{10}$/,
|
|
@@ -151,10 +141,6 @@ module Spree
|
|
|
151
141
|
brand.present? ? brand.upcase : Spree.t(:no_cc_type)
|
|
152
142
|
end
|
|
153
143
|
|
|
154
|
-
# ActiveMerchant needs first_name/last_name because we pass it a Spree::CreditCard and it calls those methods on it.
|
|
155
|
-
# Looking at the ActiveMerchant source code we should probably be calling #to_active_merchant before passing
|
|
156
|
-
# the object to ActiveMerchant but this should do for now.
|
|
157
|
-
#
|
|
158
144
|
# Returns the first name of the cardholder.
|
|
159
145
|
# @return [String]
|
|
160
146
|
def first_name
|
|
@@ -167,19 +153,6 @@ module Spree
|
|
|
167
153
|
name.to_s.split(/[[:space:]]/, 2)[1]
|
|
168
154
|
end
|
|
169
155
|
|
|
170
|
-
# Returns an ActiveMerchant::Billing::CreditCard object.
|
|
171
|
-
# @return [ActiveMerchant::Billing::CreditCard]
|
|
172
|
-
def to_active_merchant
|
|
173
|
-
ActiveMerchant::Billing::CreditCard.new(
|
|
174
|
-
number: number,
|
|
175
|
-
month: month,
|
|
176
|
-
year: year,
|
|
177
|
-
verification_value: verification_value,
|
|
178
|
-
first_name: first_name,
|
|
179
|
-
last_name: last_name
|
|
180
|
-
)
|
|
181
|
-
end
|
|
182
|
-
|
|
183
156
|
def self.json_api_permitted_attributes
|
|
184
157
|
[
|
|
185
158
|
'number', 'month', 'year', 'expiry', 'verification_value', 'first_name', 'last_name',
|
data/app/models/spree/current.rb
CHANGED
|
@@ -1,23 +1,57 @@
|
|
|
1
1
|
module Spree
|
|
2
|
+
# Thread-safe, per-request attributes for the current store context.
|
|
3
|
+
#
|
|
4
|
+
# All attributes are automatically reset between requests by Rails.
|
|
5
|
+
# Fallback chains ensure sensible defaults when attributes are not explicitly set.
|
|
2
6
|
class Current < ::ActiveSupport::CurrentAttributes
|
|
3
|
-
attribute :store, :market, :currency, :zone, :price_lists, :global_pricing_context
|
|
7
|
+
attribute :store, :market, :currency, :locale, :zone, :default_tax_zone, :price_lists, :global_pricing_context
|
|
4
8
|
|
|
9
|
+
resets { @default_tax_zone_loaded = false }
|
|
10
|
+
|
|
11
|
+
# Returns the current store, falling back to the default store.
|
|
12
|
+
# @return [Spree::Store]
|
|
5
13
|
def store
|
|
6
14
|
super || Spree::Store.default
|
|
7
15
|
end
|
|
8
16
|
|
|
17
|
+
# Returns the current market, falling back to the store's default market.
|
|
18
|
+
# @return [Spree::Market, nil]
|
|
9
19
|
def market
|
|
10
20
|
super || store&.default_market
|
|
11
21
|
end
|
|
12
22
|
|
|
23
|
+
# Returns the current currency.
|
|
24
|
+
# Fallback: market currency -> store default currency.
|
|
25
|
+
# @return [String] currency ISO code, e.g. +"USD"+
|
|
13
26
|
def currency
|
|
14
27
|
super || market&.currency || store&.default_currency
|
|
15
28
|
end
|
|
16
29
|
|
|
30
|
+
# Returns the current locale.
|
|
31
|
+
# Fallback: market default locale -> store default locale.
|
|
32
|
+
# @return [String] locale code, e.g. +"en"+, +"de"+
|
|
33
|
+
def locale
|
|
34
|
+
super || market&.default_locale || store&.default_locale
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Returns the current tax zone, falling back to the default tax zone.
|
|
38
|
+
# @return [Spree::Zone, nil]
|
|
17
39
|
def zone
|
|
18
|
-
super ||
|
|
40
|
+
super || default_tax_zone
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Returns the default tax zone (memoized per request).
|
|
44
|
+
# @return [Spree::Zone, nil]
|
|
45
|
+
def default_tax_zone
|
|
46
|
+
result = super
|
|
47
|
+
return result if result || @default_tax_zone_loaded
|
|
48
|
+
|
|
49
|
+
@default_tax_zone_loaded = true
|
|
50
|
+
self.default_tax_zone = Spree::Zone.find_by(default_tax: true)
|
|
19
51
|
end
|
|
20
52
|
|
|
53
|
+
# Returns the current price lists for the global pricing context.
|
|
54
|
+
# @return [ActiveRecord::Relation<Spree::PriceList>]
|
|
21
55
|
def price_lists
|
|
22
56
|
super || begin
|
|
23
57
|
context = global_pricing_context
|
|
@@ -25,6 +59,8 @@ module Spree
|
|
|
25
59
|
end
|
|
26
60
|
end
|
|
27
61
|
|
|
62
|
+
# Returns the current global pricing context, built from store, currency, zone, and market.
|
|
63
|
+
# @return [Spree::Pricing::Context]
|
|
28
64
|
def global_pricing_context
|
|
29
65
|
super || begin
|
|
30
66
|
self.global_pricing_context = Spree::Pricing::Context.new(
|
|
@@ -4,7 +4,6 @@ module Spree
|
|
|
4
4
|
# to avoid N+1 queries
|
|
5
5
|
def scope_includes
|
|
6
6
|
includes = [:tax_category, :master, :option_types, { taxons: :taxonomy }, { variants_including_master: variant_includes }]
|
|
7
|
-
includes << { product_properties: [:property] } if Spree::Config[:product_properties_enabled]
|
|
8
7
|
includes << { metafields: :metafield_definition }
|
|
9
8
|
includes
|
|
10
9
|
end
|
|
@@ -28,14 +27,9 @@ module Spree
|
|
|
28
27
|
|
|
29
28
|
def csv_headers
|
|
30
29
|
headers = Spree::CSV::ProductVariantPresenter::CSV_HEADERS.dup
|
|
31
|
-
headers += properties_headers if Spree::Config[:product_properties_enabled]
|
|
32
30
|
headers += metafields_headers
|
|
33
31
|
@csv_headers ||= headers
|
|
34
32
|
end
|
|
35
|
-
|
|
36
|
-
def properties_headers
|
|
37
|
-
@properties_headers ||= Spree::Property.order(:position).count.times.flat_map { |n| ["property#{n + 1}_name", "property#{n + 1}_value"] }
|
|
38
|
-
end
|
|
39
33
|
end
|
|
40
34
|
end
|
|
41
35
|
end
|
|
@@ -32,39 +32,39 @@ module Spree
|
|
|
32
32
|
def authorize(_money, credit_card, _options = {})
|
|
33
33
|
profile_id = credit_card.gateway_customer_profile_id
|
|
34
34
|
if VALID_CCS.include?(credit_card.number) || (profile_id&.starts_with?('BGS-'))
|
|
35
|
-
|
|
35
|
+
Spree::PaymentResponse.new(true, 'Bogus Gateway: Forced success', {}, test: true, authorization: '12345', avs_result: { code: 'D' })
|
|
36
36
|
else
|
|
37
|
-
|
|
37
|
+
Spree::PaymentResponse.new(false, 'Bogus Gateway: Forced failure', { message: 'Bogus Gateway: Forced failure' }, test: true)
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
def purchase(_money, credit_card, _options = {})
|
|
42
42
|
profile_id = credit_card.gateway_customer_profile_id
|
|
43
43
|
if VALID_CCS.include?(credit_card.number) || (profile_id&.starts_with?('BGS-'))
|
|
44
|
-
|
|
44
|
+
Spree::PaymentResponse.new(true, 'Bogus Gateway: Forced success', {}, test: true, authorization: '12345', avs_result: { code: 'M' })
|
|
45
45
|
else
|
|
46
|
-
|
|
46
|
+
Spree::PaymentResponse.new(false, 'Bogus Gateway: Forced failure', message: 'Bogus Gateway: Forced failure', test: true)
|
|
47
47
|
end
|
|
48
48
|
end
|
|
49
49
|
|
|
50
50
|
def credit(_money, _credit_card, _response_code, _options = {})
|
|
51
|
-
|
|
51
|
+
Spree::PaymentResponse.new(true, 'Bogus Gateway: Forced success', {}, test: true, authorization: '12345')
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
def capture(_money, authorization, _gateway_options)
|
|
55
55
|
if authorization == '12345'
|
|
56
|
-
|
|
56
|
+
Spree::PaymentResponse.new(true, 'Bogus Gateway: Forced success', {}, test: true)
|
|
57
57
|
else
|
|
58
|
-
|
|
58
|
+
Spree::PaymentResponse.new(false, 'Bogus Gateway: Forced failure', error: 'Bogus Gateway: Forced failure', test: true)
|
|
59
59
|
end
|
|
60
60
|
end
|
|
61
61
|
|
|
62
62
|
def void(_response_code, _credit_card, _options = {})
|
|
63
|
-
|
|
63
|
+
Spree::PaymentResponse.new(true, 'Bogus Gateway: Forced success', {}, test: true, authorization: 'void-12345')
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
def cancel(_response_code, _payment = nil)
|
|
67
|
-
|
|
67
|
+
Spree::PaymentResponse.new(true, 'Bogus Gateway: Forced success', {}, test: true, authorization: '12345')
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
def test?
|
data/app/models/spree/gateway.rb
CHANGED
|
@@ -20,9 +20,6 @@ module Spree
|
|
|
20
20
|
def provider
|
|
21
21
|
gateway_options = options
|
|
22
22
|
gateway_options.delete :login if gateway_options.key?(:login) && gateway_options[:login].nil?
|
|
23
|
-
if gateway_options[:server]
|
|
24
|
-
ActiveMerchant::Billing::Base.mode = gateway_options[:server].to_sym
|
|
25
|
-
end
|
|
26
23
|
@provider ||= provider_class.new(gateway_options)
|
|
27
24
|
end
|
|
28
25
|
|
|
@@ -5,8 +5,6 @@ module Spree
|
|
|
5
5
|
extend ActiveSupport::Concern
|
|
6
6
|
|
|
7
7
|
included do
|
|
8
|
-
validates :attachment, attached: true, content_type: Rails.application.config.active_storage.web_image_content_types
|
|
9
|
-
|
|
10
8
|
# Returns image styles derived from Spree::Config.product_image_variant_sizes
|
|
11
9
|
# Format: { variant_name: 'WxH>' } for API compatibility
|
|
12
10
|
def self.styles
|
data/app/models/spree/image.rb
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
module Spree
|
|
2
2
|
class Image < Asset
|
|
3
|
-
include Spree::Image::Configuration::ActiveStorage
|
|
3
|
+
include Spree::Image::Configuration::ActiveStorage # legacy to be removed in Spree 6
|
|
4
4
|
include Rails.application.routes.url_helpers
|
|
5
|
-
include Spree::ImageMethods
|
|
5
|
+
include Spree::ImageMethods # legacy, will be removed in Spree 6
|
|
6
|
+
|
|
7
|
+
validates :attachment, attached: true, content_type: Rails.application.config.active_storage.web_image_content_types
|
|
6
8
|
|
|
7
9
|
after_commit :touch_product_variants, if: :should_touch_product_variants?, on: :update
|
|
8
10
|
after_commit :update_variant_thumbnail, on: [:create, :destroy]
|
|
@@ -19,7 +21,10 @@ module Spree
|
|
|
19
21
|
# The line below prevents the error.
|
|
20
22
|
self.inheritance_column = nil
|
|
21
23
|
|
|
24
|
+
# @deprecated
|
|
22
25
|
def styles
|
|
26
|
+
Spree::Deprecation.warn("Image#styles is deprecated and will be removed in Spree 6.0. Please use active storage variants with cdn_image_url")
|
|
27
|
+
|
|
23
28
|
self.class.styles.map do |_, size|
|
|
24
29
|
width, height = size.chop.split('x').map(&:to_i)
|
|
25
30
|
|
|
@@ -32,35 +37,6 @@ module Spree
|
|
|
32
37
|
end
|
|
33
38
|
end
|
|
34
39
|
|
|
35
|
-
def style(name)
|
|
36
|
-
size = self.class.styles[name]
|
|
37
|
-
return unless size
|
|
38
|
-
|
|
39
|
-
width, height = size.chop.split('x').map(&:to_i)
|
|
40
|
-
|
|
41
|
-
{
|
|
42
|
-
url: generate_url(size: size),
|
|
43
|
-
size: size,
|
|
44
|
-
width: width,
|
|
45
|
-
height: height
|
|
46
|
-
}
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def style_dimensions(name)
|
|
50
|
-
size = self.class.styles[name]
|
|
51
|
-
width, height = size.chop.split('x').map(&:to_i)
|
|
52
|
-
|
|
53
|
-
{
|
|
54
|
-
width: width,
|
|
55
|
-
height: height
|
|
56
|
-
}
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def plp_url
|
|
60
|
-
Spree::Deprecation.warn "Image#plp_url is deprecated. Use variant(:large) instead."
|
|
61
|
-
generate_url(size: self.class.styles[:large])
|
|
62
|
-
end
|
|
63
|
-
|
|
64
40
|
private
|
|
65
41
|
|
|
66
42
|
def touch_product_variants
|
|
@@ -17,11 +17,14 @@ module Spree
|
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def parsed_details
|
|
20
|
-
@details ||=
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
@details ||= YAML.safe_load(
|
|
21
|
+
details,
|
|
22
|
+
permitted_classes: [
|
|
23
|
+
Spree::PaymentResponse,
|
|
24
|
+
ActiveSupport::HashWithIndifferentAccess,
|
|
25
|
+
(ActiveMerchant::Billing::Response if defined?(ActiveMerchant::Billing::Response))
|
|
26
|
+
].compact
|
|
27
|
+
)
|
|
25
28
|
end
|
|
26
29
|
end
|
|
27
30
|
end
|
data/app/models/spree/market.rb
CHANGED
|
@@ -44,8 +44,7 @@ module Spree
|
|
|
44
44
|
joins(:market_countries)
|
|
45
45
|
.where(store_id: store.id)
|
|
46
46
|
.where(spree_market_countries: { country_id: country.id })
|
|
47
|
-
.
|
|
48
|
-
.first
|
|
47
|
+
.take
|
|
49
48
|
end
|
|
50
49
|
|
|
51
50
|
# Returns the default market for a store, or falls back to the first by position
|
|
@@ -8,6 +8,7 @@ module Spree
|
|
|
8
8
|
validates :market, :country, presence: true
|
|
9
9
|
validates :country_id, uniqueness: { scope: :market_id }
|
|
10
10
|
validate :country_covered_by_shipping_zone
|
|
11
|
+
validate :country_unique_per_store
|
|
11
12
|
|
|
12
13
|
private
|
|
13
14
|
|
|
@@ -21,5 +22,21 @@ module Spree
|
|
|
21
22
|
errors.add(:country, :not_in_shipping_zone)
|
|
22
23
|
end
|
|
23
24
|
end
|
|
25
|
+
|
|
26
|
+
def country_unique_per_store
|
|
27
|
+
return if market.blank? || country.blank?
|
|
28
|
+
|
|
29
|
+
store = market.store
|
|
30
|
+
return if store.blank?
|
|
31
|
+
|
|
32
|
+
existing = self.class.joins(:market)
|
|
33
|
+
.where(country_id: country_id)
|
|
34
|
+
.where(spree_markets: { store_id: store.id, deleted_at: nil })
|
|
35
|
+
.where.not(id: id)
|
|
36
|
+
|
|
37
|
+
if existing.exists?
|
|
38
|
+
errors.add(:country, :already_in_market)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
24
41
|
end
|
|
25
42
|
end
|
|
@@ -89,7 +89,6 @@ module Spree
|
|
|
89
89
|
end
|
|
90
90
|
|
|
91
91
|
after_transition to: :complete, do: :create_user_record
|
|
92
|
-
after_transition to: :complete, do: :persist_user_credit_card
|
|
93
92
|
before_transition to: :payment, do: :set_shipments_cost
|
|
94
93
|
before_transition to: :payment, do: :create_tax_charge!
|
|
95
94
|
before_transition to: :payment, do: :recalculate_store_credit_payment
|
|
@@ -293,23 +292,6 @@ module Spree
|
|
|
293
292
|
Spree::Orders::CreateUserAccount.call(order: self, accepts_email_marketing: accept_marketing?)
|
|
294
293
|
end
|
|
295
294
|
|
|
296
|
-
def persist_user_credit_card
|
|
297
|
-
return unless !temporary_credit_card && user_id && valid_credit_cards.present?
|
|
298
|
-
|
|
299
|
-
valid_credit_cards.first.update(user_id: user_id, default: true)
|
|
300
|
-
end
|
|
301
|
-
|
|
302
|
-
def assign_default_credit_card
|
|
303
|
-
return unless payments.from_credit_card.size.empty? && user_has_valid_default_card? && payment_required?
|
|
304
|
-
|
|
305
|
-
cc = user.default_credit_card
|
|
306
|
-
payments.create!(payment_method_id: cc.payment_method_id, source: cc, amount: total)
|
|
307
|
-
end
|
|
308
|
-
|
|
309
|
-
def user_has_valid_default_card?
|
|
310
|
-
user && user.default_credit_card.try(:valid?)
|
|
311
|
-
end
|
|
312
|
-
|
|
313
295
|
def move_to_next_step_if_address_not_required
|
|
314
296
|
return if requires_ship_address?
|
|
315
297
|
|
data/app/models/spree/order.rb
CHANGED
|
@@ -3,7 +3,6 @@ require_dependency 'spree/order/currency_updater'
|
|
|
3
3
|
require_dependency 'spree/order/digital'
|
|
4
4
|
require_dependency 'spree/order/payments'
|
|
5
5
|
require_dependency 'spree/order/store_credit'
|
|
6
|
-
require_dependency 'spree/order/emails'
|
|
7
6
|
require_dependency 'spree/order/gift_card'
|
|
8
7
|
|
|
9
8
|
module Spree
|
|
@@ -22,7 +21,6 @@ module Spree
|
|
|
22
21
|
include Spree::Order::Payments
|
|
23
22
|
include Spree::Order::StoreCredit
|
|
24
23
|
include Spree::Order::AddressBook
|
|
25
|
-
include Spree::Order::Emails
|
|
26
24
|
include Spree::Order::Webhooks
|
|
27
25
|
include Spree::Core::NumberGenerator.new(prefix: 'R')
|
|
28
26
|
include Spree::Order::GiftCard
|
|
@@ -92,7 +90,7 @@ module Spree
|
|
|
92
90
|
self.whitelisted_ransackable_scopes = %w[refunded partially_refunded multi_search]
|
|
93
91
|
|
|
94
92
|
attr_reader :coupon_code
|
|
95
|
-
attr_accessor :temporary_address
|
|
93
|
+
attr_accessor :temporary_address
|
|
96
94
|
|
|
97
95
|
attribute :state_machine_resumed, :boolean
|
|
98
96
|
|
|
@@ -159,6 +157,7 @@ module Spree
|
|
|
159
157
|
# Needs to happen before save_permalink is called
|
|
160
158
|
before_validation :ensure_store_presence
|
|
161
159
|
before_validation :ensure_currency_presence
|
|
160
|
+
before_validation :ensure_locale_presence
|
|
162
161
|
|
|
163
162
|
before_validation :clone_billing_address, if: :use_billing?
|
|
164
163
|
before_validation :clone_shipping_address, if: :use_shipping?
|
|
@@ -174,6 +173,7 @@ module Spree
|
|
|
174
173
|
validates :item_count, numericality: { greater_than_or_equal_to: 0, less_than: 2**31, only_integer: true, allow_blank: true }
|
|
175
174
|
validates :store
|
|
176
175
|
validates :currency
|
|
176
|
+
validates :locale
|
|
177
177
|
end
|
|
178
178
|
validates :payment_state, inclusion: { in: PAYMENT_STATES, allow_blank: true }
|
|
179
179
|
validates :shipment_state, inclusion: { in: SHIPMENT_STATES, allow_blank: true }
|
|
@@ -186,6 +186,7 @@ module Spree
|
|
|
186
186
|
validates :promo_total, NEGATIVE_MONEY_VALIDATION
|
|
187
187
|
validates :total, MONEY_VALIDATION
|
|
188
188
|
validate :currency_must_be_supported_by_store
|
|
189
|
+
validate :locale_must_be_supported_by_store
|
|
189
190
|
|
|
190
191
|
delegate :update_totals, :persist_totals, to: :updater
|
|
191
192
|
delegate :merge!, to: :merger
|
|
@@ -308,9 +309,9 @@ module Spree
|
|
|
308
309
|
# @return [Boolean]
|
|
309
310
|
def order_refunded?
|
|
310
311
|
return false if item_count.zero?
|
|
312
|
+
return false if refunds_total.zero?
|
|
311
313
|
|
|
312
|
-
|
|
313
|
-
refunds_total == total_minus_store_credits - additional_tax_total.abs
|
|
314
|
+
payment_state.in?(%w[void failed]) || refunds_total == total_minus_store_credits - additional_tax_total.abs
|
|
314
315
|
end
|
|
315
316
|
|
|
316
317
|
def refunds_total
|
|
@@ -529,16 +530,6 @@ module Spree
|
|
|
529
530
|
complete? || canceled? || returned?
|
|
530
531
|
end
|
|
531
532
|
|
|
532
|
-
def credit_cards
|
|
533
|
-
credit_card_ids = payments.from_credit_card.pluck(:source_id).uniq
|
|
534
|
-
CreditCard.where(id: credit_card_ids)
|
|
535
|
-
end
|
|
536
|
-
|
|
537
|
-
def valid_credit_cards
|
|
538
|
-
credit_card_ids = payments.from_credit_card.valid.pluck(:source_id).uniq
|
|
539
|
-
CreditCard.where(id: credit_card_ids)
|
|
540
|
-
end
|
|
541
|
-
|
|
542
533
|
# Finalizes an in progress order after checkout is complete.
|
|
543
534
|
# Called after transition to complete state when payments will have been processed
|
|
544
535
|
def finalize!
|
|
@@ -972,7 +963,6 @@ module Spree
|
|
|
972
963
|
payments.store_credits.pending.each(&:void!)
|
|
973
964
|
end
|
|
974
965
|
|
|
975
|
-
send_cancel_email
|
|
976
966
|
update_with_updater!
|
|
977
967
|
send_order_canceled_webhook
|
|
978
968
|
publish_order_canceled_event
|
|
@@ -997,6 +987,12 @@ module Spree
|
|
|
997
987
|
self.currency ||= store&.default_currency
|
|
998
988
|
end
|
|
999
989
|
|
|
990
|
+
# Sets the locale from Spree::Current.locale when not already set.
|
|
991
|
+
# Called as a before_validation callback, mirroring ensure_currency_presence.
|
|
992
|
+
def ensure_locale_presence
|
|
993
|
+
self.locale ||= Spree::Current.locale
|
|
994
|
+
end
|
|
995
|
+
|
|
1000
996
|
def currency_must_be_supported_by_store
|
|
1001
997
|
return if currency.blank? || store.blank?
|
|
1002
998
|
|
|
@@ -1006,6 +1002,16 @@ module Spree
|
|
|
1006
1002
|
end
|
|
1007
1003
|
end
|
|
1008
1004
|
|
|
1005
|
+
# Validates that the order's locale is within the store's supported locales.
|
|
1006
|
+
# Mirrors currency_must_be_supported_by_store.
|
|
1007
|
+
def locale_must_be_supported_by_store
|
|
1008
|
+
return if locale.blank? || store.blank?
|
|
1009
|
+
|
|
1010
|
+
unless store.supported_locales_list.include?(locale)
|
|
1011
|
+
errors.add(:locale, Spree.t(:locale_not_supported_by_store))
|
|
1012
|
+
end
|
|
1013
|
+
end
|
|
1014
|
+
|
|
1009
1015
|
def collect_payment_methods
|
|
1010
1016
|
Spree::Deprecation.warn('`Order#collect_payment_methods` is deprecated and will be removed in Spree 5.5. Use `collect_frontend_payment_methods` instead.')
|
|
1011
1017
|
|
|
@@ -51,11 +51,11 @@ module Spree
|
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
def billing_address
|
|
54
|
-
order.bill_address.try(:
|
|
54
|
+
order.bill_address.try(:gateway_hash)
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
def shipping_address
|
|
58
|
-
order.ship_address.try(:
|
|
58
|
+
order.ship_address.try(:gateway_hash)
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
def hash_methods
|
|
@@ -48,7 +48,7 @@ module Spree
|
|
|
48
48
|
amount ||= money.amount_in_cents
|
|
49
49
|
started_processing!
|
|
50
50
|
protect_from_connection_error do
|
|
51
|
-
#
|
|
51
|
+
# Capture the payment amount
|
|
52
52
|
response = payment_method.capture(
|
|
53
53
|
amount,
|
|
54
54
|
response_code,
|
|
@@ -71,7 +71,7 @@ module Spree
|
|
|
71
71
|
# so supply the authorization itself as well as the credit card, rather than just the authorization code
|
|
72
72
|
response = payment_method.void(response_code, source, gateway_options)
|
|
73
73
|
else
|
|
74
|
-
# Standard
|
|
74
|
+
# Standard void usage
|
|
75
75
|
response = payment_method.void(response_code, gateway_options)
|
|
76
76
|
end
|
|
77
77
|
record_response(response)
|
|
@@ -165,15 +165,15 @@ module Spree
|
|
|
165
165
|
|
|
166
166
|
def protect_from_connection_error
|
|
167
167
|
yield
|
|
168
|
-
rescue
|
|
168
|
+
rescue Spree::PaymentConnectionError => e
|
|
169
169
|
failure!
|
|
170
170
|
gateway_error(e)
|
|
171
171
|
end
|
|
172
172
|
|
|
173
173
|
def gateway_error(error)
|
|
174
|
-
text = if error.is_a?
|
|
174
|
+
text = if error.is_a? Spree::PaymentResponse
|
|
175
175
|
error.params['message'] || error.params['response_reason_text'] || error.message
|
|
176
|
-
elsif error.is_a?
|
|
176
|
+
elsif error.is_a? Spree::PaymentConnectionError
|
|
177
177
|
Spree.t(:unable_to_connect_to_gateway)
|
|
178
178
|
else
|
|
179
179
|
error.to_s
|
data/app/models/spree/payment.rb
CHANGED
|
@@ -22,7 +22,7 @@ module Spree
|
|
|
22
22
|
|
|
23
23
|
def authorize(amount_in_cents, store_credit, gateway_options = {})
|
|
24
24
|
if store_credit.nil?
|
|
25
|
-
|
|
25
|
+
Spree::PaymentResponse.new(false, Spree.t('store_credit_payment_method.unable_to_find'), {}, {})
|
|
26
26
|
else
|
|
27
27
|
action = lambda do |store_credit|
|
|
28
28
|
store_credit.authorize(
|
|
@@ -58,7 +58,7 @@ module Spree
|
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
if event.blank?
|
|
61
|
-
|
|
61
|
+
Spree::PaymentResponse.new(false, Spree.t('store_credit_payment_method.unable_to_find'), {}, {})
|
|
62
62
|
else
|
|
63
63
|
capture(amount_in_cents, event.authorization_code, gateway_options)
|
|
64
64
|
end
|
|
@@ -111,14 +111,14 @@ module Spree
|
|
|
111
111
|
store_credit.with_lock do
|
|
112
112
|
if response = action.call(store_credit)
|
|
113
113
|
# note that we only need to return the auth code on an 'auth', but it's innocuous to always return
|
|
114
|
-
|
|
114
|
+
Spree::PaymentResponse.new(
|
|
115
115
|
true,
|
|
116
116
|
Spree.t('store_credit_payment_method.successful_action', action: action_name),
|
|
117
117
|
{},
|
|
118
118
|
authorization: auth_code || response
|
|
119
119
|
)
|
|
120
120
|
else
|
|
121
|
-
|
|
121
|
+
Spree::PaymentResponse.new(false, store_credit.errors.full_messages.to_sentence, {}, {})
|
|
122
122
|
end
|
|
123
123
|
end
|
|
124
124
|
end
|
|
@@ -128,7 +128,7 @@ module Spree
|
|
|
128
128
|
store_credit = StoreCreditEvent.find_by(authorization_code: auth_code).try(:store_credit)
|
|
129
129
|
|
|
130
130
|
if store_credit.nil?
|
|
131
|
-
|
|
131
|
+
Spree::PaymentResponse.new(
|
|
132
132
|
false,
|
|
133
133
|
Spree.t('store_credit_payment_method.unable_to_find_for_action', auth_code: auth_code, action: action_name),
|
|
134
134
|
{},
|