spree_core 2.0.13 → 2.1.0

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 (149) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/spree/base_controller.rb +3 -0
  3. data/app/helpers/spree/base_helper.rb +6 -16
  4. data/app/helpers/spree/products_helper.rb +3 -8
  5. data/app/helpers/spree/taxons_helper.rb +1 -1
  6. data/app/mailers/spree/base_mailer.rb +0 -5
  7. data/app/models/spree/ability.rb +10 -7
  8. data/app/models/spree/address.rb +7 -17
  9. data/app/models/spree/adjustment.rb +15 -11
  10. data/app/models/spree/app_configuration.rb +0 -5
  11. data/app/models/spree/billing_integration.rb +0 -1
  12. data/app/models/spree/calculator/flat_percent_item_total.rb +1 -3
  13. data/app/models/spree/calculator/flat_rate.rb +2 -4
  14. data/app/models/spree/calculator/flexi_rate.rb +6 -9
  15. data/app/models/spree/calculator/per_item.rb +2 -4
  16. data/app/models/spree/calculator/percent_per_item.rb +1 -3
  17. data/app/models/spree/calculator/price_sack.rb +4 -9
  18. data/app/models/spree/calculator/shipping/flat_percent_item_total.rb +1 -2
  19. data/app/models/spree/calculator/shipping/flat_rate.rb +2 -4
  20. data/app/models/spree/calculator/shipping/flexi_rate.rb +4 -9
  21. data/app/models/spree/calculator/shipping/per_item.rb +2 -3
  22. data/app/models/spree/calculator/shipping/price_sack.rb +4 -9
  23. data/app/models/spree/classification.rb +0 -3
  24. data/app/models/spree/country.rb +1 -3
  25. data/app/models/spree/credit_card.rb +37 -38
  26. data/app/models/spree/gateway/bogus_simple.rb +0 -8
  27. data/app/models/spree/gateway.rb +1 -3
  28. data/app/models/spree/image.rb +1 -3
  29. data/app/models/spree/inventory_unit.rb +5 -8
  30. data/app/models/spree/legacy_user.rb +0 -4
  31. data/app/models/spree/line_item.rb +2 -15
  32. data/app/models/spree/option_type.rb +2 -5
  33. data/app/models/spree/option_value.rb +1 -3
  34. data/app/models/spree/order/checkout.rb +4 -13
  35. data/app/models/spree/order.rb +47 -99
  36. data/app/models/spree/order_contents.rb +4 -7
  37. data/app/models/spree/order_inventory.rb +4 -8
  38. data/app/models/spree/order_updater.rb +13 -12
  39. data/app/models/spree/payment/processing.rb +12 -19
  40. data/app/models/spree/payment.rb +17 -30
  41. data/app/models/spree/payment_method.rb +2 -3
  42. data/app/models/spree/preference.rb +1 -1
  43. data/app/models/spree/preferences/configuration.rb +1 -1
  44. data/app/models/spree/preferences/preferable.rb +1 -1
  45. data/app/models/spree/preferences/store.rb +1 -1
  46. data/app/models/spree/price.rb +0 -7
  47. data/app/models/spree/product/scopes.rb +16 -17
  48. data/app/models/spree/product.rb +27 -62
  49. data/app/models/spree/product_property.rb +3 -5
  50. data/app/models/spree/promotion/actions/create_adjustment.rb +9 -8
  51. data/app/models/spree/promotion/actions/create_line_items.rb +1 -2
  52. data/app/models/spree/promotion/rules/first_order.rb +1 -1
  53. data/app/models/spree/promotion/rules/item_total.rb +2 -4
  54. data/app/models/spree/promotion/rules/product.rb +2 -2
  55. data/app/models/spree/promotion/rules/user.rb +1 -3
  56. data/app/models/spree/promotion.rb +23 -24
  57. data/app/models/spree/promotion_action.rb +0 -2
  58. data/app/models/spree/promotion_action_line_item.rb +1 -3
  59. data/app/models/spree/promotion_rule.rb +0 -2
  60. data/app/models/spree/property.rb +2 -4
  61. data/app/models/spree/prototype.rb +0 -2
  62. data/app/models/spree/return_authorization.rb +6 -9
  63. data/app/models/spree/role.rb +0 -2
  64. data/app/models/spree/shipment.rb +19 -25
  65. data/app/models/spree/shipping_calculator.rb +0 -2
  66. data/app/models/spree/shipping_category.rb +0 -2
  67. data/app/models/spree/shipping_method.rb +6 -20
  68. data/app/models/spree/shipping_rate.rb +12 -10
  69. data/app/models/spree/state.rb +2 -4
  70. data/app/models/spree/stock/availability_validator.rb +2 -2
  71. data/app/models/spree/stock/estimator.rb +6 -20
  72. data/app/models/spree/stock/packer.rb +1 -1
  73. data/app/models/spree/stock/quantifier.rb +2 -3
  74. data/app/models/spree/stock/splitter/base.rb +1 -1
  75. data/app/models/spree/stock_item.rb +8 -18
  76. data/app/models/spree/stock_location.rb +2 -11
  77. data/app/models/spree/stock_movement.rb +2 -5
  78. data/app/models/spree/stock_transfer.rb +0 -2
  79. data/app/models/spree/tax_category.rb +0 -2
  80. data/app/models/spree/tax_rate.rb +12 -12
  81. data/app/models/spree/taxon.rb +1 -13
  82. data/app/models/spree/taxonomy.rb +3 -6
  83. data/app/models/spree/tracker.rb +0 -2
  84. data/app/models/spree/variant/scopes.rb +2 -2
  85. data/app/models/spree/variant.rb +13 -31
  86. data/app/models/spree/zone.rb +2 -7
  87. data/app/models/spree/zone_member.rb +0 -2
  88. data/app/views/spree/payments/_payment.html.erb +1 -3
  89. data/config/locales/en.yml +11 -26
  90. data/db/default/spree/countries.rb +230 -229
  91. data/db/default/spree/states.rb +57 -56
  92. data/db/default/spree/zones.rb +5 -5
  93. data/db/migrate/20130213191427_create_default_stock.rb +4 -7
  94. data/db/migrate/20130417120035_update_adjustment_states.rb +2 -2
  95. data/db/migrate/20130417123427_add_shipping_rates_to_shipments.rb +1 -1
  96. data/db/migrate/20130509115210_add_number_to_stock_transfer.rb +1 -1
  97. data/db/migrate/20130611054351_rename_shipping_methods_zones_to_spree_shipping_methods_zones.rb +0 -5
  98. data/db/migrate/20130611185927_add_user_id_index_to_spree_orders.rb +5 -0
  99. data/db/migrate/20130618041418_add_updated_at_to_spree_countries.rb +9 -0
  100. data/db/migrate/20130619012236_add_updated_at_to_spree_states.rb +9 -0
  101. data/db/migrate/20130802022321_migrate_tax_categories_to_line_items.rb +4 -5
  102. data/db/migrate/20130806145853_set_default_stock_location_on_shipments.rb +1 -1
  103. data/lib/generators/spree/dummy/dummy_generator.rb +3 -14
  104. data/lib/generators/spree/dummy/templates/rails/database.yml +0 -10
  105. data/lib/generators/spree/dummy/templates/rails/test.rb +2 -7
  106. data/lib/generators/spree/install/install_generator.rb +11 -8
  107. data/lib/spree/core/calculated_adjustments.rb +9 -8
  108. data/lib/spree/core/controller_helpers/auth.rb +2 -3
  109. data/lib/spree/core/controller_helpers/order.rb +8 -13
  110. data/lib/spree/core/controller_helpers/ssl.rb +13 -22
  111. data/lib/spree/core/controller_helpers/strong_parameters.rb +36 -0
  112. data/lib/spree/core/delegate_belongs_to.rb +0 -2
  113. data/lib/spree/core/engine.rb +1 -5
  114. data/lib/spree/core/ext/active_record.rb +2 -9
  115. data/lib/spree/core/permalinks.rb +1 -5
  116. data/lib/spree/core/product_duplicator.rb +2 -16
  117. data/lib/spree/core/product_filters.rb +37 -33
  118. data/lib/spree/core/search/base.rb +1 -1
  119. data/lib/spree/core/version.rb +1 -1
  120. data/lib/spree/core.rb +3 -31
  121. data/lib/spree/i18n.rb +0 -1
  122. data/lib/spree/money.rb +2 -177
  123. data/lib/spree/permitted_attributes.rb +95 -0
  124. data/lib/spree/promo/coupon_applicator.rb +4 -12
  125. data/lib/spree/testing_support/capybara_ext.rb +13 -17
  126. data/lib/spree/testing_support/common_rake.rb +1 -1
  127. data/lib/spree/testing_support/controller_requests.rb +3 -3
  128. data/lib/spree/testing_support/factories/credit_card_factory.rb +1 -1
  129. data/lib/spree/testing_support/factories/product_factory.rb +0 -4
  130. data/lib/spree/testing_support/factories/shipping_method_factory.rb +1 -3
  131. data/lib/spree/testing_support/factories/user_factory.rb +1 -1
  132. data/lib/spree/testing_support/factories/variant_factory.rb +0 -15
  133. data/lib/spree/testing_support/factories.rb +1 -1
  134. data/lib/spree/testing_support/order_walkthrough.rb +1 -1
  135. data/lib/tasks/core.rake +2 -2
  136. data/vendor/assets/javascripts/jquery.payment.js +497 -0
  137. metadata +166 -172
  138. data/app/views/spree/admin/shared/_report_order_criteria.html.erb +0 -17
  139. data/db/migrate/20130417120034_add_index_to_source_columns_on_adjustments.rb +0 -5
  140. data/db/migrate/20130830001033_add_shipping_category_to_shipping_methods_and_products.rb +0 -15
  141. data/db/migrate/20130830001159_migrate_old_shipping_calculators.rb +0 -19
  142. data/db/migrate/20130909115621_change_states_required_for_countries.rb +0 -9
  143. data/db/migrate/20131001013410_remove_unused_credit_card_fields.rb +0 -12
  144. data/db/migrate/20131026154747_add_track_inventory_to_variant.rb +0 -5
  145. data/db/migrate/20131113035136_add_channel_to_spree_orders.rb +0 -5
  146. data/db/migrate/20140120160805_add_index_to_variant_id_and_currency_on_prices.rb +0 -5
  147. data/db/migrate/20140205181631_default_variant_weight_to_zero.rb +0 -11
  148. data/db/migrate/20140415041315_add_user_id_created_by_id_index_to_order.rb +0 -5
  149. data/lib/spree/core/preference_rescue.rb +0 -25
@@ -3,50 +3,48 @@ module Spree
3
3
  has_many :payments, as: :source
4
4
 
5
5
  before_save :set_last_digits
6
- after_validation :set_card_type
7
6
 
8
7
  attr_accessor :number, :verification_value
9
8
 
10
- validates :month, :year, numericality: { only_integer: true }, unless: :has_payment_profile?
9
+ validates :month, :year, numericality: { only_integer: true }
11
10
  validates :number, presence: true, unless: :has_payment_profile?, on: :create
12
11
  validates :verification_value, presence: true, unless: :has_payment_profile?, on: :create
13
12
  validate :expiry_not_in_the_past
14
13
 
15
- attr_accessible :first_name, :last_name, :number, :verification_value, :year,
16
- :month, :gateway_customer_profile_id, :gateway_payment_profile_id
17
-
18
14
  scope :with_payment_profile, -> { where('gateway_customer_profile_id IS NOT NULL') }
19
15
 
20
- def set_last_digits
21
- number.to_s.gsub!(/\s/,'')
22
- verification_value.to_s.gsub!(/\s/,'')
23
- self.last_digits ||= number.to_s.length <= 4 ? number : number.to_s.slice(-4..-1)
16
+ # needed for some of the ActiveMerchant gateways (eg. SagePay)
17
+ alias_attribute :brand, :cc_type
18
+
19
+ def expiry=(expiry)
20
+ self[:month], self[:year] = expiry.split(" / ")
21
+ self[:year] = "20" + self[:year]
24
22
  end
25
23
 
26
- # cheap hack to get to the type? method from deep within ActiveMerchant
27
- # without stomping on potentially existing methods in CreditCard
28
- class CardDetector
29
- class << self
30
- include ActiveMerchant::Billing::CreditCardMethods::ClassMethods
31
- end
24
+ def number=(num)
25
+ @number = num.gsub(/[^0-9]/, '') rescue nil
32
26
  end
33
27
 
34
- # Some payment gateways, such as USA EPay, only support an ActiveMerchant::Billing::CreditCard
35
- # object, rather than an object *like* that. So we need to convert it.
36
- def to_active_merchant
37
- ActiveMerchant::Billing::CreditCard.new(
38
- :number => number,
39
- :month => month,
40
- :year => year,
41
- :verification_value => verification_value,
42
- :first_name => first_name,
43
- :last_name => last_name
44
- )
28
+ # cc_type is set by jquery.payment, which helpfully provides different
29
+ # types from Active Merchant. Converting them is necessary.
30
+ def cc_type=(type)
31
+ real_type = case type
32
+ when 'mastercard', 'maestro'
33
+ 'master'
34
+ when 'amex'
35
+ 'american_express'
36
+ when 'dinersclub'
37
+ 'diners_club'
38
+ else
39
+ type
40
+ end
41
+ self[:cc_type] = real_type
45
42
  end
46
43
 
47
- # sets self.cc_type while we still have the card number
48
- def set_card_type
49
- self.cc_type ||= CardDetector.brand?(number)
44
+ def set_last_digits
45
+ number.to_s.gsub!(/\s/,'')
46
+ verification_value.to_s.gsub!(/\s/,'')
47
+ self.last_digits ||= number.to_s.length <= 4 ? number : number.to_s.slice(-4..-1)
50
48
  end
51
49
 
52
50
  def name?
@@ -66,11 +64,6 @@ module Spree
66
64
  "XXXX-XXXX-XXXX-#{last_digits}"
67
65
  end
68
66
 
69
- # needed for some of the ActiveMerchant gateways (eg. SagePay)
70
- def brand
71
- spree_cc_type
72
- end
73
-
74
67
  def actions
75
68
  %w{capture void credit}
76
69
  end
@@ -94,12 +87,18 @@ module Spree
94
87
  end
95
88
 
96
89
  def has_payment_profile?
97
- gateway_customer_profile_id.present? || gateway_payment_profile_id.present?
90
+ gateway_customer_profile_id.present?
98
91
  end
99
92
 
100
- def spree_cc_type
101
- return 'visa' if Rails.env.development?
102
- cc_type
93
+ def to_active_merchant
94
+ ActiveMerchant::Billing::CreditCard.new(
95
+ :number => number,
96
+ :month => month,
97
+ :year => year,
98
+ :verification_value => verification_value,
99
+ :first_name => first_name,
100
+ :last_name => last_name
101
+ )
103
102
  end
104
103
 
105
104
  private
@@ -6,14 +6,6 @@ module Spree
6
6
  false
7
7
  end
8
8
 
9
- def capture(money, response_code, options = {})
10
- if response_code == '12345'
11
- ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, :test => true, :authorization => '67890')
12
- else
13
- ActiveMerchant::Billing::Response.new(false, 'Bogus Gateway: Forced failure', :error => 'Bogus Gateway: Forced failure', :test => true)
14
- end
15
- end
16
-
17
9
  def authorize(money, credit_card, options = {})
18
10
  if VALID_CCS.include? credit_card.number
19
11
  ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, :test => true, :authorization => '12345', :avs_result => { :code => 'A' })
@@ -1,14 +1,12 @@
1
1
  module Spree
2
2
  class Gateway < PaymentMethod
3
- delegate :authorize, :purchase, :capture, :void, :credit, to: :provider
3
+ delegate_belongs_to :provider, :authorize, :purchase, :capture, :void, :credit
4
4
 
5
5
  validates :name, :type, presence: true
6
6
 
7
7
  preference :server, :string, default: 'test'
8
8
  preference :test_mode, :boolean, default: true
9
9
 
10
- attr_accessible :preferred_server, :preferred_test_mode
11
-
12
10
  def payment_source_class
13
11
  CreditCard
14
12
  end
@@ -3,14 +3,12 @@ module Spree
3
3
  validates_attachment_presence :attachment
4
4
  validate :no_attachment_errors
5
5
 
6
- attr_accessible :alt, :attachment, :position, :viewable_type, :viewable_id
7
-
8
6
  has_attached_file :attachment,
9
7
  styles: { mini: '48x48>', small: '100x100>', product: '240x240>', large: '600x600>' },
10
8
  default_style: :product,
11
9
  url: '/spree/products/:id/:style/:basename.:extension',
12
10
  path: ':rails_root/public/spree/products/:id/:style/:basename.:extension',
13
- convert_options: { all: '-strip -auto-orient -colorspace sRGB' }
11
+ convert_options: { all: '-strip -auto-orient -colorspace RGB' }
14
12
 
15
13
  # save the w,h of the original image (from which others can be calculated)
16
14
  # we need to look at the write-queue for images which have not been saved yet
@@ -2,21 +2,18 @@ module Spree
2
2
  class InventoryUnit < ActiveRecord::Base
3
3
  belongs_to :variant, class_name: "Spree::Variant"
4
4
  belongs_to :order, class_name: "Spree::Order"
5
- belongs_to :shipment, class_name: "Spree::Shipment", touch: true
5
+ belongs_to :shipment, class_name: "Spree::Shipment"
6
6
  belongs_to :return_authorization, class_name: "Spree::ReturnAuthorization"
7
7
 
8
8
  scope :backordered, -> { where state: 'backordered' }
9
9
  scope :shipped, -> { where state: 'shipped' }
10
10
  scope :backordered_per_variant, ->(stock_item) do
11
- includes(:shipment, :order)
12
- .where("spree_shipments.state != 'canceled'")
11
+ includes(:shipment)
12
+ .where("spree_shipments.state != 'canceled'").references(:shipment)
13
13
  .where(variant_id: stock_item.variant_id)
14
- .where('spree_orders.completed_at is not null')
15
- .backordered.order("#{Spree::Order.quoted_table_name}.completed_at ASC")
14
+ .backordered.order("#{self.table_name}.created_at ASC")
16
15
  end
17
16
 
18
- attr_accessible :shipment, :variant_id
19
-
20
17
  # state machine (see http://github.com/pluginaweek/state_machine/tree/master for details)
21
18
  state_machine initial: :on_hand do
22
19
  event :fill_backorder do
@@ -37,7 +34,7 @@ module Spree
37
34
  # lead to issues once users tried to modify the objects returned. That's due
38
35
  # to ActiveRecord `joins(shipment: :stock_location)` only return readonly
39
36
  # objects
40
- #
37
+ #
41
38
  # Returns an array of backordered inventory units as per a given stock item
42
39
  def self.backordered_for_stock_item(stock_item)
43
40
  backordered_per_variant(stock_item).select do |unit|
@@ -2,14 +2,10 @@
2
2
  module Spree
3
3
  class LegacyUser < ActiveRecord::Base
4
4
  self.table_name = 'spree_users'
5
- attr_accessible :email, :password, :password_confirmation
6
-
7
5
  has_many :orders, foreign_key: :user_id
8
6
  belongs_to :ship_address, class_name: 'Spree::Address'
9
7
  belongs_to :bill_address, class_name: 'Spree::Address'
10
8
 
11
- scope :registered
12
-
13
9
  before_destroy :check_completed_orders
14
10
 
15
11
  class DestroyWithOrdersError < StandardError; end
@@ -20,14 +20,11 @@ module Spree
20
20
  validates :price, numericality: true
21
21
  validates_with Stock::AvailabilityValidator
22
22
 
23
- attr_accessible :quantity, :variant_id
23
+ before_save :update_inventory
24
24
 
25
- after_save :update_inventory
26
25
  after_save :update_order
27
26
  after_destroy :update_order
28
27
 
29
- delegate :name, :description, :should_track_inventory?, to: :variant
30
-
31
28
  attr_accessor :target_shipment
32
29
 
33
30
  def copy_price
@@ -44,16 +41,6 @@ module Spree
44
41
  end
45
42
  end
46
43
 
47
- def increment_quantity
48
- ActiveSupport::Deprecation.warn("[SPREE] Spree::LineItem#increment_quantity will be deprecated in Spree 2.1, please use quantity.increment! instead.")
49
- self.quantity.increment!
50
- end
51
-
52
- def decrement_quantity
53
- ActiveSupport::Deprecation.warn("[SPREE] Spree::LineItem#decrement_quantity will be deprecated in Spree 2.1, please use quantity.decrement! instead.")
54
- self.quantity.decrement!
55
- end
56
-
57
44
  def amount
58
45
  price * quantity
59
46
  end
@@ -75,7 +62,7 @@ module Spree
75
62
  end
76
63
 
77
64
  def sufficient_stock?
78
- Stock::Quantifier.new(variant).can_supply? quantity
65
+ Stock::Quantifier.new(variant_id).can_supply? quantity
79
66
  end
80
67
 
81
68
  def insufficient_stock?
@@ -1,14 +1,11 @@
1
1
  module Spree
2
2
  class OptionType < ActiveRecord::Base
3
- has_many :option_values, order: "#{Spree::OptionValue.quoted_table_name}.position", dependent: :destroy
3
+ has_many :option_values, -> { order(:position) }, dependent: :destroy
4
4
  has_many :product_option_types, dependent: :destroy
5
- has_many :products, through: :product_option_types
6
5
  has_and_belongs_to_many :prototypes, join_table: 'spree_option_types_prototypes'
7
6
 
8
- attr_accessible :name, :presentation, :option_values_attributes
9
-
10
7
  validates :name, :presentation, presence: true
11
- default_scope order: "#{quoted_table_name}.position"
8
+ default_scope -> { order("#{self.table_name}.position") }
12
9
 
13
10
  accepts_nested_attributes_for :option_values, reject_if: lambda { |ov| ov[:name].blank? || ov[:presentation].blank? }, allow_destroy: true
14
11
  end
@@ -1,11 +1,9 @@
1
1
  module Spree
2
2
  class OptionValue < ActiveRecord::Base
3
- belongs_to :option_type, :class_name => 'Spree::OptionType', :touch => true
3
+ belongs_to :option_type
4
4
  acts_as_list scope: :option_type
5
5
  has_and_belongs_to_many :variants, join_table: 'spree_option_values_variants', class_name: "Spree::Variant"
6
6
 
7
7
  validates :name, :presentation, presence: true
8
-
9
- attr_accessible :name, :presentation
10
8
  end
11
9
  end
@@ -56,7 +56,7 @@ module Spree
56
56
  end
57
57
 
58
58
  event :resume do
59
- transition :to => :resumed, :from => :canceled, :if => :canceled?
59
+ transition :to => :resumed, :from => :canceled, :if => :allow_resume?
60
60
  end
61
61
 
62
62
  event :authorize_return do
@@ -71,16 +71,11 @@ module Spree
71
71
 
72
72
  before_transition :from => :cart, :do => :ensure_line_items_present
73
73
 
74
- if states[:address]
75
- before_transition :from => :address, :do => :create_tax_charge!
76
- end
77
-
78
- if states[:delivery]
79
- before_transition :to => :delivery, :do => :create_proposed_shipments
80
- before_transition :to => :delivery, :do => :ensure_available_shipping_rates
81
- end
74
+ before_transition :to => :delivery, :do => :create_proposed_shipments
75
+ before_transition :to => :delivery, :do => :ensure_available_shipping_rates
82
76
 
83
77
  after_transition :to => :complete, :do => :finalize!
78
+ after_transition :to => :delivery, :do => :create_tax_charge!
84
79
  after_transition :to => :resumed, :do => :after_resume
85
80
  after_transition :to => :canceled, :do => :after_cancel
86
81
  end
@@ -150,10 +145,6 @@ module Spree
150
145
  @checkout_steps ||= {}
151
146
  end
152
147
 
153
- def self.checkout_step_names
154
- self.checkout_steps.keys
155
- end
156
-
157
148
  def self.add_transition(options)
158
149
  self.next_event_transitions << { options.delete(:from) => options.delete(:to) }.merge(options)
159
150
  end
@@ -3,15 +3,8 @@ require 'spree/order/checkout'
3
3
 
4
4
  module Spree
5
5
  class Order < ActiveRecord::Base
6
- # TODO:
7
- # Need to use fully qualified name here because during sandbox migration
8
- # there is a class called Checkout which conflicts if you use this:
9
- #
10
- # include Checkout
11
- #
12
- # rather than the qualified name. This will most likely be fixed with the
13
- # 1.3 release.
14
- include Spree::Order::Checkout
6
+ include Checkout
7
+
15
8
  checkout_flow do
16
9
  go_to_state :address
17
10
  go_to_state :delivery
@@ -26,11 +19,6 @@ module Spree
26
19
 
27
20
  token_resource
28
21
 
29
- attr_accessible :line_items, :bill_address_attributes, :ship_address_attributes,
30
- :payments_attributes, :ship_address, :bill_address, :currency,
31
- :line_items_attributes, :number, :email, :use_billing,
32
- :special_instructions, :shipments_attributes, :coupon_code
33
-
34
22
  attr_reader :coupon_code
35
23
 
36
24
  if Spree.user_class
@@ -47,15 +35,14 @@ module Spree
47
35
  belongs_to :ship_address, foreign_key: :ship_address_id, class_name: 'Spree::Address'
48
36
  alias_attribute :shipping_address, :ship_address
49
37
 
50
- has_many :adjustments, as: :adjustable, dependent: :destroy, order: "#{::Spree::Adjustment.quoted_table_name}.created_at ASC"
51
- has_many :line_item_adjustments, through: :line_items, source: :adjustments
52
- has_many :line_items, dependent: :destroy, order: "#{::Spree::LineItem.quoted_table_name}.created_at ASC"
38
+ has_many :state_changes, as: :stateful
39
+ has_many :line_items, -> { order('created_at ASC') }, dependent: :destroy
53
40
  has_many :payments, dependent: :destroy
54
41
  has_many :return_authorizations, dependent: :destroy
55
- has_many :state_changes, as: :stateful
56
- has_many :inventory_units
42
+ has_many :adjustments, -> { order("#{Adjustment.table_name}.created_at ASC") }, as: :adjustable, dependent: :destroy
43
+ has_many :line_item_adjustments, through: :line_items, source: :adjustments
57
44
 
58
- has_many :shipments, dependent: :destroy, :class_name => "Shipment" do
45
+ has_many :shipments, dependent: :destroy do
59
46
  def states
60
47
  pluck(:state).uniq
61
48
  end
@@ -78,7 +65,6 @@ module Spree
78
65
 
79
66
  validates :email, presence: true, if: :require_email
80
67
  validates :email, email: true, if: :require_email, allow_blank: true
81
- validates :number, uniqueness: true
82
68
  validate :has_available_shipment
83
69
  validate :has_available_payment
84
70
 
@@ -91,16 +77,12 @@ module Spree
91
77
  where(number: number)
92
78
  end
93
79
 
94
- scope :created_between, ->(start_date, end_date) { where(created_at: start_date..end_date) }
95
- scope :completed_between, ->(start_date, end_date) { where(completed_at: start_date..end_date) }
96
-
97
80
  def self.between(start_date, end_date)
98
- ActiveSupport::Deprecation.warn("Order#between will be deprecated in Spree 2.3, please use either Order#created_between or Order#completed_between instead.")
99
- self.created_between(start_date, end_date)
81
+ where(created_at: start_date..end_date)
100
82
  end
101
83
 
102
84
  def self.by_customer(customer)
103
- joins(:user).where("#{Spree.user_class.quoted_table_name}.email" => customer)
85
+ joins(:user).where("#{Spree.user_class.table_name}.email" => customer)
104
86
  end
105
87
 
106
88
  def self.by_state(state)
@@ -108,7 +90,7 @@ module Spree
108
90
  end
109
91
 
110
92
  def self.complete
111
- where("#{quoted_table_name}.completed_at IS NOT NULL")
93
+ where('completed_at IS NOT NULL')
112
94
  end
113
95
 
114
96
  def self.incomplete
@@ -159,7 +141,7 @@ module Spree
159
141
  end
160
142
 
161
143
  def completed?
162
- completed_at.present? || complete?
144
+ completed_at.present?
163
145
  end
164
146
 
165
147
  # Indicates whether or not the user is allowed to proceed to checkout.
@@ -177,12 +159,7 @@ module Spree
177
159
 
178
160
  # If true, causes the confirmation step to happen during the checkout process
179
161
  def confirmation_required?
180
- Spree::Config[:always_include_confirm_step] ||
181
- payments.valid.map(&:payment_method).compact.any?(&:payment_profiles_supported?) ||
182
- # Little hacky fix for #4117
183
- # If this wasn't here, order would transition to address state on confirm failure
184
- # because there would be no valid payments any more.
185
- state == 'confirm'
162
+ payments.map(&:payment_method).compact.any?(&:payment_profiles_supported?)
186
163
  end
187
164
 
188
165
  # Indicates the number of items in the order
@@ -197,8 +174,7 @@ module Spree
197
174
  # Returns the relevant zone (if any) to be used for taxation purposes.
198
175
  # Uses default tax zone unless there is a specific match
199
176
  def tax_zone
200
- zone_address = Spree::Config[:tax_using_ship_address] ? ship_address : bill_address
201
- Zone.match(zone_address) || Zone.default_tax
177
+ Zone.match(tax_address) || Zone.default_tax
202
178
  end
203
179
 
204
180
  # Indicates whether tax should be backed out of the price calcualtions in
@@ -209,9 +185,9 @@ module Spree
209
185
  return tax_zone != Zone.default_tax
210
186
  end
211
187
 
212
- def price_adjustments
213
- ActiveSupport::Deprecation.warn("Order#price_adjustments will be deprecated in Spree 2.1, please use Order#line_item_adjustments instead.")
214
- self.line_item_adjustments
188
+ # Returns the address for taxation based on configuration
189
+ def tax_address
190
+ Spree::Config[:tax_using_ship_address] ? ship_address : bill_address
215
191
  end
216
192
 
217
193
  # Array of totals grouped by Adjustment#label. Useful for displaying line item
@@ -224,11 +200,6 @@ module Spree
224
200
  end]
225
201
  end
226
202
 
227
- def price_adjustment_totals
228
- ActiveSupport::Deprecation.warn("Order#price_adjustment_totals will be deprecated in Spree 2.1, please use Order#line_item_adjustment_totals instead.")
229
- self.line_item_adjustment_totals
230
- end
231
-
232
203
  def updater
233
204
  @updater ||= OrderUpdater.new(self)
234
205
  end
@@ -255,6 +226,13 @@ module Spree
255
226
  shipment_state.nil? || %w{ready backorder pending}.include?(shipment_state)
256
227
  end
257
228
 
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
+
258
236
  def awaiting_returns?
259
237
  return_authorizations.any? { |return_authorization| return_authorization.authorized? }
260
238
  end
@@ -263,18 +241,6 @@ module Spree
263
241
  @contents ||= Spree::OrderContents.new(self)
264
242
  end
265
243
 
266
- def add_variant(variant, quantity = 1, currency = nil)
267
- ActiveSupport::Deprecation.warn("[SPREE] Spree::Order#add_variant will be deprecated in Spree 2.1, please use order.contents.add instead.")
268
- contents.currency = currency unless currency.nil?
269
- contents.add(variant, quantity)
270
- end
271
-
272
-
273
- def remove_variant(variant, quantity = 1)
274
- ActiveSupport::Deprecation.warn("[SPREE] Spree::Order#remove_variant will be deprecated in Spree 2.1, please use order.contents.remove instead.")
275
- contents.remove(variant, quantity)
276
- end
277
-
278
244
  # Associates the specified user with the order.
279
245
  def associate_user!(user)
280
246
  self.user = user
@@ -287,16 +253,15 @@ module Spree
287
253
  end
288
254
  end
289
255
 
256
+ # FIXME refactor this method and implement validation using validates_* utilities
290
257
  def generate_order_number
291
- self.number ||= loop do
258
+ record = true
259
+ while record
292
260
  random = "R#{Array.new(9){rand(9)}.join}"
293
- break random unless self.class.exists?(number: random)
261
+ record = self.class.where(number: random).first
294
262
  end
295
- end
296
-
297
- def shipment
298
- ActiveSupport::Deprecation.warn("[SPREE] Spree::Order#shipment is typically incorrect due to multiple shipments and will be deprecated in Spree 2.1, please process Spree::Order#shipments instead.")
299
- @shipment ||= shipments.last
263
+ self.number = random if self.number.blank?
264
+ self.number
300
265
  end
301
266
 
302
267
  def shipped_shipments
@@ -324,12 +289,6 @@ module Spree
324
289
  adjustments.tax.map(&:amount).sum
325
290
  end
326
291
 
327
- # Clear shipment when transitioning to delivery step of checkout if the
328
- # current shipping address is not eligible for the existing shipping method
329
- def remove_invalid_shipments!
330
- shipments.each { |s| s.destroy unless s.shipping_method.available_to_order?(self) }
331
- end
332
-
333
292
  # Creates new tax charges if there are any applicable rates. If prices already
334
293
  # include taxes then price adjustments are created instead.
335
294
  def create_tax_charge!
@@ -356,7 +315,7 @@ module Spree
356
315
 
357
316
  def credit_cards
358
317
  credit_card_ids = payments.from_credit_card.pluck(:source_id).uniq
359
- CreditCard.scoped(conditions: { id: credit_card_ids })
318
+ CreditCard.where(id: credit_card_ids)
360
319
  end
361
320
 
362
321
  # Finalizes an in progress order after checkout is complete.
@@ -380,12 +339,12 @@ module Spree
380
339
 
381
340
  deliver_order_confirmation_email
382
341
 
383
- self.state_changes.create({
342
+ self.state_changes.create(
384
343
  previous_state: 'cart',
385
344
  next_state: 'complete',
386
345
  name: 'order' ,
387
346
  user_id: self.user_id
388
- }, without_protection: true)
347
+ )
389
348
  end
390
349
 
391
350
  def deliver_order_confirmation_email
@@ -403,7 +362,7 @@ module Spree
403
362
  end
404
363
 
405
364
  def available_payment_methods
406
- @available_payment_methods ||= (PaymentMethod.available(:front_end) + PaymentMethod.available(:both)).uniq
365
+ @available_payment_methods ||= PaymentMethod.available(:front_end)
407
366
  end
408
367
 
409
368
  def pending_payments
@@ -459,13 +418,13 @@ module Spree
459
418
  end
460
419
 
461
420
  def insufficient_stock_lines
462
- line_items.select(&:insufficient_stock?)
421
+ line_items.select &:insufficient_stock?
463
422
  end
464
423
 
465
- def merge!(order, user = nil)
424
+ def merge!(order)
466
425
  order.line_items.each do |line_item|
467
426
  next unless line_item.currency == currency
468
- current_line_item = self.line_items.find_by_variant_id(line_item.variant_id)
427
+ current_line_item = self.line_items.find_by(variant: line_item.variant)
469
428
  if current_line_item
470
429
  current_line_item.quantity += line_item.quantity
471
430
  current_line_item.save
@@ -474,17 +433,14 @@ module Spree
474
433
  line_item.save
475
434
  end
476
435
  end
477
-
478
- self.associate_user!(user) if !self.user && !user.blank?
479
-
480
436
  # So that the destroy doesn't take out line items which may have been re-assigned
481
437
  order.line_items.reload
482
438
  order.destroy
483
439
  end
484
440
 
485
441
  def empty!
486
- adjustments.destroy_all
487
442
  line_items.destroy_all
443
+ adjustments.destroy_all
488
444
  end
489
445
 
490
446
  def clear_adjustments!
@@ -500,15 +456,12 @@ module Spree
500
456
  state = "#{name}_state"
501
457
  if persisted?
502
458
  old_state = self.send("#{state}_was")
503
- new_state = self.send(state)
504
- unless old_state == new_state
505
- self.state_changes.create({
506
- previous_state: old_state,
507
- next_state: new_state,
508
- name: name,
509
- user_id: self.user_id
510
- }, :without_protection => true)
511
- end
459
+ self.state_changes.create(
460
+ previous_state: old_state,
461
+ next_state: self.send(state),
462
+ name: name,
463
+ user_id: self.user_id
464
+ )
512
465
  end
513
466
  end
514
467
 
@@ -550,7 +503,7 @@ module Spree
550
503
  #
551
504
  # At some point the might need to force the order to transition from address
552
505
  # to delivery again so that proper updated shipments are created.
553
- # e.g. customer goes back from payment step and changes order items
506
+ # e.g. customer goes back from payment step and changes order items
554
507
  def ensure_updated_shipments
555
508
  if shipments.any?
556
509
  self.shipments.destroy_all
@@ -570,7 +523,7 @@ module Spree
570
523
 
571
524
  # Determine if email is required (we don't want validation errors before we hit the checkout)
572
525
  def require_email
573
- return true unless new_record? or ['cart', 'address'].include?(state)
526
+ return true unless new_record? or state == 'cart'
574
527
  end
575
528
 
576
529
  def ensure_line_items_present
@@ -593,20 +546,15 @@ module Spree
593
546
  end
594
547
 
595
548
  def has_available_payment
596
- return unless has_step?("delivery") && delivery?
549
+ return unless delivery?
597
550
  # errors.add(:base, :no_payment_methods_available) if available_payment_methods.empty?
598
551
  end
599
552
 
600
553
  def after_cancel
601
554
  shipments.each { |shipment| shipment.cancel! }
602
- payments.completed.each { |payment| payment.cancel! }
603
-
604
- send_cancel_email
605
- self.update_column(:payment_state, 'credit_owed') unless shipped?
606
- end
607
555
 
608
- def send_cancel_email
609
556
  OrderMailer.cancel_email(self.id).deliver
557
+ self.payment_state = 'credit_owed' unless shipped?
610
558
  end
611
559
 
612
560
  def after_resume