spree_core 4.1.15 → 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.
- checksums.yaml +4 -4
- data/app/controllers/spree/base_controller.rb +1 -0
- data/app/helpers/spree/base_helper.rb +23 -2
- data/app/helpers/spree/mail_helper.rb +24 -0
- data/app/mailers/spree/base_mailer.rb +17 -3
- data/app/mailers/spree/order_mailer.rb +11 -2
- data/app/mailers/spree/reimbursement_mailer.rb +4 -2
- data/app/mailers/spree/shipment_mailer.rb +4 -2
- data/app/models/concerns/spree/default_price.rb +2 -1
- data/app/models/concerns/spree/user_methods.rb +11 -5
- data/app/models/spree/app_configuration.rb +5 -0
- data/app/models/spree/app_dependencies.rb +1 -7
- data/app/models/spree/line_item.rb +11 -3
- data/app/models/spree/option_type.rb +5 -1
- data/app/models/spree/order/address_book.rb +20 -7
- data/app/models/spree/order/store_credit.rb +0 -8
- data/app/models/spree/order.rb +28 -12
- data/app/models/spree/price.rb +26 -2
- data/app/models/spree/product.rb +17 -7
- data/app/models/spree/promotion_handler/coupon.rb +3 -2
- data/app/models/spree/reimbursement.rb +2 -0
- data/app/models/spree/shipment.rb +2 -5
- data/app/models/spree/stock_location.rb +13 -2
- data/app/models/spree/store.rb +19 -2
- data/app/models/spree/variant.rb +15 -2
- data/app/presenters/spree/variant_presenter.rb +7 -0
- data/app/presenters/spree/variants/option_types_presenter.rb +1 -0
- data/app/services/spree/checkout/update.rb +2 -13
- data/app/views/layouts/spree/base_mailer.html.erb +45 -40
- data/app/views/spree/order_mailer/cancel_email.html.erb +19 -25
- data/app/views/spree/order_mailer/cancel_email.text.erb +24 -2
- data/app/views/spree/order_mailer/confirm_email.html.erb +18 -65
- data/app/views/spree/order_mailer/confirm_email.text.erb +2 -1
- data/app/views/spree/order_mailer/store_owner_notification_email.html.erb +23 -0
- data/app/views/spree/order_mailer/store_owner_notification_email.text.erb +38 -0
- data/app/views/spree/reimbursement_mailer/reimbursement_email.html.erb +53 -58
- data/app/views/spree/reimbursement_mailer/reimbursement_email.text.erb +3 -1
- data/app/views/spree/shared/_base_mailer_footer.html.erb +6 -14
- data/app/views/spree/shared/_base_mailer_header.html.erb +12 -32
- data/app/views/spree/shared/_base_mailer_stylesheets.html.erb +293 -625
- data/app/views/spree/shared/_purchased_items_table.html.erb +60 -0
- data/app/views/spree/shared/purchased_items_table/_adjustment.html.erb +13 -0
- data/app/views/spree/shared/purchased_items_table/_line_item.html.erb +27 -0
- data/app/views/spree/shared/purchased_items_table/_subtotal.html.erb +13 -0
- data/app/views/spree/shared/purchased_items_table/_total.html.erb +13 -0
- data/app/views/spree/shipment_mailer/shipped_email.html.erb +31 -36
- data/app/views/spree/shipment_mailer/shipped_email.text.erb +2 -1
- data/config/initializers/assets.rb +1 -0
- data/config/locales/en.yml +113 -13
- data/db/default/spree/stores.rb +11 -10
- data/db/migrate/20140309033438_create_store_from_preferences.rb +1 -1
- data/db/migrate/20191016134113_add_deafult_value_for_store_default_currency.rb +1 -1
- data/db/migrate/20191017121054_add_supported_currencies_to_store.rb +10 -0
- data/db/migrate/20200102141311_add_social_to_spree_stores.rb +4 -1
- data/db/migrate/20200212144523_add_hide_from_nav_to_taxons.rb +1 -1
- data/db/migrate/20200308210757_add_default_locale_to_spree_store.rb +7 -0
- data/db/migrate/20200310145140_add_customer_support_email_to_spree_store.rb +7 -0
- data/db/migrate/20200421095017_add_compare_at_amount_to_spree_prices.rb +7 -0
- data/db/migrate/20200423123001_add_default_country_id_to_spree_store.rb +9 -0
- data/db/migrate/20200430072209_add_footer_fields_to_spree_stores.rb +8 -0
- data/db/migrate/20200513154939_add_show_property_to_spree_product_properties.rb +5 -0
- data/db/migrate/20200607161221_add_store_owner_order_notification_delivered_to_spree_orders.rb +7 -0
- data/db/migrate/20200607161222_add_new_order_notifications_email_to_spree_stores.rb +7 -0
- data/db/migrate/20200826075557_add_unique_index_on_taxon_id_and_product_id_to_spree_products_taxons.rb +5 -0
- data/lib/generators/spree/dummy/dummy_generator.rb +1 -0
- data/lib/generators/spree/install/templates/vendor/assets/javascripts/spree/backend/all.js +0 -2
- data/lib/generators/spree/install/templates/vendor/assets/javascripts/spree/frontend/all.js +0 -2
- data/lib/generators/spree/mailers_preview/mailers_preview_generator.rb +23 -0
- data/lib/generators/spree/mailers_preview/templates/mailers/previews/order_preview.rb +13 -0
- data/lib/generators/spree/mailers_preview/templates/mailers/previews/reimbursement_preview.rb +5 -0
- data/lib/generators/spree/mailers_preview/templates/mailers/previews/shipment_preview.rb +5 -0
- data/lib/generators/spree/mailers_preview/templates/mailers/previews/user_preview.rb +11 -0
- data/lib/spree/core/controller_helpers/common.rb +1 -0
- data/lib/spree/core/controller_helpers/currency_helpers.rb +15 -0
- data/lib/spree/core/controller_helpers/store.rb +12 -1
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/core.rb +1 -0
- data/lib/spree/permitted_attributes.rb +7 -4
- data/lib/spree/testing_support/authorization_helpers.rb +7 -4
- data/lib/spree/testing_support/capybara_ext.rb +0 -7
- data/lib/spree/testing_support/factories/store_factory.rb +11 -8
- data/spree_core.gemspec +6 -6
- data/vendor/assets/javascripts/cleave.js +1669 -0
- metadata +44 -32
- data/app/finders/spree/addresses/find.rb +0 -17
- data/app/models/spree/order_contents.rb +0 -31
- data/app/services/spree/account/addresses/base.rb +0 -39
- data/app/services/spree/account/addresses/create.rb +0 -18
- data/app/services/spree/account/addresses/update.rb +0 -18
- data/app/views/spree/order_mailer/_adjustment.html.erb +0 -8
- data/app/views/spree/order_mailer/_subtotal.html.erb +0 -8
- 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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dd3e3f16eb808f16f592360085f02f1382ee4ddd6ee0903c3eb8a8079e5d8bad
|
|
4
|
+
data.tar.gz: 8567b7555de6f0f578d6277e6943af11b68329e5e17a77d13c7e66085e7fe09f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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 =
|
|
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
|
-
|
|
11
|
+
current_store.mail_from_address
|
|
5
12
|
end
|
|
6
13
|
|
|
7
|
-
def money(amount, 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] ||=
|
|
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 += "#{
|
|
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 += "#{
|
|
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 += "#{
|
|
7
|
-
mail(to: @
|
|
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 += "#{
|
|
7
|
-
mail(to: @
|
|
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=,
|
|
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.
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
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
|
|
@@ -11,8 +11,7 @@ module Spree
|
|
|
11
11
|
:checkout_remove_store_credit_service, :checkout_get_shipping_rates_service,
|
|
12
12
|
:coupon_handler, :country_finder, :current_order_finder, :credit_card_finder,
|
|
13
13
|
:completed_order_finder, :order_sorter, :cart_compare_line_items_service, :collection_paginator, :products_sorter,
|
|
14
|
-
:products_finder, :taxon_finder, :line_item_by_variant_finder, :cart_estimate_shipping_rates_service
|
|
15
|
-
:account_create_address_service, :account_update_address_service, :address_finder
|
|
14
|
+
:products_finder, :taxon_finder, :line_item_by_variant_finder, :cart_estimate_shipping_rates_service
|
|
16
15
|
].freeze
|
|
17
16
|
|
|
18
17
|
attr_accessor *INJECTION_POINTS
|
|
@@ -60,14 +59,9 @@ module Spree
|
|
|
60
59
|
# coupons
|
|
61
60
|
# TODO: we should split this service into 2 seperate - Add and Remove
|
|
62
61
|
@coupon_handler = 'Spree::PromotionHandler::Coupon'
|
|
63
|
-
|
|
64
|
-
# account
|
|
65
|
-
@account_create_address_service = 'Spree::Account::Addresses::Create'
|
|
66
|
-
@account_update_address_service = 'Spree::Account::Addresses::Update'
|
|
67
62
|
end
|
|
68
63
|
|
|
69
64
|
def set_default_finders
|
|
70
|
-
@address_finder = 'Spree::Addresses::Find'
|
|
71
65
|
@country_finder = 'Spree::Countries::Find'
|
|
72
66
|
@current_order_finder = 'Spree::Orders::FindCurrent'
|
|
73
67
|
@completed_order_finder = 'Spree::Orders::FindComplete'
|
|
@@ -57,7 +57,16 @@ module Spree
|
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
def update_price
|
|
60
|
-
|
|
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
|
|
@@ -66,8 +75,7 @@ module Spree
|
|
|
66
75
|
|
|
67
76
|
extend DisplayMoney
|
|
68
77
|
money_methods :amount, :subtotal, :discounted_amount, :final_amount, :total, :price,
|
|
69
|
-
:adjustment_total, :additional_tax_total, :promo_total, :included_tax_total
|
|
70
|
-
:pre_tax_amount
|
|
78
|
+
:adjustment_total, :additional_tax_total, :promo_total, :included_tax_total
|
|
71
79
|
|
|
72
80
|
alias single_money display_price
|
|
73
81
|
alias single_display_amount display_price
|
|
@@ -55,18 +55,31 @@ module Spree
|
|
|
55
55
|
def update_or_create_address(attributes = {})
|
|
56
56
|
return if attributes.blank?
|
|
57
57
|
|
|
58
|
-
attributes.
|
|
58
|
+
attributes = attributes.select { |_k, v| v.present? }
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
if user
|
|
61
|
+
address = user.addresses.build(attributes.except(:id)).check
|
|
62
|
+
return address if address.id
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
if attributes[:id]
|
|
66
|
+
address = Spree::Address.find(attributes[:id])
|
|
67
|
+
attributes.delete(:id)
|
|
62
68
|
|
|
63
|
-
|
|
64
|
-
|
|
69
|
+
if address&.editable?
|
|
70
|
+
address.update(attributes)
|
|
71
|
+
return address
|
|
72
|
+
else
|
|
73
|
+
attributes.delete(:id)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
65
76
|
|
|
66
|
-
|
|
77
|
+
unless attributes[:id]
|
|
78
|
+
address = Spree::Address.new(attributes)
|
|
79
|
+
address.save
|
|
67
80
|
end
|
|
68
81
|
|
|
69
|
-
|
|
82
|
+
address
|
|
70
83
|
end
|
|
71
84
|
end
|
|
72
85
|
end
|
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
module Spree
|
|
2
2
|
class Order < Spree::Base
|
|
3
3
|
module StoreCredit
|
|
4
|
-
def add_store_credit_payments(amount = nil)
|
|
5
|
-
Spree::Dependencies.checkout_add_store_credit_service.constantize.call(order: self, amount: amount)
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
def remove_store_credit_payments
|
|
9
|
-
Spree::Dependencies.checkout_remove_store_credit_service.constantize.call(order: self)
|
|
10
|
-
end
|
|
11
|
-
|
|
12
4
|
def covered_by_store_credit?
|
|
13
5
|
return false unless user
|
|
14
6
|
|
data/app/models/spree/order.rb
CHANGED
|
@@ -22,7 +22,7 @@ module Spree
|
|
|
22
22
|
money_methods :outstanding_balance, :item_total, :adjustment_total,
|
|
23
23
|
:included_tax_total, :additional_tax_total, :tax_total,
|
|
24
24
|
:shipment_total, :promo_total, :total,
|
|
25
|
-
:cart_promo_total
|
|
25
|
+
:cart_promo_total
|
|
26
26
|
|
|
27
27
|
alias display_ship_total display_shipment_total
|
|
28
28
|
alias_attribute :ship_total, :shipment_total
|
|
@@ -174,12 +174,7 @@ module Spree
|
|
|
174
174
|
|
|
175
175
|
# Sum of all line item amounts pre-tax
|
|
176
176
|
def pre_tax_item_amount
|
|
177
|
-
line_items.sum(
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
# Sum of all line item and shipment pre-tax
|
|
181
|
-
def pre_tax_total
|
|
182
|
-
pre_tax_item_amount + shipments.sum(:pre_tax_amount)
|
|
177
|
+
line_items.to_a.sum(&:pre_tax_amount)
|
|
183
178
|
end
|
|
184
179
|
|
|
185
180
|
def shipping_discount
|
|
@@ -302,15 +297,15 @@ module Spree
|
|
|
302
297
|
def outstanding_balance
|
|
303
298
|
if canceled?
|
|
304
299
|
-1 * payment_total
|
|
305
|
-
elsif refunds.exists?
|
|
306
|
-
# If refund has happened add it back to total to prevent balance_due payment state
|
|
307
|
-
# See: https://github.com/spree/spree/issues/6229 & https://github.com/spree/spree/issues/8136
|
|
308
|
-
total - (payment_total + refunds.sum(:amount))
|
|
309
300
|
else
|
|
310
|
-
total - payment_total
|
|
301
|
+
total - (payment_total + reimbursement_paid_total)
|
|
311
302
|
end
|
|
312
303
|
end
|
|
313
304
|
|
|
305
|
+
def reimbursement_paid_total
|
|
306
|
+
reimbursements.sum(&:paid_amount)
|
|
307
|
+
end
|
|
308
|
+
|
|
314
309
|
def outstanding_balance?
|
|
315
310
|
outstanding_balance != 0
|
|
316
311
|
end
|
|
@@ -356,6 +351,8 @@ module Spree
|
|
|
356
351
|
|
|
357
352
|
deliver_order_confirmation_email unless confirmation_delivered?
|
|
358
353
|
|
|
354
|
+
deliver_store_owner_order_notification_email if deliver_store_owner_order_notification_email?
|
|
355
|
+
|
|
359
356
|
consider_risk
|
|
360
357
|
end
|
|
361
358
|
|
|
@@ -646,6 +643,13 @@ module Spree
|
|
|
646
643
|
sum(:amount)
|
|
647
644
|
end
|
|
648
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
|
+
|
|
649
653
|
private
|
|
650
654
|
|
|
651
655
|
def link_by_email
|
|
@@ -711,5 +715,17 @@ module Spree
|
|
|
711
715
|
def credit_card_nil_payment?(attributes)
|
|
712
716
|
payments.store_credits.present? && attributes[:amount].to_f.zero?
|
|
713
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
|
|
714
730
|
end
|
|
715
731
|
end
|
data/app/models/spree/price.rb
CHANGED
|
@@ -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 }
|
data/app/models/spree/product.rb
CHANGED
|
@@ -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
|
-
|
|
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
|
|
|
@@ -25,9 +25,10 @@ module Spree
|
|
|
25
25
|
|
|
26
26
|
def remove(coupon_code)
|
|
27
27
|
promotion = order.promotions.with_coupon_code(coupon_code)
|
|
28
|
+
|
|
28
29
|
if promotion.present?
|
|
29
30
|
# Order promotion has to be destroyed before line item removing
|
|
30
|
-
order.order_promotions.
|
|
31
|
+
order.order_promotions.where(promotion_id: promotion.id).destroy_all
|
|
31
32
|
|
|
32
33
|
remove_promotion_adjustments(promotion)
|
|
33
34
|
remove_promotion_line_items(promotion)
|
|
@@ -75,7 +76,7 @@ module Spree
|
|
|
75
76
|
line_item = order.find_line_item_by_variant(item.variant)
|
|
76
77
|
next if line_item.blank?
|
|
77
78
|
|
|
78
|
-
Spree::Dependencies.cart_remove_item_service
|
|
79
|
+
Spree::Dependencies.cart_remove_item_service(order: order, item: item.variant, quantity: item.quantity)
|
|
79
80
|
end
|
|
80
81
|
end
|
|
81
82
|
|
|
@@ -60,6 +60,8 @@ module Spree
|
|
|
60
60
|
class_attribute :reimbursement_failure_hooks
|
|
61
61
|
self.reimbursement_failure_hooks = []
|
|
62
62
|
|
|
63
|
+
delegate :store, :currency, to: :order
|
|
64
|
+
|
|
63
65
|
state_machine :reimbursement_status, initial: :pending do
|
|
64
66
|
event :errored do
|
|
65
67
|
transition to: :errored, from: :pending
|
|
@@ -42,6 +42,8 @@ module Spree
|
|
|
42
42
|
scope :reverse_chronological, -> { order(Arel.sql('coalesce(spree_shipments.shipped_at, spree_shipments.created_at) desc'), id: :desc) }
|
|
43
43
|
scope :valid, -> { where.not(state: :canceled) }
|
|
44
44
|
|
|
45
|
+
delegate :store, :currency, to: :order
|
|
46
|
+
|
|
45
47
|
# shipment state machine (see http://github.com/pluginaweek/state_machine/tree/master for details)
|
|
46
48
|
state_machine initial: :pending, use_transactions: false do
|
|
47
49
|
event :ready do
|
|
@@ -104,11 +106,6 @@ module Spree
|
|
|
104
106
|
inventory_units.any?(&:backordered?)
|
|
105
107
|
end
|
|
106
108
|
|
|
107
|
-
# TODO: delegate currency to Order, order.currency is mandatory
|
|
108
|
-
def currency
|
|
109
|
-
order ? order.currency : Spree::Config[:currency]
|
|
110
|
-
end
|
|
111
|
-
|
|
112
109
|
# Determines the appropriate +state+ according to the following logic:
|
|
113
110
|
#
|
|
114
111
|
# pending unless order is complete and +order.payment_state+ is +paid+
|
|
@@ -106,8 +106,19 @@ module Spree
|
|
|
106
106
|
private
|
|
107
107
|
|
|
108
108
|
def create_stock_items
|
|
109
|
-
|
|
110
|
-
|
|
109
|
+
variants_scope = Spree::Variant
|
|
110
|
+
prepared_stock_items = variants_scope.ids.map do |variant_id|
|
|
111
|
+
Hash[
|
|
112
|
+
'stock_location_id', id,
|
|
113
|
+
'variant_id', variant_id,
|
|
114
|
+
'backorderable', backorderable_default,
|
|
115
|
+
'created_at', Time.current,
|
|
116
|
+
'updated_at', Time.current
|
|
117
|
+
]
|
|
118
|
+
end
|
|
119
|
+
if prepared_stock_items.any?
|
|
120
|
+
stock_items.insert_all(prepared_stock_items)
|
|
121
|
+
variants_scope.touch_all
|
|
111
122
|
end
|
|
112
123
|
end
|
|
113
124
|
|