solidus_core 4.2.4 → 4.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/models/concerns/spree/named_type.rb +2 -0
- data/app/models/spree/address.rb +4 -2
- data/app/models/spree/adjustment.rb +1 -0
- data/app/models/spree/adjustment_reason.rb +2 -0
- data/app/models/spree/credit_card.rb +6 -3
- data/app/models/spree/order.rb +22 -8
- data/app/models/spree/payment_method/bogus_credit_card.rb +14 -9
- data/app/models/spree/payment_method/simple_bogus_credit_card.rb +12 -6
- data/app/models/spree/payment_method.rb +3 -1
- data/app/models/spree/preference.rb +1 -1
- data/app/models/spree/promotion/rules/minimum_quantity.rb +59 -0
- data/app/models/spree/promotion.rb +1 -1
- data/app/models/spree/refund_reason.rb +6 -1
- data/app/models/spree/reimbursement_type.rb +6 -1
- data/app/models/spree/return_item.rb +1 -1
- data/app/models/spree/return_reason.rb +6 -1
- data/app/models/spree/shipping_rate.rb +1 -2
- data/app/models/spree/stock_item.rb +1 -0
- data/app/models/spree/store.rb +2 -0
- data/app/models/spree/store_credit_reason.rb +6 -1
- data/app/models/spree/tax_rate.rb +4 -0
- data/app/models/spree/variant.rb +0 -5
- data/app/views/spree/order_mailer/inventory_cancellation_email.html.erb +0 -1
- data/config/locales/en.yml +12 -2
- data/db/migrate/20230427095534_drop_deprecated_address_id_from_shipments.rb +1 -1
- data/db/migrate/20231027084517_add_order_promotions_foreign_key.rb +10 -0
- data/db/migrate/20231031175215_add_promotion_order_promotion_foreign_key.rb +10 -0
- data/lib/generators/solidus/install/app_templates/frontend/starter.rb +1 -1
- data/lib/generators/solidus/install/install_generator.rb +53 -16
- data/lib/generators/solidus/install/templates/config/initializers/spree.rb.tt +9 -9
- data/lib/generators/spree/dummy/templates/rails/database.yml +41 -93
- data/lib/generators/spree/dummy/templates/rails/test.rb +1 -1
- data/lib/spree/app_configuration.rb +17 -2
- data/lib/spree/core/engine.rb +7 -5
- data/lib/spree/core/version.rb +2 -2
- data/lib/spree/core.rb +2 -0
- data/lib/spree/permitted_attributes.rb +1 -0
- data/lib/spree/preferences/persistable.rb +7 -1
- data/lib/spree/ransack_4_1_patch.rb +16 -0
- data/lib/spree/testing_support/dummy_app/database.yml +37 -46
- data/lib/spree/testing_support/dummy_app/rake_tasks.rb +1 -4
- data/lib/spree/testing_support/dummy_app.rb +21 -12
- data/solidus_core.gemspec +2 -2
- metadata +27 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b3062426cacae16277744fe67eb092a3f773da6f4195824cc9722982a94500e8
|
4
|
+
data.tar.gz: 02a46f714512ef4a5556be47576953406814f89c7d6963e76061a2a2ae7c2f61
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0db5204b73520cb7cf74fcffb07d4f6bdef6fe25e0206f6ac777222acbf765df7e956380677b93585041105e4cbeba971b2c9133bb7f845bbb287fe32f9f481b
|
7
|
+
data.tar.gz: 3835da0fe02e80d20dd39c152bb9cb6c1f1191cba238658624cc8b9506ae2afd0798a69102b9752a6bf96fd067cae536c38a4088376ac82be6ce1691bf1ff871
|
@@ -5,6 +5,8 @@ module Spree
|
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
7
|
included do
|
8
|
+
Spree.deprecator.warn "Spree::NamedType is deprecated. Please set scopes and validations locally instead.", caller
|
9
|
+
|
8
10
|
scope :active, -> { where(active: true) }
|
9
11
|
default_scope -> { order(arel_table[:name].lower) }
|
10
12
|
|
data/app/models/spree/address.rb
CHANGED
@@ -28,8 +28,10 @@ module Spree
|
|
28
28
|
|
29
29
|
self.allowed_ransackable_attributes = %w[name]
|
30
30
|
|
31
|
-
|
32
|
-
|
31
|
+
unless ActiveRecord::Relation.method_defined? :with_values # Rails 7.1+
|
32
|
+
scope :with_values, ->(attributes) do
|
33
|
+
where(value_attributes(attributes))
|
34
|
+
end
|
33
35
|
end
|
34
36
|
|
35
37
|
# @return [Address] an address with default attributes
|
@@ -21,9 +21,6 @@ module Spree
|
|
21
21
|
|
22
22
|
scope :with_payment_profile, -> { where('gateway_customer_profile_id IS NOT NULL') }
|
23
23
|
|
24
|
-
# needed for some of the ActiveMerchant gateways (eg. SagePay)
|
25
|
-
alias_attribute :brand, :cc_type
|
26
|
-
|
27
24
|
# Taken from ActiveMerchant
|
28
25
|
# https://github.com/activemerchant/active_merchant/blob/2f2acd4696e8de76057b5ed670b9aa022abc1187/lib/active_merchant/billing/credit_card_methods.rb#L5
|
29
26
|
CARD_TYPES = {
|
@@ -95,6 +92,12 @@ module Spree
|
|
95
92
|
end
|
96
93
|
end
|
97
94
|
|
95
|
+
# needed for some of the ActiveMerchant gateways (eg. SagePay)
|
96
|
+
alias_attribute :brand, :cc_type
|
97
|
+
|
98
|
+
# Rails 7.1+ won't use the custom setter with alias_attribute
|
99
|
+
alias_method :brand=, :cc_type=
|
100
|
+
|
98
101
|
# Sets the last digits field based on the assigned credit card number.
|
99
102
|
def set_last_digits
|
100
103
|
self.last_digits ||= number.to_s.length <= 4 ? number : number.to_s.slice(-4..)
|
data/app/models/spree/order.rb
CHANGED
@@ -72,11 +72,15 @@ module Spree
|
|
72
72
|
|
73
73
|
# Customer info
|
74
74
|
belongs_to :user, class_name: Spree::UserClassHandle.new, optional: true
|
75
|
+
|
75
76
|
belongs_to :bill_address, foreign_key: :bill_address_id, class_name: 'Spree::Address', optional: true
|
76
|
-
|
77
|
+
alias_method :billing_address, :bill_address
|
78
|
+
alias_method :billing_address=, :bill_address=
|
77
79
|
|
78
80
|
belongs_to :ship_address, foreign_key: :ship_address_id, class_name: 'Spree::Address', optional: true
|
79
|
-
|
81
|
+
alias_method :shipping_address, :ship_address
|
82
|
+
alias_method :shipping_address=, :ship_address=
|
83
|
+
|
80
84
|
alias_attribute :ship_total, :shipment_total
|
81
85
|
|
82
86
|
belongs_to :store, class_name: 'Spree::Store', optional: true
|
@@ -104,7 +108,7 @@ module Spree
|
|
104
108
|
foreign_key: :order_id,
|
105
109
|
dependent: :destroy,
|
106
110
|
inverse_of: :order
|
107
|
-
has_many :order_promotions, class_name: 'Spree::OrderPromotion'
|
111
|
+
has_many :order_promotions, class_name: 'Spree::OrderPromotion', dependent: :destroy
|
108
112
|
has_many :promotions, through: :order_promotions
|
109
113
|
|
110
114
|
# Payments
|
@@ -135,7 +139,9 @@ module Spree
|
|
135
139
|
before_validation :set_currency
|
136
140
|
before_validation :generate_order_number, on: :create
|
137
141
|
before_validation :assign_billing_to_shipping_address, if: :use_billing?
|
142
|
+
before_validation :assign_shipping_to_billing_address, if: :use_shipping?
|
138
143
|
attr_accessor :use_billing
|
144
|
+
attr_accessor :use_shipping
|
139
145
|
|
140
146
|
before_create :create_token
|
141
147
|
before_create :link_by_email
|
@@ -271,6 +277,11 @@ module Spree
|
|
271
277
|
true
|
272
278
|
end
|
273
279
|
|
280
|
+
def assign_shipping_to_billing_address
|
281
|
+
self.bill_address = ship_address if ship_address
|
282
|
+
true
|
283
|
+
end
|
284
|
+
|
274
285
|
def allow_cancel?
|
275
286
|
return false unless completed? && state != 'canceled'
|
276
287
|
shipment_state.nil? || %w{ready backorder pending}.include?(shipment_state)
|
@@ -498,7 +509,7 @@ module Spree
|
|
498
509
|
end
|
499
510
|
|
500
511
|
def apply_shipping_promotions
|
501
|
-
Spree::
|
512
|
+
Spree::Config.shipping_promotion_handler_class.new(self).activate
|
502
513
|
recalculate
|
503
514
|
end
|
504
515
|
|
@@ -788,10 +799,9 @@ module Spree
|
|
788
799
|
end
|
789
800
|
|
790
801
|
def ensure_promotions_eligible
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
if adjustment_changed
|
802
|
+
Spree::Config.promotion_adjuster_class.new(self).call
|
803
|
+
|
804
|
+
if promo_total_changed?
|
795
805
|
restart_checkout_flow
|
796
806
|
recalculate
|
797
807
|
errors.add(:base, I18n.t('spree.promotion_total_changed_before_complete'))
|
@@ -860,6 +870,10 @@ module Spree
|
|
860
870
|
use_billing.in?([true, 'true', '1'])
|
861
871
|
end
|
862
872
|
|
873
|
+
def use_shipping?
|
874
|
+
use_shipping.in?([true, 'true', '1'])
|
875
|
+
end
|
876
|
+
|
863
877
|
def set_currency
|
864
878
|
self.currency = Spree::Config[:currency] if self[:currency].nil?
|
865
879
|
end
|
@@ -29,39 +29,44 @@ module Spree
|
|
29
29
|
|
30
30
|
def authorize(_money, credit_card, _options = {})
|
31
31
|
profile_id = credit_card.gateway_customer_profile_id
|
32
|
+
message_detail = " - #{__method__}"
|
32
33
|
if VALID_CCS.include?(credit_card.number) || (profile_id && profile_id.starts_with?('BGS-'))
|
33
|
-
ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE, {}, test: true, authorization: AUTHORIZATION_CODE, avs_result: { code: 'D' })
|
34
|
+
ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE + message_detail, {}, test: true, authorization: AUTHORIZATION_CODE, avs_result: { code: 'D' })
|
34
35
|
else
|
35
|
-
ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE, { message: FAILURE_MESSAGE }, test: true)
|
36
|
+
ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE + message_detail, { message: FAILURE_MESSAGE + message_detail }, test: true)
|
36
37
|
end
|
37
38
|
end
|
38
39
|
|
39
40
|
def purchase(_money, credit_card, _options = {})
|
40
41
|
profile_id = credit_card.gateway_customer_profile_id
|
42
|
+
message_detail = " - #{__method__}"
|
41
43
|
if VALID_CCS.include?(credit_card.number) || (profile_id && profile_id.starts_with?('BGS-'))
|
42
|
-
ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE, {}, test: true, authorization: AUTHORIZATION_CODE, avs_result: { code: 'M' })
|
44
|
+
ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE + message_detail, {}, test: true, authorization: AUTHORIZATION_CODE, avs_result: { code: 'M' })
|
43
45
|
else
|
44
|
-
ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE, message: FAILURE_MESSAGE, test: true)
|
46
|
+
ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE + message_detail, message: FAILURE_MESSAGE + message_detail, test: true)
|
45
47
|
end
|
46
48
|
end
|
47
49
|
|
48
50
|
def credit(_money, _credit_card, _response_code, _options = {})
|
49
|
-
|
51
|
+
message_detail = " - #{__method__}"
|
52
|
+
ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE + message_detail, {}, test: true, authorization: AUTHORIZATION_CODE)
|
50
53
|
end
|
51
54
|
|
52
55
|
def capture(_money, authorization, _gateway_options)
|
56
|
+
message_detail = " - #{__method__}"
|
53
57
|
if authorization == '12345'
|
54
|
-
ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE, {}, test: true)
|
58
|
+
ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE + message_detail, {}, test: true)
|
55
59
|
else
|
56
|
-
ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE, error: FAILURE_MESSAGE, test: true)
|
60
|
+
ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE + message_detail, error: FAILURE_MESSAGE + message_detail, test: true)
|
57
61
|
end
|
58
62
|
end
|
59
63
|
|
60
64
|
def void(_response_code, _credit_card, options = {})
|
65
|
+
message_detail = " - #{__method__}"
|
61
66
|
if options[:originator].completed?
|
62
|
-
ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE, {}, test: true, authorization: AUTHORIZATION_CODE)
|
67
|
+
ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE + message_detail, {}, test: true, authorization: AUTHORIZATION_CODE)
|
63
68
|
else
|
64
|
-
ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE, {}, test: true, authorization: AUTHORIZATION_CODE)
|
69
|
+
ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE + message_detail, {}, test: true, authorization: AUTHORIZATION_CODE)
|
65
70
|
end
|
66
71
|
end
|
67
72
|
|
@@ -8,26 +8,32 @@ module Spree
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def authorize(_money, credit_card, _options = {})
|
11
|
+
message_detail = " - #{__method__}"
|
12
|
+
|
11
13
|
if VALID_CCS.include? credit_card.number
|
12
|
-
ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE, {}, test: true, authorization: AUTHORIZATION_CODE, avs_result: { code: 'A' })
|
14
|
+
ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE + message_detail, {}, test: true, authorization: AUTHORIZATION_CODE, avs_result: { code: 'A' })
|
13
15
|
else
|
14
|
-
ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE, { message: FAILURE_MESSAGE }, test: true)
|
16
|
+
ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE + message_detail, { message: FAILURE_MESSAGE }, test: true)
|
15
17
|
end
|
16
18
|
end
|
17
19
|
|
18
20
|
def purchase(_money, credit_card, _options = {})
|
21
|
+
message_detail = " - #{__method__}"
|
22
|
+
|
19
23
|
if VALID_CCS.include? credit_card.number
|
20
|
-
ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE, {}, test: true, authorization: AUTHORIZATION_CODE, avs_result: { code: 'A' })
|
24
|
+
ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE + message_detail, {}, test: true, authorization: AUTHORIZATION_CODE, avs_result: { code: 'A' })
|
21
25
|
else
|
22
|
-
ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE, message: FAILURE_MESSAGE, test: true)
|
26
|
+
ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE + message_detail, message: FAILURE_MESSAGE, test: true)
|
23
27
|
end
|
24
28
|
end
|
25
29
|
|
26
30
|
def void(_response_code, options = {})
|
31
|
+
message_detail = " - #{__method__}"
|
32
|
+
|
27
33
|
if options[:originator].completed?
|
28
|
-
ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE, {}, test: true, authorization: AUTHORIZATION_CODE)
|
34
|
+
ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE + message_detail, {}, test: true, authorization: AUTHORIZATION_CODE)
|
29
35
|
else
|
30
|
-
ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE, {}, test: true, authorization: AUTHORIZATION_CODE)
|
36
|
+
ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE + message_detail, {}, test: true, authorization: AUTHORIZATION_CODE)
|
31
37
|
end
|
32
38
|
end
|
33
39
|
end
|
@@ -42,6 +42,8 @@ module Spree
|
|
42
42
|
|
43
43
|
include Spree::Preferences::StaticallyConfigurable
|
44
44
|
|
45
|
+
self.allowed_ransackable_attributes = %w[name description]
|
46
|
+
|
45
47
|
# Custom ModelName#human implementation to ensure we don't refer to
|
46
48
|
# subclasses as just "PaymentMethod"
|
47
49
|
class ModelName < ActiveModel::Name
|
@@ -68,7 +70,7 @@ module Spree
|
|
68
70
|
raise UnsupportedPaymentMethod, "Found invalid payment type '#{type_name}'.\n"\
|
69
71
|
"This may happen after switching payment service provider, when payment methods "\
|
70
72
|
"reference old types that are not supported any more.\n"\
|
71
|
-
"If that is the case, consider running 'rake payment_method:
|
73
|
+
"If that is the case, consider running 'rake payment_method:deactivate_unsupported_payment_methods' "\
|
72
74
|
"to fix the issue."
|
73
75
|
end
|
74
76
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spree
|
4
|
+
class Promotion
|
5
|
+
module Rules
|
6
|
+
# Promotion rule for ensuring an order contains a minimum quantity of
|
7
|
+
# actionable items.
|
8
|
+
#
|
9
|
+
# This promotion rule is only compatible with the "all" match policy. It
|
10
|
+
# doesn't make a lot of sense to use it without that policy as it reduces
|
11
|
+
# it to a simple quantity check across the entire order which would be
|
12
|
+
# better served by an item total rule.
|
13
|
+
class MinimumQuantity < PromotionRule
|
14
|
+
validates :preferred_minimum_quantity, numericality: { only_integer: true, greater_than: 0 }
|
15
|
+
|
16
|
+
preference :minimum_quantity, :integer, default: 1
|
17
|
+
|
18
|
+
# What type of objects we should run our eligiblity checks against. In
|
19
|
+
# this case, our rule only applies to an entire order.
|
20
|
+
#
|
21
|
+
# @param promotable [Spree::Order,Spree::LineItem]
|
22
|
+
# @return [Boolean] true if promotable is a Spree::Order, false
|
23
|
+
# otherwise
|
24
|
+
def applicable?(promotable)
|
25
|
+
promotable.is_a?(Spree::Order)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Will look at all of the "actionable" line items in the order and
|
29
|
+
# determine if the sum of their quantity is greater than the minimum.
|
30
|
+
#
|
31
|
+
# "Actionable" items are ones where they pass the "actionable?" check of
|
32
|
+
# all rules on the promotion. (e.g.: Match product/taxon when one of
|
33
|
+
# those rules is present.)
|
34
|
+
#
|
35
|
+
# When false is returned, the reason will be included in the
|
36
|
+
# `eligibility_errors` object.
|
37
|
+
#
|
38
|
+
# @param order [Spree::Order] the order we want to check eligibility on
|
39
|
+
# @param _options [Hash] ignored
|
40
|
+
# @return [Boolean] true if promotion is eligible, false otherwise
|
41
|
+
def eligible?(order, _options = {})
|
42
|
+
actionable_line_items = order.line_items.select do |line_item|
|
43
|
+
promotion.rules.all? { _1.actionable?(line_item) }
|
44
|
+
end
|
45
|
+
|
46
|
+
if actionable_line_items.sum(&:quantity) < preferred_minimum_quantity
|
47
|
+
eligibility_errors.add(
|
48
|
+
:base,
|
49
|
+
eligibility_error_message(:quantity_less_than_minimum, count: preferred_minimum_quantity),
|
50
|
+
error_code: :quantity_less_than_minimum
|
51
|
+
)
|
52
|
+
end
|
53
|
+
|
54
|
+
eligibility_errors.empty?
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -14,7 +14,7 @@ module Spree
|
|
14
14
|
has_many :promotion_actions, autosave: true, dependent: :destroy, inverse_of: :promotion
|
15
15
|
alias_method :actions, :promotion_actions
|
16
16
|
|
17
|
-
has_many :order_promotions, class_name: "Spree::OrderPromotion"
|
17
|
+
has_many :order_promotions, class_name: "Spree::OrderPromotion", inverse_of: :promotion, dependent: :destroy
|
18
18
|
has_many :orders, through: :order_promotions
|
19
19
|
|
20
20
|
has_many :codes, class_name: "Spree::PromotionCode", inverse_of: :promotion, dependent: :destroy
|
@@ -2,12 +2,17 @@
|
|
2
2
|
|
3
3
|
module Spree
|
4
4
|
class RefundReason < Spree::Base
|
5
|
-
|
5
|
+
scope :active, -> { where(active: true) }
|
6
|
+
default_scope -> { order(arel_table[:name].lower) }
|
7
|
+
|
8
|
+
validates :name, presence: true, uniqueness: { case_sensitive: false, allow_blank: true }
|
6
9
|
|
7
10
|
RETURN_PROCESSING_REASON = 'Return processing'
|
8
11
|
|
9
12
|
has_many :refunds
|
10
13
|
|
14
|
+
self.allowed_ransackable_attributes = %w[name code]
|
15
|
+
|
11
16
|
def self.return_processing_reason
|
12
17
|
find_by!(name: RETURN_PROCESSING_REASON, mutable: false)
|
13
18
|
end
|
@@ -2,12 +2,17 @@
|
|
2
2
|
|
3
3
|
module Spree
|
4
4
|
class ReimbursementType < Spree::Base
|
5
|
-
|
5
|
+
scope :active, -> { where(active: true) }
|
6
|
+
default_scope -> { order(arel_table[:name].lower) }
|
7
|
+
|
8
|
+
validates :name, presence: true, uniqueness: { case_sensitive: false, allow_blank: true }
|
6
9
|
|
7
10
|
ORIGINAL = 'original'
|
8
11
|
|
9
12
|
has_many :return_items
|
10
13
|
|
14
|
+
self.allowed_ransackable_attributes = %w[name]
|
15
|
+
|
11
16
|
# This method will reimburse the return items based on however it child implements it
|
12
17
|
# By default it takes a reimbursement, the return items it needs to reimburse, and if
|
13
18
|
# it is a simulation or a real reimbursement. This should return an array
|
@@ -67,7 +67,7 @@ module Spree
|
|
67
67
|
scope :exchange_processed, -> { where.not(exchange_inventory_unit: nil) }
|
68
68
|
scope :exchange_required, -> { exchange_requested.where(exchange_inventory_unit: nil) }
|
69
69
|
|
70
|
-
serialize :acceptance_status_errors
|
70
|
+
serialize :acceptance_status_errors, coder: YAML
|
71
71
|
|
72
72
|
delegate :eligible_for_return?, :requires_manual_intervention?, to: :validator
|
73
73
|
delegate :variant, to: :inventory_unit
|
@@ -2,10 +2,15 @@
|
|
2
2
|
|
3
3
|
module Spree
|
4
4
|
class ReturnReason < Spree::Base
|
5
|
-
|
5
|
+
scope :active, -> { where(active: true) }
|
6
|
+
default_scope -> { order(arel_table[:name].lower) }
|
7
|
+
|
8
|
+
validates :name, presence: true, uniqueness: { case_sensitive: false, allow_blank: true }
|
6
9
|
|
7
10
|
has_many :return_authorizations
|
8
11
|
|
12
|
+
self.allowed_ransackable_attributes = %w[name]
|
13
|
+
|
9
14
|
def self.reasons_for_return_items(return_items)
|
10
15
|
# Only allow an inactive reason if it's already associated to a return item
|
11
16
|
active | return_items.map(&:return_reason).compact
|
@@ -18,8 +18,7 @@ module Spree
|
|
18
18
|
delegate :name, :tax_category, :tax_category_id, to: :shipping_method
|
19
19
|
delegate :code, to: :shipping_method, prefix: true
|
20
20
|
alias_attribute :amount, :cost
|
21
|
-
|
22
|
-
alias_method :total_before_tax, :amount
|
21
|
+
alias_attribute :total_before_tax, :cost
|
23
22
|
|
24
23
|
extend DisplayMoney
|
25
24
|
money_methods :amount
|
@@ -21,6 +21,7 @@ module Spree
|
|
21
21
|
after_touch { variant.touch }
|
22
22
|
|
23
23
|
self.allowed_ransackable_attributes = ['count_on_hand', 'stock_location_id']
|
24
|
+
self.allowed_ransackable_associations = %w[variant]
|
24
25
|
|
25
26
|
# @return [Array<Spree::InventoryUnit>] the backordered inventory units
|
26
27
|
# associated with this stock item
|
data/app/models/spree/store.rb
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Spree::StoreCreditReason < Spree::Base
|
4
|
-
|
4
|
+
scope :active, -> { where(active: true) }
|
5
|
+
default_scope -> { order(arel_table[:name].lower) }
|
6
|
+
|
7
|
+
validates :name, presence: true, uniqueness: { case_sensitive: false, allow_blank: true }
|
5
8
|
|
6
9
|
has_many :store_credit_events, inverse_of: :store_credit_reason
|
10
|
+
|
11
|
+
self.allowed_ransackable_attributes = %w[name]
|
7
12
|
end
|
data/app/models/spree/variant.rb
CHANGED
@@ -73,7 +73,6 @@ module Spree
|
|
73
73
|
validates_uniqueness_of :sku, allow_blank: true, case_sensitive: true, conditions: -> { where(deleted_at: nil) }, if: :enforce_unique_sku?
|
74
74
|
|
75
75
|
after_create :create_stock_items
|
76
|
-
after_create :set_position
|
77
76
|
after_create :set_master_out_of_stock, unless: :is_master?
|
78
77
|
|
79
78
|
after_save :clear_in_stock_cache
|
@@ -406,10 +405,6 @@ module Spree
|
|
406
405
|
Spree::Config.variant_vat_prices_generator_class.new(self).run
|
407
406
|
end
|
408
407
|
|
409
|
-
def set_position
|
410
|
-
update_column(:position, product.variants.maximum(:position).to_i + 1)
|
411
|
-
end
|
412
|
-
|
413
408
|
def in_stock_cache_key
|
414
409
|
"variant-#{id}-in_stock"
|
415
410
|
end
|
data/config/locales/en.yml
CHANGED
@@ -104,6 +104,7 @@ en:
|
|
104
104
|
additional_tax_total: Tax
|
105
105
|
approved_at: Approved at
|
106
106
|
approver_id: Approver
|
107
|
+
bill_address: Billing Address
|
107
108
|
canceled_at: Canceled at
|
108
109
|
canceler_id: Canceler
|
109
110
|
checkout_complete: Checkout Complete
|
@@ -117,6 +118,7 @@ en:
|
|
117
118
|
item_total: Item Total
|
118
119
|
number: Number
|
119
120
|
payment_state: Payment State
|
121
|
+
ship_address: Shipping Address
|
120
122
|
shipment_state: Shipment State
|
121
123
|
shipment_total: Ship Total
|
122
124
|
special_instructions: Special Instructions
|
@@ -217,6 +219,8 @@ en:
|
|
217
219
|
description: Order total meets these criteria
|
218
220
|
spree/promotion/rules/landing_page:
|
219
221
|
description: Customer must have visited the specified page
|
222
|
+
spree/promotion/rules/minimum_quantity:
|
223
|
+
description: Order contains minimum quantity of applicable items
|
220
224
|
spree/promotion/rules/nth_order:
|
221
225
|
description: Apply a promotion to every nth order a user has completed.
|
222
226
|
form_text: 'Apply this promotion on the users Nth order: '
|
@@ -652,6 +656,7 @@ en:
|
|
652
656
|
spree/promotion/rules/first_repeat_purchase_since: First Repeat Purchase Since
|
653
657
|
spree/promotion/rules/item_total: Item Total
|
654
658
|
spree/promotion/rules/landing_page: Landing Page
|
659
|
+
spree/promotion/rules/minimum_quantity: Minimum Quantity
|
655
660
|
spree/promotion/rules/nth_order: Nth Order
|
656
661
|
spree/promotion/rules/one_use_per_user: One Use Per User
|
657
662
|
spree/promotion/rules/option_value: Option Value(s)
|
@@ -1136,6 +1141,7 @@ en:
|
|
1136
1141
|
choose_a_taxon_to_sort_products_for: Choose a taxon to sort products for
|
1137
1142
|
choose_currency: Choose Currency
|
1138
1143
|
choose_dashboard_locale: Choose Dashboard Locale
|
1144
|
+
choose_dashboard_theme: Choose Dashboard Theme
|
1139
1145
|
choose_location: Choose Location
|
1140
1146
|
choose_promotion_action: Choose Action
|
1141
1147
|
choose_promotion_rule: Choose Rule
|
@@ -1533,6 +1539,9 @@ en:
|
|
1533
1539
|
no_user_or_email_specified: You need to login or provide your email before applying this coupon code.
|
1534
1540
|
no_user_specified: You need to login before applying this coupon code.
|
1535
1541
|
not_first_order: This coupon code can only be applied to your first order.
|
1542
|
+
quantity_less_than_minimum:
|
1543
|
+
one: You need to add a least 1 applicable item to your order.
|
1544
|
+
other: You need to add a least %{count} applicable items to your order.
|
1536
1545
|
email: Email
|
1537
1546
|
empty: Empty
|
1538
1547
|
empty_cart: Empty Cart
|
@@ -1791,8 +1800,8 @@ en:
|
|
1791
1800
|
name_on_card: Name on card
|
1792
1801
|
name_or_sku: Name or SKU (enter at least first 4 characters of product name)
|
1793
1802
|
navigation:
|
1794
|
-
switch_to_legacy:
|
1795
|
-
switch_to_solidus_admin:
|
1803
|
+
switch_to_legacy: Show Legacy UI
|
1804
|
+
switch_to_solidus_admin: Show Legacy UI
|
1796
1805
|
negative_movement_absent_item: Cannot create negative movement for absent stock item.
|
1797
1806
|
new: New
|
1798
1807
|
new_adjustment: New Adjustment
|
@@ -2339,6 +2348,7 @@ en:
|
|
2339
2348
|
subject: Test Mail
|
2340
2349
|
test_mode: Test Mode
|
2341
2350
|
thank_you_for_your_order: Thank you for your business. Please print out a copy of this confirmation page for your records.
|
2351
|
+
theme_changed: Theme Changed
|
2342
2352
|
there_are_no_items_for_this_order: There are no items for this order. Please add an item to the order to continue.
|
2343
2353
|
there_were_problems_with_the_following_fields: There were problems with the following fields
|
2344
2354
|
this_order_has_already_received_a_refund: This order has already received a refund
|
@@ -5,7 +5,7 @@ class DropDeprecatedAddressIdFromShipments < ActiveRecord::Migration[5.2]
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def down
|
8
|
-
add_column :spree_shipments, :deprecated_address_id
|
8
|
+
add_column :spree_shipments, :deprecated_address_id, :integer
|
9
9
|
add_index :spree_shipments, :deprecated_address_id, name: :index_spree_shipments_on_deprecated_address_id
|
10
10
|
end
|
11
11
|
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class AddOrderPromotionsForeignKey < ActiveRecord::Migration[7.0]
|
2
|
+
def up
|
3
|
+
Spree::OrderPromotion.left_joins(:order).where(spree_orders: { id: nil }).delete_all
|
4
|
+
add_foreign_key :spree_orders_promotions, :spree_orders, column: :order_id, validate: false, on_delete: :cascade
|
5
|
+
end
|
6
|
+
|
7
|
+
def down
|
8
|
+
remove_foreign_key :spree_orders_promotions, :spree_orders
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class AddPromotionOrderPromotionForeignKey < ActiveRecord::Migration[7.0]
|
2
|
+
def up
|
3
|
+
Spree::OrderPromotion.left_joins(:promotion).where(spree_promotions: { id: nil }).delete_all
|
4
|
+
add_foreign_key :spree_orders_promotions, :spree_promotions, column: :promotion_id, on_delete: :cascade
|
5
|
+
end
|
6
|
+
|
7
|
+
def down
|
8
|
+
remove_foreign_key :spree_orders_promotions, :spree_orders
|
9
|
+
end
|
10
|
+
end
|
@@ -1 +1 @@
|
|
1
|
-
apply 'https://github.com/solidusio/solidus_starter_frontend/raw/v4.
|
1
|
+
apply 'https://github.com/solidusio/solidus_starter_frontend/raw/v4.3/template.rb'
|