stall 0.3.2 → 0.3.3
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/README.md +15 -21
- data/app/assets/javascripts/para/stall/inputs/variants-matrix/input.coffee +8 -1
- data/app/assets/javascripts/para/stall/inputs/variants-matrix/variant.coffee +9 -0
- data/app/assets/javascripts/stall.coffee +7 -1
- data/app/assets/javascripts/stall/add-to-cart-form.coffee +1 -4
- data/app/assets/javascripts/stall/products-filters.coffee +29 -0
- data/app/assets/stylesheets/para/stall.sass +5 -0
- data/app/assets/stylesheets/stall.sass +0 -0
- data/app/controllers/stall/checkout/steps_controller.rb +6 -5
- data/app/controllers/stall/checkout_base_controller.rb +14 -0
- data/app/controllers/stall/checkouts_controller.rb +7 -4
- data/app/controllers/stall/curated_product_lists_controller.rb +10 -0
- data/app/controllers/stall/line_items_controller.rb +1 -5
- data/app/controllers/stall/manufacturers_controller.rb +12 -0
- data/app/controllers/stall/omniauth_callbacks_controller.rb +49 -0
- data/app/controllers/stall/product_categories_controller.rb +13 -0
- data/app/controllers/stall/products_breadcrumbs.rb +16 -0
- data/app/controllers/stall/products_controller.rb +20 -0
- data/app/controllers/stall/products_search.rb +11 -0
- data/app/helpers/stall/customers_helper.rb +0 -10
- data/app/helpers/stall/omniauth_helper.rb +7 -0
- data/app/helpers/stall/prices_helper.rb +12 -0
- data/app/helpers/stall/products_filters_helper.rb +34 -0
- data/app/mailers/stall/customer_mailer.rb +4 -3
- data/app/models/curated_list_product.rb +3 -0
- data/app/models/curated_product_list.rb +3 -0
- data/app/models/image.rb +3 -0
- data/app/models/product_suggestion.rb +3 -0
- data/app/models/stall/models/curated_list_product.rb +15 -0
- data/app/models/stall/models/curated_product_list.rb +22 -0
- data/app/models/stall/models/customer.rb +5 -8
- data/app/models/stall/models/image.rb +21 -0
- data/app/models/stall/models/manufacturer.rb +4 -0
- data/app/models/stall/models/product.rb +30 -7
- data/app/models/stall/models/product_category.rb +5 -2
- data/app/models/stall/models/product_list.rb +1 -1
- data/app/models/stall/models/product_suggestion.rb +14 -0
- data/app/models/stall/models/shipment.rb +0 -2
- data/app/models/stall/models/user.rb +18 -0
- data/app/models/stall/models/user_omniauth_account.rb +13 -0
- data/app/models/stall/models/variant.rb +11 -11
- data/app/models/user.rb +3 -0
- data/app/models/user_omniauth_account.rb +3 -0
- data/app/services/stall/add_to_cart_service.rb +19 -4
- data/app/services/stall/available_stocks_service.rb +11 -0
- data/app/services/stall/cart_credit_note_creation_service.rb +4 -0
- data/app/services/stall/cart_payment_validation_service.rb +5 -3
- data/app/services/stall/credit_usage_service.rb +8 -2
- data/app/services/stall/omniauth_user_authentication_service.rb +48 -0
- data/app/services/stall/product_list_staleness_handling_service.rb +6 -3
- data/app/services/stall/products_search_service.rb +23 -0
- data/app/services/stall/shipping_notification_service.rb +1 -1
- data/app/views/admin/carts/_filters.html.haml +10 -4
- data/app/views/admin/carts/_form.html.haml +9 -9
- data/app/views/admin/manufacturers/_form.html.haml +7 -0
- data/app/views/admin/manufacturers/_table.html.haml +8 -0
- data/app/views/admin/product_categories/_form.html.haml +7 -0
- data/app/views/admin/products/_form.html.haml +23 -0
- data/app/views/admin/products/_table.html.haml +4 -2
- data/app/views/checkout/steps/_informations.html.haml +2 -2
- data/app/views/para/admin/resources/_variant_row.html.haml +9 -1
- data/app/views/para/admin/resources/_variant_row_header.html.haml +14 -0
- data/app/views/para/stall/inputs/_variant_select.html.haml +3 -3
- data/app/views/para/stall/inputs/_variants_matrix.html.haml +7 -16
- data/app/views/para/stall/inputs/shipping_notes/new.html.haml +22 -0
- data/app/views/para/stall/inputs/shipping_notes/sent.html.haml +11 -0
- data/app/views/stall/carts/_cart.html.haml +1 -1
- data/app/views/stall/credit_note_adjustments/_form.html.haml +1 -1
- data/app/views/stall/curated_product_lists/show.html.haml +8 -0
- data/app/views/stall/customers/_fields.html.haml +17 -5
- data/app/views/stall/customers/_sign_in.html.haml +22 -10
- data/app/views/stall/line_items/_form.html.haml +2 -3
- data/app/views/stall/manufacturers/show.html.haml +8 -0
- data/app/views/stall/product_categories/show.html.haml +8 -0
- data/app/views/stall/products/_filters.html.haml +4 -0
- data/app/views/stall/products/_list.html.haml +7 -0
- data/app/views/stall/products/_product.html.haml +4 -0
- data/app/views/stall/products/_product_details.html.haml +13 -0
- data/app/views/stall/products/filters/_category_filter.html.haml +2 -0
- data/app/views/stall/products/filters/_manufacturer_filter.html.haml +2 -0
- data/app/views/stall/products/filters/_price_filter.html.haml +2 -0
- data/app/views/stall/products/filters/_property_filter.html.haml +2 -0
- data/app/views/stall/products/index.html.haml +8 -0
- data/app/views/stall/products/show.html.haml +26 -0
- data/config/locales/stall.fr.yml +97 -11
- data/db/migrate/20170221094450_add_slug_to_stall_manufacturers.rb +5 -0
- data/db/migrate/20170303122616_create_stall_product_suggestions.rb +13 -0
- data/db/migrate/20170303151939_add_position_to_stall_manufacturers.rb +5 -0
- data/db/migrate/20170308162740_create_stall_curated_product_lists.rb +10 -0
- data/db/migrate/20170308163532_create_stall_curated_list_products.rb +14 -0
- data/db/migrate/20170317103740_create_stall_users.rb +28 -0
- data/db/migrate/20170317104332_create_stall_user_omniauth_accounts.rb +14 -0
- data/db/migrate/20170320133513_fix_curated_product_list_bad_foreign_key.rb +6 -0
- data/db/migrate/20170321104203_create_stall_images.rb +11 -0
- data/db/migrate/20170321112248_remove_image_attachment_to_stall_products.rb +5 -0
- data/db/migrate/20170411134756_add_stock_to_stall_variants.rb +5 -0
- data/lib/ext/ransack.rb +13 -0
- data/lib/generators/stall/install/templates/initializer.rb +50 -15
- data/lib/generators/stall/service/service_generator.rb +0 -4
- data/lib/generators/stall/view/view_generator.rb +10 -8
- data/lib/para/stall/inputs/variant_select_input.rb +11 -1
- data/lib/para/stall/inputs/variants_matrix_input.rb +12 -6
- data/lib/stall.rb +14 -0
- data/lib/stall/addressable.rb +2 -2
- data/lib/stall/addresses/copy_source_to_target.rb +7 -3
- data/lib/stall/addresses/prefill_target_from_source.rb +4 -2
- data/lib/stall/cart_helper.rb +3 -3
- data/lib/stall/carts_cleaner.rb +2 -2
- data/lib/stall/checkout/informations_checkout_step.rb +2 -2
- data/lib/stall/config.rb +29 -9
- data/lib/stall/engine.rb +28 -13
- data/lib/stall/omniauth_provider.rb +41 -0
- data/lib/stall/payable.rb +3 -1
- data/lib/stall/product_filters.rb +12 -0
- data/lib/stall/product_filters/base_filter.rb +43 -0
- data/lib/stall/product_filters/builder.rb +59 -0
- data/lib/stall/product_filters/category_filter.rb +28 -0
- data/lib/stall/product_filters/manufacturer_filter.rb +19 -0
- data/lib/stall/product_filters/price_filter.rb +39 -0
- data/lib/stall/product_filters/property_filter.rb +38 -0
- data/lib/stall/routes.rb +40 -0
- data/lib/stall/shipping/calculator.rb +3 -1
- data/lib/stall/version.rb +1 -1
- metadata +158 -7
- data/app/assets/stylesheets/stall/carts.css +0 -4
data/lib/stall/config.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
module Stall
|
|
2
2
|
class Config
|
|
3
3
|
extend Stall::Utils::ConfigDSL
|
|
4
|
+
|
|
4
5
|
# Store name used in e-mails and other interfaces duisplaying such an
|
|
5
6
|
# information
|
|
6
7
|
param :store_name
|
|
@@ -20,17 +21,26 @@ module Stall
|
|
|
20
21
|
# Default prices precision for rounding
|
|
21
22
|
param :prices_precision, 2
|
|
22
23
|
|
|
24
|
+
# User omniauth providers
|
|
25
|
+
param :devise_for_user_config, { controllers: { omniauth_callbacks: 'stall/omniauth_callbacks' } }
|
|
26
|
+
|
|
23
27
|
# Engine's ApplicationController parent
|
|
24
28
|
param :application_controller_ancestor, '::ApplicationController'
|
|
25
29
|
|
|
26
30
|
param :mailers_parent_class, 'ActionMailer::Base'
|
|
27
31
|
|
|
28
|
-
# Default layout used for
|
|
32
|
+
# Default layout used for controllers
|
|
29
33
|
param :default_layout
|
|
30
34
|
|
|
35
|
+
# Default layout used for the checkout
|
|
36
|
+
param :checkout_layout
|
|
37
|
+
|
|
31
38
|
# Default currency for money objects
|
|
32
39
|
param :default_currency, 'EUR'
|
|
33
40
|
|
|
41
|
+
# Do not manage stocks on hand by default
|
|
42
|
+
param :manage_inventory, false
|
|
43
|
+
|
|
34
44
|
# Default app domain for building routes
|
|
35
45
|
param :default_app_domain
|
|
36
46
|
|
|
@@ -51,9 +61,6 @@ module Stall
|
|
|
51
61
|
# Duration after which an aborted cart is cleaned out by the rake task
|
|
52
62
|
param :aborted_carts_expires_after, 14.days
|
|
53
63
|
|
|
54
|
-
param :default_user_model_name, 'User'
|
|
55
|
-
param :default_user_helper_method, :current_user
|
|
56
|
-
|
|
57
64
|
# Configure the terms of service page path
|
|
58
65
|
param :terms_path, 'about:blank'
|
|
59
66
|
|
|
@@ -80,13 +87,15 @@ module Stall
|
|
|
80
87
|
end
|
|
81
88
|
|
|
82
89
|
# Fetch user config and add top-namespace lookup to avoid collision
|
|
83
|
-
# with Stall module services
|
|
90
|
+
# with Stall module services.
|
|
84
91
|
#
|
|
85
92
|
# Default allows looking up Stall namespace automatically, when no
|
|
86
93
|
# config has been given
|
|
87
94
|
def service_for(identifier)
|
|
88
95
|
class_name = if (service_name = services[identifier])
|
|
89
96
|
"::#{ services[identifier].gsub(/^::/, '') }"
|
|
97
|
+
elsif File.exists?(Rails.root.join('app', 'services', "#{ identifier }_service.rb"))
|
|
98
|
+
"::#{ identifier.to_s.camelize }Service"
|
|
90
99
|
else
|
|
91
100
|
"Stall::#{ identifier.to_s.camelize }Service"
|
|
92
101
|
end
|
|
@@ -98,15 +107,26 @@ module Stall
|
|
|
98
107
|
self.services.merge!(value)
|
|
99
108
|
end
|
|
100
109
|
|
|
101
|
-
def default_user_model
|
|
102
|
-
default_user_model_name.try(:constantize)
|
|
103
|
-
end
|
|
104
|
-
|
|
105
110
|
def default_currency_as_money
|
|
106
111
|
raw_default_currency && Money::Currency.new(raw_default_currency)
|
|
107
112
|
end
|
|
108
113
|
|
|
109
114
|
alias_method :raw_default_currency, :default_currency
|
|
110
115
|
alias_method :default_currency, :default_currency_as_money
|
|
116
|
+
|
|
117
|
+
# User omniauth providers
|
|
118
|
+
def omniauth_providers_configs
|
|
119
|
+
@omniauth_providers_configs ||= {}
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def omniauth_provider(name, config = {})
|
|
123
|
+
omniauth_providers_configs[name] = config
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def omniauth_providers
|
|
127
|
+
omniauth_providers_configs.map do |provider, config|
|
|
128
|
+
Stall::OmniauthProvider.new(provider, config.deep_dup)
|
|
129
|
+
end
|
|
130
|
+
end
|
|
111
131
|
end
|
|
112
132
|
end
|
data/lib/stall/engine.rb
CHANGED
|
@@ -24,29 +24,34 @@ module Stall
|
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
initializer 'stall.ensure_shipping_method_for_all_calculators' do
|
|
27
|
-
Stall::Shipping.calculators
|
|
28
|
-
ShippingMethod.where(identifier: name).first_or_create do |method|
|
|
29
|
-
method.name = name.to_s.humanize
|
|
30
|
-
end
|
|
31
|
-
end
|
|
27
|
+
register_class_models_for(ShippingMethod, Stall::Shipping.calculators)
|
|
32
28
|
end
|
|
33
29
|
|
|
34
|
-
initializer 'stall.
|
|
30
|
+
initializer 'stall.ensure_payment_method_for_all_gateways' do
|
|
35
31
|
require 'stall/payments/manual_payment_gateway'
|
|
36
|
-
end
|
|
37
32
|
|
|
38
|
-
|
|
39
|
-
Stall::Payments.gateways.each_key do |name|
|
|
40
|
-
PaymentMethod.where(identifier: name).first_or_create do |method|
|
|
41
|
-
method.name = name.to_s.humanize
|
|
42
|
-
end
|
|
43
|
-
end
|
|
33
|
+
register_class_models_for(PaymentMethod, Stall::Payments.gateways)
|
|
44
34
|
end
|
|
45
35
|
|
|
46
36
|
initializer 'stall.add_stall_plugin_to_para_config' do
|
|
47
37
|
Para.config.plugins += [:stall]
|
|
48
38
|
end
|
|
49
39
|
|
|
40
|
+
# For each omniauth provider in the config, declare a devise Omniauth
|
|
41
|
+
# provider
|
|
42
|
+
#
|
|
43
|
+
initializer 'stall.add_omniauth_providers_to_devise', before: 'devise.omniauth' do
|
|
44
|
+
Stall.config.omniauth_providers.each do |provider|
|
|
45
|
+
Devise.omniauth(provider.name, provider.app_id, provider.secret_key, provider.config)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Add ransack search predicates
|
|
50
|
+
#
|
|
51
|
+
initializer 'stall.add_omniauth_providers_to_devise', before: 'devise.omniauth' do
|
|
52
|
+
Stall::Ransack.configure
|
|
53
|
+
end
|
|
54
|
+
|
|
50
55
|
# Development : Configure rails generators to only generate the target
|
|
51
56
|
# files and not try to generate useless complementary files
|
|
52
57
|
#
|
|
@@ -57,5 +62,15 @@ module Stall
|
|
|
57
62
|
generators.javascripts false
|
|
58
63
|
generators.test_framework false
|
|
59
64
|
end
|
|
65
|
+
|
|
66
|
+
def register_class_models_for(model, classes)
|
|
67
|
+
return unless model.table_exists?
|
|
68
|
+
|
|
69
|
+
classes.each_key do |name|
|
|
70
|
+
model.where(identifier: name).first_or_create do |method|
|
|
71
|
+
method.name = name.to_s.humanize
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
60
75
|
end
|
|
61
76
|
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# This class is used as a config wrapper for devise's omniauth providers,
|
|
2
|
+
# allowing to easily configure new and existing providers.
|
|
3
|
+
#
|
|
4
|
+
module Stall
|
|
5
|
+
class OmniauthProvider
|
|
6
|
+
attr_reader :name, :config
|
|
7
|
+
|
|
8
|
+
def initialize(name, config = nil)
|
|
9
|
+
@name = name.to_s
|
|
10
|
+
|
|
11
|
+
config ||= {}
|
|
12
|
+
|
|
13
|
+
@icon = config.delete(:icon)
|
|
14
|
+
@display_name = config.delete(:display_name)
|
|
15
|
+
@app_id = config.delete(:app_id)
|
|
16
|
+
@secret_key = config.delete(:secret_key)
|
|
17
|
+
|
|
18
|
+
@config = config
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def icon
|
|
22
|
+
@icon ||= name
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def display_name
|
|
26
|
+
@display_name ||= name.humanize
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def app_id
|
|
30
|
+
@app_id ||= ENV["#{ constant_name }_APP_ID"]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def secret_key
|
|
34
|
+
@secret_key ||= ENV["#{ constant_name }_SECRET_KEY"]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def constant_name
|
|
38
|
+
@constant_name ||= name.to_s.upcase
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
data/lib/stall/payable.rb
CHANGED
|
@@ -17,7 +17,9 @@ module Stall
|
|
|
17
17
|
scope :aborted, ->(options = {}) {
|
|
18
18
|
joins('LEFT JOIN stall_payments ON stall_payments.cart_id = stall_product_lists.id')
|
|
19
19
|
.where(stall_payments: { paid_at: nil })
|
|
20
|
-
.older_than(
|
|
20
|
+
.older_than(
|
|
21
|
+
options.fetch(:before, Stall.config.aborted_carts_expires_after.ago)
|
|
22
|
+
)
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
delegate :paid?, to: :payment, allow_nil: true
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module Stall
|
|
2
|
+
module ProductFilters
|
|
3
|
+
class BaseFilter
|
|
4
|
+
attr_reader :products, :options
|
|
5
|
+
|
|
6
|
+
def initialize(products, options = {})
|
|
7
|
+
@products = products
|
|
8
|
+
@options = options
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def name
|
|
12
|
+
key.gsub(/_filter/, '')
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def label
|
|
16
|
+
I18n.t("stall.products.filters.#{ key }")
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Can be overriden to hide the filter depending on certain conditions,
|
|
20
|
+
# e.g. there's more than one option so the filter is useful
|
|
21
|
+
#
|
|
22
|
+
def available?
|
|
23
|
+
options[:force] || true
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def rendering_options(options = {})
|
|
27
|
+
{ partial: partial_path, locals: partial_locals }.deep_merge(options)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def partial_path
|
|
31
|
+
"stall/products/filters/#{ key }"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def partial_locals
|
|
35
|
+
{ filter: self }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def key
|
|
39
|
+
@key ||= self.class.name.demodulize.underscore
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module Stall
|
|
2
|
+
module ProductFilters
|
|
3
|
+
class Builder
|
|
4
|
+
attr_reader :products, :options
|
|
5
|
+
|
|
6
|
+
def initialize(products, options = {})
|
|
7
|
+
@products = products
|
|
8
|
+
@options = options
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def filters
|
|
12
|
+
[category_filter, manufacturer_filter, price_filter] + properties_filters
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def category_filter
|
|
16
|
+
CategoryFilter.new(products, options_for(:category)) if enabled?(:category)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def manufacturer_filter
|
|
20
|
+
ManufacturerFilter.new(products, options_for(:manufacturer)) if enabled?(:manufacturer)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def price_filter
|
|
24
|
+
PriceFilter.new(products, options_for(:price)) if enabled?(:price)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def properties_filters
|
|
28
|
+
if enabled?(:property)
|
|
29
|
+
properties.map do |property|
|
|
30
|
+
property_options = options_for(:property, property: property)
|
|
31
|
+
PropertyFilter.new(products, property_options)
|
|
32
|
+
end
|
|
33
|
+
else
|
|
34
|
+
[]
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def properties
|
|
41
|
+
Property.joins(
|
|
42
|
+
property_values: [
|
|
43
|
+
variant_property_values: [:variant]
|
|
44
|
+
]
|
|
45
|
+
)
|
|
46
|
+
.includes(:property_values)
|
|
47
|
+
.distinct
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def options_for(filter_name, overrides = {})
|
|
51
|
+
(options[filter_name] || {}).deep_dup.merge(overrides)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def enabled?(filter_name)
|
|
55
|
+
options[filter_name] != false
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module Stall
|
|
2
|
+
module ProductFilters
|
|
3
|
+
class CategoryFilter < BaseFilter
|
|
4
|
+
def available?
|
|
5
|
+
options[:force] || collection.count > 1
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def collection
|
|
9
|
+
@collection ||= ProductCategory.joins(:products)
|
|
10
|
+
.where(stall_products: { id: products.select(:id) })
|
|
11
|
+
.distinct
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def param
|
|
15
|
+
:"#{ param_with_parents }_in"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def param_with_parents
|
|
21
|
+
ProductCategory.max_depth.times.map do |index|
|
|
22
|
+
parents_string = index.times.map { 'parent' }.join('_').presence
|
|
23
|
+
['product_category', parents_string, 'id'].compact.join('_')
|
|
24
|
+
end.join('_or_')
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Stall
|
|
2
|
+
module ProductFilters
|
|
3
|
+
class ManufacturerFilter < BaseFilter
|
|
4
|
+
def available?
|
|
5
|
+
options[:force] || collection.count > 1
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def collection
|
|
9
|
+
@collection ||= Manufacturer.ordered.joins(:products)
|
|
10
|
+
.where(stall_products: { id: products.select(:id) })
|
|
11
|
+
.distinct
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def param
|
|
15
|
+
:manufacturer_id_in
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module Stall
|
|
2
|
+
module ProductFilters
|
|
3
|
+
class PriceFilter < BaseFilter
|
|
4
|
+
def available?
|
|
5
|
+
options[:force] || min != max
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def min
|
|
9
|
+
return 0 unless variants.any?
|
|
10
|
+
variants.order(price_cents: :asc).first.price.to_d.floor
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def max
|
|
14
|
+
return 0 unless variants.any?
|
|
15
|
+
variants.order(price_cents: :desc).first.price.to_d.ceil
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def param
|
|
19
|
+
:variants_price_cents_between_cents
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def ticks
|
|
23
|
+
min_tick = (min / 10.0).floor
|
|
24
|
+
max_tick = (max / 10.0).ceil
|
|
25
|
+
ticks_count = 4
|
|
26
|
+
|
|
27
|
+
(ticks_count + 1).times.map do |index|
|
|
28
|
+
((((max_tick - min_tick) / ticks_count.to_f) * index) + min_tick).to_i * 10
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def variants
|
|
35
|
+
@variants ||= Variant.where(product: products)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Stall
|
|
2
|
+
module ProductFilters
|
|
3
|
+
class PropertyFilter < BaseFilter
|
|
4
|
+
attr :property
|
|
5
|
+
|
|
6
|
+
def initialize(*)
|
|
7
|
+
super
|
|
8
|
+
@property = options[:property]
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def available?
|
|
12
|
+
@available ||= (options[:force] || collection.count > 1)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def name
|
|
16
|
+
property.name.parameterize
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def label
|
|
20
|
+
property.name
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def param
|
|
24
|
+
:variants_property_values_id_in
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def collection
|
|
28
|
+
@collection ||= property.property_values.joins(variants: :product)
|
|
29
|
+
.where(stall_products: { id: products.select(:id) })
|
|
30
|
+
.distinct
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def partial_locals
|
|
34
|
+
{ filter: self, property: property }
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|