spree_core 2.2.14 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/{spree.js.coffee → spree.js.coffee.erb} +11 -2
- data/app/controllers/spree/base_controller.rb +1 -0
- data/app/helpers/spree/base_helper.rb +5 -6
- data/app/helpers/spree/orders_helper.rb +4 -0
- data/app/helpers/spree/products_helper.rb +8 -7
- data/app/mailers/spree/base_mailer.rb +2 -2
- data/app/mailers/spree/order_mailer.rb +2 -2
- data/app/mailers/spree/shipment_mailer.rb +1 -1
- data/app/mailers/spree/test_mailer.rb +1 -1
- data/app/models/spree/ability.rb +15 -16
- data/app/models/spree/address.rb +3 -6
- data/app/models/spree/adjustment.rb +2 -2
- data/app/models/spree/alert.rb +1 -1
- data/app/models/spree/app_configuration.rb +17 -20
- data/app/models/spree/asset.rb +2 -2
- data/app/models/spree/base.rb +9 -0
- data/app/models/spree/calculator.rb +1 -1
- data/app/models/spree/calculator/flat_rate.rb +1 -1
- data/app/models/spree/calculator/flexi_rate.rb +1 -1
- data/app/models/spree/calculator/price_sack.rb +1 -3
- data/app/models/spree/calculator/shipping/flat_rate.rb +1 -1
- data/app/models/spree/calculator/shipping/flexi_rate.rb +1 -1
- data/app/models/spree/calculator/shipping/per_item.rb +1 -1
- data/app/models/spree/calculator/shipping/price_sack.rb +1 -3
- data/app/models/spree/classification.rb +1 -1
- data/app/models/spree/configuration.rb +1 -1
- data/app/models/spree/country.rb +1 -1
- data/app/models/spree/credit_card.rb +8 -12
- data/app/models/spree/gateway.rb +0 -3
- data/app/models/spree/gateway/bogus.rb +2 -3
- data/app/models/spree/image.rb +3 -1
- data/app/models/spree/inventory_unit.rb +5 -6
- data/app/models/spree/item_adjustments.rb +3 -4
- data/app/models/spree/legacy_user.rb +1 -1
- data/app/models/spree/line_item.rb +6 -13
- data/app/models/spree/log_entry.rb +1 -1
- data/app/models/spree/option_type.rb +1 -1
- data/app/models/spree/option_value.rb +1 -3
- data/app/models/spree/order.rb +52 -70
- data/app/models/spree/order/checkout.rb +17 -10
- data/app/models/spree/order/currency_updater.rb +1 -1
- data/app/models/spree/order_contents.rb +7 -4
- data/app/models/spree/order_populator.rb +1 -1
- data/app/models/spree/order_updater.rb +8 -21
- data/app/models/spree/payment.rb +26 -12
- data/app/models/spree/payment/processing.rb +5 -16
- data/app/models/spree/payment_capture_event.rb +1 -1
- data/app/models/spree/payment_method.rb +2 -2
- data/app/models/spree/payment_method/check.rb +0 -2
- data/app/models/spree/preference.rb +1 -31
- data/app/models/spree/preferences/configuration.rb +2 -6
- data/app/models/spree/preferences/preferable.rb +46 -74
- data/app/models/spree/preferences/preferable_class_methods.rb +11 -46
- data/app/models/spree/preferences/scoped_store.rb +33 -0
- data/app/models/spree/preferences/store.rb +8 -7
- data/app/models/spree/price.rb +1 -3
- data/app/models/spree/product.rb +59 -87
- data/app/models/spree/product/scopes.rb +22 -13
- data/app/models/spree/product_option_type.rb +1 -1
- data/app/models/spree/product_property.rb +1 -3
- data/app/models/spree/product_scope/scopes.rb +1 -1
- data/app/models/spree/promotion.rb +4 -5
- data/app/models/spree/promotion/actions/create_adjustment.rb +11 -2
- data/app/models/spree/promotion/actions/create_item_adjustments.rb +19 -2
- data/app/models/spree/promotion/actions/create_line_items.rb +2 -12
- data/app/models/spree/promotion/rules/user.rb +5 -1
- data/app/models/spree/promotion_action.rb +1 -1
- data/app/models/spree/promotion_action_line_item.rb +1 -1
- data/app/models/spree/promotion_handler/cart.rb +2 -14
- data/app/models/spree/promotion_handler/coupon.rb +3 -13
- data/app/models/spree/promotion_rule.rb +1 -1
- data/app/models/spree/property.rb +1 -3
- data/app/models/spree/prototype.rb +1 -1
- data/app/models/spree/return_authorization.rb +4 -10
- data/app/models/spree/role.rb +1 -1
- data/app/models/spree/shipment.rb +1 -9
- data/app/models/spree/shipping_category.rb +3 -3
- data/app/models/spree/shipping_method.rb +1 -1
- data/app/models/spree/shipping_method_category.rb +2 -2
- data/app/models/spree/shipping_rate.rb +3 -3
- data/app/models/spree/state.rb +1 -1
- data/app/models/spree/state_change.rb +1 -1
- data/app/models/spree/stock/availability_validator.rb +7 -3
- data/app/models/spree/stock/package.rb +0 -23
- data/app/models/spree/stock/splitter/backordered.rb +1 -1
- data/app/models/spree/stock/splitter/shipping_category.rb +1 -1
- data/app/models/spree/stock/splitter/weight.rb +1 -1
- data/app/models/spree/stock_item.rb +7 -10
- data/app/models/spree/stock_location.rb +2 -6
- data/app/models/spree/stock_movement.rb +1 -3
- data/app/models/spree/stock_transfer.rb +1 -3
- data/app/models/spree/store.rb +33 -0
- data/app/models/spree/tax_category.rb +2 -2
- data/app/models/spree/tax_rate.rb +21 -52
- data/app/models/spree/taxon.rb +9 -8
- data/app/models/spree/taxonomy.rb +1 -1
- data/app/models/spree/tracker.rb +1 -1
- data/app/models/spree/variant.rb +13 -15
- data/app/models/spree/variant/scopes.rb +1 -1
- data/app/models/spree/zone.rb +22 -22
- data/app/models/spree/zone_member.rb +2 -2
- data/config/initializers/user_class_extensions.rb +0 -8
- data/config/locales/en.yml +7 -42
- data/db/default/spree/countries.rb +2 -3
- data/db/default/spree/stores.rb +9 -0
- data/db/migrate/20130611054351_rename_shipping_methods_zones_to_spree_shipping_methods_zones.rb +0 -5
- data/db/migrate/20130807024301_upgrade_adjustments.rb +4 -5
- data/db/migrate/20130807024302_rename_adjustment_fields.rb +5 -2
- data/db/migrate/20131118183431_add_line_item_id_to_spree_inventory_units.rb +1 -1
- data/db/migrate/20140106065820_remove_value_type_from_spree_preferences.rb +8 -0
- data/db/migrate/20140227112348_add_preference_store_to_everything.rb +8 -0
- data/db/migrate/20140309023735_migrate_old_preferences.rb +23 -0
- data/db/migrate/20140309024355_create_spree_stores.rb +25 -0
- data/db/migrate/20140309033438_create_store_from_preferences.rb +30 -0
- data/db/migrate/20140315053743_add_timestamps_to_spree_assets.rb +6 -0
- data/db/migrate/20140331100557_add_additional_store_fields.rb +8 -0
- data/db/migrate/20140410141842_add_many_missing_indexes.rb +18 -0
- data/db/migrate/20140410150358_correct_some_polymorphic_index_and_add_more_missing.rb +66 -0
- data/db/migrate/20140508151342_change_spree_price_amount_precision.rb +1 -1
- data/db/migrate/20140518174634_add_token_to_spree_orders.rb +5 -0
- data/db/migrate/20140530024945_move_order_token_from_tokenized_permission.rb +29 -0
- data/db/migrate/20140601011216_set_shipment_total_for_users_upgrading.rb +5 -3
- data/db/migrate/20140604135309_drop_credit_card_first_name_and_last_name.rb +6 -0
- data/lib/generators/spree/dummy/dummy_generator.rb +1 -0
- data/lib/generators/spree/dummy/templates/initializers/devise.rb +3 -0
- data/lib/generators/spree/dummy/templates/rails/routes.rb +0 -1
- data/lib/generators/spree/install/install_generator.rb +8 -17
- data/lib/generators/spree/install/templates/config/initializers/spree.rb +2 -2
- data/lib/spree/core.rb +13 -9
- data/lib/spree/core/calculated_adjustments.rb +1 -1
- data/lib/spree/core/controller_helpers/auth.rb +27 -18
- data/lib/spree/core/controller_helpers/common.rb +2 -2
- data/lib/spree/core/controller_helpers/order.rb +15 -24
- data/lib/spree/core/controller_helpers/store.rb +19 -0
- data/lib/spree/core/delegate_belongs_to.rb +2 -2
- data/lib/spree/core/engine.rb +0 -10
- data/lib/spree/core/importer.rb +1 -0
- data/lib/spree/core/importer/order.rb +16 -44
- data/lib/spree/core/importer/product.rb +62 -0
- data/lib/spree/core/product_filters.rb +0 -4
- data/lib/spree/core/routes.rb +4 -6
- data/lib/spree/core/validators/email.rb +23 -1
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/money.rb +1 -169
- data/lib/spree/permitted_attributes.rb +6 -4
- data/lib/spree/testing_support/authorization_helpers.rb +23 -21
- data/lib/spree/testing_support/capybara_ext.rb +11 -21
- data/lib/spree/testing_support/common_rake.rb +3 -1
- data/lib/spree/testing_support/controller_requests.rb +0 -2
- data/lib/spree/testing_support/factories/credit_card_factory.rb +1 -1
- data/lib/spree/testing_support/factories/line_item_factory.rb +4 -1
- data/lib/spree/testing_support/factories/order_factory.rb +5 -4
- data/lib/spree/testing_support/factories/product_factory.rb +0 -4
- data/lib/spree/testing_support/factories/promotion_factory.rb +5 -7
- data/lib/spree/testing_support/factories/shipment_factory.rb +0 -1
- data/lib/spree/testing_support/factories/stock_factory.rb +2 -2
- data/lib/spree/testing_support/factories/store_factory.rb +8 -0
- data/lib/spree/testing_support/preferences.rb +3 -3
- data/lib/tasks/core.rake +2 -2
- metadata +48 -39
- data/app/models/spree/stock/order_counter.rb +0 -55
- data/app/models/spree/tokenized_permission.rb +0 -6
- data/app/views/spree/shared/_routes.html.erb +0 -13
- data/db/migrate/20140804185157_add_default_to_shipment_cost.rb +0 -10
- data/db/migrate/20141021194502_add_state_lock_version_to_order.rb +0 -5
- data/lib/spree/core/adjustment_source.rb +0 -26
- data/lib/spree/core/mail_interceptor.rb +0 -22
- data/lib/spree/core/mail_method.rb +0 -27
- data/lib/spree/core/mail_settings.rb +0 -55
- data/lib/spree/core/ransackable_attributes.rb +0 -15
- data/lib/spree/core/token_resource.rb +0 -27
@@ -1,5 +1,5 @@
|
|
1
1
|
module Spree
|
2
|
-
class Order <
|
2
|
+
class Order < Spree::Base
|
3
3
|
module Checkout
|
4
4
|
def self.included(klass)
|
5
5
|
klass.class_eval do
|
@@ -71,7 +71,12 @@ module Spree
|
|
71
71
|
|
72
72
|
if states[:payment]
|
73
73
|
before_transition :to => :complete do |order|
|
74
|
-
order.
|
74
|
+
if order.payment_required? && order.payments.empty?
|
75
|
+
order.errors.add(:base, Spree.t(:no_payment_found))
|
76
|
+
false
|
77
|
+
elsif order.payment_required?
|
78
|
+
order.process_payments!
|
79
|
+
end
|
75
80
|
end
|
76
81
|
end
|
77
82
|
|
@@ -92,11 +97,9 @@ module Spree
|
|
92
97
|
before_transition :from => :delivery, :do => :apply_free_shipping_promotions
|
93
98
|
end
|
94
99
|
|
95
|
-
|
96
|
-
|
97
|
-
after_transition to
|
98
|
-
after_transition to: :resumed, do: :after_resume
|
99
|
-
after_transition to: :canceled, do: :after_cancel
|
100
|
+
after_transition :to => :complete, :do => :finalize!
|
101
|
+
after_transition :to => :resumed, :do => :after_resume
|
102
|
+
after_transition :to => :canceled, :do => :after_cancel
|
100
103
|
|
101
104
|
after_transition :from => any - :cart, :to => any - [:confirm, :complete] do |order|
|
102
105
|
order.update_totals
|
@@ -206,11 +209,11 @@ module Spree
|
|
206
209
|
checkout_step_index(state) > checkout_step_index(self.state)
|
207
210
|
end
|
208
211
|
|
209
|
-
define_callbacks :updating_from_params, terminator:
|
212
|
+
define_callbacks :updating_from_params, terminator: ->(target, result) { result == false }
|
210
213
|
|
211
214
|
set_callback :updating_from_params, :before, :update_params_payment_source
|
212
215
|
|
213
|
-
def update_from_params(params, permitted_params)
|
216
|
+
def update_from_params(params, permitted_params, request_env = {})
|
214
217
|
success = false
|
215
218
|
@updating_params = params
|
216
219
|
run_callbacks :updating_from_params do
|
@@ -231,9 +234,13 @@ module Spree
|
|
231
234
|
attributes[:payments_attributes].first.delete :source_attributes
|
232
235
|
end
|
233
236
|
|
237
|
+
if attributes[:payments_attributes]
|
238
|
+
attributes[:payments_attributes].first[:request_env] = request_env
|
239
|
+
end
|
240
|
+
|
234
241
|
success = self.update_attributes(attributes)
|
235
|
-
set_shipments_cost if self.shipments.any?
|
236
242
|
end
|
243
|
+
|
237
244
|
@updating_params = nil
|
238
245
|
success
|
239
246
|
end
|
@@ -9,7 +9,6 @@ module Spree
|
|
9
9
|
def add(variant, quantity = 1, currency = nil, shipment = nil)
|
10
10
|
line_item = add_to_line_item(variant, quantity, currency, shipment)
|
11
11
|
reload_totals
|
12
|
-
shipment.present? ? shipment.update_amounts : order.ensure_updated_shipments
|
13
12
|
PromotionHandler::Cart.new(order, line_item).activate
|
14
13
|
ItemAdjustments.new(line_item).update
|
15
14
|
reload_totals
|
@@ -19,7 +18,6 @@ module Spree
|
|
19
18
|
def remove(variant, quantity = 1, shipment = nil)
|
20
19
|
line_item = remove_from_line_item(variant, quantity, shipment)
|
21
20
|
reload_totals
|
22
|
-
shipment.present? ? shipment.update_amounts : order.ensure_updated_shipments
|
23
21
|
PromotionHandler::Cart.new(order, line_item).activate
|
24
22
|
ItemAdjustments.new(line_item).update
|
25
23
|
reload_totals
|
@@ -49,7 +47,12 @@ module Spree
|
|
49
47
|
|
50
48
|
def reload_totals
|
51
49
|
order_updater.update_item_count
|
52
|
-
order_updater.
|
50
|
+
order_updater.update_item_total
|
51
|
+
order_updater.update_adjustment_total
|
52
|
+
|
53
|
+
order_updater.update_payment_state if order.completed?
|
54
|
+
order_updater.persist_totals
|
55
|
+
|
53
56
|
order.reload
|
54
57
|
end
|
55
58
|
|
@@ -77,7 +80,7 @@ module Spree
|
|
77
80
|
|
78
81
|
def remove_from_line_item(variant, quantity, shipment=nil)
|
79
82
|
line_item = grab_line_item_by_variant(variant, true)
|
80
|
-
line_item.quantity
|
83
|
+
line_item.quantity -= quantity
|
81
84
|
line_item.target_shipment= shipment
|
82
85
|
|
83
86
|
if line_item.quantity == 0
|
@@ -38,10 +38,9 @@ module Spree
|
|
38
38
|
# +payment_total+ The total value of all finalized Payments (NOTE: non-finalized Payments are excluded)
|
39
39
|
# +item_total+ The total value of all LineItems
|
40
40
|
# +adjustment_total+ The total value of all adjustments (promotions, credits, etc.)
|
41
|
-
# +promo_total+ The total value of all promotion adjustments
|
42
41
|
# +total+ The so-called "order total." This is equivalent to +item_total+ plus +adjustment_total+.
|
43
42
|
def update_totals
|
44
|
-
|
43
|
+
update_payment_total
|
45
44
|
update_item_total
|
46
45
|
update_shipment_total
|
47
46
|
update_adjustment_total
|
@@ -50,12 +49,11 @@ module Spree
|
|
50
49
|
|
51
50
|
# give each of the shipments a chance to update themselves
|
52
51
|
def update_shipments
|
53
|
-
shipments.each
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
end
|
52
|
+
shipments.each { |shipment| shipment.update!(order) }
|
53
|
+
end
|
54
|
+
|
55
|
+
def update_payment_total
|
56
|
+
order.payment_total = payments.completed.sum(:amount)
|
59
57
|
end
|
60
58
|
|
61
59
|
def update_shipment_total
|
@@ -75,10 +73,6 @@ module Spree
|
|
75
73
|
order.included_tax_total = line_items.sum(:included_tax_total) + shipments.sum(:included_tax_total)
|
76
74
|
order.additional_tax_total = line_items.sum(:additional_tax_total) + shipments.sum(:additional_tax_total)
|
77
75
|
|
78
|
-
order.promo_total = line_items.sum(:promo_total) +
|
79
|
-
shipments.sum(:promo_total) +
|
80
|
-
adjustments.promotion.eligible.sum(:amount)
|
81
|
-
|
82
76
|
update_order_total
|
83
77
|
end
|
84
78
|
|
@@ -87,7 +81,7 @@ module Spree
|
|
87
81
|
end
|
88
82
|
|
89
83
|
def update_item_total
|
90
|
-
order.item_total = line_items.
|
84
|
+
order.item_total = line_items.sum('price * quantity')
|
91
85
|
update_order_total
|
92
86
|
end
|
93
87
|
|
@@ -102,7 +96,6 @@ module Spree
|
|
102
96
|
additional_tax_total: order.additional_tax_total,
|
103
97
|
payment_total: order.payment_total,
|
104
98
|
shipment_total: order.shipment_total,
|
105
|
-
promo_total: order.promo_total,
|
106
99
|
total: order.total,
|
107
100
|
updated_at: Time.now,
|
108
101
|
)
|
@@ -152,23 +145,17 @@ module Spree
|
|
152
145
|
# The +payment_state+ value helps with reporting, etc. since it provides a quick and easy way to locate Orders needing attention.
|
153
146
|
def update_payment_state
|
154
147
|
last_state = order.payment_state
|
155
|
-
if payments.present? && payments.
|
148
|
+
if payments.present? && payments.last.state == 'failed'
|
156
149
|
order.payment_state = 'failed'
|
157
|
-
elsif !payments.present? && order.state == 'canceled'
|
158
|
-
order.payment_state = 'void'
|
159
|
-
elsif order.state == 'canceled' && order.payment_total == 0 && payments.completed.size > 0
|
160
|
-
order.payment_state = 'void'
|
161
150
|
else
|
162
151
|
order.payment_state = 'balance_due' if order.outstanding_balance > 0
|
163
152
|
order.payment_state = 'credit_owed' if order.outstanding_balance < 0
|
164
153
|
order.payment_state = 'paid' if !order.outstanding_balance?
|
165
154
|
end
|
166
155
|
order.state_changed('payment') if last_state != order.payment_state
|
167
|
-
order.payment_state
|
168
156
|
end
|
169
157
|
|
170
158
|
private
|
171
|
-
|
172
159
|
def round_money(n)
|
173
160
|
(n * 100).round / 100.0
|
174
161
|
end
|
data/app/models/spree/payment.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Spree
|
2
|
-
class Payment <
|
2
|
+
class Payment < Spree::Base
|
3
3
|
include Spree::Payment::Processing
|
4
4
|
|
5
5
|
IDENTIFIER_CHARS = (('A'..'Z').to_a + ('0'..'9').to_a - %w(0 1 I O)).freeze
|
@@ -8,7 +8,7 @@ module Spree
|
|
8
8
|
|
9
9
|
belongs_to :order, class_name: 'Spree::Order', touch: true, inverse_of: :payments
|
10
10
|
belongs_to :source, polymorphic: true
|
11
|
-
belongs_to :payment_method, class_name: 'Spree::PaymentMethod'
|
11
|
+
belongs_to :payment_method, class_name: 'Spree::PaymentMethod'
|
12
12
|
|
13
13
|
has_many :offsets, -> { where("source_type = 'Spree::Payment' AND amount < 0 AND state = 'completed'") },
|
14
14
|
class_name: "Spree::Payment", foreign_key: :source_id
|
@@ -26,13 +26,15 @@ module Spree
|
|
26
26
|
# invalidate previously entered payments
|
27
27
|
after_create :invalidate_old_payments
|
28
28
|
|
29
|
-
attr_accessor :source_attributes
|
29
|
+
attr_accessor :source_attributes, :request_env
|
30
|
+
|
30
31
|
after_initialize :build_source
|
31
32
|
|
32
33
|
scope :from_credit_card, -> { where(source_type: 'Spree::CreditCard') }
|
33
34
|
scope :with_state, ->(s) { where(state: s.to_s) }
|
34
35
|
scope :completed, -> { with_state('completed') }
|
35
36
|
scope :pending, -> { with_state('pending') }
|
37
|
+
scope :processing, -> { with_state('processing') }
|
36
38
|
scope :failed, -> { with_state('failed') }
|
37
39
|
scope :risky, -> { where("avs_response IN (?) OR (cvv_response_code IS NOT NULL and cvv_response_code != 'M') OR state = 'failed'", RISKY_AVS_CODES) }
|
38
40
|
scope :valid, -> { where.not(state: %w(failed invalid)) }
|
@@ -50,6 +52,10 @@ module Spree
|
|
50
52
|
# order state machine (see http://github.com/pluginaweek/state_machine/tree/master for details)
|
51
53
|
state_machine initial: :checkout do
|
52
54
|
# With card payments, happens before purchase or authorization happens
|
55
|
+
#
|
56
|
+
# Setting it after creating a profile and authorizing a full amount will
|
57
|
+
# prevent the payment from being authorized again once Order transitions
|
58
|
+
# to complete
|
53
59
|
event :started_processing do
|
54
60
|
transition from: [:checkout, :pending, :completed, :processing], to: :processing
|
55
61
|
end
|
@@ -66,7 +72,7 @@ module Spree
|
|
66
72
|
transition from: [:processing, :pending, :checkout], to: :completed
|
67
73
|
end
|
68
74
|
event :void do
|
69
|
-
transition from: [:pending, :completed, :checkout], to: :void
|
75
|
+
transition from: [:pending, :processing, :completed, :checkout], to: :void
|
70
76
|
end
|
71
77
|
# when the card brand isnt supported
|
72
78
|
event :invalidate do
|
@@ -166,8 +172,7 @@ module Spree
|
|
166
172
|
end
|
167
173
|
|
168
174
|
def create_payment_profile
|
169
|
-
return unless source.respond_to?(:has_payment_profile?) && !source.has_payment_profile?
|
170
|
-
state != 'invalid' && state != 'failed'
|
175
|
+
return unless source.respond_to?(:has_payment_profile?) && !source.has_payment_profile?
|
171
176
|
|
172
177
|
payment_method.create_profile(self)
|
173
178
|
rescue ActiveMerchant::ConnectionError => e
|
@@ -175,16 +180,25 @@ module Spree
|
|
175
180
|
end
|
176
181
|
|
177
182
|
def invalidate_old_payments
|
178
|
-
|
179
|
-
|
180
|
-
payment.invalidate!
|
181
|
-
end
|
183
|
+
order.payments.with_state('checkout').where("id != ?", self.id).each do |payment|
|
184
|
+
payment.invalidate!
|
182
185
|
end
|
183
186
|
end
|
184
187
|
|
185
188
|
def update_order
|
186
|
-
|
187
|
-
|
189
|
+
if self.completed?
|
190
|
+
order.updater.update_payment_total
|
191
|
+
end
|
192
|
+
|
193
|
+
if order.completed?
|
194
|
+
order.updater.update_payment_state
|
195
|
+
order.updater.update_shipments
|
196
|
+
order.updater.update_shipment_state
|
197
|
+
end
|
198
|
+
|
199
|
+
if self.completed? || order.completed?
|
200
|
+
order.persist_totals
|
201
|
+
end
|
188
202
|
end
|
189
203
|
|
190
204
|
# Necessary because some payment gateways will refuse payments with
|
@@ -1,11 +1,11 @@
|
|
1
1
|
module Spree
|
2
|
-
class Payment <
|
2
|
+
class Payment < Spree::Base
|
3
3
|
module Processing
|
4
4
|
def process!
|
5
5
|
if payment_method && payment_method.source_required?
|
6
6
|
if source
|
7
7
|
if !processing?
|
8
|
-
if payment_method.supports?(source)
|
8
|
+
if payment_method.supports?(source)
|
9
9
|
if payment_method.auto_capture?
|
10
10
|
purchase!
|
11
11
|
else
|
@@ -81,17 +81,11 @@ module Spree
|
|
81
81
|
end
|
82
82
|
|
83
83
|
def credit!(credit_amount=nil)
|
84
|
-
raise Core::GatewayError.new(Spree.t(:payment_processing_failed)) if processing?
|
85
|
-
|
86
|
-
# Calculate credit amount before marking as processing since it messes up the order totals not having payment in completed state.
|
87
|
-
credit_amount ||= credit_allowed >= order.outstanding_balance.abs ? order.outstanding_balance.abs : credit_allowed.abs
|
88
|
-
credit_amount = credit_amount.to_f
|
89
|
-
|
90
|
-
# Mark as processing to avoid race condition that could send multiple credits to the gateway.
|
91
|
-
started_processing!
|
92
84
|
protect_from_connection_error do
|
93
85
|
check_environment
|
94
86
|
|
87
|
+
credit_amount ||= credit_allowed >= order.outstanding_balance.abs ? order.outstanding_balance.abs : credit_allowed.abs
|
88
|
+
credit_amount = credit_amount.to_f
|
95
89
|
credit_cents = Spree::Money.new(credit_amount, currency: currency).money.cents
|
96
90
|
|
97
91
|
if payment_method.payment_profiles_supported?
|
@@ -101,8 +95,6 @@ module Spree
|
|
101
95
|
end
|
102
96
|
|
103
97
|
record_response(response)
|
104
|
-
# Always set back to 'completed' as initial payment record was successful.
|
105
|
-
self.update_column(:state, 'completed')
|
106
98
|
|
107
99
|
if response.success?
|
108
100
|
self.class.create!(
|
@@ -129,6 +121,7 @@ module Spree
|
|
129
121
|
|
130
122
|
def partial_credit(amount)
|
131
123
|
return if amount > credit_allowed
|
124
|
+
started_processing!
|
132
125
|
credit!(amount)
|
133
126
|
end
|
134
127
|
|
@@ -226,10 +219,6 @@ module Spree
|
|
226
219
|
def gateway_order_id
|
227
220
|
"#{order.number}-#{self.identifier}"
|
228
221
|
end
|
229
|
-
|
230
|
-
def token_based?
|
231
|
-
source.gateway_customer_profile_id.present? || source.gateway_payment_profile_id.present?
|
232
|
-
end
|
233
222
|
end
|
234
223
|
end
|
235
224
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Spree
|
2
|
-
class PaymentMethod <
|
2
|
+
class PaymentMethod < Spree::Base
|
3
3
|
acts_as_paranoid
|
4
4
|
DISPLAY = [:both, :front_end, :back_end]
|
5
5
|
default_scope -> { where(deleted_at: nil) }
|
@@ -8,7 +8,7 @@ module Spree
|
|
8
8
|
|
9
9
|
validates :name, presence: true
|
10
10
|
|
11
|
-
has_many :payments, class_name: "Spree::Payment"
|
11
|
+
has_many :payments, class_name: "Spree::Payment"
|
12
12
|
has_many :credit_cards, class_name: "Spree::CreditCard"
|
13
13
|
|
14
14
|
def self.providers
|
@@ -1,35 +1,5 @@
|
|
1
|
-
class Spree::Preference <
|
1
|
+
class Spree::Preference < Spree::Base
|
2
2
|
serialize :value
|
3
3
|
|
4
4
|
validates :key, presence: true
|
5
|
-
validates :value_type, presence: true
|
6
|
-
|
7
|
-
scope :valid, -> { where(Spree::Preference.arel_table[:key].not_eq(nil)).where(Spree::Preference.arel_table[:value_type].not_eq(nil)) }
|
8
|
-
|
9
|
-
# The type conversions here should match
|
10
|
-
# the ones in spree::preferences::preferrable#convert_preference_value
|
11
|
-
def value
|
12
|
-
if self[:value_type].present?
|
13
|
-
case self[:value_type].to_sym
|
14
|
-
when :string, :text
|
15
|
-
self[:value].to_s
|
16
|
-
when :password
|
17
|
-
self[:value].to_s
|
18
|
-
when :decimal
|
19
|
-
BigDecimal.new(self[:value].to_s).round(2, BigDecimal::ROUND_HALF_UP)
|
20
|
-
when :integer
|
21
|
-
self[:value].to_i
|
22
|
-
when :boolean
|
23
|
-
(self[:value].to_s =~ /^[t|1]/i) != nil
|
24
|
-
else
|
25
|
-
self[:value].is_a?(String) ? YAML.load(self[:value]) : self[:value]
|
26
|
-
end
|
27
|
-
else
|
28
|
-
self[:value]
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def raw_value
|
33
|
-
self[:value]
|
34
|
-
end
|
35
5
|
end
|
@@ -28,12 +28,8 @@ module Spree::Preferences
|
|
28
28
|
yield(self) if block_given?
|
29
29
|
end
|
30
30
|
|
31
|
-
def
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
def rails_cache_id
|
36
|
-
ENV['RAILS_CACHE_ID']
|
31
|
+
def preferences
|
32
|
+
ScopedStore.new(self.class.name.underscore)
|
37
33
|
end
|
38
34
|
|
39
35
|
def reset
|
@@ -1,40 +1,47 @@
|
|
1
|
-
#
|
2
|
-
# can be set. The default behavior is to return nil if there is no
|
3
|
-
# id value. On ActiveRecords, new objects will have their preferences
|
4
|
-
# saved to a pending hash until it is persisted.
|
1
|
+
# Preferable allows defining preference accessor methods.
|
5
2
|
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
3
|
+
# A class including Preferable must implement #preferences which should return
|
4
|
+
# an object responding to .fetch(key), []=(key, val), and .delete(key).
|
5
|
+
#
|
6
|
+
# The generated writer method performs typecasting before assignment into the
|
7
|
+
# preferences object.
|
8
|
+
#
|
9
|
+
# Examples:
|
10
|
+
#
|
11
|
+
# # Spree::Base includes Preferable and defines preferences as a serialized
|
12
|
+
# # column.
|
13
|
+
# class Settings < Spree::Base
|
14
|
+
# preference :color, :string, default: 'red'
|
15
|
+
# preference :temperature, :integer, default: 21
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# s = Settings.new
|
19
|
+
# s.preferred_color # => 'red'
|
20
|
+
# s.preferred_temperature # => 21
|
21
|
+
#
|
22
|
+
# s.preferred_color = 'blue'
|
23
|
+
# s.preferred_color # => 'blue'
|
24
|
+
#
|
25
|
+
# # Typecasting is performed on assignment
|
26
|
+
# s.preferred_temperature = '24'
|
27
|
+
# s.preferred_color # => 24
|
28
|
+
#
|
29
|
+
# # Modifications have been made to the .preferences hash
|
30
|
+
# s.preferences #=> {color: 'blue', temperature: 24}
|
31
|
+
#
|
32
|
+
# # Save the changes. All handled by activerecord
|
33
|
+
# s.save!
|
11
34
|
module Spree::Preferences::Preferable
|
35
|
+
extend ActiveSupport::Concern
|
12
36
|
|
13
|
-
|
14
|
-
|
15
|
-
extend Spree::Preferences::PreferableClassMethods
|
16
|
-
|
17
|
-
if respond_to?(:after_create)
|
18
|
-
after_create do |obj|
|
19
|
-
obj.save_pending_preferences
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
if respond_to?(:after_destroy)
|
24
|
-
after_destroy do |obj|
|
25
|
-
obj.clear_preferences
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
end
|
37
|
+
included do
|
38
|
+
extend Spree::Preferences::PreferableClassMethods
|
30
39
|
end
|
31
40
|
|
32
41
|
def get_preference(name)
|
33
42
|
has_preference! name
|
34
43
|
send self.class.preference_getter_method(name)
|
35
44
|
end
|
36
|
-
alias :preferred :get_preference
|
37
|
-
alias :prefers? :get_preference
|
38
45
|
|
39
46
|
def set_preference(name, value)
|
40
47
|
has_preference! name
|
@@ -51,11 +58,6 @@ module Spree::Preferences::Preferable
|
|
51
58
|
send self.class.preference_default_getter_method(name)
|
52
59
|
end
|
53
60
|
|
54
|
-
def preference_description(name)
|
55
|
-
has_preference! name
|
56
|
-
send self.class.preference_description_getter_method(name)
|
57
|
-
end
|
58
|
-
|
59
61
|
def has_preference!(name)
|
60
62
|
raise NoMethodError.new "#{name} preference not defined" unless has_preference? name
|
61
63
|
end
|
@@ -64,50 +66,26 @@ module Spree::Preferences::Preferable
|
|
64
66
|
respond_to? self.class.preference_getter_method(name)
|
65
67
|
end
|
66
68
|
|
67
|
-
def
|
68
|
-
|
69
|
-
|
70
|
-
prefs[pref_method.to_s.gsub(/prefers_|\?/, '').to_sym] = send(pref_method)
|
69
|
+
def defined_preferences
|
70
|
+
methods.grep(/\Apreferred_.*=\Z/).map do |pref_method|
|
71
|
+
pref_method.to_s.gsub(/\Apreferred_|=\Z/, '').to_sym
|
71
72
|
end
|
72
|
-
prefs
|
73
73
|
end
|
74
74
|
|
75
|
-
def
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
[rails_cache_id, self.class.name, name, id].compact.join('::').underscore
|
82
|
-
end
|
83
|
-
|
84
|
-
def rails_cache_id
|
85
|
-
ENV['RAILS_CACHE_ID']
|
86
|
-
end
|
87
|
-
|
88
|
-
def save_pending_preferences
|
89
|
-
return unless @pending_preferences
|
90
|
-
@pending_preferences.each do |name, value|
|
91
|
-
set_preference(name, value)
|
92
|
-
end
|
75
|
+
def default_preferences
|
76
|
+
Hash[
|
77
|
+
defined_preferences.map do |preference|
|
78
|
+
[preference, preference_default(preference)]
|
79
|
+
end
|
80
|
+
]
|
93
81
|
end
|
94
82
|
|
95
83
|
def clear_preferences
|
96
|
-
preferences.keys.each {|pref|
|
84
|
+
preferences.keys.each {|pref| preferences.delete pref}
|
97
85
|
end
|
98
86
|
|
99
87
|
private
|
100
88
|
|
101
|
-
def add_pending_preference(name, value)
|
102
|
-
@pending_preferences ||= {}
|
103
|
-
@pending_preferences[name] = value
|
104
|
-
end
|
105
|
-
|
106
|
-
def get_pending_preference(name)
|
107
|
-
return unless @pending_preferences
|
108
|
-
@pending_preferences[name]
|
109
|
-
end
|
110
|
-
|
111
89
|
def convert_preference_value(value, type)
|
112
90
|
case type
|
113
91
|
when :string, :text
|
@@ -115,7 +93,7 @@ module Spree::Preferences::Preferable
|
|
115
93
|
when :password
|
116
94
|
value.to_s
|
117
95
|
when :decimal
|
118
|
-
BigDecimal.new(value.to_s)
|
96
|
+
BigDecimal.new(value.to_s)
|
119
97
|
when :integer
|
120
98
|
value.to_i
|
121
99
|
when :boolean
|
@@ -132,10 +110,4 @@ module Spree::Preferences::Preferable
|
|
132
110
|
value
|
133
111
|
end
|
134
112
|
end
|
135
|
-
|
136
|
-
def preference_store
|
137
|
-
Spree::Preferences::Store.instance
|
138
|
-
end
|
139
|
-
|
140
113
|
end
|
141
|
-
|