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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2b031163e0c77da6776854068fb9769ed6cd44ff048e75a088ee6526c40db986
4
- data.tar.gz: 2cfbcbfb7a1c5221270e7b677222a94047b5965cb32e5144ca6540d927f2b51b
3
+ metadata.gz: d280751e897448ce4593ebe1d5f2fc9cd823e998699864ac8b52d2dfa28b49d6
4
+ data.tar.gz: 21ed38407942b369d6a7a2360730190a124264bd9b8137e79c49d4058fac16f6
5
5
  SHA512:
6
- metadata.gz: 375bd44efe93e706a1bd58abcc9be1fb3f2af0b0a993fe223a1e093033193105012284e0a7f03413fad0099feb105fa4b1526b8d576d76e58e62e37967c67768
7
- data.tar.gz: c82f2406e121b6fff092677e91d0344e35c5b6e19aee5aca1916ee819d7909a42ef854653922413e215c67934cb73df2a1af002fbe3d48f53db99ff854d80f93
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
- :option_value_ids, :scope, :sort_by, :deleted, :discontinued, :properties, :store
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
- Spree::Money.new(send(method_name), default_opts.merge(opts))
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 lifetime_value
7
- orders.complete.sum(:total)
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 order_count
11
- orders.complete.size
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
- if order_count > 0
16
- lifetime_value / order_count
17
- else
18
- BigDecimal('0.00')
19
- end
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
@@ -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: "http://example.com") instead
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
@@ -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
- logged_in_succesfully: Logged in successfully
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
- unless table_exists?(:spree_products_stores)
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
- stores.find_each do |store|
16
- prepared_values = product_ids.map { |id| "(#{id}, #{store.id}, '#{Time.current.to_s(:db)}', '#{Time.current.to_s(:db)}')" }.join(', ')
17
- next if prepared_values.empty?
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
- begin
20
- execute "INSERT INTO spree_products_stores (product_id, store_id, created_at, updated_at) VALUES #{prepared_values};"
21
- rescue ActiveRecord::RecordNotUnique; end
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
@@ -68,7 +68,7 @@ module Spree
68
68
  inside dummy_path do
69
69
  inject_require_for(gem)
70
70
  end
71
- rescue
71
+ rescue StandardError, LoadError
72
72
  end
73
73
  end
74
74
  end
@@ -35,4 +35,6 @@ Dummy::Application.configure do
35
35
  config.active_support.deprecation = :stderr
36
36
 
37
37
  config.active_job.queue_adapter = :test
38
+
39
+ config.cache_store = :redis_cache_store
38
40
  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+
@@ -1,5 +1,5 @@
1
1
  module Spree
2
- VERSION = '4.3.0.rc1'.freeze
2
+ VERSION = '4.3.0.rc2'.freeze
3
3
 
4
4
  def self.version
5
5
  VERSION
@@ -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
- logged_in_succesfully: 'Connexion réussie'
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://guides.spreecommerce.org/",
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.rc1
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-11 00:00:00.000000000 Z
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.rc1
1196
- documentation_uri: https://guides.spreecommerce.org/
1197
- source_code_uri: https://github.com/spree/spree/tree/v4.3.0.rc1
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: