solidus_core 3.3.4 → 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +0 -1
  3. data/app/models/concerns/spree/ransackable_attributes.rb +5 -0
  4. data/app/models/spree/fulfilment_changer.rb +65 -26
  5. data/app/models/spree/log_entry.rb +38 -14
  6. data/app/models/spree/order.rb +2 -2
  7. data/app/models/spree/order_inventory.rb +1 -1
  8. data/app/models/spree/order_update_attributes.rb +3 -1
  9. data/app/models/spree/payment/processing.rb +1 -1
  10. data/app/models/spree/payment.rb +22 -4
  11. data/app/models/spree/payment_method/credit_card.rb +0 -4
  12. data/app/models/spree/product/scopes.rb +2 -2
  13. data/app/models/spree/product.rb +1 -5
  14. data/app/models/spree/promotion.rb +3 -4
  15. data/app/models/spree/refund.rb +1 -1
  16. data/app/models/spree/shipment.rb +1 -1
  17. data/app/models/spree/taxon.rb +2 -0
  18. data/app/models/spree/taxonomy.rb +1 -0
  19. data/app/models/spree/wallet/add_payment_sources_to_wallet.rb +4 -4
  20. data/app/views/layouts/spree/base_mailer.html.erb +2 -2
  21. data/config/locales/en.yml +25 -18
  22. data/lib/generators/solidus/install/app_templates/frontend/starter.rb +1 -1
  23. data/lib/generators/solidus/install/app_templates/payment_method/bolt.rb +1 -1
  24. data/lib/generators/solidus/install/app_templates/payment_method/braintree.rb +5 -0
  25. data/lib/generators/solidus/install/app_templates/payment_method/paypal.rb +9 -2
  26. data/lib/generators/solidus/install/install_generator.rb +37 -25
  27. data/lib/spree/app_configuration.rb +55 -0
  28. data/lib/spree/core/controller_helpers/payment_parameters.rb +3 -5
  29. data/lib/spree/core/version.rb +2 -2
  30. data/lib/spree/migration_helpers.rb +3 -3
  31. data/lib/spree/promotion/match_policies.rb +2 -0
  32. data/lib/spree/testing_support/factories/taxon_factory.rb +5 -3
  33. data/lib/spree/testing_support/factories/taxonomy_factory.rb +3 -1
  34. data/lib/spree/testing_support/flaky.rb +22 -0
  35. metadata +6 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5e2fc705b84728b7954a7eb0f2375bcce15feed81189d4ef02f8b7012057718d
4
- data.tar.gz: 8617f568577f259486cb72ab6615475510350745d7f275c03dd0ebee85d434f2
3
+ metadata.gz: 3bf3e87cc1694926e3abe00013c3c2c92fb94ecfefb63405f22d92f92e91704a
4
+ data.tar.gz: f7b75754a75a0cae886af0b182e761defc86c8671c5e10b239bd73d8ce2ea7b3
5
5
  SHA512:
6
- metadata.gz: 862c53da4d2bf1f82b575a857dad8018ba6d8748b29dce7d089a508a921f7b4c64d59a79766b9077933918aea7141c62888a0f48292300bae7bec2937ca1f3ad
7
- data.tar.gz: 836f0cad8115199e78593bbc34f3521fbc64c1f8bd89128baf84412ebbbc8370c0272d9403842e35ed9154dfa3f72e398b7ce8538eec98adbfa5742ece72e11f
6
+ metadata.gz: 5668e0bc41a319c232392cbd42f688330563df655fef9c355d058d19e9f9396e4377313215eba1d009d267b3c60f60da024c17dc7edd9023f5f626412e8cfa2e
7
+ data.tar.gz: 1cb2086226a351291ad80e19179416432b1054bd7b4ba4316e62058d01dbdb2d2bc9315476bb46ceefce32c53e2e63d0694fc1079b8fbc6b74978e96465aa93c
data/README.md CHANGED
@@ -40,7 +40,6 @@ source (e.g. `Spree::CreditCard`) using a specific payment method (e.g
40
40
  `Solidus::Gateway::Braintree`).
41
41
  * `Spree::PaymentMethod` - A base class which is used for implementing payment methods.
42
42
  * `Spree::PaymentMethod::CreditCard` - An implementation of a `Spree::PaymentMethod` for credit card payments.
43
- See https://github.com/solidusio/solidus_gateway/ for officially supported payment method implementations.
44
43
  * `Spree::CreditCard` - The `source` of a `Spree::Payment` using `Spree::PaymentMethod::CreditCard` as payment method.
45
44
 
46
45
  ## Inventory sub-system
@@ -5,6 +5,7 @@ module Spree::RansackableAttributes
5
5
  included do
6
6
  class_attribute :allowed_ransackable_associations, default: []
7
7
  class_attribute :allowed_ransackable_attributes, default: []
8
+ class_attribute :allowed_ransackable_scopes, default: []
8
9
 
9
10
  def self.whitelisted_ransackable_associations
10
11
  Spree::Deprecation.deprecation_warning(:whitelisted_ransackable_associations, 'use allowed_ransackable_associations instead')
@@ -38,5 +39,9 @@ module Spree::RansackableAttributes
38
39
  def ransackable_attributes(*_args)
39
40
  default_ransackable_attributes | allowed_ransackable_attributes
40
41
  end
42
+
43
+ def ransackable_scopes(*_args)
44
+ allowed_ransackable_scopes
45
+ end
41
46
  end
42
47
  end
@@ -17,18 +17,31 @@ module Spree
17
17
  # @attr [Integer] quantity How many units we want to move
18
18
  #
19
19
  class FulfilmentChanger
20
+ # @note This private constant is only used to deprecate not passing the `track_inventory` argument
21
+ # on initialization. It will be removed in Solidus 4.0, please do not use it.
22
+ TRACK_INVENTORY_NOT_PROVIDED = Object.new.freeze
23
+ private_constant :TRACK_INVENTORY_NOT_PROVIDED
24
+
20
25
  include ActiveModel::Validations
21
26
 
22
27
  attr_accessor :current_shipment, :desired_shipment
23
- attr_reader :variant, :quantity, :current_stock_location, :desired_stock_location
28
+ attr_reader :variant, :quantity, :current_stock_location, :desired_stock_location, :track_inventory
24
29
 
25
- def initialize(current_shipment:, desired_shipment:, variant:, quantity:)
30
+ def initialize(current_shipment:, desired_shipment:, variant:, quantity:, track_inventory: TRACK_INVENTORY_NOT_PROVIDED)
26
31
  @current_shipment = current_shipment
27
32
  @desired_shipment = desired_shipment
28
33
  @current_stock_location = current_shipment.stock_location
29
34
  @desired_stock_location = desired_shipment.stock_location
30
35
  @variant = variant
31
36
  @quantity = quantity
37
+ @track_inventory = if track_inventory == TRACK_INVENTORY_NOT_PROVIDED
38
+ Spree::Deprecation.warn(
39
+ "Not passing `track_inventory` to `Spree::FulfilmentChanger` is deprecated." \
40
+ )
41
+ true
42
+ else
43
+ track_inventory
44
+ end
32
45
  end
33
46
 
34
47
  validates :quantity, numericality: { greater_than: 0 }
@@ -45,6 +58,45 @@ module Spree
45
58
  return false if invalid?
46
59
  desired_shipment.save! if desired_shipment.new_record?
47
60
 
61
+ if track_inventory
62
+ run_tracking_inventory
63
+ else
64
+ run_without_tracking_inventory
65
+ end
66
+
67
+ # We modified the inventory units at the database level for speed reasons.
68
+ # The downside of that is that we need to reload the associations.
69
+ current_shipment.inventory_units.reload
70
+ desired_shipment.inventory_units.reload
71
+
72
+ # If the current shipment now has no inventory units left, we won't need it any longer.
73
+ if current_shipment.inventory_units.length.zero?
74
+ current_shipment.destroy!
75
+ else
76
+ # The current shipment has changed, so we need to make sure that shipping rates
77
+ # have the correct amount.
78
+ current_shipment.refresh_rates
79
+ end
80
+
81
+ # The desired shipment has also change, so we need to make sure shipping rates
82
+ # are up-to-date, too.
83
+ desired_shipment.refresh_rates
84
+
85
+ # In order to reflect the changes in the order totals
86
+ desired_shipment.order.reload
87
+ desired_shipment.order.recalculate
88
+
89
+ true
90
+ end
91
+
92
+ private
93
+
94
+ # When moving things from one stock location to another, we need to restock items
95
+ # from the current location and unstock them at the desired location.
96
+ # Also, when we want to track inventory changes, we need to make sure that we have
97
+ # enough stock at the desired location to fulfil the order. Based on how many items
98
+ # we can take from the desired location, we could end up with some items being backordered.
99
+ def run_tracking_inventory
48
100
  # Retrieve how many on hand items we can take from desired stock location
49
101
  available_quantity = [desired_shipment.stock_location.count_on_hand(variant), default_on_hand_quantity].max
50
102
 
@@ -79,34 +131,21 @@ module Spree
79
131
  limit(quantity - new_on_hand_quantity).
80
132
  update_all(shipment_id: desired_shipment.id, state: :backordered)
81
133
  end
134
+ end
82
135
 
83
- # We modified the inventory units at the database level for speed reasons.
84
- # The downside of that is that we need to reload the associations.
85
- current_shipment.inventory_units.reload
86
- desired_shipment.inventory_units.reload
87
-
88
- # If the current shipment now has no inventory units left, we won't need it any longer.
89
- if current_shipment.inventory_units.length.zero?
90
- current_shipment.destroy!
91
- else
92
- # The current shipment has changed, so we need to make sure that shipping rates
93
- # have the correct amount.
94
- current_shipment.refresh_rates
136
+ # When we don't track inventory, we can just move the inventory units from one shipment
137
+ # to the other.
138
+ def run_without_tracking_inventory
139
+ ActiveRecord::Base.transaction do
140
+ current_shipment.
141
+ inventory_units.
142
+ where(variant: variant).
143
+ order(state: :asc).
144
+ limit(quantity).
145
+ update_all(shipment_id: desired_shipment.id)
95
146
  end
96
-
97
- # The desired shipment has also change, so we need to make sure shipping rates
98
- # are up-to-date, too.
99
- desired_shipment.refresh_rates
100
-
101
- # In order to reflect the changes in the order totals
102
- desired_shipment.order.reload
103
- desired_shipment.order.recalculate
104
-
105
- true
106
147
  end
107
148
 
108
- private
109
-
110
149
  # We don't need to handle stock counts for incomplete orders. Also, if
111
150
  # the new shipment and the desired shipment will ship from the same stock location,
112
151
  # unstocking and restocking will not be necessary.
@@ -15,15 +15,17 @@ module Spree
15
15
  ActiveSupport::TimeZone
16
16
  ].freeze
17
17
 
18
- # Raised when a disallowed class is tried to be loaded
19
- class DisallowedClass < RuntimeError
18
+ class SerializationError < RuntimeError
20
19
  attr_reader :psych_exception
21
20
 
22
21
  def initialize(psych_exception:)
23
22
  @psych_exception = psych_exception
24
23
  super(default_message)
25
24
  end
25
+ end
26
26
 
27
+ # Raised when a disallowed class is tried to be loaded
28
+ class DisallowedClass < SerializationError
27
29
  private
28
30
 
29
31
  def default_message
@@ -40,14 +42,7 @@ module Spree
40
42
  end
41
43
 
42
44
  # Raised when YAML contains aliases and they're not enabled
43
- class BadAlias < RuntimeError
44
- attr_reader :psych_exception
45
-
46
- def initialize(psych_exception:)
47
- @psych_exception = psych_exception
48
- super(default_message)
49
- end
50
-
45
+ class BadAlias < SerializationError
51
46
  private
52
47
 
53
48
  def default_message
@@ -70,11 +65,40 @@ module Spree
70
65
  belongs_to :source, polymorphic: true, optional: true
71
66
 
72
67
  def parsed_details
73
- @details ||= YAML.safe_load(
74
- details,
75
- permitted_classes: self.class.permitted_classes,
76
- aliases: Spree::Config.log_entry_allow_aliases
68
+ handle_psych_serialization_errors do
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
75
+ end
76
+
77
+ def parsed_details=(value)
78
+ handle_psych_serialization_errors do
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
85
+ end
86
+
87
+ def parsed_payment_response_details_with_fallback=(response)
88
+ 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 },
77
95
  )
96
+ end
97
+
98
+ private
99
+
100
+ def handle_psych_serialization_errors
101
+ yield
78
102
  rescue Psych::DisallowedClass => e
79
103
  raise DisallowedClass.new(psych_exception: e)
80
104
  rescue Psych::BadAlias => e
@@ -534,7 +534,7 @@ module Spree
534
534
  state: 'cart',
535
535
  updated_at: Time.current
536
536
  )
537
- self.next if line_items.any?
537
+ self.next
538
538
  end
539
539
 
540
540
  def refresh_shipment_rates
@@ -572,7 +572,7 @@ module Spree
572
572
 
573
573
  def has_non_reimbursement_related_refunds?
574
574
  refunds.non_reimbursement.exists? ||
575
- payments.offset_payment.exists? # how old versions of spree stored refunds
575
+ payments.where("source_type = 'Spree::Payment' AND amount < 0 AND state = 'completed'").exists? # how old versions of spree stored refunds
576
576
  end
577
577
 
578
578
  def tax_total
@@ -57,7 +57,7 @@ module Spree
57
57
  # first unshipped that's leaving from a stock_location that stocks this variant, with availability check
58
58
  # first unshipped that's leaving from a stock_location that stocks this variant, without availability check
59
59
  def determine_target_shipment(quantity)
60
- potential_shipments = order.shipments.select(&:ready_or_pending?)
60
+ potential_shipments = order.shipments.order(:created_at, :id).select(&:ready_or_pending?)
61
61
 
62
62
  potential_shipments.detect do |shipment|
63
63
  shipment.include?(variant)
@@ -15,7 +15,7 @@ module Spree
15
15
 
16
16
  # Assign the attributes to the order and save the order
17
17
  # @return true if saved, otherwise false and errors will be set on the order
18
- def apply
18
+ def call
19
19
  order.validate_payments_attributes(@payments_attributes)
20
20
 
21
21
  assign_order_attributes
@@ -24,6 +24,8 @@ module Spree
24
24
  order.save
25
25
  end
26
26
 
27
+ alias_method :apply, :call
28
+
27
29
  private
28
30
 
29
31
  attr_reader :attributes, :payments_attributes, :order
@@ -206,7 +206,7 @@ module Spree
206
206
  end
207
207
 
208
208
  def record_response(response)
209
- log_entries.create!(details: response.to_yaml)
209
+ log_entries.create!(parsed_payment_response_details_with_fallback: response)
210
210
  end
211
211
 
212
212
  def protect_from_connection_error
@@ -46,7 +46,18 @@ module Spree
46
46
  scope :from_credit_card, -> { where(source_type: 'Spree::CreditCard') }
47
47
  scope :with_state, ->(state) { where(state: state.to_s) }
48
48
  # "offset" is reserved by activerecord
49
- scope :offset_payment, -> { where("source_type = 'Spree::Payment' AND amount < 0 AND state = 'completed'") }
49
+ # TODO: When removing the method we can also:
50
+ # - Remove the `.offsets` association
51
+ # - Remove the `#offsets_total` method
52
+ # - Remove offsets count from the `#credit_allowed` method
53
+ # - Remove offsets check from `Spree::Order#has_non_reimbursement_related_refunds?
54
+ def self.offset_payment
55
+ Spree::Deprecation.warn <<~MSG
56
+ `Spree::Payment offsets` are deprecated. Use the refund system (`Spree::Refund`) instead.
57
+ MSG
58
+
59
+ where("source_type = 'Spree::Payment' AND amount < 0 AND state = 'completed'")
60
+ end
50
61
 
51
62
  scope :checkout, -> { with_state('checkout') }
52
63
  scope :completed, -> { with_state('completed') }
@@ -54,7 +65,7 @@ module Spree
54
65
  scope :processing, -> { with_state('processing') }
55
66
  scope :failed, -> { with_state('failed') }
56
67
 
57
- scope :risky, -> { where("avs_response IN (?) OR (cvv_response_code IS NOT NULL and cvv_response_code != 'M') OR state = 'failed'", RISKY_AVS_CODES) }
68
+ scope :risky, -> { failed.or(where(avs_response: RISKY_AVS_CODES)).or(where.not(cvv_response_code: [nil, '', 'M'])) }
58
69
  scope :valid, -> { where.not(state: %w(failed invalid void)) }
59
70
 
60
71
  scope :store_credits, -> { where(source_type: Spree::StoreCredit.to_s) }
@@ -101,7 +112,10 @@ module Spree
101
112
  # @return [BigDecimal] the amount of this payment minus the offsets
102
113
  # (old-style refunds) and refunds
103
114
  def credit_allowed
104
- amount - (offsets_total.abs + refunds.sum(:amount))
115
+ amount - (
116
+ (self.class.where("source_type = 'Spree::Payment' AND amount < 0 AND state = 'completed' AND source_id = ?", id).sum(:amount)).abs +
117
+ refunds.sum(:amount)
118
+ )
105
119
  end
106
120
 
107
121
  # @return [Boolean] true when this payment can be credited
@@ -127,6 +141,11 @@ module Spree
127
141
  res || payment_method
128
142
  end
129
143
 
144
+ # @return [Boolean] true when this payment is risky
145
+ def risky?
146
+ is_avs_risky? || is_cvv_risky? || state == 'failed'
147
+ end
148
+
130
149
  # @return [Boolean] true when this payment is risky based on address
131
150
  def is_avs_risky?
132
151
  return false if avs_response.blank? || NON_RISKY_AVS_CODES.include?(avs_response)
@@ -137,7 +156,6 @@ module Spree
137
156
  def is_cvv_risky?
138
157
  return false if cvv_response_code == "M"
139
158
  return false if cvv_response_code.nil?
140
- return false if cvv_response_message.present?
141
159
  true
142
160
  end
143
161
 
@@ -4,10 +4,6 @@ module Spree
4
4
  # An implementation of a `Spree::PaymentMethod` for credit card payments.
5
5
  #
6
6
  # It's a good candidate as base class for other credit card based payment methods.
7
- #
8
- # See https://github.com/solidusio/solidus_gateway/ for
9
- # officially supported payment method implementations.
10
- #
11
7
  class PaymentMethod::CreditCard < PaymentMethod
12
8
  def payment_source_class
13
9
  Spree::CreditCard
@@ -158,7 +158,7 @@ module Spree
158
158
  # order: 'COALESCE(cnt, 0) DESC'
159
159
  add_search_scope :descend_by_popularity do
160
160
  joins(:master).
161
- order(%{
161
+ order(Arel.sql(%{
162
162
  COALESCE((
163
163
  SELECT
164
164
  COUNT(#{Spree::LineItem.quoted_table_name}.id)
@@ -171,7 +171,7 @@ module Spree
171
171
  WHERE
172
172
  popular_variants.product_id = #{Spree::Product.quoted_table_name}.id
173
173
  ), 0) DESC
174
- })
174
+ }))
175
175
  end
176
176
 
177
177
  add_search_scope :not_deleted do
@@ -83,7 +83,6 @@ module Spree
83
83
  :height,
84
84
  :price,
85
85
  :sku,
86
- :track_inventory,
87
86
  :weight,
88
87
  :width,
89
88
  ]
@@ -134,10 +133,7 @@ module Spree
134
133
 
135
134
  self.allowed_ransackable_associations = %w[stores variants_including_master master variants]
136
135
  self.allowed_ransackable_attributes = %w[name slug]
137
-
138
- def self.ransackable_scopes(_auth_object = nil)
139
- %i(available with_discarded with_variant_sku_cont with_all_variant_sku_cont with_kept_variant_sku_cont)
140
- end
136
+ self.allowed_ransackable_scopes = %i[available with_discarded with_variant_sku_cont with_all_variant_sku_cont with_kept_variant_sku_cont]
141
137
 
142
138
  # @return [Boolean] true if there are any variants
143
139
  def has_variants?
@@ -2,7 +2,8 @@
2
2
 
3
3
  module Spree
4
4
  class Promotion < Spree::Base
5
- MATCH_POLICIES = %w(all any)
5
+
6
+ autoload(:MATCH_POLICIES, "spree/promotion/match_policies")
6
7
 
7
8
  UNACTIVATABLE_ORDER_STATES = ["complete", "awaiting_return", "returned"]
8
9
 
@@ -54,9 +55,7 @@ module Spree
54
55
 
55
56
  self.allowed_ransackable_associations = ['codes']
56
57
  self.allowed_ransackable_attributes = %w[name path promotion_category_id]
57
- def self.ransackable_scopes(*)
58
- %i(active)
59
- end
58
+ self.allowed_ransackable_scopes = %i[active]
60
59
 
61
60
  def self.order_activatable?(order)
62
61
  order && !UNACTIVATABLE_ORDER_STATES.include?(order.state)
@@ -53,7 +53,7 @@ module Spree
53
53
  credit_cents = money.cents
54
54
 
55
55
  @perform_response = process!(credit_cents)
56
- log_entries.build(details: perform_response.to_yaml)
56
+ log_entries.build(parsed_payment_response_details_with_fallback: perform_response)
57
57
 
58
58
  self.transaction_id = perform_response.authorization
59
59
  save!
@@ -286,7 +286,7 @@ module Spree
286
286
 
287
287
  # Updates the state of the Shipment bypassing any callbacks.
288
288
  #
289
- # If this moves the shipmnent to the 'shipped' state, after_ship will be
289
+ # If this moves the shipment to the 'shipped' state, after_ship will be
290
290
  # called.
291
291
  def update_state
292
292
  old_state = state
@@ -18,9 +18,11 @@ module Spree
18
18
  after_update :update_child_permalinks, if: :saved_change_to_permalink?
19
19
 
20
20
  validates :name, presence: true
21
+ validates :name, uniqueness: { scope: :parent_id, message: :must_be_unique_under_same_parent }, if: -> { Spree::Config.extra_taxon_validations}
21
22
  validates :meta_keywords, length: { maximum: 255 }
22
23
  validates :meta_description, length: { maximum: 255 }
23
24
  validates :meta_title, length: { maximum: 255 }
25
+ validates :taxonomy_id, uniqueness: { message: :can_have_only_one_root }, if: -> { Spree::Config.extra_taxon_validations && root? }
24
26
 
25
27
  after_save :touch_ancestors_and_taxonomy
26
28
  after_touch :touch_ancestors_and_taxonomy
@@ -5,6 +5,7 @@ module Spree
5
5
  acts_as_list
6
6
 
7
7
  validates :name, presence: true
8
+ validates :name, uniqueness: true, if: -> { Spree::Config.extra_taxonomy_validations }
8
9
 
9
10
  has_many :taxons, inverse_of: :taxonomy
10
11
  has_one :root, -> { where parent_id: nil }, class_name: "Spree::Taxon", dependent: :destroy
@@ -24,19 +24,19 @@ class Spree::Wallet::AddPaymentSourcesToWallet
24
24
  # add valid sources to wallet and optionally set a default
25
25
  if sources.any?
26
26
  # arbitrarily sort by id for picking a default
27
- sources.sort_by(&:id).each do |source|
27
+ order_wallet_payment_sources = sources.sort_by(&:id).map do |source|
28
28
  order.user.wallet.add(source)
29
29
  end
30
30
 
31
- make_default
31
+ make_default(order_wallet_payment_sources)
32
32
  end
33
33
  end
34
34
  end
35
35
 
36
36
  protected
37
37
 
38
- def make_default
39
- order.user.wallet.default_wallet_payment_source = order.user.wallet_payment_sources.last
38
+ def make_default(sources)
39
+ order.user.wallet.default_wallet_payment_source = sources.last
40
40
  end
41
41
 
42
42
  private
@@ -1,8 +1,8 @@
1
1
  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
2
  <html xmlns="http://www.w3.org/1999/xhtml">
3
3
  <head>
4
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5
- <meta name="viewport" content="width=device-width"/>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+ <meta name="viewport" content="width=device-width">
6
6
  <style>
7
7
  /**********************************************
8
8
  * Ink v1.0.5 - Copyright 2013 ZURB Inc *
@@ -498,6 +498,12 @@ en:
498
498
  attributes:
499
499
  base:
500
500
  cannot_destroy_default_store: Cannot destroy the default Store.
501
+ spree/taxon:
502
+ attributes:
503
+ name:
504
+ must_be_unique_under_same_parent: must be unique under the same parent Taxon
505
+ taxonomy_id:
506
+ can_have_only_one_root: can only have one root Taxon
501
507
  spree/user_address:
502
508
  attributes:
503
509
  user_id:
@@ -1105,7 +1111,7 @@ en:
1105
1111
  cannot_rebuild_shipments_order_completed: Cannot rebuild shipments for a completed order.
1106
1112
  cannot_rebuild_shipments_shipments_not_pending: Cannot rebuild shipments for an order with non-pending shipments.
1107
1113
  cannot_set_shipping_method_without_address: Cannot set shipping method until customer details are provided.
1108
- cannot_update_email: You do not have access to update this user's email address. <br />Please contact a superuser if you need to perform this action.
1114
+ cannot_update_email: You do not have access to update this user's email address. <br>Please contact a superuser if you need to perform this action.
1109
1115
  capture: Capture
1110
1116
  capture_events: Capture events
1111
1117
  card_code: Card Code
@@ -1467,7 +1473,7 @@ en:
1467
1473
  date_picker:
1468
1474
  first_day: 0
1469
1475
  format: "%Y/%m/%d"
1470
- js_format: yy/mm/dd
1476
+ js_format: Y/m/d
1471
1477
  date_range: Date Range
1472
1478
  default: Default
1473
1479
  default_refund_amount: Default Refund Amount
@@ -1612,43 +1618,44 @@ en:
1612
1618
  shipping_methods: This is used to calculate the shipping rates on a per order or per package rate.
1613
1619
  tax_rates: The "Default Tax" calculator is used for both sales tax (United States-style taxes) and value-added tax (VAT). Typically this calculator should be the only tax calculator required by your store. "Flat Fee" can be used for any taxes that require a flat fee be charged to the customer.
1614
1620
  spree/price:
1615
- country: 'This determines in what country the price is valid.<br/>Default: Any Country'
1621
+ country: 'This determines in what country the price is valid.<br>Default: Any Country'
1616
1622
  master_variant: Changing master variant prices will not change variant prices below, but will be used to populate all new variants
1617
1623
  options: These options are used to create variants in the variants table. They can be changed in the variants tab
1618
1624
  spree/product:
1619
1625
  available_on: This sets the availability date for the product. If this value is not set, or it is set to a date in the future, then the product is not available on the storefront.
1620
1626
  discontinue_on: This sets the discontinue date for the product. If this value is set to a date, then the product is not available on the storefront from that day on anymore.
1621
- promotionable: 'This determines whether or not promotions can apply to this product.<br/>Default: Checked'
1622
- shipping_category: 'This determines what kind of shipping this product requires.<br/> Default: Default'
1623
- tax_category: 'This determines what kind of taxation is applied to this product.<br/> Default: %{default_tax_category}'
1627
+ promotionable: 'This determines whether or not promotions can apply to this product.<br>Default: Checked'
1628
+ shipping_category: 'This determines what kind of shipping this product requires.<br> Default: Default'
1629
+ tax_category: 'This determines what kind of taxation is applied to this product.<br> Default: %{default_tax_category}'
1624
1630
  spree/promotion:
1625
- expires_at: This determines when the promotion expires. <br/> If no value is specified, the promotion will never expire.
1631
+ expires_at: This determines when the promotion expires. <br> If no value is specified, the promotion will never expire.
1626
1632
  promo_code_will_be_disabled: Selecting this option, promo codes will be disabled for this promotion because all its rules / actions will be applied automatically to all orders.
1627
- starts_at: This determines when the promotion can be applied to orders. <br/> If no value is specified, the promotion will be immediately available.
1633
+ starts_at: This determines when the promotion can be applied to orders. <br> If no value is specified, the promotion will be immediately available.
1628
1634
  spree/shipping_method:
1629
1635
  available_to_all: Uncheck to select specific stock locations this shipping method will be available in.
1630
1636
  spree/stock_location:
1631
- active: 'This determines whether stock from this location can be used when building packages.<br/> Default: Checked'
1632
- backorderable_default: 'When checked, stock items in this location will default to allowing backorders.<br/> Default: Unchecked'
1633
- check_stock_on_transfer: 'When checked, inventory levels will be checked when performing stock transfers.<br/> Default: Checked'
1634
- fulfillable: 'When unchecked, this indicates that items in this location don''t require actual fulfilment. Stock will not be checked when shipping and emails will not be sent.<br/> Default: Checked'
1635
- propagate_all_variants: 'When checked, this will create a stock item for each variant in this stock location.<br/> Default: Checked'
1636
- restock_inventory: 'When checked, returned inventory can be added back to this location''s stock levels.<br/> Default: checked'
1637
+ active: 'This determines whether stock from this location can be used when building packages.<br> Default: Checked'
1638
+ backorderable_default: 'When checked, stock items in this location will default to allowing backorders.<br> Default: Unchecked'
1639
+ check_stock_on_transfer: 'When checked, inventory levels will be checked when performing stock transfers.<br> Default: Checked'
1640
+ fulfillable: 'When unchecked, this indicates that items in this location don''t require actual fulfilment. Stock will not be checked when shipping and emails will not be sent.<br> Default: Checked'
1641
+ propagate_all_variants: 'When checked, this will create a stock item for each variant in this stock location.<br> Default: Checked'
1642
+ restock_inventory: 'When checked, returned inventory can be added back to this location''s stock levels.<br> Default: checked'
1637
1643
  spree/store:
1638
1644
  available_locales: This determines which locales are available for your customers to choose from in the storefront.
1639
- cart_tax_country_iso: 'This determines which country is used for taxes on carts (orders which don''t yet have an address).<br/> Default: None.'
1645
+ cart_tax_country_iso: 'This determines which country is used for taxes on carts (orders which don''t yet have an address).<br> Default: None.'
1640
1646
  code: An identifier for your store. Developers may need this value if you operate multiple storefronts.
1647
+ default_currency: This determines which currency will be used for the storefront's product prices. Please, be aware that changing this configuration, only products that have prices in the selected currency will be listed on your storefront. <br><br>This setting won't change the default currency used when you create a product. For that, only the global `Spree::Config.currency` is taken into account.
1641
1648
  spree/tax_category:
1642
1649
  is_default: When checked, this tax category will be selected by default when creating new products or variants.
1643
1650
  spree/tax_rate:
1644
1651
  tax_rate_level: Item-level taxes will be applied as adjustments on line items and shipments. Order-level taxes will create an adjustment on the order. Care should be taken when chosing order-level adjustments as they aren't considered in refunds or in discounts. The default is item-level.
1645
- validity_period: This determines the validity period within which the tax rate is valid and will be applied to eligible items. <br /> If no start date value is specified, the tax rate will be immediately available. <br /> If no expiration date value is specified, the tax rate will never expire
1652
+ validity_period: This determines the validity period within which the tax rate is valid and will be applied to eligible items. <br> If no start date value is specified, the tax rate will be immediately available. <br> If no expiration date value is specified, the tax rate will never expire
1646
1653
  spree/variant:
1647
1654
  deleted: Deleted Variant
1648
1655
  deleted_explanation: This variant was deleted on %{date}.
1649
1656
  deleted_explanation_with_replacement: This variant was deleted on %{date}. It has since been replaced by another with the same SKU.
1650
- shipping_category: 'This determines what kind of shipping this variant requires.<br/> Default: Use shipping category of the product associated with this variant'
1651
- tax_category: 'This determines what kind of taxation is applied to this variant.<br/> Default: Use tax category of the product associated with this variant'
1657
+ shipping_category: 'This determines what kind of shipping this variant requires.<br> Default: Use shipping category of the product associated with this variant'
1658
+ tax_category: 'This determines what kind of taxation is applied to this variant.<br> Default: Use tax category of the product associated with this variant'
1652
1659
  home: Home
1653
1660
  i18n:
1654
1661
  available_locales: Available Locales
@@ -1,3 +1,3 @@
1
1
  apply "#{__dir__}/break_down_solidus_gem.rb"
2
2
  run_bundle
3
- apply 'https://github.com/solidusio/solidus_starter_frontend/raw/v3.3/template.rb'
3
+ apply 'https://github.com/solidusio/solidus_starter_frontend/raw/v3.4/template.rb'
@@ -10,4 +10,4 @@ unless Bundler.locked_gems.dependencies['solidus_bolt']
10
10
  bundle_command 'add solidus_bolt'
11
11
  end
12
12
 
13
- generate 'solidus_bolt:install'
13
+ generate "solidus_bolt:install --auto-run-migrations=#{options[:migrate]}"
@@ -0,0 +1,5 @@
1
+ unless Bundler.locked_gems.dependencies['solidus_braintree']
2
+ bundle_command 'add solidus_braintree --version "~> 3.0"'
3
+ end
4
+
5
+ generate "solidus_braintree:install --migrate=#{options[:migrate]}"
@@ -2,9 +2,16 @@ unless Bundler.locked_gems.dependencies['solidus_frontend']
2
2
  say_status :warning, "Support for frontends other than `solidus_frontend` by `solidus_paypal_commerce_platform` is still in progress.", :yellow
3
3
  end
4
4
 
5
+ if @selected_frontend == 'classic'
6
+ version = '< 1'
7
+ migrations_flag = options[:migrate] ? '--auto-run-migrations' : '--skip-migrations'
8
+ else
9
+ version = '~> 1.0'
10
+ migrations_flag = "--migrate=#{options[:migrate]}"
11
+ end
12
+
5
13
  unless Bundler.locked_gems.dependencies['solidus_paypal_commerce_platform']
6
- version = @selected_frontend == 'classic' ? '< 1' : '~> 1.0'
7
14
  bundle_command "add solidus_paypal_commerce_platform --version='#{version}'"
8
15
  end
9
16
 
10
- generate 'solidus_paypal_commerce_platform:install'
17
+ generate "solidus_paypal_commerce_platform:install #{migrations_flag}"
@@ -29,10 +29,31 @@ module Solidus
29
29
  none
30
30
  ]
31
31
 
32
- PAYMENT_METHODS = %w[
33
- paypal
34
- bolt
35
- none
32
+ PAYMENT_METHODS = [
33
+ {
34
+ name: 'paypal',
35
+ frontends: %w[none classic starter],
36
+ description: 'Install `solidus_paypal_commerce_platform`',
37
+ default: true,
38
+ },
39
+ {
40
+ name: 'bolt',
41
+ frontends: %w[classic],
42
+ description: 'Install `solidus_bolt`',
43
+ default: false,
44
+ },
45
+ {
46
+ name: 'braintree',
47
+ frontends: %w[none starter],
48
+ description: 'Install `solidus_braintree`',
49
+ default: false,
50
+ },
51
+ {
52
+ name: 'none',
53
+ frontends: %w[none classic starter],
54
+ description: 'Skip installing a payment method',
55
+ default: false,
56
+ },
36
57
  ]
37
58
 
38
59
  class_option :migrate, type: :boolean, default: true, banner: 'Run Solidus migrations'
@@ -48,7 +69,7 @@ module Solidus
48
69
 
49
70
  class_option :frontend, type: :string, enum: FRONTENDS + LEGACY_FRONTENDS, default: nil, desc: "Indicates which frontend to install."
50
71
  class_option :authentication, type: :string, enum: AUTHENTICATIONS, default: nil, desc: "Indicates which authentication system to install."
51
- class_option :payment_method, type: :string, enum: PAYMENT_METHODS, default: nil, desc: "Indicates which payment method to install."
72
+ class_option :payment_method, type: :string, enum: PAYMENT_METHODS.map { |payment_method| payment_method[:name] }, default: nil, desc: "Indicates which payment method to install."
52
73
 
53
74
  # DEPRECATED
54
75
  class_option :with_authentication, type: :boolean, hide: true, default: nil
@@ -98,7 +119,7 @@ module Solidus
98
119
  rake 'active_storage:install'
99
120
  else
100
121
  say_status :assets, "Paperclip", :green
101
- gsub_file 'config/initializers/spree.rb', "::ActiveStorageAttachment", "::PaperclipAttachment"
122
+ gsub_file 'config/initializers/spree.rb', "ActiveStorageAttachment", "PaperclipAttachment"
102
123
  end
103
124
  end
104
125
 
@@ -201,12 +222,6 @@ module Solidus
201
222
 
202
223
  private
203
224
 
204
- def generate(what, *args, abort_on_failure: true)
205
- args << '--auto-accept' if options[:auto_accept]
206
- args << '--auto-run-migrations' if options[:migrate]
207
- super(what, *args, abort_on_failure: abort_on_failure)
208
- end
209
-
210
225
  def bundle_command(command, env = {})
211
226
  # Make `bundle install` less verbose by skipping the "Using ..." messages
212
227
  super(command, env.reverse_merge('BUNDLE_SUPPRESS_INSTALL_USING_MESSAGES' => 'true'))
@@ -323,29 +338,26 @@ module Solidus
323
338
  return 'paypal' if Bundler.locked_gems.dependencies['solidus_paypal_commerce_platform']
324
339
  return 'bolt' if Bundler.locked_gems.dependencies['solidus_bolt']
325
340
 
326
- descriptions = {
327
- paypal: "- [#{set_color 'paypal', :bold}] Install `solidus_paypal_commerce_platform` (#{set_color :default, :bold}).",
328
- bolt: "- [#{set_color 'bolt', :bold}] Install `solidus_bolt`.",
329
- none: "- [#{set_color 'none', :bold}] Skip installing a payment method.",
330
- }
331
-
332
- payment_methods = PAYMENT_METHODS
333
-
334
- if @selected_frontend != 'classic'
335
- payment_methods -= ['bolt']
336
- descriptions.delete(:bolt)
341
+ selected_frontend_payment_methods = PAYMENT_METHODS.select do |payment_method|
342
+ payment_method[:frontends].include?(@selected_frontend)
337
343
  end
338
344
 
339
345
  selected = options[:payment_method] || (options[:auto_accept] && 'paypal') ||
340
346
  ask_with_description(
341
347
  default: 'paypal',
342
- limited_to: payment_methods,
348
+ limited_to: selected_frontend_payment_methods.map { |payment_method| payment_method[:name] },
343
349
  desc: <<~TEXT
344
350
  Which payment method would you like to use?
345
351
 
346
- #{descriptions.values.join("\n")}
352
+ #{selected_frontend_payment_methods.map { |payment_method| formatted_payment_method_description(payment_method) }.join("\n")}
347
353
  TEXT
348
354
  )
349
355
  end
356
+
357
+ def formatted_payment_method_description(payment_method)
358
+ default_label = " (#{set_color :default, :bold})" if payment_method[:default]
359
+
360
+ "- [#{set_color payment_method[:name], :bold}] #{payment_method[:description]}#{default_label}."
361
+ end
350
362
  end
351
363
  end
@@ -65,6 +65,22 @@ module Spree
65
65
  # @return [Boolean] When false, admins cannot create promotions with an "any" match policy (default: +false+)
66
66
  # Create individual, separate promotions for each of your rules instead.
67
67
  preference :allow_promotions_any_match_policy, :boolean, default: false
68
+ def allow_promotions_any_match_policy=(value)
69
+ if value == true
70
+ Spree::Deprecation.warn <<~MSG
71
+ Solidus 4.0 will remove support for combining promotion rules with the "any" match policy.
72
+
73
+ Instead, it's suggested to create individual, separate promotions for each of your current
74
+ rules combined with the "any" policy. To automate this task, you can use the provided
75
+ task:
76
+
77
+ bin/rake solidus:split_promotions_with_any_match_policy
78
+ MSG
79
+ end
80
+
81
+ preferences[:allow_promotions_any_match_policy] = value
82
+ end
83
+
68
84
 
69
85
  # @!attribute [rw] guest_token_cookie_options
70
86
  # @return [Hash] Add additional guest_token cookie options here (ie. domain or path)
@@ -155,6 +171,38 @@ module Spree
155
171
  # @return [Regexp] Regex to be used in email validations, for example in Spree::EmailValidator
156
172
  preference :default_email_regexp, :regexp, default: URI::MailTo::EMAIL_REGEXP
157
173
 
174
+ # @!attribute [rw] extra_taxon_validations
175
+ # Use extra validations on Taxons in 3.4.0, but default to false so stores can
176
+ # upgrade and then fix any now invalid Taxons before enabling.
177
+ # @return [Boolean]
178
+ versioned_preference :extra_taxon_validations, :boolean, initial_value: false, boundaries: { "3.4.0.dev" => true }
179
+ def extra_taxon_validations=(value)
180
+ Spree::Deprecation.warn <<~MSG
181
+ Solidus will remove `Spree::Config.extra_taxon_validations` preference
182
+ in the next major release and will always use the extra Taxon validations.
183
+ Before upgrading to the next major, please fix any now invalid Taxons
184
+ and then remove the preference definition in `config/initializers/spree.rb`.
185
+ MSG
186
+
187
+ preferences[:extra_taxon_validations] = value
188
+ end
189
+
190
+ # @!attribute [rw] extra_taxonomy_validations
191
+ # Use extra validations on Taxonomies in 3.4.0, but default to false so stores can
192
+ # upgrade and then fix any now invalid Taxonomies before enabling.
193
+ # @return [Boolean]
194
+ versioned_preference :extra_taxonomy_validations, :boolean, initial_value: false, boundaries: { "3.4.0.dev" => true }
195
+ def extra_taxonomy_validations=(value)
196
+ Spree::Deprecation.warn <<~MSG
197
+ Solidus will remove `Spree::Config.extra_taxonomy_validations` preference
198
+ in the next major release and will always use the extra Taxonomy validations.
199
+ Before upgrading to the next major, please fix any now invalid Taxons
200
+ and then remove the preference definition in `config/initializers/spree.rb`.
201
+ MSG
202
+
203
+ preferences[:extra_taxonomy_validations] = value
204
+ end
205
+
158
206
  # @!attribute [rw] generate_api_key_for_all_roles
159
207
  # @return [Boolean] Allow generating api key automatically for user
160
208
  # at role_user creation for all roles. (default: +false+)
@@ -378,6 +426,13 @@ module Spree
378
426
  # signature as Spree::OrderMailer.confirm_email.
379
427
  class_name_attribute :order_mailer_class, default: 'Spree::OrderMailer'
380
428
 
429
+ # Allows providing your own order update attributes class for checkout.
430
+ #
431
+ # @!attribute [rw] order_update_attributes_class
432
+ # @return [Class] a class that responds to "call"
433
+ # with the same signature as Spree::OrderUpdateAttributes.
434
+ class_name_attribute :order_update_attributes_class, default: 'Spree::OrderUpdateAttributes'
435
+
381
436
  # Allows providing your own Mailer for promotion code batch mailer.
382
437
  #
383
438
  # @!attribute [rw] promotion_code_batch_mailer_class
@@ -120,9 +120,7 @@ module Spree
120
120
 
121
121
  # This is a strange thing to do since an order can have multiple payments
122
122
  # but we always assume that it only has a single payment and that its
123
- # amount should be the current order total. Also, this is pretty much
124
- # overridden when the order transitions to confirm by the logic inside of
125
- # Order#add_store_credit_payments.
123
+ # amount should be the current order total after store credit is applied.
126
124
  # We should reconsider this method and its usage at some point.
127
125
  #
128
126
  # This method expects a params hash in the format of:
@@ -147,7 +145,7 @@ module Spree
147
145
  # payments_attributes: [
148
146
  # {
149
147
  # ...params...
150
- # amount: <the order total>,
148
+ # amount: <the order total after store credit>,
151
149
  # },
152
150
  # ],
153
151
  # ...other params...
@@ -159,7 +157,7 @@ module Spree
159
157
  return params if params[:order].blank?
160
158
  return params if params[:order][:payments_attributes].blank?
161
159
 
162
- params[:order][:payments_attributes].first[:amount] = order.total
160
+ params[:order][:payments_attributes].first[:amount] = order.order_total_after_store_credit
163
161
 
164
162
  params
165
163
  end
@@ -1,14 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Spree
4
- VERSION = "3.3.4"
4
+ VERSION = "3.4.0"
5
5
 
6
6
  def self.solidus_version
7
7
  VERSION
8
8
  end
9
9
 
10
10
  def self.previous_solidus_minor_version
11
- '3.2'
11
+ '3.3'
12
12
  end
13
13
 
14
14
  def self.solidus_gem_version
@@ -6,9 +6,9 @@ module Spree
6
6
  remove_index(table, column) if index_exists?(table, column)
7
7
  end
8
8
 
9
- def safe_add_index(table, column, **options)
10
- if columns_exist?(table, column) && !index_exists?(table, column, **options)
11
- add_index(table, column, **options)
9
+ def safe_add_index(table, column, options = {})
10
+ if columns_exist?(table, column) && !index_exists?(table, column, options)
11
+ add_index(table, column, options)
12
12
  end
13
13
  end
14
14
 
@@ -0,0 +1,2 @@
1
+ Spree::Promotion::MATCH_POLICIES = %w(all any)
2
+ Spree::Deprecation.warn('Spree::Promotion::MATCH_POLICIES is deprecated')
@@ -10,11 +10,13 @@ end
10
10
  FactoryBot.define do
11
11
  factory :taxon, class: 'Spree::Taxon' do
12
12
  name { 'Ruby on Rails' }
13
- taxonomy
14
- parent_id { nil }
13
+ taxonomy_id { (parent&.taxonomy || create(:taxonomy)).id }
14
+ parent_id { parent&.id || taxonomy.root.id }
15
15
 
16
16
  trait :with_icon do
17
- icon { Spree::Core::Engine.root.join('lib', 'spree', 'testing_support', 'fixtures', 'blank.jpg').open }
17
+ after(:create) do |taxon|
18
+ taxon.update(icon: Spree::Core::Engine.root.join('lib', 'spree', 'testing_support', 'fixtures', 'blank.jpg').open)
19
+ end
18
20
  end
19
21
  end
20
22
  end
@@ -7,6 +7,8 @@ end
7
7
 
8
8
  FactoryBot.define do
9
9
  factory :taxonomy, class: 'Spree::Taxonomy' do
10
- name { 'Brand' }
10
+ sequence :name do |seq|
11
+ "Brand #{seq}"
12
+ end
11
13
  end
12
14
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+ require 'rspec/retry'
3
+
4
+ # Usage:
5
+ #
6
+ # it 'fails intermittently', :flaky do
7
+ # ...
8
+ # end
9
+ #
10
+ # Docs: https://github.com/NoRedInk/rspec-retry
11
+ RSpec.configure do |config|
12
+ config.verbose_retry = true
13
+ config.display_try_failure_messages = true
14
+
15
+ config.around(:each, :flaky) do |example|
16
+ if ENV['CI']
17
+ example.run_with_retry retry: 2
18
+ else
19
+ example.run
20
+ end
21
+ end
22
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solidus_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.4
4
+ version: 3.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Solidus Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-08-14 00:00:00.000000000 Z
11
+ date: 2023-04-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionmailer
@@ -778,6 +778,7 @@ files:
778
778
  - lib/generators/solidus/install/app_templates/frontend/none.rb
779
779
  - lib/generators/solidus/install/app_templates/frontend/starter.rb
780
780
  - lib/generators/solidus/install/app_templates/payment_method/bolt.rb
781
+ - lib/generators/solidus/install/app_templates/payment_method/braintree.rb
781
782
  - lib/generators/solidus/install/app_templates/payment_method/none.rb
782
783
  - lib/generators/solidus/install/app_templates/payment_method/paypal.rb
783
784
  - lib/generators/solidus/install/install_generator.rb
@@ -885,6 +886,7 @@ files:
885
886
  - lib/spree/preferences/static_model_preferences.rb
886
887
  - lib/spree/preferences/statically_configurable.rb
887
888
  - lib/spree/preferences/store.rb
889
+ - lib/spree/promotion/match_policies.rb
888
890
  - lib/spree/rails_compatibility.rb
889
891
  - lib/spree/testing_support.rb
890
892
  - lib/spree/testing_support/ability_helpers.rb
@@ -969,6 +971,7 @@ files:
969
971
  - lib/spree/testing_support/factory_bot.rb
970
972
  - lib/spree/testing_support/fixtures/blank.jpg
971
973
  - lib/spree/testing_support/fixtures/file.txt
974
+ - lib/spree/testing_support/flaky.rb
972
975
  - lib/spree/testing_support/flash.rb
973
976
  - lib/spree/testing_support/job_helpers.rb
974
977
  - lib/spree/testing_support/order_walkthrough.rb
@@ -1034,7 +1037,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1034
1037
  - !ruby/object:Gem::Version
1035
1038
  version: 1.8.23
1036
1039
  requirements: []
1037
- rubygems_version: 3.4.9
1040
+ rubygems_version: 3.4.6
1038
1041
  signing_key:
1039
1042
  specification_version: 4
1040
1043
  summary: Essential models, mailers, and classes for the Solidus e-commerce project.