spree_core 4.3.0.rc1 → 4.3.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/finders/spree/products/find.rb +26 -2
- data/app/models/concerns/spree/display_money.rb +6 -2
- data/app/models/concerns/spree/product_scopes.rb +12 -0
- data/app/models/concerns/spree/single_store_resource.rb +10 -0
- data/app/models/concerns/spree/user_methods.rb +9 -8
- data/app/models/concerns/spree/user_reporting.rb +35 -10
- data/app/models/concerns/spree/user_roles.rb +25 -0
- data/app/models/spree/property.rb +1 -1
- data/app/models/spree/store.rb +2 -2
- data/config/locales/en.yml +9 -1
- data/db/migrate/20210527094055_create_spree_products_stores.rb +14 -7
- data/lib/generators/spree/dummy/dummy_generator.rb +1 -1
- data/lib/generators/spree/dummy/templates/rails/test.rb +2 -0
- data/lib/spree/core/controller_helpers/store.rb +14 -0
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/testing_support/factories/product_factory.rb +6 -0
- data/lib/spree/testing_support/locale_helpers.rb +1 -1
- data/lib/spree/testing_support/rspec_retry_config.rb +5 -0
- data/spree_core.gemspec +1 -1
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d280751e897448ce4593ebe1d5f2fc9cd823e998699864ac8b52d2dfa28b49d6
|
4
|
+
data.tar.gz: 21ed38407942b369d6a7a2360730190a124264bd9b8137e79c49d4058fac16f6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 803917626fa68a87c54fd9d88dbb2388e84fefce8873ef3a7a96e7a49e1a1a7a9b327864a7c222fc31006795eaefbf10c12db584e5cd308b19464617b3235b80
|
7
|
+
data.tar.gz: f1ecb88f76d6061727b9bd569f24ae672491507248584106d1be936a2dfb3c78a1a1693b0affb84d0f8e34fe2991346b2884386ac7ac67df838408a81d10bc85
|
@@ -27,6 +27,9 @@ module Spree
|
|
27
27
|
@deleted = params.dig(:filter, :show_deleted)
|
28
28
|
@discontinued = params.dig(:filter, :show_discontinued)
|
29
29
|
@properties = params.dig(:filter, :properties)
|
30
|
+
@in_stock = params.dig(:filter, :in_stock)
|
31
|
+
@backorderable = params.dig(:filter, :backorderable)
|
32
|
+
@purchasable = params.dig(:filter, :purchasable)
|
30
33
|
end
|
31
34
|
|
32
35
|
def execute
|
@@ -42,6 +45,9 @@ module Spree
|
|
42
45
|
products = by_properties(products)
|
43
46
|
products = include_deleted(products)
|
44
47
|
products = include_discontinued(products)
|
48
|
+
products = show_only_stock(products)
|
49
|
+
products = show_only_backorderable(products)
|
50
|
+
products = show_only_purchasable(products)
|
45
51
|
products = ordered(products)
|
46
52
|
|
47
53
|
products.distinct
|
@@ -49,8 +55,8 @@ module Spree
|
|
49
55
|
|
50
56
|
private
|
51
57
|
|
52
|
-
attr_reader :ids, :skus, :price, :currency, :taxons, :concat_taxons, :name, :options,
|
53
|
-
:
|
58
|
+
attr_reader :ids, :skus, :price, :currency, :taxons, :concat_taxons, :name, :options, :option_value_ids, :scope,
|
59
|
+
:sort_by, :deleted, :discontinued, :properties, :store, :in_stock, :backorderable, :purchasable
|
54
60
|
|
55
61
|
def ids?
|
56
62
|
ids.present?
|
@@ -231,6 +237,24 @@ module Spree
|
|
231
237
|
discontinued ? products : products.active(currency)
|
232
238
|
end
|
233
239
|
|
240
|
+
def show_only_stock(products)
|
241
|
+
return products unless in_stock.to_s == 'true'
|
242
|
+
|
243
|
+
products.in_stock
|
244
|
+
end
|
245
|
+
|
246
|
+
def show_only_backorderable(products)
|
247
|
+
return products unless backorderable.to_s == 'true'
|
248
|
+
|
249
|
+
products.backorderable
|
250
|
+
end
|
251
|
+
|
252
|
+
def show_only_purchasable(products)
|
253
|
+
return products unless purchasable.to_s == 'true'
|
254
|
+
|
255
|
+
products.in_stock_or_backorderable
|
256
|
+
end
|
257
|
+
|
234
258
|
def map_prices(prices)
|
235
259
|
prices.map do |price|
|
236
260
|
price == 'Infinity' ? Float::INFINITY : price.to_f
|
@@ -17,13 +17,17 @@ module Spree
|
|
17
17
|
# Decorate a method, but with some additional options
|
18
18
|
# extend Spree::DisplayMoney
|
19
19
|
# money_methods tax_amount: { currency: "CAD", no_cents: true }, :price
|
20
|
+
# Use generated method with the same arguments as in wrapped method
|
21
|
+
# def tax_amount(order, country)
|
22
|
+
# display_tax_amount(order, country)
|
20
23
|
def money_methods(*args)
|
21
24
|
args.each do |money_method|
|
22
25
|
money_method = { money_method => {} } unless money_method.is_a? Hash
|
23
26
|
money_method.each do |method_name, opts|
|
24
|
-
define_method("display_#{method_name}") do
|
27
|
+
define_method("display_#{method_name}") do |**args_list|
|
25
28
|
default_opts = respond_to?(:currency) ? { currency: currency } : {}
|
26
|
-
|
29
|
+
|
30
|
+
Spree::Money.new(send(method_name, **args_list), default_opts.merge(opts).merge(args_list.slice(:currency)))
|
27
31
|
end
|
28
32
|
end
|
29
33
|
end
|
@@ -62,6 +62,18 @@ module Spree
|
|
62
62
|
where("#{price_table_name}.amount >= ?", price)
|
63
63
|
end
|
64
64
|
|
65
|
+
add_search_scope :in_stock do
|
66
|
+
joins(:variants_including_master).merge(Spree::Variant.in_stock)
|
67
|
+
end
|
68
|
+
|
69
|
+
add_search_scope :backorderable do
|
70
|
+
joins(:variants_including_master).merge(Spree::Variant.backorderable)
|
71
|
+
end
|
72
|
+
|
73
|
+
add_search_scope :in_stock_or_backorderable do
|
74
|
+
joins(:variants_including_master).merge(Spree::Variant.in_stock_or_backorderable)
|
75
|
+
end
|
76
|
+
|
65
77
|
# This scope selects products in taxon AND all its descendants
|
66
78
|
# If you need products only within one taxon use
|
67
79
|
#
|
@@ -3,7 +3,17 @@ module Spree
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
included do
|
6
|
+
validate :ensure_store_association_is_not_changed
|
7
|
+
|
6
8
|
scope :for_store, ->(store) { where(store_id: store.id) }
|
7
9
|
end
|
10
|
+
|
11
|
+
protected
|
12
|
+
|
13
|
+
def ensure_store_association_is_not_changed
|
14
|
+
if store_id_changed? && persisted?
|
15
|
+
errors.add(:store, Spree.t('errors.messages.store_association_can_not_be_changed'))
|
16
|
+
end
|
17
|
+
end
|
8
18
|
end
|
9
19
|
end
|
@@ -4,6 +4,7 @@ module Spree
|
|
4
4
|
|
5
5
|
include Spree::UserPaymentSource
|
6
6
|
include Spree::UserReporting
|
7
|
+
include Spree::UserRoles
|
7
8
|
include Spree::RansackableAttributes
|
8
9
|
|
9
10
|
included do
|
@@ -15,9 +16,6 @@ module Spree
|
|
15
16
|
|
16
17
|
attr_accessor :use_billing
|
17
18
|
|
18
|
-
has_many :role_users, class_name: 'Spree::RoleUser', foreign_key: :user_id, dependent: :destroy
|
19
|
-
has_many :spree_roles, through: :role_users, class_name: 'Spree::Role', source: :role
|
20
|
-
|
21
19
|
has_many :promotion_rule_users, class_name: 'Spree::PromotionRuleUser', foreign_key: :user_id, dependent: :destroy
|
22
20
|
has_many :promotion_rules, through: :promotion_rule_users, class_name: 'Spree::PromotionRule'
|
23
21
|
|
@@ -47,11 +45,6 @@ module Spree
|
|
47
45
|
end
|
48
46
|
end
|
49
47
|
|
50
|
-
# has_spree_role? simply needs to return true or false whether a user has a role or not.
|
51
|
-
def has_spree_role?(role_in_question)
|
52
|
-
spree_roles.any? { |role| role.name == role_in_question.to_s }
|
53
|
-
end
|
54
|
-
|
55
48
|
def last_incomplete_spree_order(store, options = {})
|
56
49
|
orders.where(store: store).incomplete.
|
57
50
|
includes(options[:includes]).
|
@@ -65,6 +58,14 @@ module Spree
|
|
65
58
|
store_credits.for_store(store).where(currency: currency).reload.to_a.sum(&:amount_remaining)
|
66
59
|
end
|
67
60
|
|
61
|
+
def available_store_credits(store)
|
62
|
+
store ||= Store.default
|
63
|
+
|
64
|
+
store_credits.for_store(store).pluck(:currency).uniq.each_with_object([]) do |currency, arr|
|
65
|
+
arr << Spree::Money.new(total_available_store_credit(currency, store), currency: currency)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
68
69
|
private
|
69
70
|
|
70
71
|
def check_completed_orders
|
@@ -3,20 +3,45 @@ module Spree
|
|
3
3
|
extend DisplayMoney
|
4
4
|
money_methods :lifetime_value, :average_order_value
|
5
5
|
|
6
|
-
def
|
7
|
-
|
6
|
+
def report_values_for(report_name, store)
|
7
|
+
store ||= Store.default
|
8
|
+
|
9
|
+
completed_orders(store).pluck(:currency).uniq.each_with_object([]) do |currency, arr|
|
10
|
+
arr << send("display_#{report_name}", store: store, currency: currency)
|
11
|
+
end
|
8
12
|
end
|
9
13
|
|
10
|
-
def
|
11
|
-
|
14
|
+
def lifetime_value(**args)
|
15
|
+
order_calculate(operation: :sum,
|
16
|
+
column: :total,
|
17
|
+
**args)
|
12
18
|
end
|
13
19
|
|
14
|
-
def average_order_value
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
+
def average_order_value(**args)
|
21
|
+
order_calculate(operation: :average,
|
22
|
+
column: :total,
|
23
|
+
**args)
|
24
|
+
end
|
25
|
+
|
26
|
+
def order_count(store = nil)
|
27
|
+
store ||= Store.default
|
28
|
+
order_calculate(store: store,
|
29
|
+
currency: store.supported_currencies.split(','),
|
30
|
+
operation: :count,
|
31
|
+
column: :all)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def order_calculate(operation:, column:, store: nil, currency: nil)
|
37
|
+
store ||= Store.default
|
38
|
+
currency ||= store.default_currency
|
39
|
+
|
40
|
+
completed_orders(store).where(currency: currency).calculate(operation, column) || BigDecimal('0.00')
|
41
|
+
end
|
42
|
+
|
43
|
+
def completed_orders(store)
|
44
|
+
orders.for_store(store).complete
|
20
45
|
end
|
21
46
|
end
|
22
47
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Spree
|
2
|
+
module UserRoles
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
has_many :role_users, class_name: 'Spree::RoleUser', foreign_key: :user_id, dependent: :destroy
|
7
|
+
has_many :spree_roles, through: :role_users, class_name: 'Spree::Role', source: :role
|
8
|
+
|
9
|
+
scope :admin, -> { joins(:spree_roles).where(Spree::Role.table_name => { name: 'admin' }) }
|
10
|
+
|
11
|
+
# has_spree_role? simply needs to return true or false whether a user has a role or not.
|
12
|
+
def has_spree_role?(role_name)
|
13
|
+
spree_roles.exists?(name: role_name)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.admin_created?
|
17
|
+
admin.exists?
|
18
|
+
end
|
19
|
+
|
20
|
+
def admin?
|
21
|
+
has_spree_role?('admin')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -18,7 +18,7 @@ module Spree
|
|
18
18
|
after_touch :touch_all_products
|
19
19
|
after_save :ensure_product_properties_have_filter_params
|
20
20
|
|
21
|
-
self.whitelisted_ransackable_attributes = ['presentation']
|
21
|
+
self.whitelisted_ransackable_attributes = ['presentation', 'filterable']
|
22
22
|
|
23
23
|
def uniq_values(product_properties_scope: nil)
|
24
24
|
with_uniq_values_cache_key(product_properties_scope) do
|
data/app/models/spree/store.rb
CHANGED
@@ -76,8 +76,8 @@ module Spree
|
|
76
76
|
|
77
77
|
def self.current(url = nil)
|
78
78
|
ActiveSupport::Deprecation.warn(<<-DEPRECATION, caller)
|
79
|
-
`Spree::Store.current` is deprecated and will be removed in Spree 5
|
80
|
-
Spree::Stores::FindCurrent.new(url: "
|
79
|
+
`Spree::Store.current` is deprecated and will be removed in Spree 5.0
|
80
|
+
Please use `Spree::Stores::FindCurrent.new(url: "https://example.com").execute` instead
|
81
81
|
DEPRECATION
|
82
82
|
Stores::FindCurrent.new(url: url).execute
|
83
83
|
end
|
data/config/locales/en.yml
CHANGED
@@ -184,6 +184,12 @@ en:
|
|
184
184
|
spree/address:
|
185
185
|
one: Address
|
186
186
|
other: Addresses
|
187
|
+
spree/cms_page:
|
188
|
+
one: Page
|
189
|
+
other: Pages
|
190
|
+
spree/cms_section:
|
191
|
+
one: Section
|
192
|
+
other: Sections
|
187
193
|
spree/country:
|
188
194
|
one: Country
|
189
195
|
other: Countries
|
@@ -964,6 +970,8 @@ en:
|
|
964
970
|
error: error
|
965
971
|
errors:
|
966
972
|
messages:
|
973
|
+
store_association_can_not_be_changed: The store association can not be changed
|
974
|
+
store_is_already_set: Store is already set
|
967
975
|
blank: can't be blank
|
968
976
|
could_not_create_taxon: Could not create taxon
|
969
977
|
no_shipping_methods_available: No shipping methods available for selected location, please change your address and try again.
|
@@ -1132,7 +1140,7 @@ en:
|
|
1132
1140
|
log_in_to_continue: Log in to continue
|
1133
1141
|
logs: "Logs"
|
1134
1142
|
logged_in_as: Logged in as
|
1135
|
-
|
1143
|
+
logged_in_successfully: Logged in successfully
|
1136
1144
|
logged_out: You have been logged out.
|
1137
1145
|
login: Login
|
1138
1146
|
login_as_existing: Login as Existing Customer
|
@@ -1,6 +1,13 @@
|
|
1
1
|
class CreateSpreeProductsStores < ActiveRecord::Migration[5.2]
|
2
2
|
def up
|
3
|
-
|
3
|
+
if table_exists?(:spree_products_stores)
|
4
|
+
unless index_exists?(:spree_products_stores, [:product_id, :store_id], unique: true)
|
5
|
+
add_index :spree_products_stores, [:product_id, :store_id], unique: true
|
6
|
+
end
|
7
|
+
unless column_exists?(:spree_products_stores, :created_at)
|
8
|
+
add_timestamps :spree_products_stores
|
9
|
+
end
|
10
|
+
else
|
4
11
|
create_table :spree_products_stores do |t|
|
5
12
|
t.references :product, index: true
|
6
13
|
t.references :store, index: true
|
@@ -12,13 +19,13 @@ class CreateSpreeProductsStores < ActiveRecord::Migration[5.2]
|
|
12
19
|
stores = Spree::Store.all
|
13
20
|
product_ids = Spree::Product.with_deleted.order(:id).ids
|
14
21
|
|
15
|
-
|
16
|
-
|
17
|
-
|
22
|
+
if product_ids.any? && Spree::StoreProduct.respond_to?(:insert_all)
|
23
|
+
stores.find_each do |store|
|
24
|
+
records = product_ids.map { |product_id| { product_id: product_id, store_id: store.id } }
|
18
25
|
|
19
|
-
|
20
|
-
|
21
|
-
|
26
|
+
# Rails 5 does not have insert_all
|
27
|
+
Spree::StoreProduct.insert_all(records)
|
28
|
+
end
|
22
29
|
end
|
23
30
|
end
|
24
31
|
end
|
@@ -22,6 +22,20 @@ module Spree
|
|
22
22
|
current_store.default_locale
|
23
23
|
end
|
24
24
|
|
25
|
+
def ensure_current_store(object)
|
26
|
+
return if object.nil?
|
27
|
+
|
28
|
+
if object.has_attribute?(:store_id)
|
29
|
+
if object.store.present? && object.store != current_store
|
30
|
+
raise Spree.t('errors.messages.store_is_already_set')
|
31
|
+
else
|
32
|
+
object.store = current_store
|
33
|
+
end
|
34
|
+
elsif object.class.method_defined?(:stores) && object.stores.exclude?(current_store)
|
35
|
+
object.stores << current_store
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
25
39
|
# Return a Hash of things that influence the prices displayed in your shop.
|
26
40
|
#
|
27
41
|
# By default, the only thing that influences prices that is the current order's +tax_zone+
|
data/lib/spree/core/version.rb
CHANGED
@@ -36,6 +36,12 @@ FactoryBot.define do
|
|
36
36
|
after :create do |product|
|
37
37
|
product.master.stock_items.first.adjust_count_on_hand(10)
|
38
38
|
end
|
39
|
+
|
40
|
+
trait :without_backorder do
|
41
|
+
after :create do |product|
|
42
|
+
product.master.stock_items.update_all(backorderable: false)
|
43
|
+
end
|
44
|
+
end
|
39
45
|
end
|
40
46
|
|
41
47
|
factory :product_with_option_types do
|
@@ -48,7 +48,7 @@ module Spree
|
|
48
48
|
remember_me: 'Se souvenir de moi',
|
49
49
|
my_account: 'Mon compte',
|
50
50
|
my_orders: 'Mes commandes',
|
51
|
-
|
51
|
+
logged_in_successfully: 'Connexion réussie'
|
52
52
|
})
|
53
53
|
end
|
54
54
|
# rubocop:enable Layout/ArgumentAlignment
|
@@ -7,4 +7,9 @@ RSpec.configure do |config|
|
|
7
7
|
config.around :each, type: :feature do |ex|
|
8
8
|
ex.run_with_retry retry: ENV.fetch('RSPEC_RETRY_RETRY_COUNT', 3).to_i
|
9
9
|
end
|
10
|
+
|
11
|
+
# callback to be run between retries
|
12
|
+
config.retry_callback = proc do |ex|
|
13
|
+
Rails.cache.clear
|
14
|
+
end
|
10
15
|
end
|
data/spree_core.gemspec
CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.metadata = {
|
17
17
|
"bug_tracker_uri" => "https://github.com/spree/spree/issues",
|
18
18
|
"changelog_uri" => "https://github.com/spree/spree/releases/tag/v#{s.version}",
|
19
|
-
"documentation_uri" => "https://
|
19
|
+
"documentation_uri" => "https://dev-docs.spreecommerce.org/",
|
20
20
|
"source_code_uri" => "https://github.com/spree/spree/tree/v#{s.version}",
|
21
21
|
}
|
22
22
|
|
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: 4.3.0.
|
4
|
+
version: 4.3.0.rc2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sean Schofield
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2021-08-
|
12
|
+
date: 2021-08-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: actionpack
|
@@ -483,6 +483,7 @@ files:
|
|
483
483
|
- app/models/concerns/spree/user_methods.rb
|
484
484
|
- app/models/concerns/spree/user_payment_source.rb
|
485
485
|
- app/models/concerns/spree/user_reporting.rb
|
486
|
+
- app/models/concerns/spree/user_roles.rb
|
486
487
|
- app/models/concerns/spree/vat_price_calculation.rb
|
487
488
|
- app/models/friendly_id/slug_decorator.rb
|
488
489
|
- app/models/spree/ability.rb
|
@@ -1192,9 +1193,9 @@ licenses:
|
|
1192
1193
|
- BSD-3-Clause
|
1193
1194
|
metadata:
|
1194
1195
|
bug_tracker_uri: https://github.com/spree/spree/issues
|
1195
|
-
changelog_uri: https://github.com/spree/spree/releases/tag/v4.3.0.
|
1196
|
-
documentation_uri: https://
|
1197
|
-
source_code_uri: https://github.com/spree/spree/tree/v4.3.0.
|
1196
|
+
changelog_uri: https://github.com/spree/spree/releases/tag/v4.3.0.rc2
|
1197
|
+
documentation_uri: https://dev-docs.spreecommerce.org/
|
1198
|
+
source_code_uri: https://github.com/spree/spree/tree/v4.3.0.rc2
|
1198
1199
|
post_install_message:
|
1199
1200
|
rdoc_options: []
|
1200
1201
|
require_paths:
|