spree_multi_store 1.0.0 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e04a1b3c2537beca45a3f71d694ab398b4beb627a8b1a7df529d2219720053fd
4
- data.tar.gz: 3faad6a5bf518fa4a3939bee2475ee0799a5d545fed6dedd0b72521ef9c0ffae
3
+ metadata.gz: 3882b1e05504ca432beedbb694edca5b1fdb8707a0d74d5850bb47fa43364594
4
+ data.tar.gz: de6285d81d742beea6db47cc1e9be857c8359dc6014230c53964c52f24a1735b
5
5
  SHA512:
6
- metadata.gz: '0508c322500915fcd34e1c8f1d004020d2075c7abd27615b5b607a08374ced3eb074a64ab4fe1fbe4a764f4d46ebd64d65be80dc0b08c2147115a7c7f601eda5'
7
- data.tar.gz: 4746391eeae2143b67e1fca2d70fac6853b00db0c8acc172f66fba4e7d84b94a2d1dd48cabbe8f6f723e63231f3d1ea4f04b46fd0217c3b8b151f648bfc4fdba
6
+ metadata.gz: 5fa6297b18bb5b43bc90f36c21fb915a23e032bb5c8d795883c2b8fcd1100edb707fa4dd108ac0add5000c7c2342bba02f643125b0acfe57640ea81ed4c8f24d
7
+ data.tar.gz: 32ac3d46363ced71dca2b76fc24ea78b87475febb65d3408b1daa792d464b3532d88bfd3a4ba3756c30ceb7d3c8ec30bbe89e374095898f46fadf253328881ad
@@ -13,21 +13,38 @@ module Spree
13
13
  protected
14
14
 
15
15
  def must_have_one_store
16
- return if stores.any?
16
+ return if associated_with_store?
17
17
 
18
18
  errors.add(:stores, Spree.t(:must_have_one_store))
19
19
  end
20
20
 
21
21
  def set_default_store
22
22
  return if disable_store_presence_validation?
23
- return if stores.any?
23
+ return if associated_with_store?
24
24
 
25
- stores << Spree::Store.default
25
+ # Build the join by +store_id+ instead of pushing the +Spree::Store.default+
26
+ # instance through the autosaving +has_many :stores, through:+.
27
+ send(store_join_association_name).build(store_id: Spree::Store.default.id)
26
28
  end
27
29
 
28
30
  # this can be overridden on model basis
29
31
  def disable_store_presence_validation?
30
32
  Spree::Config[:disable_store_presence_validation]
31
33
  end
34
+
35
+ private
36
+
37
+ # records built through a store's association (`store.payment_methods.build`)
38
+ # carry their link on the join association — `stores` can't see it until save
39
+ # (mirrors Spree::StoreScopedResource, spree/spree#14185)
40
+ def associated_with_store?
41
+ stores.any? || send(store_join_association_name).any?
42
+ end
43
+
44
+ # Name of the join association backing +has_many :stores, through:+
45
+ # (e.g. +:store_products+, +:store_payment_methods+, +:store_promotions+).
46
+ def store_join_association_name
47
+ self.class.reflect_on_association(:stores).through_reflection.name
48
+ end
32
49
  end
33
50
  end
@@ -10,6 +10,13 @@ module Spree
10
10
  has_many :custom_domains, class_name: 'Spree::CustomDomain', dependent: :destroy
11
11
  has_one :default_custom_domain, -> { where(default: true) }, class_name: 'Spree::CustomDomain'
12
12
 
13
+ # Replace core's singular +has_many :products, dependent: :nullify+ (FK
14
+ # +spree_products.store_id+) with the legacy join-table association.
15
+ # Same association name overrides the core declaration in Rails.
16
+ has_many :store_products, class_name: 'Spree::StoreProduct', dependent: :destroy
17
+ has_many :products, through: :store_products, class_name: 'Spree::Product'
18
+ has_many :variants, through: :products, class_name: 'Spree::Variant', source: :variants_including_master
19
+
13
20
  attribute :import_products_from_store_id, :string, default: nil
14
21
  attribute :import_payment_methods_from_store_id, :string, default: nil
15
22
 
@@ -8,6 +8,10 @@ module Spree
8
8
  formatted_custom_domain || formatted_url
9
9
  end
10
10
 
11
+ def storefront_url
12
+ formatted_custom_domain || super
13
+ end
14
+
11
15
  def can_be_deleted?
12
16
  self.class.where.not(id: id).any?
13
17
  end
@@ -2,6 +2,19 @@ module Spree
2
2
  module MultiStore
3
3
  module ProductDecorator
4
4
  def self.prepended(base)
5
+ # Spree 5.5 core sets +belongs_to :store+ via +Spree::Product::Channels+;
6
+ # this gem layers +has_many :stores+ on top through the legacy join.
7
+ # Keep both: +store+ stays as the "home" store used by core for
8
+ # publication/channel scoping; +stores+ is the multi-store catalog set.
9
+ base.has_many :store_products, class_name: 'Spree::StoreProduct'
10
+ base.has_many :stores, through: :store_products, class_name: 'Spree::Store'
11
+
12
+ base.scope :for_store, ->(store) { joins(:store_products).where(StoreProduct.table_name => { store_id: store.id }) }
13
+
14
+ # Ransack: re-expose +stores+ alongside the core associations.
15
+ base.whitelisted_ransackable_associations =
16
+ (base.whitelisted_ransackable_associations.to_a + %w[stores store_products]).uniq
17
+
5
18
  base.include Spree::MultiStoreResource
6
19
  end
7
20
  end
@@ -0,0 +1,29 @@
1
+ module Spree
2
+ class StoreProduct < Spree.base_class
3
+ has_prefix_id :sp
4
+
5
+ self.table_name = 'spree_products_stores'
6
+
7
+ belongs_to :store, class_name: 'Spree::Store', touch: true
8
+ belongs_to :product, class_name: 'Spree::Product', touch: true
9
+
10
+ validates :store, :product, presence: true
11
+ validates :store_id, uniqueness: { scope: :product_id }
12
+
13
+ def refresh_metrics!
14
+ return if product.nil?
15
+
16
+ completed_order_ids = product.completed_orders.where(store_id: store_id).select(:id)
17
+ variant_ids = product.variants_including_master.ids
18
+
19
+ line_items = Spree::LineItem.joins(:order)
20
+ .where(spree_orders: { id: completed_order_ids })
21
+ .where(variant_id: variant_ids)
22
+
23
+ update!(
24
+ units_sold_count: line_items.sum(:quantity),
25
+ revenue: line_items.sum(:pre_tax_amount)
26
+ )
27
+ end
28
+ end
29
+ end
@@ -1,3 +1,8 @@
1
+ # Multi-store setup
2
+ # You need to set a wildcard `root_domain` on the store to enable multi-store setup
3
+ # all new stores will be created in a subdomain of the root domain, eg. store1.localhost, store2.localhost, etc.
4
+ Spree.root_domain = ENV.fetch('SPREE_ROOT_DOMAIN', 'localhost')
5
+
1
6
  Rails.application.config.after_initialize do
2
7
  Spree::Dependencies.current_store_finder = 'Spree::Stores::FindCurrent'
3
8
 
@@ -8,12 +13,12 @@ Rails.application.config.after_initialize do
8
13
  :import_payment_methods_from_store_id
9
14
  )
10
15
 
16
+ # Re-add +store_ids+ to permitted product attributes — core dropped it when
17
+ # Product went single-store; this gem restores +has_many :stores+ and the
18
+ # legacy +_stores.html.erb+ partial submits a +store_ids[]+ checkbox list.
19
+ Spree::PermittedAttributes.product_attributes.push(store_ids: [])
20
+
11
21
  if defined?(Spree::Admin)
12
22
  Spree.admin.partials.product_form_sidebar << 'spree/admin/products/form/stores'
13
23
  end
14
-
15
- # Multi-store setup
16
- # You need to set a wildcard `root_domain` on the store to enable multi-store setup
17
- # all new stores will be created in a subdomain of the root domain, eg. store1.localhost, store2.localhost, etc.
18
- Spree.root_domain = ENV.fetch('SPREE_ROOT_DOMAIN', 'localhost')
19
24
  end
@@ -0,0 +1,6 @@
1
+ FactoryBot.define do
2
+ factory :store_product, class: 'Spree::StoreProduct' do
3
+ store
4
+ product
5
+ end
6
+ end
@@ -1,5 +1,9 @@
1
1
  module Spree
2
2
  module MultiStore
3
- VERSION = '1.0.0'
3
+ VERSION = '1.0.2'.freeze
4
+
5
+ def gem_version
6
+ Gem::Version.new(VERSION)
7
+ end
4
8
  end
5
9
  end
@@ -0,0 +1,3 @@
1
+ require 'factory_bot'
2
+
3
+ Dir["#{__dir__}/../spree/multi_store/factories/**/*.rb"].each { |f| load f }
@@ -1 +1,8 @@
1
+ # Top-level marker constant. Spree core checks +defined?(SpreeMultiStore)+ before
2
+ # including +Spree::Product::LegacyMultiStoreSupport+ — defining it here ensures
3
+ # core skips the deprecation-only fallback so this gem's ProductDecorator can
4
+ # install the real +has_many :stores+ association.
5
+ module SpreeMultiStore
6
+ end
7
+
1
8
  require 'spree/multi_store'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spree_multi_store
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vendo Connect Inc.
@@ -76,6 +76,7 @@ files:
76
76
  - app/models/spree/multi_store/product_decorator.rb
77
77
  - app/models/spree/multi_store/promotion_decorator.rb
78
78
  - app/models/spree/multi_store/store_decorator.rb
79
+ - app/models/spree/store_product.rb
79
80
  - app/views/spree/admin/custom_domains/_custom_domain.html.erb
80
81
  - app/views/spree/admin/custom_domains/_custom_domains.html.erb
81
82
  - app/views/spree/admin/custom_domains/_form.html.erb
@@ -92,16 +93,18 @@ files:
92
93
  - config/routes.rb
93
94
  - lib/spree/multi_store.rb
94
95
  - lib/spree/multi_store/engine.rb
96
+ - lib/spree/multi_store/factories/store_product_factory.rb
95
97
  - lib/spree/multi_store/version.rb
96
98
  - lib/spree_multi_store.rb
99
+ - lib/spree_multi_store/factories.rb
97
100
  homepage: https://github.com/spree/spree_multi_store
98
101
  licenses:
99
102
  - AGPL-3.0-or-later
100
103
  metadata:
101
104
  bug_tracker_uri: https://github.com/spree/spree_multi_store/issues
102
- changelog_uri: https://github.com/spree/spree_multi_store/releases/tag/v1.0.0
105
+ changelog_uri: https://github.com/spree/spree_multi_store/releases/tag/v1.0.2
103
106
  documentation_uri: https://docs.spreecommerce.org/
104
- source_code_uri: https://github.com/spree/spree_multi_store/tree/v1.0.0
107
+ source_code_uri: https://github.com/spree/spree_multi_store/tree/v1.0.2
105
108
  post_install_message: |
106
109
  --------------------------------------------------------------
107
110
  Thank you for installing Spree Multi-Store!