spree_core 2.1.1 → 2.1.2

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