spree_core 5.4.0.beta → 5.4.0.beta2

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.
Files changed (144) hide show
  1. checksums.yaml +4 -4
  2. data/app/finders/spree/products/find.rb +1 -28
  3. data/app/helpers/spree/base_helper.rb +1 -54
  4. data/app/mailers/spree/base_mailer.rb +4 -3
  5. data/app/models/concerns/spree/adjustment_source.rb +0 -8
  6. data/app/models/concerns/spree/admin_user_methods.rb +0 -2
  7. data/app/models/concerns/spree/image_methods.rb +4 -0
  8. data/app/models/concerns/spree/metadata.rb +10 -0
  9. data/app/models/concerns/spree/product_scopes.rb +2 -47
  10. data/app/models/concerns/spree/stores/markets.rb +7 -7
  11. data/app/models/concerns/spree/vat_price_calculation.rb +2 -2
  12. data/app/models/spree/ability.rb +5 -5
  13. data/app/models/spree/address.rb +3 -2
  14. data/app/models/spree/adjustable/promotion_accumulator.rb +1 -1
  15. data/app/models/spree/adjustment.rb +1 -20
  16. data/app/models/spree/api_key.rb +57 -2
  17. data/app/models/spree/country.rb +7 -3
  18. data/app/models/spree/credit_card.rb +0 -27
  19. data/app/models/spree/current.rb +38 -2
  20. data/app/models/spree/exports/products.rb +0 -6
  21. data/app/models/spree/gateway/bogus.rb +9 -9
  22. data/app/models/spree/gateway.rb +0 -3
  23. data/app/models/spree/gift_card_batch.rb +4 -0
  24. data/app/models/spree/image/configuration/active_storage.rb +0 -2
  25. data/app/models/spree/image.rb +7 -31
  26. data/app/models/spree/log_entry.rb +8 -5
  27. data/app/models/spree/order/checkout.rb +0 -18
  28. data/app/models/spree/order.rb +20 -11
  29. data/app/models/spree/payment/gateway_options.rb +2 -2
  30. data/app/models/spree/payment/processing.rb +5 -5
  31. data/app/models/spree/payment.rb +1 -1
  32. data/app/models/spree/payment_connection_error.rb +3 -0
  33. data/app/models/spree/payment_method/check.rb +1 -1
  34. data/app/models/spree/payment_method/store_credit.rb +5 -5
  35. data/app/models/spree/payment_response.rb +70 -0
  36. data/app/models/spree/permission_sets/default_customer.rb +0 -5
  37. data/app/models/spree/permission_sets/product_display.rb +0 -2
  38. data/app/models/spree/permission_sets/product_management.rb +0 -2
  39. data/app/models/spree/product.rb +4 -72
  40. data/app/models/spree/promotion.rb +2 -14
  41. data/app/models/spree/promotion_handler/coupon.rb +3 -3
  42. data/app/models/spree/prototype.rb +0 -3
  43. data/app/models/spree/refund.rb +6 -2
  44. data/app/models/spree/shipment/emails.rb +1 -0
  45. data/app/models/spree/shipping_category.rb +3 -3
  46. data/app/models/spree/store.rb +10 -49
  47. data/app/models/spree/store_credit.rb +4 -0
  48. data/app/models/spree/tax_category.rb +1 -11
  49. data/app/models/spree/taxon.rb +0 -16
  50. data/app/models/spree/variant.rb +2 -40
  51. data/app/models/spree/zone.rb +1 -4
  52. data/app/services/spree/cart/add_item.rb +8 -4
  53. data/app/services/spree/cart/create.rb +13 -2
  54. data/app/services/spree/products/duplicator.rb +0 -12
  55. data/app/services/spree/products/prepare_nested_attributes.rb +0 -12
  56. data/config/locales/en.yml +3 -20
  57. data/db/migrate/20210914000000_spree_four_three.rb +0 -38
  58. data/db/migrate/20210915064329_add_metadata_to_spree_multiple_tables.rb +0 -1
  59. data/db/migrate/20260226000000_add_locale_to_spree_orders.rb +5 -0
  60. data/db/migrate/20260226100000_add_token_digest_to_spree_api_keys.rb +21 -0
  61. data/lib/generators/spree/cursor_rules/templates/spree_rules.mdc +1 -3
  62. data/lib/spree/core/configuration.rb +0 -3
  63. data/lib/spree/core/controller_helpers/strong_parameters.rb +1 -2
  64. data/lib/spree/core/dependencies.rb +2 -10
  65. data/lib/spree/core/engine.rb +0 -13
  66. data/lib/spree/core/pricing/resolver.rb +1 -9
  67. data/lib/spree/core/version.rb +1 -1
  68. data/lib/spree/core.rb +10 -25
  69. data/lib/spree/permitted_attributes.rb +2 -14
  70. data/lib/spree/testing_support/factories/order_factory.rb +1 -0
  71. data/lib/spree/testing_support/factories/payment_method_factory.rb +1 -6
  72. data/lib/spree/testing_support/factories/product_factory.rb +0 -7
  73. data/lib/spree/testing_support/factories/prototype_factory.rb +0 -2
  74. data/lib/tasks/core.rake +0 -265
  75. metadata +8 -101
  76. data/app/finders/spree/posts/find.rb +0 -137
  77. data/app/finders/spree/product_properties/find_available.rb +0 -20
  78. data/app/helpers/spree/mail_helper.rb +0 -27
  79. data/app/jobs/spree/api_key_touch_job.rb +0 -9
  80. data/app/mailers/spree/test_mailer.rb +0 -8
  81. data/app/models/action_text/video_embed.rb +0 -13
  82. data/app/models/concerns/spree/has_one_link.rb +0 -42
  83. data/app/models/concerns/spree/linkable.rb +0 -9
  84. data/app/models/concerns/spree/previewable.rb +0 -17
  85. data/app/models/spree/data_feed/google.rb +0 -15
  86. data/app/models/spree/data_feed.rb +0 -42
  87. data/app/models/spree/gateway/bogus_simple.rb +0 -24
  88. data/app/models/spree/post.rb +0 -108
  89. data/app/models/spree/post_category.rb +0 -46
  90. data/app/models/spree/product_property.rb +0 -51
  91. data/app/models/spree/property.rb +0 -86
  92. data/app/models/spree/property_prototype.rb +0 -9
  93. data/app/models/spree/store_favicon_image.rb +0 -20
  94. data/app/models/spree/store_logo.rb +0 -4
  95. data/app/models/spree/store_mailer_logo.rb +0 -7
  96. data/app/models/spree/taxon_image/configuration/active_storage.rb +0 -26
  97. data/app/models/spree/taxon_image.rb +0 -28
  98. data/app/presenters/spree/filters/properties_presenter.rb +0 -23
  99. data/app/presenters/spree/filters/property_presenter.rb +0 -42
  100. data/app/services/spree/data_feeds/google/optional_attributes.rb +0 -23
  101. data/app/services/spree/data_feeds/google/optional_sub_attributes.rb +0 -21
  102. data/app/services/spree/data_feeds/google/products_list.rb +0 -14
  103. data/app/services/spree/data_feeds/google/required_attributes.rb +0 -68
  104. data/app/services/spree/data_feeds/google/rss.rb +0 -109
  105. data/app/sorters/spree/posts/sort.rb +0 -40
  106. data/app/views/action_text/video_embeds/_thumbnail.html.erb +0 -1
  107. data/app/views/action_text/video_embeds/_video_embed.html.erb +0 -3
  108. data/app/views/layouts/action_text/contents/_content.html.erb +0 -3
  109. data/app/views/spree/test_mailer/test_email.html.erb +0 -40
  110. data/app/views/spree/test_mailer/test_email.text.erb +0 -4
  111. data/config/initializers/oembed.rb +0 -1
  112. data/db/migrate/20221229132350_create_spree_data_feed_settings.rb +0 -14
  113. data/db/migrate/20230109084253_create_product_property_translations.rb +0 -24
  114. data/db/migrate/20230109105943_create_property_translations.rb +0 -24
  115. data/db/migrate/20230415155958_rename_data_feed_settings_table.rb +0 -5
  116. data/db/migrate/20230415160828_rename_data_feed_table_columns.rb +0 -7
  117. data/db/migrate/20230415161226_add_indexes_to_data_feeds_table.rb +0 -5
  118. data/db/migrate/20230512094803_rename_data_feeds_column_provider_to_type.rb +0 -5
  119. data/db/migrate/20240914153106_add_display_on_to_spree_properties.rb +0 -5
  120. data/db/migrate/20240915144935_add_position_to_spree_properties.rb +0 -6
  121. data/db/migrate/20250121160028_create_spree_posts_and_spree_post_categories.rb +0 -33
  122. data/db/migrate/20250127083740_add_kind_to_spree_properties.rb +0 -5
  123. data/db/migrate/20250217171018_create_action_text_video_embeds.rb +0 -11
  124. data/db/migrate/20250305121657_remove_spree_posts_indices.rb +0 -7
  125. data/db/migrate/20250730154601_add_unique_index_on_spree_properties_name.rb +0 -24
  126. data/db/sample_data/posts.rb +0 -7
  127. data/lib/spree/core/controller_helpers/search.rb +0 -17
  128. data/lib/spree/core/product_filters.rb +0 -218
  129. data/lib/spree/core/query_filters/comparable.rb +0 -50
  130. data/lib/spree/core/query_filters/date.rb +0 -8
  131. data/lib/spree/core/query_filters/number.rb +0 -8
  132. data/lib/spree/core/query_filters/text.rb +0 -36
  133. data/lib/spree/core/query_filters.rb +0 -11
  134. data/lib/spree/core/search/base.rb +0 -144
  135. data/lib/spree/testing_support/factories/favicon_image_factory.rb +0 -9
  136. data/lib/spree/testing_support/factories/google_data_feed_factory.rb +0 -7
  137. data/lib/spree/testing_support/factories/post_category_factory.rb +0 -7
  138. data/lib/spree/testing_support/factories/post_factory.rb +0 -22
  139. data/lib/spree/testing_support/factories/product_property_factory.rb +0 -7
  140. data/lib/spree/testing_support/factories/property_factory.rb +0 -28
  141. data/lib/spree/testing_support/factories/taxon_image_factory.rb +0 -9
  142. data/lib/spree/testing_support/flash.rb +0 -25
  143. data/lib/spree/testing_support/flatpickr_capybara.rb +0 -124
  144. data/lib/tasks/exchanges.rake +0 -66
@@ -1,137 +0,0 @@
1
- module Spree
2
- module Posts
3
- class Find < Spree::BaseFinder
4
- def initialize(scope:, params:)
5
- super(scope: scope, params: params)
6
- @scope = scope
7
- @query = params[:q].presence&.strip
8
- @ids = String(params.dig(:filter, :ids)).split(',')
9
- @slugs = String(params.dig(:filter, :slugs)).split(',')
10
- @category_ids = String(params.dig(:filter, :category_ids)).split(',')
11
- @author_ids = String(params.dig(:filter, :author_ids)).split(',')
12
- @tags = params.dig(:filter, :tags).to_s.split(',').compact_blank
13
- @sort_by = params[:sort_by]
14
- @published = params.dig(:filter, :published)
15
- end
16
-
17
- def execute
18
- posts = by_ids(scope)
19
- posts = by_slugs(posts)
20
- posts = by_query(posts)
21
- posts = by_category_ids(posts)
22
- posts = by_author_ids(posts)
23
- posts = by_tags(posts)
24
- posts = by_published(posts)
25
- posts = ordered(posts)
26
-
27
- posts.distinct
28
- end
29
-
30
- private
31
-
32
- attr_reader :scope, :query, :ids, :slugs, :category_ids, :author_ids, :tags, :sort_by, :published
33
-
34
- def query?
35
- query.present?
36
- end
37
-
38
- def ids?
39
- ids.present?
40
- end
41
-
42
- def slugs?
43
- slugs.present?
44
- end
45
-
46
- def category_ids?
47
- category_ids.present?
48
- end
49
-
50
- def author_ids?
51
- author_ids.present?
52
- end
53
-
54
- def tags?
55
- tags.present?
56
- end
57
-
58
- def published?
59
- published.present?
60
- end
61
-
62
- def sort_by?
63
- sort_by.present?
64
- end
65
-
66
- def by_query(posts)
67
- return posts unless query?
68
-
69
- posts.search_by_title(query)
70
- end
71
-
72
- def by_ids(posts)
73
- return posts unless ids?
74
-
75
- posts.where(id: ids)
76
- end
77
-
78
- def by_slugs(posts)
79
- return posts unless slugs?
80
-
81
- posts.where(slug: slugs)
82
- end
83
-
84
- def by_category_ids(posts)
85
- return posts unless category_ids?
86
-
87
- posts.where(post_category_id: category_ids)
88
- end
89
-
90
- def by_author_ids(posts)
91
- return posts unless author_ids?
92
-
93
- posts.where(author_id: author_ids)
94
- end
95
-
96
- def by_tags(posts)
97
- return posts if tags.empty?
98
-
99
- posts.tagged_with(tags, any: true)
100
- end
101
-
102
- def by_published(posts)
103
- return posts unless published?
104
-
105
- case published.to_s
106
- when 'true'
107
- posts.published
108
- when 'false'
109
- posts.where(published_at: nil)
110
- else
111
- posts
112
- end
113
- end
114
-
115
- def ordered(posts)
116
- return posts unless sort_by?
117
-
118
- case sort_by
119
- when 'newest-first'
120
- posts.by_newest
121
- when 'oldest-first'
122
- posts.order(created_at: :asc)
123
- when 'published-newest'
124
- posts.order(published_at: :desc)
125
- when 'published-oldest'
126
- posts.order(published_at: :asc)
127
- when 'title-a-z'
128
- posts.order(title: :asc)
129
- when 'title-z-a'
130
- posts.order(title: :desc)
131
- else
132
- posts
133
- end
134
- end
135
- end
136
- end
137
- end
@@ -1,20 +0,0 @@
1
- module Spree
2
- module ProductProperties
3
- class FindAvailable
4
- include ProductFilterable
5
-
6
- def initialize(scope: ProductProperty.spree_base_scopes, products_scope: Product.spree_base_scopes)
7
- @scope = scope
8
- @products_scope = products_scope
9
- end
10
-
11
- def execute
12
- find_available(scope, products_scope).includes(:translations)
13
- end
14
-
15
- private
16
-
17
- attr_reader :scope, :products_scope
18
- end
19
- end
20
- end
@@ -1,27 +0,0 @@
1
- module Spree
2
- module MailHelper
3
- include Spree::BaseHelper
4
- include Spree::ImagesHelper
5
-
6
- def variant_image_url(variant)
7
- image = variant.default_image
8
- image.present? && image.attached? ? spree_image_url(image, variant: :mini) : image_url('noimage/small.png')
9
- end
10
-
11
- def name_for(order)
12
- order.name || Spree.t('customer')
13
- end
14
-
15
- def store_logo
16
- @store_logo ||= current_store&.mailer_logo || current_store&.logo
17
- end
18
-
19
- def logo_path
20
- Spree::Deprecation.warn('logo_path is deprecated and will be removed in Spree 5.5. Please use Active Storage URL helpers instead.')
21
-
22
- return main_app.cdn_image_url(store_logo.variant(resize_to_limit: [244, 104])) if store_logo&.variable?
23
-
24
- return main_app.cdn_image_url(store_logo) if store_logo&.image?
25
- end
26
- end
27
- end
@@ -1,9 +0,0 @@
1
- module Spree
2
- class ApiKeyTouchJob < Spree::BaseJob
3
- queue_as Spree.queues.api_keys
4
-
5
- def perform(api_key_id)
6
- Spree::ApiKey.find_by(id: api_key_id)&.touch(:last_used_at)
7
- end
8
- end
9
- end
@@ -1,8 +0,0 @@
1
- module Spree
2
- class TestMailer < BaseMailer
3
- def test_email(email)
4
- subject = "#{Spree::Store.default.name} #{Spree.t('test_mailer.test_email.subject')}"
5
- mail(to: email, from: from_address, reply_to: reply_to_address, subject: subject)
6
- end
7
- end
8
- end
@@ -1,13 +0,0 @@
1
- module ActionText
2
- class VideoEmbed < ApplicationRecord
3
- include ActionText::Attachable
4
-
5
- validates :url, :raw_html, :thumbnail_url, presence: true
6
-
7
- # `to_partial_path` for the storefront render is by default "action_text/video_embeds/video_embed"
8
-
9
- def to_trix_content_attachment_partial_path
10
- 'action_text/video_embeds/thumbnail'
11
- end
12
- end
13
- end
@@ -1,42 +0,0 @@
1
- module Spree
2
- module HasOneLink
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- has_one :link, ->(ps) { ps.links }, class_name: 'Spree::PageLink', as: :parent, dependent: :destroy, inverse_of: :parent
7
- accepts_nested_attributes_for :link
8
-
9
- def allowed_linkable_types
10
- [
11
- [Spree.t(:page), 'Spree::Page'],
12
- [Spree.t(:product), 'Spree::Product'],
13
- [Spree.t(:post), 'Spree::Post'],
14
- [Spree.t(:taxon), 'Spree::Taxon'],
15
- [Spree.t(:policy), 'Spree::Policy'],
16
- [Spree.t(:url), nil]
17
- ]
18
- end
19
-
20
- def default_linkable_type
21
- 'Spree::Page'
22
- end
23
-
24
- def default_linkable_resource
25
- @default_linkable_resource ||= theme_or_parent.pages.find_by(type: 'Spree::Pages::Homepage')
26
- end
27
-
28
- def default_links
29
- @default_links.presence || [
30
- Spree::PageLink.new(
31
- label: Spree.t(:shop_all),
32
- linkable: theme_or_parent.pages.find_by(type: 'Spree::Pages::ShopAll')
33
- )
34
- ]
35
- end
36
-
37
- def theme_or_parent
38
- theme.preview? ? theme.parent : theme
39
- end
40
- end
41
- end
42
- end
@@ -1,9 +0,0 @@
1
- module Spree
2
- module Linkable
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- has_many :page_links, as: :linkable, class_name: 'Spree::PageLink', dependent: :destroy
7
- end
8
- end
9
- end
@@ -1,17 +0,0 @@
1
- module Spree
2
- module Previewable
3
- extend ActiveSupport::Concern
4
-
5
- included do |base|
6
- belongs_to :parent, class_name: base.name, optional: true, foreign_key: :parent_id
7
- has_many :previews, class_name: base.name, dependent: :destroy_async, foreign_key: :parent_id
8
-
9
- scope :without_previews, -> { where(parent_id: nil) }
10
- scope :only_previews, -> { where.not(parent_id: nil) }
11
- end
12
-
13
- def preview?
14
- parent.present?
15
- end
16
- end
17
- end
@@ -1,15 +0,0 @@
1
- require_dependency 'spree/data_feed'
2
-
3
- module Spree
4
- class DataFeed::Google < DataFeed
5
- class << self
6
- def label
7
- 'Google Merchant Center Feed'
8
- end
9
-
10
- def provider_name
11
- 'google'
12
- end
13
- end
14
- end
15
- end
@@ -1,42 +0,0 @@
1
- module Spree
2
- class DataFeed < Spree.base_class
3
- has_prefix_id :df
4
-
5
- belongs_to :store, class_name: 'Spree::Store', foreign_key: 'store_id'
6
-
7
- scope :for_store, ->(store) { where(store: store) }
8
-
9
- before_validation :generate_slug
10
-
11
- with_options presence: true do
12
- validates :store
13
- validates :name, uniqueness: true
14
- validates :slug, uniqueness: { scope: :store_id }
15
- end
16
-
17
- def formatted_url
18
- "#{store.formatted_url}/api/v2/data_feeds/#{self.class.provider_name}/#{slug}.rss"
19
- end
20
-
21
- private
22
-
23
- def generate_slug
24
- new_slug = slug.blank? ? SecureRandom.uuid : slug.parameterize
25
- write_attribute(:slug, new_slug)
26
- end
27
-
28
- class << self
29
- def label
30
- raise NotImplementedError
31
- end
32
-
33
- def provider_name
34
- raise NotImplementedError
35
- end
36
-
37
- def available_types
38
- Spree.data_feed_types
39
- end
40
- end
41
- end
42
- end
@@ -1,24 +0,0 @@
1
- # Bogus Gateway that doesn't support payment profiles
2
- module Spree
3
- class Gateway::BogusSimple < Gateway::Bogus
4
- def payment_profiles_supported?
5
- false
6
- end
7
-
8
- def authorize(_money, credit_card, _options = {})
9
- if VALID_CCS.include? credit_card.number
10
- ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, test: true, authorization: '12345', avs_result: { code: 'A' })
11
- else
12
- ActiveMerchant::Billing::Response.new(false, 'Bogus Gateway: Forced failure', { message: 'Bogus Gateway: Forced failure' }, test: true)
13
- end
14
- end
15
-
16
- def purchase(_money, credit_card, _options = {})
17
- if VALID_CCS.include? credit_card.number
18
- ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, test: true, authorization: '12345', avs_result: { code: 'A' })
19
- else
20
- ActiveMerchant::Billing::Response.new(false, 'Bogus Gateway: Forced failure', message: 'Bogus Gateway: Forced failure', test: true)
21
- end
22
- end
23
- end
24
- end
@@ -1,108 +0,0 @@
1
- module Spree
2
- class Post < Spree.base_class
3
- has_prefix_id :post
4
-
5
- include Spree::SingleStoreResource
6
- include Spree::Metafields
7
- extend FriendlyId
8
-
9
- publishes_lifecycle_events
10
-
11
- friendly_id :slug_candidates, use: %i[slugged scoped history], scope: %i[store_id deleted?]
12
- acts_as_paranoid
13
- acts_as_taggable_on :tags
14
- acts_as_taggable_tenant :store_id
15
-
16
- if defined?(PgSearch)
17
- include PgSearch::Model
18
- pg_search_scope :search_by_title, against: :title
19
- else
20
- scope :search_by_title, ->(query) { where('title LIKE ?', "%#{query}%") }
21
- end
22
-
23
- #
24
- # Ransack filtering
25
- #
26
- self.whitelisted_ransackable_attributes = %w[author_id post_category_id published_at]
27
- self.whitelisted_ransackable_associations = %w[author post_category]
28
- self.whitelisted_ransackable_scopes = %w[search_by_title]
29
-
30
- #
31
- # Attachments
32
- #
33
- has_one_attached :image, service: Spree.public_storage_service_name
34
-
35
- #
36
- # Rich Text
37
- #
38
- has_rich_text :content
39
- has_rich_text :excerpt
40
-
41
- #
42
- # Associations
43
- #
44
- belongs_to :author, class_name: Spree.admin_user_class.to_s, optional: true
45
- belongs_to :store, class_name: 'Spree::Store', inverse_of: :posts
46
- belongs_to :post_category, class_name: 'Spree::PostCategory', optional: true, touch: true, inverse_of: :posts
47
- alias category post_category
48
-
49
- #
50
- # Validations
51
- #
52
- validates :title, :store, presence: true
53
- validates :slug, presence: true, uniqueness: { scope: :store_id, conditions: -> { where(deleted_at: nil) } }
54
- validates :meta_title, length: { maximum: 160 }, allow_blank: true
55
- validates :meta_description, length: { maximum: 320 }, allow_blank: true
56
- validates :image, content_type: Rails.application.config.active_storage.web_image_content_types
57
-
58
- #
59
- # Scopes
60
- #
61
- scope :published, -> { where(published_at: [..Time.current]) }
62
- scope :by_newest, -> { order(created_at: :desc) }
63
-
64
- delegate :name, to: :author, prefix: true, allow_nil: true
65
- delegate :title, to: :post_category, prefix: true, allow_nil: true
66
-
67
- def should_generate_new_friendly_id?
68
- slug.blank? || (persisted? && title_changed?)
69
- end
70
-
71
- def slug_candidates
72
- [
73
- :title,
74
- [:title, :id]
75
- ]
76
- end
77
-
78
- def published?
79
- published_at.present?
80
- end
81
-
82
- def publish(date = nil)
83
- update(published_at: date || Time.current)
84
- end
85
-
86
- def unpublish
87
- update(published_at: nil)
88
- end
89
-
90
- def description
91
- excerpt.to_plain_text.presence || content.to_plain_text
92
- end
93
-
94
- def shortened_description
95
- desc = excerpt.to_plain_text.presence || content.to_plain_text
96
- desc.length > 320 ? "#{desc[0...320]}..." : desc
97
- end
98
-
99
- def self.to_tom_select_json
100
- pluck(:id, :title).map do |id, title|
101
- {
102
- id: id,
103
- name: title
104
- }
105
- end.as_json
106
- end
107
- end
108
- end
@@ -1,46 +0,0 @@
1
- module Spree
2
- class PostCategory < Spree.base_class
3
- has_prefix_id :pcat
4
-
5
- include Spree::SingleStoreResource
6
- include Spree::Metafields
7
- extend FriendlyId
8
-
9
- publishes_lifecycle_events
10
-
11
- friendly_id :slug_candidates, use: %i[slugged scoped history], scope: %i[store_id]
12
-
13
- #
14
- # Associations
15
- #
16
- belongs_to :store, class_name: 'Spree::Store', inverse_of: :post_categories
17
- has_many :posts, class_name: 'Spree::Post', dependent: :nullify, inverse_of: :post_category
18
-
19
- #
20
- # Validations
21
- #
22
- validates :title, :store, presence: true
23
- validates :slug, presence: true, uniqueness: { scope: :store_id }
24
-
25
- #
26
- # ActionText
27
- #
28
- has_rich_text :description
29
-
30
- #
31
- # Ransack
32
- #
33
- self.whitelisted_ransackable_attributes = %w[title slug]
34
-
35
- def should_generate_new_friendly_id?
36
- slug.blank? || title_changed?
37
- end
38
-
39
- def slug_candidates
40
- [
41
- :title,
42
- [:title, :id]
43
- ]
44
- end
45
- end
46
- end
@@ -1,51 +0,0 @@
1
- module Spree
2
- class ProductProperty < Spree.base_class
3
- include Spree::FilterParam
4
- include Spree::TranslatableResource
5
-
6
- if Spree.always_use_translations?
7
- TRANSLATABLE_FIELDS = %i[value filter_param].freeze
8
- translates(*TRANSLATABLE_FIELDS)
9
- else
10
- TRANSLATABLE_FIELDS = %i[value].freeze
11
- translates(*TRANSLATABLE_FIELDS, column_fallback: true)
12
- end
13
-
14
- self::Translation.class_eval do
15
- normalizes :value, with: ->(value) { value&.to_s&.squish&.presence }
16
- end
17
-
18
- normalizes :value, with: ->(value) { value&.to_s&.squish&.presence }
19
-
20
- acts_as_list scope: :product
21
-
22
- with_options inverse_of: :product_properties do
23
- belongs_to :product, touch: true, class_name: 'Spree::Product'
24
- belongs_to :property, touch: true, class_name: 'Spree::Property'
25
- end
26
-
27
- validates :property, presence: true
28
- validates :property_id, uniqueness: { scope: :product_id }
29
- validates :value, presence: true
30
-
31
- default_scope { order(:position) }
32
-
33
- scope :filterable, -> { joins(:property).where(Property.table_name => { filterable: true }) }
34
- scope :for_products, ->(products) { where(product_id: products) }
35
- scope :sort_by_property_position, -> {
36
- unscope(:order).joins(:property).order(Spree::Property.table_name => { position: :asc })
37
- }
38
-
39
- self.whitelisted_ransackable_attributes = ['value', 'filter_param']
40
- self.whitelisted_ransackable_associations = ['property']
41
-
42
- # virtual attributes for use with AJAX completion stuff
43
- delegate :name, :presentation, to: :property, prefix: true, allow_nil: true
44
-
45
- protected
46
-
47
- def param_candidate
48
- value
49
- end
50
- end
51
- end
@@ -1,86 +0,0 @@
1
- module Spree
2
- class Property < Spree.base_class
3
- include Spree::FilterParam
4
- include Spree::Metadata
5
- include Spree::ParameterizableName
6
- include Spree::UniqueName
7
- include Spree::DisplayOn
8
- include Spree::TranslatableResource
9
-
10
- TRANSLATABLE_FIELDS = %i[presentation].freeze
11
- translates(*TRANSLATABLE_FIELDS, column_fallback: !Spree.always_use_translations?)
12
-
13
- self::Translation.class_eval do
14
- normalizes :presentation, with: ->(value) { value&.to_s&.squish&.presence }
15
- end
16
-
17
- acts_as_list
18
-
19
- has_many :property_prototypes, class_name: 'Spree::PropertyPrototype'
20
- has_many :prototypes, through: :property_prototypes, class_name: 'Spree::Prototype'
21
-
22
- has_many :product_properties, dependent: :delete_all, inverse_of: :property
23
- has_many :products, through: :product_properties
24
-
25
- validates :name, :presentation, presence: true
26
-
27
- default_scope { order(:position) }
28
- scope :sorted, -> { order(:name) }
29
- scope :filterable, -> { where(filterable: true) }
30
-
31
- KIND_OPTIONS = { short_text: 0, long_text: 1, number: 2, rich_text: 3 }.freeze
32
- enum :kind, KIND_OPTIONS
33
-
34
- DEPENDENCY_UPDATE_FIELDS = [:presentation, :name, :kind, :filterable, :display_on, :position].freeze
35
-
36
- after_touch :touch_all_products
37
- after_update :touch_all_products, if: -> { DEPENDENCY_UPDATE_FIELDS.any? { |field| saved_changes.key?(field) } }
38
- after_save :ensure_product_properties_have_filter_params
39
-
40
- self.whitelisted_ransackable_attributes = ['presentation', 'filterable']
41
-
42
- def uniq_values(product_properties_scope: nil)
43
- with_uniq_values_cache_key(product_properties_scope) do
44
- properties = product_properties
45
- properties = properties.where(id: product_properties_scope) if product_properties_scope.present?
46
- properties.where('value IS NOT NULL AND value != ?', '').pluck(:filter_param, :value).uniq
47
- end
48
- end
49
-
50
- # Returns the metafield type for the property kind
51
- # @return [String] eg. 'Spree::Metafields::ShortText'
52
- def kind_to_metafield_type
53
- case kind
54
- when 'short_text'
55
- 'Spree::Metafields::ShortText'
56
- when 'long_text'
57
- 'Spree::Metafields::LongText'
58
- when 'number'
59
- 'Spree::Metafields::Number'
60
- when 'rich_text'
61
- 'Spree::Metafields::RichText'
62
- else
63
- 'Spree::Metafields::ShortText'
64
- end
65
- end
66
-
67
- private
68
-
69
- def touch_all_products
70
- products.touch_all
71
- end
72
-
73
- def with_uniq_values_cache_key(product_properties_scope, &block)
74
- return block.call if product_properties_scope.present?
75
-
76
- uniq_values_cache_key = ['property-uniq-values', cache_key_with_version]
77
- Rails.cache.fetch(uniq_values_cache_key) { block.call }
78
- end
79
-
80
- def ensure_product_properties_have_filter_params
81
- return unless filterable?
82
-
83
- product_properties.where(filter_param: [nil, '']).where('value IS NOT NULL AND value != ?', '').find_each(&:save)
84
- end
85
- end
86
- end
@@ -1,9 +0,0 @@
1
- module Spree
2
- class PropertyPrototype < Spree.base_class
3
- belongs_to :prototype, class_name: 'Spree::Prototype'
4
- belongs_to :property, class_name: 'Spree::Property'
5
-
6
- validates :prototype, :property, presence: true
7
- validates :prototype_id, uniqueness: { scope: :property_id }
8
- end
9
- end