spree_core 2.0.13 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/spree/base_controller.rb +3 -0
- data/app/helpers/spree/base_helper.rb +6 -16
- data/app/helpers/spree/products_helper.rb +3 -8
- data/app/helpers/spree/taxons_helper.rb +1 -1
- data/app/mailers/spree/base_mailer.rb +0 -5
- data/app/models/spree/ability.rb +10 -7
- data/app/models/spree/address.rb +7 -17
- data/app/models/spree/adjustment.rb +15 -11
- data/app/models/spree/app_configuration.rb +0 -5
- data/app/models/spree/billing_integration.rb +0 -1
- data/app/models/spree/calculator/flat_percent_item_total.rb +1 -3
- data/app/models/spree/calculator/flat_rate.rb +2 -4
- data/app/models/spree/calculator/flexi_rate.rb +6 -9
- data/app/models/spree/calculator/per_item.rb +2 -4
- data/app/models/spree/calculator/percent_per_item.rb +1 -3
- data/app/models/spree/calculator/price_sack.rb +4 -9
- data/app/models/spree/calculator/shipping/flat_percent_item_total.rb +1 -2
- data/app/models/spree/calculator/shipping/flat_rate.rb +2 -4
- data/app/models/spree/calculator/shipping/flexi_rate.rb +4 -9
- data/app/models/spree/calculator/shipping/per_item.rb +2 -3
- data/app/models/spree/calculator/shipping/price_sack.rb +4 -9
- data/app/models/spree/classification.rb +0 -3
- data/app/models/spree/country.rb +1 -3
- data/app/models/spree/credit_card.rb +37 -38
- data/app/models/spree/gateway/bogus_simple.rb +0 -8
- data/app/models/spree/gateway.rb +1 -3
- data/app/models/spree/image.rb +1 -3
- data/app/models/spree/inventory_unit.rb +5 -8
- data/app/models/spree/legacy_user.rb +0 -4
- data/app/models/spree/line_item.rb +2 -15
- data/app/models/spree/option_type.rb +2 -5
- data/app/models/spree/option_value.rb +1 -3
- data/app/models/spree/order/checkout.rb +4 -13
- data/app/models/spree/order.rb +47 -99
- data/app/models/spree/order_contents.rb +4 -7
- data/app/models/spree/order_inventory.rb +4 -8
- data/app/models/spree/order_updater.rb +13 -12
- data/app/models/spree/payment/processing.rb +12 -19
- data/app/models/spree/payment.rb +17 -30
- data/app/models/spree/payment_method.rb +2 -3
- data/app/models/spree/preference.rb +1 -1
- data/app/models/spree/preferences/configuration.rb +1 -1
- data/app/models/spree/preferences/preferable.rb +1 -1
- data/app/models/spree/preferences/store.rb +1 -1
- data/app/models/spree/price.rb +0 -7
- data/app/models/spree/product/scopes.rb +16 -17
- data/app/models/spree/product.rb +27 -62
- data/app/models/spree/product_property.rb +3 -5
- data/app/models/spree/promotion/actions/create_adjustment.rb +9 -8
- data/app/models/spree/promotion/actions/create_line_items.rb +1 -2
- data/app/models/spree/promotion/rules/first_order.rb +1 -1
- data/app/models/spree/promotion/rules/item_total.rb +2 -4
- data/app/models/spree/promotion/rules/product.rb +2 -2
- data/app/models/spree/promotion/rules/user.rb +1 -3
- data/app/models/spree/promotion.rb +23 -24
- data/app/models/spree/promotion_action.rb +0 -2
- data/app/models/spree/promotion_action_line_item.rb +1 -3
- data/app/models/spree/promotion_rule.rb +0 -2
- data/app/models/spree/property.rb +2 -4
- data/app/models/spree/prototype.rb +0 -2
- data/app/models/spree/return_authorization.rb +6 -9
- data/app/models/spree/role.rb +0 -2
- data/app/models/spree/shipment.rb +19 -25
- data/app/models/spree/shipping_calculator.rb +0 -2
- data/app/models/spree/shipping_category.rb +0 -2
- data/app/models/spree/shipping_method.rb +6 -20
- data/app/models/spree/shipping_rate.rb +12 -10
- data/app/models/spree/state.rb +2 -4
- data/app/models/spree/stock/availability_validator.rb +2 -2
- data/app/models/spree/stock/estimator.rb +6 -20
- data/app/models/spree/stock/packer.rb +1 -1
- data/app/models/spree/stock/quantifier.rb +2 -3
- data/app/models/spree/stock/splitter/base.rb +1 -1
- data/app/models/spree/stock_item.rb +8 -18
- data/app/models/spree/stock_location.rb +2 -11
- data/app/models/spree/stock_movement.rb +2 -5
- data/app/models/spree/stock_transfer.rb +0 -2
- data/app/models/spree/tax_category.rb +0 -2
- data/app/models/spree/tax_rate.rb +12 -12
- data/app/models/spree/taxon.rb +1 -13
- data/app/models/spree/taxonomy.rb +3 -6
- data/app/models/spree/tracker.rb +0 -2
- data/app/models/spree/variant/scopes.rb +2 -2
- data/app/models/spree/variant.rb +13 -31
- data/app/models/spree/zone.rb +2 -7
- data/app/models/spree/zone_member.rb +0 -2
- data/app/views/spree/payments/_payment.html.erb +1 -3
- data/config/locales/en.yml +11 -26
- data/db/default/spree/countries.rb +230 -229
- data/db/default/spree/states.rb +57 -56
- data/db/default/spree/zones.rb +5 -5
- data/db/migrate/20130213191427_create_default_stock.rb +4 -7
- data/db/migrate/20130417120035_update_adjustment_states.rb +2 -2
- data/db/migrate/20130417123427_add_shipping_rates_to_shipments.rb +1 -1
- data/db/migrate/20130509115210_add_number_to_stock_transfer.rb +1 -1
- data/db/migrate/20130611054351_rename_shipping_methods_zones_to_spree_shipping_methods_zones.rb +0 -5
- data/db/migrate/20130611185927_add_user_id_index_to_spree_orders.rb +5 -0
- data/db/migrate/20130618041418_add_updated_at_to_spree_countries.rb +9 -0
- data/db/migrate/20130619012236_add_updated_at_to_spree_states.rb +9 -0
- data/db/migrate/20130802022321_migrate_tax_categories_to_line_items.rb +4 -5
- data/db/migrate/20130806145853_set_default_stock_location_on_shipments.rb +1 -1
- data/lib/generators/spree/dummy/dummy_generator.rb +3 -14
- data/lib/generators/spree/dummy/templates/rails/database.yml +0 -10
- data/lib/generators/spree/dummy/templates/rails/test.rb +2 -7
- data/lib/generators/spree/install/install_generator.rb +11 -8
- data/lib/spree/core/calculated_adjustments.rb +9 -8
- data/lib/spree/core/controller_helpers/auth.rb +2 -3
- data/lib/spree/core/controller_helpers/order.rb +8 -13
- data/lib/spree/core/controller_helpers/ssl.rb +13 -22
- data/lib/spree/core/controller_helpers/strong_parameters.rb +36 -0
- data/lib/spree/core/delegate_belongs_to.rb +0 -2
- data/lib/spree/core/engine.rb +1 -5
- data/lib/spree/core/ext/active_record.rb +2 -9
- data/lib/spree/core/permalinks.rb +1 -5
- data/lib/spree/core/product_duplicator.rb +2 -16
- data/lib/spree/core/product_filters.rb +37 -33
- data/lib/spree/core/search/base.rb +1 -1
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/core.rb +3 -31
- data/lib/spree/i18n.rb +0 -1
- data/lib/spree/money.rb +2 -177
- data/lib/spree/permitted_attributes.rb +95 -0
- data/lib/spree/promo/coupon_applicator.rb +4 -12
- data/lib/spree/testing_support/capybara_ext.rb +13 -17
- data/lib/spree/testing_support/common_rake.rb +1 -1
- data/lib/spree/testing_support/controller_requests.rb +3 -3
- data/lib/spree/testing_support/factories/credit_card_factory.rb +1 -1
- data/lib/spree/testing_support/factories/product_factory.rb +0 -4
- data/lib/spree/testing_support/factories/shipping_method_factory.rb +1 -3
- data/lib/spree/testing_support/factories/user_factory.rb +1 -1
- data/lib/spree/testing_support/factories/variant_factory.rb +0 -15
- data/lib/spree/testing_support/factories.rb +1 -1
- data/lib/spree/testing_support/order_walkthrough.rb +1 -1
- data/lib/tasks/core.rake +2 -2
- data/vendor/assets/javascripts/jquery.payment.js +497 -0
- metadata +166 -172
- data/app/views/spree/admin/shared/_report_order_criteria.html.erb +0 -17
- data/db/migrate/20130417120034_add_index_to_source_columns_on_adjustments.rb +0 -5
- data/db/migrate/20130830001033_add_shipping_category_to_shipping_methods_and_products.rb +0 -15
- data/db/migrate/20130830001159_migrate_old_shipping_calculators.rb +0 -19
- data/db/migrate/20130909115621_change_states_required_for_countries.rb +0 -9
- data/db/migrate/20131001013410_remove_unused_credit_card_fields.rb +0 -12
- data/db/migrate/20131026154747_add_track_inventory_to_variant.rb +0 -5
- data/db/migrate/20131113035136_add_channel_to_spree_orders.rb +0 -5
- data/db/migrate/20140120160805_add_index_to_variant_id_and_currency_on_prices.rb +0 -5
- data/db/migrate/20140205181631_default_variant_weight_to_zero.rb +0 -11
- data/db/migrate/20140415041315_add_user_id_created_by_id_index_to_order.rb +0 -5
- 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 }
|
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
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
-
|
27
|
-
|
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
|
-
#
|
35
|
-
#
|
36
|
-
def
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
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
|
-
|
48
|
-
|
49
|
-
|
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?
|
90
|
+
gateway_customer_profile_id.present?
|
98
91
|
end
|
99
92
|
|
100
|
-
def
|
101
|
-
|
102
|
-
|
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' })
|
data/app/models/spree/gateway.rb
CHANGED
@@ -1,14 +1,12 @@
|
|
1
1
|
module Spree
|
2
2
|
class Gateway < PaymentMethod
|
3
|
-
|
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
|
data/app/models/spree/image.rb
CHANGED
@@ -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
|
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"
|
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
|
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
|
-
.
|
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
|
-
|
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(
|
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:
|
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
|
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
|
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 => :
|
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
|
-
|
75
|
-
|
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
|
data/app/models/spree/order.rb
CHANGED
@@ -3,15 +3,8 @@ require 'spree/order/checkout'
|
|
3
3
|
|
4
4
|
module Spree
|
5
5
|
class Order < ActiveRecord::Base
|
6
|
-
|
7
|
-
|
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 :
|
51
|
-
has_many :
|
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 :
|
56
|
-
has_many :
|
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
|
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
|
-
|
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.
|
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(
|
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?
|
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
|
-
|
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
|
-
|
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
|
-
|
213
|
-
|
214
|
-
|
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
|
-
|
258
|
+
record = true
|
259
|
+
while record
|
292
260
|
random = "R#{Array.new(9){rand(9)}.join}"
|
293
|
-
|
261
|
+
record = self.class.where(number: random).first
|
294
262
|
end
|
295
|
-
|
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.
|
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
|
-
|
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 ||=
|
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
|
-
|
421
|
+
line_items.select &:insufficient_stock?
|
463
422
|
end
|
464
423
|
|
465
|
-
def merge!(order
|
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.
|
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
|
-
|
504
|
-
|
505
|
-
self.
|
506
|
-
|
507
|
-
|
508
|
-
|
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
|
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
|
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
|