solidus_core 4.2.3 → 4.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/app/models/concerns/spree/named_type.rb +2 -0
  3. data/app/models/spree/address.rb +4 -2
  4. data/app/models/spree/adjustment.rb +1 -0
  5. data/app/models/spree/adjustment_reason.rb +2 -0
  6. data/app/models/spree/credit_card.rb +6 -3
  7. data/app/models/spree/order.rb +23 -9
  8. data/app/models/spree/payment_method/bogus_credit_card.rb +14 -9
  9. data/app/models/spree/payment_method/simple_bogus_credit_card.rb +12 -6
  10. data/app/models/spree/payment_method.rb +3 -1
  11. data/app/models/spree/preference.rb +1 -1
  12. data/app/models/spree/promotion/rules/minimum_quantity.rb +59 -0
  13. data/app/models/spree/promotion.rb +1 -1
  14. data/app/models/spree/promotion_handler/coupon.rb +1 -1
  15. data/app/models/spree/refund_reason.rb +6 -1
  16. data/app/models/spree/reimbursement_type.rb +6 -1
  17. data/app/models/spree/return_item.rb +1 -1
  18. data/app/models/spree/return_reason.rb +6 -1
  19. data/app/models/spree/shipping_rate.rb +1 -2
  20. data/app/models/spree/stock/splitter/shipping_category.rb +1 -1
  21. data/app/models/spree/stock_item.rb +1 -0
  22. data/app/models/spree/store.rb +2 -0
  23. data/app/models/spree/store_credit_reason.rb +6 -1
  24. data/app/models/spree/tax_rate.rb +4 -0
  25. data/app/models/spree/variant.rb +0 -5
  26. data/app/views/spree/order_mailer/inventory_cancellation_email.html.erb +0 -1
  27. data/config/locales/en.yml +12 -2
  28. data/db/migrate/20230427095534_drop_deprecated_address_id_from_shipments.rb +1 -1
  29. data/db/migrate/20231027084517_add_order_promotions_foreign_key.rb +10 -0
  30. data/db/migrate/20231031175215_add_promotion_order_promotion_foreign_key.rb +10 -0
  31. data/lib/generators/solidus/install/app_templates/frontend/starter.rb +1 -1
  32. data/lib/generators/solidus/install/install_generator.rb +53 -16
  33. data/lib/generators/solidus/install/templates/config/initializers/spree.rb.tt +9 -9
  34. data/lib/generators/spree/dummy/dummy_generator.rb +1 -0
  35. data/lib/generators/spree/dummy/templates/rails/database.yml +41 -93
  36. data/lib/generators/spree/dummy/templates/rails/test.rb +1 -1
  37. data/lib/spree/app_configuration.rb +17 -0
  38. data/lib/spree/core/engine.rb +7 -5
  39. data/lib/spree/core/state_machines/order.rb +5 -1
  40. data/lib/spree/core/version.rb +2 -2
  41. data/lib/spree/core.rb +2 -0
  42. data/lib/spree/money.rb +1 -1
  43. data/lib/spree/permitted_attributes.rb +1 -0
  44. data/lib/spree/preferences/persistable.rb +7 -1
  45. data/lib/spree/ransack_4_1_patch.rb +16 -0
  46. data/lib/spree/testing_support/dummy_app/database.yml +37 -46
  47. data/lib/spree/testing_support/dummy_app/rake_tasks.rb +1 -4
  48. data/lib/spree/testing_support/dummy_app.rb +21 -12
  49. data/solidus_core.gemspec +2 -2
  50. metadata +27 -23
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c7938f34b4bcad40238d6e3b65de04d09adf33f858d356a4018e9786ca4ed6ab
4
- data.tar.gz: 195dee172feed70780658e7bc036ee937968f49890d4d2ef7c0b0e8ad2444d8e
3
+ metadata.gz: 3154fd1401eef3187a12d7942c30e883bcc8e229e289f097c30d8fe50f0bfd04
4
+ data.tar.gz: e2ac175d41b1ee220217de2b5ffa3b7a27dfd0931ad0ef362edaa1317b90c922
5
5
  SHA512:
6
- metadata.gz: dac210f0e4f20d0d0d5ffb9b4544855ecb4577674283340a27c21943df9949d9a56bfeb514efa5ad70892ec3ecdc65d7134adb01b1861fd2567d9b289dd663b6
7
- data.tar.gz: c7ee0dd8abcc63ac7efc17b6736da623e0ed9ff57c9954c3ef90666aea214d348dca3893b21b97aa883bfb8a493a7a6fca69b2e0507a9d3be2e7b60da855cbab
6
+ metadata.gz: baf556b1e3a617526ff3963637f98fb643f3ccca0d3b1504cc65740b9fb7213a6f26692ad085ecfba9a10d1dcaecd9a8ed3e6946b52b46169f6ce9001d8a793b
7
+ data.tar.gz: 1ec1d893433de9e85e181a1c1caa2257310b9bebdaa23c74a0bbb1115f1506745701bd3c31b1cdad433c93cdb2eea20d467d39b5b0d85f1b290703f85d00b475
@@ -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
 
@@ -28,8 +28,10 @@ module Spree
28
28
 
29
29
  self.allowed_ransackable_attributes = %w[name]
30
30
 
31
- scope :with_values, ->(attributes) do
32
- where(value_attributes(attributes))
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
@@ -132,6 +132,7 @@ module Spree
132
132
  eligible?
133
133
  end
134
134
  end
135
+ deprecate :calculate_eligibility, deprecator: Spree.deprecator
135
136
 
136
137
  private
137
138
 
@@ -8,5 +8,7 @@ module Spree
8
8
  validates :code, presence: true, uniqueness: { case_sensitive: false, allow_blank: true }
9
9
 
10
10
  scope :active, -> { where(active: true) }
11
+
12
+ self.allowed_ransackable_attributes = %w[name code]
11
13
  end
12
14
  end
@@ -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..)
@@ -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
- alias_attribute :billing_address, :bill_address
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
- alias_attribute :shipping_address, :ship_address
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::PromotionHandler::Shipping.new(self).activate
512
+ Spree::Config.shipping_promotion_handler_class.new(self).activate
502
513
  recalculate
503
514
  end
504
515
 
@@ -630,7 +641,7 @@ module Spree
630
641
  if can_complete? || complete?
631
642
  valid_store_credit_payments.to_a.sum(&:amount)
632
643
  else
633
- [total, (user.try(:available_store_credit_total, currency: currency) || 0.0)].min
644
+ [total, user.try(:available_store_credit_total, currency: currency) || 0.0].min
634
645
  end
635
646
  end
636
647
 
@@ -788,10 +799,9 @@ module Spree
788
799
  end
789
800
 
790
801
  def ensure_promotions_eligible
791
- adjustment_changed = all_adjustments.eligible.promotion.any? do |adjustment|
792
- !adjustment.calculate_eligibility
793
- end
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
- ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE, {}, test: true, authorization: AUTHORIZATION_CODE)
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:deprecate_unsupported_payment_methods' "\
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
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Spree::Preference < Spree::Base
4
- serialize :value
4
+ serialize :value, coder: YAML
5
5
 
6
6
  validates :key, presence: true, uniqueness: { allow_blank: true, case_sensitive: true }
7
7
  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
@@ -73,7 +73,7 @@ module Spree
73
73
 
74
74
  unless promotion.eligible?(order, promotion_code: promotion_code)
75
75
  set_promotion_eligibility_error_code(promotion)
76
- return (error || ineligible_for_this_order)
76
+ return error || ineligible_for_this_order
77
77
  end
78
78
 
79
79
  # If any of the actions for the promotion return `true`,
@@ -2,12 +2,17 @@
2
2
 
3
3
  module Spree
4
4
  class RefundReason < Spree::Base
5
- include Spree::NamedType
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
- include Spree::NamedType
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
- include Spree::NamedType
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
@@ -24,7 +24,7 @@ module Spree
24
24
 
25
25
  def hash_to_packages(categories)
26
26
  packages = []
27
- categories.each do |_id, contents|
27
+ categories.each_value do |contents|
28
28
  packages << build_package(contents)
29
29
  end
30
30
  packages
@@ -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
@@ -22,6 +22,8 @@ module Spree
22
22
  validates :url, presence: true
23
23
  validates :mail_from_address, presence: true
24
24
 
25
+ self.allowed_ransackable_attributes = %w[name url code]
26
+
25
27
  before_save :ensure_default_exists_and_is_unique
26
28
  before_destroy :validate_not_default
27
29
 
@@ -1,7 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Spree::StoreCreditReason < Spree::Base
4
- include Spree::NamedType
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
@@ -113,6 +113,10 @@ module Spree
113
113
  )
114
114
  end
115
115
 
116
+ def display_amount
117
+ amount_for_adjustment_label
118
+ end
119
+
116
120
  private
117
121
 
118
122
  def amount_for_adjustment_label
@@ -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
@@ -19,7 +19,6 @@
19
19
  </tr>
20
20
  <% end %>
21
21
  </table>
22
- <p>
23
22
  </td>
24
23
  <td class="expander"></td>
25
24
  </tr>
@@ -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: Switch to legacy admin
1795
- switch_to_solidus_admin: Switch to new 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.2/template.rb'
1
+ apply 'https://github.com/solidusio/solidus_starter_frontend/raw/v4.3/template.rb'