spree_core 4.3.0.rc1 → 4.3.0.rc2
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 +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:
|