spree_core 4.2.5 → 4.3.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (248) hide show
  1. checksums.yaml +4 -4
  2. data/app/finders/concerns/spree/product_filterable.rb +9 -0
  3. data/app/finders/spree/cms_pages/find.rb +41 -0
  4. data/app/finders/spree/menus/find.rb +11 -0
  5. data/app/finders/spree/option_values/find_available.rb +20 -0
  6. data/app/finders/spree/orders/find_complete.rb +14 -2
  7. data/app/finders/spree/orders/find_current.rb +1 -13
  8. data/app/finders/spree/product_properties/find_available.rb +20 -0
  9. data/app/finders/spree/products/find.rb +55 -20
  10. data/app/finders/spree/stores/find_current.rb +24 -0
  11. data/app/helpers/spree/base_helper.rb +62 -2
  12. data/app/helpers/spree/locale_helper.rb +5 -1
  13. data/app/helpers/spree/products_helper.rb +7 -3
  14. data/app/models/concerns/spree/display_link.rb +42 -0
  15. data/app/models/concerns/spree/filter_param.rb +21 -0
  16. data/app/models/concerns/spree/memoized_data.rb +24 -0
  17. data/app/models/concerns/spree/multi_store_resource.rb +24 -0
  18. data/app/models/concerns/spree/product_scopes.rb +59 -8
  19. data/app/models/concerns/spree/single_store_resource.rb +9 -0
  20. data/app/models/concerns/spree/user_address.rb +19 -0
  21. data/app/models/concerns/spree/user_methods.rb +5 -4
  22. data/app/models/concerns/spree/user_payment_source.rb +1 -1
  23. data/app/models/spree/ability.rb +3 -1
  24. data/app/models/spree/address.rb +27 -6
  25. data/app/models/spree/app_configuration.rb +8 -0
  26. data/app/models/spree/app_dependencies.rb +18 -6
  27. data/app/models/spree/base.rb +18 -0
  28. data/app/models/spree/classification.rb +3 -0
  29. data/app/models/spree/cms/pages/feature_page.rb +7 -0
  30. data/app/models/spree/cms/pages/homepage.rb +20 -0
  31. data/app/models/spree/cms/pages/standard_page.rb +4 -0
  32. data/app/models/spree/cms/sections/featured_article.rb +29 -0
  33. data/app/models/spree/cms/sections/hero_image.rb +47 -0
  34. data/app/models/spree/cms/sections/image_gallery.rb +103 -0
  35. data/app/models/spree/cms/sections/product_carousel.rb +14 -0
  36. data/app/models/spree/cms/sections/rich_text_content.rb +13 -0
  37. data/app/models/spree/cms/sections/side_by_side_images.rb +74 -0
  38. data/app/models/spree/cms_page.rb +66 -0
  39. data/app/models/spree/cms_section.rb +57 -0
  40. data/app/models/spree/country.rb +14 -6
  41. data/app/models/spree/credit_card.rb +2 -8
  42. data/app/models/spree/customer_return.rb +8 -2
  43. data/app/models/spree/icon.rb +9 -0
  44. data/app/models/spree/image/configuration/active_storage.rb +2 -0
  45. data/app/models/spree/inventory_unit.rb +1 -1
  46. data/app/models/spree/line_item.rb +1 -1
  47. data/app/models/spree/menu.rb +63 -0
  48. data/app/models/spree/menu_item.rb +76 -0
  49. data/app/models/spree/option_type.rb +1 -1
  50. data/app/models/spree/option_value.rb +11 -0
  51. data/app/models/spree/option_value_variant.rb +1 -1
  52. data/app/models/spree/order.rb +46 -45
  53. data/app/models/spree/order/address_book.rb +3 -5
  54. data/app/models/spree/order/currency_updater.rb +1 -1
  55. data/app/models/spree/order/emails.rb +32 -0
  56. data/app/models/spree/order/payments.rb +1 -1
  57. data/app/models/spree/order/store_credit.rb +1 -1
  58. data/app/models/spree/payment.rb +7 -0
  59. data/app/models/spree/payment_method.rb +4 -0
  60. data/app/models/spree/preferences/preferable.rb +12 -0
  61. data/app/models/spree/preferences/preferable_class_methods.rb +10 -1
  62. data/app/models/spree/product.rb +27 -22
  63. data/app/models/spree/product_property.rb +19 -4
  64. data/app/models/spree/promotion.rb +6 -15
  65. data/app/models/spree/promotion/rules/country.rb +1 -1
  66. data/app/models/spree/promotion/rules/first_order.rb +4 -3
  67. data/app/models/spree/promotion/rules/taxon.rb +10 -7
  68. data/app/models/spree/promotion_handler/cart.rb +7 -2
  69. data/app/models/spree/promotion_handler/coupon.rb +5 -4
  70. data/app/models/spree/promotion_handler/free_shipping.rb +5 -6
  71. data/app/models/spree/promotion_handler/page.rb +3 -2
  72. data/app/models/spree/promotion_handler/promotion_duplicator.rb +1 -0
  73. data/app/models/spree/promotion_rule.rb +2 -0
  74. data/app/models/spree/property.rb +27 -0
  75. data/app/models/spree/reimbursement.rb +3 -1
  76. data/app/models/spree/reimbursement_type/reimbursement_helpers.rb +2 -1
  77. data/app/models/spree/shipment_handler.rb +4 -2
  78. data/app/models/spree/stock/quantifier.rb +6 -6
  79. data/app/models/spree/store.rb +90 -7
  80. data/app/models/spree/store_credit.rb +7 -3
  81. data/app/models/spree/store_credit_event.rb +2 -2
  82. data/app/models/spree/store_payment_method.rb +11 -0
  83. data/app/models/spree/store_product.rb +11 -0
  84. data/app/models/spree/store_promotion.rb +11 -0
  85. data/app/models/spree/taxon.rb +21 -1
  86. data/app/models/spree/taxon_image/configuration/active_storage.rb +2 -0
  87. data/app/models/spree/taxonomy.rb +3 -1
  88. data/app/models/spree/variant.rb +13 -4
  89. data/app/presenters/spree/filters/options_presenter.rb +27 -0
  90. data/app/presenters/spree/filters/price_presenter.rb +22 -0
  91. data/app/presenters/spree/filters/price_range_presenter.rb +29 -0
  92. data/app/presenters/spree/filters/properties_presenter.rb +23 -0
  93. data/app/presenters/spree/filters/property_presenter.rb +22 -0
  94. data/app/presenters/spree/filters/quantified_price_range_presenter.rb +44 -0
  95. data/app/services/spree/account/addresses/create.rb +1 -0
  96. data/app/services/spree/account/addresses/helper.rb +6 -0
  97. data/app/services/spree/account/addresses/update.rb +9 -3
  98. data/app/services/spree/account/create.rb +17 -0
  99. data/app/services/spree/account/update.rb +15 -0
  100. data/app/services/spree/build_localized_redirect_url.rb +1 -1
  101. data/app/services/spree/cart/create.rb +5 -3
  102. data/app/services/spree/cart/destroy.rb +40 -0
  103. data/app/services/spree/cart/empty.rb +36 -0
  104. data/app/services/spree/cart/estimate_shipping_rates.rb +3 -3
  105. data/app/services/spree/checkout/add_store_credit.rb +1 -1
  106. data/app/services/spree/classifications/reposition.rb +18 -0
  107. data/app/services/spree/credit_cards/destroy.rb +41 -0
  108. data/app/validators/db_maximum_length_validator.rb +5 -0
  109. data/app/validators/email_validator.rb +3 -1
  110. data/app/views/spree/shared/_purchased_items_table.text.erb +25 -0
  111. data/config/initializers/active_storage.rb +2 -0
  112. data/config/locales/en.yml +166 -2
  113. data/config/routes.rb +0 -5
  114. data/db/migrate/20201023152810_add_filterable_to_spree_properties.rb +8 -0
  115. data/db/migrate/20210407200948_create_spree_menus.rb +16 -0
  116. data/db/migrate/20210408092939_create_spree_menu_items.rb +31 -0
  117. data/db/migrate/20210504163720_add_filter_param_to_spree_product_properties.rb +8 -0
  118. data/db/migrate/20210505114659_add_filter_param_to_spree_properties.rb +8 -0
  119. data/db/migrate/20210512191732_create_spree_cms_pages.rb +24 -0
  120. data/db/migrate/20210514204251_create_spree_cms_sections.rb +22 -0
  121. data/db/migrate/20210527094055_create_spree_products_stores.rb +29 -0
  122. data/db/migrate/20210608045519_ensure_store_default_country_is_set.rb +5 -0
  123. data/db/migrate/20210702112334_add_missing_timestamp_columns.rb +46 -0
  124. data/db/migrate/20210713131614_add_unique_index_on_property_id_and_product_id_to_product_properties.rb +29 -0
  125. data/db/migrate/20210715091956_add_store_id_to_spree_store_credits.rb +10 -0
  126. data/db/migrate/20210716093151_add_store_id_to_spree_taxonomies.rb +11 -0
  127. data/db/migrate/20210716104141_add_index_on_name_parent_id_and_taxonomy_id_on_spree_taxons.rb +31 -0
  128. data/db/migrate/20210721120857_add_index_on_permalink_parent_id_and_taxonomy_id_on_spree_taxons.rb +31 -0
  129. data/db/migrate/20210721125657_create_spree_promotions_stores.rb +29 -0
  130. data/db/migrate/20210722090705_add_store_id_to_spree_customer_returns.rb +11 -0
  131. data/db/migrate/20210726065456_change_integer_id_columns_into_bigint.rb +305 -0
  132. data/db/migrate/20210730154425_fix_promotion_code_and_path_unique_indexes.rb +9 -0
  133. data/lib/generators/spree/dummy/dummy_generator.rb +11 -6
  134. data/lib/generators/spree/dummy_model/templates/model.rb.tt +1 -1
  135. data/lib/generators/spree/install/install_generator.rb +12 -24
  136. data/lib/spree/core.rb +8 -4
  137. data/lib/spree/core/components.rb +8 -0
  138. data/lib/spree/core/controller_helpers/auth.rb +7 -1
  139. data/lib/spree/core/controller_helpers/common.rb +1 -1
  140. data/lib/spree/core/controller_helpers/order.rb +4 -4
  141. data/lib/spree/core/controller_helpers/search.rb +1 -0
  142. data/lib/spree/core/controller_helpers/store.rb +10 -1
  143. data/lib/spree/core/engine.rb +6 -0
  144. data/lib/spree/core/importer/product.rb +3 -1
  145. data/lib/spree/core/product_duplicator.rb +1 -0
  146. data/lib/spree/core/search/base.rb +17 -22
  147. data/lib/spree/core/version.rb +1 -1
  148. data/lib/spree/i18n.rb +1 -1
  149. data/lib/spree/money.rb +2 -1
  150. data/lib/spree/permitted_attributes.rb +14 -3
  151. data/lib/spree/testing_support/authorization_helpers.rb +6 -3
  152. data/lib/spree/testing_support/capybara_config.rb +3 -1
  153. data/lib/spree/testing_support/common_rake.rb +17 -4
  154. data/lib/spree/testing_support/extension_rake.rb +2 -2
  155. data/lib/spree/testing_support/factories/address_factory.rb +1 -1
  156. data/lib/spree/testing_support/factories/classification_factory.rb +8 -0
  157. data/lib/spree/testing_support/factories/cms_page_factory.rb +20 -0
  158. data/lib/spree/testing_support/factories/cms_section_factory.rb +31 -0
  159. data/lib/spree/testing_support/factories/customer_return_factory.rb +24 -17
  160. data/lib/spree/testing_support/factories/icon_factory.rb +7 -0
  161. data/lib/spree/testing_support/factories/line_item_factory.rb +6 -2
  162. data/lib/spree/testing_support/factories/menu_factory.rb +16 -0
  163. data/lib/spree/testing_support/factories/menu_item_factory.rb +10 -0
  164. data/lib/spree/testing_support/factories/options_factory.rb +5 -0
  165. data/lib/spree/testing_support/factories/order_factory.rb +11 -2
  166. data/lib/spree/testing_support/factories/payment_method_factory.rb +6 -2
  167. data/lib/spree/testing_support/factories/product_factory.rb +11 -1
  168. data/lib/spree/testing_support/factories/product_property_factory.rb +1 -1
  169. data/lib/spree/testing_support/factories/promotion_factory.rb +18 -9
  170. data/lib/spree/testing_support/factories/property_factory.rb +22 -0
  171. data/lib/spree/testing_support/factories/stock_location_factory.rb +5 -4
  172. data/lib/spree/testing_support/factories/store_credit_factory.rb +1 -0
  173. data/lib/spree/testing_support/factories/store_factory.rb +11 -0
  174. data/lib/spree/testing_support/factories/taxon_factory.rb +3 -1
  175. data/lib/spree/testing_support/factories/taxon_image_factory.rb +7 -0
  176. data/lib/spree/testing_support/factories/taxonomy_factory.rb +1 -0
  177. data/lib/spree/testing_support/factories/user_factory.rb +7 -2
  178. data/lib/spree/testing_support/factories/variant_factory.rb +2 -2
  179. data/lib/spree/testing_support/flatpickr_capybara.rb +58 -35
  180. data/lib/spree/testing_support/order_walkthrough.rb +9 -9
  181. data/lib/tasks/core.rake +1 -1
  182. data/spec/fixtures/favicon.ico +0 -0
  183. data/spec/fixtures/files/icon_256x256.gif +0 -0
  184. data/spec/fixtures/files/icon_256x256.png +0 -0
  185. data/spec/fixtures/files/icon_512x512.png +0 -0
  186. data/spec/fixtures/files/img_256x128.png +0 -0
  187. data/spree_core.gemspec +11 -10
  188. metadata +206 -157
  189. data/app/assets/images/logo/spree_50.png +0 -0
  190. data/app/assets/images/noimage/large.png +0 -0
  191. data/app/assets/images/noimage/mini.png +0 -0
  192. data/app/assets/images/noimage/product.png +0 -0
  193. data/app/assets/images/noimage/small.png +0 -0
  194. data/app/assets/javascripts/spree.js +0 -78
  195. data/app/controllers/spree/errors_controller.rb +0 -11
  196. data/app/helpers/spree/mail_helper.rb +0 -29
  197. data/app/mailers/spree/base_mailer.rb +0 -46
  198. data/app/mailers/spree/order_mailer.rb +0 -26
  199. data/app/mailers/spree/reimbursement_mailer.rb +0 -12
  200. data/app/mailers/spree/shipment_mailer.rb +0 -12
  201. data/app/mailers/spree/test_mailer.rb +0 -8
  202. data/app/models/spree/validations/db_maximum_length_validator.rb +0 -22
  203. data/app/views/layouts/spree/base_mailer.html.erb +0 -46
  204. data/app/views/spree/errors/forbidden.html.erb +0 -0
  205. data/app/views/spree/errors/unauthorized.html.erb +0 -0
  206. data/app/views/spree/order_mailer/cancel_email.html.erb +0 -24
  207. data/app/views/spree/order_mailer/cancel_email.text.erb +0 -38
  208. data/app/views/spree/order_mailer/confirm_email.html.erb +0 -23
  209. data/app/views/spree/order_mailer/confirm_email.text.erb +0 -39
  210. data/app/views/spree/order_mailer/store_owner_notification_email.html.erb +0 -23
  211. data/app/views/spree/order_mailer/store_owner_notification_email.text.erb +0 -38
  212. data/app/views/spree/reimbursement_mailer/reimbursement_email.html.erb +0 -56
  213. data/app/views/spree/reimbursement_mailer/reimbursement_email.text.erb +0 -24
  214. data/app/views/spree/shared/_base_mailer_footer.html.erb +0 -12
  215. data/app/views/spree/shared/_base_mailer_header.html.erb +0 -13
  216. data/app/views/spree/shared/_base_mailer_stylesheets.html.erb +0 -456
  217. data/app/views/spree/shared/_error_messages.html.erb +0 -11
  218. data/app/views/spree/shared/_mailer_line_item.html.erb +0 -16
  219. data/app/views/spree/shared/_paths.html.erb +0 -8
  220. data/app/views/spree/shared/_purchased_items_table.html.erb +0 -69
  221. data/app/views/spree/shared/purchased_items_table/_adjustment.html.erb +0 -13
  222. data/app/views/spree/shared/purchased_items_table/_line_item.html.erb +0 -27
  223. data/app/views/spree/shared/purchased_items_table/_subtotal.html.erb +0 -13
  224. data/app/views/spree/shared/purchased_items_table/_total.html.erb +0 -13
  225. data/app/views/spree/shipment_mailer/shipped_email.html.erb +0 -36
  226. data/app/views/spree/shipment_mailer/shipped_email.text.erb +0 -17
  227. data/app/views/spree/test_mailer/test_email.html.erb +0 -40
  228. data/app/views/spree/test_mailer/test_email.text.erb +0 -4
  229. data/config/initializers/assets.rb +0 -2
  230. data/config/initializers/premailer_assets.rb +0 -1
  231. data/config/initializers/premailer_rails.rb +0 -3
  232. data/db/migrate/20140805171219_make_existing_credit_cards_default.rb +0 -10
  233. data/lib/generators/spree/dummy/templates/initializers/bullet.rb +0 -5
  234. data/lib/generators/spree/install/templates/vendor/assets/javascripts/spree/backend/all.js +0 -15
  235. data/lib/generators/spree/install/templates/vendor/assets/javascripts/spree/frontend/all.js +0 -16
  236. data/lib/generators/spree/install/templates/vendor/assets/stylesheets/spree/backend/all.css +0 -16
  237. data/lib/generators/spree/install/templates/vendor/assets/stylesheets/spree/frontend/all.css +0 -16
  238. data/lib/generators/spree/mailers_preview/mailers_preview_generator.rb +0 -23
  239. data/lib/generators/spree/mailers_preview/templates/mailers/previews/order_preview.rb +0 -13
  240. data/lib/generators/spree/mailers_preview/templates/mailers/previews/reimbursement_preview.rb +0 -5
  241. data/lib/generators/spree/mailers_preview/templates/mailers/previews/shipment_preview.rb +0 -5
  242. data/lib/generators/spree/mailers_preview/templates/mailers/previews/user_preview.rb +0 -11
  243. data/lib/tasks/email.rake +0 -10
  244. data/vendor/assets/javascripts/cleave.js +0 -1669
  245. data/vendor/assets/javascripts/fetch.umd.js +0 -531
  246. data/vendor/assets/javascripts/jquery.payment.js +0 -652
  247. data/vendor/assets/javascripts/jsuri.js +0 -458
  248. data/vendor/assets/javascripts/polyfill.min.js +0 -1
@@ -0,0 +1,17 @@
1
+ module Spree
2
+ module Account
3
+ class Create
4
+ prepend Spree::ServiceModule::Base
5
+
6
+ def call(user_params: {})
7
+ user = Spree.user_class.new(user_params)
8
+
9
+ if user.save
10
+ success(user)
11
+ else
12
+ failure(user)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ module Spree
2
+ module Account
3
+ class Update
4
+ prepend Spree::ServiceModule::Base
5
+
6
+ def call(user:, user_params: {})
7
+ if user.update(user_params)
8
+ success(user)
9
+ else
10
+ failure(user)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -6,7 +6,7 @@ module Spree
6
6
 
7
7
  LOCALE_REGEX = /^\/[A-Za-z]{2}\/|^\/[A-Za-z]{2}-[A-Za-z]{2}\/|^\/[A-Za-z]{2}$|^\/[A-Za-z]{2}-[A-Za-z]{2}$/.freeze
8
8
 
9
- SUPPORTED_PATHS_REGEX = /\/(products|t\/|cart|checkout|addresses|content)/.freeze
9
+ SUPPORTED_PATHS_REGEX = /\/(#{Spree::Config[:storefront_products_path]}|#{Spree::Config[:storefront_taxons_path]}\/|cart|checkout|addresses|content|#{Spree::Config[:storefront_pages_path]})/.freeze
10
10
 
11
11
  # rubocop:disable Lint/UnusedMethodArgument
12
12
  def call(url:, locale:, default_locale: nil)
@@ -6,14 +6,16 @@ module Spree
6
6
  def call(user:, store:, currency:, order_params: nil)
7
7
  order_params ||= {}
8
8
 
9
+ # we cannot create an order without store
10
+ return failure(:store_is_required) if store.nil?
11
+
9
12
  default_params = {
10
13
  user: user,
11
- store: store,
12
- currency: currency,
14
+ currency: currency || store.default_currency,
13
15
  token: Spree::GenerateToken.new.call(Spree::Order)
14
16
  }
15
17
 
16
- order = Spree::Order.create!(default_params.merge(order_params))
18
+ order = store.orders.create!(default_params.merge(order_params))
17
19
  success(order)
18
20
  end
19
21
  end
@@ -0,0 +1,40 @@
1
+ module Spree
2
+ module Cart
3
+ class Destroy
4
+ prepend Spree::ServiceModule::Base
5
+
6
+ def call(order:)
7
+ run :check_if_can_be_destroyed
8
+ run :cancel_shipments
9
+ run :void_payments
10
+ run :destroy_order
11
+ end
12
+
13
+ private
14
+
15
+ def check_if_can_be_destroyed(order:)
16
+ return failure(Spree.t(:cannot_be_destroyed)) unless order&.can_be_destroyed?
17
+
18
+ success(order: order)
19
+ end
20
+
21
+ def cancel_shipments(order:)
22
+ order.shipments.each(&:cancel!)
23
+
24
+ success(order: order)
25
+ end
26
+
27
+ def void_payments(order:)
28
+ order.payments.each(&:void!)
29
+
30
+ success(order: order)
31
+ end
32
+
33
+ def destroy_order(order:)
34
+ order.destroy
35
+
36
+ success(order)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,36 @@
1
+ module Spree
2
+ module Cart
3
+ class Empty
4
+ prepend Spree::ServiceModule::Base
5
+
6
+ def call(order:)
7
+ run :check_if_can_be_empty
8
+ run :empty_order
9
+ end
10
+
11
+ private
12
+
13
+ def check_if_can_be_empty(order:)
14
+ return failure(Spree.t(:cannot_empty)) if order.nil? || order.completed?
15
+
16
+ success(order: order)
17
+ end
18
+
19
+ def empty_order(order:)
20
+ ActiveRecord::Base.transaction do
21
+ order.line_items.destroy_all
22
+ order.updater.update_item_count
23
+ order.adjustments.destroy_all
24
+ order.shipments.destroy_all
25
+ order.state_changes.destroy_all
26
+ order.order_promotions.destroy_all
27
+ order.update_totals
28
+ order.persist_totals
29
+ order.restart_checkout_flow
30
+
31
+ success(order)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -4,7 +4,7 @@ module Spree
4
4
  prepend Spree::ServiceModule::Base
5
5
 
6
6
  def call(order:, country_iso: nil)
7
- country_id = country_id(country_iso)
7
+ country_id = country_id(order.store, country_iso)
8
8
  dummy_order = generate_dummy_order(order, country_id)
9
9
 
10
10
  packages = ::Spree::Stock::Coordinator.new(dummy_order).packages
@@ -20,11 +20,11 @@ module Spree
20
20
 
21
21
  private
22
22
 
23
- def country_id(country_iso)
23
+ def country_id(store, country_iso)
24
24
  if country_iso.present?
25
25
  ::Spree::Country.by_iso(country_iso)&.id
26
26
  else
27
- Spree::Config[:default_country_id]
27
+ store.default_country_id
28
28
  end
29
29
  end
30
30
 
@@ -23,7 +23,7 @@ module Spree
23
23
  payment_method = Spree::PaymentMethod::StoreCredit.available.first
24
24
  raise 'Store credit payment method could not be found' unless payment_method
25
25
 
26
- @order.user.store_credits.order_by_priority.each do |credit|
26
+ @order.user.store_credits.for_store(@order.store).order_by_priority.each do |credit|
27
27
  break if remaining_total.zero?
28
28
  next if credit.amount_remaining.zero?
29
29
 
@@ -0,0 +1,18 @@
1
+ module Spree
2
+ module Classifications
3
+ class Reposition
4
+ prepend Spree::ServiceModule::Base
5
+
6
+ def call(classification:, position:)
7
+ if position.is_a?(String) && !position.match(/^\d+$/)
8
+ return failure(nil, I18n.t('errors.messages.not_a_number'))
9
+ end
10
+
11
+ # Because position we get back is 0-indexed.
12
+ # acts_as_list is 1-indexed.
13
+ classification.insert_at(position.to_i + 1)
14
+ success(classification)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,41 @@
1
+ module Spree
2
+ module CreditCards
3
+ class Destroy
4
+ prepend Spree::ServiceModule::Base
5
+
6
+ def call(card:)
7
+ ApplicationRecord.transaction do
8
+ run :invalidate_payments
9
+ run :void_payments
10
+ run :destroy
11
+ end
12
+ end
13
+
14
+ protected
15
+
16
+ def invalidate_payments(card:)
17
+ payment_scope(card).checkout.each(&:invalidate!)
18
+
19
+ success(card: card)
20
+ end
21
+
22
+ def void_payments(card:)
23
+ payment_scope(card).where.not(state: :checkout).each(&:void!)
24
+
25
+ success(card: card)
26
+ end
27
+
28
+ def destroy(card:)
29
+ if card.destroy
30
+ success(card: card)
31
+ else
32
+ failure(card.errors.full_messages.to_sentance)
33
+ end
34
+ end
35
+
36
+ def payment_scope(card)
37
+ card.payments.valid.joins(:order).merge(Spree::Order.incomplete)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -2,6 +2,11 @@
2
2
  # Validates a field based on the maximum length of the underlying DB field, if there is one.
3
3
  class DbMaximumLengthValidator < ActiveModel::EachValidator
4
4
  def validate_each(record, attribute, value)
5
+ ActiveSupport::Deprecation.warn(<<-DEPRECATION, caller)
6
+ `DbMaximumLengthValidator` is deprecated and will be removed in Spree 5.0.
7
+ Please remove any `db_maximum_length: true` validations from your codebase
8
+ DEPRECATION
9
+
5
10
  limit = if defined?(Globalize)
6
11
  record.class.translation_class.columns_hash[attribute.to_s].limit
7
12
  else
@@ -1,6 +1,8 @@
1
1
  class EmailValidator < ActiveModel::EachValidator
2
+ EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
3
+
2
4
  def validate_each(record, attribute, value)
3
- unless value =~ /\A[^@\s]+@[^@\s]+\z/
5
+ unless value =~ EMAIL_REGEX
4
6
  record.errors.add(attribute, :invalid, **{ value: value }.merge!(options))
5
7
  end
6
8
  end
@@ -0,0 +1,25 @@
1
+ <% line_items.each do |item| %>
2
+ <%= item.variant.sku %> <%= raw(item.variant.product.name) %> <%= raw(item.variant.options_text) -%> (<%=item.quantity%>) <%= Spree.t('at_symbol') %> <%= item.single_money %> = <%= item.display_amount %>
3
+ <% end %>
4
+ ============================================================
5
+ <%= Spree.t('order_mailer.subtotal') %> <%= order.display_item_total %>
6
+ <% if order.line_item_adjustments.exists? %>
7
+ <% if order.all_adjustments.promotion.eligible.exists? %>
8
+ <% order.all_adjustments.promotion.eligible.group_by(&:label).each do |label, adjustments| %>
9
+ <%= Spree.t(:promotion) %>: <%= label %> <%= Spree::Money.new(adjustments.sum(&:amount), currency: order.currency) %>
10
+ <% end %>
11
+ <% end %>
12
+ <% end %>
13
+
14
+ <% order.shipments.group_by { |s| s.selected_shipping_rate.try(:name) }.each do |name, shipments| %>
15
+ <%= Spree.t(:shipping) %>: <%= name %> <%= Spree::Money.new(shipments.sum(&:discounted_cost), currency: order.currency) %>
16
+ <% end %>
17
+
18
+ <% if order.additional_tax_total != 0 %>
19
+ <%= Spree.t(:tax) %>: <%= order.display_additional_tax_total.to_html %>
20
+ <% end %>
21
+
22
+ <% order.adjustments.eligible.each do |adjustment| %>
23
+ <% next if (adjustment.source_type == 'Spree::TaxRate') and (adjustment.amount == 0) %>
24
+ <%= adjustment.label %> <%= adjustment.display_amount %>
25
+ <% end %>
@@ -3,3 +3,5 @@ class ActiveStorage::PurgeJob < ActiveStorage::BaseJob
3
3
  blob.purge unless blob.attachments.present?
4
4
  end
5
5
  end
6
+
7
+ Rails.application.config.active_storage.content_types_to_serve_as_binary.delete('image/svg+xml')
@@ -101,6 +101,7 @@ en:
101
101
  shipping_category: Shipping Category
102
102
  tax_category: Tax Category
103
103
  less_than: Less than
104
+ more_than: More than
104
105
  spree/promotion:
105
106
  advertise: Advertise
106
107
  code: Code
@@ -324,6 +325,22 @@ en:
324
325
  base:
325
326
  card_expired: "Card has expired"
326
327
  expiry_invalid: "Card expiration is invalid"
328
+ spree/legacy_user:
329
+ attributes:
330
+ bill_address_id:
331
+ belongs_to_other_user: belongs to other user
332
+ deprecated_in_completed_order: deprecated in completed order
333
+ ship_address_id:
334
+ belongs_to_other_user: belongs to other user
335
+ deprecated_in_completed_order: deprecated in completed order
336
+ spree/user:
337
+ attributes:
338
+ bill_address_id:
339
+ belongs_to_other_user: belongs to other user
340
+ deprecated_in_completed_order: deprecated in completed order
341
+ ship_address_id:
342
+ belongs_to_other_user: belongs to other user
343
+ deprecated_in_completed_order: deprecated in completed order
327
344
  spree/line_item:
328
345
  attributes:
329
346
  currency:
@@ -532,23 +549,96 @@ en:
532
549
  adjustment_total: Adjustment Total
533
550
  adjustments: Adjustments
534
551
  admin:
552
+ cms:
553
+ all_pages: All Pages
554
+ add_new_page: Add New Page
555
+ add_new_section: Add New Section
556
+ content: Content
557
+ click_here: click here
558
+ draft_mode: Draft Mode
559
+ full_width: Full width
560
+ link_to_taxon: Link to Taxon
561
+ title: Title
562
+ fit: Fit To
563
+ info_hero_image_body: "<p>The Hero Image section adds a large image with a button and tagline text to your page.</p>
564
+ <p>The button can link to a Product, Taxon or Page. This section can be set to fit within the central container or to the edges of the screen.</p>
565
+ <p><b>Tip:</b> Use a hero image with no button text or title, and then set the <b>Fit:</b> to <b>Container</b> and <b>Gutters</b> to <b>Use Gutters</b> this creates an image section that looks great above a Side-by-Side Images section, or an Image Gallery section.</p>
566
+ <p>Experiment with the settings, and don't be afraid to use more than one Hero Image section per page.</p>"
567
+ info_image_gallery_body: "<p>The Image Gallery section can be configured in several ways. For example, each image can link to a product or taxon. If you do not provide a link, you can display three images. Additionally, you can also use labels to add text to your images.</p>
568
+ <p>There are two layout configurations for the Image Gallery section, with the taller image used on the left or the right. You can also set this section to fit the edges of the screen or the central container to match your website's style.</p>"
569
+ info_product_carousel_body: "<p>Product Carousel is a simple section to use. Search for the taxon you wish to display, save the changes, and the products in your chosen taxon will be displayed on your page.</p>"
570
+ info_featured_article_body: "<p>The Feature Article section allows you to add rich text to your page with a set title subtitle and linking button.</p>
571
+ <p>This section can be set to use full screen or container and also use gutters.</p>"
572
+ info_side_by_side_images_body: "<p>The Side-by-Side Images section can be configured in several ways, you have the option of using them as plane images, images with text, and either of those options can be clickable links if a link is set.</p>
573
+ <p><b>Tip:</b> You can blow these images out to the edge of the screen and remove the gutters to create a completely different look.</p>"
574
+ info_rich_text_content_body: "<p>The Rich Text Content section is simply a section that offers nothing more than an area of rich text editor content to be displayed on your page.</p>"
575
+ brand_bar:
576
+ uses_menu: This section uses your Spree Menu named <b>%{menu}</b> to manage the images and links,
577
+ vist_menu_to_edit: to edit this menu.
578
+ full_width_on_small: Full width on small devices
579
+ button_text: Button Text
580
+ go_to_fullscreen_section_manager: Go To Fullscreen Section Manager
581
+ page_type: Page Type
582
+ gutters: Gutters
583
+ you_have_no_pages: You have no Pages, click the <b>+ Add New Page</b> button to get started.
584
+ new_page: New Page
585
+ toggle_page_visibility: Toggle page visibility
586
+ meta_title: Meta Title
587
+ meta_description: Meta Description
588
+ preview_page: Preview Page
589
+ full_screen_mode: '<span class="exit">Exit </span>Full Screen Mode'
590
+ hero:
591
+ aspect_ratio: Please use an image with the aspect ratio of 12:5 (2400px x 1000px)
592
+ select_page_type: Select a page type
593
+ section_type: Section Type
594
+ subtitle: Subtitle
595
+ set_gutters: Set Gutters
596
+ click_button_to_change_page_type: Click the <b>%{button_type}</b> button to load the options for this page type.
597
+ more_page_settings: '<span class="more">More</span><span class="less">Less</span> Page Settings'
598
+ seo_settings: SEO Settings
599
+ no_sections_found_please_add_one: Add your first section to this page by clicking the <b>+ Add New Section</b> button above.
600
+ click_create_to_load_new_link: 'Click the <b>Create</b> button below to save your new page section, and load the section settings.'
601
+ click_update_to_load_new_link: 'Click the <b>Update</b> button below to load the new section settings.'
602
+ settings_for: 'Options For: <b>%{section}</b>'
603
+ page_sections: '%{page_name} Sections'
604
+ page_sections_info: 'The area below represents your %{page_type} displayed in %{store}, add sections and drag them into position'
605
+ visible: Visible
606
+ side_by_side:
607
+ left_image: Left Image
608
+ right_image: Right Image
609
+ image_info: 'Please use an image with an aspect ratio of 54:35 (1468px x 952px).'
610
+ image_gallery:
611
+ display_labels: Display labels
612
+ image_a: Image A
613
+ image_b: Image B
614
+ image_c: Image C
615
+ layout_style: Layout Style
616
+ square_image: Please use an image with an aspect ratio of 18:13 (1080px x 780px).
617
+ tall_image: Please use an image with an aspect ratio of 27:40 (1080px x 1600px).
618
+ linkable:
619
+ seach_for_a_page: Search for a page
535
620
  tab:
536
621
  configuration: Configuration
622
+ content: Content
537
623
  option_types: Option Types
538
624
  orders: Orders
539
625
  overview: Overview
626
+ pages: Pages
540
627
  products: Products
541
628
  promotions: Promotions
542
629
  promotion_categories: Promotion Categories
543
630
  properties: Properties
544
631
  prototypes: Prototypes
545
632
  reports: Reports
633
+ navigation: Navigation
546
634
  taxonomies: Taxonomies
547
635
  taxons: Taxons
548
636
  users: Users
549
637
  return_authorizations: Return Authorizations
550
638
  customer_returns: Customer Returns
551
639
  order:
640
+ changing_store_warning: If you change the store this order belongs to, the order will be reset.
641
+ once_an_order_is_complete_you_can_not_change_store: 'Sorry, once an order is complete, you can no longer change the store that the order belongs to.'
552
642
  events:
553
643
  approve: approve
554
644
  cancel: cancel
@@ -556,6 +646,8 @@ en:
556
646
  resend: Resend
557
647
  orders:
558
648
  cart: Cart
649
+ reports:
650
+ for: For %{store_name}
559
651
  return_authorization:
560
652
  product: Product
561
653
  user:
@@ -571,7 +663,57 @@ en:
571
663
  store_credits: Store Credits
572
664
  no_store_credit: User has no Store Credit available.
573
665
  available_store_credit: User has %{amount} in Store Credit available.
666
+ navigation:
667
+ all_menus: All Menus
668
+ add_new_menu: Add New Menu
669
+ add_new_item: 'Add New Item'
670
+ code: Code
671
+ default_menus_info:
672
+ title: Default Menus
673
+ body: "Default menus are menus whose language matches the associated store's default language.<br><br>
674
+ <h5>Example</h5>If you have a store that uses Spanish as the default language but also offers the options of German and French; your default header menu for this store would be set to use <b>Español (es)</b> for the language and <b>Header</b> as the location.<br><br>
675
+ <h5>Why Are Default Menus Important?</h5> Default menus are displayed to your visitor if no menu is available in the current language they are browsing. It is recommended that you create a default menu for each menu location within each store.<br><br>
676
+ <h5>More Information</h5>To learn more about menus, view the official Spree user documentation by <a href='https://guides.spreecommerce.org/user/navigation/building_the_main_menu.html' target='_blank' class='alert-link'>clicking here</a>."
677
+ allow_this_menu_item_to_contain_nested_menu_items: Allow this Menu Item to contain nested items
678
+ back_to_all_menus: Back To All Menus
679
+ click_create_to_load_new_link: 'Click the <b>Create</b> button below to change the link field.'
680
+ click_update_to_load_new_link: 'Click the <b>Update</b> button below to change the link field.'
681
+ give_your_menu_a_unique_name: 'Use the unique code to identify your menu: spree-eu-main'
682
+ link_settings: Link Settings
683
+ link_to: Link To
684
+ image_alt_text: Add alt text to your image
685
+ image_asset: Add a Promotion image or Link icon.
686
+ move_could_not_be_saved: 'ERROR: This move could not be saved.'
687
+ managing_by_store_title: 'Managing Menus By Store'
688
+ managing_by_store: <p>You are managing the menus for <b>%{store}</b>. To manage menus for other stores, change the global store using the drop-down in the main navbar found at the top of the screen.</p>
689
+ new_menu_item: New Menu Item
690
+ new_menu: New Menu
691
+ nested_under: Nested under
692
+ no_menu_items: '<b>%{menu}</b> has no items. Click the <b>Add New Item</b> button to begin adding links to this menu.'
693
+ nested_under_info: Quickly nest your Menu Item if you already know where it needs to be.
694
+ item_type: Item Type
695
+ image_info: '<b>NOTE:</b> You can attach an image to any menu item, but your image will only be displayed in the main menu when nested inside a container with the code <b>promo</b>.<br><br> For best results use images with a width of 540px and height of 350px.'
696
+ open_link_in_new_window: Open this link in a new window
697
+ menu_item_type_container_message: "Containers are menu items that do not link to a destination. If you are building the Spree Main Menu
698
+ create containers with the code: <b>category</b> or <b>promo</b>, and then nest your links inside these containers build out your menu.
699
+ <br><br> For an indepth guide to building the main menu see the documenttation page <a href='https://guides.spreecommerce.org/user/navigation/building_the_main_menu.html' target='_blank' class='alert-link'>Building The Main Menu</a>"
700
+ menus: Menus
701
+ menu_items: '%{menu_name} Items'
702
+ public_details: Public Details
703
+ subtitle: Subtitle
704
+ url_info: 'The URL field can link to an external website using <b>https://example.com</b>, link to an otherwise unreachable internal path using <b>/policies/privacy</b>,
705
+ launch an email client using <b>mailto:sales@example.com</b> or used to create a clickable phone number with <b>tel:123456789</b>'
706
+ seach_for_a_product: Search for a Product
707
+ seach_for_a_taxon: Search for a Taxon
708
+ settings: Settings
709
+ set_a_code: "Adding a code is optional but can be useful if you need to identify this menu item. When building
710
+ the Spree main menu use the code <b>category</b> or <b>promo</b> to create the containers that organize links and promotions appropriately. To learn more view the documentation by <a href='https://guides.spreecommerce.org/user/navigation/add_menu_items.html' target='_blank' class='alert-link'>clicking here</a>."
711
+ type: Type
712
+ used_in: Used In
713
+ you_have_no_menus: You have no Menus, click the Add New Menu button to create your first Menu.
714
+ this_link_takes_you_to_your_stores_home_page: This link takes you to your stores home page.
574
715
  administration: Administration
716
+ add_new_store: Add New Store
575
717
  advertise: Advertise
576
718
  agree_to_privacy_policy: Agree to Privacy Policy
577
719
  agree_to_terms_of_service: Agree to Terms of Service
@@ -629,6 +771,8 @@ en:
629
771
  canceled: Canceled
630
772
  canceler: Canceler
631
773
  canceled_at: Canceled at
774
+ cannot_be_destroyed: Order cannot be destroyed.
775
+ cannot_empty: Cannot empty order.
632
776
  cannot_empty_completed_order: Order has already been processed so it cannot be emptied
633
777
  cannot_create_payment_without_payment_methods: You cannot create a payment for an order without any payment methods defined.
634
778
  cannot_create_customer_returns: Cannot create customer returns as this order has no shipped units.
@@ -669,7 +813,7 @@ en:
669
813
  checkout_page:
670
814
  main_navigation: Main navigation
671
815
  checkout_navigation: Checkout navigation
672
- back_to_cart: back to the cart
816
+ back_to_cart: back to cart
673
817
  delivery_method: delivery method
674
818
  header: Checkout
675
819
  product: Product
@@ -736,6 +880,7 @@ en:
736
880
  created_by: Created By
737
881
  credit: Credit
738
882
  credit_card: Credit Card
883
+ credit_card_remove_confirmation: Are you sure you want to delete the credit card?
739
884
  credit_cards: Credit Cards
740
885
  credit_owed: Credit Owed
741
886
  credited: Credited
@@ -788,6 +933,7 @@ en:
788
933
  display: Display
789
934
  doesnt_track_inventory: It doesn't track inventory
790
935
  dont_have_account: No account?
936
+ draft_mode: Draft Mode
791
937
  edit: Edit
792
938
  editing_resource: 'Editing %{resource}'
793
939
  editing_rma_reason: Editing RMA Reason
@@ -856,6 +1002,8 @@ en:
856
1002
  existing_shipments: Existing shipments
857
1003
  facebook: Facebook
858
1004
  failed_payment_attempts: Failed Payment Attempts
1005
+ favicon: 'Favicon'
1006
+ favicon_upload_info: "File format: PNG or ICO. File resolution: up to 256x256. File size: up to 1MB"
859
1007
  filename: Filename
860
1008
  fill_in_customer_info: Please fill in customer info
861
1009
  filter: Filter
@@ -915,6 +1063,7 @@ en:
915
1063
  icon: Icon
916
1064
  image: Image
917
1065
  images: Images
1066
+ image_alt_text: Add Alt text to your image
918
1067
  implement_eligible_for_return: "Must implement #eligible_for_return? for your EligibilityValidator."
919
1068
  implement_requires_manual_intervention: "Must implement #requires_manual_intervention? for your EligibilityValidator."
920
1069
  in_stock: In Stock
@@ -964,6 +1113,7 @@ en:
964
1113
  items_to_be_reimbursed: Items to be reimbursed
965
1114
  items_reimbursed: Items reimbursed
966
1115
  join_slack: Join Slack
1116
+ language: Language
967
1117
  last_name: Last Name
968
1118
  lastname: Last Name
969
1119
  last_name_begins_with: Last Name Begins With
@@ -1005,6 +1155,7 @@ en:
1005
1155
  match_choices:
1006
1156
  all: All
1007
1157
  none: None
1158
+ max: 'Max'
1008
1159
  max_items: Max Items
1009
1160
  member_since: Member Since
1010
1161
  memo: Memo
@@ -1013,6 +1164,7 @@ en:
1013
1164
  meta_title: Meta Title
1014
1165
  metadata: Metadata
1015
1166
  mutable: Mutable
1167
+ min: 'Min'
1016
1168
  minimal_amount: Minimal Amount
1017
1169
  missing_return_authorization: ! 'Missing Return Authorization for %{item_name}.'
1018
1170
  month: Month
@@ -1121,6 +1273,7 @@ en:
1121
1273
  open: Open
1122
1274
  open_all_adjustments: Open All Adjustments
1123
1275
  option_type: Option Type
1276
+ option_type_filterable_info: 'When an option type is set to Filterable, your storefront visitors are presented with the option to filter a taxon of products based on the option type. A typical example of this would be to filter clothing by size and color.<br><br><b>Please Note:</b> Filters will only be visible in the storefront taxons that contain products with this option type set.'
1124
1277
  option_type_placeholder: Choose an option type
1125
1278
  option_types: Option Types
1126
1279
  option_value: Option Value
@@ -1257,6 +1410,8 @@ en:
1257
1410
  price: price
1258
1411
  price_high_to_low: PRICE (HIGH - LOW)
1259
1412
  price_low_to_high: PRICE (LOW - HIGH)
1413
+ name_a_z: NAME (A-Z)
1414
+ name_z_a: NAME (Z-A)
1260
1415
  result: RESULT
1261
1416
  results_for: RESULTS FOR
1262
1417
  size: SIZE
@@ -1281,6 +1436,7 @@ en:
1281
1436
  price_sack: Price Sack
1282
1437
  process: Process
1283
1438
  product: Product
1439
+ product_name: Product Name
1284
1440
  product_details: Product Details
1285
1441
  product_has_no_description: This product has no description
1286
1442
  product_not_available_in_this_currency: This product is not available in the selected currency.
@@ -1457,6 +1613,8 @@ en:
1457
1613
  say_yes: 'Yes'
1458
1614
  scope: Scope
1459
1615
  search: Search
1616
+ search_by: 'Search by:'
1617
+ search_order_number: Order Number
1460
1618
  search_results: Search results for '%{keywords}'
1461
1619
  searching: Searching
1462
1620
  secure_connection_type: Secure Connection Type
@@ -1470,6 +1628,7 @@ en:
1470
1628
  select_a_store_credit_reason: Select a reason for the store credit
1471
1629
  select_an_option: Select an option
1472
1630
  select_stock: Select stock
1631
+ select_stores: Select Store(s)
1473
1632
  selected_quantity_not_available: ! 'selected of %{item} is not available.'
1474
1633
  send_copy_of_all_mails_to: Send Copy of All Mails To
1475
1634
  send_mails_as: Send Mails As
@@ -1623,7 +1782,6 @@ en:
1623
1782
  customer_support_email_help: "This email is visible to your Store visitors in the Footer section"
1624
1783
  new_order_notifications_email_help: "If you want to receive an email notification every time someone places an Order please provide an email address for that notification to be sent to"
1625
1784
  seo_robots: "Please check <a href='https://developers.google.com/search/reference/robots_meta_tag' target='_blank'>this page for more help</a>"
1626
- store_set_default_button: Set as default
1627
1785
  stores: Stores
1628
1786
  store_credit_name: Store Credit
1629
1787
  store_credit:
@@ -1670,6 +1828,7 @@ en:
1670
1828
  successfully_removed: ! '%{resource} has been successfully removed!'
1671
1829
  successfully_updated: ! '%{resource} has been successfully updated!'
1672
1830
  summary: Summary
1831
+ support: Support
1673
1832
  supported_currencies: Supported Currencies
1674
1833
  supported_currencies_long: A comma separated list of supported currencies
1675
1834
  supported_locales: Supported Locales
@@ -1706,6 +1865,7 @@ en:
1706
1865
  message: If you have received this email, then your email settings are correct.
1707
1866
  subject: Test Mail
1708
1867
  test_mode: Test Mode
1868
+ this_menu_already_has_a_root_item: This Menu already has a root item
1709
1869
  thank_you_for_your_order: Thank you for your business. Please print out a copy of this confirmation page for your records.
1710
1870
  there_are_no_items_for_this_order: There are no items for this order. Please add an item to the order to continue.
1711
1871
  there_were_problems_with_the_following_fields: There were problems with the following fields
@@ -1770,6 +1930,10 @@ en:
1770
1930
  variants: Variants
1771
1931
  version: Version
1772
1932
  void: Void
1933
+ we_will_be_back: We will be back.
1934
+ we_are_busy_updating: "We're updating the %{store_name} homepage."
1935
+ we_are_busy_updating_page: "We're busy updating this page."
1936
+ please_check_back_soon: Please check back soon.
1773
1937
  weight: Weight
1774
1938
  what_is_a_cvv: What is a (CVV) Credit Card Code?
1775
1939
  what_is_this: What's This?