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.
- 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
|