spree_multi_store 1.0.2 → 1.0.4

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: 3882b1e05504ca432beedbb694edca5b1fdb8707a0d74d5850bb47fa43364594
4
- data.tar.gz: de6285d81d742beea6db47cc1e9be857c8359dc6014230c53964c52f24a1735b
3
+ metadata.gz: f02e67d50bbd118761a9eecdc52fbf4778cc404e5ee1058bfbb709fc04bb7e15
4
+ data.tar.gz: 456956ceb3ec5b6a86ed5f70bbfc6d0a1787be5e65c9dcf04abad49b14a3085c
5
5
  SHA512:
6
- metadata.gz: 5fa6297b18bb5b43bc90f36c21fb915a23e032bb5c8d795883c2b8fcd1100edb707fa4dd108ac0add5000c7c2342bba02f643125b0acfe57640ea81ed4c8f24d
7
- data.tar.gz: 32ac3d46363ced71dca2b76fc24ea78b87475febb65d3408b1daa792d464b3532d88bfd3a4ba3756c30ceb7d3c8ec30bbe89e374095898f46fadf253328881ad
6
+ metadata.gz: 3b6b0612cfb84d157f356e958a6bd91266b143caa025ee454c24a423def08e0529fdb6b7bac534eee3792edf6c78fe6f032f7b7f51e718edf5fca9a2b75e2c93
7
+ data.tar.gz: 320a0abbfe36ee10071702145209e2d514b956e0c98c911359b2205b88f0a571e8472332f3d329a858cfc0f99fefd0922ca06bc4a0733bdf688a0e4e8908f423
@@ -1,13 +1,6 @@
1
1
  module Spree
2
2
  module Store::MultiStoreClassOverrides
3
- def current(url = nil)
4
- if url.present?
5
- Spree.current_store_finder.new(url: url).execute
6
- else
7
- Spree::Current.store
8
- end
9
- end
10
-
3
+ # Aggregate supported locales across every store, not just the current one.
11
4
  def available_locales
12
5
  Spree::Store.all.map(&:supported_locales_list).flatten.uniq
13
6
  end
@@ -7,16 +7,20 @@ module Spree
7
7
  )
8
8
 
9
9
  included do
10
- has_many :custom_domains, class_name: 'Spree::CustomDomain', dependent: :destroy
11
- has_one :default_custom_domain, -> { where(default: true) }, class_name: 'Spree::CustomDomain'
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.
10
+ # Replace core's singular FK associations (+has_many :products /
11
+ # :promotions / :payment_methods, dependent: :nullify+, backed by each
12
+ # resource's +store_id+ column) with the legacy join-table associations.
13
+ # Re-declaring the same association name overrides the core declaration.
16
14
  has_many :store_products, class_name: 'Spree::StoreProduct', dependent: :destroy
17
15
  has_many :products, through: :store_products, class_name: 'Spree::Product'
18
16
  has_many :variants, through: :products, class_name: 'Spree::Variant', source: :variants_including_master
19
17
 
18
+ has_many :store_promotions, class_name: 'Spree::StorePromotion', dependent: :destroy
19
+ has_many :promotions, through: :store_promotions, class_name: 'Spree::Promotion'
20
+
21
+ has_many :store_payment_methods, class_name: 'Spree::StorePaymentMethod', dependent: :destroy
22
+ has_many :payment_methods, through: :store_payment_methods, class_name: 'Spree::PaymentMethod'
23
+
20
24
  attribute :import_products_from_store_id, :string, default: nil
21
25
  attribute :import_payment_methods_from_store_id, :string, default: nil
22
26
 
@@ -32,27 +36,12 @@ module Spree
32
36
  before_destroy :validate_not_last, unless: :skip_validate_not_last
33
37
  before_destroy :pass_default_flag_to_other_store
34
38
 
35
- scope :by_custom_domain, ->(url) { left_joins(:custom_domains).where("#{Spree::CustomDomain.table_name}.url" => url) }
36
39
  scope :by_url, ->(url) { where(url: url).or(where("#{table_name}.url like ?", "%#{url}%")) }
37
40
 
38
41
  # Re-configure FriendlyId to use :history for code tracking across renames
39
42
  friendly_id :slug_candidates, use: [:slugged, :history], slug_column: :code, routes: :normal
40
43
  end
41
44
 
42
- def formatted_custom_domain
43
- return unless default_custom_domain
44
-
45
- @formatted_custom_domain ||= if Rails.env.development? || Rails.env.test?
46
- URI::Generic.build(
47
- scheme: Rails.application.routes.default_url_options[:protocol] || 'http',
48
- host: default_custom_domain.url,
49
- port: Rails.application.routes.default_url_options[:port]
50
- ).to_s
51
- else
52
- URI::HTTPS.build(host: default_custom_domain.url).to_s
53
- end
54
- end
55
-
56
45
  def can_be_deleted?
57
46
  self.class.where.not(id: id).any?
58
47
  end
@@ -1,17 +1,5 @@
1
1
  module Spree
2
2
  module Store::MultiStoreOverrides
3
- def url_or_custom_domain
4
- default_custom_domain&.url || url
5
- end
6
-
7
- def formatted_url_or_custom_domain
8
- formatted_custom_domain || formatted_url
9
- end
10
-
11
- def storefront_url
12
- formatted_custom_domain || super
13
- end
14
-
15
3
  def can_be_deleted?
16
4
  self.class.where.not(id: id).any?
17
5
  end
@@ -2,8 +2,30 @@ module Spree
2
2
  module MultiStore
3
3
  module PaymentMethodDecorator
4
4
  def self.prepended(base)
5
+ # Single-store core sets +belongs_to :store+ on PaymentMethod; this gem
6
+ # layers +has_many :stores+ back on top through the legacy join table.
7
+ # Core no longer declares this association, so it must live here —
8
+ # without it +Spree::MultiStoreResource#set_default_store+ has no
9
+ # +:stores+ reflection to build the join through.
10
+ base.has_many :store_payment_methods, class_name: 'Spree::StorePaymentMethod', inverse_of: :payment_method
11
+ base.has_many :stores, through: :store_payment_methods, class_name: 'Spree::Store'
12
+
13
+ base.scope :for_store, ->(store) { joins(:store_payment_methods).where(StorePaymentMethod.table_name => { store_id: store.id }) }
14
+
15
+ base.whitelisted_ransackable_associations =
16
+ (base.whitelisted_ransackable_associations.to_a + %w[stores store_payment_methods]).uniq
17
+
5
18
  base.include Spree::MultiStoreResource
6
19
  end
20
+
21
+ # Core checks the singular +store_id+ FK; with multi-store sharing a
22
+ # payment method can belong to several stores, so test membership of the
23
+ # join table instead.
24
+ def available_for_store?(store)
25
+ return true if store.blank?
26
+
27
+ store_ids.include?(store.id)
28
+ end
7
29
  end
8
30
  end
9
31
 
@@ -2,6 +2,19 @@ module Spree
2
2
  module MultiStore
3
3
  module PromotionDecorator
4
4
  def self.prepended(base)
5
+ # Single-store core sets +belongs_to :store+ on Promotion; this gem
6
+ # layers +has_many :stores+ back on top through the legacy join table.
7
+ # Core no longer declares this association, so it must live here —
8
+ # without it +Spree::MultiStoreResource#set_default_store+ has no
9
+ # +:stores+ reflection to build the join through.
10
+ base.has_many :store_promotions, class_name: 'Spree::StorePromotion'
11
+ base.has_many :stores, through: :store_promotions, class_name: 'Spree::Store'
12
+
13
+ base.scope :for_store, ->(store) { joins(:store_promotions).where(StorePromotion.table_name => { store_id: store.id }) }
14
+
15
+ base.whitelisted_ransackable_associations =
16
+ (base.whitelisted_ransackable_associations.to_a + %w[stores store_promotions]).uniq
17
+
5
18
  base.include Spree::MultiStoreResource
6
19
  end
7
20
  end
@@ -4,10 +4,6 @@
4
4
  Spree.root_domain = ENV.fetch('SPREE_ROOT_DOMAIN', 'localhost')
5
5
 
6
6
  Rails.application.config.after_initialize do
7
- Spree::Dependencies.current_store_finder = 'Spree::Stores::FindCurrent'
8
-
9
- Spree.metafields.enabled_resources << Spree::CustomDomain
10
-
11
7
  Spree::PermittedAttributes.store_attributes.push(
12
8
  :import_products_from_store_id,
13
9
  :import_payment_methods_from_store_id
data/config/routes.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  Spree::Core::Engine.add_routes do
2
2
  namespace :admin, path: Spree.admin_path do
3
3
  resources :stores, only: [:new, :create], controller: 'multi_store/stores'
4
- resources :custom_domains, except: :show
5
4
  end
6
5
  end
@@ -1,6 +1,6 @@
1
1
  module Spree
2
2
  module MultiStore
3
- VERSION = '1.0.2'.freeze
3
+ VERSION = '1.0.4'.freeze
4
4
 
5
5
  def gem_version
6
6
  Gem::Version.new(VERSION)
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.2
4
+ version: 1.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vendo Connect Inc.
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: 5.4.0.beta
41
+ - !ruby/object:Gem::Dependency
42
+ name: spree_custom_domains
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: spree_dev_tools
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -62,33 +76,23 @@ files:
62
76
  - LICENSE.md
63
77
  - README.md
64
78
  - Rakefile
65
- - app/controllers/spree/admin/custom_domains_controller.rb
66
79
  - app/controllers/spree/admin/multi_store/base_controller_decorator.rb
67
80
  - app/controllers/spree/admin/multi_store/stores_controller.rb
68
- - app/finders/spree/stores/find_current.rb
69
81
  - app/helpers/spree/admin/multi_store_helper.rb
70
82
  - app/models/concerns/spree/multi_store_resource.rb
71
83
  - app/models/concerns/spree/store/multi_store_class_overrides.rb
72
84
  - app/models/concerns/spree/store/multi_store_methods.rb
73
85
  - app/models/concerns/spree/store/multi_store_overrides.rb
74
- - app/models/spree/custom_domain.rb
75
86
  - app/models/spree/multi_store/payment_method_decorator.rb
76
87
  - app/models/spree/multi_store/product_decorator.rb
77
88
  - app/models/spree/multi_store/promotion_decorator.rb
78
89
  - app/models/spree/multi_store/store_decorator.rb
79
90
  - app/models/spree/store_product.rb
80
- - app/views/spree/admin/custom_domains/_custom_domain.html.erb
81
- - app/views/spree/admin/custom_domains/_custom_domains.html.erb
82
- - app/views/spree/admin/custom_domains/_form.html.erb
83
- - app/views/spree/admin/custom_domains/edit.html.erb
84
- - app/views/spree/admin/custom_domains/index.html.erb
85
- - app/views/spree/admin/custom_domains/new.html.erb
86
91
  - app/views/spree/admin/multi_store/stores/new.html.erb
87
92
  - app/views/spree/admin/multi_store/stores/new.turbo_stream.erb
88
93
  - app/views/spree/admin/products/form/_stores.html.erb
89
94
  - app/views/spree/admin/shared/sidebar/_store_dropdown.html.erb
90
95
  - config/initializers/spree_multi_store.rb
91
- - config/initializers/spree_multi_store_navigation.rb
92
96
  - config/locales/en.yml
93
97
  - config/routes.rb
94
98
  - lib/spree/multi_store.rb
@@ -102,9 +106,9 @@ licenses:
102
106
  - AGPL-3.0-or-later
103
107
  metadata:
104
108
  bug_tracker_uri: https://github.com/spree/spree_multi_store/issues
105
- changelog_uri: https://github.com/spree/spree_multi_store/releases/tag/v1.0.2
109
+ changelog_uri: https://github.com/spree/spree_multi_store/releases/tag/v1.0.4
106
110
  documentation_uri: https://docs.spreecommerce.org/
107
- source_code_uri: https://github.com/spree/spree_multi_store/tree/v1.0.2
111
+ source_code_uri: https://github.com/spree/spree_multi_store/tree/v1.0.4
108
112
  post_install_message: |
109
113
  --------------------------------------------------------------
110
114
  Thank you for installing Spree Multi-Store!
@@ -1,21 +0,0 @@
1
- module Spree
2
- module Admin
3
- class CustomDomainsController < ResourceController
4
- include Spree::Admin::SettingsConcern
5
-
6
- protected
7
-
8
- def collection_url
9
- spree.admin_custom_domains_path
10
- end
11
-
12
- def location_after_save
13
- spree.admin_custom_domains_path
14
- end
15
-
16
- def permitted_resource_params
17
- params.require(:custom_domain).permit(Spree::PermittedAttributes.custom_domain_attributes)
18
- end
19
- end
20
- end
21
- end
@@ -1,28 +0,0 @@
1
- module Spree
2
- module Stores
3
- class FindCurrent
4
- def initialize(scope: nil, url: nil)
5
- @scope = scope || Spree::Store
6
- @url = url
7
- end
8
-
9
- def execute
10
- store = by_url(scope) || scope.default
11
- return if store.nil?
12
-
13
- Spree::Current.store = store
14
- store
15
- end
16
-
17
- protected
18
-
19
- attr_reader :scope, :url
20
-
21
- def by_url(scope)
22
- return if url.blank?
23
-
24
- scope.by_custom_domain(url).or(scope.by_url(url)).first
25
- end
26
- end
27
- end
28
- end
@@ -1,61 +0,0 @@
1
- module Spree
2
- class CustomDomain < Spree::Base
3
- has_prefix_id :domain
4
-
5
- include Spree::SingleStoreResource
6
- include Spree::Metafields
7
- include Spree::Metadata
8
-
9
- normalizes :url, with: ->(value) { value&.to_s&.squish&.presence }
10
-
11
- #
12
- # Associations
13
- #
14
- belongs_to :store, class_name: 'Spree::Store', inverse_of: :custom_domains, touch: true
15
-
16
- #
17
- # Validations
18
- #
19
- validates :url, presence: true, uniqueness: true, format: {
20
- with: %r{\A(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\z}i
21
- }, length: { in: 1..63 }
22
- validate :url_is_valid
23
-
24
- #
25
- # Callbacks
26
- #
27
- before_validation :sanitize_url
28
- after_save :ensure_has_one_default
29
- after_validation :ensure_default, on: :create
30
-
31
- def url_is_valid
32
- return if url.blank?
33
- parts = url.split('.')
34
-
35
- errors.add(:url, 'use domain or subdomain') if parts.size > 4 || parts.size < 2
36
- end
37
-
38
- def ensure_default
39
- self.default = store.custom_domains.count.zero?
40
- end
41
-
42
- def ensure_has_one_default
43
- store.custom_domains.where.not(id: id).update_all(default: false) if default?
44
- end
45
-
46
- def active?
47
- true
48
- end
49
-
50
- def name
51
- url
52
- end
53
-
54
- private
55
-
56
- # remove https:// and http:// from the url
57
- def sanitize_url
58
- self.url = url&.gsub(%r{https?://}, '')
59
- end
60
- end
61
- end
@@ -1,11 +0,0 @@
1
- <tr id="<%= spree_dom_id custom_domain %>">
2
- <td><%= custom_domain.url %></td>
3
- <td>
4
- <%= active_badge(custom_domain.active?) %>
5
- </td>
6
-
7
- <td><%= active_badge(custom_domain.default?) %></td>
8
- <td class="actions">
9
- <%= link_to_edit(custom_domain, no_text: true, url: spree.edit_admin_custom_domain_path(custom_domain), data: { turbo: false }) %>
10
- </td>
11
- </tr>
@@ -1,19 +0,0 @@
1
- <% if current_store.custom_domains.any? %>
2
- <div class="table-responsive rounded-lg mt-4 border">
3
- <table class="table">
4
- <thead>
5
- <tr>
6
- <th scope="col"><%= sort_link @search, :name, Spree.t(:name) %></th>
7
- <th scope="col"><%= Spree.t(:active) %>?</th>
8
- <th scope="col"><%= Spree.t(:default) %>?</th>
9
- <th scope="col"></th>
10
- </tr>
11
- </thead>
12
- <tbody>
13
- <%= render collection: current_store.custom_domains, partial: 'spree/admin/custom_domains/custom_domain', cached: spree_base_cache_scope %>
14
- </tbody>
15
- </table>
16
- </div>
17
- <% else %>
18
- <%= render 'spree/admin/shared/no_resource_found' %>
19
- <% end %>
@@ -1,7 +0,0 @@
1
- <div class="card mb-6">
2
- <div class="card-body">
3
- <%= f.spree_text_field :url, label: Spree.t(:domain), prepend: 'https://', autofocus: f.object.new_record?, required: true %>
4
-
5
- <%= f.spree_check_box :default, help: 'We will use this domain in emails to customers.' %>
6
- </div>
7
- </div>
@@ -1 +0,0 @@
1
- <%= render 'spree/admin/shared/edit_resource' %>
@@ -1,65 +0,0 @@
1
- <%= content_for(:page_title) do %>
2
- <%= Spree.t(:domains) %>
3
- <% end %>
4
-
5
- <% content_for :page_actions do %>
6
- <%= render_admin_partials(:custom_domains_actions_partials) %>
7
- <% end %>
8
-
9
- <%= render_admin_partials(:custom_domains_header_partials) %>
10
-
11
- <div class="card-lg p-6">
12
- <h5 class="mb-2">Internal URL</h5>
13
- <div class="grid grid-cols-12 gap-6 mb-6">
14
- <div class="col-span-12 lg:col-span-4">
15
- <p class="text-gray-600">
16
- This is your internal Admin URL.
17
- </p>
18
- </div>
19
- <div class="col-span-12 lg:col-span-7 lg:col-start-6">
20
- <%= form_for current_store, url: spree.admin_store_path, data: { turbo: false, controller: 'enable-button', 'enable-button-disable-when-not-changed-value': true } do |f| %>
21
- <% if Spree.root_domain.present? %>
22
- <div class="flex items-center gap-6">
23
- <div class="input-group pr-2 grow <% if current_store.custom_domains.any? %>disabled<% end %>">
24
- <span class="text-gray-400 pl-3 pr-0">https://</span>
25
- <%= f.text_field :code, class: 'border-0 focus:ring-0 focus:outline-none grow rounded-lg text-base pl-0', data: { enable_button_target: 'input' }, required: true, disabled: current_store.custom_domains.any? %>
26
- <span>.<%= Spree.root_domain %></span>
27
-
28
- <%= clipboard_component(current_store.formatted_url) %>
29
- </div>
30
- <% unless current_store.custom_domains.any? %>
31
- <%= turbo_save_button_tag %>
32
- <% end %>
33
- </div>
34
- <% else %>
35
- <div class="flex items-center gap-6">
36
- <div class="input-group pr-2 grow">
37
- <span class="text-gray-400 pl-3 pr-0">https://</span>
38
- <%= f.text_field :url, class: 'border-0 focus:ring-0 focus:outline-none grow rounded-lg text-base pl-0', required: true, data: { enable_button_target: 'input' } %>
39
- <%= clipboard_component(current_store.formatted_url) %>
40
- </div>
41
- <%= turbo_save_button_tag %>
42
- </div>
43
- <% end %>
44
- <% end %>
45
- </div>
46
- </div>
47
- <hr class="my-12" />
48
- <h5 class="mb-2"><%= Spree.t(:custom_domains) %></h5>
49
- <div class="grid grid-cols-12 gap-6">
50
- <div class="col-span-12 lg:col-span-4">
51
- <p class="text-gray-600">
52
- Connect your domain or subdomain to your storefront.
53
- </p>
54
- </div>
55
- <div class="col-span-12 lg:col-span-7 lg:col-start-6">
56
- <div class="text-right">
57
- <%= link_to Spree.t(:new_domain), spree.new_admin_custom_domain_path, class: "btn btn-primary" %>
58
- </div>
59
-
60
- <%= turbo_frame_tag 'admin_custom_domains_index' do %>
61
- <%= render 'custom_domains' %>
62
- <% end %>
63
- </div>
64
- </div>
65
- </div>
@@ -1 +0,0 @@
1
- <%= render 'spree/admin/shared/new_resource' %>
@@ -1,14 +0,0 @@
1
- Rails.application.config.after_initialize do
2
- next unless defined?(Spree::Admin)
3
-
4
- settings_nav = Spree.admin.navigation.settings
5
-
6
- # Domains
7
- settings_nav.add :domains,
8
- label: :domains,
9
- url: :admin_custom_domains_path,
10
- icon: 'world-www',
11
- position: 60,
12
- active: -> { controller_name == 'custom_domains' },
13
- if: -> { can?(:manage, Spree::CustomDomain) }
14
- end