spree_core 2.3.13 → 2.4.0.rc1
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/assets/javascripts/spree.js.coffee.erb +1 -5
- data/app/helpers/spree/base_helper.rb +22 -11
- data/app/helpers/spree/products_helper.rb +8 -7
- data/app/mailers/spree/base_mailer.rb +1 -0
- data/app/mailers/spree/reimbursement_mailer.rb +10 -0
- data/app/mailers/spree/test_mailer.rb +2 -3
- data/app/models/concerns/spree/adjustment_source.rb +24 -0
- data/app/models/concerns/spree/calculated_adjustments.rb +33 -0
- data/app/models/concerns/spree/named_type.rb +12 -0
- data/app/models/concerns/spree/user_address.rb +30 -0
- data/app/models/concerns/spree/user_payment_source.rb +19 -0
- data/app/models/spree/address.rb +13 -6
- data/app/models/spree/adjustment.rb +5 -5
- data/app/models/spree/app_configuration.rb +8 -4
- data/app/models/spree/asset.rb +1 -1
- data/app/models/spree/base.rb +0 -3
- data/app/models/spree/calculator/flat_rate.rb +1 -5
- data/app/models/spree/calculator/returns/default_refund_amount.rb +36 -0
- data/app/models/spree/classification.rb +1 -1
- data/app/models/spree/credit_card.rb +18 -22
- data/app/models/spree/customer_return.rb +70 -0
- data/app/models/spree/exchange.rb +42 -0
- data/app/models/spree/gateway/bogus.rb +3 -3
- data/app/models/spree/image.rb +1 -1
- data/app/models/spree/inventory_unit.rb +32 -8
- data/app/models/spree/item_adjustments.rb +7 -11
- data/app/models/spree/legacy_user.rb +2 -2
- data/app/models/spree/line_item.rb +25 -12
- data/app/models/spree/option_type.rb +1 -1
- data/app/models/spree/option_value.rb +1 -8
- data/app/models/spree/order.rb +163 -145
- data/app/models/spree/order/checkout.rb +35 -23
- data/app/models/spree/order/payments.rb +66 -0
- data/app/models/spree/order_contents.rb +34 -24
- data/app/models/spree/order_populator.rb +6 -4
- data/app/models/spree/order_updater.rb +10 -1
- data/app/models/spree/payment.rb +19 -16
- data/app/models/spree/payment/processing.rb +40 -72
- data/app/models/spree/payment_method.rb +1 -1
- data/app/models/spree/payment_method/check.rb +0 -2
- data/app/models/spree/preference.rb +1 -1
- data/app/models/spree/preferences/preferable.rb +20 -0
- data/app/models/spree/price.rb +13 -3
- data/app/models/spree/product.rb +24 -29
- data/app/models/spree/product_property.rb +0 -2
- data/app/models/spree/promotion.rb +66 -24
- data/app/models/spree/promotion/actions/create_adjustment.rb +2 -2
- data/app/models/spree/promotion/actions/create_item_adjustments.rb +15 -11
- data/app/models/spree/promotion/actions/create_line_items.rb +2 -12
- data/app/models/spree/promotion/rules/first_order.rb +6 -2
- data/app/models/spree/promotion/rules/item_total.rb +42 -4
- data/app/models/spree/promotion/rules/one_use_per_user.rb +24 -0
- data/app/models/spree/promotion/rules/product.rb +13 -11
- data/app/models/spree/promotion/rules/taxon.rb +61 -0
- data/app/models/spree/promotion/rules/user.rb +1 -1
- data/app/models/spree/promotion/rules/user_logged_in.rb +4 -1
- data/app/models/spree/promotion_category.rb +6 -0
- data/app/models/spree/promotion_handler/cart.rb +14 -18
- data/app/models/spree/promotion_handler/coupon.rb +25 -16
- data/app/models/spree/promotion_rule.rb +13 -0
- data/app/models/spree/property.rb +1 -3
- data/app/models/spree/refund.rb +91 -0
- data/app/models/spree/refund_reason.rb +13 -0
- data/app/models/spree/reimbursement.rb +148 -0
- data/app/models/spree/reimbursement/credit.rb +25 -0
- data/app/models/spree/reimbursement/reimbursement_type_engine.rb +56 -0
- data/app/models/spree/reimbursement/reimbursement_type_validator.rb +12 -0
- data/app/models/spree/reimbursement_performer.rb +43 -0
- data/app/models/spree/reimbursement_tax_calculator.rb +38 -0
- data/app/models/spree/reimbursement_type.rb +16 -0
- data/app/models/spree/reimbursement_type/credit.rb +13 -0
- data/app/models/spree/reimbursement_type/exchange.rb +9 -0
- data/app/models/spree/reimbursement_type/original_payment.rb +13 -0
- data/app/models/spree/reimbursement_type/reimbursement_helpers.rb +50 -0
- data/app/models/spree/return_authorization.rb +52 -68
- data/app/models/spree/return_authorization_reason.rb +7 -0
- data/app/models/spree/return_item.rb +230 -0
- data/app/models/spree/return_item/default_eligibility_validator.rb +27 -0
- data/app/models/spree/return_item/eligibility_validator/base_validator.rb +24 -0
- data/app/models/spree/return_item/eligibility_validator/rma_required.rb +17 -0
- data/app/models/spree/return_item/eligibility_validator/time_since_purchase.rb +16 -0
- data/app/models/spree/return_item/exchange_variant_eligibility/same_option_value.rb +34 -0
- data/app/models/spree/return_item/exchange_variant_eligibility/same_product.rb +10 -0
- data/app/models/spree/returns_calculator.rb +8 -0
- data/app/models/spree/shipment.rb +209 -154
- data/app/models/spree/shipment_handler.rb +43 -0
- data/app/models/spree/shipping_calculator.rb +1 -1
- data/app/models/spree/shipping_category.rb +2 -2
- data/app/models/spree/shipping_method.rb +1 -1
- data/app/models/spree/shipping_method_category.rb +1 -1
- data/app/models/spree/shipping_rate.rb +4 -0
- data/app/models/spree/stock/adjuster.rb +10 -11
- data/app/models/spree/stock/availability_validator.rb +6 -10
- data/app/models/spree/stock/content_item.rb +48 -0
- data/app/models/spree/stock/coordinator.rb +14 -7
- data/app/models/spree/stock/estimator.rb +1 -1
- data/app/models/spree/stock/inventory_unit_builder.rb +21 -0
- data/app/models/spree/stock/package.rb +38 -51
- data/app/models/spree/stock/packer.rb +13 -11
- data/app/models/spree/stock/prioritizer.rb +7 -7
- data/app/models/spree/stock/splitter/base.rb +2 -2
- data/app/models/spree/stock_item.rb +6 -9
- data/app/models/spree/stock_location.rb +17 -25
- data/app/models/spree/stock_movement.rb +1 -8
- data/app/models/spree/stock_transfer.rb +0 -2
- data/app/models/spree/store.rb +1 -1
- data/app/models/spree/tax_category.rb +2 -2
- data/app/models/spree/tax_rate.rb +16 -22
- data/app/models/spree/taxon.rb +1 -1
- data/app/models/spree/variant.rb +45 -23
- data/app/models/spree/zone.rb +17 -17
- data/app/models/spree/zone_member.rb +1 -1
- data/app/views/layouts/spree/base_mailer.html.erb +784 -0
- data/app/views/spree/order_mailer/cancel_email.html.erb +45 -0
- data/app/views/spree/order_mailer/cancel_email.text.erb +2 -2
- data/app/views/spree/order_mailer/confirm_email.html.erb +84 -0
- data/app/views/spree/order_mailer/confirm_email.text.erb +2 -2
- data/app/views/spree/reimbursement_mailer/reimbursement_email.text.erb +22 -0
- data/app/views/spree/shared/_base_mailer_footer.html.erb +20 -0
- data/app/views/spree/shared/_base_mailer_header.html.erb +31 -0
- data/app/views/spree/shipment_mailer/shipped_email.html.erb +34 -0
- data/app/views/spree/test_mailer/test_email.html.erb +40 -0
- data/app/views/spree/test_mailer/test_email.text.erb +2 -2
- data/config/initializers/friendly_id.rb +88 -0
- data/config/initializers/premailer_assets.rb +1 -0
- data/config/initializers/user_class_extensions.rb +9 -22
- data/config/locales/en.yml +180 -12
- data/db/default/spree/states.rb +73 -55
- data/db/migrate/20130213191427_create_default_stock.rb +1 -0
- data/db/migrate/20130807024301_upgrade_adjustments.rb +4 -5
- data/db/migrate/20140309033438_create_store_from_preferences.rb +0 -7
- data/db/migrate/20140318191500_create_spree_taxons_promotion_rules.rb +8 -0
- data/db/migrate/20140530024945_move_order_token_from_tokenized_permission.rb +1 -1
- data/db/migrate/20140601011216_set_shipment_total_for_users_upgrading.rb +5 -3
- data/db/migrate/20140625214618_create_spree_refunds.rb +12 -0
- data/db/migrate/20140702140656_create_spree_return_authorization_inventory_unit.rb +12 -0
- data/db/migrate/20140707125621_rename_return_authorization_inventory_unit_to_return_items.rb +5 -0
- data/db/migrate/20140709160534_backfill_line_item_pre_tax_amount.rb +10 -0
- data/db/migrate/20140710041921_recreate_spree_return_authorizations.rb +55 -0
- data/db/migrate/20140710181204_add_amount_fields_to_return_items.rb +7 -0
- data/db/migrate/20140710190048_drop_return_authorization_amount.rb +5 -0
- data/db/migrate/20140713140455_create_spree_return_authorization_reasons.rb +28 -0
- data/db/migrate/20140713140527_create_spree_refund_reasons.rb +14 -0
- data/db/migrate/20140713142214_rename_return_authorization_reason.rb +5 -0
- data/db/migrate/20140715182625_create_spree_promotion_categories.rb +11 -0
- data/db/migrate/20140716204111_drop_received_at_on_return_items.rb +9 -0
- data/db/migrate/20140716212330_add_reception_and_acceptance_status_to_return_items.rb +6 -0
- data/db/migrate/20140717155155_create_default_refund_reason.rb +9 -0
- data/db/migrate/20140717185932_add_default_to_spree_stock_locations.rb +5 -0
- data/db/migrate/20140718133010_create_spree_customer_returns.rb +9 -0
- data/db/migrate/20140718133349_add_customer_return_id_to_return_item.rb +6 -0
- data/db/migrate/20140718195325_create_friendly_id_slugs.rb +15 -0
- data/db/migrate/20140723004419_rename_spree_refund_return_authorization_id.rb +5 -0
- data/db/migrate/20140723152808_increase_return_item_pre_tax_amount_precision.rb +13 -0
- data/db/migrate/20140723214541_copy_product_slugs_to_slug_history.rb +15 -0
- data/db/migrate/20140725131539_create_spree_reimbursements.rb +21 -0
- data/db/migrate/20140728225422_add_promotionable_to_spree_products.rb +5 -0
- data/db/migrate/20140729133613_add_exchange_inventory_unit_foreign_keys.rb +7 -0
- data/db/migrate/20140730155938_add_acceptance_status_errors_to_return_item.rb +5 -0
- data/db/migrate/20140731150017_create_spree_reimbursement_types.rb +20 -0
- data/db/migrate/20140805171035_add_default_to_spree_credit_cards.rb +5 -0
- data/db/migrate/20140805171219_make_existing_credit_cards_default.rb +10 -0
- data/db/migrate/20140806144901_add_type_to_reimbursement_type.rb +9 -0
- data/db/migrate/20140808184039_create_spree_reimbursement_credits.rb +10 -0
- data/db/migrate/20140827170513_add_meta_title_to_spree_products.rb +7 -0
- data/db/migrate/20140924164824_add_code_to_spree_tax_categories.rb +5 -0
- data/db/migrate/20141002191113_add_code_to_spree_shipping_methods.rb +5 -0
- data/db/migrate/20141007230328_add_cancel_audit_fields_to_spree_orders.rb +6 -0
- data/db/migrate/20141009204607_add_store_id_to_orders.rb +8 -0
- data/lib/generators/spree/install/install_generator.rb +7 -3
- data/lib/spree/core.rb +11 -10
- data/lib/spree/core/controller_helpers/common.rb +3 -10
- data/lib/spree/core/controller_helpers/order.rb +15 -12
- data/lib/spree/core/controller_helpers/strong_parameters.rb +9 -9
- data/lib/spree/core/engine.rb +8 -1
- data/lib/spree/core/importer/order.rb +5 -17
- data/lib/spree/core/search/base.rb +1 -1
- data/lib/spree/core/validators/email.rb +1 -1
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/instrumentation.rb +41 -0
- data/lib/spree/migrations.rb +3 -7
- data/lib/spree/money.rb +2 -2
- data/lib/spree/permitted_attributes.rb +10 -9
- data/lib/spree/testing_support/ability_helpers.rb +25 -25
- data/lib/spree/testing_support/authorization_helpers.rb +3 -5
- data/lib/spree/testing_support/capybara_ext.rb +2 -2
- data/lib/spree/testing_support/factories/calculator_factory.rb +0 -8
- data/lib/spree/testing_support/factories/credit_card_factory.rb +1 -1
- data/lib/spree/testing_support/factories/customer_return_factory.rb +31 -0
- data/lib/spree/testing_support/factories/inventory_unit_factory.rb +1 -0
- data/lib/spree/testing_support/factories/line_item_factory.rb +2 -1
- data/lib/spree/testing_support/factories/order_factory.rb +11 -6
- data/lib/spree/testing_support/factories/promotion_category_factory.rb +6 -0
- data/lib/spree/testing_support/factories/promotion_factory.rb +9 -7
- data/lib/spree/testing_support/factories/refund_factory.rb +14 -0
- data/lib/spree/testing_support/factories/reimbursement_factory.rb +16 -0
- data/lib/spree/testing_support/factories/reimbursement_type_factory.rb +7 -0
- data/lib/spree/testing_support/factories/return_authorization_factory.rb +9 -3
- data/lib/spree/testing_support/factories/return_item_factory.rb +10 -0
- data/lib/spree/testing_support/factories/shipment_factory.rb +1 -0
- data/lib/spree/testing_support/factories/shipping_method_factory.rb +3 -2
- data/lib/spree/testing_support/factories/stock_factory.rb +12 -11
- data/lib/spree/testing_support/flash.rb +2 -2
- data/lib/tasks/email.rake +7 -0
- data/lib/tasks/exchanges.rake +70 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_et.js +23 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_eu.js +25 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_hr.js +25 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_ka.js +25 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_ko.js +25 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_my.js +25 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_pt_BR.js +26 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_pt_PT.js +26 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_sl.js +25 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_sv.js +23 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_uk.js +25 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_zh.js +25 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_zh_TW.js +26 -0
- metadata +163 -47
- data/app/models/concerns/spree/ransackable_attributes.rb +0 -19
- data/db/migrate/20141021194502_add_state_lock_version_to_order.rb +0 -5
- data/db/migrate/20141101231208_fix_adjustment_order_presence.rb +0 -13
- data/db/migrate/20141105213646_update_classifications_positions.rb +0 -9
- data/db/migrate/20141120135441_add_guest_token_index_to_spree_orders.rb +0 -5
- data/db/migrate/20150515211137_fix_adjustment_order_id.rb +0 -70
- data/lib/spree/core/adjustment_source.rb +0 -26
- data/lib/spree/core/calculated_adjustments.rb +0 -35
- data/lib/spree/core/controller_helpers.rb +0 -20
- data/lib/spree/core/user_address.rb +0 -32
- data/lib/spree/core/user_payment_source.rb +0 -20
- data/lib/spree/localized_number.rb +0 -20
|
@@ -58,7 +58,7 @@ module Spree
|
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
event :return do
|
|
61
|
-
transition to: :returned, from: :awaiting_return,
|
|
61
|
+
transition to: :returned, from: [:complete, :awaiting_return, :canceled], if: :all_inventory_units_returned?
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
event :resume do
|
|
@@ -78,6 +78,10 @@ module Spree
|
|
|
78
78
|
order.process_payments!
|
|
79
79
|
end
|
|
80
80
|
end
|
|
81
|
+
after_transition to: :complete, do: :persist_user_credit_card
|
|
82
|
+
before_transition to: :payment, do: :set_shipments_cost
|
|
83
|
+
before_transition to: :payment, do: :create_tax_charge!
|
|
84
|
+
before_transition to: :payment, do: :assign_default_credit_card
|
|
81
85
|
end
|
|
82
86
|
|
|
83
87
|
before_transition from: :cart, do: :ensure_line_items_present
|
|
@@ -88,11 +92,6 @@ module Spree
|
|
|
88
92
|
before_transition from: :address, do: :persist_user_address!
|
|
89
93
|
end
|
|
90
94
|
|
|
91
|
-
if states[:payment]
|
|
92
|
-
before_transition to: :payment, do: :set_shipments_cost
|
|
93
|
-
before_transition to: :payment, do: :create_tax_charge!
|
|
94
|
-
end
|
|
95
|
-
|
|
96
95
|
if states[:delivery]
|
|
97
96
|
before_transition to: :delivery, do: :create_proposed_shipments
|
|
98
97
|
before_transition to: :delivery, do: :ensure_available_shipping_rates
|
|
@@ -102,8 +101,6 @@ module Spree
|
|
|
102
101
|
|
|
103
102
|
before_transition to: :resumed, do: :ensure_line_items_are_in_stock
|
|
104
103
|
|
|
105
|
-
before_transition to: :complete, do: :ensure_line_items_are_in_stock
|
|
106
|
-
|
|
107
104
|
after_transition to: :complete, do: :finalize!
|
|
108
105
|
after_transition to: :resumed, do: :after_resume
|
|
109
106
|
after_transition to: :canceled, do: :after_cancel
|
|
@@ -203,8 +200,12 @@ module Spree
|
|
|
203
200
|
step.present? && self.checkout_steps.include?(step)
|
|
204
201
|
end
|
|
205
202
|
|
|
203
|
+
def passed_checkout_step?(step)
|
|
204
|
+
has_checkout_step?(step) && checkout_step_index(step) < checkout_step_index(self.state)
|
|
205
|
+
end
|
|
206
|
+
|
|
206
207
|
def checkout_step_index(step)
|
|
207
|
-
self.checkout_steps.index(step)
|
|
208
|
+
self.checkout_steps.index(step).to_i
|
|
208
209
|
end
|
|
209
210
|
|
|
210
211
|
def self.removed_transitions
|
|
@@ -228,10 +229,7 @@ module Spree
|
|
|
228
229
|
|
|
229
230
|
# Set existing card after setting permitted parameters because
|
|
230
231
|
# rails would slice parameters containg ruby objects, apparently
|
|
231
|
-
|
|
232
|
-
# Need to check both outside and inside :order beacuse frontend
|
|
233
|
-
# sends existing_card out of :order
|
|
234
|
-
existing_card_id = @updating_params[:existing_card] || (@updating_params[:order] ? @updating_params[:order][:existing_card] : nil)
|
|
232
|
+
existing_card_id = @updating_params[:order] ? @updating_params[:order][:existing_card] : nil
|
|
235
233
|
|
|
236
234
|
if existing_card_id.present?
|
|
237
235
|
credit_card = CreditCard.find existing_card_id
|
|
@@ -273,6 +271,22 @@ module Spree
|
|
|
273
271
|
end
|
|
274
272
|
end
|
|
275
273
|
|
|
274
|
+
def persist_user_credit_card
|
|
275
|
+
if !self.temporary_credit_card && self.user_id && self.valid_credit_cards.present?
|
|
276
|
+
default_cc = self.valid_credit_cards.first
|
|
277
|
+
default_cc.user_id = self.user_id
|
|
278
|
+
default_cc.default = true
|
|
279
|
+
default_cc.save
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
def assign_default_credit_card
|
|
284
|
+
if self.payments.from_credit_card.count == 0 && self.user && self.user.default_credit_card.try(:valid?)
|
|
285
|
+
cc = self.user.default_credit_card
|
|
286
|
+
self.payments.create!(payment_method_id: cc.payment_method_id, source: cc)
|
|
287
|
+
end
|
|
288
|
+
end
|
|
289
|
+
|
|
276
290
|
private
|
|
277
291
|
# For payment step, filter order parameters to produce the expected nested
|
|
278
292
|
# attributes for a single payment and its source, discarding attributes
|
|
@@ -288,19 +302,17 @@ module Spree
|
|
|
288
302
|
# }
|
|
289
303
|
#
|
|
290
304
|
def update_params_payment_source
|
|
291
|
-
if
|
|
292
|
-
|
|
293
|
-
source_params = @updating_params.delete(:payment_source)[@updating_params[:order][:payments_attributes].first[:payment_method_id].to_s]
|
|
305
|
+
if @updating_params[:payment_source].present?
|
|
306
|
+
source_params = @updating_params.delete(:payment_source)[@updating_params[:order][:payments_attributes].first[:payment_method_id].to_s]
|
|
294
307
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
end
|
|
308
|
+
if source_params
|
|
309
|
+
@updating_params[:order][:payments_attributes].first[:source_attributes] = source_params
|
|
298
310
|
end
|
|
311
|
+
end
|
|
299
312
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
end
|
|
313
|
+
if @updating_params[:order] && (@updating_params[:order][:payments_attributes] || @updating_params[:order][:existing_card])
|
|
314
|
+
@updating_params[:order][:payments_attributes] ||= [{}]
|
|
315
|
+
@updating_params[:order][:payments_attributes].first[:amount] = self.total
|
|
304
316
|
end
|
|
305
317
|
end
|
|
306
318
|
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
class Order < Spree::Base
|
|
3
|
+
module Payments
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
included do
|
|
6
|
+
# processes any pending payments and must return a boolean as it's
|
|
7
|
+
# return value is used by the checkout state_machine to determine
|
|
8
|
+
# success or failure of the 'complete' event for the order
|
|
9
|
+
#
|
|
10
|
+
# Returns:
|
|
11
|
+
#
|
|
12
|
+
# - true if all pending_payments processed successfully
|
|
13
|
+
#
|
|
14
|
+
# - true if a payment failed, ie. raised a GatewayError
|
|
15
|
+
# which gets rescued and converted to TRUE when
|
|
16
|
+
# :allow_checkout_gateway_error is set to true
|
|
17
|
+
#
|
|
18
|
+
# - false if a payment failed, ie. raised a GatewayError
|
|
19
|
+
# which gets rescued and converted to FALSE when
|
|
20
|
+
# :allow_checkout_on_gateway_error is set to false
|
|
21
|
+
#
|
|
22
|
+
def process_payments!
|
|
23
|
+
process_payments_with(:process!)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def authorize_payments!
|
|
27
|
+
process_payments_with(:authorize!)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def capture_payments!
|
|
31
|
+
process_payments_with(:purchase!)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def pending_payments
|
|
35
|
+
payments.select { |payment| payment.pending? }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def unprocessed_payments
|
|
39
|
+
payments.select { |payment| payment.checkout? }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def process_payments_with(method)
|
|
45
|
+
# Don't run if there is nothing to pay.
|
|
46
|
+
return if payment_total >= total
|
|
47
|
+
# Prevent orders from transitioning to complete without a successfully processed payment.
|
|
48
|
+
raise Core::GatewayError.new(Spree.t(:no_payment_found)) if unprocessed_payments.empty?
|
|
49
|
+
|
|
50
|
+
unprocessed_payments.each do |payment|
|
|
51
|
+
break if payment_total >= total
|
|
52
|
+
|
|
53
|
+
payment.public_send(method)
|
|
54
|
+
|
|
55
|
+
if payment.completed?
|
|
56
|
+
self.payment_total += payment.amount
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
rescue Core::GatewayError => e
|
|
60
|
+
result = !!Spree::Config[:allow_checkout_on_gateway_error]
|
|
61
|
+
errors.add(:base, e.message) and return result
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -6,9 +6,10 @@ module Spree
|
|
|
6
6
|
@order = order
|
|
7
7
|
end
|
|
8
8
|
|
|
9
|
-
def add(variant, quantity = 1,
|
|
10
|
-
line_item = add_to_line_item(variant, quantity,
|
|
9
|
+
def add(variant, quantity = 1, options = {})
|
|
10
|
+
line_item = add_to_line_item(variant, quantity, options)
|
|
11
11
|
reload_totals
|
|
12
|
+
shipment = options[:shipment]
|
|
12
13
|
shipment.present? ? shipment.update_amounts : order.ensure_updated_shipments
|
|
13
14
|
PromotionHandler::Cart.new(order, line_item).activate
|
|
14
15
|
ItemAdjustments.new(line_item).update
|
|
@@ -16,9 +17,10 @@ module Spree
|
|
|
16
17
|
line_item
|
|
17
18
|
end
|
|
18
19
|
|
|
19
|
-
def remove(variant, quantity = 1,
|
|
20
|
-
line_item = remove_from_line_item(variant, quantity,
|
|
20
|
+
def remove(variant, quantity = 1, options = {})
|
|
21
|
+
line_item = remove_from_line_item(variant, quantity, options)
|
|
21
22
|
reload_totals
|
|
23
|
+
shipment = options[:shipment]
|
|
22
24
|
shipment.present? ? shipment.update_amounts : order.ensure_updated_shipments
|
|
23
25
|
PromotionHandler::Cart.new(order, line_item).activate
|
|
24
26
|
ItemAdjustments.new(line_item).update
|
|
@@ -27,8 +29,8 @@ module Spree
|
|
|
27
29
|
end
|
|
28
30
|
|
|
29
31
|
def update_cart(params)
|
|
30
|
-
if order.update_attributes(params)
|
|
31
|
-
order.line_items = order.line_items.select {|li| li.quantity > 0 }
|
|
32
|
+
if order.update_attributes(filter_order_items(params))
|
|
33
|
+
order.line_items = order.line_items.select { |li| li.quantity > 0 }
|
|
32
34
|
# Update totals, then check if the order is eligible for any cart promotions.
|
|
33
35
|
# If we do not update first, then the item total will be wrong and ItemTotal
|
|
34
36
|
# promotion rules would not be triggered.
|
|
@@ -43,6 +45,18 @@ module Spree
|
|
|
43
45
|
end
|
|
44
46
|
|
|
45
47
|
private
|
|
48
|
+
|
|
49
|
+
def filter_order_items(params)
|
|
50
|
+
filtered_params = params.symbolize_keys
|
|
51
|
+
return filtered_params if filtered_params[:line_items_attributes].nil? || filtered_params[:line_items_attributes][:id]
|
|
52
|
+
|
|
53
|
+
params[:line_items_attributes].each_pair do |id, value|
|
|
54
|
+
line_item_id = value[:id]
|
|
55
|
+
filtered_params[:line_items_attributes].delete(id) unless Spree::LineItem.find_by_id(line_item_id.to_i)
|
|
56
|
+
end
|
|
57
|
+
filtered_params
|
|
58
|
+
end
|
|
59
|
+
|
|
46
60
|
def order_updater
|
|
47
61
|
@updater ||= OrderUpdater.new(order)
|
|
48
62
|
end
|
|
@@ -53,32 +67,28 @@ module Spree
|
|
|
53
67
|
order.reload
|
|
54
68
|
end
|
|
55
69
|
|
|
56
|
-
def add_to_line_item(variant, quantity,
|
|
57
|
-
line_item = grab_line_item_by_variant(variant)
|
|
70
|
+
def add_to_line_item(variant, quantity, options = {})
|
|
71
|
+
line_item = grab_line_item_by_variant(variant, false, options)
|
|
58
72
|
|
|
59
73
|
if line_item
|
|
60
|
-
line_item.target_shipment = shipment
|
|
61
74
|
line_item.quantity += quantity.to_i
|
|
62
75
|
line_item.currency = currency unless currency.nil?
|
|
63
76
|
else
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
else
|
|
70
|
-
line_item.price = variant.price
|
|
71
|
-
end
|
|
77
|
+
opts = { currency: order.currency }.merge ActionController::Parameters.new(options).
|
|
78
|
+
permit(PermittedAttributes.line_item_attributes)
|
|
79
|
+
line_item = order.line_items.new(quantity: quantity,
|
|
80
|
+
variant: variant,
|
|
81
|
+
options: opts)
|
|
72
82
|
end
|
|
73
|
-
|
|
74
|
-
line_item.save
|
|
83
|
+
line_item.target_shipment = options[:shipment] if options.has_key? :shipment
|
|
84
|
+
line_item.save!
|
|
75
85
|
line_item
|
|
76
86
|
end
|
|
77
87
|
|
|
78
|
-
def remove_from_line_item(variant, quantity,
|
|
79
|
-
line_item = grab_line_item_by_variant(variant, true)
|
|
88
|
+
def remove_from_line_item(variant, quantity, options = {})
|
|
89
|
+
line_item = grab_line_item_by_variant(variant, true, options)
|
|
80
90
|
line_item.quantity -= quantity
|
|
81
|
-
line_item.target_shipment= shipment
|
|
91
|
+
line_item.target_shipment= options[:shipment]
|
|
82
92
|
|
|
83
93
|
if line_item.quantity == 0
|
|
84
94
|
line_item.destroy
|
|
@@ -89,8 +99,8 @@ module Spree
|
|
|
89
99
|
line_item
|
|
90
100
|
end
|
|
91
101
|
|
|
92
|
-
def grab_line_item_by_variant(variant, raise_error = false)
|
|
93
|
-
line_item = order.find_line_item_by_variant(variant)
|
|
102
|
+
def grab_line_item_by_variant(variant, raise_error = false, options = {})
|
|
103
|
+
line_item = order.find_line_item_by_variant(variant, options)
|
|
94
104
|
|
|
95
105
|
if !line_item.present? && raise_error
|
|
96
106
|
raise ActiveRecord::RecordNotFound, "Line item not found for variant #{variant.sku}"
|
|
@@ -9,8 +9,10 @@ module Spree
|
|
|
9
9
|
@errors = ActiveModel::Errors.new(self)
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
def populate(variant_id, quantity)
|
|
13
|
-
|
|
12
|
+
def populate(variant_id, quantity, options = {})
|
|
13
|
+
# protect against passing a nil hash being passed in
|
|
14
|
+
# due to an empty params[:options]
|
|
15
|
+
attempt_cart_add(variant_id, quantity, options || {})
|
|
14
16
|
valid?
|
|
15
17
|
end
|
|
16
18
|
|
|
@@ -20,7 +22,7 @@ module Spree
|
|
|
20
22
|
|
|
21
23
|
private
|
|
22
24
|
|
|
23
|
-
def attempt_cart_add(variant_id, quantity)
|
|
25
|
+
def attempt_cart_add(variant_id, quantity, options = {})
|
|
24
26
|
quantity = quantity.to_i
|
|
25
27
|
# 2,147,483,647 is crazy.
|
|
26
28
|
# See issue #2695.
|
|
@@ -31,7 +33,7 @@ module Spree
|
|
|
31
33
|
|
|
32
34
|
variant = Spree::Variant.find(variant_id)
|
|
33
35
|
if quantity > 0
|
|
34
|
-
line_item = @order.contents.add(variant, quantity, currency)
|
|
36
|
+
line_item = @order.contents.add(variant, quantity, options.merge(currency: currency))
|
|
35
37
|
unless line_item.valid?
|
|
36
38
|
errors.add(:base, line_item.errors.messages.values.join(" "))
|
|
37
39
|
return false
|
|
@@ -24,6 +24,7 @@ module Spree
|
|
|
24
24
|
run_hooks
|
|
25
25
|
persist_totals
|
|
26
26
|
end
|
|
27
|
+
Spree.instrument_method self, :update
|
|
27
28
|
|
|
28
29
|
def run_hooks
|
|
29
30
|
update_hooks.each { |hook| order.send hook }
|
|
@@ -111,6 +112,7 @@ module Spree
|
|
|
111
112
|
updated_at: Time.now,
|
|
112
113
|
)
|
|
113
114
|
end
|
|
115
|
+
Spree.instrument_method self, :persist_totals
|
|
114
116
|
|
|
115
117
|
# Updates the +shipment_state+ attribute according to the following logic:
|
|
116
118
|
#
|
|
@@ -158,7 +160,9 @@ module Spree
|
|
|
158
160
|
last_state = order.payment_state
|
|
159
161
|
if payments.present? && payments.valid.size == 0
|
|
160
162
|
order.payment_state = 'failed'
|
|
161
|
-
elsif order.state == 'canceled'
|
|
163
|
+
elsif !payments.present? && order.state == 'canceled'
|
|
164
|
+
order.payment_state = 'void'
|
|
165
|
+
elsif order.state == 'canceled' && order.payment_total == 0 && payments.completed.size > 0
|
|
162
166
|
order.payment_state = 'void'
|
|
163
167
|
else
|
|
164
168
|
order.payment_state = 'balance_due' if order.outstanding_balance > 0
|
|
@@ -168,5 +172,10 @@ module Spree
|
|
|
168
172
|
order.state_changed('payment') if last_state != order.payment_state
|
|
169
173
|
order.payment_state
|
|
170
174
|
end
|
|
175
|
+
|
|
176
|
+
private
|
|
177
|
+
def round_money(n)
|
|
178
|
+
(n * 100).round / 100.0
|
|
179
|
+
end
|
|
171
180
|
end
|
|
172
181
|
end
|
data/app/models/spree/payment.rb
CHANGED
|
@@ -8,15 +8,14 @@ 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
|
-
has_many :offsets, -> {
|
|
14
|
-
class_name: "Spree::Payment", foreign_key: :source_id
|
|
13
|
+
has_many :offsets, -> { offset_payment }, class_name: "Spree::Payment", foreign_key: :source_id
|
|
15
14
|
has_many :log_entries, as: :source
|
|
16
15
|
has_many :state_changes, as: :stateful
|
|
17
16
|
has_many :capture_events, :class_name => 'Spree::PaymentCaptureEvent'
|
|
17
|
+
has_many :refunds, inverse_of: :payment
|
|
18
18
|
|
|
19
|
-
validates_presence_of :payment_method
|
|
20
19
|
before_validation :validate_source
|
|
21
20
|
before_create :set_unique_identifier
|
|
22
21
|
|
|
@@ -39,13 +38,23 @@ module Spree
|
|
|
39
38
|
|
|
40
39
|
scope :from_credit_card, -> { where(source_type: 'Spree::CreditCard') }
|
|
41
40
|
scope :with_state, ->(s) { where(state: s.to_s) }
|
|
41
|
+
# "offset" is reserved by activerecord
|
|
42
|
+
scope :offset_payment, -> { where("source_type = 'Spree::Payment' AND amount < 0 AND state = 'completed'") }
|
|
43
|
+
|
|
44
|
+
scope :checkout, -> { with_state('checkout') }
|
|
42
45
|
scope :completed, -> { with_state('completed') }
|
|
43
46
|
scope :pending, -> { with_state('pending') }
|
|
44
47
|
scope :processing, -> { with_state('processing') }
|
|
45
48
|
scope :failed, -> { with_state('failed') }
|
|
49
|
+
|
|
46
50
|
scope :risky, -> { where("avs_response IN (?) OR (cvv_response_code IS NOT NULL and cvv_response_code != 'M') OR state = 'failed'", RISKY_AVS_CODES) }
|
|
47
51
|
scope :valid, -> { where.not(state: %w(failed invalid)) }
|
|
48
52
|
|
|
53
|
+
# transaction_id is much easier to understand
|
|
54
|
+
def transaction_id
|
|
55
|
+
response_code
|
|
56
|
+
end
|
|
57
|
+
|
|
49
58
|
def persist_invalid
|
|
50
59
|
return unless ['failed', 'invalid'].include?(state)
|
|
51
60
|
state_will_change!
|
|
@@ -115,7 +124,7 @@ module Spree
|
|
|
115
124
|
end
|
|
116
125
|
|
|
117
126
|
def credit_allowed
|
|
118
|
-
amount - offsets_total.abs
|
|
127
|
+
amount - (offsets_total.abs + refunds.sum(:amount))
|
|
119
128
|
end
|
|
120
129
|
|
|
121
130
|
def can_credit?
|
|
@@ -158,10 +167,6 @@ module Spree
|
|
|
158
167
|
amount - capture_events.sum(:amount)
|
|
159
168
|
end
|
|
160
169
|
|
|
161
|
-
def editable?
|
|
162
|
-
checkout? || pending?
|
|
163
|
-
end
|
|
164
|
-
|
|
165
170
|
private
|
|
166
171
|
|
|
167
172
|
def validate_source
|
|
@@ -179,8 +184,8 @@ module Spree
|
|
|
179
184
|
end
|
|
180
185
|
|
|
181
186
|
def create_payment_profile
|
|
182
|
-
|
|
183
|
-
return
|
|
187
|
+
# Payment profile cannot be created without source
|
|
188
|
+
return unless source
|
|
184
189
|
# Imported payments shouldn't create a payment profile.
|
|
185
190
|
return if source.imported
|
|
186
191
|
|
|
@@ -190,15 +195,13 @@ module Spree
|
|
|
190
195
|
end
|
|
191
196
|
|
|
192
197
|
def invalidate_old_payments
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
payment.invalidate!
|
|
196
|
-
end
|
|
198
|
+
order.payments.with_state('checkout').where("id != ?", self.id).each do |payment|
|
|
199
|
+
payment.invalidate!
|
|
197
200
|
end
|
|
198
201
|
end
|
|
199
202
|
|
|
200
203
|
def update_order
|
|
201
|
-
if completed?
|
|
204
|
+
if self.completed?
|
|
202
205
|
order.updater.update_payment_total
|
|
203
206
|
end
|
|
204
207
|
|