spree_core 5.4.0.beta → 5.4.0.beta2
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 +4 -4
- data/app/finders/spree/products/find.rb +1 -28
- data/app/helpers/spree/base_helper.rb +1 -54
- data/app/mailers/spree/base_mailer.rb +4 -3
- data/app/models/concerns/spree/adjustment_source.rb +0 -8
- data/app/models/concerns/spree/admin_user_methods.rb +0 -2
- data/app/models/concerns/spree/image_methods.rb +4 -0
- data/app/models/concerns/spree/metadata.rb +10 -0
- data/app/models/concerns/spree/product_scopes.rb +2 -47
- data/app/models/concerns/spree/stores/markets.rb +7 -7
- data/app/models/concerns/spree/vat_price_calculation.rb +2 -2
- data/app/models/spree/ability.rb +5 -5
- data/app/models/spree/address.rb +3 -2
- data/app/models/spree/adjustable/promotion_accumulator.rb +1 -1
- data/app/models/spree/adjustment.rb +1 -20
- data/app/models/spree/api_key.rb +57 -2
- data/app/models/spree/country.rb +7 -3
- data/app/models/spree/credit_card.rb +0 -27
- data/app/models/spree/current.rb +38 -2
- data/app/models/spree/exports/products.rb +0 -6
- data/app/models/spree/gateway/bogus.rb +9 -9
- data/app/models/spree/gateway.rb +0 -3
- data/app/models/spree/gift_card_batch.rb +4 -0
- data/app/models/spree/image/configuration/active_storage.rb +0 -2
- data/app/models/spree/image.rb +7 -31
- data/app/models/spree/log_entry.rb +8 -5
- data/app/models/spree/order/checkout.rb +0 -18
- data/app/models/spree/order.rb +20 -11
- data/app/models/spree/payment/gateway_options.rb +2 -2
- data/app/models/spree/payment/processing.rb +5 -5
- data/app/models/spree/payment.rb +1 -1
- data/app/models/spree/payment_connection_error.rb +3 -0
- data/app/models/spree/payment_method/check.rb +1 -1
- data/app/models/spree/payment_method/store_credit.rb +5 -5
- data/app/models/spree/payment_response.rb +70 -0
- data/app/models/spree/permission_sets/default_customer.rb +0 -5
- data/app/models/spree/permission_sets/product_display.rb +0 -2
- data/app/models/spree/permission_sets/product_management.rb +0 -2
- data/app/models/spree/product.rb +4 -72
- data/app/models/spree/promotion.rb +2 -14
- data/app/models/spree/promotion_handler/coupon.rb +3 -3
- data/app/models/spree/prototype.rb +0 -3
- data/app/models/spree/refund.rb +6 -2
- data/app/models/spree/shipment/emails.rb +1 -0
- data/app/models/spree/shipping_category.rb +3 -3
- data/app/models/spree/store.rb +10 -49
- data/app/models/spree/store_credit.rb +4 -0
- data/app/models/spree/tax_category.rb +1 -11
- data/app/models/spree/taxon.rb +0 -16
- data/app/models/spree/variant.rb +2 -40
- data/app/models/spree/zone.rb +1 -4
- data/app/services/spree/cart/add_item.rb +8 -4
- data/app/services/spree/cart/create.rb +13 -2
- data/app/services/spree/products/duplicator.rb +0 -12
- data/app/services/spree/products/prepare_nested_attributes.rb +0 -12
- data/config/locales/en.yml +3 -20
- data/db/migrate/20210914000000_spree_four_three.rb +0 -38
- data/db/migrate/20210915064329_add_metadata_to_spree_multiple_tables.rb +0 -1
- data/db/migrate/20260226000000_add_locale_to_spree_orders.rb +5 -0
- data/db/migrate/20260226100000_add_token_digest_to_spree_api_keys.rb +21 -0
- data/lib/generators/spree/cursor_rules/templates/spree_rules.mdc +1 -3
- data/lib/spree/core/configuration.rb +0 -3
- data/lib/spree/core/controller_helpers/strong_parameters.rb +1 -2
- data/lib/spree/core/dependencies.rb +2 -10
- data/lib/spree/core/engine.rb +0 -13
- data/lib/spree/core/pricing/resolver.rb +1 -9
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/core.rb +10 -25
- data/lib/spree/permitted_attributes.rb +2 -14
- data/lib/spree/testing_support/factories/order_factory.rb +1 -0
- data/lib/spree/testing_support/factories/payment_method_factory.rb +1 -6
- data/lib/spree/testing_support/factories/product_factory.rb +0 -7
- data/lib/spree/testing_support/factories/prototype_factory.rb +0 -2
- data/lib/tasks/core.rake +0 -265
- metadata +8 -101
- data/app/finders/spree/posts/find.rb +0 -137
- data/app/finders/spree/product_properties/find_available.rb +0 -20
- data/app/helpers/spree/mail_helper.rb +0 -27
- data/app/jobs/spree/api_key_touch_job.rb +0 -9
- data/app/mailers/spree/test_mailer.rb +0 -8
- data/app/models/action_text/video_embed.rb +0 -13
- data/app/models/concerns/spree/has_one_link.rb +0 -42
- data/app/models/concerns/spree/linkable.rb +0 -9
- data/app/models/concerns/spree/previewable.rb +0 -17
- data/app/models/spree/data_feed/google.rb +0 -15
- data/app/models/spree/data_feed.rb +0 -42
- data/app/models/spree/gateway/bogus_simple.rb +0 -24
- data/app/models/spree/post.rb +0 -108
- data/app/models/spree/post_category.rb +0 -46
- data/app/models/spree/product_property.rb +0 -51
- data/app/models/spree/property.rb +0 -86
- data/app/models/spree/property_prototype.rb +0 -9
- data/app/models/spree/store_favicon_image.rb +0 -20
- data/app/models/spree/store_logo.rb +0 -4
- data/app/models/spree/store_mailer_logo.rb +0 -7
- data/app/models/spree/taxon_image/configuration/active_storage.rb +0 -26
- data/app/models/spree/taxon_image.rb +0 -28
- data/app/presenters/spree/filters/properties_presenter.rb +0 -23
- data/app/presenters/spree/filters/property_presenter.rb +0 -42
- data/app/services/spree/data_feeds/google/optional_attributes.rb +0 -23
- data/app/services/spree/data_feeds/google/optional_sub_attributes.rb +0 -21
- data/app/services/spree/data_feeds/google/products_list.rb +0 -14
- data/app/services/spree/data_feeds/google/required_attributes.rb +0 -68
- data/app/services/spree/data_feeds/google/rss.rb +0 -109
- data/app/sorters/spree/posts/sort.rb +0 -40
- data/app/views/action_text/video_embeds/_thumbnail.html.erb +0 -1
- data/app/views/action_text/video_embeds/_video_embed.html.erb +0 -3
- data/app/views/layouts/action_text/contents/_content.html.erb +0 -3
- data/app/views/spree/test_mailer/test_email.html.erb +0 -40
- data/app/views/spree/test_mailer/test_email.text.erb +0 -4
- data/config/initializers/oembed.rb +0 -1
- data/db/migrate/20221229132350_create_spree_data_feed_settings.rb +0 -14
- data/db/migrate/20230109084253_create_product_property_translations.rb +0 -24
- data/db/migrate/20230109105943_create_property_translations.rb +0 -24
- data/db/migrate/20230415155958_rename_data_feed_settings_table.rb +0 -5
- data/db/migrate/20230415160828_rename_data_feed_table_columns.rb +0 -7
- data/db/migrate/20230415161226_add_indexes_to_data_feeds_table.rb +0 -5
- data/db/migrate/20230512094803_rename_data_feeds_column_provider_to_type.rb +0 -5
- data/db/migrate/20240914153106_add_display_on_to_spree_properties.rb +0 -5
- data/db/migrate/20240915144935_add_position_to_spree_properties.rb +0 -6
- data/db/migrate/20250121160028_create_spree_posts_and_spree_post_categories.rb +0 -33
- data/db/migrate/20250127083740_add_kind_to_spree_properties.rb +0 -5
- data/db/migrate/20250217171018_create_action_text_video_embeds.rb +0 -11
- data/db/migrate/20250305121657_remove_spree_posts_indices.rb +0 -7
- data/db/migrate/20250730154601_add_unique_index_on_spree_properties_name.rb +0 -24
- data/db/sample_data/posts.rb +0 -7
- data/lib/spree/core/controller_helpers/search.rb +0 -17
- data/lib/spree/core/product_filters.rb +0 -218
- data/lib/spree/core/query_filters/comparable.rb +0 -50
- data/lib/spree/core/query_filters/date.rb +0 -8
- data/lib/spree/core/query_filters/number.rb +0 -8
- data/lib/spree/core/query_filters/text.rb +0 -36
- data/lib/spree/core/query_filters.rb +0 -11
- data/lib/spree/core/search/base.rb +0 -144
- data/lib/spree/testing_support/factories/favicon_image_factory.rb +0 -9
- data/lib/spree/testing_support/factories/google_data_feed_factory.rb +0 -7
- data/lib/spree/testing_support/factories/post_category_factory.rb +0 -7
- data/lib/spree/testing_support/factories/post_factory.rb +0 -22
- data/lib/spree/testing_support/factories/product_property_factory.rb +0 -7
- data/lib/spree/testing_support/factories/property_factory.rb +0 -28
- data/lib/spree/testing_support/factories/taxon_image_factory.rb +0 -9
- data/lib/spree/testing_support/flash.rb +0 -25
- data/lib/spree/testing_support/flatpickr_capybara.rb +0 -124
- data/lib/tasks/exchanges.rake +0 -66
data/app/models/spree/product.rb
CHANGED
|
@@ -72,9 +72,6 @@ module Spree
|
|
|
72
72
|
|
|
73
73
|
has_many :product_option_types, -> { order(:position) }, dependent: :destroy, inverse_of: :product
|
|
74
74
|
has_many :option_types, through: :product_option_types
|
|
75
|
-
has_many :product_properties, dependent: :destroy, inverse_of: :product
|
|
76
|
-
has_many :properties, through: :product_properties
|
|
77
|
-
|
|
78
75
|
has_many :classifications, -> { order(created_at: :asc) }, dependent: :delete_all, inverse_of: :product
|
|
79
76
|
has_many :taxons, through: :classifications, before_remove: :remove_taxon
|
|
80
77
|
has_many :taxonomies, through: :taxons
|
|
@@ -215,9 +212,6 @@ module Spree
|
|
|
215
212
|
|
|
216
213
|
attr_accessor :option_values_hash
|
|
217
214
|
|
|
218
|
-
accepts_nested_attributes_for :product_properties, allow_destroy: true, reject_if: lambda { |pp|
|
|
219
|
-
pp[:property_id].blank? || (pp[:id].blank? && pp[:value].blank?)
|
|
220
|
-
}
|
|
221
215
|
accepts_nested_attributes_for(
|
|
222
216
|
:variants,
|
|
223
217
|
allow_destroy: true,
|
|
@@ -236,7 +230,7 @@ module Spree
|
|
|
236
230
|
|
|
237
231
|
self.whitelisted_ransackable_attributes = %w[description name slug discontinue_on status available_on created_at updated_at]
|
|
238
232
|
self.whitelisted_ransackable_associations = %w[taxons stores variants_including_master master variants tags labels
|
|
239
|
-
shipping_category classifications option_types
|
|
233
|
+
shipping_category classifications option_types]
|
|
240
234
|
self.whitelisted_ransackable_scopes = %w[not_discontinued search_by_name in_taxon price_between
|
|
241
235
|
multi_search in_stock_items out_of_stock_items with_option_value_ids
|
|
242
236
|
ascend_by_price descend_by_price]
|
|
@@ -417,7 +411,7 @@ module Spree
|
|
|
417
411
|
# Returns the short description for the product
|
|
418
412
|
# @return [String]
|
|
419
413
|
def storefront_description
|
|
420
|
-
|
|
414
|
+
description
|
|
421
415
|
end
|
|
422
416
|
|
|
423
417
|
# Returns tax category for Product
|
|
@@ -479,13 +473,6 @@ module Spree
|
|
|
479
473
|
Products::Duplicator.call(product: self)
|
|
480
474
|
end
|
|
481
475
|
|
|
482
|
-
# use deleted? rather than checking the attribute directly. this
|
|
483
|
-
# allows extensions to override deleted? if they want to provide
|
|
484
|
-
# their own definition.
|
|
485
|
-
def deleted?
|
|
486
|
-
!!deleted_at
|
|
487
|
-
end
|
|
488
|
-
|
|
489
476
|
# determine if product is available.
|
|
490
477
|
# deleted products and products with status different than active
|
|
491
478
|
# are not available
|
|
@@ -513,14 +500,6 @@ module Spree
|
|
|
513
500
|
variants_including_master.any?(&:backordered?)
|
|
514
501
|
end
|
|
515
502
|
|
|
516
|
-
# split variants list into hash which shows mapping of opt value onto matching variants
|
|
517
|
-
# eg categorise_variants_from_option(color) => {"red" -> [...], "blue" -> [...]}
|
|
518
|
-
def categorise_variants_from_option(opt_type)
|
|
519
|
-
return {} unless option_types.include?(opt_type)
|
|
520
|
-
|
|
521
|
-
variants.active.group_by { |v| v.option_values.detect { |o| o.option_type == opt_type } }
|
|
522
|
-
end
|
|
523
|
-
|
|
524
503
|
def self.like_any(fields, values)
|
|
525
504
|
conditions = fields.product(values).map do |(field, value)|
|
|
526
505
|
arel_table[field].matches("%#{value}%")
|
|
@@ -537,48 +516,6 @@ module Spree
|
|
|
537
516
|
variants.active(current_currency).joins(:option_value_variants)
|
|
538
517
|
end
|
|
539
518
|
|
|
540
|
-
def empty_option_values?
|
|
541
|
-
options.empty? || options.any? do |opt|
|
|
542
|
-
opt.option_type.option_values.empty?
|
|
543
|
-
end
|
|
544
|
-
end
|
|
545
|
-
|
|
546
|
-
def property(property_name)
|
|
547
|
-
if product_properties.loaded?
|
|
548
|
-
product_properties.detect { |property| property.property.name == property_name }.try(:value)
|
|
549
|
-
else
|
|
550
|
-
product_properties.joins(:property).find_by(spree_properties: { name: property_name }).try(:value)
|
|
551
|
-
end
|
|
552
|
-
end
|
|
553
|
-
|
|
554
|
-
def set_property(property_name, property_value, property_presentation = property_name)
|
|
555
|
-
property_name = property_name.to_s.parameterize
|
|
556
|
-
ApplicationRecord.transaction do
|
|
557
|
-
# Manual first_or_create to work around Mobility bug
|
|
558
|
-
property = if Property.where(name: property_name).exists?
|
|
559
|
-
existing_property = Property.where(name: property_name).first
|
|
560
|
-
existing_property.presentation ||= property_presentation
|
|
561
|
-
existing_property.save
|
|
562
|
-
existing_property
|
|
563
|
-
else
|
|
564
|
-
Property.create(name: property_name, presentation: property_presentation)
|
|
565
|
-
end
|
|
566
|
-
|
|
567
|
-
product_property = if ProductProperty.where(product: self, property: property).exists?
|
|
568
|
-
ProductProperty.where(product: self, property: property).first
|
|
569
|
-
else
|
|
570
|
-
ProductProperty.new(product: self, property: property)
|
|
571
|
-
end
|
|
572
|
-
|
|
573
|
-
product_property.value = property_value
|
|
574
|
-
product_property.save!
|
|
575
|
-
end
|
|
576
|
-
end
|
|
577
|
-
|
|
578
|
-
def remove_property(property_name)
|
|
579
|
-
product_properties.joins(:property).find_by(spree_properties: { name: property_name.parameterize })&.destroy
|
|
580
|
-
end
|
|
581
|
-
|
|
582
519
|
def total_on_hand
|
|
583
520
|
@total_on_hand ||= if any_variants_not_track_inventory?
|
|
584
521
|
BigDecimal::INFINITY
|
|
@@ -668,9 +605,7 @@ module Spree
|
|
|
668
605
|
def taxons_for_store(store)
|
|
669
606
|
return if classification_count.zero?
|
|
670
607
|
|
|
671
|
-
|
|
672
|
-
taxons.loaded? ? taxons.find_all { |taxon| taxon.taxonomy.store_id == store.id } : taxons.for_store(store)
|
|
673
|
-
end
|
|
608
|
+
taxons.loaded? ? taxons.find_all { |taxon| taxon.taxonomy.store_id == store.id } : taxons.for_store(store)
|
|
674
609
|
end
|
|
675
610
|
|
|
676
611
|
def any_variant_in_stock_or_backorderable?
|
|
@@ -702,7 +637,7 @@ module Spree
|
|
|
702
637
|
|
|
703
638
|
def to_csv(store = nil)
|
|
704
639
|
store ||= stores.default || stores.first
|
|
705
|
-
properties_for_csv = if Spree::Config[:product_properties_enabled]
|
|
640
|
+
properties_for_csv = if respond_to?(:product_properties) && Spree::Config.respond_to?(:product_properties_enabled) && Spree::Config[:product_properties_enabled]
|
|
706
641
|
Spree::Property.order(:position).flat_map do |property|
|
|
707
642
|
[
|
|
708
643
|
property.name,
|
|
@@ -746,9 +681,6 @@ module Spree
|
|
|
746
681
|
|
|
747
682
|
def add_associations_from_prototype
|
|
748
683
|
if prototype_id && prototype = Spree::Prototype.find_by(id: prototype_id)
|
|
749
|
-
prototype.properties.each do |property|
|
|
750
|
-
product_properties.create(property: property, value: 'Placeholder')
|
|
751
|
-
end
|
|
752
684
|
self.option_types = prototype.option_types
|
|
753
685
|
self.taxons = prototype.taxons
|
|
754
686
|
end
|
|
@@ -190,26 +190,14 @@ module Spree
|
|
|
190
190
|
!!eligible_rules(promotable, options)
|
|
191
191
|
end
|
|
192
192
|
|
|
193
|
-
# We cache the rules to avoid multiple database queries
|
|
194
|
-
# this is useful for orders with many line items
|
|
195
|
-
#
|
|
196
|
-
# @return [Array<Spree::PromotionRule>]
|
|
197
|
-
def cached_rules
|
|
198
|
-
Rails.cache.fetch("#{cache_key_with_version}/rules") do
|
|
199
|
-
rules.to_a
|
|
200
|
-
end
|
|
201
|
-
rescue TypeError # when using null_store in test environment
|
|
202
|
-
rules.to_a
|
|
203
|
-
end
|
|
204
|
-
|
|
205
193
|
# eligible_rules returns an array of promotion rules where eligible? is true for the promotable
|
|
206
194
|
# if there are no such rules, an empty array is returned
|
|
207
195
|
# if the rules make this promotable ineligible, then nil is returned (i.e. this promotable is not eligible)
|
|
208
196
|
def eligible_rules(promotable, options = {})
|
|
209
197
|
# Promotions without rules are eligible by default.
|
|
210
|
-
return [] if
|
|
198
|
+
return [] if rules.none?
|
|
211
199
|
|
|
212
|
-
specific_rules =
|
|
200
|
+
specific_rules = rules.select { |rule| rule.applicable?(promotable) }
|
|
213
201
|
return [] if specific_rules.none?
|
|
214
202
|
|
|
215
203
|
rule_eligibility = Hash[specific_rules.map do |rule|
|
|
@@ -177,8 +177,8 @@ module Spree
|
|
|
177
177
|
|
|
178
178
|
# Check for applied adjustments.
|
|
179
179
|
discount = order.all_adjustments.promotion.eligible.detect do |p|
|
|
180
|
-
p.
|
|
181
|
-
Spree::CouponCode.unused.where(promotion_id: p.
|
|
180
|
+
p.source.promotion.code.try(:downcase) == coupon_code ||
|
|
181
|
+
Spree::CouponCode.unused.where(promotion_id: p.source.promotion_id, code: coupon_code).exists?
|
|
182
182
|
end
|
|
183
183
|
|
|
184
184
|
# Check for applied line items.
|
|
@@ -209,7 +209,7 @@ module Spree
|
|
|
209
209
|
end
|
|
210
210
|
|
|
211
211
|
def handle_coupon_code(discount, coupon_code)
|
|
212
|
-
Spree::CouponCode.unused.find_by(promotion_id: discount.
|
|
212
|
+
Spree::CouponCode.unused.find_by(promotion_id: discount.source.promotion_id, code: coupon_code)&.apply_order!(order)
|
|
213
213
|
end
|
|
214
214
|
|
|
215
215
|
def load_gift_card_code
|
|
@@ -4,9 +4,6 @@ module Spree
|
|
|
4
4
|
|
|
5
5
|
include Spree::Metadata
|
|
6
6
|
|
|
7
|
-
has_many :property_prototypes, class_name: 'Spree::PropertyPrototype'
|
|
8
|
-
has_many :properties, through: :property_prototypes, class_name: 'Spree::Property'
|
|
9
|
-
|
|
10
7
|
has_many :option_type_prototypes, class_name: 'Spree::OptionTypePrototype'
|
|
11
8
|
has_many :option_types, through: :option_type_prototypes, class_name: 'Spree::OptionType'
|
|
12
9
|
|
data/app/models/spree/refund.rb
CHANGED
|
@@ -36,6 +36,10 @@ module Spree
|
|
|
36
36
|
|
|
37
37
|
delegate :order, :currency, to: :payment
|
|
38
38
|
|
|
39
|
+
def amount=(amount)
|
|
40
|
+
self[:amount] = Spree::LocalizedNumber.parse(amount)
|
|
41
|
+
end
|
|
42
|
+
|
|
39
43
|
def money
|
|
40
44
|
Spree::Money.new(amount, currency: currency)
|
|
41
45
|
end
|
|
@@ -83,7 +87,7 @@ module Spree
|
|
|
83
87
|
update_order
|
|
84
88
|
end
|
|
85
89
|
|
|
86
|
-
# return
|
|
90
|
+
# return a payment response object if successful or else raise an error
|
|
87
91
|
def process!(credit_cents)
|
|
88
92
|
refund_total_in_cents = calculate_refund_amount(credit_cents)
|
|
89
93
|
|
|
@@ -102,7 +106,7 @@ module Spree
|
|
|
102
106
|
end
|
|
103
107
|
|
|
104
108
|
response
|
|
105
|
-
rescue
|
|
109
|
+
rescue Spree::PaymentConnectionError => e
|
|
106
110
|
Rails.logger.error(Spree.t(:gateway_error) + " #{e.inspect}")
|
|
107
111
|
raise Core::GatewayError, Spree.t(:unable_to_connect_to_gateway)
|
|
108
112
|
end
|
|
@@ -2,6 +2,7 @@ module Spree
|
|
|
2
2
|
class Shipment < Spree.base_class
|
|
3
3
|
module Emails
|
|
4
4
|
def send_shipped_email
|
|
5
|
+
Spree::Deprecation.warn("Shipment#send_shipped_email is deprecated and will be removed in Spree 5.5. Please use events")
|
|
5
6
|
# you can overwrite this method in your application / extension to send out the confirmation email
|
|
6
7
|
# or use `spree_emails` gem
|
|
7
8
|
# YourEmailVendor.deliver_shipment_notification_email(@shipment.id)
|
|
@@ -16,10 +16,10 @@ module Spree
|
|
|
16
16
|
find_by(name: DIGITAL_NAME)
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
+
# Returns true if this shipping category includes a digital shipping method
|
|
20
|
+
# @return [Boolean]
|
|
19
21
|
def includes_digital_shipping_method?
|
|
20
|
-
|
|
21
|
-
shipping_methods.digital.exists?
|
|
22
|
-
end
|
|
22
|
+
@includes_digital_shipping_method ||= shipping_methods.digital.exists?
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
end
|
data/app/models/spree/store.rb
CHANGED
|
@@ -75,7 +75,6 @@ module Spree
|
|
|
75
75
|
|
|
76
76
|
has_many :store_products, class_name: 'Spree::StoreProduct'
|
|
77
77
|
has_many :products, through: :store_products, class_name: 'Spree::Product'
|
|
78
|
-
has_many :product_properties, through: :products, class_name: 'Spree::ProductProperty'
|
|
79
78
|
has_many :variants, through: :products, class_name: 'Spree::Variant', source: :variants_including_master
|
|
80
79
|
has_many :stock_items, through: :variants, class_name: 'Spree::StockItem'
|
|
81
80
|
has_many :inventory_units, through: :variants, class_name: 'Spree::InventoryUnit'
|
|
@@ -93,17 +92,12 @@ module Spree
|
|
|
93
92
|
|
|
94
93
|
has_many :wishlists, class_name: 'Spree::Wishlist'
|
|
95
94
|
|
|
96
|
-
has_many :data_feeds, class_name: 'Spree::DataFeed'
|
|
97
|
-
|
|
98
95
|
belongs_to :default_country, class_name: 'Spree::Country'
|
|
99
96
|
belongs_to :checkout_zone, class_name: 'Spree::Zone'
|
|
100
97
|
|
|
101
98
|
has_many :reports, class_name: 'Spree::Report'
|
|
102
99
|
has_many :exports, class_name: 'Spree::Export'
|
|
103
100
|
|
|
104
|
-
has_many :posts, class_name: 'Spree::Post', dependent: :destroy, inverse_of: :store
|
|
105
|
-
has_many :post_categories, class_name: 'Spree::PostCategory', dependent: :destroy, inverse_of: :store
|
|
106
|
-
|
|
107
101
|
has_many :integrations, class_name: 'Spree::Integration'
|
|
108
102
|
|
|
109
103
|
has_many :gift_cards, class_name: 'Spree::GiftCard', dependent: :destroy
|
|
@@ -165,9 +159,7 @@ module Spree
|
|
|
165
159
|
after_create :ensure_default_market
|
|
166
160
|
after_create :ensure_default_taxonomies_are_created
|
|
167
161
|
after_create :ensure_default_automatic_taxons
|
|
168
|
-
after_create :ensure_default_post_categories_are_created
|
|
169
162
|
after_create :create_default_policies
|
|
170
|
-
after_commit :clear_cache
|
|
171
163
|
|
|
172
164
|
#
|
|
173
165
|
# Scopes
|
|
@@ -184,17 +176,15 @@ module Spree
|
|
|
184
176
|
|
|
185
177
|
# @deprecated The or_initialize behavior will be removed in Spree 5.5.
|
|
186
178
|
def self.default
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
Spree::
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
new(default: true)
|
|
197
|
-
end
|
|
179
|
+
# workaround for Mobility bug with first_or_initialize
|
|
180
|
+
if where(default: true).any?
|
|
181
|
+
where(default: true).first
|
|
182
|
+
else
|
|
183
|
+
Spree::Deprecation.warn(
|
|
184
|
+
'Spree::Store.default returning a new unpersisted store when no default store exists is deprecated ' \
|
|
185
|
+
'and will be removed in Spree 5.5. Please ensure a default store is created before calling Store.default.'
|
|
186
|
+
)
|
|
187
|
+
new(default: true)
|
|
198
188
|
end
|
|
199
189
|
end
|
|
200
190
|
|
|
@@ -296,9 +286,7 @@ module Spree
|
|
|
296
286
|
# @param country [Spree::Country] the country to get the states for
|
|
297
287
|
# @return [Array<Spree::State>]
|
|
298
288
|
def states_available_for_checkout(country)
|
|
299
|
-
|
|
300
|
-
country.states.to_a
|
|
301
|
-
end
|
|
289
|
+
country.states.to_a
|
|
302
290
|
end
|
|
303
291
|
|
|
304
292
|
# @deprecated Use {Spree::Zone.all} or {#countries_with_shipping_coverage} instead.
|
|
@@ -388,18 +376,6 @@ module Spree
|
|
|
388
376
|
|
|
389
377
|
private
|
|
390
378
|
|
|
391
|
-
def countries_available_for_checkout_cache_key
|
|
392
|
-
"#{cache_key_with_version}/countries_available_for_checkout"
|
|
393
|
-
end
|
|
394
|
-
|
|
395
|
-
def states_available_for_checkout_cache_key(country)
|
|
396
|
-
"#{cache_key_with_version}/states_available_for_checkout/#{country&.cache_key_with_version}"
|
|
397
|
-
end
|
|
398
|
-
|
|
399
|
-
def clear_cache
|
|
400
|
-
Rails.cache.delete('default_store')
|
|
401
|
-
end
|
|
402
|
-
|
|
403
379
|
def ensure_default_market
|
|
404
380
|
return if markets.exists?
|
|
405
381
|
|
|
@@ -463,21 +439,6 @@ module Spree
|
|
|
463
439
|
end
|
|
464
440
|
end
|
|
465
441
|
|
|
466
|
-
def ensure_default_post_categories_are_created
|
|
467
|
-
Spree::Events.disable do
|
|
468
|
-
[
|
|
469
|
-
translate_with_store_locale_fallback('spree.default_post_categories.resources'),
|
|
470
|
-
translate_with_store_locale_fallback('spree.default_post_categories.articles'),
|
|
471
|
-
translate_with_store_locale_fallback('spree.default_post_categories.news')
|
|
472
|
-
].each do |category_title|
|
|
473
|
-
# Use exists?/create pattern for safety
|
|
474
|
-
next if post_categories.where(title: category_title).exists?
|
|
475
|
-
|
|
476
|
-
post_categories.create(title: category_title)
|
|
477
|
-
end
|
|
478
|
-
end
|
|
479
|
-
end
|
|
480
|
-
|
|
481
442
|
def create_default_policies
|
|
482
443
|
Spree::Events.disable do
|
|
483
444
|
[
|
|
@@ -54,6 +54,10 @@ module Spree
|
|
|
54
54
|
extend Spree::DisplayMoney
|
|
55
55
|
money_methods :amount, :amount_used, :amount_remaining, :amount_authorized
|
|
56
56
|
|
|
57
|
+
def amount=(amount)
|
|
58
|
+
self[:amount] = Spree::LocalizedNumber.parse(amount)
|
|
59
|
+
end
|
|
60
|
+
|
|
57
61
|
self.whitelisted_ransackable_attributes = %w[user_id created_by_id amount currency type_id]
|
|
58
62
|
self.whitelisted_ransackable_associations = %w[type user created_by]
|
|
59
63
|
|
|
@@ -10,15 +10,11 @@ module Spree
|
|
|
10
10
|
has_many :variants, dependent: :nullify
|
|
11
11
|
|
|
12
12
|
before_save :set_default_category
|
|
13
|
-
after_update :delete_cache
|
|
14
|
-
after_create :delete_cache
|
|
15
13
|
|
|
16
14
|
self.whitelisted_ransackable_attributes = %w[name is_default tax_code]
|
|
17
15
|
|
|
18
16
|
def self.default
|
|
19
|
-
|
|
20
|
-
find_by(is_default: true)
|
|
21
|
-
end
|
|
17
|
+
find_by(is_default: true)
|
|
22
18
|
end
|
|
23
19
|
|
|
24
20
|
def set_default_category
|
|
@@ -28,11 +24,5 @@ module Spree
|
|
|
28
24
|
tax_category.update_columns(is_default: false, updated_at: Time.current)
|
|
29
25
|
end
|
|
30
26
|
end
|
|
31
|
-
|
|
32
|
-
private
|
|
33
|
-
|
|
34
|
-
def delete_cache
|
|
35
|
-
Rails.cache.delete('default_tax_category')
|
|
36
|
-
end
|
|
37
27
|
end
|
|
38
28
|
end
|
data/app/models/spree/taxon.rb
CHANGED
|
@@ -38,8 +38,6 @@ module Spree
|
|
|
38
38
|
has_one :store, through: :taxonomy
|
|
39
39
|
has_many :classifications, -> { order(:position) }, dependent: :destroy_async, inverse_of: :taxon
|
|
40
40
|
has_many :products, through: :classifications
|
|
41
|
-
# @deprecated Use Spree::Taxon#image (Active Storage) instead. Will be removed in Spree 5.5.
|
|
42
|
-
has_one :icon, as: :viewable, dependent: :destroy, class_name: 'Spree::TaxonImage'
|
|
43
41
|
|
|
44
42
|
has_many :prototype_taxons, class_name: 'Spree::PrototypeTaxon', dependent: :destroy
|
|
45
43
|
has_many :prototypes, through: :prototype_taxons, class_name: 'Spree::Prototype'
|
|
@@ -60,7 +58,6 @@ module Spree
|
|
|
60
58
|
validates :taxonomy, presence: true
|
|
61
59
|
validates :permalink, uniqueness: { case_sensitive: false, scope: [:parent_id, :taxonomy_id] }
|
|
62
60
|
validates :hide_from_nav, inclusion: { in: [true, false] }
|
|
63
|
-
validates_associated :icon
|
|
64
61
|
validate :check_for_root, on: :create
|
|
65
62
|
validate :parent_belongs_to_same_taxonomy
|
|
66
63
|
with_options length: { maximum: 255 }, allow_blank: true do
|
|
@@ -312,19 +309,6 @@ module Spree
|
|
|
312
309
|
end
|
|
313
310
|
end
|
|
314
311
|
|
|
315
|
-
# indicate which filters should be used for a taxon
|
|
316
|
-
# this method should be customized to your own site
|
|
317
|
-
def applicable_filters
|
|
318
|
-
Spree::Deprecation.warn('applicable_filters is deprecated and will be removed in Spree 5.5')
|
|
319
|
-
fs = []
|
|
320
|
-
# fs << ProductFilters.taxons_below(self)
|
|
321
|
-
## unless it's a root taxon? left open for demo purposes
|
|
322
|
-
|
|
323
|
-
fs << Spree::Core::ProductFilters.price_filter if Spree::Core::ProductFilters.respond_to?(:price_filter)
|
|
324
|
-
fs << Spree::Core::ProductFilters.brand_filter if Spree::Core::ProductFilters.respond_to?(:brand_filter)
|
|
325
|
-
fs
|
|
326
|
-
end
|
|
327
|
-
|
|
328
312
|
# Return meta_title if set otherwise generates from taxon name
|
|
329
313
|
def seo_title
|
|
330
314
|
meta_title.blank? ? name : meta_title
|
data/app/models/spree/variant.rb
CHANGED
|
@@ -88,8 +88,6 @@ module Spree
|
|
|
88
88
|
after_create :increment_product_variant_count, unless: :is_master?
|
|
89
89
|
after_destroy :decrement_product_variant_count, unless: :is_master?
|
|
90
90
|
|
|
91
|
-
after_touch :clear_in_stock_cache
|
|
92
|
-
|
|
93
91
|
scope :in_stock, -> { left_joins(:stock_items).where("#{Spree::Variant.table_name}.track_inventory = ? OR #{Spree::StockItem.table_name}.count_on_hand > ?", false, 0) }
|
|
94
92
|
scope :backorderable, -> { left_joins(:stock_items).where(spree_stock_items: { backorderable: true }) }
|
|
95
93
|
scope :in_stock_or_backorderable, -> { in_stock.or(backorderable) }
|
|
@@ -281,14 +279,6 @@ module Spree
|
|
|
281
279
|
is_master? ? name + ' - Master' : name + ' - ' + options_text
|
|
282
280
|
end
|
|
283
281
|
|
|
284
|
-
# use deleted? rather than checking the attribute directly. this
|
|
285
|
-
# allows extensions to override deleted? if they want to provide
|
|
286
|
-
# their own definition.
|
|
287
|
-
# @return [Boolean] true if the variant is deleted.
|
|
288
|
-
def deleted?
|
|
289
|
-
!!deleted_at
|
|
290
|
-
end
|
|
291
|
-
|
|
292
282
|
# Returns true if the variant has images.
|
|
293
283
|
# Uses loaded association when available, otherwise falls back to counter cache.
|
|
294
284
|
# @return [Boolean]
|
|
@@ -532,36 +522,16 @@ module Spree
|
|
|
532
522
|
@compare_at_price ||= price_in(cost_currency).try(:compare_at_amount)
|
|
533
523
|
end
|
|
534
524
|
|
|
535
|
-
# Returns the name and sku of the variant.
|
|
536
|
-
# @return [String] the name and sku of the variant
|
|
537
|
-
def name_and_sku
|
|
538
|
-
"#{name} - #{sku}"
|
|
539
|
-
end
|
|
540
|
-
|
|
541
|
-
# Returns the sku and options text of the variant.
|
|
542
|
-
# @return [String] the sku and options text of the variant
|
|
543
|
-
def sku_and_options_text
|
|
544
|
-
"#{sku} #{options_text}".strip
|
|
545
|
-
end
|
|
546
|
-
|
|
547
525
|
# Returns true if the variant is in stock.
|
|
548
526
|
# @return [Boolean] true if the variant is in stock
|
|
549
527
|
def in_stock?
|
|
550
|
-
@in_stock ||=
|
|
551
|
-
total_on_hand.positive?
|
|
552
|
-
else
|
|
553
|
-
Rails.cache.fetch(in_stock_cache_key, version: cache_version) do
|
|
554
|
-
total_on_hand.positive?
|
|
555
|
-
end
|
|
556
|
-
end
|
|
528
|
+
@in_stock ||= total_on_hand.positive?
|
|
557
529
|
end
|
|
558
530
|
|
|
559
531
|
# Returns true if the variant is backorderable.
|
|
560
532
|
# @return [Boolean] true if the variant is backorderable
|
|
561
533
|
def backorderable?
|
|
562
|
-
@backorderable ||=
|
|
563
|
-
quantifier.backorderable?
|
|
564
|
-
end
|
|
534
|
+
@backorderable ||= quantifier.backorderable?
|
|
565
535
|
end
|
|
566
536
|
|
|
567
537
|
def on_sale?(currency)
|
|
@@ -619,10 +589,6 @@ module Spree
|
|
|
619
589
|
digitals.any?
|
|
620
590
|
end
|
|
621
591
|
|
|
622
|
-
def clear_in_stock_cache
|
|
623
|
-
Rails.cache.delete(in_stock_cache_key)
|
|
624
|
-
end
|
|
625
|
-
|
|
626
592
|
private
|
|
627
593
|
|
|
628
594
|
def ensure_not_in_complete_orders
|
|
@@ -674,10 +640,6 @@ module Spree
|
|
|
674
640
|
end
|
|
675
641
|
end
|
|
676
642
|
|
|
677
|
-
def in_stock_cache_key
|
|
678
|
-
"variant-#{id}-in_stock"
|
|
679
|
-
end
|
|
680
|
-
|
|
681
643
|
def disable_sku_validation?
|
|
682
644
|
Spree::Config[:disable_sku_validation]
|
|
683
645
|
end
|
data/app/models/spree/zone.rb
CHANGED
|
@@ -27,9 +27,7 @@ module Spree
|
|
|
27
27
|
self.whitelisted_ransackable_attributes = ['description']
|
|
28
28
|
|
|
29
29
|
def self.default_tax
|
|
30
|
-
|
|
31
|
-
find_by(default_tax: true)
|
|
32
|
-
end
|
|
30
|
+
Spree::Current.default_tax_zone
|
|
33
31
|
end
|
|
34
32
|
|
|
35
33
|
def self.potential_matching_zones(zone)
|
|
@@ -186,7 +184,6 @@ module Spree
|
|
|
186
184
|
|
|
187
185
|
def remove_previous_default
|
|
188
186
|
Spree::Zone.with_default_tax.where.not(id: id).update_all(default_tax: false)
|
|
189
|
-
Rails.cache.delete('default_zone')
|
|
190
187
|
end
|
|
191
188
|
|
|
192
189
|
def set_zone_members(ids, type)
|
|
@@ -3,7 +3,7 @@ module Spree
|
|
|
3
3
|
class AddItem
|
|
4
4
|
prepend Spree::ServiceModule::Base
|
|
5
5
|
|
|
6
|
-
def call(order:, variant:, quantity: nil, public_metadata: {}, private_metadata: {}, options: {})
|
|
6
|
+
def call(order:, variant:, quantity: nil, metadata: {}, public_metadata: {}, private_metadata: {}, options: {})
|
|
7
7
|
ApplicationRecord.transaction do
|
|
8
8
|
run :add_to_line_item
|
|
9
9
|
run Spree.cart_recalculate_service
|
|
@@ -12,7 +12,7 @@ module Spree
|
|
|
12
12
|
|
|
13
13
|
private
|
|
14
14
|
|
|
15
|
-
def add_to_line_item(order:, variant:, quantity: nil, public_metadata: {}, private_metadata: {}, options: {})
|
|
15
|
+
def add_to_line_item(order:, variant:, quantity: nil, metadata: {}, public_metadata: {}, private_metadata: {}, options: {})
|
|
16
16
|
options ||= {}
|
|
17
17
|
quantity ||= 1
|
|
18
18
|
|
|
@@ -34,8 +34,12 @@ module Spree
|
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
line_item.target_shipment = options[:shipment] if options.key? :shipment
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
|
|
38
|
+
# `metadata` is the primary API param (maps to private_metadata).
|
|
39
|
+
# Legacy `public_metadata`/`private_metadata` params kept for backward compatibility.
|
|
40
|
+
resolved_metadata = metadata.presence || private_metadata
|
|
41
|
+
line_item.metadata = resolved_metadata.to_h if resolved_metadata.present?
|
|
42
|
+
line_item.public_metadata = public_metadata.to_h if public_metadata.present?
|
|
39
43
|
|
|
40
44
|
return failure(line_item) unless line_item.save
|
|
41
45
|
|
|
@@ -3,18 +3,29 @@ module Spree
|
|
|
3
3
|
class Create
|
|
4
4
|
prepend Spree::ServiceModule::Base
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
# @param user [Spree.user_class, nil] the user to associate with the cart
|
|
7
|
+
# @param store [Spree::Store] the store for the cart
|
|
8
|
+
# @param currency [String, nil] ISO currency code, defaults to store's default currency
|
|
9
|
+
# @param locale [String, nil] locale for the cart (e.g. 'en', 'fr'), defaults to Spree::Current.locale
|
|
10
|
+
# @param public_metadata [Hash] public metadata for the order
|
|
11
|
+
# @param private_metadata [Hash] private metadata for the order
|
|
12
|
+
# @param order_params [Hash] additional order attributes
|
|
13
|
+
# @return [Spree::ServiceModule::Result]
|
|
14
|
+
def call(user:, store:, currency:, locale: nil, metadata: {}, public_metadata: {}, private_metadata: {}, order_params: {})
|
|
7
15
|
order_params ||= {}
|
|
8
16
|
|
|
9
17
|
# we cannot create an order without store
|
|
10
18
|
return failure(:store_is_required) if store.nil?
|
|
11
19
|
|
|
20
|
+
resolved_metadata = metadata.presence || private_metadata
|
|
21
|
+
|
|
12
22
|
default_params = {
|
|
13
23
|
user: user,
|
|
14
24
|
currency: currency || store.default_currency,
|
|
25
|
+
locale: locale || Spree::Current.locale,
|
|
15
26
|
token: Spree::GenerateToken.new.call(Spree::Order),
|
|
16
27
|
public_metadata: public_metadata.to_h,
|
|
17
|
-
private_metadata:
|
|
28
|
+
private_metadata: resolved_metadata.to_h
|
|
18
29
|
}
|
|
19
30
|
|
|
20
31
|
order = store.orders.create!(default_params.merge(order_params))
|
|
@@ -13,8 +13,6 @@ module Spree
|
|
|
13
13
|
new_product.send(:duplicate_extra, product) if new_product.respond_to?(:duplicate_extra)
|
|
14
14
|
new_product.save
|
|
15
15
|
|
|
16
|
-
new_product.product_properties = duplicate_properties(product.product_properties) if new_product.persisted?
|
|
17
|
-
|
|
18
16
|
new_product.persisted? ? success(new_product) : failure(new_product, duplicate_error_message(new_product))
|
|
19
17
|
end
|
|
20
18
|
|
|
@@ -89,16 +87,6 @@ module Spree
|
|
|
89
87
|
new_image
|
|
90
88
|
end
|
|
91
89
|
|
|
92
|
-
def duplicate_properties(product_properties)
|
|
93
|
-
product_properties.map do |prop|
|
|
94
|
-
new_prop = prop.dup
|
|
95
|
-
new_prop.product = nil
|
|
96
|
-
new_prop.created_at = nil
|
|
97
|
-
new_prop.updated_at = nil
|
|
98
|
-
new_prop
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
|
|
102
90
|
def sku_generator(sku)
|
|
103
91
|
return '' if sku.blank?
|
|
104
92
|
|
|
@@ -61,18 +61,6 @@ module Spree
|
|
|
61
61
|
end
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
-
# mark resource properties to be removed
|
|
65
|
-
# when value is left blank
|
|
66
|
-
if params[:product_properties_attributes].present?
|
|
67
|
-
params[:product_properties_attributes].each do |key, product_property_params|
|
|
68
|
-
next unless product_property_params[:id].present?
|
|
69
|
-
next if product_property_params[:value].present?
|
|
70
|
-
|
|
71
|
-
# https://api.rubyonrails.org/v7.1.3.4/classes/ActiveRecord/NestedAttributes/ClassMethods.html
|
|
72
|
-
params[:product_properties_attributes][key]['_destroy'] = '1'
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
|
|
76
64
|
# ensure there is at least one store
|
|
77
65
|
params[:store_ids] = [store.id] if params[:store_ids].blank?
|
|
78
66
|
|