solidus_core 4.7.2 → 4.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +3 -0
- data/app/helpers/spree/base_helper.rb +3 -3
- data/app/helpers/spree/core/controller_helpers/auth.rb +1 -1
- data/app/helpers/spree/core/controller_helpers/common.rb +2 -2
- data/app/helpers/spree/core/controller_helpers/timezone.rb +55 -0
- data/app/helpers/spree/products_helper.rb +2 -2
- data/app/jobs/spree/base_job.rb +1 -1
- data/app/mailers/spree/base_mailer.rb +2 -2
- data/app/models/spree/address.rb +1 -1
- data/app/models/spree/adjustment.rb +1 -1
- data/app/models/spree/calculator/flat_rate.rb +2 -2
- data/app/models/spree/calculator/shipping/flat_rate.rb +1 -1
- data/app/models/spree/calculator/shipping/flexi_rate.rb +1 -1
- data/app/models/spree/calculator/shipping/per_item.rb +1 -1
- data/app/models/spree/calculator/shipping/price_sack.rb +1 -1
- data/app/models/spree/calculator.rb +1 -1
- data/app/models/spree/country.rb +1 -1
- data/app/models/spree/customer_return.rb +7 -0
- data/app/models/spree/exchange.rb +4 -1
- data/app/models/spree/image/active_storage_attachment.rb +15 -0
- data/app/models/spree/image/paperclip_attachment.rb +3 -0
- data/app/models/spree/image.rb +4 -0
- data/app/models/spree/log_entry.rb +26 -22
- data/app/models/spree/money.rb +2 -2
- data/app/models/spree/order/payments.rb +1 -1
- data/app/models/spree/order.rb +15 -17
- data/app/models/spree/order_cancellations.rb +1 -0
- data/app/models/spree/order_mutex.rb +1 -1
- data/app/models/spree/order_shipping.rb +17 -0
- data/app/models/spree/order_updater.rb +1 -1
- data/app/models/spree/payment_method/bogus_credit_card.rb +4 -0
- data/app/models/spree/payment_method/check.rb +4 -2
- data/app/models/spree/payment_method.rb +1 -1
- data/app/models/spree/price.rb +1 -1
- data/app/models/spree/product.rb +1 -1
- data/app/models/spree/product_option_type.rb +2 -0
- data/app/models/spree/refund.rb +17 -0
- data/app/models/spree/return_item/eligibility_validator/time_since_purchase.rb +1 -1
- data/app/models/spree/return_item.rb +1 -1
- data/app/models/spree/shipment.rb +5 -3
- data/app/models/spree/stock/inventory_unit_builder.rb +1 -0
- data/app/models/spree/stock/simple_coordinator.rb +9 -2
- data/app/models/spree/store.rb +8 -1
- data/app/models/spree/store_credit.rb +1 -1
- data/app/models/spree/tax_calculator/default.rb +2 -0
- data/app/models/spree/variant/pricing_options.rb +1 -1
- data/app/models/spree/variant.rb +3 -3
- data/config/locales/en.yml +13 -0
- data/db/default/spree/states.rb +1 -1
- data/db/migrate/20260924120000_add_address_to_spree_stores.rb +9 -0
- data/lib/generators/solidus/install/app_templates/authentication/existing.rb +0 -2
- data/lib/generators/solidus/install/app_templates/frontend/starter.rb +19 -1
- data/lib/generators/solidus/install/app_templates/payment_method/paypal.rb +2 -1
- data/lib/generators/solidus/install/install_generator.rb +7 -7
- data/lib/spree/app_configuration.rb +51 -0
- data/lib/spree/core/search/base.rb +3 -1
- data/lib/spree/core/version.rb +2 -2
- data/lib/spree/core.rb +0 -1
- data/lib/spree/permitted_attributes.rb +3 -2
- data/lib/spree/testing_support/capybara_ext.rb +0 -10
- data/lib/spree/testing_support/factories/calculator_factory.rb +6 -0
- data/lib/spree/testing_support/factories/shipping_method_factory.rb +1 -1
- data/lib/spree/testing_support/factories/store_factory.rb +4 -0
- data/lib/spree/testing_support/order_walkthrough.rb +1 -1
- data/solidus_core.gemspec +3 -3
- metadata +13 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '01835b000500c6523be13d69e3b323203e5e5e5e8cdc0879c20b80aecbc4ab6e'
|
|
4
|
+
data.tar.gz: 81ad53d980d3d2c9fca7cce88e1b9fa0546114e6431d064ac53b46edfeb85e92
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: af199e02adbf3b4ee94bfb927bc2a6f7b5320737a65a7de7147700e3f5a4bec71147ae1b20881f27b71d522321833c9eaab60873bfb3cfe91eee48bcb40f9c53
|
|
7
|
+
data.tar.gz: 9ca9fbf1c2706cc69e11654026e6f64f2a623051c70dce63e57a9db46ba03542f98888371751e1c6fa19d2f731f35c839612f9423ca9d78ee968abf3cd93f0bf
|
data/LICENSE
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
Copyright (c) 2007-2014, Spree Commerce, Inc. and other contributors
|
|
2
2
|
All rights reserved.
|
|
3
3
|
|
|
4
|
+
Copyright (c) 2015-2026, Solidus contributors
|
|
5
|
+
All rights reserved.
|
|
6
|
+
|
|
4
7
|
Redistribution and use in source and binary forms, with or without modification,
|
|
5
8
|
are permitted provided that the following conditions are met:
|
|
6
9
|
|
|
@@ -57,7 +57,7 @@ module Spree
|
|
|
57
57
|
@body_class
|
|
58
58
|
end
|
|
59
59
|
|
|
60
|
-
def logo(image_path = Spree::Config
|
|
60
|
+
def logo(image_path = Spree::Config.logo)
|
|
61
61
|
link_to image_tag(image_path), spree.root_path
|
|
62
62
|
end
|
|
63
63
|
|
|
@@ -93,7 +93,7 @@ module Spree
|
|
|
93
93
|
end
|
|
94
94
|
end
|
|
95
95
|
|
|
96
|
-
content_tag(:nav, content_tag(:ol,
|
|
96
|
+
content_tag(:nav, content_tag(:ol, safe_join(items), class: breadcrumb_class, itemscope: "", itemtype: "https://schema.org/BreadcrumbList"), id: "breadcrumbs", class: "sixteen columns")
|
|
97
97
|
end
|
|
98
98
|
|
|
99
99
|
def taxons_tree(root_taxon, current_taxon, max_level = 1)
|
|
@@ -110,7 +110,7 @@ module Spree
|
|
|
110
110
|
end
|
|
111
111
|
end
|
|
112
112
|
|
|
113
|
-
def available_countries(restrict_to_zone: Spree::Config
|
|
113
|
+
def available_countries(restrict_to_zone: Spree::Config.checkout_zone)
|
|
114
114
|
countries = Spree::Country.available(restrict_to_zone:)
|
|
115
115
|
|
|
116
116
|
country_names = Carmen::Country.all.map do |country|
|
|
@@ -37,7 +37,7 @@ module Spree
|
|
|
37
37
|
|
|
38
38
|
def set_guest_token
|
|
39
39
|
if cookies.signed[:guest_token].blank?
|
|
40
|
-
cookies.permanent.signed[:guest_token] = Spree::Config
|
|
40
|
+
cookies.permanent.signed[:guest_token] = Spree::Config.guest_token_cookie_options.merge(
|
|
41
41
|
value: SecureRandom.urlsafe_base64(nil, false),
|
|
42
42
|
httponly: true
|
|
43
43
|
)
|
|
@@ -27,7 +27,7 @@ module Spree
|
|
|
27
27
|
def title
|
|
28
28
|
title_string = @title.presence || accurate_title
|
|
29
29
|
if title_string.present?
|
|
30
|
-
if Spree::Config
|
|
30
|
+
if Spree::Config.always_put_site_name_in_title
|
|
31
31
|
[title_string, default_title].join(" - ")
|
|
32
32
|
else
|
|
33
33
|
title_string
|
|
@@ -75,7 +75,7 @@ module Spree
|
|
|
75
75
|
# Default layout is: +app/views/spree/layouts/spree_application+
|
|
76
76
|
#
|
|
77
77
|
def get_layout
|
|
78
|
-
Spree::Config
|
|
78
|
+
Spree::Config.layout
|
|
79
79
|
end
|
|
80
80
|
end
|
|
81
81
|
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
module Core
|
|
5
|
+
module ControllerHelpers
|
|
6
|
+
module Timezone
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
included do
|
|
10
|
+
around_action :set_timezone
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
# Sets the timezone for the current request.
|
|
16
|
+
#
|
|
17
|
+
# Uses the most preferred timezone or falls back to the server default.
|
|
18
|
+
#
|
|
19
|
+
# It respects the server's configured timezone from +config/application.rb+.
|
|
20
|
+
#
|
|
21
|
+
def set_timezone(&action)
|
|
22
|
+
timezone = if timezone_change_needed?
|
|
23
|
+
resolved_timezone || Time.zone.name
|
|
24
|
+
else
|
|
25
|
+
session[:solidus_timezone]
|
|
26
|
+
end
|
|
27
|
+
session[:solidus_timezone] = timezone
|
|
28
|
+
Time.use_zone(timezone, &action)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Checks if we need to change the timezone or not.
|
|
32
|
+
def timezone_change_needed?
|
|
33
|
+
params[:solidus_timezone].present? || session[:solidus_timezone].blank?
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Returns the first valid timezone from the priority chain, or nil.
|
|
37
|
+
#
|
|
38
|
+
# The priority order is:
|
|
39
|
+
#
|
|
40
|
+
# * the passed parameter: +params[:solidus_timezone]+
|
|
41
|
+
# * the user's timezone preference
|
|
42
|
+
#
|
|
43
|
+
def resolved_timezone
|
|
44
|
+
candidates = [params[:solidus_timezone], timezone_from_user].compact
|
|
45
|
+
candidates.detect { |tz| ActiveSupport::TimeZone[tz].present? }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Try to get the timezone from user settings.
|
|
49
|
+
def timezone_from_user
|
|
50
|
+
spree_current_user.try(:timezone).presence
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -8,7 +8,7 @@ module Spree
|
|
|
8
8
|
# @param variant [Spree::Variant] the variant
|
|
9
9
|
# @return [Spree::Money] the price or price diff
|
|
10
10
|
def variant_price(variant)
|
|
11
|
-
if Spree::Config
|
|
11
|
+
if Spree::Config.show_variant_full_price
|
|
12
12
|
variant_full_price(variant)
|
|
13
13
|
else
|
|
14
14
|
variant_price_diff(variant)
|
|
@@ -46,7 +46,7 @@ module Spree
|
|
|
46
46
|
# @param product [Spree::Product] the product whose description you want to filter
|
|
47
47
|
# @return [String] the generated HTML
|
|
48
48
|
def product_description(product)
|
|
49
|
-
if Spree::Config
|
|
49
|
+
if Spree::Config.show_raw_product_description
|
|
50
50
|
raw(product.description)
|
|
51
51
|
else
|
|
52
52
|
sanitize(product.description.gsub(/(.*?)\r?\n\r?\n/m, '<p>\1</p>'))
|
data/app/jobs/spree/base_job.rb
CHANGED
|
@@ -10,13 +10,13 @@ module Spree
|
|
|
10
10
|
store.bcc_email
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
def money(amount, currency = Spree::Config
|
|
13
|
+
def money(amount, currency = Spree::Config.currency)
|
|
14
14
|
Spree::Money.new(amount, currency:).to_s
|
|
15
15
|
end
|
|
16
16
|
helper_method :money
|
|
17
17
|
|
|
18
18
|
def mail(headers = {}, &block)
|
|
19
|
-
super if Spree::Config
|
|
19
|
+
super if Spree::Config.send_core_emails
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
22
|
end
|
data/app/models/spree/address.rb
CHANGED
|
@@ -118,7 +118,7 @@ module Spree
|
|
|
118
118
|
# @return [true] whether or not the address requires a phone number to be
|
|
119
119
|
# present
|
|
120
120
|
def require_phone?
|
|
121
|
-
Spree::Config
|
|
121
|
+
Spree::Config.address_requires_phone
|
|
122
122
|
end
|
|
123
123
|
|
|
124
124
|
# @todo Remove this from the public API if possible.
|
|
@@ -65,7 +65,7 @@ module Spree
|
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
def currency
|
|
68
|
-
adjustable ? adjustable.currency : Spree::Config
|
|
68
|
+
adjustable ? adjustable.currency : Spree::Config.currency
|
|
69
69
|
end
|
|
70
70
|
|
|
71
71
|
# @return [Boolean] true when this is a promotion adjustment (Promotion adjustments have a {PromotionAction} source)
|
|
@@ -5,13 +5,13 @@ require_dependency "spree/calculator"
|
|
|
5
5
|
module Spree
|
|
6
6
|
class Calculator::FlatRate < Calculator
|
|
7
7
|
preference :amount, :decimal, default: 0
|
|
8
|
-
preference :currency, :string, default: -> { Spree::Config
|
|
8
|
+
preference :currency, :string, default: -> { Spree::Config.currency }
|
|
9
9
|
|
|
10
10
|
def compute(object = nil)
|
|
11
11
|
if object && preferred_currency.casecmp(object.currency).zero?
|
|
12
12
|
preferred_amount
|
|
13
13
|
else
|
|
14
|
-
|
|
14
|
+
Spree::ZERO
|
|
15
15
|
end
|
|
16
16
|
end
|
|
17
17
|
end
|
|
@@ -7,7 +7,7 @@ module Spree
|
|
|
7
7
|
module Calculator::Shipping
|
|
8
8
|
class FlatRate < ShippingCalculator
|
|
9
9
|
preference :amount, :decimal, default: 0
|
|
10
|
-
preference :currency, :string, default: -> { Spree::Config
|
|
10
|
+
preference :currency, :string, default: -> { Spree::Config.currency }
|
|
11
11
|
|
|
12
12
|
def compute_package(_package)
|
|
13
13
|
preferred_amount
|
|
@@ -9,7 +9,7 @@ module Spree
|
|
|
9
9
|
preference :first_item, :decimal, default: 0.0
|
|
10
10
|
preference :additional_item, :decimal, default: 0.0
|
|
11
11
|
preference :max_items, :integer, default: 0
|
|
12
|
-
preference :currency, :string, default: -> { Spree::Config
|
|
12
|
+
preference :currency, :string, default: -> { Spree::Config.currency }
|
|
13
13
|
|
|
14
14
|
def compute_package(package)
|
|
15
15
|
compute_from_quantity(package.contents.sum(&:quantity))
|
|
@@ -7,7 +7,7 @@ module Spree
|
|
|
7
7
|
module Calculator::Shipping
|
|
8
8
|
class PerItem < ShippingCalculator
|
|
9
9
|
preference :amount, :decimal, default: 0
|
|
10
|
-
preference :currency, :string, default: -> { Spree::Config
|
|
10
|
+
preference :currency, :string, default: -> { Spree::Config.currency }
|
|
11
11
|
|
|
12
12
|
def compute_package(package)
|
|
13
13
|
compute_from_quantity(package.contents.sum(&:quantity))
|
|
@@ -9,7 +9,7 @@ module Spree
|
|
|
9
9
|
preference :minimal_amount, :decimal, default: 0
|
|
10
10
|
preference :normal_amount, :decimal, default: 0
|
|
11
11
|
preference :discount_amount, :decimal, default: 0
|
|
12
|
-
preference :currency, :string, default: -> { Spree::Config
|
|
12
|
+
preference :currency, :string, default: -> { Spree::Config.currency }
|
|
13
13
|
|
|
14
14
|
def compute_package(package)
|
|
15
15
|
compute_from_price(total(package.contents))
|
|
@@ -21,7 +21,7 @@ module Spree
|
|
|
21
21
|
# Spree::ShippingRate)
|
|
22
22
|
# @param ... [args, kwargs] Additional arguments passed to the specific compute method
|
|
23
23
|
#
|
|
24
|
-
# @return [BigDecimal
|
|
24
|
+
# @return [BigDecimal] The computed amount
|
|
25
25
|
#
|
|
26
26
|
# @raise [NotImplementedError] If the calculator doesn't implement the required compute method
|
|
27
27
|
#
|
data/app/models/spree/country.rb
CHANGED
|
@@ -25,7 +25,7 @@ module Spree
|
|
|
25
25
|
find_by!(iso: Spree::Config.default_country_iso)
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
def self.available(restrict_to_zone: Spree::Config
|
|
28
|
+
def self.available(restrict_to_zone: Spree::Config.checkout_zone)
|
|
29
29
|
checkout_zone = Zone.find_by(name: restrict_to_zone)
|
|
30
30
|
|
|
31
31
|
return checkout_zone.country_list if checkout_zone.try(:kind) == "country"
|
|
@@ -15,6 +15,7 @@ module Spree
|
|
|
15
15
|
|
|
16
16
|
validates :return_items, presence: true
|
|
17
17
|
validate :return_items_belong_to_same_order
|
|
18
|
+
validate :return_items_have_returnable_inventory_units, on: :create
|
|
18
19
|
|
|
19
20
|
accepts_nested_attributes_for :return_items
|
|
20
21
|
|
|
@@ -73,6 +74,12 @@ module Spree
|
|
|
73
74
|
end
|
|
74
75
|
end
|
|
75
76
|
|
|
77
|
+
def return_items_have_returnable_inventory_units
|
|
78
|
+
return if inventory_units.compact.all?(&:can_return?)
|
|
79
|
+
|
|
80
|
+
errors.add(:base, I18n.t("spree.return_items_must_have_shipped_inventory_units"))
|
|
81
|
+
end
|
|
82
|
+
|
|
76
83
|
def inventory_units
|
|
77
84
|
return_items.flat_map(&:inventory_unit)
|
|
78
85
|
end
|
|
@@ -22,7 +22,10 @@ module Spree
|
|
|
22
22
|
|
|
23
23
|
def perform!
|
|
24
24
|
begin
|
|
25
|
-
shipments = Spree::Config.stock.coordinator_class.new(
|
|
25
|
+
shipments = Spree::Config.stock.coordinator_class.new(
|
|
26
|
+
@order,
|
|
27
|
+
inventory_units: @reimbursement_objects.map(&:build_exchange_inventory_unit)
|
|
28
|
+
).shipments
|
|
26
29
|
rescue Spree::Order::InsufficientStock
|
|
27
30
|
raise UnableToCreateShipments.new("Could not generate shipments for all items. Out of stock?")
|
|
28
31
|
end
|
|
@@ -21,4 +21,19 @@ module Spree::Image::ActiveStorageAttachment
|
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
|
+
|
|
25
|
+
# Returns the preload tree needed to resolve image.url(style) and image.alt
|
|
26
|
+
# without N+1 queries. Used by callers to nest preloads under image-bearing
|
|
27
|
+
# associations on parent records, e.g.
|
|
28
|
+
# includes(variant_images: Spree::Image.attachment_preloads)
|
|
29
|
+
#
|
|
30
|
+
# We build this manually rather than delegating to with_attached_attachment
|
|
31
|
+
# because Rails' generated scope includes a preview_image_attachment branch
|
|
32
|
+
# that is only relevant for non-image files (PDFs, videos, etc.). Product
|
|
33
|
+
# images never have previews, so including that branch loads empty result
|
|
34
|
+
# sets from active_storage_attachments and active_storage_blobs on every
|
|
35
|
+
# request for no benefit.
|
|
36
|
+
def self.attachment_preloads = [
|
|
37
|
+
{attachment_attachment: {blob: {variant_records: {image_attachment: :blob}}}}
|
|
38
|
+
]
|
|
24
39
|
end
|
|
@@ -22,6 +22,9 @@ module Spree::Image::PaperclipAttachment
|
|
|
22
22
|
after_post_process :find_dimensions, if: :valid?
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
# When using the Paperclip adapter, attachment preloads are a no-op.
|
|
26
|
+
def self.attachment_preloads = []
|
|
27
|
+
|
|
25
28
|
def url(size)
|
|
26
29
|
attachment.url(size)
|
|
27
30
|
end
|
data/app/models/spree/image.rb
CHANGED
|
@@ -11,8 +11,10 @@ module Spree
|
|
|
11
11
|
CORE_PERMITTED_CLASSES = [
|
|
12
12
|
ActiveMerchant::Billing::Response,
|
|
13
13
|
ActiveSupport::TimeWithZone,
|
|
14
|
+
ActiveSupport::HashWithIndifferentAccess,
|
|
14
15
|
Time,
|
|
15
|
-
ActiveSupport::TimeZone
|
|
16
|
+
ActiveSupport::TimeZone,
|
|
17
|
+
Symbol
|
|
16
18
|
].freeze
|
|
17
19
|
|
|
18
20
|
class SerializationError < RuntimeError
|
|
@@ -65,38 +67,40 @@ module Spree
|
|
|
65
67
|
belongs_to :source, polymorphic: true, optional: true
|
|
66
68
|
|
|
67
69
|
def parsed_details
|
|
68
|
-
|
|
69
|
-
@details ||= YAML.safe_load(
|
|
70
|
-
details,
|
|
71
|
-
permitted_classes: self.class.permitted_classes,
|
|
72
|
-
aliases: Spree::Config.log_entry_allow_aliases
|
|
73
|
-
)
|
|
74
|
-
end
|
|
70
|
+
@details ||= deserialize_details
|
|
75
71
|
end
|
|
76
72
|
|
|
77
73
|
def parsed_details=(value)
|
|
78
|
-
|
|
79
|
-
self.details = YAML.safe_dump(
|
|
80
|
-
value,
|
|
81
|
-
permitted_classes: self.class.permitted_classes,
|
|
82
|
-
aliases: Spree::Config.log_entry_allow_aliases
|
|
83
|
-
)
|
|
84
|
-
end
|
|
74
|
+
self.details = YAML.dump(value)
|
|
85
75
|
end
|
|
86
76
|
|
|
87
77
|
def parsed_payment_response_details_with_fallback=(response)
|
|
88
78
|
self.parsed_details = response
|
|
89
|
-
rescue SerializationError, YAML::Exception => e
|
|
90
|
-
# Fall back on wrapping the response and signaling the error to the end user.
|
|
91
|
-
self.parsed_details = ActiveMerchant::Billing::Response.new(
|
|
92
|
-
response.success?,
|
|
93
|
-
"[WARNING: An error occurred while trying to serialize the payment response] #{response.message}",
|
|
94
|
-
{"data" => response.inspect, "error" => e.message.to_s}
|
|
95
|
-
)
|
|
96
79
|
end
|
|
97
80
|
|
|
98
81
|
private
|
|
99
82
|
|
|
83
|
+
def deserialize_details
|
|
84
|
+
handle_psych_serialization_errors do
|
|
85
|
+
YAML.safe_load(
|
|
86
|
+
details,
|
|
87
|
+
permitted_classes: self.class.permitted_classes,
|
|
88
|
+
aliases: Spree::Config.log_entry_allow_aliases
|
|
89
|
+
)
|
|
90
|
+
end
|
|
91
|
+
rescue SerializationError, Psych::Exception => e
|
|
92
|
+
# The stored response could not be deserialized (a class that isn't
|
|
93
|
+
# permitted, a disabled alias, or malformed YAML). Keep the record readable
|
|
94
|
+
# by wrapping the raw details and surfacing the reason instead of raising,
|
|
95
|
+
# while reporting the error so it stays visible to developers.
|
|
96
|
+
Rails.error.report(e, handled: true, severity: :warning, context: {spree_log_entry_id: id})
|
|
97
|
+
ActiveMerchant::Billing::Response.new(
|
|
98
|
+
false,
|
|
99
|
+
"[WARNING: An error occurred while trying to deserialize the stored payment response] #{e.message}",
|
|
100
|
+
{"data" => details, "error" => e.message}
|
|
101
|
+
)
|
|
102
|
+
end
|
|
103
|
+
|
|
100
104
|
def handle_psych_serialization_errors
|
|
101
105
|
yield
|
|
102
106
|
rescue Psych::DisallowedClass => e
|
data/app/models/spree/money.rb
CHANGED
|
@@ -11,7 +11,7 @@ module Spree
|
|
|
11
11
|
class << self
|
|
12
12
|
attr_accessor :default_formatting_rules
|
|
13
13
|
|
|
14
|
-
def parse(amount, currency = Spree::Config
|
|
14
|
+
def parse(amount, currency = Spree::Config.currency)
|
|
15
15
|
new(parse_to_money(amount, currency))
|
|
16
16
|
end
|
|
17
17
|
|
|
@@ -36,7 +36,7 @@ module Spree
|
|
|
36
36
|
if amount.is_a?(::Money)
|
|
37
37
|
@money = amount
|
|
38
38
|
else
|
|
39
|
-
currency = options[:currency] || Spree::Config
|
|
39
|
+
currency = options[:currency] || Spree::Config.currency
|
|
40
40
|
|
|
41
41
|
@money = Monetize.from_string(amount, currency)
|
|
42
42
|
end
|
|
@@ -47,7 +47,7 @@ module Spree
|
|
|
47
47
|
payment.public_send(method_name)
|
|
48
48
|
end
|
|
49
49
|
rescue Core::GatewayError => error
|
|
50
|
-
result = !!Spree::Config
|
|
50
|
+
result = !!Spree::Config.allow_checkout_on_gateway_error
|
|
51
51
|
errors.add(:base, error.message) && (return result)
|
|
52
52
|
end
|
|
53
53
|
end
|
data/app/models/spree/order.rb
CHANGED
|
@@ -151,7 +151,8 @@ module Spree
|
|
|
151
151
|
validates :email, presence: true, if: :email_required?
|
|
152
152
|
validates :email, "spree/email" => true, :allow_blank => true
|
|
153
153
|
validates :guest_token, presence: {allow_nil: true}
|
|
154
|
-
validates :number, presence: true
|
|
154
|
+
validates :number, presence: true
|
|
155
|
+
validates :number, uniqueness: {allow_blank: true, case_sensitive: true}, if: :number_changed?
|
|
155
156
|
validates :store_id, presence: true
|
|
156
157
|
|
|
157
158
|
def self.find_by_param(value)
|
|
@@ -237,7 +238,7 @@ module Spree
|
|
|
237
238
|
end
|
|
238
239
|
|
|
239
240
|
def currency
|
|
240
|
-
self[:currency] || Spree::Config
|
|
241
|
+
self[:currency] || Spree::Config.currency
|
|
241
242
|
end
|
|
242
243
|
|
|
243
244
|
def shipping_discount
|
|
@@ -271,7 +272,7 @@ module Spree
|
|
|
271
272
|
|
|
272
273
|
# Returns the address for taxation based on configuration
|
|
273
274
|
def tax_address
|
|
274
|
-
if Spree::Config
|
|
275
|
+
if Spree::Config.tax_using_ship_address
|
|
275
276
|
ship_address
|
|
276
277
|
else
|
|
277
278
|
bill_address
|
|
@@ -307,6 +308,14 @@ module Spree
|
|
|
307
308
|
inventory_units.reload.all?(&:returned?)
|
|
308
309
|
end
|
|
309
310
|
|
|
311
|
+
# Since this method is called from within the order state machine, we cannot
|
|
312
|
+
# simply delegate this to :shipping. The state_machines gem uses the arity
|
|
313
|
+
# of the method to determine if it should pass in the transition as an
|
|
314
|
+
# argument. The arity of the method is masked when using delegates.
|
|
315
|
+
def create_proposed_shipments
|
|
316
|
+
shipping.create_proposed_shipments
|
|
317
|
+
end
|
|
318
|
+
|
|
310
319
|
def contents
|
|
311
320
|
@contents ||= Spree::Config.order_contents_class.new(self)
|
|
312
321
|
end
|
|
@@ -501,21 +510,10 @@ module Spree
|
|
|
501
510
|
Spree::Config.billing_address_required
|
|
502
511
|
end
|
|
503
512
|
|
|
504
|
-
def create_proposed_shipments
|
|
505
|
-
if completed?
|
|
506
|
-
raise CannotRebuildShipments.new(I18n.t("spree.cannot_rebuild_shipments_order_completed"))
|
|
507
|
-
elsif shipments.any? { |shipment| !shipment.pending? }
|
|
508
|
-
raise CannotRebuildShipments.new(I18n.t("spree.cannot_rebuild_shipments_shipments_not_pending"))
|
|
509
|
-
else
|
|
510
|
-
shipments.destroy_all
|
|
511
|
-
shipments.push(*Spree::Config.stock.coordinator_class.new(self).shipments)
|
|
512
|
-
end
|
|
513
|
-
end
|
|
514
|
-
|
|
515
513
|
def create_shipments_for_line_item(line_item)
|
|
516
|
-
|
|
514
|
+
inventory_units = Spree::Config.stock.inventory_unit_builder_class.new(self).missing_units_for_line_item(line_item)
|
|
517
515
|
|
|
518
|
-
Spree::Config.stock.coordinator_class.new(self,
|
|
516
|
+
Spree::Config.stock.coordinator_class.new(self, inventory_units:).shipments.each do |shipment|
|
|
519
517
|
shipments << shipment
|
|
520
518
|
end
|
|
521
519
|
end
|
|
@@ -879,7 +877,7 @@ module Spree
|
|
|
879
877
|
end
|
|
880
878
|
|
|
881
879
|
def set_currency
|
|
882
|
-
self.currency = Spree::Config
|
|
880
|
+
self.currency = Spree::Config.currency if self[:currency].nil?
|
|
883
881
|
end
|
|
884
882
|
|
|
885
883
|
def create_token
|
|
@@ -6,7 +6,7 @@ module Spree
|
|
|
6
6
|
|
|
7
7
|
belongs_to :order, class_name: "Spree::Order", optional: true
|
|
8
8
|
|
|
9
|
-
scope :expired, -> { where(arel_table[:created_at].lteq(Spree::Config
|
|
9
|
+
scope :expired, -> { where(arel_table[:created_at].lteq(Spree::Config.order_mutex_max_age.seconds.ago)) }
|
|
10
10
|
|
|
11
11
|
class << self
|
|
12
12
|
# Obtain a lock on an order, execute the supplied block and then release the lock.
|
|
@@ -8,6 +8,23 @@ class Spree::OrderShipping
|
|
|
8
8
|
@order = order
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
+
# A method that destroys the current shipments on an order, creates new
|
|
12
|
+
# shipments for the line items, and assigns them to the order.
|
|
13
|
+
#
|
|
14
|
+
# @return [Array<Spree::Shipment>] The created shipments
|
|
15
|
+
# @raise [Spree::Order::CannotRebuildShipments] raised if order is completed
|
|
16
|
+
# or there are any non-pending shipments.
|
|
17
|
+
def create_proposed_shipments
|
|
18
|
+
if @order.completed?
|
|
19
|
+
raise Spree::Order::CannotRebuildShipments.new(I18n.t("spree.cannot_rebuild_shipments_order_completed"))
|
|
20
|
+
elsif @order.shipments.any? { |shipment| !shipment.pending? }
|
|
21
|
+
raise Spree::Order::CannotRebuildShipments.new(I18n.t("spree.cannot_rebuild_shipments_shipments_not_pending"))
|
|
22
|
+
else
|
|
23
|
+
@order.shipments.destroy_all
|
|
24
|
+
@order.shipments.push(*Spree::Config.stock.coordinator_class.new(@order).shipments)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
11
28
|
# A shortcut method that ships *all* inventory units in a shipment in a single
|
|
12
29
|
# carton. See also {#ship}.
|
|
13
30
|
#
|
|
@@ -148,7 +148,7 @@ module Spree
|
|
|
148
148
|
end
|
|
149
149
|
|
|
150
150
|
def recalculate_payment_total
|
|
151
|
-
order.payment_total = payments.completed.includes(:refunds).sum { |payment| payment.amount - payment.refunds.sum(
|
|
151
|
+
order.payment_total = payments.completed.includes(:refunds).sum { |payment| payment.amount - payment.refunds.sum(&:amount) }
|
|
152
152
|
end
|
|
153
153
|
alias_method :update_payment_total, :recalculate_payment_total
|
|
154
154
|
deprecate update_payment_total: :recalculate_payment_total, deprecator: Spree.deprecator
|
|
@@ -6,16 +6,18 @@ module Spree
|
|
|
6
6
|
%w[capture void credit]
|
|
7
7
|
end
|
|
8
8
|
|
|
9
|
-
# Indicates whether its possible to capture the payment
|
|
10
9
|
def can_capture?(payment)
|
|
11
10
|
["checkout", "pending"].include?(payment.state)
|
|
12
11
|
end
|
|
13
12
|
|
|
14
|
-
# Indicates whether its possible to void the payment.
|
|
15
13
|
def can_void?(payment)
|
|
16
14
|
payment.state != "void"
|
|
17
15
|
end
|
|
18
16
|
|
|
17
|
+
def can_credit?(payment)
|
|
18
|
+
payment.completed? && payment.credit_allowed > 0
|
|
19
|
+
end
|
|
20
|
+
|
|
19
21
|
def capture(*)
|
|
20
22
|
simulated_successful_billing_response
|
|
21
23
|
end
|
|
@@ -156,7 +156,7 @@ module Spree
|
|
|
156
156
|
end
|
|
157
157
|
|
|
158
158
|
def auto_capture?
|
|
159
|
-
auto_capture.nil? ? Spree::Config
|
|
159
|
+
auto_capture.nil? ? Spree::Config.auto_capture : auto_capture
|
|
160
160
|
end
|
|
161
161
|
|
|
162
162
|
# Check if given source is supported by this payment method
|
data/app/models/spree/price.rb
CHANGED
data/app/models/spree/product.rb
CHANGED
|
@@ -124,7 +124,7 @@ module Spree
|
|
|
124
124
|
validates :meta_keywords, length: {maximum: 255}
|
|
125
125
|
validates :meta_title, length: {maximum: 255}
|
|
126
126
|
validates :name, presence: true
|
|
127
|
-
validates :price, presence: true, if: proc { Spree::Config
|
|
127
|
+
validates :price, presence: true, if: proc { Spree::Config.require_master_price }
|
|
128
128
|
validates :slug, presence: true, uniqueness: {allow_blank: true, case_sensitive: true}
|
|
129
129
|
|
|
130
130
|
attr_accessor :option_values_hash
|