spree_core 4.1.9 → 4.2.0.beta

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 (79) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/spree/base_controller.rb +1 -0
  3. data/app/helpers/spree/base_helper.rb +23 -2
  4. data/app/helpers/spree/mail_helper.rb +24 -0
  5. data/app/mailers/spree/base_mailer.rb +17 -3
  6. data/app/mailers/spree/order_mailer.rb +11 -2
  7. data/app/mailers/spree/reimbursement_mailer.rb +4 -2
  8. data/app/mailers/spree/shipment_mailer.rb +4 -2
  9. data/app/models/concerns/spree/default_price.rb +2 -1
  10. data/app/models/concerns/spree/user_methods.rb +11 -5
  11. data/app/models/spree/app_configuration.rb +5 -0
  12. data/app/models/spree/line_item.rb +10 -1
  13. data/app/models/spree/option_type.rb +5 -1
  14. data/app/models/spree/order.rb +26 -5
  15. data/app/models/spree/price.rb +26 -2
  16. data/app/models/spree/product.rb +17 -7
  17. data/app/models/spree/promotion_handler/coupon.rb +1 -1
  18. data/app/models/spree/reimbursement.rb +2 -0
  19. data/app/models/spree/shipment.rb +2 -5
  20. data/app/models/spree/stock_location.rb +13 -2
  21. data/app/models/spree/store.rb +19 -2
  22. data/app/models/spree/variant.rb +15 -2
  23. data/app/presenters/spree/variant_presenter.rb +7 -0
  24. data/app/presenters/spree/variants/option_types_presenter.rb +1 -0
  25. data/app/views/layouts/spree/base_mailer.html.erb +45 -40
  26. data/app/views/spree/order_mailer/cancel_email.html.erb +19 -25
  27. data/app/views/spree/order_mailer/cancel_email.text.erb +24 -2
  28. data/app/views/spree/order_mailer/confirm_email.html.erb +18 -65
  29. data/app/views/spree/order_mailer/confirm_email.text.erb +2 -1
  30. data/app/views/spree/order_mailer/store_owner_notification_email.html.erb +23 -0
  31. data/app/views/spree/order_mailer/store_owner_notification_email.text.erb +38 -0
  32. data/app/views/spree/reimbursement_mailer/reimbursement_email.html.erb +53 -58
  33. data/app/views/spree/reimbursement_mailer/reimbursement_email.text.erb +3 -1
  34. data/app/views/spree/shared/_base_mailer_footer.html.erb +6 -14
  35. data/app/views/spree/shared/_base_mailer_header.html.erb +12 -32
  36. data/app/views/spree/shared/_base_mailer_stylesheets.html.erb +293 -625
  37. data/app/views/spree/shared/_purchased_items_table.html.erb +60 -0
  38. data/app/views/spree/shared/purchased_items_table/_adjustment.html.erb +13 -0
  39. data/app/views/spree/shared/purchased_items_table/_line_item.html.erb +27 -0
  40. data/app/views/spree/shared/purchased_items_table/_subtotal.html.erb +13 -0
  41. data/app/views/spree/shared/purchased_items_table/_total.html.erb +13 -0
  42. data/app/views/spree/shipment_mailer/shipped_email.html.erb +31 -36
  43. data/app/views/spree/shipment_mailer/shipped_email.text.erb +2 -1
  44. data/config/initializers/assets.rb +1 -0
  45. data/config/locales/en.yml +113 -13
  46. data/db/default/spree/stores.rb +11 -10
  47. data/db/migrate/20140309033438_create_store_from_preferences.rb +1 -1
  48. data/db/migrate/20191017121054_add_supported_currencies_to_store.rb +10 -0
  49. data/db/migrate/20200102141311_add_social_to_spree_stores.rb +3 -0
  50. data/db/migrate/20200308210757_add_default_locale_to_spree_store.rb +7 -0
  51. data/db/migrate/20200310145140_add_customer_support_email_to_spree_store.rb +7 -0
  52. data/db/migrate/20200421095017_add_compare_at_amount_to_spree_prices.rb +7 -0
  53. data/db/migrate/20200423123001_add_default_country_id_to_spree_store.rb +9 -0
  54. data/db/migrate/20200430072209_add_footer_fields_to_spree_stores.rb +8 -0
  55. data/db/migrate/20200513154939_add_show_property_to_spree_product_properties.rb +5 -0
  56. data/db/migrate/20200607161221_add_store_owner_order_notification_delivered_to_spree_orders.rb +7 -0
  57. data/db/migrate/20200607161222_add_new_order_notifications_email_to_spree_stores.rb +7 -0
  58. data/db/migrate/20200826075557_add_unique_index_on_taxon_id_and_product_id_to_spree_products_taxons.rb +5 -0
  59. data/lib/generators/spree/install/templates/vendor/assets/javascripts/spree/backend/all.js +0 -2
  60. data/lib/generators/spree/install/templates/vendor/assets/javascripts/spree/frontend/all.js +0 -2
  61. data/lib/generators/spree/mailers_preview/mailers_preview_generator.rb +23 -0
  62. data/lib/generators/spree/mailers_preview/templates/mailers/previews/order_preview.rb +13 -0
  63. data/lib/generators/spree/mailers_preview/templates/mailers/previews/reimbursement_preview.rb +5 -0
  64. data/lib/generators/spree/mailers_preview/templates/mailers/previews/shipment_preview.rb +5 -0
  65. data/lib/generators/spree/mailers_preview/templates/mailers/previews/user_preview.rb +11 -0
  66. data/lib/spree/core.rb +1 -0
  67. data/lib/spree/core/controller_helpers/common.rb +1 -0
  68. data/lib/spree/core/controller_helpers/currency_helpers.rb +15 -0
  69. data/lib/spree/core/controller_helpers/store.rb +12 -1
  70. data/lib/spree/core/version.rb +1 -1
  71. data/lib/spree/permitted_attributes.rb +7 -4
  72. data/lib/spree/testing_support/authorization_helpers.rb +7 -4
  73. data/lib/spree/testing_support/factories/store_factory.rb +11 -8
  74. data/spree_core.gemspec +4 -4
  75. data/vendor/assets/javascripts/cleave.js +1669 -0
  76. metadata +37 -14
  77. data/app/views/spree/order_mailer/_adjustment.html.erb +0 -8
  78. data/app/views/spree/order_mailer/_subtotal.html.erb +0 -8
  79. data/app/views/spree/order_mailer/_total.html.erb +0 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 735a7c4cad6166518bb05cc45fcc5a2f303e1b4a11f5ec9ae1e17a6df5916142
4
- data.tar.gz: a62c2b5fec62e7c9bf7971198f3805c573785c9e9768d88c61b3ae89b578c31d
3
+ metadata.gz: dd3e3f16eb808f16f592360085f02f1382ee4ddd6ee0903c3eb8a8079e5d8bad
4
+ data.tar.gz: 8567b7555de6f0f578d6277e6943af11b68329e5e17a77d13c7e66085e7fe09f
5
5
  SHA512:
6
- metadata.gz: 25b68dc35a114eaa937dc25fc06576065d8b56baa23d4839cdfa401c08fb5f85638e65d924cba0f9f84b9585761eb3855cf938811c288578968aee2d0ef3e2bb
7
- data.tar.gz: 67270a8f7d20847ddcced170c3ebb82b419d89ffff202905d4a9161b13cd526a954b67367bf925133822a0903e5a7a41e81f2f11e4abadf7d9b375b5bdf54793
6
+ metadata.gz: 113900d45a999bb7aa47209797e8ab47a5ed6f40caa445242952eac3a604cc43bc658fec8fb86dc148743032f71341d97331cd7d6d7b77d84df36ffc979f122b
7
+ data.tar.gz: a175395cbe157f6ca1704ab5bdacbbf5c9abbee4bdae89f19363c06fc7a1fe06610fab87347342ecddd297d3bf22bf9354116340e8e408270a4f968a78883a0e
@@ -7,6 +7,7 @@ class Spree::BaseController < ApplicationController
7
7
  include Spree::Core::ControllerHelpers::Search
8
8
  include Spree::Core::ControllerHelpers::Store
9
9
  include Spree::Core::ControllerHelpers::StrongParameters
10
+ include Spree::Core::ControllerHelpers::CurrencyHelpers
10
11
 
11
12
  respond_to :html
12
13
  end
@@ -22,6 +22,13 @@ module Spree
22
22
  to_html
23
23
  end
24
24
 
25
+ def display_compare_at_price(product_or_variant)
26
+ product_or_variant.
27
+ price_in(current_currency).
28
+ display_compare_at_price_including_vat_for(current_price_options).
29
+ to_html
30
+ end
31
+
25
32
  def link_to_tracking(shipment, options = {})
26
33
  return unless shipment.tracking && shipment.shipping_method
27
34
 
@@ -34,7 +41,15 @@ module Spree
34
41
  end
35
42
  end
36
43
 
37
- def logo(image_path = Spree::Config[:logo], options = {})
44
+ def logo(image_path = nil, options = {})
45
+ image_path ||= if current_store.logo.attached? && current_store.logo.variable?
46
+ main_app.url_for(current_store.logo.variant(resize: '244x104>'))
47
+ elsif current_store.logo.attached? && current_store.logo.image?
48
+ main_app.url_for(current_store.logo)
49
+ else
50
+ Spree::Config[:logo]
51
+ end
52
+
38
53
  path = spree.respond_to?(:root_path) ? spree.root_path : main_app.root_path
39
54
 
40
55
  link_to path, 'aria-label': current_store.name, method: options[:method] do
@@ -97,7 +112,13 @@ module Spree
97
112
  def pretty_time(time)
98
113
  return '' if time.blank?
99
114
 
100
- [I18n.l(time.to_date, format: :long), time.strftime('%l:%M %p')].join(' ')
115
+ [I18n.l(time.to_date, format: :long), time.strftime('%l:%M %p %Z')].join(' ')
116
+ end
117
+
118
+ def pretty_date(date)
119
+ return '' if date.blank?
120
+
121
+ [I18n.l(date.to_date, format: :long)].join(' ')
101
122
  end
102
123
 
103
124
  def seo_url(taxon, options = nil)
@@ -0,0 +1,24 @@
1
+ module Spree
2
+ module MailHelper
3
+ include BaseHelper
4
+
5
+ def variant_image_url(variant)
6
+ image = default_image_for_product_or_variant(variant)
7
+ image ? main_app.url_for(image.url(:small)) : 'noimage/small.png'
8
+ end
9
+
10
+ def name_for(order)
11
+ order.name || Spree.t('customer')
12
+ end
13
+
14
+ def logo_path
15
+ if current_store.present? && current_store.logo.attached? && current_store.logo.variable?
16
+ main_app.url_for(current_store.logo.variant(resize: '244x104>'))
17
+ elsif current_store.present? && current_store.logo.attached? && current_store.logo.image?
18
+ main_app.url_for(current_store.logo)
19
+ else
20
+ Spree::Config.mailer_logo || Spree::Config.logo
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,10 +1,18 @@
1
1
  module Spree
2
2
  class BaseMailer < ActionMailer::Base
3
+ add_template_helper(MailHelper)
4
+
5
+ def current_store
6
+ @current_store ||= Spree::Store.current
7
+ end
8
+ helper_method :current_store
9
+
3
10
  def from_address
4
- Spree::Store.current.mail_from_address
11
+ current_store.mail_from_address
5
12
  end
6
13
 
7
- def money(amount, currency = Spree::Config[:currency])
14
+ def money(amount, currency = nil)
15
+ currency ||= current_store.default_currency
8
16
  Spree::Money.new(amount, currency: currency).to_s
9
17
  end
10
18
  helper_method :money
@@ -16,6 +24,7 @@ module Spree
16
24
 
17
25
  def mail(headers = {}, &block)
18
26
  ensure_default_action_mailer_url_host
27
+ set_email_locale
19
28
  super if Spree::Config[:send_core_emails]
20
29
  end
21
30
 
@@ -26,7 +35,12 @@ module Spree
26
35
  # http://guides.rubyonrails.org/action_mailer_basics.html#generating-urls-in-action-mailer-views
27
36
  def ensure_default_action_mailer_url_host
28
37
  ActionMailer::Base.default_url_options ||= {}
29
- ActionMailer::Base.default_url_options[:host] ||= Spree::Store.current.url
38
+ ActionMailer::Base.default_url_options[:host] ||= current_store.url
39
+ end
40
+
41
+ def set_email_locale
42
+ locale = @order&.store&.default_locale || current_store&.default_locale
43
+ I18n.locale = locale if locale.present?
30
44
  end
31
45
  end
32
46
  end
@@ -2,15 +2,24 @@ module Spree
2
2
  class OrderMailer < BaseMailer
3
3
  def confirm_email(order, resend = false)
4
4
  @order = order.respond_to?(:id) ? order : Spree::Order.find(order)
5
+ current_store = @order.store
5
6
  subject = (resend ? "[#{Spree.t(:resend).upcase}] " : '')
6
- subject += "#{Spree::Store.current.name} #{Spree.t('order_mailer.confirm_email.subject')} ##{@order.number}"
7
+ subject += "#{current_store.name} #{Spree.t('order_mailer.confirm_email.subject')} ##{@order.number}"
7
8
  mail(to: @order.email, from: from_address, subject: subject)
8
9
  end
9
10
 
11
+ def store_owner_notification_email(order)
12
+ @order = order.respond_to?(:id) ? order : Spree::Order.find(order)
13
+ current_store = @order.store
14
+ subject = Spree.t('order_mailer.store_owner_notification_email.subject', store_name: current_store.name)
15
+ mail(to: current_store.new_order_notifications_email, from: from_address, subject: subject)
16
+ end
17
+
10
18
  def cancel_email(order, resend = false)
11
19
  @order = order.respond_to?(:id) ? order : Spree::Order.find(order)
20
+ current_store = @order.store
12
21
  subject = (resend ? "[#{Spree.t(:resend).upcase}] " : '')
13
- subject += "#{Spree::Store.current.name} #{Spree.t('order_mailer.cancel_email.subject')} ##{@order.number}"
22
+ subject += "#{current_store.name} #{Spree.t('order_mailer.cancel_email.subject')} ##{@order.number}"
14
23
  mail(to: @order.email, from: from_address, subject: subject)
15
24
  end
16
25
  end
@@ -2,9 +2,11 @@ module Spree
2
2
  class ReimbursementMailer < BaseMailer
3
3
  def reimbursement_email(reimbursement, resend = false)
4
4
  @reimbursement = reimbursement.respond_to?(:id) ? reimbursement : Spree::Reimbursement.find(reimbursement)
5
+ @order = @reimbursement.order
6
+ current_store = @reimbursement.store || Spree::Store.current
5
7
  subject = (resend ? "[#{Spree.t(:resend).upcase}] " : '')
6
- subject += "#{Spree::Store.current.name} #{Spree.t('reimbursement_mailer.reimbursement_email.subject')} ##{@reimbursement.order.number}"
7
- mail(to: @reimbursement.order.email, from: from_address, subject: subject)
8
+ subject += "#{current_store.name} #{Spree.t('reimbursement_mailer.reimbursement_email.subject')} ##{@order.number}"
9
+ mail(to: @order.email, from: current_store.mail_from_address, subject: subject)
8
10
  end
9
11
  end
10
12
  end
@@ -2,9 +2,11 @@ module Spree
2
2
  class ShipmentMailer < BaseMailer
3
3
  def shipped_email(shipment, resend = false)
4
4
  @shipment = shipment.respond_to?(:id) ? shipment : Spree::Shipment.find(shipment)
5
+ @order = @shipment.order
6
+ current_store = @shipment.store
5
7
  subject = (resend ? "[#{Spree.t(:resend).upcase}] " : '')
6
- subject += "#{Spree::Store.current.name} #{Spree.t('shipment_mailer.shipped_email.subject')} ##{@shipment.order.number}"
7
- mail(to: @shipment.order.email, from: from_address, subject: subject)
8
+ subject += "#{current_store.name} #{Spree.t('shipment_mailer.shipped_email.subject')} ##{@order.number}"
9
+ mail(to: @order.email, from: from_address, subject: subject)
8
10
  end
9
11
  end
10
12
  end
@@ -9,7 +9,8 @@ module Spree
9
9
  dependent: :destroy
10
10
 
11
11
  delegate :display_price, :display_amount, :price, :currency, :price=,
12
- :price_including_vat_for, :currency=, to: :find_or_build_default_price
12
+ :price_including_vat_for, :currency=, :display_compare_at_price,
13
+ :compare_at_price, :compare_at_price=, to: :find_or_build_default_price
13
14
 
14
15
  after_save :save_default_price
15
16
 
@@ -30,15 +30,20 @@ module Spree
30
30
  self.whitelisted_ransackable_associations = %w[bill_address ship_address]
31
31
  self.whitelisted_ransackable_attributes = %w[id email]
32
32
 
33
+ def self.with_email(query)
34
+ where('email LIKE ?', "%#{query}%")
35
+ end
36
+
33
37
  def self.with_address(query, address = :ship_address)
34
38
  left_outer_joins(address).
35
39
  where("#{Spree::Address.table_name}.firstname like ?", "%#{query}%").
36
40
  or(left_outer_joins(address).where("#{Spree::Address.table_name}.lastname like ?", "%#{query}%"))
37
41
  end
38
42
 
39
- def self.with_email_or_addresses_ids(query, addresses_ids = [])
40
- where('email LIKE ?', "%#{query}%").
41
- or(where(id: addresses_ids))
43
+ def self.with_email_or_address(email, address)
44
+ left_outer_joins(:addresses).
45
+ where("#{Spree::Address.table_name}.firstname LIKE ? or #{Spree::Address.table_name}.lastname LIKE ? or email LIKE ?",
46
+ "%#{address}%", "%#{address}%", "%#{email}%")
42
47
  end
43
48
  end
44
49
 
@@ -54,8 +59,9 @@ module Spree
54
59
  first
55
60
  end
56
61
 
57
- def total_available_store_credit
58
- store_credits.reload.to_a.sum(&:amount_remaining)
62
+ def total_available_store_credit(currency = nil)
63
+ currency ||= Spree::Config[:currency]
64
+ store_credits.where(currency: currency).reload.to_a.sum(&:amount_remaining)
59
65
  end
60
66
 
61
67
  private
@@ -49,6 +49,7 @@ module Spree
49
49
  preference :expedited_exchanges_days_window, :integer, default: 14 # the amount of days the customer has to return their item after the expedited exchange is shipped in order to avoid being charged
50
50
  preference :layout, :string, default: 'spree/layouts/spree_application'
51
51
  preference :logo, :string, default: 'logo/spree_50.png'
52
+ preference :mailer_logo, :string, default: 'logo/spree_50.png'
52
53
  preference :max_level_in_taxons_menu, :integer, default: 1 # maximum nesting level in taxons menu
53
54
  preference :products_per_page, :integer, default: 12
54
55
  preference :require_master_price, :boolean, default: true
@@ -67,6 +68,10 @@ module Spree
67
68
  preference :non_expiring_credit_types, :array, default: []
68
69
  preference :credit_to_new_allocation, :boolean, default: false
69
70
 
71
+ # Multi currency configurations
72
+ preference :allow_currency_change, :boolean, default: false
73
+ preference :show_currency_selector, :boolean, default: false
74
+
70
75
  # searcher_class allows spree extension writers to provide their own Search class
71
76
  def searcher_class
72
77
  @searcher_class ||= Spree::Core::Search::Base
@@ -57,7 +57,16 @@ module Spree
57
57
  end
58
58
 
59
59
  def update_price
60
- self.price = variant.price_including_vat_for(tax_zone: tax_zone)
60
+ if Spree::Config.allow_currency_change == true
61
+ currency_price = Spree::Price.where(
62
+ currency: order.currency,
63
+ variant_id: variant_id
64
+ ).first
65
+
66
+ self.price = currency_price.price_including_vat_for(tax_zone: tax_zone)
67
+ else
68
+ self.price = variant.price_including_vat_for(tax_zone: tax_zone)
69
+ end
61
70
  end
62
71
 
63
72
  def copy_tax_category
@@ -24,7 +24,11 @@ module Spree
24
24
  after_touch :touch_all_products
25
25
 
26
26
  def filter_param
27
- presentation.titleize.delete(' ').downcase
27
+ name.titleize.delete(' ').downcase
28
+ end
29
+
30
+ def self.color
31
+ find_by(name: 'color')
28
32
  end
29
33
 
30
34
  private
@@ -297,15 +297,15 @@ module Spree
297
297
  def outstanding_balance
298
298
  if canceled?
299
299
  -1 * payment_total
300
- elsif refunds.exists?
301
- # If refund has happened add it back to total to prevent balance_due payment state
302
- # See: https://github.com/spree/spree/issues/6229 & https://github.com/spree/spree/issues/8136
303
- total - (payment_total + refunds.sum(:amount))
304
300
  else
305
- total - payment_total
301
+ total - (payment_total + reimbursement_paid_total)
306
302
  end
307
303
  end
308
304
 
305
+ def reimbursement_paid_total
306
+ reimbursements.sum(&:paid_amount)
307
+ end
308
+
309
309
  def outstanding_balance?
310
310
  outstanding_balance != 0
311
311
  end
@@ -351,6 +351,8 @@ module Spree
351
351
 
352
352
  deliver_order_confirmation_email unless confirmation_delivered?
353
353
 
354
+ deliver_store_owner_order_notification_email if deliver_store_owner_order_notification_email?
355
+
354
356
  consider_risk
355
357
  end
356
358
 
@@ -641,6 +643,13 @@ module Spree
641
643
  sum(:amount)
642
644
  end
643
645
 
646
+ def has_free_shipping?
647
+ promotions.
648
+ joins(:promotion_actions).
649
+ where(spree_promotion_actions: { type: 'Spree::Promotion::Actions::FreeShipping' }).
650
+ exists?
651
+ end
652
+
644
653
  private
645
654
 
646
655
  def link_by_email
@@ -706,5 +715,17 @@ module Spree
706
715
  def credit_card_nil_payment?(attributes)
707
716
  payments.store_credits.present? && attributes[:amount].to_f.zero?
708
717
  end
718
+
719
+ # Returns true if:
720
+ # 1. an email address is set for new order notifications AND
721
+ # 2. no notification for this order has been sent yet.
722
+ def deliver_store_owner_order_notification_email?
723
+ store.new_order_notifications_email.present? && !store_owner_notification_delivered?
724
+ end
725
+
726
+ def deliver_store_owner_order_notification_email
727
+ OrderMailer.store_owner_notification_email(id).deliver_later
728
+ update_column(:store_owner_notification_delivered, true)
729
+ end
709
730
  end
710
731
  end
@@ -15,10 +15,16 @@ module Spree
15
15
  less_than_or_equal_to: MAXIMUM_AMOUNT
16
16
  }
17
17
 
18
+ validates :compare_at_amount, allow_nil: true, numericality: {
19
+ greater_than_or_equal_to: 0,
20
+ less_than_or_equal_to: MAXIMUM_AMOUNT
21
+ }
22
+
18
23
  extend DisplayMoney
19
- money_methods :amount, :price
24
+ money_methods :amount, :price, :compare_at_amount
25
+ alias display_compare_at_price display_compare_at_amount
20
26
 
21
- self.whitelisted_ransackable_attributes = ['amount']
27
+ self.whitelisted_ransackable_attributes = ['amount', 'compare_at_amount']
22
28
 
23
29
  def money
24
30
  Spree::Money.new(amount || 0, currency: currency)
@@ -28,17 +34,35 @@ module Spree
28
34
  self[:amount] = Spree::LocalizedNumber.parse(amount)
29
35
  end
30
36
 
37
+ def compare_at_money
38
+ Spree::Money.new(compare_at_amount || 0, currency: currency)
39
+ end
40
+
41
+ def compare_at_amount=(compare_at_amount)
42
+ self[:compare_at_amount] = Spree::LocalizedNumber.parse(compare_at_amount)
43
+ end
44
+
31
45
  alias_attribute :price, :amount
46
+ alias_attribute :compare_at_price, :compare_at_amount
32
47
 
33
48
  def price_including_vat_for(price_options)
34
49
  options = price_options.merge(tax_category: variant.tax_category)
35
50
  gross_amount(price, options)
36
51
  end
37
52
 
53
+ def compare_at_price_including_vat_for(price_options)
54
+ options = price_options.merge(tax_category: variant.tax_category)
55
+ gross_amount(compare_at_price, options)
56
+ end
57
+
38
58
  def display_price_including_vat_for(price_options)
39
59
  Spree::Money.new(price_including_vat_for(price_options), currency: currency)
40
60
  end
41
61
 
62
+ def display_compare_at_price_including_vat_for(price_options)
63
+ Spree::Money.new(compare_at_price_including_vat_for(price_options), currency: currency)
64
+ end
65
+
42
66
  # Remove variant default_scope `deleted_at: nil`
43
67
  def variant
44
68
  Spree::Variant.unscoped { super }
@@ -113,17 +113,17 @@ module Spree
113
113
 
114
114
  self.whitelisted_ransackable_associations = %w[taxons stores variants_including_master master variants]
115
115
  self.whitelisted_ransackable_attributes = %w[description name slug discontinue_on]
116
- self.whitelisted_ransackable_scopes = %w[not_discontinued]
116
+ self.whitelisted_ransackable_scopes = %w[not_discontinued search_by_name]
117
117
 
118
118
  [
119
119
  :sku, :price, :currency, :weight, :height, :width, :depth, :is_master,
120
- :cost_currency, :price_in, :amount_in, :cost_price
120
+ :cost_currency, :price_in, :amount_in, :cost_price, :compare_at_price
121
121
  ].each do |method_name|
122
122
  delegate method_name, :"#{method_name}=", to: :find_or_build_master
123
123
  end
124
124
 
125
125
  delegate :display_amount, :display_price, :has_default_price?,
126
- :images, to: :find_or_build_master
126
+ :display_compare_at_price, :images, to: :find_or_build_master
127
127
 
128
128
  alias master_images images
129
129
 
@@ -160,10 +160,8 @@ module Spree
160
160
  #
161
161
  # @return [Spree::Variant]
162
162
  def default_variant
163
- track_inventory = Spree::Config[:track_inventory_levels]
164
-
165
- Rails.cache.fetch("spree/default-variant/#{cache_key_with_version}/#{track_inventory}") do
166
- if track_inventory && variants.in_stock_or_backorderable.any?
163
+ Rails.cache.fetch(default_variant_cache_key) do
164
+ if Spree::Config[:track_inventory_levels] && variants.in_stock_or_backorderable.any?
167
165
  variants.in_stock_or_backorderable.first
168
166
  else
169
167
  has_variants? ? variants.first : master
@@ -252,6 +250,14 @@ module Spree
252
250
  where conditions.inject(:or)
253
251
  end
254
252
 
253
+ def self.search_by_name(query)
254
+ if defined?(SpreeGlobalize)
255
+ joins(:translations).order(:name).where("LOWER(#{Product::Translation.table_name}.name) LIKE LOWER(:query)", query: "%#{query}%").distinct
256
+ else
257
+ where("LOWER(#{Product.table_name}.name) LIKE LOWER(:query)", query: "%#{query}%")
258
+ end
259
+ end
260
+
255
261
  # Suitable for displaying only variants that has at least one option value.
256
262
  # There may be scenarios where an option type is removed and along with it
257
263
  # all option values. At that point all variants associated with only those
@@ -344,6 +350,10 @@ module Spree
344
350
  save
345
351
  end
346
352
 
353
+ def default_variant_cache_key
354
+ "spree/default-variant/#{cache_key_with_version}/#{Spree::Config[:track_inventory_levels]}"
355
+ end
356
+
347
357
  def ensure_master
348
358
  return unless new_record?
349
359