spree_core 3.7.14.1 → 4.0.0.beta

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 (83) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/app/controllers/spree/base_controller.rb +0 -1
  4. data/app/finders/spree/taxons/find.rb +6 -5
  5. data/app/helpers/spree/base_helper.rb +0 -9
  6. data/app/helpers/spree/products_helper.rb +1 -1
  7. data/app/models/concerns/spree/product_scopes.rb +254 -0
  8. data/app/models/concerns/spree/user_address.rb +5 -2
  9. data/app/models/friendly_id/slug_decorator.rb +8 -2
  10. data/app/models/spree/ability.rb +21 -22
  11. data/app/models/spree/address.rb +37 -24
  12. data/app/models/spree/adjustment.rb +0 -10
  13. data/app/models/spree/app_dependencies.rb +2 -2
  14. data/app/models/spree/asset.rb +1 -12
  15. data/app/models/spree/country.rb +2 -2
  16. data/app/models/spree/credit_card.rb +4 -5
  17. data/app/models/spree/gateway/bogus.rb +1 -1
  18. data/app/models/spree/image.rb +8 -1
  19. data/app/models/spree/image/configuration/active_storage.rb +0 -2
  20. data/app/models/spree/order.rb +13 -78
  21. data/app/models/spree/order/address_book.rb +86 -0
  22. data/app/models/spree/order/checkout.rb +4 -22
  23. data/app/models/spree/order/currency_updater.rb +1 -1
  24. data/app/models/spree/order/store_credit.rb +0 -18
  25. data/app/models/spree/order_merger.rb +1 -0
  26. data/app/models/spree/payment.rb +4 -2
  27. data/app/models/spree/payment/gateway_options.rb +1 -1
  28. data/app/models/spree/payment/processing.rb +2 -0
  29. data/app/models/spree/preferences/configuration.rb +1 -1
  30. data/app/models/spree/preferences/preferable.rb +1 -1
  31. data/app/models/spree/product.rb +2 -3
  32. data/app/models/spree/promotion_handler/coupon.rb +2 -1
  33. data/app/models/spree/reimbursement_tax_calculator.rb +1 -1
  34. data/app/models/spree/return_item.rb +1 -1
  35. data/app/models/spree/return_item/eligibility_validator/default.rb +2 -0
  36. data/app/models/spree/return_item/eligibility_validator/{rma_required.rb → r_m_a_required.rb} +0 -0
  37. data/app/models/spree/shipment.rb +1 -1
  38. data/app/models/spree/store_credit.rb +4 -5
  39. data/app/models/spree/taxon_image.rb +1 -1
  40. data/app/models/spree/taxonomy.rb +1 -1
  41. data/app/services/spree/cart/add_item.rb +3 -1
  42. data/app/services/spree/cart/update.rb +1 -1
  43. data/config/locales/en.yml +15 -0
  44. data/db/default/spree/stores.rb +1 -0
  45. data/db/default/spree/zones.rb +16 -0
  46. data/db/migrate/20140806144901_add_type_to_reimbursement_type.rb +1 -1
  47. data/db/migrate/20141101231208_fix_adjustment_order_presence.rb +2 -2
  48. data/db/migrate/20170323151450_add_missing_unique_indexes_for_unique_attributes.rb +1 -1
  49. data/db/migrate/20190305121659_add_iso_and_iso3_validation_on_presence_and_uniqueness.rb +18 -0
  50. data/db/migrate/20190523092729_add_user_id_and_deleted_at_to_spree_addresses.rb +12 -0
  51. data/lib/generators/spree/dummy/dummy_generator.rb +3 -1
  52. data/lib/spree/core.rb +0 -2
  53. data/lib/spree/core/importer/order.rb +64 -103
  54. data/lib/spree/core/importer/product.rb +2 -2
  55. data/lib/spree/core/product_duplicator.rb +1 -5
  56. data/lib/spree/core/version.rb +1 -3
  57. data/lib/spree/permitted_attributes.rb +3 -1
  58. data/lib/spree/testing_support/ability_helpers.rb +3 -11
  59. data/lib/spree/testing_support/capybara_config.rb +4 -1
  60. data/lib/spree/testing_support/capybara_ext.rb +22 -98
  61. data/lib/spree/testing_support/controller_requests.rb +36 -26
  62. data/lib/spree/testing_support/factories/image_factory.rb +2 -6
  63. data/lib/spree/testing_support/factories/return_item_factory.rb +2 -2
  64. data/lib/spree/testing_support/factories/taxon_factory.rb +1 -1
  65. data/lib/spree/testing_support/i18n.rb +6 -8
  66. data/lib/spree/testing_support/image_helpers.rb +5 -11
  67. data/lib/tasks/exchanges.rake +35 -37
  68. data/spree_core.gemspec +11 -14
  69. metadata +63 -103
  70. data/app/models/concerns/spree/acts_as_taggable.rb +0 -11
  71. data/app/models/spree/image/configuration/paperclip.rb +0 -64
  72. data/app/models/spree/order_contents.rb +0 -54
  73. data/app/models/spree/product/scopes.rb +0 -250
  74. data/app/models/spree/tag.rb +0 -4
  75. data/app/models/spree/taxon_image/configuration/paperclip.rb +0 -27
  76. data/config/initializers/acts_as_taggable_on.rb +0 -9
  77. data/config/initializers/use_paperclip.rb +0 -3
  78. data/db/migrate/20160511071954_acts_as_taggable_on_spree_migration.rb +0 -40
  79. data/db/migrate/20160511072249_change_collation_for_spree_tag_names.rb +0 -9
  80. data/db/migrate/20160511072335_add_missing_indexes_to_spree_taggings.rb +0 -14
  81. data/lib/spree/core/controller_helpers/respond_with.rb +0 -67
  82. data/lib/spree/responder.rb +0 -44
  83. data/lib/spree/testing_support/factories/tag_factory.rb +0 -5
@@ -1,11 +0,0 @@
1
- module Spree
2
- module ActsAsTaggable
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- acts_as_taggable
7
- Spree::PermittedAttributes.send("#{model_name.param_key}_attributes") <<
8
- [:tag_list]
9
- end
10
- end
11
- end
@@ -1,64 +0,0 @@
1
- module Spree
2
- class Image < Asset
3
- module Configuration
4
- module Paperclip
5
- extend ActiveSupport::Concern
6
-
7
- included do
8
- validate :no_attachment_errors
9
-
10
- def self.accepted_image_types
11
- %w(image/jpeg image/jpg image/png image/gif)
12
- end
13
-
14
- def self.styles
15
- attachment_definitions[:attachment][:styles]
16
- end
17
-
18
- has_attached_file :attachment,
19
- styles: { mini: '48x48>', small: '100x100>', product: '240x240>', large: '600x600>' },
20
- default_style: :product,
21
- url: '/spree/products/:id/:style/:basename.:extension',
22
- path: ':rails_root/public/spree/products/:id/:style/:basename.:extension',
23
- convert_options: { all: '-strip -auto-orient -colorspace sRGB' }
24
-
25
- validates_attachment :attachment,
26
- presence: true,
27
- content_type: { content_type: accepted_image_types }
28
-
29
- # save the w,h of the original image (from which others can be calculated)
30
- # we need to look at the write-queue for images which have not been saved yet
31
- before_save :find_dimensions, if: :attachment_updated_at_changed?
32
-
33
- delegate :url, to: :attachment
34
-
35
- # used by admin products autocomplete
36
- def mini_url
37
- url(:mini, false)
38
- end
39
-
40
- def find_dimensions
41
- temporary = attachment.queued_for_write[:original]
42
- filename = temporary.path unless temporary.nil?
43
- filename = attachment.path if filename.blank?
44
- geometry = ::Paperclip::Geometry.from_file(filename)
45
- self.attachment_width = geometry.width
46
- self.attachment_height = geometry.height
47
- end
48
-
49
- # if there are errors from the plugin, then add a more meaningful message
50
- def no_attachment_errors
51
- unless attachment.errors.empty?
52
- # uncomment this to get rid of the less-than-useful interim messages
53
- # errors.clear
54
- errors.add :attachment,
55
- "Paperclip returned errors for file '#{attachment_file_name}' - check ImageMagick installation or image source file."
56
-
57
- false
58
- end
59
- end
60
- end
61
- end
62
- end
63
- end
64
- end
@@ -1,54 +0,0 @@
1
- module Spree
2
- class OrderContents
3
- attr_accessor :order, :currency
4
-
5
- def initialize(order)
6
- @order = order
7
- end
8
-
9
- def add(variant, quantity = 1, options = {})
10
- ActiveSupport::Deprecation.warn(<<-EOS, caller)
11
- OrderContents#add method is deprecated and will be removed in Spree 4.0.
12
- Please use Spree::Dependencies.cart_add_item_service
13
- to add items to cart.
14
- EOS
15
-
16
- Spree::Dependencies.cart_add_item_service.constantize.call(order: order,
17
- variant: variant,
18
- quantity: quantity,
19
- options: options).value
20
- end
21
-
22
- def remove(variant, quantity = 1, options = {})
23
- ActiveSupport::Deprecation.warn(<<-EOS, caller)
24
- OrderContents#remove method is deprecated and will be removed in Spree 4.0.
25
- Please use Spree::Dependencies.cart_remove_item_service
26
- service to remove item from cart.
27
- EOS
28
-
29
- # change this dependencies to Spree::Cart::RemoveItem
30
- Spree::Dependencies.cart_remove_item_service.constantize.call(order: order,
31
- variant: variant,
32
- quantity: quantity,
33
- options: options).value
34
- end
35
-
36
- def remove_line_item(line_item, options = {})
37
- ActiveSupport::Deprecation.warn(<<-EOS, caller)
38
- OrderContents#remove_line_item method is deprecated and will be removed in Spree 4.0.
39
- EOS
40
-
41
- Spree::Cart::RemoveLineItem.call(order: @order, line_item: line_item, options: options).value
42
- end
43
-
44
- def update_cart(params)
45
- ActiveSupport::Deprecation.warn(<<-EOS, caller)
46
- OrderContents#update_cart method is deprecated and will be removed in Spree 4.0.
47
- Spree::Dependencies.cart_update_service
48
- service to update cart.
49
- EOS
50
-
51
- Spree::Dependencies.cart_update_service.constantize.call(order: order, params: params).value
52
- end
53
- end
54
- end
@@ -1,250 +0,0 @@
1
- module Spree
2
- class Product < Spree::Base
3
- cattr_accessor :search_scopes do
4
- []
5
- end
6
-
7
- def self.add_search_scope(name, &block)
8
- singleton_class.send(:define_method, name.to_sym, &block)
9
- search_scopes << name.to_sym
10
- end
11
-
12
- def self.simple_scopes
13
- [
14
- :ascend_by_updated_at,
15
- :descend_by_updated_at,
16
- :ascend_by_name,
17
- :descend_by_name
18
- ]
19
- end
20
-
21
- def self.add_simple_scopes(scopes)
22
- scopes.each do |name|
23
- # We should not define price scopes here, as they require something slightly different
24
- next if name.to_s.include?('master_price')
25
-
26
- parts = name.to_s.match(/(.*)_by_(.*)/)
27
- scope(name.to_s, -> { order(Arel.sql("#{Product.quoted_table_name}.#{parts[2]} #{parts[1] == 'ascend' ? 'ASC' : 'DESC'}")) })
28
- end
29
- end
30
-
31
- def self.property_conditions(property)
32
- properties = Property.table_name
33
- case property
34
- when String then { "#{properties}.name" => property }
35
- when Property then { "#{properties}.id" => property.id }
36
- else { "#{properties}.id" => property.to_i }
37
- end
38
- end
39
-
40
- add_simple_scopes simple_scopes
41
-
42
- add_search_scope :ascend_by_master_price do
43
- joins(master: :default_price).order("#{price_table_name}.amount ASC")
44
- end
45
-
46
- add_search_scope :descend_by_master_price do
47
- joins(master: :default_price).order("#{price_table_name}.amount DESC")
48
- end
49
-
50
- add_search_scope :price_between do |low, high|
51
- joins(master: :default_price).where(Price.table_name => { amount: low..high })
52
- end
53
-
54
- add_search_scope :master_price_lte do |price|
55
- joins(master: :default_price).where("#{price_table_name}.amount <= ?", price)
56
- end
57
-
58
- add_search_scope :master_price_gte do |price|
59
- joins(master: :default_price).where("#{price_table_name}.amount >= ?", price)
60
- end
61
-
62
- # This scope selects products in taxon AND all its descendants
63
- # If you need products only within one taxon use
64
- #
65
- # Spree::Product.joins(:taxons).where(Taxon.table_name => { id: taxon.id })
66
- #
67
- # If you're using count on the result of this scope, you must use the
68
- # `:distinct` option as well:
69
- #
70
- # Spree::Product.in_taxon(taxon).count(distinct: true)
71
- #
72
- # This is so that the count query is distinct'd:
73
- #
74
- # SELECT COUNT(DISTINCT "spree_products"."id") ...
75
- #
76
- # vs.
77
- #
78
- # SELECT COUNT(*) ...
79
- add_search_scope :in_taxon do |taxon|
80
- includes(:classifications).
81
- where('spree_products_taxons.taxon_id' => taxon.self_and_descendants.pluck(:id)).
82
- order('spree_products_taxons.position ASC')
83
- end
84
-
85
- # This scope selects products in all taxons AND all its descendants
86
- # If you need products only within one taxon use
87
- #
88
- # Spree::Product.taxons_id_eq([x,y])
89
- add_search_scope :in_taxons do |*taxons|
90
- taxons = get_taxons(taxons)
91
- taxons.first ? prepare_taxon_conditions(taxons) : where(nil)
92
- end
93
-
94
- # a scope that finds all products having property specified by name, object or id
95
- add_search_scope :with_property do |property|
96
- joins(:properties).where(property_conditions(property))
97
- end
98
-
99
- # a simple test for product with a certain property-value pairing
100
- # note that it can test for properties with NULL values, but not for absent values
101
- add_search_scope :with_property_value do |property, value|
102
- joins(:properties).
103
- where("#{ProductProperty.table_name}.value = ?", value).
104
- where(property_conditions(property))
105
- end
106
-
107
- add_search_scope :with_option do |option|
108
- option_types = OptionType.table_name
109
- conditions = case option
110
- when String then { "#{option_types}.name" => option }
111
- when OptionType then { "#{option_types}.id" => option.id }
112
- else { "#{option_types}.id" => option.to_i }
113
- end
114
-
115
- joins(:option_types).where(conditions)
116
- end
117
-
118
- add_search_scope :with_option_value do |option, value|
119
- option_values = OptionValue.table_name
120
- option_type_id = case option
121
- when String then OptionType.find_by(name: option) || option.to_i
122
- when OptionType then option.id
123
- else option.to_i
124
- end
125
-
126
- conditions = "#{option_values}.name = ? AND #{option_values}.option_type_id = ?", value, option_type_id
127
- group('spree_products.id').joins(variants_including_master: :option_values).where(conditions)
128
- end
129
-
130
- # Finds all products which have either:
131
- # 1) have an option value with the name matching the one given
132
- # 2) have a product property with a value matching the one given
133
- add_search_scope :with do |value|
134
- includes(variants_including_master: :option_values).
135
- includes(:product_properties).
136
- where("#{OptionValue.table_name}.name = ? OR #{ProductProperty.table_name}.value = ?", value, value)
137
- end
138
-
139
- # Finds all products that have a name containing the given words.
140
- add_search_scope :in_name do |words|
141
- like_any([:name], prepare_words(words))
142
- end
143
-
144
- # Finds all products that have a name or meta_keywords containing the given words.
145
- add_search_scope :in_name_or_keywords do |words|
146
- like_any([:name, :meta_keywords], prepare_words(words))
147
- end
148
-
149
- # Finds all products that have a name, description, meta_description or meta_keywords containing the given keywords.
150
- add_search_scope :in_name_or_description do |words|
151
- like_any([:name, :description, :meta_description, :meta_keywords], prepare_words(words))
152
- end
153
-
154
- # Finds all products that have the ids matching the given collection of ids.
155
- # Alternatively, you could use find(collection_of_ids), but that would raise an exception if one product couldn't be found
156
- add_search_scope :with_ids do |*ids|
157
- where(id: ids)
158
- end
159
-
160
- # Sorts products from most popular (popularity is extracted from how many
161
- # times use has put product in cart, not completed orders)
162
- #
163
- # there is alternative faster and more elegant solution, it has small drawback though,
164
- # it doesn stack with other scopes :/
165
- #
166
- # joins: "LEFT OUTER JOIN (SELECT line_items.variant_id as vid, COUNT(*) as cnt FROM line_items GROUP BY line_items.variant_id) AS popularity_count ON variants.id = vid",
167
- # order: 'COALESCE(cnt, 0) DESC'
168
- add_search_scope :descend_by_popularity do
169
- joins(:master).
170
- order(%Q{
171
- COALESCE((
172
- SELECT
173
- COUNT(#{LineItem.quoted_table_name}.id)
174
- FROM
175
- #{LineItem.quoted_table_name}
176
- JOIN
177
- #{Variant.quoted_table_name} AS popular_variants
178
- ON
179
- popular_variants.id = #{LineItem.quoted_table_name}.variant_id
180
- WHERE
181
- popular_variants.product_id = #{Product.quoted_table_name}.id
182
- ), 0) DESC
183
- })
184
- end
185
-
186
- add_search_scope :not_deleted do
187
- where("#{Product.quoted_table_name}.deleted_at IS NULL or #{Product.quoted_table_name}.deleted_at >= ?", Time.zone.now)
188
- end
189
-
190
- def self.not_discontinued(only_not_discontinued = true)
191
- if only_not_discontinued != '0' && only_not_discontinued
192
- where("#{Product.quoted_table_name}.discontinue_on IS NULL or #{Product.quoted_table_name}.discontinue_on >= ?", Time.zone.now)
193
- else
194
- all
195
- end
196
- end
197
- search_scopes << :not_discontinued
198
- # Can't use add_search_scope for this as it needs a default argument
199
- def self.available(available_on = nil, _currency = nil)
200
- available_on ||= Time.current
201
- not_discontinued.joins(master: :prices).where("#{Product.quoted_table_name}.available_on <= ?", available_on)
202
- end
203
- search_scopes << :available
204
-
205
- def self.active(currency = nil)
206
- available(nil, currency)
207
- end
208
- search_scopes << :active
209
-
210
- add_search_scope :taxons_name_eq do |name|
211
- group('spree_products.id').joins(:taxons).where(Taxon.arel_table[:name].eq(name))
212
- end
213
-
214
- def self.price_table_name
215
- Price.quoted_table_name
216
- end
217
- private_class_method :price_table_name
218
-
219
- # specifically avoid having an order for taxon search (conflicts with main order)
220
- def self.prepare_taxon_conditions(taxons)
221
- ids = taxons.map { |taxon| taxon.self_and_descendants.pluck(:id) }.flatten.uniq
222
- joins(:classifications).where(Classification.table_name => { taxon_id: ids })
223
- end
224
- private_class_method :prepare_taxon_conditions
225
-
226
- # Produce an array of keywords for use in scopes.
227
- # Always return array with at least an empty string to avoid SQL errors
228
- def self.prepare_words(words)
229
- return [''] if words.blank?
230
-
231
- a = words.split(/[,\s]/).map(&:strip)
232
- a.any? ? a : ['']
233
- end
234
- private_class_method :prepare_words
235
-
236
- def self.get_taxons(*ids_or_records_or_names)
237
- taxons = Taxon.table_name
238
- ids_or_records_or_names.flatten.map do |t|
239
- case t
240
- when Integer then Taxon.find_by(id: t)
241
- when ApplicationRecord then t
242
- when String
243
- Taxon.find_by(name: t) ||
244
- Taxon.where("#{taxons}.permalink LIKE ? OR #{taxons}.permalink = ?", "%/#{t}/", "#{t}/").first
245
- end
246
- end.compact.flatten.uniq
247
- end
248
- private_class_method :get_taxons
249
- end
250
- end
@@ -1,4 +0,0 @@
1
- module Spree
2
- class Tag < ActsAsTaggableOn::Tag
3
- end
4
- end
@@ -1,27 +0,0 @@
1
- module Spree
2
- class TaxonImage < Asset
3
- module Configuration
4
- module Paperclip
5
- extend ActiveSupport::Concern
6
-
7
- included do
8
- def self.styles
9
- attachment_definitions[:attachment][:styles]
10
- end
11
-
12
- delegate :url, to: :attachment
13
-
14
- has_attached_file :attachment,
15
- styles: { mini: '32x32>', normal: '128x128>' },
16
- default_style: :mini,
17
- url: '/spree/taxons/:viewable_id/:style/:basename.:extension',
18
- path: ':rails_root/public/spree/taxons/:viewable_id/:style/:basename.:extension',
19
- default_url: '/assets/default_taxon.png'
20
-
21
- validates_attachment :attachment,
22
- content_type: { content_type: ['image/jpg', 'image/jpeg', 'image/png', 'image/gif'] }
23
- end
24
- end
25
- end
26
- end
27
- end
@@ -1,9 +0,0 @@
1
- require 'acts-as-taggable-on'
2
-
3
- ActsAsTaggableOn::Tag.class_eval do
4
- self.table_name_prefix = 'spree_'
5
- end
6
-
7
- ActsAsTaggableOn::Tagging.class_eval do
8
- self.table_name_prefix = 'spree_'
9
- end
@@ -1,3 +0,0 @@
1
- Rails.application.configure do
2
- config.use_paperclip = ActiveModel::Type::Boolean.new.cast ENV['SPREE_USE_PAPERCLIP']
3
- end
@@ -1,40 +0,0 @@
1
- class ActsAsTaggableOnSpreeMigration < ActiveRecord::Migration[4.2]
2
- def self.up
3
- create_table :spree_tags do |t|
4
- t.string :name
5
- t.integer :taggings_count, default: 0
6
- end
7
-
8
- create_table :spree_taggings do |t|
9
- t.references :tag
10
-
11
- # You should make sure that the column created is
12
- # long enough to store the required class names.
13
- t.references :taggable, polymorphic: true
14
- t.references :tagger, polymorphic: true
15
-
16
- # Limit is created to prevent MySQL error on index
17
- # length for MyISAM table type: http://bit.ly/vgW2Ql
18
- t.string :context, limit: 128
19
-
20
- t.datetime :created_at
21
- end
22
-
23
- add_index :spree_tags, :name, unique: true
24
- add_index :spree_taggings,
25
- [
26
- :tag_id,
27
- :taggable_id,
28
- :taggable_type,
29
- :context,
30
- :tagger_id,
31
- :tagger_type
32
- ],
33
- unique: true, name: "spree_taggings_idx"
34
- end
35
-
36
- def self.down
37
- drop_table :spree_taggings
38
- drop_table :spree_tags
39
- end
40
- end