spree_core 4.4.0 → 4.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (212) hide show
  1. checksums.yaml +4 -4
  2. data/app/finders/spree/option_values/find_available.rb +1 -1
  3. data/app/finders/spree/product_properties/find_available.rb +1 -1
  4. data/app/finders/spree/products/find.rb +21 -15
  5. data/app/finders/spree/taxons/find.rb +11 -8
  6. data/app/helpers/spree/base_helper.rb +14 -11
  7. data/app/helpers/spree/locale_helper.rb +6 -2
  8. data/app/helpers/spree/products_helper.rb +9 -4
  9. data/app/jobs/spree/variants/remove_from_incomplete_orders_job.rb +9 -0
  10. data/app/jobs/spree/variants/remove_line_item_job.rb +9 -0
  11. data/app/models/concerns/spree/calculated_adjustments.rb +1 -1
  12. data/app/models/concerns/spree/display_link.rb +17 -29
  13. data/app/models/concerns/spree/image_methods.rb +21 -9
  14. data/app/models/concerns/spree/metadata.rb +2 -2
  15. data/app/models/concerns/spree/product_scopes.rb +34 -28
  16. data/app/models/concerns/spree/translatable_resource.rb +25 -0
  17. data/app/models/concerns/spree/translatable_resource_scopes.rb +24 -0
  18. data/app/models/concerns/spree/translatable_resource_slug.rb +17 -0
  19. data/app/models/spree/address.rb +7 -1
  20. data/app/models/spree/asset/support/active_storage.rb +3 -2
  21. data/app/models/spree/asset.rb +3 -0
  22. data/app/models/spree/base.rb +1 -0
  23. data/app/models/spree/cms_page.rb +4 -0
  24. data/app/models/spree/cms_section.rb +12 -12
  25. data/app/models/spree/cms_section_image.rb +15 -0
  26. data/app/models/spree/cms_section_image_one.rb +4 -0
  27. data/app/models/spree/cms_section_image_three.rb +4 -0
  28. data/app/models/spree/cms_section_image_two.rb +4 -0
  29. data/app/models/spree/credit_card.rb +10 -4
  30. data/app/models/spree/customer_return.rb +3 -0
  31. data/app/models/spree/data_feed/google.rb +15 -0
  32. data/app/models/spree/data_feed.rb +40 -0
  33. data/app/models/spree/digital.rb +4 -0
  34. data/app/models/spree/digital_link.rb +7 -0
  35. data/app/models/spree/fulfilment_changer.rb +1 -1
  36. data/app/models/spree/gateway/bogus.rb +1 -1
  37. data/app/models/spree/icon.rb +5 -1
  38. data/app/models/spree/image/configuration/active_storage.rb +5 -1
  39. data/app/models/spree/image.rb +3 -3
  40. data/app/models/spree/inventory_unit.rb +5 -2
  41. data/app/models/spree/legacy_user.rb +1 -2
  42. data/app/models/spree/line_item.rb +4 -1
  43. data/app/models/spree/linkable/homepage.rb +3 -0
  44. data/app/models/spree/linkable/uri.rb +3 -0
  45. data/app/models/spree/log_entry.rb +9 -1
  46. data/app/models/spree/menu.rb +3 -0
  47. data/app/models/spree/menu_item.rb +7 -11
  48. data/app/models/spree/option_type.rb +8 -0
  49. data/app/models/spree/option_value.rb +9 -0
  50. data/app/models/spree/order/address_book.rb +1 -0
  51. data/app/models/spree/order.rb +12 -3
  52. data/app/models/spree/order_merger.rb +1 -1
  53. data/app/models/spree/payment/processing.rb +1 -1
  54. data/app/models/spree/payment.rb +7 -1
  55. data/app/models/spree/payment_capture_event.rb +4 -0
  56. data/app/models/spree/payment_method/store_credit.rb +1 -1
  57. data/app/models/spree/payment_method.rb +3 -0
  58. data/app/models/spree/payment_source.rb +10 -0
  59. data/app/models/spree/preference.rb +4 -0
  60. data/app/models/spree/price.rb +3 -0
  61. data/app/models/spree/product.rb +97 -24
  62. data/app/models/spree/product_property.rb +13 -3
  63. data/app/models/spree/promotion/rules/option_value.rb +2 -2
  64. data/app/models/spree/promotion.rb +6 -0
  65. data/app/models/spree/promotion_rule.rb +1 -1
  66. data/app/models/spree/promotion_rule_user.rb +1 -1
  67. data/app/models/spree/property.rb +10 -1
  68. data/app/models/spree/prototype.rb +3 -0
  69. data/app/models/spree/refund.rb +8 -0
  70. data/app/models/spree/reimbursement.rb +3 -0
  71. data/app/models/spree/return_authorization.rb +3 -0
  72. data/app/models/spree/return_item.rb +4 -0
  73. data/app/models/spree/role.rb +1 -1
  74. data/app/models/spree/role_user.rb +1 -1
  75. data/app/models/spree/shipment.rb +8 -1
  76. data/app/models/spree/shipping_category.rb +3 -0
  77. data/app/models/spree/shipping_method.rb +6 -0
  78. data/app/models/spree/state_change.rb +1 -1
  79. data/app/models/spree/stock/availability_validator.rb +9 -3
  80. data/app/models/spree/stock/content_item.rb +1 -1
  81. data/app/models/spree/stock/quantifier.rb +1 -1
  82. data/app/models/spree/stock_item.rb +5 -0
  83. data/app/models/spree/stock_location.rb +19 -5
  84. data/app/models/spree/stock_movement.rb +4 -0
  85. data/app/models/spree/stock_transfer.rb +3 -0
  86. data/app/models/spree/store.rb +39 -15
  87. data/app/models/spree/store_credit.rb +4 -1
  88. data/app/models/spree/store_favicon_image.rb +17 -0
  89. data/app/models/spree/store_logo.rb +9 -0
  90. data/app/models/spree/store_mailer_logo.rb +13 -0
  91. data/app/models/spree/tax_category.rb +6 -0
  92. data/app/models/spree/tax_rate.rb +6 -1
  93. data/app/models/spree/taxon.rb +26 -7
  94. data/app/models/spree/taxon_image/configuration/active_storage.rb +5 -1
  95. data/app/models/spree/taxon_image.rb +3 -2
  96. data/app/models/spree/taxonomy.rb +8 -1
  97. data/app/models/spree/variant.rb +47 -21
  98. data/app/models/spree/wished_item.rb +4 -0
  99. data/app/models/spree/wishlist.rb +4 -1
  100. data/app/models/spree/zone.rb +3 -0
  101. data/app/services/spree/addresses/create.rb +1 -1
  102. data/app/services/spree/addresses/update.rb +7 -2
  103. data/app/services/spree/cart/remove_line_item.rb +1 -0
  104. data/app/services/spree/data_feeds/google/optional_attributes.rb +23 -0
  105. data/app/services/spree/data_feeds/google/optional_sub_attributes.rb +21 -0
  106. data/app/services/spree/data_feeds/google/products_list.rb +14 -0
  107. data/app/services/spree/data_feeds/google/required_attributes.rb +67 -0
  108. data/app/services/spree/data_feeds/google/rss.rb +107 -0
  109. data/app/services/spree/variants/remove_line_items.rb +15 -0
  110. data/app/sorters/spree/products/sort.rb +23 -0
  111. data/brakeman.ignore +326 -18
  112. data/config/initializers/friendly_id.rb +2 -0
  113. data/config/initializers/mobility.rb +18 -0
  114. data/config/locales/en.yml +6 -2
  115. data/config/routes.rb +43 -0
  116. data/db/migrate/20211201202851_update_linkable_resource_types.rb +10 -0
  117. data/db/migrate/20211203082008_add_settings_to_payment_methods.rb +11 -0
  118. data/db/migrate/20211229162122_disable_propagate_all_variants_by_default.rb +5 -0
  119. data/db/migrate/20220103082046_add_status_and_make_active_at_to_spree_products.rb +7 -0
  120. data/db/migrate/20220106230929_add_internal_note_to_spree_orders.rb +5 -0
  121. data/db/migrate/20220113052823_create_payment_sources.rb +22 -0
  122. data/db/migrate/20220117100333_add_make_active_at_to_spree_products.rb +17 -0
  123. data/db/migrate/20220120092821_add_metadata_to_spree_tax_rates.rb +13 -0
  124. data/db/migrate/20220201103922_add_first_name_and_last_name_to_spree_users.rb +9 -0
  125. data/db/migrate/20220222083546_add_barcode_to_spree_variants.rb +6 -0
  126. data/db/migrate/20220329113557_fix_cms_pages_unique_indexes.rb +8 -0
  127. data/db/migrate/20220613133029_add_metadata_to_spree_stock_items.rb +13 -0
  128. data/db/migrate/20220706112554_create_product_name_and_description_translations_for_mobility_table_backend.rb +27 -0
  129. data/db/migrate/20220715083542_create_spree_product_translations_for_mobility.rb +7 -0
  130. data/db/migrate/20220715120222_change_product_name_null_to_true.rb +5 -0
  131. data/db/migrate/20220718100743_create_spree_taxon_name_and_description_translations_for_mobility_table_backend.rb +27 -0
  132. data/db/migrate/20220718100948_change_taxon_name_null_to_true.rb +5 -0
  133. data/db/migrate/20220802070609_add_locale_to_friendly_id_slugs.rb +11 -0
  134. data/db/migrate/20220802073225_create_spree_product_slug_translations_for_mobility_table_backend.rb +5 -0
  135. data/db/migrate/20220804073928_transfer_data_to_translatable_tables.rb +66 -0
  136. data/db/migrate/20221215151408_add_selected_locale_to_spree_users.rb +8 -0
  137. data/db/migrate/20221219123957_add_deleted_at_to_product_translations.rb +6 -0
  138. data/db/migrate/20221220133432_add_uniqueness_constraint_to_product_translations.rb +5 -0
  139. data/db/migrate/20221229132350_create_spree_data_feed_settings.rb +14 -0
  140. data/db/migrate/20230103144439_create_option_type_translations.rb +26 -0
  141. data/db/migrate/20230103151034_create_option_value_translations.rb +26 -0
  142. data/db/migrate/20230109084253_create_product_property_translations.rb +25 -0
  143. data/db/migrate/20230109094907_transfer_options_data_to_translatable_tables.rb +58 -0
  144. data/db/migrate/20230109105943_create_property_translations.rb +26 -0
  145. data/db/migrate/20230109110840_transfer_property_data_to_translatable_tables.rb +59 -0
  146. data/db/migrate/20230110142344_backfill_friendly_id_slug_locale.rb +15 -0
  147. data/db/migrate/20230111121534_add_additional_taxon_translation_fields.rb +8 -0
  148. data/db/migrate/20230111122511_transfer_product_and_taxon_data_to_translatable_tables.rb +82 -0
  149. data/db/migrate/20230117115531_create_taxonomy_translations.rb +24 -0
  150. data/db/migrate/20230117120430_allow_null_taxonomy_name.rb +5 -0
  151. data/db/migrate/20230117121303_transfer_taxonomy_data_to_translatable_tables.rb +11 -0
  152. data/db/migrate/20230210142732_create_store_translations.rb +50 -0
  153. data/db/migrate/20230210142849_transfer_store_data_to_translatable_tables.rb +11 -0
  154. data/db/migrate/20230210230434_add_deleted_at_to_store_translations.rb +6 -0
  155. data/db/migrate/20230415155958_rename_data_feed_settings_table.rb +5 -0
  156. data/db/migrate/20230415160828_rename_data_feed_table_columns.rb +7 -0
  157. data/db/migrate/20230415161226_add_indexes_to_data_feeds_table.rb +5 -0
  158. data/db/migrate/20230512094803_rename_data_feeds_column_provider_to_type.rb +5 -0
  159. data/db/migrate/20230514162157_add_index_on_locale_and_permalink_to_spree_taxons.rb +5 -0
  160. data/lib/friendly_id/paranoia.rb +4 -0
  161. data/lib/generators/spree/dummy/dummy_generator.rb +13 -2
  162. data/lib/generators/spree/dummy/templates/package.json +12 -0
  163. data/lib/generators/spree/dummy/templates/rails/test.rb +2 -0
  164. data/lib/spree/core/configuration.rb +91 -0
  165. data/lib/spree/core/controller_helpers/auth.rb +3 -1
  166. data/lib/spree/core/controller_helpers/currency.rb +7 -5
  167. data/lib/spree/core/controller_helpers/locale.rb +34 -8
  168. data/lib/spree/core/controller_helpers/order.rb +4 -2
  169. data/lib/spree/core/controller_helpers/search.rb +1 -1
  170. data/lib/spree/core/controller_helpers/store.rb +5 -3
  171. data/lib/spree/core/dependencies.rb +106 -0
  172. data/lib/spree/core/dependencies_helper.rb +19 -0
  173. data/lib/spree/core/engine.rb +53 -38
  174. data/{app/models/spree → lib/spree/core}/preferences/configuration.rb +3 -0
  175. data/{app/models/spree → lib/spree/core}/preferences/preferable.rb +3 -0
  176. data/lib/spree/core/product_duplicator.rb +1 -1
  177. data/lib/spree/core/product_filters.rb +7 -4
  178. data/lib/spree/core/search/base.rb +10 -6
  179. data/lib/spree/core/version.rb +1 -1
  180. data/lib/spree/core.rb +27 -5
  181. data/lib/spree/permitted_attributes.rb +9 -7
  182. data/lib/spree/testing_support/common_rake.rb +1 -0
  183. data/lib/spree/testing_support/factories/favicon_image_factory.rb +9 -0
  184. data/lib/spree/testing_support/factories/google_data_feed_factory.rb +8 -0
  185. data/lib/spree/testing_support/factories/icon_factory.rb +3 -1
  186. data/lib/spree/testing_support/factories/image_factory.rb +3 -1
  187. data/lib/spree/testing_support/factories/menu_item_factory.rb +1 -1
  188. data/lib/spree/testing_support/factories/order_factory.rb +2 -1
  189. data/lib/spree/testing_support/factories/product_factory.rb +12 -1
  190. data/lib/spree/testing_support/factories/product_property_factory.rb +1 -0
  191. data/lib/spree/testing_support/factories/product_translation_factory.rb +6 -0
  192. data/lib/spree/testing_support/factories/refund_factory.rb +1 -1
  193. data/lib/spree/testing_support/factories/return_authorization_factory.rb +1 -1
  194. data/lib/spree/testing_support/factories/role_factory.rb +1 -1
  195. data/lib/spree/testing_support/factories/shipping_category_factory.rb +1 -1
  196. data/lib/spree/testing_support/factories/stock_location_factory.rb +3 -2
  197. data/lib/spree/testing_support/factories/store_factory.rb +2 -1
  198. data/lib/spree/testing_support/factories/taxon_image_factory.rb +3 -1
  199. data/lib/spree/testing_support/factories/user_factory.rb +4 -0
  200. data/lib/spree/testing_support/factories/variant_factory.rb +8 -0
  201. data/lib/spree/translation_migrations.rb +40 -0
  202. data/lib/spree_core.rb +2 -1
  203. data/lib/tasks/core.rake +12 -0
  204. data/spree_core.gemspec +5 -3
  205. metadata +152 -52
  206. data/app/models/friendly_id/slug_decorator.rb +0 -9
  207. data/app/models/spree/app_configuration.rb +0 -86
  208. data/lib/friendly_id/slug_rails5_patch.rb +0 -11
  209. data/lib/spree/core/app_dependencies.rb +0 -126
  210. /data/{app/models/spree → lib/spree/core}/preferences/preferable_class_methods.rb +0 -0
  211. /data/{app/models/spree → lib/spree/core}/preferences/scoped_store.rb +0 -0
  212. /data/{app/models/spree → lib/spree/core}/preferences/store.rb +0 -0
@@ -3,6 +3,12 @@ module Spree
3
3
  require 'validates_zipcode'
4
4
 
5
5
  include Metadata
6
+ if defined?(Spree::Webhooks)
7
+ include Spree::Webhooks::HasWebhooks
8
+ end
9
+ if defined?(Spree::Security::Addresses)
10
+ include Spree::Security::Addresses
11
+ end
6
12
 
7
13
  if Rails::VERSION::STRING >= '6.1'
8
14
  serialize :preferences, Hash, default: {}
@@ -31,7 +37,7 @@ module Spree
31
37
 
32
38
  belongs_to :country, class_name: 'Spree::Country'
33
39
  belongs_to :state, class_name: 'Spree::State', optional: true
34
- belongs_to :user, class_name: Spree.user_class.name, optional: true
40
+ belongs_to :user, class_name: "::#{Spree.user_class}", optional: true
35
41
 
36
42
  has_many :shipments, inverse_of: :address
37
43
 
@@ -8,7 +8,7 @@ module Spree
8
8
  def url(style)
9
9
  return placeholder(style) unless attachment.attached?
10
10
 
11
- attachment.variant(resize: dimensions_for_style(style))
11
+ attachment.variant(resize_to_limit: dimensions_for_style(style))
12
12
  end
13
13
 
14
14
  def placeholder(style)
@@ -16,7 +16,8 @@ module Spree
16
16
  end
17
17
 
18
18
  def dimensions_for_style(style)
19
- self.class.styles.with_indifferent_access[style] || self.class.styles.with_indifferent_access[default_style]
19
+ dimensions = self.class.styles.with_indifferent_access[style] || self.class.styles.with_indifferent_access[default_style]
20
+ dimensions.split('x').map(&:to_i)
20
21
  end
21
22
  end
22
23
  end
@@ -2,6 +2,9 @@ module Spree
2
2
  class Asset < Spree::Base
3
3
  include Support::ActiveStorage
4
4
  include Metadata
5
+ if defined?(Spree::Webhooks)
6
+ include Spree::Webhooks::HasWebhooks
7
+ end
5
8
 
6
9
  belongs_to :viewable, polymorphic: true, touch: true
7
10
  acts_as_list scope: [:viewable_id, :viewable_type]
@@ -3,6 +3,7 @@ class Spree::Base < ApplicationRecord
3
3
  serialize :preferences, Hash
4
4
 
5
5
  include Spree::RansackableAttributes
6
+ include Spree::TranslatableResourceScopes
6
7
 
7
8
  after_initialize do
8
9
  if has_attribute?(:preferences) && !preferences.nil?
@@ -3,6 +3,10 @@ module Spree
3
3
  include SingleStoreResource
4
4
  include DisplayLink
5
5
 
6
+ if defined?(Spree::Webhooks)
7
+ include Spree::Webhooks::HasWebhooks
8
+ end
9
+
6
10
  acts_as_paranoid
7
11
 
8
12
  TYPES = ['Spree::Cms::Pages::StandardPage',
@@ -7,30 +7,30 @@ module Spree
7
7
 
8
8
  validate :reset_link_attributes
9
9
 
10
- IMAGE_COUNT = ['one', 'two', 'three']
11
- IMAGE_TYPES = ['image/png', 'image/jpg', 'image/jpeg', 'image/gif'].freeze
12
- IMAGE_SIZE = ['sm', 'md', 'lg', 'xl']
10
+ has_one :image_one, class_name: 'Spree::CmsSectionImageOne', dependent: :destroy, as: :viewable
11
+ accepts_nested_attributes_for :image_one, reject_if: :all_blank
13
12
 
14
- IMAGE_COUNT.each do |count|
15
- send(:has_one_attached, "image_#{count}".to_sym)
13
+ has_one :image_two, class_name: 'Spree::CmsSectionImageTwo', dependent: :destroy, as: :viewable
14
+ accepts_nested_attributes_for :image_two, reject_if: :all_blank
16
15
 
17
- IMAGE_SIZE.each do |size|
16
+ has_one :image_three, class_name: 'Spree::CmsSectionImageThree', dependent: :destroy, as: :viewable
17
+ accepts_nested_attributes_for :image_three, reject_if: :all_blank
18
+
19
+ Spree::CmsSectionImage::IMAGE_COUNT.each do |count|
20
+ Spree::CmsSectionImage::IMAGE_SIZE.each do |size|
18
21
  define_method("img_#{count}_#{size}") do |dimensions = nil|
19
- return if !send("image_#{count}").attached? || dimensions.nil?
22
+ image = send("image_#{count}")&.attachment
23
+ return if !image&.attached? || dimensions.nil?
20
24
 
21
- send("image_#{count}").variant(resize: dimensions)
25
+ image.variant(resize_to_limit: dimensions.split('x').map(&:to_i))
22
26
  end
23
27
  end
24
28
  end
25
29
 
26
- belongs_to :linked_resource, polymorphic: true
27
-
28
30
  default_scope { order(position: :asc) }
29
31
 
30
32
  validates :name, :cms_page, :type, presence: true
31
33
 
32
- validates :image_one, :image_two, :image_three, content_type: IMAGE_TYPES
33
-
34
34
  LINKED_RESOURCE_TYPE = []
35
35
 
36
36
  TYPES = ['Spree::Cms::Sections::HeroImage',
@@ -0,0 +1,15 @@
1
+ module Spree
2
+ class CmsSectionImage < Asset
3
+ if Spree.public_storage_service_name
4
+ has_one_attached :attachment, service: Spree.public_storage_service_name
5
+ else
6
+ has_one_attached :attachment
7
+ end
8
+
9
+ IMAGE_COUNT = ['one', 'two', 'three']
10
+ IMAGE_TYPES = ['image/png', 'image/jpg', 'image/jpeg', 'image/gif'].freeze
11
+ IMAGE_SIZE = ['sm', 'md', 'lg', 'xl']
12
+
13
+ validates :attachment, attached: true, content_type: IMAGE_TYPES
14
+ end
15
+ end
@@ -0,0 +1,4 @@
1
+ module Spree
2
+ class CmsSectionImageOne < CmsSectionImage
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Spree
2
+ class CmsSectionImageThree < CmsSectionImage
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Spree
2
+ class CmsSectionImageTwo < CmsSectionImage
3
+ end
4
+ end
@@ -2,11 +2,17 @@ module Spree
2
2
  class CreditCard < Spree::Base
3
3
  include ActiveMerchant::Billing::CreditCardMethods
4
4
  include Metadata
5
+ if defined?(Spree::Webhooks)
6
+ include Spree::Webhooks::HasWebhooks
7
+ end
8
+ if defined?(Spree::Security::CreditCards)
9
+ include Spree::Security::CreditCards
10
+ end
5
11
 
6
12
  acts_as_paranoid
7
13
 
8
14
  belongs_to :payment_method
9
- belongs_to :user, class_name: Spree.user_class.to_s, foreign_key: 'user_id',
15
+ belongs_to :user, class_name: "::#{Spree.user_class}", foreign_key: 'user_id',
10
16
  optional: true
11
17
  has_many :payments, as: :source
12
18
 
@@ -174,9 +180,9 @@ module Spree
174
180
 
175
181
  def self.json_api_permitted_attributes
176
182
  [
177
- 'number', 'month', 'year', 'expiry', 'verification_value', 'first_name', 'last_name',
178
- 'cc_type', 'gateway_customer_profile_id', 'gateway_payment_profile_id', 'last_digits',
179
- 'name', 'encrypted_data', 'address_id', 'created_at', 'updated_at', 'user_id',
183
+ 'number', 'month', 'year', 'expiry', 'verification_value', 'first_name', 'last_name',
184
+ 'cc_type', 'gateway_customer_profile_id', 'gateway_payment_profile_id', 'last_digits',
185
+ 'name', 'encrypted_data', 'address_id', 'created_at', 'updated_at', 'user_id',
180
186
  'payment_method_id', 'default', 'deleted_at'
181
187
  ]
182
188
  end
@@ -3,6 +3,9 @@ module Spree
3
3
  include Spree::Core::NumberGenerator.new(prefix: 'CR', length: 9)
4
4
  include NumberIdentifier
5
5
  include Metadata
6
+ if defined?(Spree::Webhooks)
7
+ include Spree::Webhooks::HasWebhooks
8
+ end
6
9
 
7
10
  belongs_to :stock_location
8
11
  belongs_to :store, class_name: 'Spree::Store', inverse_of: :customer_returns
@@ -0,0 +1,15 @@
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
@@ -0,0 +1,40 @@
1
+ module Spree
2
+ class DataFeed < Base
3
+ belongs_to :store, class_name: 'Spree::Store', foreign_key: 'store_id'
4
+
5
+ scope :for_store, ->(store) { where(store: store) }
6
+
7
+ before_validation :generate_slug
8
+
9
+ with_options presence: true do
10
+ validates :store
11
+ validates :name, uniqueness: true
12
+ validates :slug, uniqueness: { scope: :store_id }
13
+ end
14
+
15
+ def formatted_url
16
+ "#{store.formatted_url}/api/v2/data_feeds/#{self.class.provider_name}/#{slug}.rss"
17
+ end
18
+
19
+ private
20
+
21
+ def generate_slug
22
+ new_slug = slug.blank? ? SecureRandom.uuid : slug.parameterize
23
+ write_attribute(:slug, new_slug)
24
+ end
25
+
26
+ class << self
27
+ def label
28
+ raise NotImplementedError
29
+ end
30
+
31
+ def provider_name
32
+ raise NotImplementedError
33
+ end
34
+
35
+ def available_types
36
+ Rails.application.config.spree.data_feed_types
37
+ end
38
+ end
39
+ end
40
+ end
@@ -3,6 +3,10 @@ module Spree
3
3
  belongs_to :variant
4
4
  has_many :digital_links, dependent: :destroy
5
5
 
6
+ if defined?(Spree::Webhooks)
7
+ include Spree::Webhooks::HasWebhooks
8
+ end
9
+
6
10
  if Spree.private_storage_service_name
7
11
  has_one_attached :attachment, service: Spree.private_storage_service_name
8
12
  else
@@ -2,6 +2,13 @@ module Spree
2
2
  class DigitalLink < Spree::Base
3
3
  has_secure_token
4
4
 
5
+ if defined?(Spree::Webhooks)
6
+ include Spree::Webhooks::HasWebhooks
7
+ end
8
+ if defined?(Spree::Security::DigitalLinks)
9
+ include Spree::Security::DigitalLinks
10
+ end
11
+
5
12
  belongs_to :digital
6
13
  belongs_to :line_item
7
14
 
@@ -92,7 +92,7 @@ module Spree
92
92
  end
93
93
 
94
94
  def get_desired_shipment_inventory_unit(state)
95
- desired_shipment.inventory_units.find_or_create_by(state: state) do |unit|
95
+ desired_shipment.inventory_units.find_or_create_by(state: state, variant: variant) do |unit|
96
96
  current_shipment_unit = current_shipment_units.first
97
97
  unit.variant_id = current_shipment_unit.variant_id
98
98
  unit.order_id = current_shipment_unit.order_id
@@ -58,7 +58,7 @@ module Spree
58
58
  ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, test: true, authorization: '12345')
59
59
  end
60
60
 
61
- def cancel(_response_code)
61
+ def cancel(_response_code, _payment = nil)
62
62
  ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, test: true, authorization: '12345')
63
63
  end
64
64
 
@@ -1,6 +1,10 @@
1
1
  module Spree
2
2
  class Icon < Spree::Asset
3
- has_one_attached :attachment
3
+ if Spree.public_storage_service_name
4
+ has_one_attached :attachment, service: Spree.public_storage_service_name
5
+ else
6
+ has_one_attached :attachment
7
+ end
4
8
 
5
9
  ICON_TYPES = %i[png jpg jpeg gif svg]
6
10
 
@@ -5,7 +5,11 @@ module Spree
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  included do
8
- has_one_attached :attachment
8
+ if Spree.public_storage_service_name
9
+ has_one_attached :attachment, service: Spree.public_storage_service_name
10
+ else
11
+ has_one_attached :attachment
12
+ end
9
13
 
10
14
  validates :attachment, attached: true, content_type: /\Aimage\/.*\z/
11
15
 
@@ -13,7 +13,7 @@ module Spree
13
13
 
14
14
  def styles
15
15
  self.class.styles.map do |_, size|
16
- width, height = size.chop.split('x')
16
+ width, height = size.chop.split('x').map(&:to_i)
17
17
 
18
18
  {
19
19
  url: generate_url(size: size),
@@ -28,7 +28,7 @@ module Spree
28
28
  size = self.class.styles[name]
29
29
  return unless size
30
30
 
31
- width, height = size.chop.split('x')
31
+ width, height = size.chop.split('x').map(&:to_i)
32
32
 
33
33
  {
34
34
  url: generate_url(size: size),
@@ -40,7 +40,7 @@ module Spree
40
40
 
41
41
  def style_dimensions(name)
42
42
  size = self.class.styles[name]
43
- width, height = size.chop.split('x')
43
+ width, height = size.chop.split('x').map(&:to_i)
44
44
 
45
45
  {
46
46
  width: width,
@@ -1,5 +1,9 @@
1
1
  module Spree
2
2
  class InventoryUnit < Spree::Base
3
+ if defined?(Spree::Webhooks)
4
+ include Spree::Webhooks::HasWebhooks
5
+ end
6
+
3
7
  with_options inverse_of: :inventory_units do
4
8
  belongs_to :variant, -> { with_deleted }, class_name: 'Spree::Variant'
5
9
  belongs_to :order, class_name: 'Spree::Order'
@@ -59,8 +63,7 @@ module Spree
59
63
  end
60
64
 
61
65
  def find_stock_item
62
- Spree::StockItem.where(stock_location_id: shipment.stock_location_id,
63
- variant_id: variant_id).first
66
+ shipment.stock_location.stock_item_or_create(variant)
64
67
  end
65
68
 
66
69
  def self.split(original_inventory_unit, extract_quantity)
@@ -8,7 +8,6 @@ module Spree
8
8
 
9
9
  self.table_name = 'spree_users'
10
10
 
11
- attr_accessor :password
12
- attr_accessor :password_confirmation
11
+ attr_accessor :password, :password_confirmation
13
12
  end
14
13
  end
@@ -1,6 +1,9 @@
1
1
  module Spree
2
2
  class LineItem < Spree::Base
3
3
  include Metadata
4
+ if defined?(Spree::Webhooks)
5
+ include Spree::Webhooks::HasWebhooks
6
+ end
4
7
 
5
8
  before_validation :ensure_valid_quantity
6
9
 
@@ -8,7 +11,7 @@ module Spree
8
11
  belongs_to :order, class_name: 'Spree::Order', touch: true
9
12
  belongs_to :variant, -> { with_deleted }, class_name: 'Spree::Variant'
10
13
  end
11
- belongs_to :tax_category, class_name: 'Spree::TaxCategory'
14
+ belongs_to :tax_category, -> { with_deleted }, class_name: 'Spree::TaxCategory'
12
15
 
13
16
  has_one :product, through: :variant
14
17
 
@@ -0,0 +1,3 @@
1
+ module Spree::Linkable::Homepage
2
+ # Placeholder for polymorphic lookup.
3
+ end
@@ -0,0 +1,3 @@
1
+ module Spree::Linkable::Uri
2
+ # Placeholder for polymorphic lookup.
3
+ end
@@ -1,5 +1,9 @@
1
1
  module Spree
2
2
  class LogEntry < Spree::Base
3
+ if defined?(Spree::Security::LogEntries)
4
+ include Spree::Security::LogEntries
5
+ end
6
+
3
7
  belongs_to :source, polymorphic: true
4
8
 
5
9
  # Fix for #1767
@@ -11,7 +15,11 @@ module Spree
11
15
  end
12
16
 
13
17
  def parsed_details
14
- @details ||= YAML.safe_load(details, [ActiveMerchant::Billing::Response])
18
+ @details ||= if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.1.0')
19
+ YAML.safe_load(details, permitted_classes: [ActiveMerchant::Billing::Response])
20
+ else
21
+ YAML.safe_load(details, [ActiveMerchant::Billing::Response])
22
+ end
15
23
  end
16
24
  end
17
25
  end
@@ -1,6 +1,9 @@
1
1
  module Spree
2
2
  class Menu < Spree::Base
3
3
  include SingleStoreResource
4
+ if defined?(Spree::Webhooks)
5
+ include Spree::Webhooks::HasWebhooks
6
+ end
4
7
 
5
8
  MENU_LOCATIONS = ['Header', 'Footer']
6
9
  MENU_LOCATIONS_PARAMETERIZED = []
@@ -1,11 +1,16 @@
1
1
  module Spree
2
2
  class MenuItem < Spree::Base
3
3
  include Spree::DisplayLink
4
+ if defined?(Spree::Webhooks)
5
+ include Spree::Webhooks::HasWebhooks
6
+ end
4
7
 
5
8
  acts_as_nested_set dependent: :destroy
6
9
 
10
+ ITEM_TYPE = %w[Link Container]
11
+ LINKED_RESOURCE_TYPE = ['Spree::Linkable::Uri', 'Spree::Linkable::Homepage', 'Spree::Product', 'Spree::Taxon', 'Spree::CmsPage']
12
+
7
13
  belongs_to :menu, touch: true
8
- belongs_to :linked_resource, polymorphic: true
9
14
 
10
15
  before_create :ensure_item_belongs_to_root
11
16
  before_update :reset_link_attributes
@@ -14,15 +19,6 @@ module Spree
14
19
  after_save :touch_ancestors_and_menu
15
20
  after_touch :touch_ancestors_and_menu
16
21
 
17
- ITEM_TYPE = %w[Link Container]
18
-
19
- LINKED_RESOURCE_TYPE = ['URL']
20
- STATIC_RESOURCE_TYPE = ['Home Page']
21
- DYNAMIC_RESOURCE_TYPE = ['Spree::Product', 'Spree::Taxon', 'Spree::CmsPage']
22
-
23
- LINKED_RESOURCE_TYPE.unshift(*STATIC_RESOURCE_TYPE)
24
- LINKED_RESOURCE_TYPE.push(*DYNAMIC_RESOURCE_TYPE)
25
-
26
22
  validates :name, :menu, presence: true
27
23
  validates :item_type, inclusion: { in: ITEM_TYPE }
28
24
  validates :linked_resource_type, inclusion: { in: LINKED_RESOURCE_TYPE }
@@ -50,7 +46,7 @@ module Spree
50
46
  self.destination = nil
51
47
  self.new_window = false
52
48
 
53
- self.linked_resource_type = 'URL' if item_type == 'Container'
49
+ self.linked_resource_type = 'Spree::Linkable::Uri' if item_type == 'Container'
54
50
  end
55
51
  end
56
52
 
@@ -2,8 +2,16 @@ module Spree
2
2
  class OptionType < Spree::Base
3
3
  include UniqueName
4
4
  include Metadata
5
+ include TranslatableResource
6
+ if defined?(Spree::Webhooks)
7
+ include Spree::Webhooks::HasWebhooks
8
+ end
9
+
10
+ TRANSLATABLE_FIELDS = %i[name presentation].freeze
11
+ translates(*TRANSLATABLE_FIELDS)
5
12
 
6
13
  acts_as_list
14
+ auto_strip_attributes :name, :presentation
7
15
 
8
16
  with_options dependent: :destroy, inverse_of: :option_type do
9
17
  has_many :option_values, -> { order(:position) }
@@ -1,9 +1,18 @@
1
1
  module Spree
2
2
  class OptionValue < Spree::Base
3
3
  include Metadata
4
+ include TranslatableResource
5
+ if defined?(Spree::Webhooks)
6
+ include Spree::Webhooks::HasWebhooks
7
+ end
8
+
9
+ TRANSLATABLE_FIELDS = %i[name presentation].freeze
10
+ translates(*TRANSLATABLE_FIELDS)
4
11
 
5
12
  belongs_to :option_type, class_name: 'Spree::OptionType', touch: true, inverse_of: :option_values
13
+
6
14
  acts_as_list scope: :option_type
15
+ auto_strip_attributes :name, :presentation
7
16
 
8
17
  has_many :option_value_variants, class_name: 'Spree::OptionValueVariant'
9
18
  has_many :variants, through: :option_value_variants, class_name: 'Spree::Variant'
@@ -54,6 +54,7 @@ module Spree
54
54
  return if attributes.blank?
55
55
 
56
56
  attributes.transform_values! { |v| v == '' ? nil : v }
57
+ attributes = attributes.to_h.symbolize_keys
57
58
 
58
59
  default_address_scope = user ? user.addresses : ::Spree::Address
59
60
  default_address = default_address_scope.find_by(id: attributes[:id])
@@ -24,7 +24,16 @@ module Spree
24
24
  include NumberAsParam
25
25
  include SingleStoreResource
26
26
  include MemoizedData
27
- include Metadata
27
+ include Spree::Metadata
28
+ if defined?(Spree::Webhooks)
29
+ include Spree::Webhooks::HasWebhooks
30
+ end
31
+ if defined?(Spree::Security::Orders)
32
+ include Spree::Security::Orders
33
+ end
34
+ if defined?(Spree::VendorConcern)
35
+ include Spree::VendorConcern
36
+ end
28
37
 
29
38
  MEMOIZED_METHODS = %w(tax_zone)
30
39
 
@@ -77,7 +86,7 @@ module Spree
77
86
  attribute :state_machine_resumed, :boolean
78
87
 
79
88
  if Spree.user_class
80
- belongs_to :user, class_name: Spree.user_class.to_s, optional: true
89
+ belongs_to :user, class_name: "::#{Spree.user_class}", optional: true
81
90
  else
82
91
  belongs_to :user, optional: true
83
92
  end
@@ -146,7 +155,7 @@ module Spree
146
155
 
147
156
  before_create :create_token
148
157
  before_create :link_by_email
149
- before_update :homogenize_line_item_currencies, if: :currency_changed?
158
+ before_update :ensure_updated_shipments, :homogenize_line_item_currencies, if: :currency_changed?
150
159
 
151
160
  with_options presence: true do
152
161
  # we want to have this case_sentive: true as changing it to false causes all SQL to use LOWER(slug)
@@ -54,7 +54,7 @@ module Spree
54
54
 
55
55
  # Change the error messages as you choose.
56
56
  def handle_error(line_item)
57
- order.errors[:base] << line_item.errors.full_messages
57
+ order.errors.add(:base, line_item.errors.full_messages)
58
58
  end
59
59
 
60
60
  def persist_merge
@@ -72,7 +72,7 @@ module Spree
72
72
  end
73
73
 
74
74
  def cancel!
75
- response = payment_method.cancel(response_code)
75
+ response = payment_method.cancel(response_code, self)
76
76
  handle_response(response, :void, :failure)
77
77
  end
78
78
 
@@ -6,12 +6,18 @@ module Spree
6
6
  include NumberIdentifier
7
7
  include NumberAsParam
8
8
  include Metadata
9
+ if defined?(Spree::Webhooks)
10
+ include Spree::Webhooks::HasWebhooks
11
+ end
12
+ if defined?(Spree::Security::Payments)
13
+ include Spree::Security::Payments
14
+ end
9
15
 
10
16
  include Spree::Payment::Processing
11
17
 
12
18
  NON_RISKY_AVS_CODES = ['B', 'D', 'H', 'J', 'M', 'Q', 'T', 'V', 'X', 'Y'].freeze
13
19
  RISKY_AVS_CODES = ['A', 'C', 'E', 'F', 'G', 'I', 'K', 'L', 'N', 'O', 'P', 'R', 'S', 'U', 'W', 'Z'].freeze
14
- INVALID_STATES = %w(failed invalid).freeze
20
+ INVALID_STATES = %w(failed invalid void).freeze
15
21
 
16
22
  with_options inverse_of: :payments do
17
23
  belongs_to :order, class_name: 'Spree::Order', touch: true
@@ -1,5 +1,9 @@
1
1
  module Spree
2
2
  class PaymentCaptureEvent < Spree::Base
3
+ if defined?(Spree::Webhooks)
4
+ include Spree::Webhooks::HasWebhooks
5
+ end
6
+
3
7
  belongs_to :payment, class_name: 'Spree::Payment'
4
8
 
5
9
  def display_amount
@@ -74,7 +74,7 @@ module Spree
74
74
  handle_action(action, :credit, auth_code)
75
75
  end
76
76
 
77
- def cancel(auth_code)
77
+ def cancel(auth_code, _payment = nil)
78
78
  store_credit_event = StoreCreditEvent.find_by(authorization_code: auth_code,
79
79
  action: Spree::StoreCredit::CAPTURE_ACTION)
80
80
  store_credit = store_credit_event.try(:store_credit)
@@ -5,6 +5,9 @@ module Spree
5
5
 
6
6
  include MultiStoreResource
7
7
  include Spree::Metadata
8
+ if defined?(Spree::Security::PaymentMethods)
9
+ include Spree::Security::PaymentMethods
10
+ end
8
11
 
9
12
  DISPLAY = [:both, :front_end, :back_end].freeze
10
13
 
@@ -0,0 +1,10 @@
1
+ module Spree
2
+ class PaymentSource < Spree::Base
3
+ include Metadata
4
+
5
+ belongs_to :payment_method, class_name: 'Spree::PaymentMethod'
6
+ belongs_to :user, class_name: 'Spree::User', optional: true
7
+
8
+ validates_uniqueness_of :gateway_payment_profile_id, scope: :type
9
+ end
10
+ end