solidus_core 4.6.3 → 4.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 03c5f9ed344221d9efde0c16e7d40604521c067f36abbf3e09b050fbc9efd3de
4
- data.tar.gz: 920e1ac4c8266d2110c1eed180d5ffe32e8d16bab3a92ff02eab5446ecba6a2c
3
+ metadata.gz: 9ab7d28a51c8f5ad031bf0613a5dc1c3fddff295f09edf5032ee6b5173d22ca3
4
+ data.tar.gz: 4e5e1b57bb62eeff08f426242c042603eb8112804afaca7490b618739fc4e564
5
5
  SHA512:
6
- metadata.gz: 3f81fd0110e433d54dc81e4f73f9f3c0e3dfc37a81c30a443ea2e9c72d0e9882362e917f121b917bfac36300cd2aae7495eec86b40c624873c4cfc5d070d6bf8
7
- data.tar.gz: 3cedf567b53ad2a9ddee3b4da7f863787092c9d72daccc7fbd02fa4244d9447a1a8a5e3a84c9eeec080b759e57656c8a56dd3ae173f982283cb531169e715aed
6
+ metadata.gz: 9a04c4401ce4d6b775b9f0ef450315941cc944722429d8cbc066d8f608ffd567b41d6aa53060ce1fe90a76292676b359c0ca15d6255a59f54cbeaea3dfa02c20
7
+ data.tar.gz: a178b017f4121166d78af2ce80ce2ba9dbbfc04e87c677f30d0bca86874f4c02ee2cd3511b3b2cb5caef70cf2c5ffdbc85ef8a8afa4c721381b3e490eb4458bb
@@ -14,19 +14,19 @@ module Spree
14
14
 
15
15
  def permitted_credit_card_update_attributes
16
16
  permitted_attributes.credit_card_update_attributes + [
17
- address_attributes: permitted_address_attributes
17
+ { address_attributes: permitted_address_attributes }
18
18
  ]
19
19
  end
20
20
 
21
21
  def permitted_payment_attributes
22
22
  permitted_attributes.payment_attributes + [
23
- source_attributes: permitted_source_attributes
23
+ { source_attributes: permitted_source_attributes }
24
24
  ]
25
25
  end
26
26
 
27
27
  def permitted_source_attributes
28
28
  permitted_attributes.source_attributes + [
29
- address_attributes: permitted_address_attributes
29
+ { address_attributes: permitted_address_attributes }
30
30
  ]
31
31
  end
32
32
 
@@ -52,20 +52,22 @@ module Spree
52
52
  permitted_checkout_payment_attributes +
53
53
  permitted_attributes.customer_metadata_attributes +
54
54
  permitted_checkout_confirm_attributes + [
55
- line_items_attributes: permitted_line_item_attributes
55
+ { line_items_attributes: permitted_line_item_attributes }
56
56
  ]
57
57
  end
58
58
 
59
59
  def permitted_product_attributes
60
60
  permitted_attributes.product_attributes + [
61
- product_properties_attributes: permitted_product_properties_attributes
61
+ { product_properties_attributes: permitted_product_properties_attributes }
62
62
  ]
63
63
  end
64
64
 
65
65
  def permitted_user_attributes
66
66
  permitted_attributes.user_attributes + [
67
- bill_address_attributes: permitted_address_attributes,
68
- ship_address_attributes: permitted_address_attributes
67
+ {
68
+ bill_address_attributes: permitted_address_attributes,
69
+ ship_address_attributes: permitted_address_attributes
70
+ }
69
71
  ]
70
72
  end
71
73
  end
@@ -49,7 +49,7 @@ module Spree
49
49
  if Spree::Config[:show_raw_product_description]
50
50
  raw(product.description)
51
51
  else
52
- raw(product.description.gsub(/(.*?)\r?\n\r?\n/m, '<p>\1</p>'))
52
+ sanitize(product.description.gsub(/(.*?)\r?\n\r?\n/m, '<p>\1</p>'))
53
53
  end
54
54
  end
55
55
 
@@ -130,14 +130,14 @@ module Spree
130
130
 
131
131
  # Updates the roles in keeping with the given ability's permissions
132
132
  #
133
- # Roles that are not accessible to the given ability will be ignored. It
134
- # also ensure not to remove non accessible roles when assigning new
135
- # accessible ones.
133
+ # Roles that the given ability cannot manage will be ignored. It also
134
+ # ensure not to remove non manageable roles when assigning new manageable
135
+ # ones.
136
136
  #
137
137
  # @param given_roles [Spree::Role]
138
138
  # @param ability [Spree::Ability]
139
139
  def update_spree_roles(given_roles, ability:)
140
- accessible_roles = Spree::Role.accessible_by(ability)
140
+ accessible_roles = Spree::Role.accessible_by(ability, :manage)
141
141
  non_accessible_roles = Spree::Role.all - accessible_roles
142
142
  new_accessible_roles = given_roles - non_accessible_roles
143
143
  self.spree_roles = spree_roles - accessible_roles + new_accessible_roles
@@ -8,6 +8,10 @@ module Spree
8
8
  # * :payment_method_id Id of payment method used for this payment
9
9
  # * :source_attributes Attributes used to build the source of this payment. Usually a {CreditCard}
10
10
  # * :wallet_payment_source_id (Integer): The id of a {WalletPaymentSource} to use
11
+ # * :gateway_customer_profile_id, :gateway_payment_profile_id (String): Gateway
12
+ # identifiers for a new {CreditCard}, e.g. a one-time token. Raises
13
+ # ActiveRecord::RecordNotFound if either already belongs to a {CreditCard}
14
+ # owned by a different user.
11
15
  # @param request_env [Hash] rack env of user creating the payment
12
16
  # @param payment [Payment] Internal use only. Instead of making a new payment, change the attributes for an existing one.
13
17
  def initialize(order, attributes, payment: nil, request_env: {})
@@ -44,6 +48,7 @@ module Spree
44
48
  def build_source
45
49
  payment_method = payment.payment_method
46
50
  if source_attributes.present? && payment_method.try(:payment_source_class)
51
+ ensure_gateway_profile_ownership!(payment_method.payment_source_class)
47
52
  payment.source = payment_method.payment_source_class.new(source_attributes)
48
53
  payment.source.payment_method_id = payment_method.id
49
54
  if order && payment.source.respond_to?(:user=)
@@ -52,6 +57,24 @@ module Spree
52
57
  end
53
58
  end
54
59
 
60
+ # Gateway profile ids may only be submitted for a new source when they are
61
+ # unknown to the store (e.g. a one-time token) or already belong to the
62
+ # order's user. Raises if either id is stored on a {CreditCard} owned by a
63
+ # different user, so customers cannot pay with another customer's stored
64
+ # gateway credential.
65
+ def ensure_gateway_profile_ownership!(source_class)
66
+ return unless source_class <= Spree::CreditCard
67
+
68
+ %i[gateway_customer_profile_id gateway_payment_profile_id].each do |attribute|
69
+ value = source_attributes[attribute]
70
+ next if value.blank?
71
+
72
+ foreign_cards = Spree::CreditCard.where(attribute => value).where.not(user_id: nil)
73
+ foreign_cards = foreign_cards.where.not(user_id: order.user_id) if order&.user_id
74
+ raise ActiveRecord::RecordNotFound if foreign_cards.exists?
75
+ end
76
+ end
77
+
55
78
  def build_from_wallet_payment_source
56
79
  wallet_payment_source_id = source_attributes.fetch(:wallet_payment_source_id)
57
80
  raise(ActiveRecord::RecordNotFound) if order.user.nil?
@@ -364,14 +364,17 @@ module Spree
364
364
  run_callbacks(:touch)
365
365
  end
366
366
 
367
- # Iterate through this product's taxons and taxonomies and touch their timestamps in a batch
367
+ # Iterate through this product's taxons and taxonomies and touch their timestamps
368
368
  def touch_taxons
369
- taxons_to_touch = taxons.flat_map(&:self_and_ancestors).uniq
370
- unless taxons_to_touch.empty?
371
- Spree::Taxon.where(id: taxons_to_touch.map(&:id)).update_all(updated_at: Time.current)
369
+ taxons_to_touch = taxons.flat_map(&:self_and_ancestors).uniq.sort_by(&:id)
370
+ return if taxons_to_touch.empty?
372
371
 
373
- taxonomy_ids_to_touch = taxons_to_touch.flat_map(&:taxonomy_id).uniq
374
- Spree::Taxonomy.where(id: taxonomy_ids_to_touch).update_all(updated_at: Time.current)
372
+ time = Time.current
373
+ taxons_to_touch.each { |taxon| taxon.update_column(:updated_at, time) }
374
+
375
+ taxonomy_ids_to_touch = taxons_to_touch.map(&:taxonomy_id).uniq
376
+ Spree::Taxonomy.where(id: taxonomy_ids_to_touch).order(:id).each do |taxonomy|
377
+ taxonomy.touch(time:)
375
378
  end
376
379
  end
377
380
 
@@ -41,6 +41,7 @@ module Spree
41
41
 
42
42
  validate :eligible_exchange_variant
43
43
  validate :belongs_to_same_customer_order
44
+ validate :belongs_to_return_authorization_order, if: -> { inventory_unit_id_changed? || return_authorization_id_changed? }
44
45
  validate :validate_acceptance_status_for_reimbursement
45
46
  validate :validate_no_other_completed_return_items
46
47
 
@@ -225,6 +226,14 @@ module Spree
225
226
  end
226
227
  end
227
228
 
229
+ def belongs_to_return_authorization_order
230
+ return unless return_authorization && inventory_unit
231
+
232
+ if return_authorization.order_id != inventory_unit.order_id
233
+ errors.add(:base, I18n.t("spree.return_items_cannot_be_associated_with_multiple_orders"))
234
+ end
235
+ end
236
+
228
237
  def eligible_exchange_variant
229
238
  return unless exchange_variant && exchange_variant_id_changed?
230
239
  unless eligible_exchange_variants.include?(exchange_variant)
@@ -141,8 +141,11 @@ module Spree
141
141
  private
142
142
 
143
143
  def touch_ancestors_and_taxonomy
144
- # Touches all ancestors at once to avoid recursive taxonomy touch, and reduce queries.
145
- self.class.default_scoped.where(id: ancestors.pluck(:id)).update_all(updated_at: Time.current)
144
+ # Touches ancestors directly rather than through #touch to avoid a recursive taxonomy touch.
145
+ time = Time.current
146
+ self.class.default_scoped.where(id: ancestors.pluck(:id)).order(:id).each do |ancestor|
147
+ ancestor.update_column(:updated_at, time)
148
+ end
146
149
  # Have taxonomy touch happen in #touch_ancestors_and_taxonomy rather than association option in order for imports to override.
147
150
  taxonomy.try!(:touch)
148
151
  end
@@ -25,6 +25,6 @@ module Spree
25
25
  all
26
26
  }
27
27
 
28
- default_scope -> { order([default: :desc, updated_at: :desc]) }
28
+ default_scope -> { order([{ default: :desc, updated_at: :desc }]) }
29
29
  end
30
30
  end
@@ -25,6 +25,7 @@ module Spree
25
25
  def run
26
26
  # Early return if there is no VAT rates in the current store.
27
27
  return if !variant.tax_category || variant_vat_rates.empty?
28
+ return if variant.default_price&.amount.nil?
28
29
 
29
30
  country_isos_requiring_price.each do |country_iso|
30
31
  # Don't re-create the default price
@@ -36,7 +36,6 @@ class AddAmountRemainingToStoreCreditEvents < ActiveRecord::Migration[5.0]
36
36
  # These actions do not change the amount_remaining so the previous
37
37
  # amount available is used (either the credit's amount or the
38
38
  # amount_remaining coming from the event right before this one).
39
- credit_amount
40
39
  when StoreCredit::AUTHORIZE_ACTION,
41
40
  StoreCredit::INVALIDATE_ACTION
42
41
  # These actions remove the amount from the available credit amount.
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Spree
4
- VERSION = "4.6.3"
4
+ VERSION = "4.6.4"
5
5
 
6
6
  def self.solidus_version = VERSION
7
7
 
@@ -2,7 +2,15 @@
2
2
 
3
3
  FactoryBot.define do
4
4
  factory :return_item, class: 'Spree::ReturnItem' do
5
- association(:inventory_unit, factory: :inventory_unit, state: :shipped)
5
+ inventory_unit do
6
+ # When a return authorization is given, the inventory unit must belong
7
+ # to the same order.
8
+ if __override_names__.include?(:return_authorization) && return_authorization&.order
9
+ association(:inventory_unit, state: :shipped, order: return_authorization.order)
10
+ else
11
+ association(:inventory_unit, state: :shipped)
12
+ end
13
+ end
6
14
  association(:return_reason, factory: :return_reason)
7
15
  return_authorization do |_return_item|
8
16
  build(:return_authorization, order: inventory_unit.order)
@@ -8,11 +8,11 @@ FactoryBot.define do
8
8
  action { Spree::StoreCredit::AUTHORIZE_ACTION }
9
9
 
10
10
  factory :store_credit_auth_event, class: 'Spree::StoreCreditEvent' do
11
- action { Spree::StoreCredit::AUTHORIZE_ACTION }
11
+ action { Spree::StoreCredit::AUTHORIZE_ACTION }
12
12
  end
13
13
 
14
14
  factory :store_credit_capture_event do
15
- action { Spree::StoreCredit::CAPTURE_ACTION }
15
+ action { Spree::StoreCredit::CAPTURE_ACTION }
16
16
  end
17
17
 
18
18
  factory :store_credit_adjustment_event do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solidus_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.6.3
4
+ version: 4.6.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Solidus Team