spree_core 2.1.12 → 2.2.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/helpers/spree/base_helper.rb +4 -7
- data/app/helpers/spree/products_helper.rb +11 -9
- data/app/helpers/spree/store_helper.rb +5 -0
- data/app/models/spree/ability.rb +4 -0
- data/app/models/spree/address.rb +6 -6
- data/app/models/spree/adjustment.rb +40 -61
- data/app/models/spree/app_configuration.rb +1 -14
- data/app/models/spree/calculator.rb +12 -4
- data/app/models/spree/calculator/default_tax.rb +42 -38
- data/app/models/spree/calculator/flat_percent_item_total.rb +2 -4
- data/app/models/spree/calculator/free_shipping.rb +5 -2
- data/app/models/spree/calculator/percent_on_line_item.rb +15 -0
- data/app/models/spree/calculator/percent_per_item.rb +3 -0
- data/app/models/spree/classification.rb +3 -2
- data/app/models/spree/credit_card.rb +7 -25
- data/app/models/spree/gateway/bogus.rb +5 -5
- data/app/models/spree/gateway/bogus_simple.rb +0 -8
- data/app/models/spree/image.rb +0 -9
- data/app/models/spree/inventory_unit.rb +10 -4
- data/app/models/spree/item_adjustments.rb +65 -0
- data/app/models/spree/legacy_user.rb +1 -0
- data/app/models/spree/line_item.rb +33 -13
- data/app/models/spree/option_type.rb +2 -2
- data/app/models/spree/option_value.rb +1 -1
- data/app/models/spree/order.rb +109 -89
- data/app/models/spree/order/checkout.rb +48 -0
- data/app/models/spree/order_contents.rb +72 -37
- data/app/models/spree/order_inventory.rb +65 -68
- data/app/models/spree/order_populator.rb +3 -17
- data/app/models/spree/order_updater.rb +63 -44
- data/app/models/spree/payment.rb +20 -5
- data/app/models/spree/payment/processing.rb +19 -25
- data/app/models/spree/payment_capture_event.rb +9 -0
- data/app/models/spree/payment_method/check.rb +0 -2
- data/app/models/spree/price.rb +1 -1
- data/app/models/spree/product.rb +14 -16
- data/app/models/spree/product/scopes.rb +4 -6
- data/app/models/spree/product_option_type.rb +2 -2
- data/app/models/spree/product_property.rb +2 -2
- data/app/models/spree/promotion.rb +71 -50
- data/app/models/spree/promotion/actions/create_adjustment.rb +31 -32
- data/app/models/spree/promotion/actions/create_item_adjustments.rb +83 -0
- data/app/models/spree/promotion/actions/free_shipping.rb +36 -0
- data/app/models/spree/promotion/rules/first_order.rb +4 -0
- data/app/models/spree/promotion/rules/item_total.rb +5 -1
- data/app/models/spree/promotion/rules/product.rb +4 -0
- data/app/models/spree/promotion/rules/user.rb +5 -6
- data/app/models/spree/promotion/rules/user_logged_in.rb +4 -0
- data/app/models/spree/promotion_action.rb +1 -5
- data/app/models/spree/promotion_handler/cart.rb +38 -0
- data/app/models/spree/promotion_handler/coupon.rb +76 -0
- data/app/models/spree/promotion_handler/free_shipping.rb +31 -0
- data/app/models/spree/promotion_handler/page.rb +24 -0
- data/app/models/spree/promotion_rule.rb +15 -7
- data/app/models/spree/property.rb +1 -1
- data/app/models/spree/return_authorization.rb +7 -1
- data/app/models/spree/shipment.rb +113 -49
- data/app/models/spree/shipping_calculator.rb +4 -5
- data/app/models/spree/shipping_category.rb +2 -2
- data/app/models/spree/shipping_method.rb +12 -6
- data/app/models/spree/shipping_rate.rb +27 -7
- data/app/models/spree/stock/availability_validator.rb +1 -1
- data/app/models/spree/stock/estimator.rb +13 -1
- data/app/models/spree/stock/package.rb +11 -7
- data/app/models/spree/stock/packer.rb +3 -3
- data/app/models/spree/stock/quantifier.rb +9 -1
- data/app/models/spree/stock_item.rb +11 -6
- data/app/models/spree/stock_movement.rb +1 -2
- data/app/models/spree/tax_category.rb +6 -1
- data/app/models/spree/tax_rate.rb +57 -49
- data/app/models/spree/taxon.rb +10 -5
- data/app/models/spree/taxonomy.rb +5 -2
- data/app/models/spree/variant.rb +33 -16
- data/app/models/spree/zone.rb +24 -24
- data/app/views/spree/shared/_routes.html.erb +3 -0
- data/config/locales/en.yml +42 -26
- data/db/migrate/20130213191427_create_default_stock.rb +3 -3
- data/db/migrate/20130413230529_add_name_to_spree_credit_cards.rb +5 -0
- data/db/migrate/20130414000512_update_name_fields_on_spree_credit_cards.rb +13 -0
- 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/20130802022321_migrate_tax_categories_to_line_items.rb +7 -5
- data/db/migrate/20130807024301_upgrade_adjustments.rb +39 -0
- data/db/migrate/20130807024302_rename_adjustment_fields.rb +17 -0
- data/db/migrate/20130813004002_add_shipment_total_to_spree_orders.rb +5 -0
- data/db/migrate/20130813232134_rename_activators_to_promotions.rb +5 -0
- data/db/migrate/20130815000406_add_adjustment_total_to_line_items.rb +5 -0
- data/db/migrate/20130815024413_add_adjustment_total_to_shipments.rb +5 -0
- data/db/migrate/20130828234942_add_tax_total_to_line_items_shipments_and_orders.rb +8 -0
- data/db/migrate/20130830001159_migrate_old_shipping_calculators.rb +1 -1
- data/db/migrate/20130903183026_add_code_to_spree_promotion_rules.rb +5 -0
- data/db/migrate/20130917024658_remove_promotions_event_name_field.rb +5 -0
- data/db/migrate/20130924040529_add_promo_total_to_line_items_and_shipments_and_orders.rb +7 -0
- data/db/migrate/20131001013410_remove_unused_credit_card_fields.rb +7 -3
- data/db/migrate/20131107132123_add_tax_category_to_variants.rb +6 -0
- data/db/migrate/20131118043959_add_included_to_adjustments.rb +5 -0
- data/db/migrate/20131118050234_rename_tax_total_fields.rb +11 -0
- data/db/migrate/20131118183431_add_line_item_id_to_spree_inventory_units.rb +21 -0
- data/db/migrate/20131127001002_add_position_to_classifications.rb +5 -0
- data/db/migrate/20131211112807_create_spree_orders_promotions.rb +8 -0
- data/db/migrate/20131218054603_add_item_count_to_spree_orders.rb +5 -0
- data/db/migrate/20140106224208_rename_permalink_to_slug_for_products.rb +5 -0
- data/db/migrate/20140124023232_rename_activator_id_in_rules_and_actions_to_promotion_id.rb +6 -0
- data/db/migrate/20140203161722_add_approver_id_and_approved_at_to_orders.rb +6 -0
- data/db/migrate/20140204115338_add_confirmation_delivered_to_spree_orders.rb +5 -0
- data/db/migrate/20140205120320_create_spree_payment_capture_events.rb +12 -0
- data/db/migrate/20140205144710_add_uncaptured_amount_to_payments.rb +5 -0
- data/db/migrate/20140207085910_add_tax_category_id_to_shipping_methods.rb +5 -0
- data/db/migrate/20140207093021_add_tax_rate_id_to_shipping_rates.rb +5 -0
- data/db/migrate/20140211040159_add_pre_tax_amount_to_line_items_and_shipments.rb +6 -0
- data/db/migrate/20140213184916_add_more_indexes.rb +13 -0
- data/db/migrate/20140219060952_add_considered_risky_to_orders.rb +5 -0
- data/lib/generators/spree/dummy/dummy_generator.rb +1 -6
- data/lib/generators/spree/install/install_generator.rb +6 -6
- data/lib/generators/spree/install/templates/{app/assets/javascripts/admin → vendor/assets/javascripts/spree/backend}/all.js +3 -3
- data/lib/generators/spree/install/templates/{app/assets/javascripts/store → vendor/assets/javascripts/spree/frontend}/all.js +3 -3
- data/lib/generators/spree/install/templates/{app/assets/stylesheets/store → vendor/assets/stylesheets/spree/backend}/all.css +3 -3
- data/lib/generators/spree/install/templates/{app/assets/stylesheets/admin → vendor/assets/stylesheets/spree/frontend}/all.css +3 -3
- data/lib/spree/core.rb +21 -8
- data/lib/spree/core/calculated_adjustments.rb +0 -40
- data/lib/spree/core/controller_helpers.rb +5 -0
- data/lib/spree/core/controller_helpers/auth.rb +2 -2
- data/lib/spree/core/controller_helpers/common.rb +0 -5
- data/lib/spree/core/controller_helpers/order.rb +8 -9
- data/lib/spree/core/engine.rb +10 -17
- data/lib/spree/core/permalinks.rb +1 -1
- data/lib/spree/core/product_duplicator.rb +3 -8
- data/lib/spree/core/user_address.rb +1 -1
- data/lib/spree/core/validators/email.rb +23 -1
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/money.rb +1 -1
- data/lib/spree/permitted_attributes.rb +2 -2
- data/lib/spree/testing_support/caching.rb +47 -0
- data/lib/spree/testing_support/factories/adjustment_factory.rb +11 -2
- data/lib/spree/testing_support/factories/credit_card_factory.rb +2 -1
- data/lib/spree/testing_support/factories/order_factory.rb +10 -5
- data/lib/spree/testing_support/factories/payment_factory.rb +2 -2
- data/lib/spree/testing_support/factories/payment_method_factory.rb +3 -3
- data/lib/spree/testing_support/factories/promotion_factory.rb +16 -1
- data/lib/spree/testing_support/factories/shipment_factory.rb +8 -4
- data/lib/spree/testing_support/factories/shipping_method_factory.rb +1 -3
- data/lib/spree/testing_support/factories/stock_factory.rb +1 -1
- data/lib/spree/testing_support/factories/tax_rate_factory.rb +2 -2
- data/lib/spree/testing_support/order_walkthrough.rb +1 -1
- data/lib/tasks/core.rake +2 -2
- data/vendor/assets/fonts/FontAwesome.otf +0 -0
- data/vendor/assets/fonts/fontawesome-webfont.eot +0 -0
- data/vendor/assets/fonts/fontawesome-webfont.svg +399 -0
- data/vendor/assets/fonts/fontawesome-webfont.ttf +0 -0
- data/vendor/assets/fonts/fontawesome-webfont.woff +0 -0
- data/vendor/assets/stylesheets/font-awesome.scss +1475 -0
- metadata +73 -44
- data/app/assets/javascripts/admin/handlebar_extensions.js +0 -9
- data/app/helpers/spree/admin/adjustments_helper.rb +0 -26
- data/app/helpers/spree/admin/images_helper.rb +0 -18
- data/app/helpers/spree/promotion_rules_helper.rb +0 -13
- data/app/models/spree/activator.rb +0 -29
- data/app/models/spree/calculator/per_item.rb +0 -41
- data/app/models/spree/stock/remaining_packer.rb +0 -22
- data/app/views/spree/payments/_payment.html.erb +0 -18
- data/db/migrate/20131118041203_add_tax_total_to_spree_orders.rb +0 -5
- data/db/migrate/20131118043021_add_order_id_to_spree_adjustments.rb +0 -6
- data/db/migrate/20131118074808_add_included_to_spree_adjustments.rb +0 -5
- data/db/migrate/20140415041315_add_user_id_created_by_id_index_to_order.rb +0 -5
- data/lib/spree/core/gateway_error.rb +0 -5
- data/lib/spree/core/preference_rescue.rb +0 -25
- data/lib/spree/core/s3_support.rb +0 -25
- data/lib/spree/promo/coupon_applicator.rb +0 -71
- data/lib/spree/testing_support/factories/activator_factory.rb +0 -8
@@ -1,3 +1,7 @@
|
|
1
|
+
# TODO: Deprecate this class.
|
2
|
+
# This calculator will be removed in future versions of Spree.
|
3
|
+
# The only case where it was used was for Free Shipping Promotions.
|
4
|
+
# There is now a Promotion Action which deals with these types of promotions instead.
|
1
5
|
module Spree
|
2
6
|
class Calculator::FreeShipping < Calculator
|
3
7
|
def self.description
|
@@ -15,5 +19,4 @@ module Spree
|
|
15
19
|
order.ship_total
|
16
20
|
end
|
17
21
|
end
|
18
|
-
end
|
19
|
-
|
22
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Spree
|
2
|
+
class Calculator
|
3
|
+
class PercentOnLineItem < Calculator
|
4
|
+
preference :percent, :decimal, default: 0
|
5
|
+
|
6
|
+
def self.description
|
7
|
+
Spree.t(:percent_per_item)
|
8
|
+
end
|
9
|
+
|
10
|
+
def compute(object)
|
11
|
+
((object.price * object.quantity) * preferred_percent) / 100
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -4,6 +4,9 @@ module Spree
|
|
4
4
|
# for all matching products in an order. This should not be used as a
|
5
5
|
# shipping calculator since it would be the same thing as a flat percent
|
6
6
|
# off the entire order.
|
7
|
+
#
|
8
|
+
#
|
9
|
+
# TODO Should be deprecated now that we have adjustments at the line item level in spree core
|
7
10
|
|
8
11
|
class Calculator::PercentPerItem < Calculator
|
9
12
|
preference :percent, :decimal, default: 0
|
@@ -1,8 +1,9 @@
|
|
1
1
|
module Spree
|
2
2
|
class Classification < ActiveRecord::Base
|
3
3
|
self.table_name = 'spree_products_taxons'
|
4
|
-
|
5
|
-
belongs_to :
|
4
|
+
acts_as_list
|
5
|
+
belongs_to :product, class_name: "Spree::Product", inverse_of: :classifications
|
6
|
+
belongs_to :taxon, class_name: "Spree::Taxon", inverse_of: :classifications
|
6
7
|
|
7
8
|
# For #3494
|
8
9
|
validates_uniqueness_of :taxon_id, :scope => :product_id, :message => :already_linked
|
@@ -8,6 +8,7 @@ module Spree
|
|
8
8
|
|
9
9
|
validates :month, :year, numericality: { only_integer: true }, unless: :has_payment_profile?
|
10
10
|
validates :number, presence: true, unless: :has_payment_profile?, on: :create
|
11
|
+
validates :name, presence: true
|
11
12
|
validates :verification_value, presence: true, unless: :has_payment_profile?, on: :create
|
12
13
|
validate :expiry_not_in_the_past
|
13
14
|
|
@@ -26,19 +27,12 @@ module Spree
|
|
26
27
|
}
|
27
28
|
|
28
29
|
def expiry=(expiry)
|
29
|
-
|
30
|
-
|
31
|
-
self[:month], self[:year] =
|
32
|
-
if expiry.match(/\d\s?\/\s?\d/) # will match mm/yy and mm / yyyy
|
33
|
-
expiry.delete(' ').split('/')
|
34
|
-
elsif match = expiry.match(/(\d{2})(\d{2,4})/) # will match mmyy and mmyyyy
|
35
|
-
[match[1], match[2]]
|
36
|
-
end
|
37
|
-
if self[:year]
|
30
|
+
if expiry.present?
|
31
|
+
self[:month], self[:year] = expiry.delete(' ').split('/')
|
38
32
|
self[:year] = "20" + self[:year] if self[:year].length == 2
|
39
33
|
self[:year] = self[:year].to_i
|
34
|
+
self[:month] = self[:month].to_i
|
40
35
|
end
|
41
|
-
self[:month] = self[:month].to_i
|
42
36
|
end
|
43
37
|
|
44
38
|
def number=(num)
|
@@ -68,14 +62,6 @@ module Spree
|
|
68
62
|
CARD_TYPES.find{|type, pattern| return type.to_s if numbers =~ pattern}.to_s
|
69
63
|
end
|
70
64
|
|
71
|
-
def name?
|
72
|
-
first_name? && last_name?
|
73
|
-
end
|
74
|
-
|
75
|
-
def name
|
76
|
-
"#{first_name} #{last_name}"
|
77
|
-
end
|
78
|
-
|
79
65
|
def verification_value?
|
80
66
|
verification_value.present?
|
81
67
|
end
|
@@ -126,13 +112,9 @@ module Spree
|
|
126
112
|
|
127
113
|
def expiry_not_in_the_past
|
128
114
|
if year.present? && month.present?
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
current = Time.current
|
133
|
-
if year.to_i < current.year or (year.to_i == current.year and month.to_i < current.month)
|
134
|
-
errors.add(:base, :card_expired)
|
135
|
-
end
|
115
|
+
time = "#{year}-#{month}-1".to_time
|
116
|
+
if time < Time.zone.now.to_time.beginning_of_month
|
117
|
+
errors.add(:base, :card_expired)
|
136
118
|
end
|
137
119
|
end
|
138
120
|
end
|
@@ -26,7 +26,7 @@ module Spree
|
|
26
26
|
def authorize(money, credit_card, options = {})
|
27
27
|
profile_id = credit_card.gateway_customer_profile_id
|
28
28
|
if VALID_CCS.include? credit_card.number or (profile_id and profile_id.starts_with? 'BGS-')
|
29
|
-
ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, :test => true, :authorization => '12345', :avs_result => { :code => '
|
29
|
+
ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, :test => true, :authorization => '12345', :avs_result => { :code => 'D' })
|
30
30
|
else
|
31
31
|
ActiveMerchant::Billing::Response.new(false, 'Bogus Gateway: Forced failure', { :message => 'Bogus Gateway: Forced failure' }, :test => true)
|
32
32
|
end
|
@@ -35,7 +35,7 @@ module Spree
|
|
35
35
|
def purchase(money, credit_card, options = {})
|
36
36
|
profile_id = credit_card.gateway_customer_profile_id
|
37
37
|
if VALID_CCS.include? credit_card.number or (profile_id and profile_id.starts_with? 'BGS-')
|
38
|
-
ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, :test => true, :authorization => '12345', :avs_result => { :code => '
|
38
|
+
ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, :test => true, :authorization => '12345', :avs_result => { :code => 'M' })
|
39
39
|
else
|
40
40
|
ActiveMerchant::Billing::Response.new(false, 'Bogus Gateway: Forced failure', :message => 'Bogus Gateway: Forced failure', :test => true)
|
41
41
|
end
|
@@ -45,9 +45,9 @@ module Spree
|
|
45
45
|
ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, :test => true, :authorization => '12345')
|
46
46
|
end
|
47
47
|
|
48
|
-
def capture(
|
49
|
-
if authorization
|
50
|
-
ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, :test => true
|
48
|
+
def capture(money, authorization, gateway_options)
|
49
|
+
if authorization == '12345'
|
50
|
+
ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, :test => true)
|
51
51
|
else
|
52
52
|
ActiveMerchant::Billing::Response.new(false, 'Bogus Gateway: Forced failure', :error => 'Bogus Gateway: Forced failure', :test => true)
|
53
53
|
end
|
@@ -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/image.rb
CHANGED
@@ -14,15 +14,6 @@ module Spree
|
|
14
14
|
# we need to look at the write-queue for images which have not been saved yet
|
15
15
|
after_post_process :find_dimensions
|
16
16
|
|
17
|
-
include Spree::Core::S3Support
|
18
|
-
supports_s3 :attachment
|
19
|
-
|
20
|
-
Spree::Image.attachment_definitions[:attachment][:styles] = ActiveSupport::JSON.decode(Spree::Config[:attachment_styles]).symbolize_keys!
|
21
|
-
Spree::Image.attachment_definitions[:attachment][:path] = Spree::Config[:attachment_path]
|
22
|
-
Spree::Image.attachment_definitions[:attachment][:url] = Spree::Config[:attachment_url]
|
23
|
-
Spree::Image.attachment_definitions[:attachment][:default_url] = Spree::Config[:attachment_default_url]
|
24
|
-
Spree::Image.attachment_definitions[:attachment][:default_style] = Spree::Config[:attachment_default_style]
|
25
|
-
|
26
17
|
#used by admin products autocomplete
|
27
18
|
def mini_url
|
28
19
|
attachment.url(:mini, false)
|
@@ -1,9 +1,10 @@
|
|
1
1
|
module Spree
|
2
2
|
class InventoryUnit < ActiveRecord::Base
|
3
|
-
belongs_to :variant, class_name: "Spree::Variant"
|
4
|
-
belongs_to :order, class_name: "Spree::Order"
|
5
|
-
belongs_to :shipment, class_name: "Spree::Shipment", touch: true
|
3
|
+
belongs_to :variant, class_name: "Spree::Variant", inverse_of: :inventory_units
|
4
|
+
belongs_to :order, class_name: "Spree::Order", inverse_of: :inventory_units
|
5
|
+
belongs_to :shipment, class_name: "Spree::Shipment", touch: true, inverse_of: :inventory_units
|
6
6
|
belongs_to :return_authorization, class_name: "Spree::ReturnAuthorization"
|
7
|
+
belongs_to :line_item, class_name: "Spree::LineItem", inverse_of: :inventory_units
|
7
8
|
|
8
9
|
scope :backordered, -> { where state: 'backordered' }
|
9
10
|
scope :shipped, -> { where state: 'shipped' }
|
@@ -44,7 +45,12 @@ module Spree
|
|
44
45
|
end
|
45
46
|
|
46
47
|
def self.finalize_units!(inventory_units)
|
47
|
-
inventory_units.map
|
48
|
+
inventory_units.map do |iu|
|
49
|
+
iu.update_columns(
|
50
|
+
pending: false,
|
51
|
+
updated_at: Time.now,
|
52
|
+
)
|
53
|
+
end
|
48
54
|
end
|
49
55
|
|
50
56
|
def find_stock_item
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Spree
|
2
|
+
# Manage (recalculate) item (LineItem or Shipment) adjustments
|
3
|
+
class ItemAdjustments
|
4
|
+
attr_reader :item
|
5
|
+
|
6
|
+
delegate :adjustments, :order, to: :item
|
7
|
+
|
8
|
+
def initialize(item)
|
9
|
+
@item = item
|
10
|
+
end
|
11
|
+
|
12
|
+
def update
|
13
|
+
update_adjustments if item.persisted?
|
14
|
+
item
|
15
|
+
end
|
16
|
+
|
17
|
+
# TODO this should be probably the place to calculate proper item taxes
|
18
|
+
# values after promotions are applied
|
19
|
+
def update_adjustments
|
20
|
+
# Promotion adjustments must be applied first, then tax adjustments.
|
21
|
+
# This fits the criteria for VAT tax as outlined here:
|
22
|
+
# http://www.hmrc.gov.uk/vat/managing/charging/discounts-etc.htm#1
|
23
|
+
#
|
24
|
+
# It also fits the criteria for sales tax as outlined here:
|
25
|
+
# http://www.boe.ca.gov/formspubs/pub113/
|
26
|
+
#
|
27
|
+
# Tax adjustments come in not one but *two* exciting flavours:
|
28
|
+
# Included & additional
|
29
|
+
|
30
|
+
# Included tax adjustments are those which are included in the price.
|
31
|
+
# These ones should not effect the eventual total price.
|
32
|
+
#
|
33
|
+
# Additional tax adjustments are the opposite; effecting the final total.
|
34
|
+
promotion_total = adjustments.promotion.reload.map(&:update!).compact.sum
|
35
|
+
unless promotion_total == 0
|
36
|
+
choose_best_promotion_adjustment
|
37
|
+
end
|
38
|
+
promo_total = best_promotion_adjustment.try(:amount).to_f
|
39
|
+
included_tax_total = adjustments.tax.included.reload.map(&:update!).compact.sum
|
40
|
+
additional_tax_total = adjustments.tax.additional.reload.map(&:update!).compact.sum
|
41
|
+
|
42
|
+
item.update_columns(
|
43
|
+
:promo_total => promo_total,
|
44
|
+
:included_tax_total => included_tax_total,
|
45
|
+
:additional_tax_total => additional_tax_total,
|
46
|
+
:adjustment_total => promo_total + additional_tax_total,
|
47
|
+
:updated_at => Time.now,
|
48
|
+
)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Picks one (and only one) promotion to be eligible for this order
|
52
|
+
# This promotion provides the most discount, and if two promotions
|
53
|
+
# have the same amount, then it will pick the latest one.
|
54
|
+
def choose_best_promotion_adjustment
|
55
|
+
if best_promotion_adjustment
|
56
|
+
other_promotions = self.adjustments.promotion.where("id NOT IN (?)", best_promotion_adjustment.id)
|
57
|
+
other_promotions.update_all(:eligible => false)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def best_promotion_adjustment
|
62
|
+
@best_promotion_adjustment ||= adjustments.promotion.eligible.reorder("amount ASC, created_at DESC").first
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -1,12 +1,14 @@
|
|
1
1
|
module Spree
|
2
2
|
class LineItem < ActiveRecord::Base
|
3
3
|
before_validation :adjust_quantity
|
4
|
-
belongs_to :order, class_name: "Spree::Order",
|
5
|
-
belongs_to :variant, class_name: "Spree::Variant"
|
4
|
+
belongs_to :order, class_name: "Spree::Order", inverse_of: :line_items
|
5
|
+
belongs_to :variant, class_name: "Spree::Variant", inverse_of: :line_items
|
6
6
|
belongs_to :tax_category, class_name: "Spree::TaxCategory"
|
7
7
|
|
8
8
|
has_one :product, through: :variant
|
9
|
+
|
9
10
|
has_many :adjustments, as: :adjustable, dependent: :destroy
|
11
|
+
has_many :inventory_units, inverse_of: :line_item
|
10
12
|
|
11
13
|
before_validation :copy_price
|
12
14
|
before_validation :copy_tax_category
|
@@ -20,9 +22,12 @@ module Spree
|
|
20
22
|
validates :price, numericality: true
|
21
23
|
validates_with Stock::AvailabilityValidator
|
22
24
|
|
25
|
+
before_destroy :update_inventory
|
26
|
+
|
23
27
|
after_save :update_inventory
|
24
|
-
after_save :
|
25
|
-
|
28
|
+
after_save :update_adjustments
|
29
|
+
|
30
|
+
after_create :create_tax_charge
|
26
31
|
|
27
32
|
delegate :name, :description, :should_track_inventory?, to: :variant
|
28
33
|
|
@@ -38,14 +43,23 @@ module Spree
|
|
38
43
|
|
39
44
|
def copy_tax_category
|
40
45
|
if variant
|
41
|
-
self.tax_category = variant.
|
46
|
+
self.tax_category = variant.tax_category
|
42
47
|
end
|
43
48
|
end
|
44
49
|
|
45
50
|
def amount
|
46
51
|
price * quantity
|
47
52
|
end
|
48
|
-
alias
|
53
|
+
alias subtotal amount
|
54
|
+
|
55
|
+
def discounted_amount
|
56
|
+
amount + promo_total
|
57
|
+
end
|
58
|
+
|
59
|
+
def final_amount
|
60
|
+
amount + adjustment_total.to_f
|
61
|
+
end
|
62
|
+
alias total final_amount
|
49
63
|
|
50
64
|
def single_money
|
51
65
|
Spree::Money.new(price, { currency: currency })
|
@@ -63,7 +77,7 @@ module Spree
|
|
63
77
|
end
|
64
78
|
|
65
79
|
def sufficient_stock?
|
66
|
-
Stock::Quantifier.new(
|
80
|
+
Stock::Quantifier.new(variant_id).can_supply? quantity
|
67
81
|
end
|
68
82
|
|
69
83
|
def insufficient_stock?
|
@@ -87,17 +101,23 @@ module Spree
|
|
87
101
|
private
|
88
102
|
def update_inventory
|
89
103
|
if changed?
|
90
|
-
Spree::OrderInventory.new(self.order).verify(
|
104
|
+
Spree::OrderInventory.new(self.order, self).verify(target_shipment)
|
91
105
|
end
|
92
106
|
end
|
93
107
|
|
94
|
-
def
|
95
|
-
if
|
96
|
-
|
97
|
-
order.create_tax_charge!
|
98
|
-
order.update!
|
108
|
+
def update_adjustments
|
109
|
+
if quantity_changed?
|
110
|
+
recalculate_adjustments
|
99
111
|
end
|
100
112
|
end
|
113
|
+
|
114
|
+
def recalculate_adjustments
|
115
|
+
Spree::ItemAdjustments.new(self).update
|
116
|
+
end
|
117
|
+
|
118
|
+
def create_tax_charge
|
119
|
+
Spree::TaxRate.adjust(order, [self])
|
120
|
+
end
|
101
121
|
end
|
102
122
|
end
|
103
123
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Spree
|
2
2
|
class OptionType < ActiveRecord::Base
|
3
|
-
has_many :option_values, -> { order(:position) }, dependent: :destroy
|
4
|
-
has_many :product_option_types, dependent: :destroy
|
3
|
+
has_many :option_values, -> { order(:position) }, dependent: :destroy, inverse_of: :option_type
|
4
|
+
has_many :product_option_types, dependent: :destroy, inverse_of: :option_type
|
5
5
|
has_many :products, through: :product_option_types
|
6
6
|
has_and_belongs_to_many :prototypes, join_table: 'spree_option_types_prototypes'
|
7
7
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Spree
|
2
2
|
class OptionValue < ActiveRecord::Base
|
3
|
-
belongs_to :option_type, :
|
3
|
+
belongs_to :option_type, class_name: 'Spree::OptionType', touch: true, inverse_of: :option_values
|
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
|
|
data/app/models/spree/order.rb
CHANGED
@@ -9,7 +9,6 @@ module Spree
|
|
9
9
|
go_to_state :address
|
10
10
|
go_to_state :delivery
|
11
11
|
go_to_state :payment, if: ->(order) {
|
12
|
-
order.update_totals
|
13
12
|
order.payment_required?
|
14
13
|
}
|
15
14
|
go_to_state :confirm, if: ->(order) { order.confirmation_required? }
|
@@ -24,9 +23,11 @@ module Spree
|
|
24
23
|
if Spree.user_class
|
25
24
|
belongs_to :user, class_name: Spree.user_class.to_s
|
26
25
|
belongs_to :created_by, class_name: Spree.user_class.to_s
|
26
|
+
belongs_to :approver, class_name: Spree.user_class.to_s
|
27
27
|
else
|
28
28
|
belongs_to :user
|
29
29
|
belongs_to :created_by
|
30
|
+
belongs_to :approver
|
30
31
|
end
|
31
32
|
|
32
33
|
belongs_to :bill_address, foreign_key: :bill_address_id, class_name: 'Spree::Address'
|
@@ -35,16 +36,20 @@ module Spree
|
|
35
36
|
belongs_to :ship_address, foreign_key: :ship_address_id, class_name: 'Spree::Address'
|
36
37
|
alias_attribute :shipping_address, :ship_address
|
37
38
|
|
39
|
+
alias_attribute :ship_total, :shipment_total
|
40
|
+
|
38
41
|
has_many :state_changes, as: :stateful
|
39
|
-
has_many :line_items, -> { order('created_at ASC') }, dependent: :destroy
|
42
|
+
has_many :line_items, -> { order('created_at ASC') }, dependent: :destroy, inverse_of: :order
|
40
43
|
has_many :payments, dependent: :destroy
|
41
44
|
has_many :return_authorizations, dependent: :destroy
|
42
45
|
has_many :adjustments, -> { order("#{Adjustment.table_name}.created_at ASC") }, as: :adjustable, dependent: :destroy
|
43
46
|
has_many :line_item_adjustments, through: :line_items, source: :adjustments
|
44
|
-
has_many :
|
45
|
-
has_many :inventory_units
|
47
|
+
has_many :shipment_adjustments, through: :shipments, source: :adjustments
|
48
|
+
has_many :inventory_units, inverse_of: :order
|
49
|
+
|
50
|
+
has_and_belongs_to_many :promotions, join_table: 'spree_orders_promotions'
|
46
51
|
|
47
|
-
has_many :shipments, dependent: :destroy do
|
52
|
+
has_many :shipments, dependent: :destroy, inverse_of: :order do
|
48
53
|
def states
|
49
54
|
pluck(:state).uniq
|
50
55
|
end
|
@@ -63,16 +68,15 @@ module Spree
|
|
63
68
|
attr_accessor :use_billing
|
64
69
|
|
65
70
|
before_create :link_by_email
|
66
|
-
after_create :create_tax_charge!
|
67
71
|
|
68
72
|
validates :email, presence: true, if: :require_email
|
69
73
|
validates :email, email: true, if: :require_email, allow_blank: true
|
70
|
-
validates :number, uniqueness: true
|
71
74
|
validate :has_available_shipment
|
72
|
-
validate :has_available_payment
|
73
75
|
|
74
76
|
make_permalink field: :number
|
75
77
|
|
78
|
+
delegate :update_totals, :persist_totals, :to => :updater
|
79
|
+
|
76
80
|
class_attribute :update_hooks
|
77
81
|
self.update_hooks = Set.new
|
78
82
|
|
@@ -80,12 +84,8 @@ module Spree
|
|
80
84
|
where(number: number)
|
81
85
|
end
|
82
86
|
|
83
|
-
scope :created_between, ->(start_date, end_date) { where(created_at: start_date..end_date) }
|
84
|
-
scope :completed_between, ->(start_date, end_date) { where(completed_at: start_date..end_date) }
|
85
|
-
|
86
87
|
def self.between(start_date, end_date)
|
87
|
-
|
88
|
-
self.created_between(start_date, end_date)
|
88
|
+
where(created_at: start_date..end_date)
|
89
89
|
end
|
90
90
|
|
91
91
|
def self.by_customer(customer)
|
@@ -110,6 +110,10 @@ module Spree
|
|
110
110
|
self.update_hooks.add(hook)
|
111
111
|
end
|
112
112
|
|
113
|
+
def all_adjustments
|
114
|
+
Adjustment.where("order_id = :order_id OR adjustable_id = :order_id", :order_id => self.id)
|
115
|
+
end
|
116
|
+
|
113
117
|
# For compatiblity with Calculator::PriceSack
|
114
118
|
def amount
|
115
119
|
line_items.inject(0.0) { |sum, li| sum + li.amount }
|
@@ -131,24 +135,33 @@ module Spree
|
|
131
135
|
Spree::Money.new(adjustment_total, { currency: currency })
|
132
136
|
end
|
133
137
|
|
134
|
-
def
|
135
|
-
Spree::Money.new(
|
138
|
+
def display_included_tax_total
|
139
|
+
Spree::Money.new(included_tax_total, { currency: currency })
|
140
|
+
end
|
141
|
+
|
142
|
+
def display_additional_tax_total
|
143
|
+
Spree::Money.new(additional_tax_total, { currency: currency })
|
136
144
|
end
|
137
145
|
|
138
|
-
def
|
139
|
-
Spree::Money.new(
|
146
|
+
def display_shipment_total
|
147
|
+
Spree::Money.new(shipment_total, { currency: currency })
|
140
148
|
end
|
149
|
+
alias :display_ship_total :display_shipment_total
|
141
150
|
|
142
151
|
def display_total
|
143
152
|
Spree::Money.new(total, { currency: currency })
|
144
153
|
end
|
145
154
|
|
155
|
+
def shipping_discount
|
156
|
+
shipment_adjustments.eligible.sum(:amount) * - 1
|
157
|
+
end
|
158
|
+
|
146
159
|
def to_param
|
147
160
|
number.to_s.to_url.upcase
|
148
161
|
end
|
149
162
|
|
150
163
|
def completed?
|
151
|
-
completed_at.present?
|
164
|
+
completed_at.present?
|
152
165
|
end
|
153
166
|
|
154
167
|
# Indicates whether or not the user is allowed to proceed to checkout.
|
@@ -174,11 +187,6 @@ module Spree
|
|
174
187
|
state == 'confirm'
|
175
188
|
end
|
176
189
|
|
177
|
-
# Indicates the number of items in the order
|
178
|
-
def item_count
|
179
|
-
line_items.inject(0) { |sum, li| sum + li.quantity }
|
180
|
-
end
|
181
|
-
|
182
190
|
def backordered?
|
183
191
|
shipments.any?(&:backordered?)
|
184
192
|
end
|
@@ -202,16 +210,6 @@ module Spree
|
|
202
210
|
Spree::Config[:tax_using_ship_address] ? ship_address : bill_address
|
203
211
|
end
|
204
212
|
|
205
|
-
# Array of totals grouped by Adjustment#label. Useful for displaying line item
|
206
|
-
# adjustments on an invoice. For example, you can display tax breakout for
|
207
|
-
# cases where tax is included in price.
|
208
|
-
def line_item_adjustment_totals
|
209
|
-
Hash[self.line_item_adjustments.eligible.group_by(&:label).map do |label, adjustments|
|
210
|
-
total = adjustments.sum(&:amount)
|
211
|
-
[label, Spree::Money.new(total, { currency: currency })]
|
212
|
-
end]
|
213
|
-
end
|
214
|
-
|
215
213
|
def updater
|
216
214
|
@updater ||= OrderUpdater.new(self)
|
217
215
|
end
|
@@ -220,10 +218,6 @@ module Spree
|
|
220
218
|
updater.update
|
221
219
|
end
|
222
220
|
|
223
|
-
def update_totals
|
224
|
-
updater.update_totals
|
225
|
-
end
|
226
|
-
|
227
221
|
def clone_billing_address
|
228
222
|
if bill_address and self.ship_address.nil?
|
229
223
|
self.ship_address = bill_address.clone
|
@@ -258,11 +252,15 @@ module Spree
|
|
258
252
|
end
|
259
253
|
end
|
260
254
|
|
255
|
+
# FIXME refactor this method and implement validation using validates_* utilities
|
261
256
|
def generate_order_number
|
262
|
-
|
257
|
+
record = true
|
258
|
+
while record
|
263
259
|
random = "R#{Array.new(9){rand(9)}.join}"
|
264
|
-
|
260
|
+
record = self.class.where(number: random).first
|
265
261
|
end
|
262
|
+
self.number = random if self.number.blank?
|
263
|
+
self.number
|
266
264
|
end
|
267
265
|
|
268
266
|
def shipped_shipments
|
@@ -282,14 +280,11 @@ module Spree
|
|
282
280
|
line_items.detect { |line_item| line_item.variant_id == variant.id }
|
283
281
|
end
|
284
282
|
|
285
|
-
def ship_total
|
286
|
-
adjustments.shipping.sum(:amount)
|
287
|
-
end
|
288
|
-
|
289
283
|
# Creates new tax charges if there are any applicable rates. If prices already
|
290
284
|
# include taxes then price adjustments are created instead.
|
291
285
|
def create_tax_charge!
|
292
|
-
Spree::TaxRate.adjust(self)
|
286
|
+
Spree::TaxRate.adjust(self, line_items)
|
287
|
+
Spree::TaxRate.adjust(self, shipments) if shipments.any?
|
293
288
|
end
|
294
289
|
|
295
290
|
def outstanding_balance
|
@@ -318,10 +313,8 @@ module Spree
|
|
318
313
|
# Finalizes an in progress order after checkout is complete.
|
319
314
|
# Called after transition to complete state when payments will have been processed
|
320
315
|
def finalize!
|
321
|
-
touch :completed_at
|
322
|
-
|
323
316
|
# lock all adjustments (coupon promotions, etc.)
|
324
|
-
|
317
|
+
all_adjustments.each{|a| a.close}
|
325
318
|
|
326
319
|
# update payment and shipment(s) states, and save
|
327
320
|
updater.update_payment_state
|
@@ -334,16 +327,16 @@ module Spree
|
|
334
327
|
save
|
335
328
|
updater.run_hooks
|
336
329
|
|
337
|
-
|
330
|
+
touch :completed_at
|
331
|
+
|
332
|
+
deliver_order_confirmation_email unless confirmation_delivered?
|
333
|
+
|
334
|
+
consider_risk
|
338
335
|
end
|
339
336
|
|
340
337
|
def deliver_order_confirmation_email
|
341
|
-
|
342
|
-
|
343
|
-
rescue Exception => e
|
344
|
-
logger.error("#{e.class.name}: #{e.message}")
|
345
|
-
logger.error(e.backtrace * "\n")
|
346
|
-
end
|
338
|
+
OrderMailer.confirm_email(self.id).deliver
|
339
|
+
update_column(:confirmation_delivered, true)
|
347
340
|
end
|
348
341
|
|
349
342
|
# Helper methods for checkout steps
|
@@ -356,7 +349,7 @@ module Spree
|
|
356
349
|
end
|
357
350
|
|
358
351
|
def pending_payments
|
359
|
-
payments.select
|
352
|
+
payments.select { |payment| payment.checkout? || payment.pending? }
|
360
353
|
end
|
361
354
|
|
362
355
|
# processes any pending payments and must return a boolean as it's
|
@@ -408,7 +401,7 @@ module Spree
|
|
408
401
|
end
|
409
402
|
|
410
403
|
def insufficient_stock_lines
|
411
|
-
|
404
|
+
@insufficient_stock_lines ||= line_items.select(&:insufficient_stock?)
|
412
405
|
end
|
413
406
|
|
414
407
|
def merge!(order, user = nil)
|
@@ -432,13 +425,10 @@ module Spree
|
|
432
425
|
end
|
433
426
|
|
434
427
|
def empty!
|
435
|
-
adjustments.destroy_all
|
436
428
|
line_items.destroy_all
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
self.adjustments.destroy_all
|
441
|
-
self.line_item_adjustments.destroy_all
|
429
|
+
adjustments.destroy_all
|
430
|
+
update_totals
|
431
|
+
persist_totals
|
442
432
|
end
|
443
433
|
|
444
434
|
def has_step?(step)
|
@@ -465,27 +455,10 @@ module Spree
|
|
465
455
|
@coupon_code = code.strip.downcase rescue nil
|
466
456
|
end
|
467
457
|
|
468
|
-
|
469
|
-
|
470
|
-
# you would only want a promotion action to apply to order no more than once.
|
471
|
-
#
|
472
|
-
# Receives an adjustment +originator+ (here a PromotionAction object) and tells
|
473
|
-
# if the order has adjustments from that already
|
474
|
-
def promotion_credit_exists?(originator)
|
475
|
-
!! adjustments.includes(:originator).promotion.reload.detect { |credit| credit.originator.id == originator.id }
|
476
|
-
end
|
477
|
-
|
478
|
-
def promo_total
|
479
|
-
adjustments.eligible.promotion.sum(:amount)
|
458
|
+
def can_add_coupon?
|
459
|
+
Spree::Promotion.order_activatable?(self)
|
480
460
|
end
|
481
461
|
|
482
|
-
def manual_adjustment_total
|
483
|
-
adjustments.eligible.manual.sum(:amount)
|
484
|
-
end
|
485
|
-
|
486
|
-
def discount_total
|
487
|
-
promo_total + manual_adjustment_total
|
488
|
-
end
|
489
462
|
|
490
463
|
def shipped?
|
491
464
|
%w(partial shipped).include?(shipment_state)
|
@@ -503,20 +476,31 @@ module Spree
|
|
503
476
|
shipments
|
504
477
|
end
|
505
478
|
|
479
|
+
def apply_free_shipping_promotions
|
480
|
+
Spree::PromotionHandler::FreeShipping.new(self).activate
|
481
|
+
shipments.each { |shipment| ItemAdjustments.new(shipment).update }
|
482
|
+
updater.update_shipment_total
|
483
|
+
persist_totals
|
484
|
+
end
|
485
|
+
|
506
486
|
# Clean shipments and make order back to address state
|
507
487
|
#
|
508
488
|
# At some point the might need to force the order to transition from address
|
509
489
|
# to delivery again so that proper updated shipments are created.
|
510
490
|
# e.g. customer goes back from payment step and changes order items
|
511
491
|
def ensure_updated_shipments
|
512
|
-
if shipments.any?
|
492
|
+
if shipments.any?
|
513
493
|
self.shipments.destroy_all
|
494
|
+
self.update_column(:shipment_total, 0)
|
514
495
|
restart_checkout_flow
|
515
496
|
end
|
516
497
|
end
|
517
498
|
|
518
499
|
def restart_checkout_flow
|
519
|
-
self.
|
500
|
+
self.update_columns(
|
501
|
+
state: checkout_steps.first,
|
502
|
+
updated_at: Time.now,
|
503
|
+
)
|
520
504
|
end
|
521
505
|
|
522
506
|
def refresh_shipment_rates
|
@@ -527,6 +511,12 @@ module Spree
|
|
527
511
|
(bill_address.empty? && ship_address.empty?) || bill_address.same_as?(ship_address)
|
528
512
|
end
|
529
513
|
|
514
|
+
def set_shipments_cost
|
515
|
+
shipments.each(&:update_amounts)
|
516
|
+
updater.update_shipment_total
|
517
|
+
persist_totals
|
518
|
+
end
|
519
|
+
|
530
520
|
def is_risky?
|
531
521
|
self.payments.where(%{
|
532
522
|
(avs_response IS NOT NULL and avs_response != '' and avs_response != 'D' and avs_response != 'M') or
|
@@ -536,6 +526,39 @@ module Spree
|
|
536
526
|
}.squish!).uniq.count > 0
|
537
527
|
end
|
538
528
|
|
529
|
+
def approved_by(user)
|
530
|
+
self.transaction do
|
531
|
+
approve!
|
532
|
+
self.update_columns(
|
533
|
+
approver_id: user.id,
|
534
|
+
approved_at: Time.now,
|
535
|
+
considered_risky: false,
|
536
|
+
)
|
537
|
+
end
|
538
|
+
end
|
539
|
+
|
540
|
+
def approved?
|
541
|
+
!!self.approved_at
|
542
|
+
end
|
543
|
+
|
544
|
+
def can_approve?
|
545
|
+
!approved?
|
546
|
+
end
|
547
|
+
|
548
|
+
def consider_risk
|
549
|
+
if is_risky? && !approved?
|
550
|
+
considered_risky!
|
551
|
+
end
|
552
|
+
end
|
553
|
+
|
554
|
+
def considered_risky!
|
555
|
+
update_column(:considered_risky, true)
|
556
|
+
end
|
557
|
+
|
558
|
+
def approve!
|
559
|
+
update_column(:considered_risky, false)
|
560
|
+
end
|
561
|
+
|
539
562
|
private
|
540
563
|
|
541
564
|
def link_by_email
|
@@ -566,14 +589,9 @@ module Spree
|
|
566
589
|
end
|
567
590
|
end
|
568
591
|
|
569
|
-
def has_available_payment
|
570
|
-
return unless has_step?("delivery") && delivery?
|
571
|
-
# errors.add(:base, :no_payment_methods_available) if available_payment_methods.empty?
|
572
|
-
end
|
573
|
-
|
574
592
|
def after_cancel
|
575
593
|
shipments.each { |shipment| shipment.cancel! }
|
576
|
-
payments.completed.each { |payment| payment.
|
594
|
+
payments.completed.each { |payment| payment.credit! }
|
577
595
|
|
578
596
|
send_cancel_email
|
579
597
|
self.update_column(:payment_state, 'credit_owed') unless shipped?
|
@@ -585,6 +603,7 @@ module Spree
|
|
585
603
|
|
586
604
|
def after_resume
|
587
605
|
shipments.each { |shipment| shipment.resume! }
|
606
|
+
consider_risk
|
588
607
|
end
|
589
608
|
|
590
609
|
def use_billing?
|
@@ -594,5 +613,6 @@ module Spree
|
|
594
613
|
def set_currency
|
595
614
|
self.currency = Spree::Config[:currency] if self[:currency].nil?
|
596
615
|
end
|
616
|
+
|
597
617
|
end
|
598
618
|
end
|