spree_core 4.2.7 → 4.3.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/finders/concerns/spree/product_filterable.rb +9 -0
- data/app/finders/spree/cms_pages/find.rb +41 -0
- data/app/finders/spree/menus/find.rb +11 -0
- data/app/finders/spree/option_values/find_available.rb +20 -0
- data/app/finders/spree/orders/find_complete.rb +14 -2
- data/app/finders/spree/orders/find_current.rb +1 -13
- data/app/finders/spree/product_properties/find_available.rb +20 -0
- data/app/finders/spree/products/find.rb +55 -20
- data/app/finders/spree/stores/find_current.rb +24 -0
- data/app/helpers/spree/base_helper.rb +62 -2
- data/app/helpers/spree/locale_helper.rb +5 -1
- data/app/helpers/spree/products_helper.rb +7 -3
- data/app/models/concerns/spree/display_link.rb +42 -0
- data/app/models/concerns/spree/filter_param.rb +21 -0
- data/app/models/concerns/spree/memoized_data.rb +24 -0
- data/app/models/concerns/spree/multi_store_resource.rb +24 -0
- data/app/models/concerns/spree/product_scopes.rb +59 -8
- data/app/models/concerns/spree/single_store_resource.rb +9 -0
- data/app/models/concerns/spree/user_address.rb +19 -0
- data/app/models/concerns/spree/user_methods.rb +5 -4
- data/app/models/concerns/spree/user_payment_source.rb +1 -1
- data/app/models/spree/ability.rb +3 -1
- data/app/models/spree/address.rb +27 -6
- data/app/models/spree/app_configuration.rb +8 -0
- data/app/models/spree/app_dependencies.rb +18 -6
- data/app/models/spree/base.rb +18 -0
- data/app/models/spree/classification.rb +3 -0
- data/app/models/spree/cms/pages/feature_page.rb +7 -0
- data/app/models/spree/cms/pages/homepage.rb +20 -0
- data/app/models/spree/cms/pages/standard_page.rb +4 -0
- data/app/models/spree/cms/sections/featured_article.rb +29 -0
- data/app/models/spree/cms/sections/hero_image.rb +47 -0
- data/app/models/spree/cms/sections/image_gallery.rb +103 -0
- data/app/models/spree/cms/sections/product_carousel.rb +14 -0
- data/app/models/spree/cms/sections/rich_text_content.rb +13 -0
- data/app/models/spree/cms/sections/side_by_side_images.rb +74 -0
- data/app/models/spree/cms_page.rb +66 -0
- data/app/models/spree/cms_section.rb +57 -0
- data/app/models/spree/country.rb +14 -6
- data/app/models/spree/credit_card.rb +2 -8
- data/app/models/spree/customer_return.rb +8 -2
- data/app/models/spree/icon.rb +9 -0
- data/app/models/spree/image/configuration/active_storage.rb +2 -0
- data/app/models/spree/inventory_unit.rb +1 -1
- data/app/models/spree/line_item.rb +1 -1
- data/app/models/spree/menu.rb +63 -0
- data/app/models/spree/menu_item.rb +76 -0
- data/app/models/spree/option_type.rb +1 -1
- data/app/models/spree/option_value.rb +11 -0
- data/app/models/spree/option_value_variant.rb +1 -1
- data/app/models/spree/order/address_book.rb +3 -5
- data/app/models/spree/order/currency_updater.rb +1 -1
- data/app/models/spree/order/emails.rb +32 -0
- data/app/models/spree/order/payments.rb +1 -1
- data/app/models/spree/order/store_credit.rb +1 -9
- data/app/models/spree/order.rb +46 -45
- data/app/models/spree/payment.rb +7 -0
- data/app/models/spree/payment_method.rb +4 -0
- data/app/models/spree/preferences/preferable.rb +12 -0
- data/app/models/spree/preferences/preferable_class_methods.rb +10 -1
- data/app/models/spree/product.rb +27 -22
- data/app/models/spree/product_property.rb +19 -4
- data/app/models/spree/promotion/rules/country.rb +1 -1
- data/app/models/spree/promotion/rules/first_order.rb +4 -3
- data/app/models/spree/promotion/rules/taxon.rb +10 -7
- data/app/models/spree/promotion.rb +6 -15
- data/app/models/spree/promotion_handler/cart.rb +7 -2
- data/app/models/spree/promotion_handler/coupon.rb +5 -4
- data/app/models/spree/promotion_handler/free_shipping.rb +5 -6
- data/app/models/spree/promotion_handler/page.rb +3 -2
- data/app/models/spree/promotion_handler/promotion_duplicator.rb +1 -0
- data/app/models/spree/promotion_rule.rb +2 -0
- data/app/models/spree/property.rb +27 -0
- data/app/models/spree/reimbursement.rb +3 -1
- data/app/models/spree/reimbursement_type/reimbursement_helpers.rb +2 -1
- data/app/models/spree/shipment_handler.rb +4 -2
- data/app/models/spree/stock/quantifier.rb +6 -6
- data/app/models/spree/store.rb +90 -7
- data/app/models/spree/store_credit.rb +7 -3
- data/app/models/spree/store_credit_event.rb +2 -2
- data/app/models/spree/store_payment_method.rb +11 -0
- data/app/models/spree/store_product.rb +11 -0
- data/app/models/spree/store_promotion.rb +11 -0
- data/app/models/spree/taxon.rb +21 -1
- data/app/models/spree/taxon_image/configuration/active_storage.rb +2 -0
- data/app/models/spree/taxonomy.rb +3 -1
- data/app/models/spree/variant.rb +13 -4
- data/app/presenters/spree/filters/options_presenter.rb +27 -0
- data/app/presenters/spree/filters/price_presenter.rb +22 -0
- data/app/presenters/spree/filters/price_range_presenter.rb +29 -0
- data/app/presenters/spree/filters/properties_presenter.rb +23 -0
- data/app/presenters/spree/filters/property_presenter.rb +22 -0
- data/app/presenters/spree/filters/quantified_price_range_presenter.rb +44 -0
- data/app/services/spree/account/addresses/create.rb +1 -0
- data/app/services/spree/account/addresses/helper.rb +6 -0
- data/app/services/spree/account/addresses/update.rb +9 -3
- data/app/services/spree/account/create.rb +17 -0
- data/app/services/spree/account/update.rb +15 -0
- data/app/services/spree/build_localized_redirect_url.rb +1 -1
- data/app/services/spree/cart/create.rb +5 -3
- data/app/services/spree/cart/destroy.rb +40 -0
- data/app/services/spree/cart/empty.rb +36 -0
- data/app/services/spree/cart/estimate_shipping_rates.rb +3 -3
- data/app/services/spree/checkout/add_store_credit.rb +1 -1
- data/app/services/spree/classifications/reposition.rb +18 -0
- data/app/services/spree/credit_cards/destroy.rb +41 -0
- data/app/validators/db_maximum_length_validator.rb +5 -0
- data/app/validators/email_validator.rb +3 -1
- data/app/views/spree/shared/_purchased_items_table.text.erb +25 -0
- data/config/initializers/active_storage.rb +2 -0
- data/config/locales/en.yml +166 -2
- data/config/routes.rb +0 -5
- data/db/migrate/20201023152810_add_filterable_to_spree_properties.rb +8 -0
- data/db/migrate/20210407200948_create_spree_menus.rb +16 -0
- data/db/migrate/20210408092939_create_spree_menu_items.rb +31 -0
- data/db/migrate/20210504163720_add_filter_param_to_spree_product_properties.rb +8 -0
- data/db/migrate/20210505114659_add_filter_param_to_spree_properties.rb +8 -0
- data/db/migrate/20210512191732_create_spree_cms_pages.rb +24 -0
- data/db/migrate/20210514204251_create_spree_cms_sections.rb +22 -0
- data/db/migrate/20210527094055_create_spree_products_stores.rb +29 -0
- data/db/migrate/20210608045519_ensure_store_default_country_is_set.rb +5 -0
- data/db/migrate/20210702112334_add_missing_timestamp_columns.rb +46 -0
- data/db/migrate/20210713131614_add_unique_index_on_property_id_and_product_id_to_product_properties.rb +29 -0
- data/db/migrate/20210715091956_add_store_id_to_spree_store_credits.rb +10 -0
- data/db/migrate/20210716093151_add_store_id_to_spree_taxonomies.rb +11 -0
- data/db/migrate/20210716104141_add_index_on_name_parent_id_and_taxonomy_id_on_spree_taxons.rb +31 -0
- data/db/migrate/20210721120857_add_index_on_permalink_parent_id_and_taxonomy_id_on_spree_taxons.rb +31 -0
- data/db/migrate/20210721125657_create_spree_promotions_stores.rb +29 -0
- data/db/migrate/20210722090705_add_store_id_to_spree_customer_returns.rb +11 -0
- data/db/migrate/20210726065456_change_integer_id_columns_into_bigint.rb +305 -0
- data/db/migrate/20210730154425_fix_promotion_code_and_path_unique_indexes.rb +9 -0
- data/lib/generators/spree/dummy/dummy_generator.rb +11 -6
- data/lib/generators/spree/dummy_model/templates/model.rb.tt +1 -1
- data/lib/generators/spree/install/install_generator.rb +12 -24
- data/lib/spree/core/components.rb +8 -0
- data/lib/spree/core/controller_helpers/auth.rb +7 -1
- data/lib/spree/core/controller_helpers/common.rb +1 -1
- data/lib/spree/core/controller_helpers/order.rb +4 -4
- data/lib/spree/core/controller_helpers/search.rb +1 -0
- data/lib/spree/core/controller_helpers/store.rb +10 -1
- data/lib/spree/core/engine.rb +6 -0
- data/lib/spree/core/importer/product.rb +3 -1
- data/lib/spree/core/product_duplicator.rb +1 -0
- data/lib/spree/core/search/base.rb +17 -22
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/core.rb +8 -4
- data/lib/spree/i18n.rb +1 -1
- data/lib/spree/money.rb +2 -1
- data/lib/spree/permitted_attributes.rb +14 -3
- data/lib/spree/testing_support/authorization_helpers.rb +6 -3
- data/lib/spree/testing_support/capybara_config.rb +3 -1
- data/lib/spree/testing_support/common_rake.rb +17 -4
- data/lib/spree/testing_support/extension_rake.rb +2 -2
- data/lib/spree/testing_support/factories/address_factory.rb +1 -1
- data/lib/spree/testing_support/factories/classification_factory.rb +8 -0
- data/lib/spree/testing_support/factories/cms_page_factory.rb +20 -0
- data/lib/spree/testing_support/factories/cms_section_factory.rb +31 -0
- data/lib/spree/testing_support/factories/customer_return_factory.rb +24 -17
- data/lib/spree/testing_support/factories/icon_factory.rb +7 -0
- data/lib/spree/testing_support/factories/line_item_factory.rb +6 -2
- data/lib/spree/testing_support/factories/menu_factory.rb +16 -0
- data/lib/spree/testing_support/factories/menu_item_factory.rb +10 -0
- data/lib/spree/testing_support/factories/options_factory.rb +5 -0
- data/lib/spree/testing_support/factories/order_factory.rb +11 -2
- data/lib/spree/testing_support/factories/payment_method_factory.rb +6 -2
- data/lib/spree/testing_support/factories/product_factory.rb +11 -1
- data/lib/spree/testing_support/factories/product_property_factory.rb +1 -1
- data/lib/spree/testing_support/factories/promotion_factory.rb +18 -9
- data/lib/spree/testing_support/factories/property_factory.rb +22 -0
- data/lib/spree/testing_support/factories/stock_location_factory.rb +5 -4
- data/lib/spree/testing_support/factories/store_credit_factory.rb +1 -0
- data/lib/spree/testing_support/factories/store_factory.rb +11 -0
- data/lib/spree/testing_support/factories/taxon_factory.rb +3 -1
- data/lib/spree/testing_support/factories/taxon_image_factory.rb +7 -0
- data/lib/spree/testing_support/factories/taxonomy_factory.rb +1 -0
- data/lib/spree/testing_support/factories/user_factory.rb +7 -2
- data/lib/spree/testing_support/factories/variant_factory.rb +2 -2
- data/lib/spree/testing_support/flatpickr_capybara.rb +58 -35
- data/lib/spree/testing_support/order_walkthrough.rb +9 -9
- data/lib/tasks/core.rake +1 -1
- data/spec/fixtures/favicon.ico +0 -0
- data/spec/fixtures/files/icon_256x256.gif +0 -0
- data/spec/fixtures/files/icon_256x256.png +0 -0
- data/spec/fixtures/files/icon_512x512.png +0 -0
- data/spec/fixtures/files/img_256x128.png +0 -0
- data/spree_core.gemspec +11 -10
- metadata +207 -159
- data/app/assets/images/logo/spree_50.png +0 -0
- data/app/assets/images/noimage/large.png +0 -0
- data/app/assets/images/noimage/mini.png +0 -0
- data/app/assets/images/noimage/product.png +0 -0
- data/app/assets/images/noimage/small.png +0 -0
- data/app/assets/javascripts/spree.js +0 -78
- data/app/controllers/spree/errors_controller.rb +0 -11
- data/app/helpers/spree/mail_helper.rb +0 -29
- data/app/mailers/spree/base_mailer.rb +0 -46
- data/app/mailers/spree/order_mailer.rb +0 -26
- data/app/mailers/spree/reimbursement_mailer.rb +0 -12
- data/app/mailers/spree/shipment_mailer.rb +0 -12
- data/app/mailers/spree/test_mailer.rb +0 -8
- data/app/models/spree/order_contents.rb +0 -31
- data/app/models/spree/validations/db_maximum_length_validator.rb +0 -22
- data/app/views/layouts/spree/base_mailer.html.erb +0 -46
- data/app/views/spree/errors/forbidden.html.erb +0 -0
- data/app/views/spree/errors/unauthorized.html.erb +0 -0
- data/app/views/spree/order_mailer/cancel_email.html.erb +0 -24
- data/app/views/spree/order_mailer/cancel_email.text.erb +0 -38
- data/app/views/spree/order_mailer/confirm_email.html.erb +0 -23
- data/app/views/spree/order_mailer/confirm_email.text.erb +0 -39
- data/app/views/spree/order_mailer/store_owner_notification_email.html.erb +0 -23
- data/app/views/spree/order_mailer/store_owner_notification_email.text.erb +0 -38
- data/app/views/spree/reimbursement_mailer/reimbursement_email.html.erb +0 -56
- data/app/views/spree/reimbursement_mailer/reimbursement_email.text.erb +0 -24
- data/app/views/spree/shared/_base_mailer_footer.html.erb +0 -12
- data/app/views/spree/shared/_base_mailer_header.html.erb +0 -13
- data/app/views/spree/shared/_base_mailer_stylesheets.html.erb +0 -456
- data/app/views/spree/shared/_error_messages.html.erb +0 -11
- data/app/views/spree/shared/_mailer_line_item.html.erb +0 -16
- data/app/views/spree/shared/_paths.html.erb +0 -8
- data/app/views/spree/shared/_purchased_items_table.html.erb +0 -69
- data/app/views/spree/shared/purchased_items_table/_adjustment.html.erb +0 -13
- data/app/views/spree/shared/purchased_items_table/_line_item.html.erb +0 -27
- data/app/views/spree/shared/purchased_items_table/_subtotal.html.erb +0 -13
- data/app/views/spree/shared/purchased_items_table/_total.html.erb +0 -13
- data/app/views/spree/shipment_mailer/shipped_email.html.erb +0 -36
- data/app/views/spree/shipment_mailer/shipped_email.text.erb +0 -17
- data/app/views/spree/test_mailer/test_email.html.erb +0 -40
- data/app/views/spree/test_mailer/test_email.text.erb +0 -4
- data/config/initializers/assets.rb +0 -2
- data/config/initializers/premailer_assets.rb +0 -1
- data/config/initializers/premailer_rails.rb +0 -3
- data/db/migrate/20140805171219_make_existing_credit_cards_default.rb +0 -10
- data/lib/generators/spree/dummy/templates/initializers/bullet.rb +0 -5
- data/lib/generators/spree/install/templates/vendor/assets/javascripts/spree/backend/all.js +0 -15
- data/lib/generators/spree/install/templates/vendor/assets/javascripts/spree/frontend/all.js +0 -16
- data/lib/generators/spree/install/templates/vendor/assets/stylesheets/spree/backend/all.css +0 -16
- data/lib/generators/spree/install/templates/vendor/assets/stylesheets/spree/frontend/all.css +0 -16
- data/lib/generators/spree/mailers_preview/mailers_preview_generator.rb +0 -23
- data/lib/generators/spree/mailers_preview/templates/mailers/previews/order_preview.rb +0 -13
- data/lib/generators/spree/mailers_preview/templates/mailers/previews/reimbursement_preview.rb +0 -5
- data/lib/generators/spree/mailers_preview/templates/mailers/previews/shipment_preview.rb +0 -5
- data/lib/generators/spree/mailers_preview/templates/mailers/previews/user_preview.rb +0 -11
- data/lib/tasks/email.rake +0 -10
- data/vendor/assets/javascripts/cleave.js +0 -1669
- data/vendor/assets/javascripts/fetch.umd.js +0 -531
- data/vendor/assets/javascripts/jquery.payment.js +0 -652
- data/vendor/assets/javascripts/jsuri.js +0 -458
- data/vendor/assets/javascripts/polyfill.min.js +0 -1
@@ -43,23 +43,23 @@ module Spree
|
|
43
43
|
add_simple_scopes simple_scopes
|
44
44
|
|
45
45
|
add_search_scope :ascend_by_master_price do
|
46
|
-
|
46
|
+
order("#{price_table_name}.amount ASC")
|
47
47
|
end
|
48
48
|
|
49
49
|
add_search_scope :descend_by_master_price do
|
50
|
-
|
50
|
+
order("#{price_table_name}.amount DESC")
|
51
51
|
end
|
52
52
|
|
53
53
|
add_search_scope :price_between do |low, high|
|
54
|
-
|
54
|
+
where(Price.table_name => { amount: low..high })
|
55
55
|
end
|
56
56
|
|
57
57
|
add_search_scope :master_price_lte do |price|
|
58
|
-
|
58
|
+
where("#{price_table_name}.amount <= ?", price)
|
59
59
|
end
|
60
60
|
|
61
61
|
add_search_scope :master_price_gte do |price|
|
62
|
-
|
62
|
+
where("#{price_table_name}.amount >= ?", price)
|
63
63
|
end
|
64
64
|
|
65
65
|
# This scope selects products in taxon AND all its descendants
|
@@ -94,6 +94,19 @@ module Spree
|
|
94
94
|
taxons.first ? prepare_taxon_conditions(taxons) : where(nil)
|
95
95
|
end
|
96
96
|
|
97
|
+
add_search_scope :ascend_by_taxons_min_position do |taxon_ids|
|
98
|
+
joins(:classifications).
|
99
|
+
where(Classification.table_name => { taxon_id: taxon_ids }).
|
100
|
+
select(
|
101
|
+
[
|
102
|
+
"#{Product.table_name}.*",
|
103
|
+
"MIN(#{Classification.table_name}.position) AS min_position"
|
104
|
+
].join(', ')
|
105
|
+
).
|
106
|
+
group(:id).
|
107
|
+
order(min_position: :asc)
|
108
|
+
end
|
109
|
+
|
97
110
|
# a scope that finds all products having property specified by name, object or id
|
98
111
|
add_search_scope :with_property do |property|
|
99
112
|
joins(:properties).where(property_conditions(property))
|
@@ -107,6 +120,12 @@ module Spree
|
|
107
120
|
where(property_conditions(property))
|
108
121
|
end
|
109
122
|
|
123
|
+
add_search_scope :with_property_values do |property_filter_param, property_values|
|
124
|
+
joins(product_properties: :property).
|
125
|
+
where(Property.table_name => { filter_param: property_filter_param }).
|
126
|
+
where(ProductProperty.table_name => { filter_param: property_values.map(&:parameterize) })
|
127
|
+
end
|
128
|
+
|
110
129
|
add_search_scope :with_option do |option|
|
111
130
|
option_types = OptionType.table_name
|
112
131
|
conditions = case option
|
@@ -198,18 +217,50 @@ module Spree
|
|
198
217
|
end
|
199
218
|
end
|
200
219
|
search_scopes << :not_discontinued
|
220
|
+
|
221
|
+
def self.with_currency(currency)
|
222
|
+
joins(variants_including_master: :prices).
|
223
|
+
where(Price.table_name => { currency: currency.upcase }).
|
224
|
+
where.not(Price.table_name => { amount: nil }).
|
225
|
+
distinct
|
226
|
+
end
|
227
|
+
search_scopes << :with_currency
|
228
|
+
|
201
229
|
# Can't use add_search_scope for this as it needs a default argument
|
202
|
-
def self.available(available_on = nil,
|
230
|
+
def self.available(available_on = nil, currency = nil)
|
203
231
|
available_on ||= Time.current
|
204
|
-
|
232
|
+
|
233
|
+
scope = not_discontinued.where("#{Product.quoted_table_name}.available_on <= ?", available_on)
|
234
|
+
|
235
|
+
unless Spree::Config.show_products_without_price
|
236
|
+
currency ||= Spree::Config[:currency]
|
237
|
+
scope = scope.with_currency(currency)
|
238
|
+
end
|
239
|
+
|
240
|
+
scope
|
205
241
|
end
|
206
242
|
search_scopes << :available
|
207
243
|
|
208
244
|
def self.active(currency = nil)
|
209
|
-
available(nil, currency
|
245
|
+
available(nil, currency)
|
210
246
|
end
|
211
247
|
search_scopes << :active
|
212
248
|
|
249
|
+
def self.for_filters(currency, taxon: nil)
|
250
|
+
scope = active(currency)
|
251
|
+
scope = scope.in_taxon(taxon) if taxon.present?
|
252
|
+
scope
|
253
|
+
end
|
254
|
+
search_scopes << :for_filters
|
255
|
+
|
256
|
+
def self.for_user(user = nil)
|
257
|
+
if user.try(:has_spree_role?, 'admin')
|
258
|
+
with_deleted
|
259
|
+
else
|
260
|
+
not_deleted.not_discontinued.where("#{Product.quoted_table_name}.available_on <= ?", Time.current)
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
213
264
|
add_search_scope :taxons_name_eq do |name|
|
214
265
|
group('spree_products.id').joins(:taxons).where(Taxon.arel_table[:name].eq(name))
|
215
266
|
end
|
@@ -16,7 +16,12 @@ module Spree
|
|
16
16
|
has_many :addresses, -> { where(deleted_at: nil).order('updated_at DESC') },
|
17
17
|
class_name: 'Spree::Address', foreign_key: :user_id
|
18
18
|
|
19
|
+
validate :address_not_associated_with_other_user, :address_not_deprecated_in_completed_order
|
20
|
+
|
19
21
|
def persist_order_address(order)
|
22
|
+
# FIXME: we should check if the User's address is associated with country accepted by Store
|
23
|
+
# if not we should try to find an address with valid country in User's address book
|
24
|
+
# or we should call `build_bill_address`
|
20
25
|
b_address = bill_address || build_bill_address
|
21
26
|
b_address.attributes = order.bill_address.value_attributes
|
22
27
|
b_address.save
|
@@ -30,6 +35,20 @@ module Spree
|
|
30
35
|
update(ship_address_id: s_address.id)
|
31
36
|
end
|
32
37
|
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def address_not_associated_with_other_user
|
42
|
+
errors.add(:bill_address_id, :belongs_to_other_user) if bill_address&.user_id && self != bill_address&.user
|
43
|
+
errors.add(:ship_address_id, :belongs_to_other_user) if ship_address&.user_id && self != ship_address&.user
|
44
|
+
end
|
45
|
+
|
46
|
+
def address_not_deprecated_in_completed_order
|
47
|
+
errors.add(:bill_address_id, :deprecated_in_completed_order) if
|
48
|
+
orders.complete.with_deleted_bill_address.where(bill_address: bill_address_id).any?
|
49
|
+
errors.add(:ship_address_id, :deprecated_in_completed_order) if
|
50
|
+
orders.complete.with_deleted_ship_address.where(ship_address: ship_address_id).any?
|
51
|
+
end
|
33
52
|
end
|
34
53
|
end
|
35
54
|
end
|
@@ -27,7 +27,7 @@ module Spree
|
|
27
27
|
belongs_to :ship_address, class_name: 'Spree::Address', optional: true
|
28
28
|
belongs_to :bill_address, class_name: 'Spree::Address', optional: true
|
29
29
|
|
30
|
-
self.whitelisted_ransackable_associations = %w[bill_address ship_address]
|
30
|
+
self.whitelisted_ransackable_associations = %w[bill_address ship_address addresses]
|
31
31
|
self.whitelisted_ransackable_attributes = %w[id email]
|
32
32
|
|
33
33
|
def self.with_email(query)
|
@@ -59,9 +59,10 @@ module Spree
|
|
59
59
|
first
|
60
60
|
end
|
61
61
|
|
62
|
-
def total_available_store_credit(currency = nil)
|
63
|
-
|
64
|
-
|
62
|
+
def total_available_store_credit(currency = nil, store = nil)
|
63
|
+
store ||= Store.default
|
64
|
+
currency ||= store.default_currency
|
65
|
+
store_credits.for_store(store).where(currency: currency).reload.to_a.sum(&:amount_remaining)
|
65
66
|
end
|
66
67
|
|
67
68
|
private
|
@@ -9,7 +9,7 @@ module Spree
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def payment_sources
|
12
|
-
credit_cards.with_payment_profile.not_expired.where(payment_method: Spree::PaymentMethod.active)
|
12
|
+
credit_cards.with_payment_profile.not_expired.where(payment_method: Spree::PaymentMethod.active).not_removed
|
13
13
|
end
|
14
14
|
|
15
15
|
def drop_payment_source(source)
|
data/app/models/spree/ability.rb
CHANGED
@@ -61,6 +61,8 @@ module Spree
|
|
61
61
|
|
62
62
|
def apply_user_permissions(user)
|
63
63
|
can :read, ::Spree::Country
|
64
|
+
can :read, ::Spree::Menu
|
65
|
+
can :read, ::Spree::CmsPage
|
64
66
|
can :read, ::Spree::OptionType
|
65
67
|
can :read, ::Spree::OptionValue
|
66
68
|
can :create, ::Spree::Order
|
@@ -71,7 +73,7 @@ module Spree
|
|
71
73
|
!order.completed? && (order.user == user || order.token && token == order.token)
|
72
74
|
end
|
73
75
|
can :manage, ::Spree::Address, user_id: user.id
|
74
|
-
can :read, ::Spree::CreditCard, user_id: user.id
|
76
|
+
can [:read, :destroy], ::Spree::CreditCard, user_id: user.id
|
75
77
|
can :read, ::Spree::Product
|
76
78
|
can :read, ::Spree::ProductProperty
|
77
79
|
can :read, ::Spree::Property
|
data/app/models/spree/address.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Spree
|
2
2
|
class Address < Spree::Base
|
3
|
-
require '
|
3
|
+
require 'validates_zipcode'
|
4
4
|
|
5
5
|
if Rails::VERSION::STRING >= '6.1'
|
6
6
|
serialize :preferences, Hash, default: {}
|
@@ -55,13 +55,21 @@ module Spree
|
|
55
55
|
alias_attribute :first_name, :firstname
|
56
56
|
alias_attribute :last_name, :lastname
|
57
57
|
|
58
|
-
self.whitelisted_ransackable_attributes =
|
58
|
+
self.whitelisted_ransackable_attributes = ADDRESS_FIELDS
|
59
|
+
self.whitelisted_ransackable_associations = %w[country state user]
|
59
60
|
|
60
61
|
def self.build_default
|
62
|
+
ActiveSupport::Deprecation.warn(<<-DEPRECATION, caller)
|
63
|
+
`Address#build_default` is deprecated and will be removed in Spree 5.0.
|
64
|
+
Please use standard rails `Address.new(country: current_store.default_country)`
|
65
|
+
DEPRECATION
|
61
66
|
new(country: Spree::Country.default)
|
62
67
|
end
|
63
68
|
|
64
69
|
def self.default(user = nil, kind = 'bill')
|
70
|
+
ActiveSupport::Deprecation.warn(<<-DEPRECATION, caller)
|
71
|
+
`Address#default` is deprecated and will be removed in Spree 5.0.
|
72
|
+
DEPRECATION
|
65
73
|
if user && user_address = user.public_send(:"#{kind}_address")
|
66
74
|
user_address.clone
|
67
75
|
else
|
@@ -157,6 +165,7 @@ module Spree
|
|
157
165
|
super
|
158
166
|
else
|
159
167
|
update_column :deleted_at, Time.current
|
168
|
+
assign_new_default_address_to_user
|
160
169
|
end
|
161
170
|
end
|
162
171
|
|
@@ -214,11 +223,23 @@ module Spree
|
|
214
223
|
end
|
215
224
|
|
216
225
|
def postal_code_validate
|
217
|
-
return if country.blank? ||
|
218
|
-
return unless
|
226
|
+
return if country.blank? || country_iso.blank? || !require_zipcode? || zipcode.blank?
|
227
|
+
return unless ::ValidatesZipcode::CldrRegexpCollection::ZIPCODES_REGEX.keys.include?(country_iso.upcase.to_sym)
|
219
228
|
|
220
|
-
|
221
|
-
|
229
|
+
formatted_zip = ::ValidatesZipcode::Formatter.new(
|
230
|
+
zipcode: zipcode.to_s.strip,
|
231
|
+
country_alpha2: country_iso.upcase
|
232
|
+
).format
|
233
|
+
|
234
|
+
errors.add(:zipcode, :invalid) unless ::ValidatesZipcode.valid?(formatted_zip, country_iso.upcase)
|
235
|
+
end
|
236
|
+
|
237
|
+
def assign_new_default_address_to_user
|
238
|
+
return unless user
|
239
|
+
|
240
|
+
user.bill_address = user.addresses.last if user.bill_address == self
|
241
|
+
user.ship_address = user.addresses.last if user.ship_address == self
|
242
|
+
user.save!
|
222
243
|
end
|
223
244
|
end
|
224
245
|
end
|
@@ -45,6 +45,7 @@ module Spree
|
|
45
45
|
preference :currency, :string, default: 'USD'
|
46
46
|
preference :default_country_id, :integer
|
47
47
|
preference :disable_sku_validation, :boolean, default: false # when turned off disables the built-in SKU uniqueness validation
|
48
|
+
preference :disable_store_presence_validation, :boolean, default: false # when turned off disables Store presence validation for Products and Payment Methods
|
48
49
|
preference :expedited_exchanges, :boolean, default: false # NOTE this requires payment profiles to be supported on your gateway of choice as well as a delayed job handler to be configured with activejob. kicks off an exchange shipment upon return authorization save. charge customer if they do not return items within timely manner.
|
49
50
|
preference :expedited_exchanges_days_window, :integer, default: 14 # the amount of days the customer has to return their item after the expedited exchange is shipped in order to avoid being charged
|
50
51
|
preference :layout, :string, default: 'spree/layouts/spree_application'
|
@@ -52,6 +53,7 @@ module Spree
|
|
52
53
|
preference :mailer_logo, :string, default: 'logo/spree_50.png'
|
53
54
|
preference :max_level_in_taxons_menu, :integer, default: 1 # maximum nesting level in taxons menu
|
54
55
|
preference :products_per_page, :integer, default: 12
|
56
|
+
preference :product_wysiwyg_editor_enabled, :boolean, default: true
|
55
57
|
preference :require_master_price, :boolean, default: true
|
56
58
|
preference :restock_inventory, :boolean, default: true # Determines if a return item is restocked automatically once it has been received
|
57
59
|
preference :return_eligibility_number_of_days, :integer, default: 365
|
@@ -62,6 +64,7 @@ module Spree
|
|
62
64
|
preference :show_products_without_price, :boolean, default: false
|
63
65
|
preference :show_raw_product_description, :boolean, default: false
|
64
66
|
preference :tax_using_ship_address, :boolean, default: true
|
67
|
+
preference :taxon_wysiwyg_editor_enabled, :boolean, default: true
|
65
68
|
preference :track_inventory_levels, :boolean, default: true # Determines whether to track on_hand values for variants / products.
|
66
69
|
|
67
70
|
# Store credits configurations
|
@@ -76,6 +79,11 @@ module Spree
|
|
76
79
|
@searcher_class ||= Spree::Core::Search::Base
|
77
80
|
end
|
78
81
|
|
82
|
+
# Sets the path used for products, taxons and pages.
|
83
|
+
preference :storefront_products_path, :string, default: 'products'
|
84
|
+
preference :storefront_taxons_path, :string, default: 't'
|
85
|
+
preference :storefront_pages_path, :string, default: 'pages'
|
86
|
+
|
79
87
|
attr_writer :searcher_class
|
80
88
|
end
|
81
89
|
end
|
@@ -6,14 +6,14 @@ module Spree
|
|
6
6
|
:ability_class,
|
7
7
|
:cart_create_service, :cart_add_item_service, :cart_remove_item_service,
|
8
8
|
:cart_remove_line_item_service, :cart_set_item_quantity_service, :cart_recalculate_service,
|
9
|
-
:cart_update_service, :checkout_next_service, :checkout_advance_service, :checkout_update_service,
|
10
|
-
:checkout_complete_service, :checkout_add_store_credit_service,
|
11
|
-
:
|
12
|
-
:coupon_handler, :country_finder, :current_order_finder, :credit_card_finder,
|
9
|
+
:cms_page_finder, :cart_update_service, :checkout_next_service, :checkout_advance_service, :checkout_update_service,
|
10
|
+
:checkout_complete_service, :checkout_add_store_credit_service, :checkout_remove_store_credit_service, :checkout_get_shipping_rates_service,
|
11
|
+
:coupon_handler, :menu_finder, :country_finder, :current_order_finder, :credit_card_finder,
|
13
12
|
:completed_order_finder, :order_sorter, :cart_compare_line_items_service, :collection_paginator, :products_sorter,
|
14
13
|
:products_finder, :taxon_finder, :line_item_by_variant_finder, :cart_estimate_shipping_rates_service,
|
15
|
-
:account_create_address_service, :account_update_address_service, :
|
16
|
-
:collection_sorter, :error_handler
|
14
|
+
:account_create_address_service, :account_update_address_service, :account_create_service, :account_update_service,
|
15
|
+
:address_finder, :collection_sorter, :error_handler, :current_store_finder, :cart_empty_service, :cart_destroy_service,
|
16
|
+
:classification_reposition_service, :credit_cards_destroy_service
|
17
17
|
].freeze
|
18
18
|
|
19
19
|
attr_accessor *INJECTION_POINTS
|
@@ -41,6 +41,8 @@ module Spree
|
|
41
41
|
@cart_remove_line_item_service = 'Spree::Cart::RemoveLineItem'
|
42
42
|
@cart_set_item_quantity_service = 'Spree::Cart::SetQuantity'
|
43
43
|
@cart_estimate_shipping_rates_service = 'Spree::Cart::EstimateShippingRates'
|
44
|
+
@cart_empty_service = 'Spree::Cart::Empty'
|
45
|
+
@cart_destroy_service = 'Spree::Cart::Destroy'
|
44
46
|
|
45
47
|
# checkout
|
46
48
|
@checkout_next_service = 'Spree::Checkout::Next'
|
@@ -64,16 +66,26 @@ module Spree
|
|
64
66
|
@coupon_handler = 'Spree::PromotionHandler::Coupon'
|
65
67
|
|
66
68
|
# account
|
69
|
+
@account_create_service = 'Spree::Account::Create'
|
70
|
+
@account_update_service = 'Spree::Account::Update'
|
67
71
|
@account_create_address_service = 'Spree::Account::Addresses::Create'
|
68
72
|
@account_update_address_service = 'Spree::Account::Addresses::Update'
|
69
73
|
|
74
|
+
# credit cards
|
75
|
+
@credit_cards_destroy_service = 'Spree::CreditCards::Destroy'
|
76
|
+
|
77
|
+
@classification_reposition_service = 'Spree::Classifications::Reposition'
|
78
|
+
|
70
79
|
@error_handler = 'Spree::ErrorReporter'
|
71
80
|
end
|
72
81
|
|
73
82
|
def set_default_finders
|
74
83
|
@address_finder = 'Spree::Addresses::Find'
|
75
84
|
@country_finder = 'Spree::Countries::Find'
|
85
|
+
@cms_page_finder = 'Spree::CmsPages::Find'
|
86
|
+
@menu_finder = 'Spree::Menus::Find'
|
76
87
|
@current_order_finder = 'Spree::Orders::FindCurrent'
|
88
|
+
@current_store_finder = 'Spree::Stores::FindCurrent'
|
77
89
|
@completed_order_finder = 'Spree::Orders::FindComplete'
|
78
90
|
@credit_card_finder = 'Spree::CreditCards::Find'
|
79
91
|
@products_finder = 'Spree::Products::Find'
|
data/app/models/spree/base.rb
CHANGED
@@ -22,6 +22,16 @@ class Spree::Base < ApplicationRecord
|
|
22
22
|
false
|
23
23
|
end
|
24
24
|
|
25
|
+
def self.for_store(store)
|
26
|
+
plural_model_name = model_name.plural.gsub(/spree_/, '').to_sym
|
27
|
+
|
28
|
+
if store.respond_to?(plural_model_name)
|
29
|
+
store.send(plural_model_name)
|
30
|
+
else
|
31
|
+
self
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
25
35
|
def self.spree_base_scopes
|
26
36
|
where(nil)
|
27
37
|
end
|
@@ -30,4 +40,12 @@ class Spree::Base < ApplicationRecord
|
|
30
40
|
def self.has_many_inversing
|
31
41
|
false
|
32
42
|
end
|
43
|
+
|
44
|
+
def self.json_api_columns
|
45
|
+
column_names.reject { |c| c.match(/_id$|id|preferences|(.*)password|(.*)token|(.*)api_key/) }
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.json_api_type
|
49
|
+
to_s.demodulize.underscore
|
50
|
+
end
|
33
51
|
end
|
@@ -9,7 +9,10 @@ module Spree
|
|
9
9
|
end
|
10
10
|
|
11
11
|
validates :taxon, :product, presence: true
|
12
|
+
validates :position, numericality: { only_integer: true, allow_blank: true, allow_nil: true }
|
12
13
|
# For #3494
|
13
14
|
validates :taxon_id, uniqueness: { scope: :product_id, message: :already_linked, allow_blank: true }
|
15
|
+
|
16
|
+
self.whitelisted_ransackable_attributes = ['taxon_id', 'product_id']
|
14
17
|
end
|
15
18
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Spree::Cms::Pages
|
2
|
+
class Homepage < Spree::CmsPage
|
3
|
+
before_create :empty_slug
|
4
|
+
after_save :empty_slug
|
5
|
+
|
6
|
+
def sections?
|
7
|
+
true
|
8
|
+
end
|
9
|
+
|
10
|
+
def seo_meta_description
|
11
|
+
meta_description if meta_description.present?
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def empty_slug
|
17
|
+
self.slug = nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Spree::Cms::Sections
|
2
|
+
class FeaturedArticle < Spree::CmsSection
|
3
|
+
before_save :reset_link_attributes
|
4
|
+
after_initialize :default_values
|
5
|
+
|
6
|
+
store :content, accessors: [:title, :subtitle, :button_text, :rte_content], coder: JSON
|
7
|
+
store :settings, accessors: [:gutters], coder: JSON
|
8
|
+
|
9
|
+
LINKED_RESOURCE_TYPE = ['Spree::Taxon', 'Spree::Product', 'Spree::CmsPage']
|
10
|
+
|
11
|
+
def gutters?
|
12
|
+
gutters == 'Gutters'
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def reset_link_attributes
|
18
|
+
if linked_resource_type_changed?
|
19
|
+
self.linked_resource_id = nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def default_values
|
24
|
+
self.gutters ||= 'No Gutters'
|
25
|
+
self.fit ||= 'Screen'
|
26
|
+
self.linked_resource_type ||= 'Spree::Taxon'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Spree::Cms::Sections
|
2
|
+
class HeroImage < Spree::CmsSection
|
3
|
+
before_save :reset_link_attributes
|
4
|
+
after_initialize :default_values
|
5
|
+
|
6
|
+
store :content, accessors: [:title, :button_text], coder: JSON
|
7
|
+
store :settings, accessors: [:gutters], coder: JSON
|
8
|
+
|
9
|
+
LINKED_RESOURCE_TYPE = ['Spree::Taxon', 'Spree::Product', 'Spree::CmsPage']
|
10
|
+
|
11
|
+
def gutters?
|
12
|
+
gutters == 'Gutters'
|
13
|
+
end
|
14
|
+
|
15
|
+
def img_one_sm(dimensions = '600x250>')
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
def img_one_md(dimensions = '1200x500>')
|
20
|
+
super
|
21
|
+
end
|
22
|
+
|
23
|
+
def img_one_lg(dimensions = '2400x1000>')
|
24
|
+
super
|
25
|
+
end
|
26
|
+
|
27
|
+
def img_one_xl(dimensions = '4800x2000>')
|
28
|
+
super
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def reset_link_attributes
|
34
|
+
if linked_resource_type_changed?
|
35
|
+
return if linked_resource_id_was.nil?
|
36
|
+
|
37
|
+
self.linked_resource_id = nil
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def default_values
|
42
|
+
self.gutters ||= 'No Gutters'
|
43
|
+
self.fit ||= 'Screen'
|
44
|
+
self.linked_resource_type ||= 'Spree::Taxon'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
module Spree::Cms::Sections
|
2
|
+
class ImageGallery < Spree::CmsSection
|
3
|
+
after_initialize :default_values
|
4
|
+
before_save :reset_link_attributes
|
5
|
+
|
6
|
+
LINKED_RESOURCE_TYPE = if Rails::VERSION::STRING < '6.0'
|
7
|
+
['Spree::Taxon'].freeze
|
8
|
+
else
|
9
|
+
['Spree::Taxon', 'Spree::Product'].freeze
|
10
|
+
end
|
11
|
+
|
12
|
+
LAYOUT_OPTIONS = ['Default', 'Reversed'].freeze
|
13
|
+
LABEL_OPTIONS = ['Show', 'Hide'].freeze
|
14
|
+
|
15
|
+
store :content, accessors: [:link_type_one, :link_one, :title_one,
|
16
|
+
:link_type_two, :link_two, :title_two,
|
17
|
+
:link_type_three, :link_three, :title_three], coder: JSON
|
18
|
+
|
19
|
+
store :settings, accessors: [:layout_style, :display_labels], coder: JSON
|
20
|
+
|
21
|
+
#
|
22
|
+
# img_one sizing
|
23
|
+
def img_one_md(dimensions = '270x195>')
|
24
|
+
super
|
25
|
+
end
|
26
|
+
|
27
|
+
def img_one_lg(dimensions = '540x390>')
|
28
|
+
super
|
29
|
+
end
|
30
|
+
|
31
|
+
def img_one_xl(dimensions = '1080x780>')
|
32
|
+
super
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
# img_two sizing
|
37
|
+
def img_two_md(dimensions = '270x400>')
|
38
|
+
super
|
39
|
+
end
|
40
|
+
|
41
|
+
def img_two_lg(dimensions = '540x800>')
|
42
|
+
super
|
43
|
+
end
|
44
|
+
|
45
|
+
def img_two_xl(dimensions = '1080x1600>')
|
46
|
+
super
|
47
|
+
end
|
48
|
+
|
49
|
+
#
|
50
|
+
# img_three sizing
|
51
|
+
def img_three_md(dimensions = '270x195>')
|
52
|
+
super
|
53
|
+
end
|
54
|
+
|
55
|
+
def img_three_lg(dimensions = '540x390>')
|
56
|
+
super
|
57
|
+
end
|
58
|
+
|
59
|
+
def img_three_xl(dimensions = '1080x780>')
|
60
|
+
super
|
61
|
+
end
|
62
|
+
|
63
|
+
def default_layout?
|
64
|
+
layout_style == 'Default'
|
65
|
+
end
|
66
|
+
|
67
|
+
def show_labels?
|
68
|
+
display_labels == 'Show'
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def reset_link_attributes
|
74
|
+
return if Rails::VERSION::STRING < '6.0'
|
75
|
+
|
76
|
+
if link_type_one_changed?
|
77
|
+
return if link_type_one_was.nil?
|
78
|
+
|
79
|
+
self.link_one = nil
|
80
|
+
end
|
81
|
+
|
82
|
+
if link_type_two_changed?
|
83
|
+
return if link_type_two_was.nil?
|
84
|
+
|
85
|
+
self.link_two = nil
|
86
|
+
end
|
87
|
+
|
88
|
+
if link_type_three_changed?
|
89
|
+
return if link_type_three_was.nil?
|
90
|
+
|
91
|
+
self.link_three = nil
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def default_values
|
96
|
+
self.layout_style ||= 'Default'
|
97
|
+
self.fit ||= 'Container'
|
98
|
+
self.link_type_one ||= 'Spree::Taxon'
|
99
|
+
self.link_type_two ||= 'Spree::Taxon'
|
100
|
+
self.link_type_three ||= 'Spree::Taxon'
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Spree::Cms::Sections
|
2
|
+
class ProductCarousel < Spree::CmsSection
|
3
|
+
after_initialize :default_values
|
4
|
+
|
5
|
+
LINKED_RESOURCE_TYPE = ['Spree::Taxon']
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def default_values
|
10
|
+
self.fit ||= 'Screen'
|
11
|
+
self.linked_resource_type ||= 'Spree::Taxon'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|