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
@@ -0,0 +1,67 @@
1
+ module Spree
2
+ module DataFeeds
3
+ module Google
4
+ class RequiredAttributes
5
+ prepend Spree::ServiceModule::Base
6
+
7
+ def call(input)
8
+ information = {}
9
+
10
+ return failure(nil, error: 'No image link') if get_image_link(input[:variant], input[:product]).nil?
11
+
12
+ information['id'] = input[:variant].id
13
+ information['title'] = format_title(input[:product], input[:variant])
14
+ information['description'] = get_description(input[:product], input[:variant])
15
+ information['link'] = "#{input[:store].url}/#{input[:product].slug}"
16
+ information['image_link'] = get_image_link(input[:variant], input[:product])
17
+ information['price'] = format_price(input[:variant])
18
+ information['availability'] = get_availability(input[:product])
19
+ information['availability_date'] = input[:product].available_on&.xmlschema unless input[:product].available_on.nil?
20
+
21
+ success(information: information)
22
+ end
23
+
24
+ private
25
+
26
+ def format_title(product, variant)
27
+ # Title of a variant is created by joining title of a product and variant's option_values, as they are
28
+ # what differentiates it from other variants.
29
+ title = product.name
30
+ variant.option_values.find_each do |option_value|
31
+ title << " - #{option_value.name}"
32
+ end
33
+ title
34
+ end
35
+
36
+ def get_description(product, variant)
37
+ return product.description unless product.description.nil?
38
+
39
+ format_title(product, variant)
40
+ end
41
+
42
+ def get_image_link(variant, product)
43
+ # try getting image from variant
44
+ img = variant.images.first&.plp_url
45
+
46
+ # if no image specified for variant try getting product image
47
+ if img.nil?
48
+ img = product.images.first&.plp_url
49
+ end
50
+
51
+ img
52
+ end
53
+
54
+ def format_price(variant)
55
+ "#{variant.price} #{variant.cost_currency}"
56
+ end
57
+
58
+ def get_availability(product)
59
+ return 'in stock' if product.available? && product.available_on&.past?
60
+ return 'backorder' if product.backorderable? && product.backordered? && product.available_on&.future?
61
+
62
+ 'out of stock'
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,107 @@
1
+ require 'nokogiri'
2
+
3
+ module Spree
4
+ module DataFeeds
5
+ module Google
6
+ class Rss
7
+ prepend Spree::ServiceModule::Base
8
+
9
+ def call(settings)
10
+ @settings = settings
11
+
12
+ return failure(store, error: "Store with id: #{settings.store_id} does not exist.") if store.nil?
13
+
14
+ builder = Nokogiri::XML::Builder.new do |xml|
15
+ xml.rss('xmlns:g' => 'http://base.google.com/ns/1.0', 'version' => '2.0') do
16
+ xml.channel do
17
+ add_store_information_to_xml(xml)
18
+ result = products_list.call(store)
19
+ if result.success?
20
+ result.value[:products].find_each do |product|
21
+ product.variants.active.find_each do |variant|
22
+ add_variant_information_to_xml(xml, product, variant)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ success(file: builder.to_xml)
31
+ end
32
+
33
+ private
34
+
35
+ def store
36
+ return @store if defined? @store
37
+
38
+ @store ||= Spree::Store.find_by(id: @settings.store_id)
39
+ end
40
+
41
+ def add_store_information_to_xml(xml)
42
+ xml.title store.name
43
+ xml.link store.url
44
+ xml.description store.meta_description
45
+ end
46
+
47
+ def add_variant_information_to_xml(xml, product, variant)
48
+ input = { product: product, variant: variant, settings: @settings, store: store }
49
+ result = required_attributes.call(input)
50
+
51
+ if result.success
52
+ xml.item do
53
+ result.value[:information]&.each do |key, value|
54
+ xml['g'].send(key, value)
55
+ end
56
+
57
+ add_optional_information(xml, product, variant)
58
+ add_optional_sub_attributes(xml, product, variant)
59
+ end
60
+ end
61
+ end
62
+
63
+ def add_optional_information(xml, product, variant)
64
+ input = { product: product, variant: variant, settings: @settings, store: store }
65
+ result = optional_attributes.call(input)
66
+ if result.success?
67
+ information = result.value[:information]
68
+ information.each do |key, value|
69
+ xml['g'].send(key, value)
70
+ end
71
+ end
72
+ end
73
+
74
+ def add_optional_sub_attributes(xml, product, variant)
75
+ input = { product: product, variant: variant, settings: @settings, store: store }
76
+ result = optional_sub_attributes.call(input)
77
+ if result.success?
78
+ information = result.value[:information]
79
+ information.each do |key, value|
80
+ xml['g'].send(key) do
81
+ value.each do |subkey, subvalue|
82
+ xml['g'].send(subkey, subvalue)
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+ def optional_attributes
90
+ Spree::Dependencies.data_feeds_google_optional_attributes_service.constantize.new
91
+ end
92
+
93
+ def required_attributes
94
+ Spree::Dependencies.data_feeds_google_required_attributes_service.constantize.new
95
+ end
96
+
97
+ def optional_sub_attributes
98
+ Spree::Dependencies.data_feeds_google_optional_sub_attributes_service.constantize.new
99
+ end
100
+
101
+ def products_list
102
+ Spree::Dependencies.data_feeds_google_products_list.constantize.new
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,15 @@
1
+ module Spree
2
+ module Variants
3
+ class RemoveLineItems
4
+ prepend Spree::ServiceModule::Base
5
+
6
+ def call(variant:)
7
+ variant.line_items.joins(:order).where.not(spree_orders: { state: 'complete' }).find_each do |line_item|
8
+ Spree::Variants::RemoveLineItemJob.perform_later(line_item: line_item)
9
+ end
10
+
11
+ success(true)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -11,6 +11,8 @@ module Spree
11
11
  products = by_price(products)
12
12
  products = by_sku(products)
13
13
 
14
+ products = select_translatable_fields(products)
15
+
14
16
  products.distinct
15
17
  end
16
18
 
@@ -46,6 +48,27 @@ module Spree
46
48
  def sort_by?(field)
47
49
  sort.detect { |s| s[0] == field }
48
50
  end
51
+
52
+ # Add translatable fields to SELECT statement to avoid InvalidColumnReference error (workaround for Mobility issue #596)
53
+ def select_translatable_fields(scope)
54
+ translatable_fields = translatable_sortable_fields
55
+ return scope if translatable_fields.empty?
56
+
57
+ # if sorting by 'sku' or 'price', spree_products.* is already included in SELECT statement
58
+ if sort_by?('sku') || sort_by?('price')
59
+ scope.i18n.select(*translatable_fields)
60
+ else
61
+ scope.i18n.select("#{Product.table_name}.*").select(*translatable_fields)
62
+ end
63
+ end
64
+
65
+ def translatable_sortable_fields
66
+ fields = []
67
+ Product.translatable_fields.each do |field|
68
+ fields << field if sort_by?(field.to_s)
69
+ end
70
+ fields
71
+ end
49
72
  end
50
73
  end
51
74
  end
data/brakeman.ignore CHANGED
@@ -1,20 +1,328 @@
1
1
  {
2
- "ignored_warnings": [
3
- {
4
- "fingerprint": "011b2643940ba1112f7a737e403abe3616ad91764703c801cc35a48d36b721da",
5
- "note": "interpolating table name"
6
- },
7
- {
8
- "fingerprint": "965d3919f811ab63b7b8d62da528559a7f38dc122c57efea7136e7ec5ef1f062",
9
- "note": "interpolating table name"
10
- },
11
- {
12
- "fingerprint": "abd8e90e7a7dfbcdcd6d44fd3fb550598aee6d7a9ef2bb132ad1a18a3c50be30",
13
- "note": "interpolating table name"
14
- },
15
- {
16
- "fingerprint": "efcc57e1a5648d7db59d1beaf5e399d2278539a8667b19c520b305a6ca7e15e8",
17
- "note": "interpolating table name"
18
- }
19
- ]
2
+ "ignored_warnings": [
3
+ {
4
+ "warning_type": "SQL Injection",
5
+ "warning_code": 0,
6
+ "fingerprint": "011b2643940ba1112f7a737e403abe3616ad91764703c801cc35a48d36b721da",
7
+ "check_name": "SQL",
8
+ "message": "Possible SQL injection",
9
+ "file": "app/models/concerns/spree/product_scopes.rb",
10
+ "line": 64,
11
+ "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
12
+ "code": "where(\"#{price_table_name}.amount <= ?\", price)",
13
+ "render_path": null,
14
+ "location": {
15
+ "type": "method",
16
+ "class": "Spree",
17
+ "method": null
18
+ },
19
+ "user_input": "price_table_name",
20
+ "confidence": "Medium",
21
+ "cwe_id": [
22
+ 89
23
+ ],
24
+ "note": "interpolating table name"
25
+ },
26
+ {
27
+ "warning_type": "Redirect",
28
+ "warning_code": 18,
29
+ "fingerprint": "05d3870f66d650510c859a8949d5686b05eb028825083b096d0f65fedf80b118",
30
+ "check_name": "Redirect",
31
+ "message": "Possible unprotected redirect",
32
+ "file": "lib/spree/core/controller_helpers/auth.rb",
33
+ "line": 25,
34
+ "link": "https://brakemanscanner.org/docs/warning_types/redirect/",
35
+ "code": "redirect_to((session[\"spree_user_return_to\"] or (request.env[\"HTTP_REFERER\"] or default)))",
36
+ "render_path": null,
37
+ "location": {
38
+ "type": "method",
39
+ "class": "Spree::Core::ControllerHelpers::Auth",
40
+ "method": "redirect_back_or_default"
41
+ },
42
+ "user_input": "request.env[\"HTTP_REFERER\"]",
43
+ "confidence": "High",
44
+ "cwe_id": [
45
+ 601
46
+ ],
47
+ "note": ""
48
+ },
49
+ {
50
+ "warning_type": "SQL Injection",
51
+ "warning_code": 0,
52
+ "fingerprint": "1c12fcb833b0ddffa07880acb7e604922c0d1d52de598316186241baf16551cd",
53
+ "check_name": "SQL",
54
+ "message": "Possible SQL injection",
55
+ "file": "app/finders/spree/taxons/find.rb",
56
+ "line": 75,
57
+ "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
58
+ "code": "taxons.joins(\"INNER JOIN #{Spree::Taxon.table_name} AS parent_taxon ON parent_taxon.id = #{Spree::Taxon.table_name}.parent_id\").join_translation_table(Taxon, \"parent_taxon\").where([\"#{Taxon.translation_table_alias}.permalink = ?\", parent_permalink])",
59
+ "render_path": null,
60
+ "location": {
61
+ "type": "method",
62
+ "class": "Spree::Taxons::Find",
63
+ "method": "by_parent_permalink"
64
+ },
65
+ "user_input": "Taxon.translation_table_alias",
66
+ "confidence": "Weak",
67
+ "cwe_id": [
68
+ 89
69
+ ],
70
+ "note": ""
71
+ },
72
+ {
73
+ "warning_type": "SQL Injection",
74
+ "warning_code": 0,
75
+ "fingerprint": "1f02952550c2f54d044c9577a45e7ba7c7990c8b8a59d1dac83a96790237f507",
76
+ "check_name": "SQL",
77
+ "message": "Possible SQL injection",
78
+ "file": "app/models/concerns/spree/product_scopes.rb",
79
+ "line": 139,
80
+ "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
81
+ "code": "joins(:properties).join_translation_table(Property).join_translation_table(ProductProperty).where(\"#{ProductProperty.translation_table_alias}.value = ?\", value)",
82
+ "render_path": null,
83
+ "location": {
84
+ "type": "method",
85
+ "class": "Spree::ProductScopes",
86
+ "method": null
87
+ },
88
+ "user_input": "ProductProperty.translation_table_alias",
89
+ "confidence": "Weak",
90
+ "cwe_id": [
91
+ 89
92
+ ],
93
+ "note": ""
94
+ },
95
+ {
96
+ "warning_type": "SQL Injection",
97
+ "warning_code": 0,
98
+ "fingerprint": "7928c0813a0bf084ead091b4554ef6abea9ae9c7167936f5c62da9e328b9f736",
99
+ "check_name": "SQL",
100
+ "message": "Possible SQL injection",
101
+ "file": "app/models/concerns/spree/product_scopes.rb",
102
+ "line": 139,
103
+ "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
104
+ "code": "joins(:properties).join_translation_table(Property).join_translation_table(ProductProperty).where(\"#{ProductProperty.translation_table_alias}.value = ?\", value)",
105
+ "render_path": null,
106
+ "location": {
107
+ "type": "method",
108
+ "class": "Spree",
109
+ "method": null
110
+ },
111
+ "user_input": "ProductProperty.translation_table_alias",
112
+ "confidence": "Weak",
113
+ "cwe_id": [
114
+ 89
115
+ ],
116
+ "note": ""
117
+ },
118
+ {
119
+ "warning_type": "SQL Injection",
120
+ "warning_code": 0,
121
+ "fingerprint": "857c335935a00f584137f31dbcb1a4532af5c8bb5cf53a86058b4af98c6597dc",
122
+ "check_name": "SQL",
123
+ "message": "Possible SQL injection",
124
+ "file": "lib/spree/translation_migrations.rb",
125
+ "line": 21,
126
+ "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
127
+ "code": "ActiveRecord::Base.connection.execute(\"\\n UPDATE #{resource_class.table_name}\\n SET #{resource_class.translatable_fields.map do\n \"#{f}=null\"\n end.join(\", \")};\\n \")",
128
+ "render_path": null,
129
+ "location": {
130
+ "type": "method",
131
+ "class": "Spree::TranslationMigrations",
132
+ "method": "transfer_translation_data"
133
+ },
134
+ "user_input": "resource_class.translatable_fields.map do\n \"#{f}=null\"\n end.join(\", \")",
135
+ "confidence": "Medium",
136
+ "cwe_id": [
137
+ 89
138
+ ],
139
+ "note": ""
140
+ },
141
+ {
142
+ "warning_type": "SQL Injection",
143
+ "warning_code": 0,
144
+ "fingerprint": "965d3919f811ab63b7b8d62da528559a7f38dc122c57efea7136e7ec5ef1f062",
145
+ "check_name": "SQL",
146
+ "message": "Possible SQL injection",
147
+ "file": "app/models/concerns/spree/product_scopes.rb",
148
+ "line": 68,
149
+ "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
150
+ "code": "where(\"#{price_table_name}.amount >= ?\", price)",
151
+ "render_path": null,
152
+ "location": {
153
+ "type": "method",
154
+ "class": "Spree::ProductScopes",
155
+ "method": null
156
+ },
157
+ "user_input": "price_table_name",
158
+ "confidence": "Medium",
159
+ "cwe_id": [
160
+ 89
161
+ ],
162
+ "note": "interpolating table name"
163
+ },
164
+ {
165
+ "warning_type": "SQL Injection",
166
+ "warning_code": 0,
167
+ "fingerprint": "98607ecfb86c2d3c2567390f813861edbc42d6ffa9f482afb7c0b3464eaf6e73",
168
+ "check_name": "SQL",
169
+ "message": "Possible SQL injection",
170
+ "file": "app/models/concerns/spree/translatable_resource_scopes.rb",
171
+ "line": 18,
172
+ "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
173
+ "code": "joins(\"LEFT OUTER JOIN #{translatable_class::Translation.table_name} #{translatable_class.translation_table_alias}\\n ON #{translatable_class.translation_table_alias}.#{\"#{translatable_class.table_name.singularize}_id\"} = #{(translatable_class.table_name or join_on_table_alias)}.id\\n AND #{translatable_class.translation_table_alias}.locale = '#{Mobility.locale}'\")",
174
+ "render_path": null,
175
+ "location": {
176
+ "type": "method",
177
+ "class": "Spree::TranslatableResourceScopes",
178
+ "method": "join_translation_table"
179
+ },
180
+ "user_input": "translatable_class.translation_table_alias",
181
+ "confidence": "Medium",
182
+ "cwe_id": [
183
+ 89
184
+ ],
185
+ "note": ""
186
+ },
187
+ {
188
+ "warning_type": "SQL Injection",
189
+ "warning_code": 0,
190
+ "fingerprint": "abd8e90e7a7dfbcdcd6d44fd3fb550598aee6d7a9ef2bb132ad1a18a3c50be30",
191
+ "check_name": "SQL",
192
+ "message": "Possible SQL injection",
193
+ "file": "app/models/concerns/spree/product_scopes.rb",
194
+ "line": 64,
195
+ "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
196
+ "code": "where(\"#{price_table_name}.amount <= ?\", price)",
197
+ "render_path": null,
198
+ "location": {
199
+ "type": "method",
200
+ "class": "Spree::ProductScopes",
201
+ "method": null
202
+ },
203
+ "user_input": "price_table_name",
204
+ "confidence": "Medium",
205
+ "cwe_id": [
206
+ 89
207
+ ],
208
+ "note": "interpolating table name"
209
+ },
210
+ {
211
+ "warning_type": "SQL Injection",
212
+ "warning_code": 0,
213
+ "fingerprint": "c1c97347a2d74ea41d46519e3bfbd94c511a1bd9c285f3f2a1fa0cb7e624d232",
214
+ "check_name": "SQL",
215
+ "message": "Possible SQL injection",
216
+ "file": "lib/spree/translation_migrations.rb",
217
+ "line": 32,
218
+ "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
219
+ "code": "ActiveRecord::Base.connection.execute(\"\\n UPDATE #{resource_class.table_name}\\n SET (#{resource_class.translatable_fields.join(\", \")}) = #{(\"ROW\" or \"\")}(#{resource_class.translatable_fields.map do\n \"#{resource_class::Translation.table_name}.#{f}\"\n end.join(\", \")})\\n FROM #{resource_class::Translation.table_name}\\n WHERE #{resource_class::Translation.table_name}.#{\"#{resource_class.table_name.singularize}_id\"} = #{resource_class.table_name}.id\\n \")",
220
+ "render_path": null,
221
+ "location": {
222
+ "type": "method",
223
+ "class": "Spree::TranslationMigrations",
224
+ "method": "revert_translation_data_transfer"
225
+ },
226
+ "user_input": "resource_class.translatable_fields.join(\", \")",
227
+ "confidence": "Medium",
228
+ "cwe_id": [
229
+ 89
230
+ ],
231
+ "note": ""
232
+ },
233
+ {
234
+ "warning_type": "SQL Injection",
235
+ "warning_code": 0,
236
+ "fingerprint": "c2bc48d98076b7c4fc3314c6a85f7bd1132efe5fcc346da4d28df7c25f93633f",
237
+ "check_name": "SQL",
238
+ "message": "Possible SQL injection",
239
+ "file": "app/models/spree/variant.rb",
240
+ "line": 126,
241
+ "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
242
+ "code": "joins(:product).join_translation_table(Product).where(\"LOWER(#{Product.translation_table_alias}.name) LIKE LOWER(:query)\\n OR LOWER(sku) LIKE LOWER(:query)\", :query => (\"%#{query}%\"))",
243
+ "render_path": null,
244
+ "location": {
245
+ "type": "method",
246
+ "class": "Spree::Variant",
247
+ "method": "Spree::Variant.product_name_or_sku_cont"
248
+ },
249
+ "user_input": "Product.translation_table_alias",
250
+ "confidence": "Weak",
251
+ "cwe_id": [
252
+ 89
253
+ ],
254
+ "note": ""
255
+ },
256
+ {
257
+ "warning_type": "SQL Injection",
258
+ "warning_code": 0,
259
+ "fingerprint": "ed253ae6b1b4ea3fe3d87d3652380fecab80133319b1ed041d98d163fd16b815",
260
+ "check_name": "SQL",
261
+ "message": "Possible SQL injection",
262
+ "file": "app/finders/spree/taxons/find.rb",
263
+ "line": 71,
264
+ "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
265
+ "code": "taxons.joins(:parent).join_translation_table(Taxon, \"parents_spree_taxons\").where([\"#{Taxon.translation_table_alias}.permalink = ?\", parent_permalink])",
266
+ "render_path": null,
267
+ "location": {
268
+ "type": "method",
269
+ "class": "Spree::Taxons::Find",
270
+ "method": "by_parent_permalink"
271
+ },
272
+ "user_input": "Taxon.translation_table_alias",
273
+ "confidence": "Weak",
274
+ "cwe_id": [
275
+ 89
276
+ ],
277
+ "note": ""
278
+ },
279
+ {
280
+ "warning_type": "SQL Injection",
281
+ "warning_code": 0,
282
+ "fingerprint": "efcc57e1a5648d7db59d1beaf5e399d2278539a8667b19c520b305a6ca7e15e8",
283
+ "check_name": "SQL",
284
+ "message": "Possible SQL injection",
285
+ "file": "app/models/concerns/spree/product_scopes.rb",
286
+ "line": 68,
287
+ "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
288
+ "code": "where(\"#{price_table_name}.amount >= ?\", price)",
289
+ "render_path": null,
290
+ "location": {
291
+ "type": "method",
292
+ "class": "Spree",
293
+ "method": null
294
+ },
295
+ "user_input": "price_table_name",
296
+ "confidence": "Medium",
297
+ "cwe_id": [
298
+ 89
299
+ ],
300
+ "note": "interpolating table name"
301
+ },
302
+ {
303
+ "warning_type": "SQL Injection",
304
+ "warning_code": 0,
305
+ "fingerprint": "f14dd62fac0dd1e9d5532dd5efc770e2eb873a8db80faf366b6295378634754a",
306
+ "check_name": "SQL",
307
+ "message": "Possible SQL injection",
308
+ "file": "lib/spree/translation_migrations.rb",
309
+ "line": 16,
310
+ "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
311
+ "code": "ActiveRecord::Base.connection.execute(\"\\n INSERT INTO #{resource_class::Translation.table_name} (#{resource_class.translatable_fields.join(\", \")}, #{\"#{resource_class.table_name.singularize}_id\"}, locale, created_at, updated_at)\\n SELECT #{resource_class.translatable_fields.join(\", \")}, id, '#{default_locale}' as locale, created_at, updated_at FROM #{resource_class.table_name};\\n \")",
312
+ "render_path": null,
313
+ "location": {
314
+ "type": "method",
315
+ "class": "Spree::TranslationMigrations",
316
+ "method": "transfer_translation_data"
317
+ },
318
+ "user_input": "resource_class.translatable_fields.join(\", \")",
319
+ "confidence": "Medium",
320
+ "cwe_id": [
321
+ 89
322
+ ],
323
+ "note": ""
324
+ }
325
+ ],
326
+ "updated": "2023-03-22 20:11:32 +0100",
327
+ "brakeman_version": "5.4.1"
20
328
  }
@@ -1,3 +1,5 @@
1
+ require 'friendly_id/mobility'
2
+
1
3
  # To learn more, check out the guide:
2
4
  # http://norman.github.io/friendly_id/file.Guide.html
3
5
  FriendlyId.defaults do |config|
@@ -0,0 +1,18 @@
1
+ Mobility.configure do |config|
2
+ config.plugins do
3
+ ransack
4
+ backend :table
5
+ active_record
6
+ reader
7
+ writer
8
+ backend_reader
9
+ query
10
+ cache
11
+ fallbacks
12
+ locale_accessors
13
+ presence
14
+ dirty
15
+ end
16
+
17
+ config.defaults[:fallbacks] = true
18
+ end
@@ -91,6 +91,7 @@ en:
91
91
  name: Name
92
92
  spree/product:
93
93
  available_on: Available On
94
+ make_active_at: Make Active At
94
95
  discontinue_on: Discontinue On
95
96
  cost_currency: Cost Currency
96
97
  cost_price: Cost Price
@@ -360,7 +361,7 @@ en:
360
361
  discontinue_on:
361
362
  invalid_date_range: must be later than available date
362
363
  base:
363
- cannot_destroy_if_attached_to_line_items: Cannot delete products once they are attached to line items.
364
+ cannot_destroy_if_attached_to_line_items: Cannot delete Products that are added to placed Orders. In such cases, please discontinue them.
364
365
  spree/refund:
365
366
  attributes:
366
367
  amount:
@@ -397,7 +398,7 @@ en:
397
398
  spree/variant:
398
399
  attributes:
399
400
  base:
400
- cannot_destroy_if_attached_to_line_items: Cannot delete variants once they are attached to line items.
401
+ cannot_destroy_if_attached_to_line_items: Cannot delete Variants that are added to placed Orders. In such cases, please discontinue them.
401
402
  no_master_variant_found_to_infer_price: No master variant found to infer price
402
403
  must_supply_price_for_variant_or_master: Must supply price for variant or master price for product.
403
404
  spree/image:
@@ -583,6 +584,7 @@ en:
583
584
  auto_capture: Auto Capture
584
585
  availability: availability
585
586
  available_on: Available On
587
+ make_active_at: Make Active At
586
588
  available: Available
587
589
  average_order_value: Average Order Value
588
590
  avs_response: AVS Response
@@ -1110,6 +1112,7 @@ en:
1110
1112
  notice_messages:
1111
1113
  icon_removed: Image has been successfully removed
1112
1114
  prices_saved: Prices successfully saved
1115
+ translations_saved: Translations successfully saved
1113
1116
  product_cloned: Product has been cloned
1114
1117
  product_deleted: Product has been deleted
1115
1118
  product_not_cloned: "Product could not be cloned. Reason: %{error}"
@@ -1120,6 +1123,7 @@ en:
1120
1123
  number: Number
1121
1124
  ok: OK
1122
1125
  on_hand: On Hand
1126
+ only_active_products_can_be_added_to_cart: Draft and archived products cannot be added to cart, please mark the product as active before.
1123
1127
  open: Open
1124
1128
  open_all_adjustments: Open All Adjustments
1125
1129
  option_type: Option Type