spree_core 5.2.0.rc2 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/app/helpers/spree/integrations_helper.rb +1 -1
  3. data/app/jobs/spree/images/save_from_url_job.rb +14 -3
  4. data/app/models/concerns/spree/calculated_adjustments.rb +1 -1
  5. data/app/models/concerns/spree/user_methods.rb +1 -1
  6. data/app/models/spree/address.rb +1 -1
  7. data/app/models/spree/adjustable/adjustments_updater.rb +1 -1
  8. data/app/models/spree/asset.rb +2 -2
  9. data/app/models/spree/calculator.rb +1 -1
  10. data/app/models/spree/data_feed.rb +1 -1
  11. data/app/models/spree/export.rb +1 -1
  12. data/app/models/spree/gateway/bogus.rb +1 -1
  13. data/app/models/spree/import.rb +1 -1
  14. data/app/models/spree/import_row.rb +1 -0
  15. data/app/models/spree/import_schemas/products.rb +1 -1
  16. data/app/models/spree/metafield_definition.rb +3 -3
  17. data/app/models/spree/order/payments.rb +2 -0
  18. data/app/models/spree/order.rb +1 -0
  19. data/app/models/spree/payment/processing.rb +13 -0
  20. data/app/models/spree/payment.rb +20 -0
  21. data/app/models/spree/payment_method.rb +1 -1
  22. data/app/models/spree/post.rb +2 -2
  23. data/app/models/spree/post_category.rb +10 -2
  24. data/app/models/spree/product.rb +37 -3
  25. data/app/models/spree/shipping_rate.rb +7 -3
  26. data/app/models/spree/stock/coordinator.rb +1 -1
  27. data/app/models/spree/store.rb +2 -2
  28. data/app/models/spree/taxon.rb +1 -0
  29. data/app/models/spree/theme.rb +4 -4
  30. data/app/presenters/spree/csv/product_variant_presenter.rb +3 -3
  31. data/app/services/spree/compare_line_items.rb +1 -1
  32. data/app/services/spree/imports/row_processors/product_variant.rb +24 -1
  33. data/app/views/spree/shared/_base_mailer_stylesheets.html.erb +5 -0
  34. data/config/locales/en.yml +4 -0
  35. data/lib/generators/spree/cursor_rules/templates/spree_rules.mdc +1 -1
  36. data/lib/generators/spree/install/templates/config/initializers/spree.rb +31 -24
  37. data/lib/generators/spree/model/model_generator.rb +21 -0
  38. data/lib/generators/spree/model/templates/model.rb.tt +22 -0
  39. data/lib/generators/spree/model_decorator/model_decorator_generator.rb +37 -0
  40. data/lib/generators/spree/model_decorator/templates/model_decorator.rb.tt +12 -0
  41. data/lib/spree/analytics.rb +2 -2
  42. data/lib/spree/core/configuration.rb +1 -0
  43. data/lib/spree/core/controller_helpers/order.rb +10 -1
  44. data/lib/spree/core/engine.rb +10 -4
  45. data/lib/spree/core/importer/order.rb +2 -0
  46. data/lib/spree/core/importer/product.rb +2 -0
  47. data/lib/spree/core/partials.rb +42 -0
  48. data/lib/spree/core/token_generator.rb +1 -0
  49. data/lib/spree/core/version.rb +1 -1
  50. data/lib/spree/core.rb +191 -0
  51. data/lib/spree/testing_support/factories/calculator_factory.rb +2 -2
  52. data/lib/spree/testing_support/factories/order_factory.rb +7 -4
  53. metadata +10 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dab40885bc7e0251d44dd6a304b6481ecfd0769bb010ac31d52934545e2c6757
4
- data.tar.gz: 4997a5779b19f924e737192f1b0539cc84da5ae357110af959ebf0720cfd079f
3
+ metadata.gz: ae177c6a311a310cbcb6d6faf5b879afc52177f9f6bf4c7063edb5ece85fc755
4
+ data.tar.gz: 54794ac79f785c9965c7a1f69fe0c88470fdf751cb789cab9db047b6d9ddbaa4
5
5
  SHA512:
6
- metadata.gz: c54c706398a2f808628857c04ff03fad05107f9649acd18ff5ec879e273d93575b05e009a2a1915d7109f7d62b38582d6c314d536b4448b942872f092528950f
7
- data.tar.gz: 50bdfa531705e422848a0207caf2dc52c36bae0464cc9a867df66b4b8723b869a3eeb33cc610ff875d7b5efecbe3bc2fc33f3978833a585a33ca138be596052d
6
+ metadata.gz: a0f404ec813d9fc4eaabcab6cac7a461aae2671d43a55c5b59b3e53c10fbb442acf6fa01171690999f576f93e90ab77a26f767881f77dbe6f14dd73ec5619689
7
+ data.tar.gz: d4bacd845e8c842ab4ee8e394feb1006a4289c85ca7569e017eee6053fe29492dfc30466e413793b1af07b00a2f2575487d8746cf9a9ecdf959292b4cc0e6763
@@ -9,7 +9,7 @@ module Spree
9
9
  end
10
10
 
11
11
  def grouped_available_store_integrations
12
- Rails.application.config.spree.integrations.group_by(&:integration_group).sort_by { |group, _| group }
12
+ Spree.integrations.group_by(&:integration_group).sort_by { |group, _| group }
13
13
  end
14
14
  end
15
15
  end
@@ -1,10 +1,11 @@
1
1
  require 'open-uri'
2
+ require 'openssl'
2
3
 
3
4
  module Spree
4
5
  module Images
5
6
  class SaveFromUrlJob < ::Spree::BaseJob
6
7
  queue_as Spree.queues.images
7
- retry_on ActiveRecord::RecordInvalid, OpenURI::HTTPError, wait: :polynomially_longer, attempts: 2
8
+ retry_on ActiveRecord::RecordInvalid, OpenURI::HTTPError, wait: :polynomially_longer, attempts: Spree::Config.images_save_from_url_job_attempts.to_i
8
9
  discard_on URI::InvalidURIError
9
10
 
10
11
  def perform(viewable_id, viewable_type, external_url, external_id = nil, position = nil)
@@ -12,7 +13,7 @@ module Spree
12
13
 
13
14
  Spree::Image.ensure_metafield_definition_exists!(Spree::Image::EXTERNAL_URL_METAFIELD_KEY)
14
15
 
15
- external_url = external_url.downcase.strip
16
+ external_url = external_url.strip
16
17
  external_id = external_id.to_s.downcase.strip if external_id.present?
17
18
 
18
19
  image = find_or_initialize_image(viewable, external_url, external_id)
@@ -33,7 +34,17 @@ module Spree
33
34
  raise URI::InvalidURIError, "Invalid URL scheme: #{uri.scheme}. Only http and https are allowed."
34
35
  end
35
36
 
36
- file = uri.open
37
+ file = uri.open(
38
+ 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
39
+ 'Accept' => 'image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8',
40
+ 'Accept-Language' => 'en-US,en;q=0.9',
41
+ 'Accept-Encoding' => 'gzip, deflate, br',
42
+ 'Cache-Control' => 'no-cache',
43
+ 'Pragma' => 'no-cache',
44
+ read_timeout: 60,
45
+ ssl_verify_mode: OpenSSL::SSL::VERIFY_PEER,
46
+ redirect: true
47
+ )
37
48
  filename = File.basename(uri.path)
38
49
 
39
50
  image.attachment.attach(io: file, filename: filename)
@@ -30,7 +30,7 @@ module Spree
30
30
  end
31
31
 
32
32
  def self.spree_calculators
33
- Rails.application.config.spree.calculators
33
+ Spree.calculators
34
34
  end
35
35
  end
36
36
  end
@@ -160,7 +160,7 @@ module Spree
160
160
  private
161
161
 
162
162
  def check_completed_orders
163
- raise Spree::Core::DestroyWithOrdersError if !has_spree_role?(Spree::Role::ADMIN_ROLE) && orders.complete.present?
163
+ raise Spree::Core::DestroyWithOrdersError if !spree_admin? && orders.complete.present?
164
164
  end
165
165
 
166
166
  def clone_billing_address
@@ -76,7 +76,7 @@ module Spree
76
76
  allow_nil: true }
77
77
 
78
78
  def address_validators
79
- Rails.application.config.spree.validators.addresses.each do |validator|
79
+ Spree.validators.addresses.each do |validator|
80
80
  validates_with validator
81
81
  end
82
82
  end
@@ -55,7 +55,7 @@ module Spree
55
55
  end
56
56
 
57
57
  def adjusters
58
- Rails.application.config.spree.adjusters
58
+ Spree.adjusters
59
59
  end
60
60
 
61
61
  def tax_adjuster
@@ -22,7 +22,7 @@ module Spree
22
22
  scope :with_session_uploaded_assets_uuid, lambda { |uuid|
23
23
  where(session_id: uuid)
24
24
  }
25
- scope :with_external_url, ->(url) { url.present? ? with_metafield_key_value(EXTERNAL_URL_METAFIELD_KEY, url.downcase.strip) : none }
25
+ scope :with_external_url, ->(url) { url.present? ? with_metafield_key_value(EXTERNAL_URL_METAFIELD_KEY, url.strip) : none }
26
26
 
27
27
  def product
28
28
  @product ||= viewable_type == 'Spree::Variant' ? viewable&.product : nil
@@ -33,7 +33,7 @@ module Spree
33
33
  end
34
34
 
35
35
  def external_url=(url)
36
- set_metafield(EXTERNAL_URL_METAFIELD_KEY, url.downcase.strip)
36
+ set_metafield(EXTERNAL_URL_METAFIELD_KEY, url.strip)
37
37
  end
38
38
 
39
39
  def skip_import?
@@ -26,7 +26,7 @@ module Spree
26
26
 
27
27
  # Returns all calculators applicable for kind of work
28
28
  def self.calculators
29
- Rails.application.config.spree.calculators
29
+ Spree.calculators
30
30
  end
31
31
 
32
32
  def to_s
@@ -33,7 +33,7 @@ module Spree
33
33
  end
34
34
 
35
35
  def available_types
36
- Rails.application.config.spree.data_feed_types
36
+ Spree.data_feed_types
37
37
  end
38
38
  end
39
39
  end
@@ -175,7 +175,7 @@ module Spree
175
175
 
176
176
  class << self
177
177
  def available_types
178
- Rails.application.config.spree.export_types
178
+ Spree.export_types
179
179
  end
180
180
 
181
181
  def available_models
@@ -60,7 +60,7 @@ module Spree
60
60
  end
61
61
 
62
62
  def void(_response_code, _credit_card, _options = {})
63
- ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, test: true, authorization: '12345')
63
+ ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, test: true, authorization: 'void-12345')
64
64
  end
65
65
 
66
66
  def cancel(_response_code, _payment = nil)
@@ -224,7 +224,7 @@ module Spree
224
224
  # Returns the available types for the import
225
225
  # @return [Array<Class>]
226
226
  def available_types
227
- Rails.application.config.spree.import_types
227
+ Spree.import_types
228
228
  end
229
229
 
230
230
  # Returns the available models for the import
@@ -76,6 +76,7 @@ module Spree
76
76
  self.item = import.row_processor_class.new(self).process!
77
77
  complete!
78
78
  rescue StandardError => e
79
+ Rails.error.report(e, handled: true, context: { import_row_id: id }, source: 'spree.core')
79
80
  self.validation_errors = e.message
80
81
  fail!
81
82
  end
@@ -26,7 +26,7 @@ module Spree
26
26
  { name: 'inventory_count', label: 'Inventory Count' },
27
27
  { name: 'inventory_backorderable', label: 'Inventory Backorderable' },
28
28
  { name: 'tax_category', label: 'Tax Category' },
29
- { name: 'digital', label: 'Digital' },
29
+ { name: 'shipping_category', label: 'Shipping Category' },
30
30
  { name: 'image1_src', label: 'Image 1 URL' },
31
31
  { name: 'image2_src', label: 'Image 2 URL' },
32
32
  { name: 'image3_src', label: 'Image 3 URL' },
@@ -61,13 +61,13 @@ module Spree
61
61
  # Returns the available types
62
62
  # @return [Array<Class>]
63
63
  def self.available_types
64
- Rails.application.config.spree.metafield_types
64
+ Spree.metafields.types
65
65
  end
66
66
 
67
67
  # Returns the available resources
68
68
  # @return [Array<Class>]
69
69
  def self.available_resources
70
- Rails.application.config.spree.metafield_enabled_resources
70
+ Spree.metafields.enabled_resources
71
71
  end
72
72
 
73
73
  private
@@ -81,7 +81,7 @@ module Spree
81
81
  end
82
82
 
83
83
  def set_default_type
84
- self.metafield_type ||= Rails.application.config.spree.metafield_types.first.to_s
84
+ self.metafield_type ||= Spree.metafields.types.first.to_s
85
85
  end
86
86
 
87
87
  def set_name_from_key
@@ -44,6 +44,8 @@ module Spree
44
44
  def process_payments_with(method)
45
45
  # Don't run if there is nothing to pay.
46
46
  return if payment_total >= total
47
+ # Don't run if there are authorized payments
48
+ return if pending_payments.any? && unprocessed_payments.empty?
47
49
  # Prevent orders from transitioning to complete without a successfully processed payment.
48
50
  raise Core::GatewayError, Spree.t(:no_payment_found) if unprocessed_payments.empty?
49
51
 
@@ -910,6 +910,7 @@ module Spree
910
910
  payments.completed.store_credits.each(&:void!)
911
911
  else
912
912
  payments.completed.each(&:cancel!)
913
+ payments.incomplete.not_store_credits.each(&:void_transaction!)
913
914
  payments.store_credits.pending.each(&:void!)
914
915
  end
915
916
 
@@ -26,6 +26,19 @@ module Spree
26
26
  handle_payment_preconditions { process_purchase }
27
27
  end
28
28
 
29
+ # Confirms a payment by completing it or pending it depending on the payment method's auto_capture setting
30
+ # Useful for payments that are authorized/captured with SDK/Drop-in elements
31
+ def confirm!
32
+ started_processing! if checkout?
33
+
34
+ if payment_method&.auto_capture? && can_complete?
35
+ complete!
36
+ capture_events.create!(amount: amount)
37
+ elsif can_pend?
38
+ pend!
39
+ end
40
+ end
41
+
29
42
  # Takes the amount in cents to capture.
30
43
  # Can be used to capture partial amounts of a payment, and will create
31
44
  # a new pending payment record for the remaining amount to capture later.
@@ -255,6 +255,26 @@ module Spree
255
255
  payment_method&.source_required?
256
256
  end
257
257
 
258
+ def add_gateway_processing_error(error_message)
259
+ if has_metafield?('gateway.processing_errors')
260
+ errors = JSON.parse(get_metafield('gateway.processing_errors').value)
261
+ errors << { message: error_message }
262
+
263
+ set_metafield('gateway.processing_errors', errors.to_json)
264
+ else
265
+ set_metafield('gateway.processing_errors', [{ message: error_message }].to_json)
266
+ end
267
+ end
268
+
269
+ def gateway_processing_error_messages
270
+ @gateway_processing_error_messages ||= begin
271
+ errors = JSON.parse(get_metafield('gateway.processing_errors')&.value || '[]')
272
+ errors.map { |error| error['message'] }
273
+ rescue JSON::ParserError
274
+ []
275
+ end
276
+ end
277
+
258
278
  private
259
279
 
260
280
  def set_amount
@@ -29,7 +29,7 @@ module Spree
29
29
  has_many :gateway_customers, class_name: 'Spree::GatewayCustomer', dependent: :destroy
30
30
 
31
31
  def self.providers
32
- Rails.application.config.spree.payment_methods
32
+ Spree.payment_methods
33
33
  end
34
34
 
35
35
  def provider_class
@@ -39,8 +39,8 @@ module Spree
39
39
  # Associations
40
40
  #
41
41
  belongs_to :author, class_name: Spree.admin_user_class.to_s, optional: true
42
- belongs_to :store, class_name: 'Spree::Store'
43
- belongs_to :post_category, class_name: 'Spree::PostCategory', optional: true
42
+ belongs_to :store, class_name: 'Spree::Store', inverse_of: :posts
43
+ belongs_to :post_category, class_name: 'Spree::PostCategory', optional: true, touch: true, inverse_of: :posts
44
44
  alias category post_category
45
45
 
46
46
  #
@@ -9,8 +9,8 @@ module Spree
9
9
  #
10
10
  # Associations
11
11
  #
12
- belongs_to :store, class_name: 'Spree::Store'
13
- has_many :posts, class_name: 'Spree::Post'
12
+ belongs_to :store, class_name: 'Spree::Store', inverse_of: :post_categories
13
+ has_many :posts, class_name: 'Spree::Post', dependent: :nullify, inverse_of: :post_category
14
14
 
15
15
  #
16
16
  # Validations
@@ -18,8 +18,16 @@ module Spree
18
18
  validates :title, :store, presence: true
19
19
  validates :slug, presence: true, uniqueness: { scope: :store_id }
20
20
 
21
+ #
22
+ # ActionText
23
+ #
21
24
  has_rich_text :description
22
25
 
26
+ #
27
+ # Ransack
28
+ #
29
+ self.whitelisted_ransackable_attributes = %w[title slug]
30
+
23
31
  def should_generate_new_friendly_id?
24
32
  slug.blank? || title_changed?
25
33
  end
@@ -255,8 +255,6 @@ module Spree
255
255
  delegate :display_amount, :display_price, :has_default_price?, :track_inventory?,
256
256
  :display_compare_at_price, :images, to: :default_variant
257
257
 
258
- delegate :name, to: :brand, prefix: true, allow_nil: true
259
-
260
258
  alias master_images images
261
259
 
262
260
  state_machine :status, initial: :draft do
@@ -550,7 +548,22 @@ module Spree
550
548
  super || variants_including_master.with_deleted.find_by(is_master: true)
551
549
  end
552
550
 
551
+ # Returns the brand for the product
552
+ # If a brand association is defined (e.g., belongs_to :brand), it will be used
553
+ # Otherwise, falls back to brand_taxon for compatibility
554
+ # @return [Spree::Brand, Spree::Taxon]
553
555
  def brand
556
+ if self.class.reflect_on_association(:brand)
557
+ super
558
+ else
559
+ Spree::Deprecation.warn('Spree::Product#brand is deprecated and will be removed in Spree 6. Please use Spree::Product#brand_taxon instead.')
560
+ brand_taxon
561
+ end
562
+ end
563
+
564
+ # Returns the brand taxon for the product
565
+ # @return [Spree::Taxon]
566
+ def brand_taxon
554
567
  @brand ||= if Spree.use_translations?
555
568
  taxons.joins(:taxonomy).
556
569
  join_translation_table(Taxonomy).
@@ -564,7 +577,28 @@ module Spree
564
577
  end
565
578
  end
566
579
 
580
+ # Returns the brand name for the product
581
+ # @return [String]
582
+ def brand_name
583
+ brand&.name
584
+ end
585
+
586
+ # Returns the category for the product
587
+ # If a category association is defined (e.g., belongs_to :category), it will be used
588
+ # Otherwise, falls back to category_taxon for compatibility
589
+ # @return [Spree::Category, Spree::Taxon]
567
590
  def category
591
+ if self.class.reflect_on_association(:category)
592
+ super
593
+ else
594
+ Spree::Deprecation.warn('Spree::Product#category is deprecated and will be removed in Spree 6. Please use Spree::Product#category_taxon instead.')
595
+ category_taxon
596
+ end
597
+ end
598
+
599
+ # Returns the category taxon for the product
600
+ # @return [Spree::Taxon]
601
+ def category_taxon
568
602
  @category ||= if Spree.use_translations?
569
603
  taxons.joins(:taxonomy).
570
604
  join_translation_table(Taxonomy).
@@ -580,7 +614,7 @@ module Spree
580
614
  end
581
615
 
582
616
  def main_taxon
583
- category || taxons.first
617
+ category_taxon || taxons.first
584
618
  end
585
619
 
586
620
  def taxons_for_store(store)
@@ -7,9 +7,9 @@ module Spree
7
7
 
8
8
  money_methods :base_price, :final_price, :tax_amount
9
9
 
10
- delegate :order, :currency, :free?, :with_free_shipping_promotion?, to: :shipment
11
- delegate :name, to: :shipping_method
12
- delegate :code, to: :shipping_method, prefix: true
10
+ delegate :order, :currency, :with_free_shipping_promotion?, to: :shipment
11
+ delegate :name, to: :shipping_method
12
+ delegate :code, to: :shipping_method, prefix: true
13
13
 
14
14
  def display_price
15
15
  price = display_base_price.to_s
@@ -27,6 +27,10 @@ module Spree
27
27
  alias display_cost display_price
28
28
  alias_attribute :base_price, :cost
29
29
 
30
+ def free?
31
+ final_price.zero?
32
+ end
33
+
30
34
  def tax_amount
31
35
  @tax_amount ||= tax_rate&.calculator&.compute_shipping_rate(self) || BigDecimal(0)
32
36
  end
@@ -60,7 +60,7 @@ module Spree
60
60
 
61
61
  def splitters(_stock_location)
62
62
  # extension point to return custom splitters for a location
63
- Rails.application.config.spree.stock_splitters
63
+ Spree.stock_splitters
64
64
  end
65
65
  end
66
66
  end
@@ -106,8 +106,8 @@ module Spree
106
106
  has_many :custom_domains, class_name: 'Spree::CustomDomain', dependent: :destroy
107
107
  has_one :default_custom_domain, -> { where(default: true) }, class_name: 'Spree::CustomDomain'
108
108
 
109
- has_many :posts, class_name: 'Spree::Post'
110
- has_many :post_categories, class_name: 'Spree::PostCategory'
109
+ has_many :posts, class_name: 'Spree::Post', dependent: :destroy, inverse_of: :store
110
+ has_many :post_categories, class_name: 'Spree::PostCategory', dependent: :destroy, inverse_of: :store
111
111
 
112
112
  has_many :integrations, class_name: 'Spree::Integration'
113
113
 
@@ -324,6 +324,7 @@ module Spree
324
324
  # indicate which filters should be used for a taxon
325
325
  # this method should be customized to your own site
326
326
  def applicable_filters
327
+ Spree::Deprecation.warn('applicable_filters is deprecated and will be removed in Spree 6.0')
327
328
  fs = []
328
329
  # fs << ProductFilters.taxons_below(self)
329
330
  ## unless it's a root taxon? left open for demo purposes
@@ -56,7 +56,7 @@ module Spree
56
56
  #
57
57
  # @return [Array<Spree::Theme>]
58
58
  def self.available_themes
59
- @available_themes ||= Rails.application.config.spree.themes.sort_by(&:display_name)
59
+ @available_themes ||= Spree.page_builder.themes.sort_by(&:display_name)
60
60
  end
61
61
 
62
62
  def self.metadata
@@ -98,7 +98,7 @@ module Spree
98
98
  end
99
99
 
100
100
  def create_default_pages
101
- Rails.application.config.spree.pages.map(&:to_s).map(&:constantize).each do |page_class|
101
+ Spree.page_builder.pages.map(&:to_s).map(&:constantize).each do |page_class|
102
102
  next if page_class == Spree::Pages::Custom
103
103
 
104
104
  page_class.where(pageable: self).first_or_create!
@@ -160,7 +160,7 @@ module Spree
160
160
  # @return [Array<Class>]
161
161
  def available_layout_sections
162
162
  [
163
- *Rails.application.config.spree.theme_layout_sections,
163
+ *Spree.page_builder.theme_layout_sections,
164
164
  *custom_layout_sections
165
165
  ]
166
166
  end
@@ -181,7 +181,7 @@ module Spree
181
181
  return @available_page_sections if @available_page_sections
182
182
 
183
183
  @available_page_sections ||= [
184
- *Rails.application.config.spree.page_sections.find_all do |section_class|
184
+ *Spree.page_builder.page_sections.find_all do |section_class|
185
185
  section_class.role == 'content'
186
186
  end,
187
187
  *custom_page_sections
@@ -32,7 +32,7 @@ module Spree
32
32
  'inventory_count',
33
33
  'inventory_backorderable',
34
34
  'tax_category',
35
- 'digital',
35
+ 'shipping_category',
36
36
  'image1_src',
37
37
  'image2_src',
38
38
  'image3_src',
@@ -66,7 +66,7 @@ module Spree
66
66
  # For the primary variant row (when the index is zero), product-level details such as name,
67
67
  # slug, status, vendor and brand names, description, meta tags, and tag/label lists are included.
68
68
  # In all cases, variant-specific attributes (e.g., id, SKU, pricing, dimensions, weight,
69
- # availability dates, inventory count, digital flag, tax category, image URLs via original_url,
69
+ # availability dates, inventory count, shipping category, tax category, image URLs via original_url,
70
70
  # and the first three option types and corresponding option values) are appended.
71
71
  # Additionally, when the index is zero, associated taxons and properties are added.
72
72
  #
@@ -103,7 +103,7 @@ module Spree
103
103
  total_on_hand == BigDecimal::INFINITY ? '∞' : total_on_hand,
104
104
  variant.backorderable?,
105
105
  variant.tax_category&.name,
106
- variant.digital?,
106
+ product.shipping_category&.name,
107
107
  spree_image_url(variant.images[0], image_url_options),
108
108
  spree_image_url(variant.images[1], image_url_options),
109
109
  spree_image_url(variant.images[2], image_url_options),
@@ -4,7 +4,7 @@ module Spree
4
4
  prepend Spree::ServiceModule::Base
5
5
 
6
6
  def call(order:, line_item:, options: {}, comparison_hooks: nil)
7
- comparison_hooks ||= Rails.application.config.spree.line_item_comparison_hooks
7
+ comparison_hooks ||= Spree.line_item_comparison_hooks
8
8
 
9
9
  legacy_part = comparison_hooks.all? do |hook|
10
10
  order.send(hook, line_item, options)
@@ -33,6 +33,12 @@ module Spree
33
33
  variant.depth = attributes['depth'] if attributes['depth'].present?
34
34
  variant.track_inventory = attributes['track_inventory'] if attributes['track_inventory'].present?
35
35
  variant.option_value_variants = prepare_option_value_variants
36
+
37
+ if attributes['tax_category'].present?
38
+ tax_category = prepare_tax_category
39
+ variant.tax_category = tax_category if tax_category.present?
40
+ end
41
+
36
42
  variant.save!
37
43
 
38
44
  if attributes['price'].present?
@@ -94,10 +100,27 @@ module Spree
94
100
  product.status = to_spree_status(attributes['status']) if attributes['status'].present?
95
101
  product.tag_list = attributes['tags'] if attributes['tags'].present?
96
102
 
97
- product.taxons = prepare_taxons if options.empty?
103
+ if options.empty?
104
+ if attributes['shipping_category'].present?
105
+ shipping_category = prepare_shipping_category
106
+ product.shipping_category = shipping_category if shipping_category.present?
107
+ end
108
+ product.taxons = prepare_taxons
109
+ end
110
+
98
111
  product
99
112
  end
100
113
 
114
+ def prepare_shipping_category
115
+ shipping_category_name = attributes['shipping_category'].strip
116
+ Spree::ShippingCategory.find_by(name: shipping_category_name)
117
+ end
118
+
119
+ def prepare_tax_category
120
+ tax_category_name = attributes['tax_category'].strip
121
+ Spree::TaxCategory.find_by(name: tax_category_name)
122
+ end
123
+
101
124
  def prepare_taxons
102
125
  taxon_pretty_names = [
103
126
  attributes['category1'],
@@ -253,6 +253,11 @@
253
253
 
254
254
  .purchase_image {
255
255
  padding: 5px;
256
+ width: 100px;
257
+
258
+ img {
259
+ width: 100px;
260
+ }
256
261
  }
257
262
 
258
263
  .purchase_item p {
@@ -105,6 +105,8 @@ en:
105
105
  phone: Shipping address phone
106
106
  state: Shipping address state
107
107
  zipcode: Shipping address zipcode
108
+ spree/page_link:
109
+ open_in_new_tab: Open in new tab
108
110
  spree/payment:
109
111
  amount: Amount
110
112
  number: Number
@@ -200,6 +202,7 @@ en:
200
202
  spree/taxonomy:
201
203
  name: Name
202
204
  spree/user:
205
+ avatar: Avatar
203
206
  email: Email
204
207
  password: Password
205
208
  password_confirmation: Password Confirmation
@@ -1622,6 +1625,7 @@ en:
1622
1625
  payment_updated: Payment Updated
1623
1626
  payments: Payments
1624
1627
  payments_count: Payments count
1628
+ payments_gateway_processing_errors: "%{payment_method_name} processing errors"
1625
1629
  pending: Pending
1626
1630
  pending_sale: Pending Sale
1627
1631
  percent: Percent
@@ -255,7 +255,7 @@ bin/rails g spree:storefront:theme MyTheme
255
255
 
256
256
  ```ruby
257
257
  # Register theme in config/initializers/spree.rb
258
- Rails.application.config.spree.themes << Spree::Themes::MyTheme
258
+ Spree.page_builder.themes << Spree::Themes::MyTheme
259
259
  ```
260
260
 
261
261
  #### View Overrides