spree_core 4.4.0 → 4.6.0

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 (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
@@ -1,5 +1,15 @@
1
1
  module Spree
2
2
  module DependenciesHelper
3
+ def self.included(base)
4
+ injection_points = base::INJECTION_POINTS_WITH_DEFAULTS.keys.freeze
5
+ base.const_set(:INJECTION_POINTS, injection_points)
6
+ base.attr_accessor(*injection_points)
7
+ end
8
+
9
+ def initialize
10
+ set_default_values
11
+ end
12
+
3
13
  def current_values
4
14
  values = []
5
15
  self.class::INJECTION_POINTS.each do |injection_point|
@@ -7,5 +17,14 @@ module Spree
7
17
  end
8
18
  values
9
19
  end
20
+
21
+ private
22
+
23
+ def set_default_values
24
+ self.class::INJECTION_POINTS_WITH_DEFAULTS.each do |injection_point, default_value|
25
+ value = default_value.respond_to?(:call) ? default_value.call : default_value
26
+ instance_variable_set("@#{injection_point}", value)
27
+ end
28
+ end
10
29
  end
11
30
  end
@@ -1,3 +1,6 @@
1
+ require_relative 'dependencies'
2
+ require_relative 'configuration'
3
+
1
4
  module Spree
2
5
  module Core
3
6
  class Engine < ::Rails::Engine
@@ -8,7 +11,8 @@ module Spree
8
11
  :adjusters,
9
12
  :stock_splitters,
10
13
  :promotions,
11
- :line_item_comparison_hooks)
14
+ :line_item_comparison_hooks,
15
+ :data_feed_types)
12
16
  SpreeCalculators = Struct.new(:shipping_methods, :tax_rates, :promotion_actions_create_adjustments, :promotion_actions_create_item_adjustments)
13
17
  PromoEnvironment = Struct.new(:rules, :actions)
14
18
  isolate_namespace Spree
@@ -19,13 +23,44 @@ module Spree
19
23
  end
20
24
 
21
25
  initializer 'spree.environment', before: :load_config_initializers do |app|
22
- app.config.spree = Environment.new(SpreeCalculators.new, Spree::AppConfiguration.new, Spree::AppDependencies.new)
26
+ app.config.spree = Environment.new(SpreeCalculators.new, Spree::Core::Configuration.new, Spree::Core::Dependencies.new)
27
+ app.config.active_record.yaml_column_permitted_classes = [Symbol, BigDecimal]
23
28
  Spree::Config = app.config.spree.preferences
24
29
  Spree::Dependencies = app.config.spree.dependencies
25
30
  end
26
31
 
27
- initializer 'spree.register.calculators' do |app|
28
- app.config.spree.calculators.shipping_methods = [
32
+ initializer 'spree.register.calculators', before: :after_initialize do |app|
33
+ end
34
+
35
+ initializer 'spree.register.stock_splitters', before: :load_config_initializers do |app|
36
+ end
37
+
38
+ initializer 'spree.register.line_item_comparison_hooks', before: :load_config_initializers do |app|
39
+ app.config.spree.line_item_comparison_hooks = Set.new
40
+ end
41
+
42
+ initializer 'spree.register.payment_methods', after: 'acts_as_list.insert_into_active_record' do |app|
43
+ end
44
+
45
+ initializer 'spree.register.adjustable_adjusters' do |app|
46
+ end
47
+
48
+ # We need to define promotions rules here so extensions and existing apps
49
+ # can add their custom classes on their initializer files
50
+ initializer 'spree.promo.environment' do |app|
51
+ app.config.spree.promotions = PromoEnvironment.new
52
+ app.config.spree.promotions.rules = []
53
+ end
54
+
55
+ initializer 'spree.promo.register.promotion.calculators' do |app|
56
+ end
57
+
58
+ # Promotion rules need to be evaluated on after initialize otherwise
59
+ # Spree.user_class would be nil and users might experience errors related
60
+ # to malformed model associations (Spree.user_class is only defined on
61
+ # the app initializer)
62
+ config.after_initialize do
63
+ Rails.application.config.spree.calculators.shipping_methods = [
29
64
  Spree::Calculator::Shipping::FlatPercentItemTotal,
30
65
  Spree::Calculator::Shipping::FlatRate,
31
66
  Spree::Calculator::Shipping::FlexiRate,
@@ -34,48 +69,29 @@ module Spree
34
69
  Spree::Calculator::Shipping::DigitalDelivery,
35
70
  ]
36
71
 
37
- app.config.spree.calculators.tax_rates = [
72
+ Rails.application.config.spree.calculators.tax_rates = [
38
73
  Spree::Calculator::DefaultTax
39
74
  ]
40
- end
41
75
 
42
- initializer 'spree.register.stock_splitters', before: :load_config_initializers do |app|
43
- app.config.spree.stock_splitters = [
76
+ Rails.application.config.spree.stock_splitters = [
44
77
  Spree::Stock::Splitter::ShippingCategory,
45
78
  Spree::Stock::Splitter::Backordered,
46
79
  Spree::Stock::Splitter::Digital
47
80
  ]
48
- end
49
-
50
- initializer 'spree.register.line_item_comparison_hooks', before: :load_config_initializers do |app|
51
- app.config.spree.line_item_comparison_hooks = Set.new
52
- end
53
81
 
54
- initializer 'spree.register.payment_methods', after: 'acts_as_list.insert_into_active_record' do |app|
55
- app.config.spree.payment_methods = [
82
+ Rails.application.config.spree.payment_methods = [
56
83
  Spree::Gateway::Bogus,
57
84
  Spree::Gateway::BogusSimple,
58
85
  Spree::PaymentMethod::Check,
59
86
  Spree::PaymentMethod::StoreCredit
60
87
  ]
61
- end
62
88
 
63
- initializer 'spree.register.adjustable_adjusters' do |app|
64
- app.config.spree.adjusters = [
89
+ Rails.application.config.spree.adjusters = [
65
90
  Spree::Adjustable::Adjuster::Promotion,
66
91
  Spree::Adjustable::Adjuster::Tax
67
92
  ]
68
- end
69
93
 
70
- # We need to define promotions rules here so extensions and existing apps
71
- # can add their custom classes on their initializer files
72
- initializer 'spree.promo.environment' do |app|
73
- app.config.spree.promotions = PromoEnvironment.new
74
- app.config.spree.promotions.rules = []
75
- end
76
-
77
- initializer 'spree.promo.register.promotion.calculators' do |app|
78
- app.config.spree.calculators.promotion_actions_create_adjustments = [
94
+ Rails.application.config.spree.calculators.promotion_actions_create_adjustments = [
79
95
  Spree::Calculator::FlatPercentItemTotal,
80
96
  Spree::Calculator::FlatRate,
81
97
  Spree::Calculator::FlexiRate,
@@ -83,18 +99,12 @@ module Spree
83
99
  Spree::Calculator::TieredFlatRate
84
100
  ]
85
101
 
86
- app.config.spree.calculators.promotion_actions_create_item_adjustments = [
102
+ Rails.application.config.spree.calculators.promotion_actions_create_item_adjustments = [
87
103
  Spree::Calculator::PercentOnLineItem,
88
104
  Spree::Calculator::FlatRate,
89
105
  Spree::Calculator::FlexiRate
90
106
  ]
91
- end
92
107
 
93
- # Promotion rules need to be evaluated on after initialize otherwise
94
- # Spree.user_class would be nil and users might experience errors related
95
- # to malformed model associations (Spree.user_class is only defined on
96
- # the app initializer)
97
- config.after_initialize do
98
108
  Rails.application.config.spree.promotions.rules.concat [
99
109
  Spree::Promotion::Rules::ItemTotal,
100
110
  Spree::Promotion::Rules::Product,
@@ -106,15 +116,20 @@ module Spree
106
116
  Spree::Promotion::Rules::OptionValue,
107
117
  Spree::Promotion::Rules::Country
108
118
  ]
109
- end
110
119
 
111
- initializer 'spree.promo.register.promotions.actions' do |app|
112
- app.config.spree.promotions.actions = [
120
+ Rails.application.config.spree.promotions.actions = [
113
121
  Promotion::Actions::CreateAdjustment,
114
122
  Promotion::Actions::CreateItemAdjustments,
115
123
  Promotion::Actions::CreateLineItems,
116
124
  Promotion::Actions::FreeShipping
117
125
  ]
126
+
127
+ Rails.application.config.spree.data_feed_types = [
128
+ Spree::DataFeed::Google
129
+ ]
130
+ end
131
+
132
+ initializer 'spree.promo.register.promotions.actions' do |app|
118
133
  end
119
134
 
120
135
  # filter sensitive information during logging
@@ -20,6 +20,9 @@
20
20
  # a.preferred_color
21
21
  #
22
22
  #
23
+
24
+ require 'spree/core/preferences/preferable'
25
+
23
26
  module Spree::Preferences
24
27
  class Configuration
25
28
  include Spree::Preferences::Preferable
@@ -31,6 +31,9 @@
31
31
  #
32
32
  # # Save the changes. All handled by activerecord
33
33
  # s.save!
34
+
35
+ require 'spree/core/preferences/preferable_class_methods'
36
+
34
37
  module Spree::Preferences::Preferable
35
38
  extend ActiveSupport::Concern
36
39
 
@@ -26,7 +26,7 @@ module Spree
26
26
 
27
27
  def duplicate_product
28
28
  product.dup.tap do |new_product|
29
- new_product.name = "COPY OF #{product.name}"
29
+ product.translations.each { |t| new_product.send(:name=, "COPY OF #{t.name}", locale: t.locale) }
30
30
  new_product.taxons = product.taxons
31
31
  new_product.stores = product.stores
32
32
  new_product.created_at = nil
@@ -98,18 +98,21 @@ module Spree
98
98
  conds.each do |new_scope|
99
99
  scope = scope.or(new_scope)
100
100
  end
101
- Spree::Product.with_property('brand').where(scope)
101
+ Product.with_property('brand').join_translation_table(ProductProperty).where(scope)
102
102
  end
103
103
 
104
104
  def self.brand_filter
105
105
  brand_property = Spree::Property.find_by(name: 'brand')
106
106
  brands = brand_property ? Spree::ProductProperty.where(property_id: brand_property.id).pluck(:value).uniq.map(&:to_s) : []
107
- pp = Spree::ProductProperty.arel_table
108
- conds = Hash[*brands.map { |b| [b, pp[:value].eq(b)] }.flatten]
107
+
108
+ conditions = brands.map do |brand|
109
+ [brand, { ProductProperty.translation_table_alias => { value: brand } }]
110
+ end.to_h
111
+
109
112
  {
110
113
  name: I18n.t('spree.taxonomy_brands_name'),
111
114
  scope: :brand_any,
112
- conds: conds,
115
+ conds: conditions,
113
116
  labels: brands.sort.map { |k| [k, k] }
114
117
  }
115
118
  end
@@ -30,7 +30,13 @@ module Spree
30
30
  def extended_base_scope
31
31
  base_scope = current_store.products.spree_base_scopes
32
32
  base_scope = get_products_conditions_for(base_scope, keywords)
33
- base_scope = Spree::Dependencies.products_finder.constantize.new(
33
+ base_scope = Spree::Dependencies.products_finder.constantize.new(**product_finder_params(base_scope)).execute
34
+ base_scope = add_search_scopes(base_scope)
35
+ add_eagerload_scopes(base_scope)
36
+ end
37
+
38
+ def product_finder_params(base_scope)
39
+ {
34
40
  scope: base_scope,
35
41
  params: {
36
42
  store: current_store,
@@ -43,9 +49,7 @@ module Spree
43
49
  },
44
50
  sort_by: sort_by
45
51
  }
46
- ).execute
47
- base_scope = add_search_scopes(base_scope)
48
- add_eagerload_scopes(base_scope)
52
+ }
49
53
  end
50
54
 
51
55
  def add_eagerload_scopes(scope)
@@ -79,7 +83,7 @@ module Spree
79
83
  # method should return new scope based on base_scope
80
84
  def get_products_conditions_for(base_scope, query)
81
85
  unless query.blank?
82
- base_scope = base_scope.like_any([:name, :description], [query])
86
+ base_scope = base_scope.i18n { name.matches("%#{query}%").or(description.matches("%#{query}%")) }
83
87
  end
84
88
  base_scope
85
89
  end
@@ -101,7 +105,7 @@ module Spree
101
105
  high_price = Monetize.parse(price_param.remove("#{less_than_string} ")).to_i
102
106
  else
103
107
  low_price, high_price = Monetize.parse_collection(price_param).map(&:to_i)
104
- high_price = Float::INFINITY if high_price&.zero?
108
+ high_price = BigDecimal::INFINITY if high_price&.zero?
105
109
  end
106
110
 
107
111
  "#{low_price},#{high_price}"
@@ -1,5 +1,5 @@
1
1
  module Spree
2
- VERSION = '4.4.0'.freeze
2
+ VERSION = '4.6.0'.freeze
3
3
 
4
4
  def self.version
5
5
  VERSION
data/lib/spree/core.rb CHANGED
@@ -13,8 +13,8 @@ require 'cancan'
13
13
  require 'friendly_id'
14
14
  require 'kaminari'
15
15
  require 'monetize'
16
+ require 'mobility'
16
17
  require 'paranoia'
17
- require 'mini_magick'
18
18
  require 'ransack'
19
19
  require 'state_machines-activerecord'
20
20
  require 'active_storage_validations'
@@ -25,7 +25,8 @@ require 'activerecord-typedstore'
25
25
  StateMachines::Machine.ignore_method_conflicts = true
26
26
 
27
27
  module Spree
28
- mattr_accessor :user_class, :admin_user_class, :private_storage_service_name
28
+ mattr_accessor :user_class, :admin_user_class, :private_storage_service_name,
29
+ :public_storage_service_name, :cdn_host, :searcher_class
29
30
 
30
31
  def self.user_class(constantize: true)
31
32
  if @@user_class.is_a?(Class)
@@ -55,6 +56,26 @@ module Spree
55
56
  end
56
57
  end
57
58
 
59
+ def self.public_storage_service_name
60
+ if @@public_storage_service_name
61
+ if @@public_storage_service_name.is_a?(String) || @@public_storage_service_name.is_a?(Symbol)
62
+ @@public_storage_service_name.to_sym
63
+ else
64
+ raise 'Spree.public_storage_service_name MUST be a String or Symbol object.'
65
+ end
66
+ end
67
+ end
68
+
69
+ def self.searcher_class(constantize: true)
70
+ @@searcher_class ||= 'Spree::Core::Search::Base'
71
+
72
+ if @@searcher_class.is_a?(Class)
73
+ raise 'Spree.searcher_class MUST be a String or Symbol object, not a Class object.'
74
+ elsif @@searcher_class.is_a?(String) || @@searcher_class.is_a?(Symbol)
75
+ constantize ? @@searcher_class.to_s.constantize : @@searcher_class.to_s
76
+ end
77
+ end
78
+
58
79
  # Used to configure Spree.
59
80
  #
60
81
  # Example:
@@ -96,6 +117,7 @@ require 'spree/core/version'
96
117
 
97
118
  require 'spree/core/number_generator'
98
119
  require 'spree/migrations'
120
+ require 'spree/translation_migrations'
99
121
  require 'spree/core/engine'
100
122
 
101
123
  require 'spree/i18n'
@@ -105,9 +127,6 @@ require 'spree/permitted_attributes'
105
127
  require 'spree/service_module'
106
128
  require 'spree/database_type_utilities'
107
129
 
108
- require 'spree/core/dependencies_helper'
109
- require 'spree/core/app_dependencies'
110
-
111
130
  require 'spree/core/importer'
112
131
  require 'spree/core/query_filters'
113
132
  require 'spree/core/product_duplicator'
@@ -119,3 +138,6 @@ require 'spree/core/controller_helpers/store'
119
138
  require 'spree/core/controller_helpers/strong_parameters'
120
139
  require 'spree/core/controller_helpers/locale'
121
140
  require 'spree/core/controller_helpers/currency'
141
+
142
+ require 'spree/core/preferences/store'
143
+ require 'spree/core/preferences/scoped_store'
@@ -89,7 +89,7 @@ module Spree
89
89
  @@product_properties_attributes = [:property_name, :value, :position]
90
90
 
91
91
  @@product_attributes = [
92
- :name, :description, :available_on, :discontinue_on, :permalink, :meta_description,
92
+ :name, :description, :available_on, :make_active_at, :discontinue_on, :permalink, :meta_description,
93
93
  :meta_keywords, :price, :sku, :deleted_at, :prototype_id,
94
94
  :option_values_hash, :weight, :height, :width, :depth,
95
95
  :shipping_category_id, :tax_category_id,
@@ -126,14 +126,15 @@ module Spree
126
126
  :quantity, :stock_item, :stock_item_id, :originator, :action
127
127
  ]
128
128
 
129
- @@store_attributes = [:name, :url, :seo_title, :code, :meta_keywords, :logo,
129
+ @@store_attributes = [:name, :url, :seo_title, :code, :meta_keywords,
130
130
  :meta_description, :default_currency, :mail_from_address,
131
131
  :customer_support_email, :facebook, :twitter, :instagram,
132
132
  :description, :address, :contact_phone, :supported_locales,
133
133
  :default_locale, :default_country_id, :supported_currencies,
134
- :new_order_notifications_email, :mailer_logo, :favicon_image,
135
- :checkout_zone_id, :seo_robots, :digital_asset_authorized_clicks,
136
- :digital_asset_authorized_days, :limit_digital_download_count, :limit_digital_download_days]
134
+ :new_order_notifications_email, :checkout_zone_id, :seo_robots,
135
+ :digital_asset_authorized_clicks, :digital_asset_authorized_days,
136
+ :limit_digital_download_count, :limit_digital_download_days, :digital_asset_link_expire_time,
137
+ { mailer_logo_attributes: {}, favicon_image_attributes: {}, logo_attributes: {} }]
137
138
 
138
139
  @@store_credit_attributes = %i[amount currency category_id memo]
139
140
 
@@ -145,13 +146,14 @@ module Spree
145
146
  ]
146
147
 
147
148
  # TODO: Should probably use something like Spree.user_class.attributes
148
- @@user_attributes = [:email, :bill_address_id, :ship_address_id, :password, :password_confirmation, { public_metadata: {}, private_metadata: {} }]
149
+ @@user_attributes = [:email, :bill_address_id, :ship_address_id, :password, :first_name, :last_name,
150
+ :password_confirmation, { public_metadata: {}, private_metadata: {} }, :selected_locale]
149
151
 
150
152
  @@variant_attributes = [
151
153
  :name, :presentation, :cost_price, :discontinue_on, :lock_version,
152
154
  :position, :track_inventory,
153
155
  :product_id, :product, :option_values_attributes, :price, :compare_at_price,
154
- :weight, :height, :width, :depth, :sku, :cost_currency,
156
+ :weight, :height, :width, :depth, :sku, :barcode, :cost_currency,
155
157
  { options: [:name, :value], option_value_ids: [] }
156
158
  ]
157
159
 
@@ -44,6 +44,7 @@ namespace :common do
44
44
  unless ['spree/api', 'spree/core', 'spree/sample', 'spree/emails'].include?(ENV['LIB_NAME'])
45
45
  puts 'Setting up node environment'
46
46
  system('bin/rails javascript:install:esbuild')
47
+ system('bin/rails turbo:install')
47
48
  end
48
49
 
49
50
  begin
@@ -0,0 +1,9 @@
1
+ FactoryBot.define do
2
+ factory :favicon_image, class: Spree::StoreFaviconImage do
3
+ transient do
4
+ filepath { Spree::Core::Engine.root.join('spec', 'fixtures', 'favicon.ico') }
5
+ end
6
+
7
+ attachment { Rack::Test::UploadedFile.new(filepath) }
8
+ end
9
+ end
@@ -0,0 +1,8 @@
1
+ FactoryBot.define do
2
+ factory :google_data_feed, class: Spree::DataFeed::Google do
3
+ id { 1 }
4
+ active { true }
5
+ store { create(:store) }
6
+ name { 'test' }
7
+ end
8
+ end
@@ -1,7 +1,9 @@
1
1
  FactoryBot.define do
2
2
  factory :icon, class: Spree::Icon do
3
3
  before(:create) do |icon|
4
- icon.attachment.attach(io: File.new(Spree::Core::Engine.root + 'spec/fixtures' + 'thinking-cat.jpg'), filename: 'thinking-cat.jpg')
4
+ if icon.respond_to? :attachment
5
+ icon.attachment.attach(io: File.new(Spree::Core::Engine.root + 'spec/fixtures' + 'thinking-cat.jpg'), filename: 'thinking-cat.jpg')
6
+ end
5
7
  end
6
8
  end
7
9
  end
@@ -1,7 +1,9 @@
1
1
  FactoryBot.define do
2
2
  factory :image, class: Spree::Image do
3
3
  before(:create) do |image|
4
- image.attachment.attach(io: File.new(Spree::Core::Engine.root + 'spec/fixtures' + 'thinking-cat.jpg'), filename: 'thinking-cat.jpg')
4
+ if image.class.method_defined?(:attachment)
5
+ image.attachment.attach(io: File.new(Spree::Core::Engine.root + 'spec/fixtures' + 'thinking-cat.jpg'), filename: 'thinking-cat.jpg')
6
+ end
5
7
  end
6
8
  end
7
9
  end
@@ -2,7 +2,7 @@ FactoryBot.define do
2
2
  factory :menu_item, class: Spree::MenuItem do
3
3
  sequence(:name) { |n| "Link no. #{n} To Somewhere" }
4
4
  item_type { 'Link' }
5
- linked_resource_type { 'URL' }
5
+ linked_resource_type { 'Spree::Linkable::Uri' }
6
6
 
7
7
  menu
8
8
  icon
@@ -55,7 +55,8 @@ FactoryBot.define do
55
55
  order.line_items.reload
56
56
  end
57
57
 
58
- create(:shipment, order: order, cost: evaluator.shipment_cost)
58
+ stock_location = order.line_items&.first&.variant&.stock_items&.first&.stock_location || create(:stock_location)
59
+ create(:shipment, order: order, cost: evaluator.shipment_cost, stock_location: stock_location)
59
60
  order.shipments.reload
60
61
 
61
62
  order.update_with_updater!
@@ -1,13 +1,15 @@
1
1
  FactoryBot.define do
2
2
  factory :base_product, class: Spree::Product do
3
- sequence(:name) { |n| "Product ##{n} - #{Kernel.rand(9999)}" }
3
+ sequence(:name) { |n| "Product #{n}#{Kernel.rand(9999)}" }
4
4
  description { generate(:random_description) }
5
5
  price { 19.99 }
6
6
  cost_price { 17.00 }
7
7
  sku { generate(:sku) }
8
8
  available_on { 1.year.ago }
9
+ make_active_at { 1.year.ago }
9
10
  deleted_at { nil }
10
11
  shipping_category { |r| Spree::ShippingCategory.first || r.association(:shipping_category) }
12
+ status { 'active' }
11
13
 
12
14
  # ensure stock item will be created for this products master
13
15
  # also attach this product to the default store if no stores are passed in
@@ -21,6 +23,9 @@ FactoryBot.define do
21
23
  product.stores << [store]
22
24
  end
23
25
  end
26
+ after(:create) do |product|
27
+ Spree::StockLocation.all.each { |stock_location| stock_location.propagate_variant(product.master) unless stock_location.stock_items.exists?(variant: product.master) }
28
+ end
24
29
 
25
30
  factory :custom_product do
26
31
  name { 'Custom Product' }
@@ -47,6 +52,12 @@ FactoryBot.define do
47
52
  factory :product_with_option_types do
48
53
  after(:create) { |product| create(:product_option_type, product: product) }
49
54
  end
55
+ factory :product_with_properties do
56
+ after(:create) do |product|
57
+ create(:property, :brand, id: 10)
58
+ create(:product_property, product: product, property_id: 10, value: 'Epsilon')
59
+ end
60
+ end
50
61
  end
51
62
  end
52
63
  end
@@ -1,6 +1,7 @@
1
1
  FactoryBot.define do
2
2
  factory :product_property, class: Spree::ProductProperty do
3
3
  product { create(:product, stores: [create(:store)]) }
4
+ value { "val-#{rand(50)}" }
4
5
  property
5
6
  end
6
7
  end
@@ -0,0 +1,6 @@
1
+ FactoryBot.define do
2
+ factory :product_translation, class: Spree::Product::Translation do
3
+ sequence(:name) { |n| "Product #{n}" }
4
+ description { generate(:random_description) }
5
+ end
6
+ end
@@ -15,7 +15,7 @@ FactoryBot.define do
15
15
  end
16
16
 
17
17
  factory :refund_reason, class: Spree::RefundReason do
18
- sequence(:name) { |n| "Refund for return ##{n}" }
18
+ sequence(:name) { |n| "Refund for return #{n}" }
19
19
  active { true }
20
20
  mutable { false }
21
21
  end
@@ -14,7 +14,7 @@ FactoryBot.define do
14
14
  end
15
15
 
16
16
  factory :return_authorization_reason, class: Spree::ReturnAuthorizationReason do
17
- sequence(:name) { |n| "Defect ##{n}" }
17
+ sequence(:name) { |n| "Defect #{n}" }
18
18
  active { true }
19
19
  mutable { false }
20
20
  end
@@ -1,6 +1,6 @@
1
1
  FactoryBot.define do
2
2
  factory :role, class: Spree::Role do
3
- sequence(:name) { |n| "Role ##{n}" }
3
+ sequence(:name) { |n| "Role #{n}" }
4
4
 
5
5
  factory :admin_role do
6
6
  name { 'admin' }
@@ -1,5 +1,5 @@
1
1
  FactoryBot.define do
2
2
  factory :shipping_category, class: Spree::ShippingCategory do
3
- sequence(:name) { |n| "ShippingCategory ##{n}" }
3
+ sequence(:name) { |n| "ShippingCategory #{n}" }
4
4
  end
5
5
  end
@@ -7,6 +7,7 @@ FactoryBot.define do
7
7
  phone { '(202) 456-1111' }
8
8
  active { true }
9
9
  backorderable_default { true }
10
+ propagate_all_variants { false }
10
11
 
11
12
  country { |stock_location| Spree::Country.first || stock_location.association(:country) }
12
13
  state do |stock_location|
@@ -21,8 +22,8 @@ FactoryBot.define do
21
22
  product_1 = create(:product, stores: [store])
22
23
  product_2 = create(:product, stores: [store])
23
24
 
24
- stock_location.stock_items.where(variant_id: product_1.master.id).first.adjust_count_on_hand(10)
25
- stock_location.stock_items.where(variant_id: product_2.master.id).first.adjust_count_on_hand(20)
25
+ stock_location.stock_item_or_create(product_1.master).adjust_count_on_hand(10)
26
+ stock_location.stock_item_or_create(product_2.master).adjust_count_on_hand(20)
26
27
  end
27
28
  end
28
29
  end
@@ -12,6 +12,7 @@ FactoryBot.define do
12
12
  facebook { 'spreecommerce' }
13
13
  twitter { 'spreecommerce' }
14
14
  instagram { 'spreecommerce' }
15
+ meta_description { 'Sample store description.' }
15
16
 
16
17
  trait :with_favicon do
17
18
  transient do
@@ -20,7 +21,7 @@ FactoryBot.define do
20
21
  end
21
22
 
22
23
  favicon_image do
23
- Rack::Test::UploadedFile.new(filepath, image_type)
24
+ create(:favicon_image, attachment: Rack::Test::UploadedFile.new(filepath, image_type))
24
25
  end
25
26
  end
26
27
  end
@@ -1,7 +1,9 @@
1
1
  FactoryBot.define do
2
2
  factory :taxon_image, class: Spree::TaxonImage do
3
3
  before(:create) do |taxon_image|
4
- taxon_image.attachment.attach(io: File.new(Spree::Core::Engine.root + 'spec/fixtures/thinking-cat.jpg'), filename: 'thinking-cat.jpg')
4
+ if taxon_image.class.method_defined?(:attachment)
5
+ taxon_image.attachment.attach(io: File.new(Spree::Core::Engine.root + 'spec/fixtures/thinking-cat.jpg'), filename: 'thinking-cat.jpg')
6
+ end
5
7
  end
6
8
  end
7
9
  end
@@ -9,6 +9,10 @@ FactoryBot.define do
9
9
  password { 'secret' }
10
10
  password_confirmation { password }
11
11
  authentication_token { generate(:user_authentication_token) } if Spree.user_class.attribute_method? :authentication_token
12
+
13
+ first_name { FFaker::Name.first_name }
14
+ last_name { FFaker::Name.last_name }
15
+
12
16
  public_metadata { {} }
13
17
  private_metadata { {} }
14
18