spree_core 2.1.1 → 2.1.2

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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/spree/base_controller.rb +1 -2
  3. data/app/helpers/spree/products_helper.rb +8 -3
  4. data/app/mailers/spree/base_mailer.rb +5 -0
  5. data/app/models/spree/ability.rb +0 -3
  6. data/app/models/spree/adjustment.rb +2 -1
  7. data/app/models/spree/app_configuration.rb +2 -0
  8. data/app/models/spree/classification.rb +3 -0
  9. data/app/models/spree/country.rb +2 -1
  10. data/app/models/spree/image.rb +1 -1
  11. data/app/models/spree/line_item.rb +2 -0
  12. data/app/models/spree/order.rb +33 -16
  13. data/app/models/spree/order/checkout.rb +1 -1
  14. data/app/models/spree/payment.rb +14 -2
  15. data/app/models/spree/payment/processing.rb +3 -3
  16. data/app/models/spree/preferences/configuration.rb +5 -1
  17. data/app/models/spree/preferences/preferable.rb +5 -1
  18. data/app/models/spree/preferences/store.rb +14 -15
  19. data/app/models/spree/product.rb +4 -3
  20. data/app/models/spree/product/scopes.rb +7 -14
  21. data/app/models/spree/return_authorization.rb +3 -6
  22. data/app/models/spree/shipment.rb +4 -1
  23. data/app/models/spree/state.rb +1 -0
  24. data/app/models/spree/stock/availability_validator.rb +1 -1
  25. data/app/models/spree/stock/estimator.rb +26 -26
  26. data/app/models/spree/stock/quantifier.rb +1 -1
  27. data/app/models/spree/stock_item.rb +11 -7
  28. data/app/models/spree/variant.rb +4 -3
  29. data/config/locales/en.yml +8 -2
  30. data/config/routes.rb +1 -0
  31. data/db/default/spree/countries.rb +26 -26
  32. data/db/migrate/20130213191427_create_default_stock.rb +5 -2
  33. data/db/migrate/20130830001033_add_shipping_category_to_shipping_methods_and_products.rb +15 -0
  34. data/db/migrate/20130830001159_migrate_old_shipping_calculators.rb +19 -0
  35. data/db/migrate/20130909115621_change_states_required_for_countries.rb +9 -0
  36. data/db/migrate/20131001013410_remove_unused_credit_card_fields.rb +12 -0
  37. data/lib/spree/core/controller_helpers/order.rb +1 -1
  38. data/lib/spree/core/controller_helpers/ssl.rb +22 -13
  39. data/lib/spree/core/engine.rb +2 -10
  40. data/lib/spree/core/permalinks.rb +1 -5
  41. data/lib/spree/core/preference_rescue.rb +25 -0
  42. data/lib/spree/core/product_filters.rb +34 -38
  43. data/lib/spree/core/routes.rb +48 -0
  44. data/lib/spree/core/version.rb +1 -1
  45. data/lib/spree/money.rb +4 -0
  46. data/lib/spree/permitted_attributes.rb +1 -1
  47. data/lib/spree/testing_support/factories/credit_card_factory.rb +1 -1
  48. metadata +15 -9
  49. data/app/views/spree/shared/_address.html.erb +0 -38
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 48dc9ada13cae9de3d32bcb9c76e95872dfdfcd2
4
- data.tar.gz: 665071b4c805498e9c03d4a02f4a3b7af84f7b3a
3
+ metadata.gz: 3ab1a9b77dfdfc7b40bb62c108eadc067ea71124
4
+ data.tar.gz: c2183c55225bf1d1d23c06e61807ee0c08690c39
5
5
  SHA512:
6
- metadata.gz: ede3b69166c6172c17786e982aa34b5b983178fc4f83e43eaa4acd5306ea70ae895d1cdbb3861997ef2154df22b0afcb4b801e6ba02cd5df7cddec61cad03d07
7
- data.tar.gz: 57c30112d37519af4a1ee58d07dc63a4bb3a61456b1ee27e88c9d02aa13165e300c5bae4a61051d2bfe718f13635e97d759f31f106179d6b4ccda086b8628158
6
+ metadata.gz: 723eadefb8438e4953836ff989f6c95e12b2c5b4a677e38b2402994c58e346886f45c7c7389b888a9ad1fafc0bdf60d1d7788982df9296fbf9a155e929053f59
7
+ data.tar.gz: 664c6401e80f75ecac438efc557ac374578b933f5c453a439e075a8a9046b0c65abf9dcecfcfa1a8d0167a6d818f2f711273af5b5d108fd01991df6ac7f42994
@@ -8,9 +8,8 @@ class Spree::BaseController < ApplicationController
8
8
  include Spree::Core::ControllerHelpers::Common
9
9
  include Spree::Core::ControllerHelpers::Search
10
10
  include Spree::Core::ControllerHelpers::StrongParameters
11
- include Spree::Core::ControllerHelpers::Search
12
11
 
13
12
  respond_to :html
14
13
  end
15
14
 
16
- require 'spree/i18n/initializer'
15
+ require 'spree/i18n/initializer'
@@ -40,9 +40,14 @@ module Spree
40
40
  end
41
41
 
42
42
  def line_item_description(variant)
43
- description = variant.product.description
44
- if description.present?
45
- truncate(strip_tags(description.gsub('&nbsp;', ' ')), length: 100)
43
+ ActiveSupport::Deprecation.warn "line_item_description(variant) is deprecated and may be removed from future releases, use line_item_description_text(line_item.description) instead.", caller
44
+
45
+ line_item_description_text(variant.product.description)
46
+ end
47
+
48
+ def line_item_description_text description_text
49
+ if description_text.present?
50
+ truncate(strip_tags(description_text.gsub('&nbsp;', ' ')), length: 100)
46
51
  else
47
52
  Spree.t(:product_has_no_description)
48
53
  end
@@ -8,5 +8,10 @@ module Spree
8
8
  Spree::Money.new(amount).to_s
9
9
  end
10
10
  helper_method :money
11
+
12
+ def mail(headers={}, &block)
13
+ super if Spree::Config[:send_core_emails]
14
+ end
15
+
11
16
  end
12
17
  end
@@ -53,9 +53,6 @@ module Spree
53
53
  can :create, Spree.user_class
54
54
  can [:read, :update, :destroy], Spree.user_class, id: user.id
55
55
  can [:index, :read], State
56
- can [:index, :read], StockItem
57
- can [:index, :read], StockLocation
58
- can [:index, :read], StockMovement
59
56
  can [:index, :read], Taxon
60
57
  can [:index, :read], Taxonomy
61
58
  can [:index, :read], Variant
@@ -56,6 +56,7 @@ module Spree
56
56
  scope :charge, -> { where('amount >= 0') }
57
57
  scope :credit, -> { where('amount < 0') }
58
58
  scope :promotion, -> { where(originator_type: 'Spree::PromotionAction') }
59
+ scope :manual, -> { where(originator_type: nil) }
59
60
  scope :return_authorization, -> { where(source_type: "Spree::ReturnAuthorization") }
60
61
 
61
62
  def promotion?
@@ -85,7 +86,7 @@ module Spree
85
86
  # are not recalculated.
86
87
  #
87
88
  # It receives +calculable+ as the updated source here so calculations can be
88
- # performed on the current values of that source. If we used +source+ it
89
+ # performed on the current values of that source. If we used +source+ it
89
90
  # could load the old record from db for the association. e.g. when updating
90
91
  # more than on line items at once via accepted_nested_attributes the order
91
92
  # object on the association would be in a old state and therefore the
@@ -32,6 +32,7 @@ module Spree
32
32
  preference :allow_ssl_in_staging, :boolean, default: true
33
33
  preference :alternative_billing_phone, :boolean, default: false # Request extra phone for bill addr
34
34
  preference :alternative_shipping_phone, :boolean, default: false # Request extra phone for ship addr
35
+ preference :always_include_confirm_step, :boolean, default: false # Ensures confirmation step is always in checkout_progress bar, but does not force a confirm step if your payment methods do not support it.
35
36
  preference :always_put_site_name_in_title, :boolean, default: true
36
37
  preference :auto_capture, :boolean, default: false # automatically capture the credit card (as opposed to just authorize and capture later)
37
38
  preference :check_for_spree_alerts, :boolean, default: true
@@ -84,6 +85,7 @@ module Spree
84
85
 
85
86
  # Default mail headers settings
86
87
  preference :enable_mail_delivery, :boolean, :default => false
88
+ preference :send_core_emails, :boolean, :default => true
87
89
  preference :mails_from, :string, :default => 'spree@example.com'
88
90
  preference :mail_bcc, :string, :default => 'spree@example.com'
89
91
  preference :intercept_email, :string, :default => nil
@@ -3,5 +3,8 @@ module Spree
3
3
  self.table_name = 'spree_products_taxons'
4
4
  belongs_to :product, class_name: "Spree::Product"
5
5
  belongs_to :taxon, class_name: "Spree::Taxon"
6
+
7
+ # For #3494
8
+ validates_uniqueness_of :taxon_id, :scope => :product_id, :message => :already_linked
6
9
  end
7
10
  end
@@ -1,6 +1,7 @@
1
1
  module Spree
2
2
  class Country < ActiveRecord::Base
3
- has_many :states, -> { order('name ASC') }
3
+ has_many :states, -> { order('name ASC') }, dependent: :destroy
4
+ has_many :addresses, dependent: :nullify
4
5
 
5
6
  validates :name, :iso_name, presence: true
6
7
 
@@ -8,7 +8,7 @@ module Spree
8
8
  default_style: :product,
9
9
  url: '/spree/products/:id/:style/:basename.:extension',
10
10
  path: ':rails_root/public/spree/products/:id/:style/:basename.:extension',
11
- convert_options: { all: '-strip -auto-orient -colorspace RGB' }
11
+ convert_options: { all: '-strip -auto-orient -colorspace sRGB' }
12
12
 
13
13
  # save the w,h of the original image (from which others can be calculated)
14
14
  # we need to look at the write-queue for images which have not been saved yet
@@ -25,6 +25,8 @@ module Spree
25
25
  after_save :update_order
26
26
  after_destroy :update_order
27
27
 
28
+ delegate :name, :description, to: :variant
29
+
28
30
  attr_accessor :target_shipment
29
31
 
30
32
  def copy_price
@@ -41,6 +41,7 @@ module Spree
41
41
  has_many :return_authorizations, dependent: :destroy
42
42
  has_many :adjustments, -> { order("#{Adjustment.table_name}.created_at ASC") }, as: :adjustable, dependent: :destroy
43
43
  has_many :line_item_adjustments, through: :line_items, source: :adjustments
44
+ has_many :inventory_units
44
45
 
45
46
  has_many :shipments, dependent: :destroy do
46
47
  def states
@@ -141,7 +142,7 @@ module Spree
141
142
  end
142
143
 
143
144
  def completed?
144
- completed_at.present?
145
+ completed_at.present? || complete?
145
146
  end
146
147
 
147
148
  # Indicates whether or not the user is allowed to proceed to checkout.
@@ -159,7 +160,11 @@ module Spree
159
160
 
160
161
  # If true, causes the confirmation step to happen during the checkout process
161
162
  def confirmation_required?
162
- payments.map(&:payment_method).compact.any?(&:payment_profiles_supported?)
163
+ if payments.empty? and Spree::Config[:always_include_confirm_step]
164
+ true
165
+ else
166
+ payments.map(&:payment_method).compact.any?(&:payment_profiles_supported?)
167
+ end
163
168
  end
164
169
 
165
170
  # Indicates the number of items in the order
@@ -226,13 +231,6 @@ module Spree
226
231
  shipment_state.nil? || %w{ready backorder pending}.include?(shipment_state)
227
232
  end
228
233
 
229
- def allow_resume?
230
- # we shouldn't allow resume for legacy orders b/c we lack the information
231
- # necessary to restore to a previous state
232
- return false if state_changes.empty? || state_changes.last.previous_state.nil?
233
- true
234
- end
235
-
236
234
  def awaiting_returns?
237
235
  return_authorizations.any? { |return_authorization| return_authorization.authorized? }
238
236
  end
@@ -282,11 +280,11 @@ module Spree
282
280
  end
283
281
 
284
282
  def ship_total
285
- adjustments.shipping.map(&:amount).sum
283
+ adjustments.shipping.sum(:amount)
286
284
  end
287
285
 
288
286
  def tax_total
289
- adjustments.tax.map(&:amount).sum
287
+ adjustments.tax.sum(:amount)
290
288
  end
291
289
 
292
290
  # Creates new tax charges if there are any applicable rates. If prices already
@@ -421,7 +419,7 @@ module Spree
421
419
  line_items.select &:insufficient_stock?
422
420
  end
423
421
 
424
- def merge!(order)
422
+ def merge!(order, user = nil)
425
423
  order.line_items.each do |line_item|
426
424
  next unless line_item.currency == currency
427
425
  current_line_item = self.line_items.find_by(variant: line_item.variant)
@@ -433,14 +431,17 @@ module Spree
433
431
  line_item.save
434
432
  end
435
433
  end
434
+
435
+ self.associate_user!(user) if !self.user && !user.blank?
436
+
436
437
  # So that the destroy doesn't take out line items which may have been re-assigned
437
438
  order.line_items.reload
438
439
  order.destroy
439
440
  end
440
441
 
441
442
  def empty!
442
- line_items.destroy_all
443
443
  adjustments.destroy_all
444
+ line_items.destroy_all
444
445
  end
445
446
 
446
447
  def clear_adjustments!
@@ -480,7 +481,15 @@ module Spree
480
481
  end
481
482
 
482
483
  def promo_total
483
- adjustments.eligible.promotion.map(&:amount).sum
484
+ adjustments.eligible.promotion.sum(:amount)
485
+ end
486
+
487
+ def manual_adjustment_total
488
+ adjustments.eligible.manual.sum(:amount)
489
+ end
490
+
491
+ def discount_total
492
+ promo_total + manual_adjustment_total
484
493
  end
485
494
 
486
495
  def shipped?
@@ -503,7 +512,7 @@ module Spree
503
512
  #
504
513
  # At some point the might need to force the order to transition from address
505
514
  # to delivery again so that proper updated shipments are created.
506
- # e.g. customer goes back from payment step and changes order items
515
+ # e.g. customer goes back from payment step and changes order items
507
516
  def ensure_updated_shipments
508
517
  if shipments.any?
509
518
  self.shipments.destroy_all
@@ -515,6 +524,10 @@ module Spree
515
524
  shipments.map &:refresh_rates
516
525
  end
517
526
 
527
+ def shipping_eq_billing_address?
528
+ (bill_address.empty? && ship_address.empty?) || bill_address.same_as?(ship_address)
529
+ end
530
+
518
531
  private
519
532
 
520
533
  def link_by_email
@@ -553,10 +566,14 @@ module Spree
553
566
  def after_cancel
554
567
  shipments.each { |shipment| shipment.cancel! }
555
568
 
556
- OrderMailer.cancel_email(self.id).deliver
569
+ send_cancel_email
557
570
  self.payment_state = 'credit_owed' unless shipped?
558
571
  end
559
572
 
573
+ def send_cancel_email
574
+ OrderMailer.cancel_email(self.id).deliver
575
+ end
576
+
560
577
  def after_resume
561
578
  shipments.each { |shipment| shipment.resume! }
562
579
  end
@@ -56,7 +56,7 @@ module Spree
56
56
  end
57
57
 
58
58
  event :resume do
59
- transition :to => :resumed, :from => :canceled, :if => :allow_resume?
59
+ transition :to => :resumed, :from => :canceled, :if => :canceled?
60
60
  end
61
61
 
62
62
  event :authorize_return do
@@ -13,7 +13,7 @@ module Spree
13
13
  has_many :log_entries, as: :source
14
14
 
15
15
  before_validation :validate_source
16
- before_save :set_unique_identifier
16
+ before_create :set_unique_identifier
17
17
 
18
18
  after_save :create_payment_profile, if: :profiles_supported?
19
19
 
@@ -34,10 +34,12 @@ module Spree
34
34
 
35
35
  after_rollback :persist_invalid
36
36
 
37
+ validates :amount, numericality: true
38
+
37
39
  def persist_invalid
38
40
  return unless ['failed', 'invalid'].include?(state)
39
41
  state_will_change!
40
- save
42
+ save
41
43
  end
42
44
 
43
45
  # order state machine (see http://github.com/pluginaweek/state_machine/tree/master for details)
@@ -76,6 +78,16 @@ module Spree
76
78
  end
77
79
  alias display_amount money
78
80
 
81
+ def amount=(amount)
82
+ self[:amount] =
83
+ case amount
84
+ when String
85
+ separator = I18n.t('number.currency.format.separator')
86
+ number = amount.delete("^0-9-#{separator}").tr(separator, '.')
87
+ number.to_d if number.present?
88
+ end || amount
89
+ end
90
+
79
91
  def offsets_total
80
92
  offsets.pluck(:amount).sum
81
93
  end
@@ -93,7 +93,7 @@ module Spree
93
93
  record_response(response)
94
94
 
95
95
  if response.success?
96
- self.class.create(
96
+ self.class.create!(
97
97
  :order => order,
98
98
  :source => self,
99
99
  :payment_method => payment_method,
@@ -126,7 +126,7 @@ module Spree
126
126
  options.merge!({ :shipping => order.ship_total * 100,
127
127
  :tax => order.tax_total * 100,
128
128
  :subtotal => order.item_total * 100,
129
- :discount => order.promo_total * 100,
129
+ :discount => order.discount_total * 100,
130
130
  :currency => currency })
131
131
 
132
132
  options.merge!({ :billing_address => order.bill_address.try(:active_merchant_hash),
@@ -169,7 +169,7 @@ module Spree
169
169
  end
170
170
 
171
171
  def record_response(response)
172
- log_entries.create(:details => response.to_yaml)
172
+ log_entries.create!(:details => response.to_yaml)
173
173
  end
174
174
 
175
175
  def protect_from_connection_error
@@ -29,7 +29,11 @@ module Spree::Preferences
29
29
  end
30
30
 
31
31
  def preference_cache_key(name)
32
- [ENV['RAILS_CACHE_ID'], self.class.name, name].flatten.join('::').underscore
32
+ [rails_cache_id, self.class.name, name].compact.join('::').underscore
33
+ end
34
+
35
+ def rails_cache_id
36
+ ENV['RAILS_CACHE_ID']
33
37
  end
34
38
 
35
39
  def reset
@@ -78,7 +78,11 @@ module Spree::Preferences::Preferable
78
78
 
79
79
  def preference_cache_key(name)
80
80
  return unless id
81
- [ENV["RAILS_CACHE_ID"], self.class.name, name, id].join('::').underscore
81
+ [rails_cache_id, self.class.name, name, id].compact.join('::').underscore
82
+ end
83
+
84
+ def rails_cache_id
85
+ ENV['RAILS_CACHE_ID']
82
86
  end
83
87
 
84
88
  def save_pending_preferences
@@ -39,23 +39,22 @@ module Spree::Preferences
39
39
  # has been cleared from the cache
40
40
 
41
41
  # does it exist in the database?
42
- if Spree::Preference.table_exists? && preference = Spree::Preference.find_by_key(key)
43
- # it does exist, so let's put it back into the cache
44
- @cache.write(preference.key, preference.value)
45
-
46
- # and return the value
47
- return preference.value
42
+ if preference = Spree::Preference.find_by_key(key)
43
+ # it does exist
44
+ val = preference.value
45
+ else
46
+ # use the fallback value
47
+ val = fallback
48
48
  end
49
- end
50
49
 
51
- unless fallback.nil?
52
- # cache fallback so we won't hit the db above on
53
- # subsequent queries for the same key
54
- #
55
- @cache.write(key, fallback)
56
- end
50
+ # Cache either the value from the db or the fallback value.
51
+ # This avoids hitting the db with subsequent queries.
52
+ @cache.write(key, val)
57
53
 
58
- return fallback
54
+ return val
55
+ else
56
+ return fallback
57
+ end
59
58
  end
60
59
 
61
60
  def delete(key)
@@ -86,7 +85,7 @@ module Spree::Preferences
86
85
  end
87
86
 
88
87
  def should_persist?
89
- @persistence && Spree::Preference.connected? && Spree::Preference.table_exists?
88
+ @persistence and Spree::Preference.table_exists?
90
89
  end
91
90
 
92
91
  end
@@ -49,10 +49,11 @@ module Spree
49
49
 
50
50
  has_many :prices, -> { order('spree_variants.position, spree_variants.id, currency') }, through: :variants
51
51
 
52
- has_many :stock_items, through: :variants
52
+ has_many :stock_items, through: :variants_including_master
53
53
 
54
54
  delegate_belongs_to :master, :sku, :price, :currency, :display_amount, :display_price, :weight, :height, :width, :depth, :is_master, :has_default_price?, :cost_currency, :price_in, :amount_in
55
- delegate_belongs_to :master, :cost_price if Variant.table_exists? && Variant.column_names.include?('cost_price')
55
+
56
+ delegate_belongs_to :master, :cost_price
56
57
 
57
58
  after_create :set_master_variant_defaults
58
59
  after_create :add_properties_and_option_types_from_prototype
@@ -233,7 +234,7 @@ module Spree
233
234
  # there's a weird quirk with the delegate stuff that does not automatically save the delegate object
234
235
  # when saving so we force a save using a hook.
235
236
  def save_master
236
- master.save if master && (master.changed? || master.new_record? || (master.default_price && (master.default_price.changed || master.default_price.new_record)))
237
+ master.save if master && (master.changed? || master.new_record? || (master.default_price && (master.default_price.changed? || master.default_price.new_record?)))
237
238
  end
238
239
 
239
240
  def ensure_master