spree_core 4.5.5 → 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 (109) 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 +20 -12
  5. data/app/finders/spree/taxons/find.rb +10 -7
  6. data/app/helpers/spree/base_helper.rb +2 -2
  7. data/app/models/concerns/spree/product_scopes.rb +27 -23
  8. data/app/models/concerns/spree/translatable_resource.rb +25 -0
  9. data/app/models/concerns/spree/translatable_resource_scopes.rb +24 -0
  10. data/app/models/concerns/spree/translatable_resource_slug.rb +17 -0
  11. data/app/models/spree/address.rb +1 -1
  12. data/app/models/spree/asset.rb +1 -1
  13. data/app/models/spree/base.rb +1 -0
  14. data/app/models/spree/calculator/default_tax.rb +1 -1
  15. data/app/models/spree/cms_page.rb +1 -1
  16. data/app/models/spree/cms_section.rb +1 -1
  17. data/app/models/spree/credit_card.rb +1 -1
  18. data/app/models/spree/customer_return.rb +2 -2
  19. data/app/models/spree/data_feed/google.rb +15 -0
  20. data/app/models/spree/data_feed.rb +40 -0
  21. data/app/models/spree/line_item.rb +1 -1
  22. data/app/models/spree/option_type.rb +5 -1
  23. data/app/models/spree/option_value.rb +5 -1
  24. data/app/models/spree/order/store_credit.rb +0 -8
  25. data/app/models/spree/order.rb +3 -3
  26. data/app/models/spree/payment.rb +3 -3
  27. data/app/models/spree/payment_method.rb +1 -1
  28. data/app/models/spree/payment_source.rb +1 -1
  29. data/app/models/spree/price.rb +1 -1
  30. data/app/models/spree/product.rb +44 -13
  31. data/app/models/spree/product_property.rb +12 -3
  32. data/app/models/spree/promotion.rb +2 -2
  33. data/app/models/spree/property.rb +8 -2
  34. data/app/models/spree/prototype.rb +1 -1
  35. data/app/models/spree/refund.rb +1 -1
  36. data/app/models/spree/reimbursement.rb +1 -1
  37. data/app/models/spree/return_authorization.rb +1 -1
  38. data/app/models/spree/shipment.rb +5 -5
  39. data/app/models/spree/shipping_method.rb +1 -1
  40. data/app/models/spree/stock/estimator.rb +1 -1
  41. data/app/models/spree/stock_item.rb +1 -1
  42. data/app/models/spree/stock_transfer.rb +3 -3
  43. data/app/models/spree/store.rb +20 -1
  44. data/app/models/spree/store_credit.rb +1 -1
  45. data/app/models/spree/taxon.rb +23 -7
  46. data/app/models/spree/taxonomy.rb +5 -1
  47. data/app/models/spree/variant.rb +6 -9
  48. data/app/services/spree/data_feeds/google/optional_attributes.rb +23 -0
  49. data/app/services/spree/data_feeds/google/optional_sub_attributes.rb +21 -0
  50. data/app/services/spree/data_feeds/google/products_list.rb +14 -0
  51. data/app/services/spree/data_feeds/google/required_attributes.rb +67 -0
  52. data/app/services/spree/data_feeds/google/rss.rb +107 -0
  53. data/app/sorters/spree/products/sort.rb +23 -0
  54. data/brakeman.ignore +326 -18
  55. data/config/initializers/friendly_id.rb +2 -0
  56. data/config/initializers/mobility.rb +18 -0
  57. data/config/locales/en.yml +1 -0
  58. data/db/migrate/20220706112554_create_product_name_and_description_translations_for_mobility_table_backend.rb +27 -0
  59. data/db/migrate/20220715083542_create_spree_product_translations_for_mobility.rb +7 -0
  60. data/db/migrate/20220715120222_change_product_name_null_to_true.rb +5 -0
  61. data/db/migrate/20220718100743_create_spree_taxon_name_and_description_translations_for_mobility_table_backend.rb +27 -0
  62. data/db/migrate/20220718100948_change_taxon_name_null_to_true.rb +5 -0
  63. data/db/migrate/20220802070609_add_locale_to_friendly_id_slugs.rb +11 -0
  64. data/db/migrate/20220802073225_create_spree_product_slug_translations_for_mobility_table_backend.rb +5 -0
  65. data/db/migrate/20220804073928_transfer_data_to_translatable_tables.rb +66 -0
  66. data/db/migrate/20221215151408_add_selected_locale_to_spree_users.rb +8 -0
  67. data/db/migrate/20221219123957_add_deleted_at_to_product_translations.rb +6 -0
  68. data/db/migrate/20221220133432_add_uniqueness_constraint_to_product_translations.rb +5 -0
  69. data/db/migrate/20221229132350_create_spree_data_feed_settings.rb +14 -0
  70. data/db/migrate/20230103144439_create_option_type_translations.rb +26 -0
  71. data/db/migrate/20230103151034_create_option_value_translations.rb +26 -0
  72. data/db/migrate/20230109084253_create_product_property_translations.rb +25 -0
  73. data/db/migrate/20230109094907_transfer_options_data_to_translatable_tables.rb +58 -0
  74. data/db/migrate/20230109105943_create_property_translations.rb +26 -0
  75. data/db/migrate/20230109110840_transfer_property_data_to_translatable_tables.rb +59 -0
  76. data/db/migrate/20230110142344_backfill_friendly_id_slug_locale.rb +15 -0
  77. data/db/migrate/20230111121534_add_additional_taxon_translation_fields.rb +8 -0
  78. data/db/migrate/20230111122511_transfer_product_and_taxon_data_to_translatable_tables.rb +82 -0
  79. data/db/migrate/20230117115531_create_taxonomy_translations.rb +24 -0
  80. data/db/migrate/20230117120430_allow_null_taxonomy_name.rb +5 -0
  81. data/db/migrate/20230117121303_transfer_taxonomy_data_to_translatable_tables.rb +11 -0
  82. data/db/migrate/20230210142732_create_store_translations.rb +50 -0
  83. data/db/migrate/20230210142849_transfer_store_data_to_translatable_tables.rb +11 -0
  84. data/db/migrate/20230210230434_add_deleted_at_to_store_translations.rb +6 -0
  85. data/db/migrate/20230415155958_rename_data_feed_settings_table.rb +5 -0
  86. data/db/migrate/20230415160828_rename_data_feed_table_columns.rb +7 -0
  87. data/db/migrate/20230415161226_add_indexes_to_data_feeds_table.rb +5 -0
  88. data/db/migrate/20230512094803_rename_data_feeds_column_provider_to_type.rb +5 -0
  89. data/db/migrate/20230514162157_add_index_on_locale_and_permalink_to_spree_taxons.rb +5 -0
  90. data/lib/spree/core/configuration.rb +1 -0
  91. data/lib/spree/core/controller_helpers/locale.rb +26 -2
  92. data/lib/spree/core/dependencies.rb +70 -94
  93. data/lib/spree/core/dependencies_helper.rb +19 -0
  94. data/lib/spree/core/engine.rb +6 -1
  95. data/lib/spree/core/product_duplicator.rb +1 -1
  96. data/lib/spree/core/product_filters.rb +7 -4
  97. data/lib/spree/core/search/base.rb +1 -1
  98. data/lib/spree/core/version.rb +1 -1
  99. data/lib/spree/core.rb +2 -0
  100. data/lib/spree/permitted_attributes.rb +1 -1
  101. data/lib/spree/testing_support/factories/google_data_feed_factory.rb +8 -0
  102. data/lib/spree/testing_support/factories/product_factory.rb +6 -0
  103. data/lib/spree/testing_support/factories/product_translation_factory.rb +6 -0
  104. data/lib/spree/testing_support/factories/store_factory.rb +1 -0
  105. data/lib/spree/testing_support/factories/variant_factory.rb +4 -0
  106. data/lib/spree/translation_migrations.rb +40 -0
  107. data/spree_core.gemspec +3 -0
  108. metadata +93 -6
  109. data/app/models/spree/order_contents.rb +0 -31
@@ -3,128 +3,104 @@ require_relative 'dependencies_helper'
3
3
  module Spree
4
4
  module Core
5
5
  class Dependencies
6
- include Spree::DependenciesHelper
6
+ INJECTION_POINTS_WITH_DEFAULTS = {
7
+ # ability
8
+ ability_class: 'Spree::Ability',
7
9
 
8
- INJECTION_POINTS = [
9
- :ability_class,
10
- :cart_create_service, :cart_add_item_service, :cart_remove_item_service,
11
- :cart_remove_line_item_service, :cart_set_item_quantity_service, :cart_recalculate_service,
12
- :cms_page_finder, :cart_update_service, :checkout_next_service, :checkout_advance_service, :checkout_update_service,
13
- :checkout_complete_service, :checkout_add_store_credit_service, :checkout_remove_store_credit_service, :checkout_get_shipping_rates_service,
14
- :coupon_handler, :menu_finder, :country_finder, :current_order_finder, :credit_card_finder,
15
- :completed_order_finder, :order_sorter, :cart_compare_line_items_service, :collection_paginator, :products_sorter,
16
- :products_finder, :taxon_finder, :line_item_by_variant_finder, :cart_estimate_shipping_rates_service,
17
- :account_create_address_service, :account_update_address_service, :account_create_service, :account_update_service,
18
- :address_finder, :collection_sorter, :error_handler, :current_store_finder, :cart_empty_service, :cart_destroy_service,
19
- :classification_reposition_service, :credit_cards_destroy_service, :cart_associate_service, :cart_change_currency_service,
20
- :line_item_create_service, :line_item_update_service, :line_item_destroy_service,
21
- :order_approve_service, :order_cancel_service, :shipment_change_state_service, :shipment_update_service,
22
- :shipment_create_service, :shipment_add_item_service, :shipment_remove_item_service,
23
- :payment_create_service, :address_create_service, :address_update_service,
24
- :checkout_select_shipping_method_service
25
- ].freeze
26
-
27
- attr_accessor *INJECTION_POINTS
28
-
29
- def initialize
30
- set_default_ability
31
- set_default_services
32
- set_default_finders
33
- end
34
-
35
- private
36
-
37
- def set_default_ability
38
- @ability_class = 'Spree::Ability'
39
- end
40
-
41
- def set_default_services
42
10
  # cart
43
- @cart_compare_line_items_service = 'Spree::CompareLineItems'
44
- @cart_create_service = 'Spree::Cart::Create'
45
- @cart_add_item_service = 'Spree::Cart::AddItem'
46
- @cart_update_service = 'Spree::Cart::Update'
47
- @cart_recalculate_service = 'Spree::Cart::Recalculate'
48
- @cart_remove_item_service = 'Spree::Cart::RemoveItem'
49
- @cart_remove_line_item_service = 'Spree::Cart::RemoveLineItem'
50
- @cart_set_item_quantity_service = 'Spree::Cart::SetQuantity'
51
- @cart_estimate_shipping_rates_service = 'Spree::Cart::EstimateShippingRates'
52
- @cart_empty_service = 'Spree::Cart::Empty'
53
- @cart_destroy_service = 'Spree::Cart::Destroy'
54
- @cart_associate_service = 'Spree::Cart::Associate'
55
- @cart_change_currency_service = 'Spree::Cart::ChangeCurrency'
11
+ cart_compare_line_items_service: 'Spree::CompareLineItems',
12
+ cart_create_service: 'Spree::Cart::Create',
13
+ cart_add_item_service: 'Spree::Cart::AddItem',
14
+ cart_update_service: 'Spree::Cart::Update',
15
+ cart_recalculate_service: 'Spree::Cart::Recalculate',
16
+ cart_remove_item_service: 'Spree::Cart::RemoveItem',
17
+ cart_remove_line_item_service: 'Spree::Cart::RemoveLineItem',
18
+ cart_set_item_quantity_service: 'Spree::Cart::SetQuantity',
19
+ cart_estimate_shipping_rates_service: 'Spree::Cart::EstimateShippingRates',
20
+ cart_empty_service: 'Spree::Cart::Empty',
21
+ cart_destroy_service: 'Spree::Cart::Destroy',
22
+ cart_associate_service: 'Spree::Cart::Associate',
23
+ cart_change_currency_service: 'Spree::Cart::ChangeCurrency',
56
24
 
57
25
  # checkout
58
- @checkout_next_service = 'Spree::Checkout::Next'
59
- @checkout_advance_service = 'Spree::Checkout::Advance'
60
- @checkout_update_service = 'Spree::Checkout::Update'
61
- @checkout_complete_service = 'Spree::Checkout::Complete'
62
- @checkout_add_store_credit_service = 'Spree::Checkout::AddStoreCredit'
63
- @checkout_remove_store_credit_service = 'Spree::Checkout::RemoveStoreCredit'
64
- @checkout_get_shipping_rates_service = 'Spree::Checkout::GetShippingRates'
65
- @checkout_select_shipping_method_service = 'Spree::Checkout::SelectShippingMethod'
26
+ checkout_next_service: 'Spree::Checkout::Next',
27
+ checkout_advance_service: 'Spree::Checkout::Advance',
28
+ checkout_update_service: 'Spree::Checkout::Update',
29
+ checkout_complete_service: 'Spree::Checkout::Complete',
30
+ checkout_add_store_credit_service: 'Spree::Checkout::AddStoreCredit',
31
+ checkout_remove_store_credit_service: 'Spree::Checkout::RemoveStoreCredit',
32
+ checkout_get_shipping_rates_service: 'Spree::Checkout::GetShippingRates',
33
+ checkout_select_shipping_method_service: 'Spree::Checkout::SelectShippingMethod',
66
34
 
67
35
  # order
68
- @order_approve_service = 'Spree::Orders::Approve'
69
- @order_cancel_service = 'Spree::Orders::Cancel'
36
+ order_approve_service: 'Spree::Orders::Approve',
37
+ order_cancel_service: 'Spree::Orders::Cancel',
70
38
 
71
39
  # shipment
72
- @shipment_change_state_service = 'Spree::Shipments::ChangeState'
73
- @shipment_create_service = 'Spree::Shipments::Create'
74
- @shipment_update_service = 'Spree::Shipments::Update'
75
- @shipment_add_item_service = 'Spree::Shipments::AddItem'
76
- @shipment_remove_item_service = 'Spree::Shipments::RemoveItem'
40
+ shipment_change_state_service: 'Spree::Shipments::ChangeState',
41
+ shipment_create_service: 'Spree::Shipments::Create',
42
+ shipment_update_service: 'Spree::Shipments::Update',
43
+ shipment_add_item_service: 'Spree::Shipments::AddItem',
44
+ shipment_remove_item_service: 'Spree::Shipments::RemoveItem',
77
45
 
78
46
  # sorter
79
- @collection_sorter = 'Spree::BaseSorter'
80
- @order_sorter = 'Spree::BaseSorter'
81
- @products_sorter = 'Spree::Products::Sort'
47
+ collection_sorter: 'Spree::BaseSorter',
48
+ order_sorter: 'Spree::BaseSorter',
49
+ products_sorter: 'Spree::Products::Sort',
82
50
 
83
51
  # paginator
84
- @collection_paginator = 'Spree::Shared::Paginate'
52
+ collection_paginator: 'Spree::Shared::Paginate',
85
53
 
86
54
  # coupons
87
55
  # TODO: we should split this service into 2 separate - Add and Remove
88
- @coupon_handler = 'Spree::PromotionHandler::Coupon'
56
+ coupon_handler: 'Spree::PromotionHandler::Coupon',
89
57
 
90
58
  # account
91
- @account_create_service = 'Spree::Account::Create'
92
- @account_update_service = 'Spree::Account::Update'
59
+ account_create_service: 'Spree::Account::Create',
60
+ account_update_service: 'Spree::Account::Update',
93
61
 
94
62
  # addresses
95
- @address_create_service = 'Spree::Addresses::Create'
96
- @address_update_service = 'Spree::Addresses::Update'
63
+ address_create_service: 'Spree::Addresses::Create',
64
+ address_update_service: 'Spree::Addresses::Update',
97
65
 
98
66
  # credit cards
99
- @credit_cards_destroy_service = 'Spree::CreditCards::Destroy'
67
+ credit_cards_destroy_service: 'Spree::CreditCards::Destroy',
100
68
 
101
69
  # classifications
102
- @classification_reposition_service = 'Spree::Classifications::Reposition'
70
+ classification_reposition_service: 'Spree::Classifications::Reposition',
103
71
 
104
72
  # line items
105
- @line_item_create_service = 'Spree::LineItems::Create'
106
- @line_item_update_service = 'Spree::LineItems::Update'
107
- @line_item_destroy_service = 'Spree::LineItems::Destroy'
73
+ line_item_create_service: 'Spree::LineItems::Create',
74
+ line_item_update_service: 'Spree::LineItems::Update',
75
+ line_item_destroy_service: 'Spree::LineItems::Destroy',
108
76
 
109
- @payment_create_service = 'Spree::Payments::Create'
77
+ payment_create_service: 'Spree::Payments::Create',
110
78
 
111
79
  # errors
112
- @error_handler = 'Spree::ErrorReporter'
113
- end
114
-
115
- def set_default_finders
116
- @address_finder = 'Spree::Addresses::Find'
117
- @country_finder = 'Spree::Countries::Find'
118
- @cms_page_finder = 'Spree::CmsPages::Find'
119
- @menu_finder = 'Spree::Menus::Find'
120
- @current_order_finder = 'Spree::Orders::FindCurrent'
121
- @current_store_finder = 'Spree::Stores::FindCurrent'
122
- @completed_order_finder = 'Spree::Orders::FindComplete'
123
- @credit_card_finder = 'Spree::CreditCards::Find'
124
- @products_finder = 'Spree::Products::Find'
125
- @taxon_finder = 'Spree::Taxons::Find'
126
- @line_item_by_variant_finder = 'Spree::LineItems::FindByVariant'
127
- end
80
+ error_handler: 'Spree::ErrorReporter',
81
+
82
+ # data feeds
83
+ data_feeds_google_rss_service: 'Spree::DataFeeds::Google::Rss',
84
+ data_feeds_google_optional_attributes_service: 'Spree::DataFeeds::Google::OptionalAttributes',
85
+ data_feeds_google_required_attributes_service: 'Spree::DataFeeds::Google::RequiredAttributes',
86
+ data_feeds_google_optional_sub_attributes_service: 'Spree::DataFeeds::Google::OptionalSubAttributes',
87
+ data_feeds_google_products_list: 'Spree::DataFeeds::Google::ProductsList',
88
+
89
+ # finders
90
+ address_finder: 'Spree::Addresses::Find',
91
+ country_finder: 'Spree::Countries::Find',
92
+ cms_page_finder: 'Spree::CmsPages::Find',
93
+ menu_finder: 'Spree::Menus::Find',
94
+ current_order_finder: 'Spree::Orders::FindCurrent',
95
+ current_store_finder: 'Spree::Stores::FindCurrent',
96
+ completed_order_finder: 'Spree::Orders::FindComplete',
97
+ credit_card_finder: 'Spree::CreditCards::Find',
98
+ products_finder: 'Spree::Products::Find',
99
+ taxon_finder: 'Spree::Taxons::Find',
100
+ line_item_by_variant_finder: 'Spree::LineItems::FindByVariant'
101
+ }.freeze
102
+
103
+ include Spree::DependenciesHelper
128
104
  end
129
105
  end
130
106
  end
@@ -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
@@ -11,7 +11,8 @@ module Spree
11
11
  :adjusters,
12
12
  :stock_splitters,
13
13
  :promotions,
14
- :line_item_comparison_hooks)
14
+ :line_item_comparison_hooks,
15
+ :data_feed_types)
15
16
  SpreeCalculators = Struct.new(:shipping_methods, :tax_rates, :promotion_actions_create_adjustments, :promotion_actions_create_item_adjustments)
16
17
  PromoEnvironment = Struct.new(:rules, :actions)
17
18
  isolate_namespace Spree
@@ -122,6 +123,10 @@ module Spree
122
123
  Promotion::Actions::CreateLineItems,
123
124
  Promotion::Actions::FreeShipping
124
125
  ]
126
+
127
+ Rails.application.config.spree.data_feed_types = [
128
+ Spree::DataFeed::Google
129
+ ]
125
130
  end
126
131
 
127
132
  initializer 'spree.promo.register.promotions.actions' do |app|
@@ -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
@@ -83,7 +83,7 @@ module Spree
83
83
  # method should return new scope based on base_scope
84
84
  def get_products_conditions_for(base_scope, query)
85
85
  unless query.blank?
86
- base_scope = base_scope.like_any([:name, :description], [query])
86
+ base_scope = base_scope.i18n { name.matches("%#{query}%").or(description.matches("%#{query}%")) }
87
87
  end
88
88
  base_scope
89
89
  end
@@ -1,5 +1,5 @@
1
1
  module Spree
2
- VERSION = '4.5.5'.freeze
2
+ VERSION = '4.6.0'.freeze
3
3
 
4
4
  def self.version
5
5
  VERSION
data/lib/spree/core.rb CHANGED
@@ -13,6 +13,7 @@ require 'cancan'
13
13
  require 'friendly_id'
14
14
  require 'kaminari'
15
15
  require 'monetize'
16
+ require 'mobility'
16
17
  require 'paranoia'
17
18
  require 'ransack'
18
19
  require 'state_machines-activerecord'
@@ -116,6 +117,7 @@ require 'spree/core/version'
116
117
 
117
118
  require 'spree/core/number_generator'
118
119
  require 'spree/migrations'
120
+ require 'spree/translation_migrations'
119
121
  require 'spree/core/engine'
120
122
 
121
123
  require 'spree/i18n'
@@ -147,7 +147,7 @@ module Spree
147
147
 
148
148
  # TODO: Should probably use something like Spree.user_class.attributes
149
149
  @@user_attributes = [:email, :bill_address_id, :ship_address_id, :password, :first_name, :last_name,
150
- :password_confirmation, { public_metadata: {}, private_metadata: {} }]
150
+ :password_confirmation, { public_metadata: {}, private_metadata: {} }, :selected_locale]
151
151
 
152
152
  @@variant_attributes = [
153
153
  :name, :presentation, :cost_price, :discontinue_on, :lock_version,
@@ -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
@@ -52,6 +52,12 @@ FactoryBot.define do
52
52
  factory :product_with_option_types do
53
53
  after(:create) { |product| create(:product_option_type, product: product) }
54
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
55
61
  end
56
62
  end
57
63
  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
@@ -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
@@ -25,6 +25,10 @@ FactoryBot.define do
25
25
  factory :variant do
26
26
  # on_hand 5
27
27
  product { |p| p.association(:product, stores: [create(:store)]) }
28
+
29
+ factory :with_image_variant do
30
+ images { create_list(:image, 1) }
31
+ end
28
32
  end
29
33
 
30
34
  factory :master_variant do
@@ -0,0 +1,40 @@
1
+ module Spree
2
+ class TranslationMigrations
3
+ def initialize(resource_class, default_locale)
4
+ @resource_class = resource_class
5
+ @translations_table = resource_class::Translation.table_name
6
+ @translatable_fields = resource_class.translatable_fields.join(', ')
7
+ @foreign_key = "#{resource_class.table_name.singularize}_id"
8
+ @default_locale = default_locale
9
+ end
10
+
11
+ def transfer_translation_data
12
+ nullify_translatable_fields = @resource_class.translatable_fields.map { |f| "#{f}=null" }.join(', ')
13
+
14
+ unless @resource_class::Translation.exists?
15
+ ActiveRecord::Base.connection.execute("
16
+ INSERT INTO #{@translations_table} (#{@translatable_fields}, #{@foreign_key}, locale, created_at, updated_at)
17
+ SELECT #{@translatable_fields}, id, '#{@default_locale}' as locale, created_at, updated_at FROM #{@resource_class.table_name};
18
+ ")
19
+ ActiveRecord::Base.connection.execute("
20
+ UPDATE #{@resource_class.table_name}
21
+ SET #{nullify_translatable_fields};
22
+ ")
23
+ end
24
+ end
25
+
26
+ def revert_translation_data_transfer
27
+ translation_table_fields = @resource_class.translatable_fields.map { |f| "#{@translations_table}.#{f}" }.join(', ')
28
+ row_expression = @resource_class.translatable_fields.count == 1 ? 'ROW' : ''
29
+
30
+ ActiveRecord::Base.connection.execute("
31
+ UPDATE #{@resource_class.table_name}
32
+ SET (#{@translatable_fields}) = #{row_expression}(#{translation_table_fields})
33
+ FROM #{@translations_table}
34
+ WHERE #{@translations_table}.#{@foreign_key} = #{@resource_class.table_name}.id
35
+ ")
36
+
37
+ ActiveRecord::Base.connection.execute("TRUNCATE TABLE #{@translations_table}")
38
+ end
39
+ end
40
+ end
data/spree_core.gemspec CHANGED
@@ -54,4 +54,7 @@ Gem::Specification.new do |s|
54
54
  s.add_dependency 'image_processing', '~> 1.2'
55
55
  s.add_dependency 'active_storage_validations', '~> 0.9', '<= 0.9.5'
56
56
  s.add_dependency 'activerecord-typedstore'
57
+ s.add_dependency 'mobility', '~> 1.2.9'
58
+ s.add_dependency 'mobility-ransack', '~> 1.2.1'
59
+ s.add_dependency 'friendly_id-mobility', '~> 1.0.4'
57
60
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spree_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.5.5
4
+ version: 4.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Schofield
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-04-24 00:00:00.000000000 Z
12
+ date: 2023-05-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: actionpack
@@ -441,6 +441,48 @@ dependencies:
441
441
  - - ">="
442
442
  - !ruby/object:Gem::Version
443
443
  version: '0'
444
+ - !ruby/object:Gem::Dependency
445
+ name: mobility
446
+ requirement: !ruby/object:Gem::Requirement
447
+ requirements:
448
+ - - "~>"
449
+ - !ruby/object:Gem::Version
450
+ version: 1.2.9
451
+ type: :runtime
452
+ prerelease: false
453
+ version_requirements: !ruby/object:Gem::Requirement
454
+ requirements:
455
+ - - "~>"
456
+ - !ruby/object:Gem::Version
457
+ version: 1.2.9
458
+ - !ruby/object:Gem::Dependency
459
+ name: mobility-ransack
460
+ requirement: !ruby/object:Gem::Requirement
461
+ requirements:
462
+ - - "~>"
463
+ - !ruby/object:Gem::Version
464
+ version: 1.2.1
465
+ type: :runtime
466
+ prerelease: false
467
+ version_requirements: !ruby/object:Gem::Requirement
468
+ requirements:
469
+ - - "~>"
470
+ - !ruby/object:Gem::Version
471
+ version: 1.2.1
472
+ - !ruby/object:Gem::Dependency
473
+ name: friendly_id-mobility
474
+ requirement: !ruby/object:Gem::Requirement
475
+ requirements:
476
+ - - "~>"
477
+ - !ruby/object:Gem::Version
478
+ version: 1.0.4
479
+ type: :runtime
480
+ prerelease: false
481
+ version_requirements: !ruby/object:Gem::Requirement
482
+ requirements:
483
+ - - "~>"
484
+ - !ruby/object:Gem::Version
485
+ version: 1.0.4
444
486
  description: Spree Models, Helpers, Services and core libraries
445
487
  email: hello@spreecommerce.org
446
488
  executables: []
@@ -492,6 +534,9 @@ files:
492
534
  - app/models/concerns/spree/product_scopes.rb
493
535
  - app/models/concerns/spree/ransackable_attributes.rb
494
536
  - app/models/concerns/spree/single_store_resource.rb
537
+ - app/models/concerns/spree/translatable_resource.rb
538
+ - app/models/concerns/spree/translatable_resource_scopes.rb
539
+ - app/models/concerns/spree/translatable_resource_slug.rb
495
540
  - app/models/concerns/spree/unique_name.rb
496
541
  - app/models/concerns/spree/user_address.rb
497
542
  - app/models/concerns/spree/user_methods.rb
@@ -545,6 +590,8 @@ files:
545
590
  - app/models/spree/country.rb
546
591
  - app/models/spree/credit_card.rb
547
592
  - app/models/spree/customer_return.rb
593
+ - app/models/spree/data_feed.rb
594
+ - app/models/spree/data_feed/google.rb
548
595
  - app/models/spree/digital.rb
549
596
  - app/models/spree/digital_link.rb
550
597
  - app/models/spree/exchange.rb
@@ -575,7 +622,6 @@ files:
575
622
  - app/models/spree/order/emails.rb
576
623
  - app/models/spree/order/payments.rb
577
624
  - app/models/spree/order/store_credit.rb
578
- - app/models/spree/order_contents.rb
579
625
  - app/models/spree/order_inventory.rb
580
626
  - app/models/spree/order_merger.rb
581
627
  - app/models/spree/order_promotion.rb
@@ -745,6 +791,11 @@ files:
745
791
  - app/services/spree/classifications/reposition.rb
746
792
  - app/services/spree/compare_line_items.rb
747
793
  - app/services/spree/credit_cards/destroy.rb
794
+ - app/services/spree/data_feeds/google/optional_attributes.rb
795
+ - app/services/spree/data_feeds/google/optional_sub_attributes.rb
796
+ - app/services/spree/data_feeds/google/products_list.rb
797
+ - app/services/spree/data_feeds/google/required_attributes.rb
798
+ - app/services/spree/data_feeds/google/rss.rb
748
799
  - app/services/spree/generate_token.rb
749
800
  - app/services/spree/line_items/create.rb
750
801
  - app/services/spree/line_items/destroy.rb
@@ -782,6 +833,7 @@ files:
782
833
  - config/initializers/active_storage.rb
783
834
  - config/initializers/friendly_id.rb
784
835
  - config/initializers/inflections.rb
836
+ - config/initializers/mobility.rb
785
837
  - config/initializers/rails61_fixes.rb
786
838
  - config/initializers/state_machine.rb
787
839
  - config/locales/en.yml
@@ -819,6 +871,38 @@ files:
819
871
  - db/migrate/20220222083546_add_barcode_to_spree_variants.rb
820
872
  - db/migrate/20220329113557_fix_cms_pages_unique_indexes.rb
821
873
  - db/migrate/20220613133029_add_metadata_to_spree_stock_items.rb
874
+ - db/migrate/20220706112554_create_product_name_and_description_translations_for_mobility_table_backend.rb
875
+ - db/migrate/20220715083542_create_spree_product_translations_for_mobility.rb
876
+ - db/migrate/20220715120222_change_product_name_null_to_true.rb
877
+ - db/migrate/20220718100743_create_spree_taxon_name_and_description_translations_for_mobility_table_backend.rb
878
+ - db/migrate/20220718100948_change_taxon_name_null_to_true.rb
879
+ - db/migrate/20220802070609_add_locale_to_friendly_id_slugs.rb
880
+ - db/migrate/20220802073225_create_spree_product_slug_translations_for_mobility_table_backend.rb
881
+ - db/migrate/20220804073928_transfer_data_to_translatable_tables.rb
882
+ - db/migrate/20221215151408_add_selected_locale_to_spree_users.rb
883
+ - db/migrate/20221219123957_add_deleted_at_to_product_translations.rb
884
+ - db/migrate/20221220133432_add_uniqueness_constraint_to_product_translations.rb
885
+ - db/migrate/20221229132350_create_spree_data_feed_settings.rb
886
+ - db/migrate/20230103144439_create_option_type_translations.rb
887
+ - db/migrate/20230103151034_create_option_value_translations.rb
888
+ - db/migrate/20230109084253_create_product_property_translations.rb
889
+ - db/migrate/20230109094907_transfer_options_data_to_translatable_tables.rb
890
+ - db/migrate/20230109105943_create_property_translations.rb
891
+ - db/migrate/20230109110840_transfer_property_data_to_translatable_tables.rb
892
+ - db/migrate/20230110142344_backfill_friendly_id_slug_locale.rb
893
+ - db/migrate/20230111121534_add_additional_taxon_translation_fields.rb
894
+ - db/migrate/20230111122511_transfer_product_and_taxon_data_to_translatable_tables.rb
895
+ - db/migrate/20230117115531_create_taxonomy_translations.rb
896
+ - db/migrate/20230117120430_allow_null_taxonomy_name.rb
897
+ - db/migrate/20230117121303_transfer_taxonomy_data_to_translatable_tables.rb
898
+ - db/migrate/20230210142732_create_store_translations.rb
899
+ - db/migrate/20230210142849_transfer_store_data_to_translatable_tables.rb
900
+ - db/migrate/20230210230434_add_deleted_at_to_store_translations.rb
901
+ - db/migrate/20230415155958_rename_data_feed_settings_table.rb
902
+ - db/migrate/20230415160828_rename_data_feed_table_columns.rb
903
+ - db/migrate/20230415161226_add_indexes_to_data_feeds_table.rb
904
+ - db/migrate/20230512094803_rename_data_feeds_column_provider_to_type.rb
905
+ - db/migrate/20230514162157_add_index_on_locale_and_permalink_to_spree_taxons.rb
822
906
  - db/seeds.rb
823
907
  - lib/friendly_id/paranoia.rb
824
908
  - lib/generators/spree/custom_user/custom_user_generator.rb
@@ -903,6 +987,7 @@ files:
903
987
  - lib/spree/testing_support/factories/digital_factory.rb
904
988
  - lib/spree/testing_support/factories/digital_link_factory.rb
905
989
  - lib/spree/testing_support/factories/favicon_image_factory.rb
990
+ - lib/spree/testing_support/factories/google_data_feed_factory.rb
906
991
  - lib/spree/testing_support/factories/icon_factory.rb
907
992
  - lib/spree/testing_support/factories/image_factory.rb
908
993
  - lib/spree/testing_support/factories/inventory_unit_factory.rb
@@ -920,6 +1005,7 @@ files:
920
1005
  - lib/spree/testing_support/factories/product_factory.rb
921
1006
  - lib/spree/testing_support/factories/product_option_type_factory.rb
922
1007
  - lib/spree/testing_support/factories/product_property_factory.rb
1008
+ - lib/spree/testing_support/factories/product_translation_factory.rb
923
1009
  - lib/spree/testing_support/factories/promotion_action_factory.rb
924
1010
  - lib/spree/testing_support/factories/promotion_category_factory.rb
925
1011
  - lib/spree/testing_support/factories/promotion_factory.rb
@@ -973,6 +1059,7 @@ files:
973
1059
  - lib/spree/testing_support/preferences.rb
974
1060
  - lib/spree/testing_support/rspec_retry_config.rb
975
1061
  - lib/spree/testing_support/url_helpers.rb
1062
+ - lib/spree/translation_migrations.rb
976
1063
  - lib/spree_core.rb
977
1064
  - lib/tasks/core.rake
978
1065
  - lib/tasks/exchanges.rake
@@ -990,9 +1077,9 @@ licenses:
990
1077
  - BSD-3-Clause
991
1078
  metadata:
992
1079
  bug_tracker_uri: https://github.com/spree/spree/issues
993
- changelog_uri: https://github.com/spree/spree/releases/tag/v4.5.5
1080
+ changelog_uri: https://github.com/spree/spree/releases/tag/v4.6.0
994
1081
  documentation_uri: https://dev-docs.spreecommerce.org/
995
- source_code_uri: https://github.com/spree/spree/tree/v4.5.5
1082
+ source_code_uri: https://github.com/spree/spree/tree/v4.6.0
996
1083
  post_install_message:
997
1084
  rdoc_options: []
998
1085
  require_paths:
@@ -1008,7 +1095,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1008
1095
  - !ruby/object:Gem::Version
1009
1096
  version: 1.8.23
1010
1097
  requirements: []
1011
- rubygems_version: 3.5.3
1098
+ rubygems_version: 3.4.1
1012
1099
  signing_key:
1013
1100
  specification_version: 4
1014
1101
  summary: The bare bones necessary for Spree