From 6238c5c433bd6728ade080f16dff0764af8f034c Mon Sep 17 00:00:00 2001 From: Jordan Brough Date: Wed, 20 Apr 2016 13:17:24 -0600 Subject: [PATCH] Interfaces for persist_user_credit_card and assign_default_credit_card Extract the logic for persist_user_credit_card and assign_default_credit_card into configurable classes. --- core/app/models/spree/app_configuration.rb | 22 +++++++++++++++ core/app/models/spree/order/checkout.rb | 27 ++++++++++--------- .../spree/wallet/add_after_order_complete.rb | 25 +++++++++++++++++ .../spree/wallet/add_default_payment.rb | 24 +++++++++++++++++ 4 files changed, 86 insertions(+), 12 deletions(-) create mode 100644 core/app/models/spree/wallet/add_after_order_complete.rb create mode 100644 core/app/models/spree/wallet/add_default_payment.rb diff --git a/core/app/models/spree/app_configuration.rb b/core/app/models/spree/app_configuration.rb index 3a962e1ab92..b6f39a23766 100644 --- a/core/app/models/spree/app_configuration.rb +++ b/core/app/models/spree/app_configuration.rb @@ -349,6 +349,28 @@ def order_merger_class @order_merger_class ||= Spree::OrderMerger end + # Allows providing your own class for adding default payments to a user's + # order from their "wallet". + # + # @!attribute [rw] add_default_payment_class + # @return [Class] a class with the same public interfaces + # as Spree::Wallet::AddDefaultPayment. + attr_writer :add_default_payment_class + def add_default_payment_class + @add_default_payment_class ||= Spree::Wallet::AddDefaultPayment + end + + # Allows providing your own class for adding payment sources to a user's + # "wallet" after an order moves to the complete state. + # + # @!attribute [rw] wallet_add_after_order_complete_class + # @return [Class] a class with the same public interfaces + # as Spree::Wallet::AddAfterOrderComplete. + attr_writer :wallet_add_after_order_complete_class + def wallet_add_after_order_complete_class + @wallet_add_after_order_complete_class ||= Spree::Wallet::AddAfterOrderComplete + end + def static_model_preferences @static_model_preferences ||= Spree::Preferences::StaticModelPreferences.new end diff --git a/core/app/models/spree/order/checkout.rb b/core/app/models/spree/order/checkout.rb index f229382c18e..c4937936718 100644 --- a/core/app/models/spree/order/checkout.rb +++ b/core/app/models/spree/order/checkout.rb @@ -310,21 +310,24 @@ def persist_user_address! end def persist_user_credit_card - if !temporary_credit_card && user_id && valid_credit_cards.present? - default_cc = valid_credit_cards.first - # TODO: target for refactoring -- why is order checkout responsible for the user -> credit_card relationship? - default_cc.user_id = user_id - default_cc.default = true - default_cc.save - end + Spree::Config. + wallet_add_after_order_complete_class.new(self). + add_to_wallet end def assign_default_credit_card - if payments.from_credit_card.count == 0 && user && user.default_credit_card.try(:valid?) - cc = user.default_credit_card - payments.create!(payment_method_id: cc.payment_method_id, source: cc) - # this is one of 2 places still using User#bill_address - self.bill_address ||= user.default_credit_card.address || user.bill_address + payment = Spree::Config. + add_default_payment_class.new(self). + build_payment + + if payment + payments << payment + + if bill_address.nil? + # this is one of 2 places still using User#bill_address + self.bill_address = payment.source.try(:address) || + user.bill_address + end end end diff --git a/core/app/models/spree/wallet/add_after_order_complete.rb b/core/app/models/spree/wallet/add_after_order_complete.rb new file mode 100644 index 00000000000..dd6c888a981 --- /dev/null +++ b/core/app/models/spree/wallet/add_after_order_complete.rb @@ -0,0 +1,25 @@ +class Spree::Wallet::AddAfterOrderComplete + def initialize(order) + @order = order + end + + # AddAfterOrderComplete is called after an order transitions to complete. It + # is responsible for saving payment sources in the user's "wallet" for future + # use. + def add_to_wallet + if !order.temporary_credit_card && + order.user_id && + order.valid_credit_cards.present? + # arbitrarily pick the first one for the default + default_cc = order.valid_credit_cards.first + # TODO: target for refactoring -- why is order checkout responsible for the user -> credit_card relationship? + default_cc.user_id = order.user_id + default_cc.default = true + default_cc.save + end + end + + private + + attr_reader :order +end diff --git a/core/app/models/spree/wallet/add_default_payment.rb b/core/app/models/spree/wallet/add_default_payment.rb new file mode 100644 index 00000000000..098e8cfe867 --- /dev/null +++ b/core/app/models/spree/wallet/add_default_payment.rb @@ -0,0 +1,24 @@ +class Spree::Wallet::AddDefaultPayment + def initialize(order) + @order = order + end + + # Build a payment to be added to an order prior to moving into the "payment" + # state. + # + # @return [Payment] the unsaved payment to be added, or nil if none. + def build_payment + credit_card = order.user.try!(:default_credit_card) + + if credit_card.try!(:valid?) && order.payments.from_credit_card.count == 0 + Spree::Payment.new( + payment_method_id: credit_card.payment_method_id, + source: credit_card, + ) + end + end + + private + + attr_reader :order +end