spree_core 3.7.14.1 → 4.0.0.beta

Sign up to get free protection for your applications and to get access to all the features.
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