spree_core 4.2.0.rc3 → 4.2.2
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/assets/javascripts/spree.js +19 -0
- data/app/controllers/spree/base_controller.rb +2 -1
- data/app/controllers/spree/errors_controller.rb +11 -0
- data/app/finders/spree/orders/find_current.rb +1 -1
- data/app/finders/spree/products/find.rb +14 -3
- data/app/helpers/spree/base_helper.rb +2 -1
- data/app/helpers/spree/currency_helper.rb +34 -0
- data/app/helpers/spree/locale_helper.rb +31 -0
- data/app/helpers/spree/products_helper.rb +37 -12
- data/app/models/concerns/spree/product_scopes.rb +1 -1
- data/app/models/concerns/spree/user_payment_source.rb +1 -1
- data/app/models/spree/ability.rb +45 -30
- data/app/models/spree/app_configuration.rb +2 -2
- data/app/models/spree/app_dependencies.rb +3 -1
- data/app/models/spree/credit_card.rb +4 -0
- data/app/models/spree/image.rb +14 -14
- data/app/models/spree/line_item.rb +6 -9
- data/app/models/spree/price.rb +1 -1
- data/app/models/spree/product.rb +29 -15
- data/app/models/spree/promotion/rules/option_value.rb +1 -1
- data/app/models/spree/store.rb +38 -9
- data/app/models/spree/variant.rb +8 -8
- data/app/paginators/spree/shared/paginate.rb +8 -1
- data/app/presenters/spree/variant_presenter.rb +2 -5
- data/app/services/spree/build_localized_redirect_url.rb +101 -0
- data/app/services/spree/cart/estimate_shipping_rates.rb +1 -1
- data/app/views/spree/errors/forbidden.html.erb +0 -0
- data/app/views/spree/errors/unauthorized.html.erb +0 -0
- data/app/views/spree/shared/_base_mailer_stylesheets.html.erb +13 -2
- data/app/views/spree/shared/_purchased_items_table.html.erb +15 -6
- data/app/views/spree/shared/purchased_items_table/_adjustment.html.erb +2 -2
- data/app/views/spree/shared/purchased_items_table/_line_item.html.erb +2 -2
- data/config/locales/en.yml +8 -54
- data/config/routes.rb +2 -1
- data/db/default/spree/stores.rb +1 -0
- data/db/default/spree/zones.rb +4 -1
- data/db/migrate/20191017121054_add_supported_currencies_to_store.rb +1 -0
- data/db/migrate/20201012091259_add_filterable_column_to_spree_option_types.rb +6 -2
- data/db/migrate/20210120142527_ensure_default_locale_in_spree_stores.rb +5 -0
- data/db/migrate/20210205211040_add_supported_locales_to_spree_stores.rb +11 -0
- data/db/migrate/20210215202602_migrate_spree_i18n_globalize_config.rb +22 -0
- data/lib/generators/spree/install/install_generator.rb +9 -6
- data/lib/spree/core.rb +2 -1
- data/lib/spree/core/controller_helpers/auth.rb +3 -1
- data/lib/spree/core/controller_helpers/common.rb +6 -8
- data/lib/spree/core/controller_helpers/currency.rb +54 -0
- data/lib/spree/core/controller_helpers/locale.rb +58 -0
- data/lib/spree/core/controller_helpers/search.rb +1 -1
- data/lib/spree/core/controller_helpers/store.rb +4 -16
- data/lib/spree/core/version.rb +3 -1
- data/lib/spree/i18n.rb +12 -0
- data/lib/spree/permitted_attributes.rb +1 -1
- data/lib/spree/service_module.rb +2 -2
- data/lib/spree/testing_support/common_rake.rb +1 -1
- data/lib/spree/testing_support/controller_requests.rb +10 -10
- data/lib/spree/testing_support/factories/stock_location_factory.rb +2 -2
- data/lib/spree/testing_support/factories/store_factory.rb +1 -0
- data/lib/spree/testing_support/flatpickr_capybara.rb +101 -0
- data/lib/spree/testing_support/locale_helpers.rb +78 -0
- data/lib/spree/testing_support/next_instance_of.rb +38 -0
- data/spree_core.gemspec +1 -1
- metadata +20 -9
- data/lib/generators/spree/install/templates/config/initializers/spree_storefront.rb +0 -1
- data/lib/generators/spree/install/templates/config/spree_storefront.yml +0 -67
- data/lib/spree/core/controller_helpers/currency_helpers.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 612f2690babce476b244e52eaf770e6993cabeef0ba9d7fa76a921cc1281a826
|
4
|
+
data.tar.gz: 1e71e1322e8d7af3b9595f33108c5b82ddb1ba0824570d6e9bb50e47160cc71e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3d8788642e21a9ae5f5e5ea2684cafb00e80a3ed300851c4b4bdb83e8bf83a927dfd6798ea99e8da04f94809e9163ada634e89452568b3307b0bffc3e567827c
|
7
|
+
data.tar.gz: db77fb1c959dbe53a50cc103977a1b3c83f3d45d846ce353b1ed739ebd89c8e9b0234b470ddc23a0b14b94137ee996c60165cf36350b997ea2eeb42d34ec7caf
|
@@ -17,9 +17,28 @@ Spree.adminPath = function () {
|
|
17
17
|
|
18
18
|
Spree.pathFor = function (path) {
|
19
19
|
var locationOrigin = (window.location.protocol + '//' + window.location.hostname) + (window.location.port ? ':' + window.location.port : '')
|
20
|
+
|
20
21
|
return this.url('' + locationOrigin + (this.mountedAt()) + path, this.url_params).toString()
|
21
22
|
}
|
22
23
|
|
24
|
+
Spree.localizedPathFor = function(path) {
|
25
|
+
if (typeof (SPREE_LOCALE) !== 'undefined' && typeof (SPREE_CURRENCY) !== 'undefined') {
|
26
|
+
var fullUrl = new URL(Spree.pathFor(path))
|
27
|
+
var params = fullUrl.searchParams
|
28
|
+
var pathName = fullUrl.pathname
|
29
|
+
|
30
|
+
params.set('currency', SPREE_CURRENCY)
|
31
|
+
|
32
|
+
if (pathName.match(/api\/v/)) {
|
33
|
+
params.set('locale', SPREE_LOCALE)
|
34
|
+
} else {
|
35
|
+
pathName = SPREE_LOCALE + '/' + path
|
36
|
+
}
|
37
|
+
return fullUrl.origin + (this.mountedAt()) + pathName + '?' + params.toString()
|
38
|
+
}
|
39
|
+
return Spree.pathFor(path)
|
40
|
+
}
|
41
|
+
|
23
42
|
Spree.adminPathFor = function (path) {
|
24
43
|
return this.pathFor('' + (this.adminPath()) + path)
|
25
44
|
}
|
@@ -7,7 +7,8 @@ class Spree::BaseController < ApplicationController
|
|
7
7
|
include Spree::Core::ControllerHelpers::Search
|
8
8
|
include Spree::Core::ControllerHelpers::Store
|
9
9
|
include Spree::Core::ControllerHelpers::StrongParameters
|
10
|
-
include Spree::Core::ControllerHelpers::
|
10
|
+
include Spree::Core::ControllerHelpers::Locale
|
11
|
+
include Spree::Core::ControllerHelpers::Currency
|
11
12
|
|
12
13
|
respond_to :html
|
13
14
|
end
|
@@ -9,7 +9,7 @@ module Spree
|
|
9
9
|
return order unless order.nil?
|
10
10
|
return if user.nil?
|
11
11
|
|
12
|
-
incomplete_orders.order(created_at: :desc).find_by(store: store, user: user)
|
12
|
+
incomplete_orders.order(created_at: :desc).find_by(store: store, user: user, currency: params[:currency])
|
13
13
|
end
|
14
14
|
|
15
15
|
private
|
@@ -7,7 +7,7 @@ module Spree
|
|
7
7
|
@ids = String(params.dig(:filter, :ids)).split(',')
|
8
8
|
@skus = String(params.dig(:filter, :skus)).split(',')
|
9
9
|
@price = String(params.dig(:filter, :price)).split(',').map(&:to_f)
|
10
|
-
@currency =
|
10
|
+
@currency = current_currency
|
11
11
|
@taxons = taxon_ids(params.dig(:filter, :taxons))
|
12
12
|
@concat_taxons = taxon_ids(params.dig(:filter, :concat_taxons))
|
13
13
|
@name = params.dig(:filter, :name)
|
@@ -22,6 +22,7 @@ module Spree
|
|
22
22
|
products = by_ids(scope)
|
23
23
|
products = by_skus(products)
|
24
24
|
products = by_price(products)
|
25
|
+
products = by_currency(products)
|
25
26
|
products = by_taxons(products)
|
26
27
|
products = by_concat_taxons(products)
|
27
28
|
products = by_name(products)
|
@@ -51,6 +52,10 @@ module Spree
|
|
51
52
|
price.present?
|
52
53
|
end
|
53
54
|
|
55
|
+
def currency?
|
56
|
+
currency.present?
|
57
|
+
end
|
58
|
+
|
54
59
|
def taxons?
|
55
60
|
taxons.present?
|
56
61
|
end
|
@@ -94,15 +99,21 @@ module Spree
|
|
94
99
|
def by_price(products)
|
95
100
|
return products unless price?
|
96
101
|
|
97
|
-
products.joins(master: :
|
102
|
+
products.joins(master: :prices).
|
98
103
|
where(
|
99
104
|
spree_prices: {
|
100
105
|
amount: price.min..price.max,
|
101
|
-
currency: currency
|
106
|
+
currency: currency&.upcase
|
102
107
|
}
|
103
108
|
)
|
104
109
|
end
|
105
110
|
|
111
|
+
def by_currency(products)
|
112
|
+
return products unless currency?
|
113
|
+
|
114
|
+
products.joins(master: :prices).where(spree_prices: { currency: currency.upcase })
|
115
|
+
end
|
116
|
+
|
106
117
|
def by_taxons(products)
|
107
118
|
return products unless taxons?
|
108
119
|
|
@@ -134,7 +134,8 @@ module Spree
|
|
134
134
|
[I18n.l(date.to_date, format: :long)].join(' ')
|
135
135
|
end
|
136
136
|
|
137
|
-
def seo_url(taxon, options =
|
137
|
+
def seo_url(taxon, options = {})
|
138
|
+
options.merge(locale: locale_param)
|
138
139
|
spree.nested_taxons_path(taxon.permalink, options)
|
139
140
|
end
|
140
141
|
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Spree
|
2
|
+
module CurrencyHelper
|
3
|
+
def currency_options(selected_value = nil)
|
4
|
+
selected_value ||= Spree::Config[:currency]
|
5
|
+
currencies = ::Money::Currency.table.map do |_code, details|
|
6
|
+
iso = details[:iso_code]
|
7
|
+
[iso, "#{details[:name]} (#{iso})"]
|
8
|
+
end
|
9
|
+
options_from_collection_for_select(currencies, :first, :last, selected_value)
|
10
|
+
end
|
11
|
+
|
12
|
+
def supported_currency_options
|
13
|
+
return if current_store.nil?
|
14
|
+
|
15
|
+
current_store.supported_currencies_list.map(&:iso_code).map { |currency| currency_presentation(currency) }
|
16
|
+
end
|
17
|
+
|
18
|
+
def should_render_currency_dropdown?
|
19
|
+
return false if current_store.nil?
|
20
|
+
|
21
|
+
current_store.supported_currencies_list.size > 1
|
22
|
+
end
|
23
|
+
|
24
|
+
def currency_symbol(currency)
|
25
|
+
::Money::Currency.find(currency).symbol
|
26
|
+
end
|
27
|
+
|
28
|
+
def currency_presentation(currency)
|
29
|
+
label = [currency_symbol(currency), currency].compact.join(' ')
|
30
|
+
|
31
|
+
[label, currency]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Spree
|
2
|
+
module LocaleHelper
|
3
|
+
def all_locales_options
|
4
|
+
supported_locales_for_all_stores.map { |locale| locale_presentation(locale) }
|
5
|
+
end
|
6
|
+
|
7
|
+
def available_locales_options
|
8
|
+
available_locales.map { |locale| locale_presentation(locale) }
|
9
|
+
end
|
10
|
+
|
11
|
+
def supported_locales_options
|
12
|
+
return if current_store.nil?
|
13
|
+
|
14
|
+
current_store.supported_locales_list.map { |locale| locale_presentation(locale) }
|
15
|
+
end
|
16
|
+
|
17
|
+
def locale_presentation(locale)
|
18
|
+
if I18n.exists?('spree.i18n.this_file_language', locale: locale)
|
19
|
+
[Spree.t('i18n.this_file_language', locale: locale), locale.to_s]
|
20
|
+
else
|
21
|
+
locale.to_s == 'en' ? ['English (US)', 'en'] : [locale, locale.to_s]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def should_render_locale_dropdown?
|
26
|
+
return false if current_store.nil?
|
27
|
+
|
28
|
+
current_store.supported_locales_list.size > 1
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -35,6 +35,11 @@ module Spree
|
|
35
35
|
variants_option_types_presenter(variants, product).default_variant || product.default_variant
|
36
36
|
end
|
37
37
|
|
38
|
+
def should_display_compare_at_price?(default_variant)
|
39
|
+
default_variant_price = default_variant.price_in(current_currency)
|
40
|
+
default_variant_price.compare_at_amount.present? && (default_variant_price.compare_at_amount > default_variant_price.amount)
|
41
|
+
end
|
42
|
+
|
38
43
|
def used_variants_options(variants, product)
|
39
44
|
variants_option_types_presenter(variants, product).options
|
40
45
|
end
|
@@ -115,19 +120,39 @@ module Spree
|
|
115
120
|
).call.to_json
|
116
121
|
end
|
117
122
|
|
123
|
+
def product_relation_types
|
124
|
+
@product_relation_types ||= @product.respond_to?(:relation_types) ? @product.relation_types : []
|
125
|
+
end
|
126
|
+
|
127
|
+
def product_relations_by_type(relation_type)
|
128
|
+
return [] if product_relation_types.none? || !@product.respond_to?(:relations)
|
129
|
+
|
130
|
+
product_ids = @product.relations.where(relation_type: relation_type).pluck(:related_to_id).uniq
|
131
|
+
|
132
|
+
return [] if product_ids.empty?
|
133
|
+
|
134
|
+
Spree::Product.
|
135
|
+
available.not_discontinued.distinct.
|
136
|
+
where(id: product_ids).
|
137
|
+
includes(
|
138
|
+
:tax_category,
|
139
|
+
master: [
|
140
|
+
:prices,
|
141
|
+
{ images: { attachment_attachment: :blob } },
|
142
|
+
]
|
143
|
+
).
|
144
|
+
limit(Spree::Config[:products_per_page])
|
145
|
+
end
|
146
|
+
|
118
147
|
def related_products
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
images: { attachment_attachment: :blob },
|
128
|
-
]
|
129
|
-
).
|
130
|
-
limit(Spree::Config[:products_per_page])
|
148
|
+
ActiveSupport::Deprecation.warn(<<-DEPRECATION, caller)
|
149
|
+
ProductsHelper#related_products is deprecated and will be removed in Spree 5.0.
|
150
|
+
Please use ProductsHelper#relations from now on.
|
151
|
+
DEPRECATION
|
152
|
+
|
153
|
+
return [] unless @product.respond_to?(:has_related_products?)
|
154
|
+
|
155
|
+
@related_products ||= relations_by_type('related_products')
|
131
156
|
end
|
132
157
|
|
133
158
|
def product_available_in_currency?
|
data/app/models/spree/ability.rb
CHANGED
@@ -23,55 +23,70 @@ module Spree
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def initialize(user)
|
26
|
-
|
27
|
-
alias_action :delete, to: :destroy
|
28
|
-
alias_action :create, :update, :destroy, to: :modify
|
26
|
+
alias_cancan_delete_action
|
29
27
|
|
30
28
|
user ||= Spree.user_class.new
|
31
29
|
|
32
30
|
if user.respond_to?(:has_spree_role?) && user.has_spree_role?('admin')
|
33
|
-
|
31
|
+
apply_admin_permissions(user)
|
34
32
|
else
|
35
|
-
|
36
|
-
can :read, OptionType
|
37
|
-
can :read, OptionValue
|
38
|
-
can :create, Order
|
39
|
-
can :show, Order do |order, token|
|
40
|
-
order.user == user || order.token && token == order.token
|
41
|
-
end
|
42
|
-
can :update, Order do |order, token|
|
43
|
-
!order.completed? && (order.user == user || order.token && token == order.token)
|
44
|
-
end
|
45
|
-
can :manage, Address, user_id: user.id
|
46
|
-
can :read, CreditCard, user_id: user.id
|
47
|
-
can :read, Product
|
48
|
-
can :read, ProductProperty
|
49
|
-
can :read, Property
|
50
|
-
can :create, Spree.user_class
|
51
|
-
can [:show, :update, :destroy], Spree.user_class, id: user.id
|
52
|
-
can :read, State
|
53
|
-
can :read, Store
|
54
|
-
can :read, Taxon
|
55
|
-
can :read, Taxonomy
|
56
|
-
can :read, Variant
|
57
|
-
can :read, Zone
|
33
|
+
apply_user_permissions(user)
|
58
34
|
end
|
59
35
|
|
60
36
|
# Include any abilities registered by extensions, etc.
|
37
|
+
# this is legacy behaviour and should be removed in Spree 5.0
|
61
38
|
Ability.abilities.merge(abilities_to_register).each do |clazz|
|
62
39
|
merge clazz.new(user)
|
63
40
|
end
|
64
41
|
|
65
|
-
|
66
|
-
cannot [:update, :destroy], Role, name: ['admin']
|
42
|
+
protect_admin_role
|
67
43
|
end
|
68
44
|
|
69
|
-
|
45
|
+
protected
|
70
46
|
|
71
47
|
# you can override this method to register your abilities
|
72
48
|
# this method has to return array of classes
|
73
49
|
def abilities_to_register
|
74
50
|
[]
|
75
51
|
end
|
52
|
+
|
53
|
+
def alias_cancan_delete_action
|
54
|
+
alias_action :delete, to: :destroy
|
55
|
+
alias_action :create, :update, :destroy, to: :modify
|
56
|
+
end
|
57
|
+
|
58
|
+
def apply_admin_permissions(user)
|
59
|
+
can :manage, :all
|
60
|
+
end
|
61
|
+
|
62
|
+
def apply_user_permissions(user)
|
63
|
+
can :read, ::Spree::Country
|
64
|
+
can :read, ::Spree::OptionType
|
65
|
+
can :read, ::Spree::OptionValue
|
66
|
+
can :create, ::Spree::Order
|
67
|
+
can :show, ::Spree::Order do |order, token|
|
68
|
+
order.user == user || order.token && token == order.token
|
69
|
+
end
|
70
|
+
can :update, ::Spree::Order do |order, token|
|
71
|
+
!order.completed? && (order.user == user || order.token && token == order.token)
|
72
|
+
end
|
73
|
+
can :manage, ::Spree::Address, user_id: user.id
|
74
|
+
can :read, ::Spree::CreditCard, user_id: user.id
|
75
|
+
can :read, ::Spree::Product
|
76
|
+
can :read, ::Spree::ProductProperty
|
77
|
+
can :read, ::Spree::Property
|
78
|
+
can :create, ::Spree.user_class
|
79
|
+
can [:show, :update, :destroy], ::Spree.user_class, id: user.id
|
80
|
+
can :read, ::Spree::State
|
81
|
+
can :read, ::Spree::Store
|
82
|
+
can :read, ::Spree::Taxon
|
83
|
+
can :read, ::Spree::Taxonomy
|
84
|
+
can :read, ::Spree::Variant
|
85
|
+
can :read, ::Spree::Zone
|
86
|
+
end
|
87
|
+
|
88
|
+
def protect_admin_role
|
89
|
+
cannot [:update, :destroy], ::Spree::Role, name: ['admin']
|
90
|
+
end
|
76
91
|
end
|
77
92
|
end
|
@@ -68,8 +68,8 @@ module Spree
|
|
68
68
|
preference :non_expiring_credit_types, :array, default: []
|
69
69
|
preference :credit_to_new_allocation, :boolean, default: false
|
70
70
|
|
71
|
-
# Multi
|
72
|
-
preference :
|
71
|
+
# Multi store configurations
|
72
|
+
preference :show_store_selector, :boolean, default: false
|
73
73
|
|
74
74
|
# searcher_class allows spree extension writers to provide their own Search class
|
75
75
|
def searcher_class
|
@@ -13,7 +13,7 @@ module Spree
|
|
13
13
|
:completed_order_finder, :order_sorter, :cart_compare_line_items_service, :collection_paginator, :products_sorter,
|
14
14
|
:products_finder, :taxon_finder, :line_item_by_variant_finder, :cart_estimate_shipping_rates_service,
|
15
15
|
:account_create_address_service, :account_update_address_service, :address_finder,
|
16
|
-
:collection_sorter
|
16
|
+
:collection_sorter, :error_handler
|
17
17
|
].freeze
|
18
18
|
|
19
19
|
attr_accessor *INJECTION_POINTS
|
@@ -66,6 +66,8 @@ module Spree
|
|
66
66
|
# account
|
67
67
|
@account_create_address_service = 'Spree::Account::Addresses::Create'
|
68
68
|
@account_update_address_service = 'Spree::Account::Addresses::Update'
|
69
|
+
|
70
|
+
@error_handler = 'Spree::ErrorReporter'
|
69
71
|
end
|
70
72
|
|
71
73
|
def set_default_finders
|
data/app/models/spree/image.rb
CHANGED
@@ -15,13 +15,13 @@ module Spree
|
|
15
15
|
width, height = size.chop.split('x')
|
16
16
|
|
17
17
|
{
|
18
|
-
url: polymorphic_path(attachment.variant(
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
18
|
+
url: polymorphic_path(attachment.variant(
|
19
|
+
gravity: 'center',
|
20
|
+
resize: size,
|
21
|
+
extent: size,
|
22
|
+
background: 'snow2',
|
23
|
+
quality: 80
|
24
|
+
), only_path: true),
|
25
25
|
width: width,
|
26
26
|
height: height
|
27
27
|
}
|
@@ -35,13 +35,13 @@ module Spree
|
|
35
35
|
width, height = size.chop.split('x')
|
36
36
|
|
37
37
|
{
|
38
|
-
url: polymorphic_path(attachment.variant(
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
38
|
+
url: polymorphic_path(attachment.variant(
|
39
|
+
gravity: 'center',
|
40
|
+
resize: size,
|
41
|
+
extent: size,
|
42
|
+
background: 'snow2',
|
43
|
+
quality: 80
|
44
|
+
), only_path: true),
|
45
45
|
size: size,
|
46
46
|
width: width,
|
47
47
|
height: height
|