Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions core/app/models/spree/actions/action.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module Spree
module Actions
class Action
def call
mutex do
perform
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we want to do 'recalculate' at the end of this?

end
end

private

# FIXME: waiting on nested mutexes being supported
def mutex
yield
end
end
end
end
29 changes: 29 additions & 0 deletions core/app/models/spree/actions/associate_user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
module Spree
module Actions
class AssociateUser
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would this extend Action ?

attr_reader :order, :user, :override_email

def initialize(order, user, override_email: true)
@order = order
@user = user
@override_email = override_email
end

def perform
order.user = user
attrs_to_set = { user_id: user.try!(:id) }
attrs_to_set[:email] = user.try!(:email) if override_email
attrs_to_set[:created_by_id] = user.try!(:id) if order.created_by.blank?

if order.persisted?
# immediately persist the changes we just made, but don't use save since we might have an invalid address associated
Spree::Order.unscoped.where(id: order.id).update_all(attrs_to_set)
end

attrs_to_set[:ship_address_attributes] = user.ship_address.attributes.except('id', 'updated_at', 'created_at') if user.try!(:ship_address)
attrs_to_set[:bill_address_attributes] = user.bill_address.attributes.except('id', 'updated_at', 'created_at') if user.try!(:bill_address)
order.assign_attributes(attrs_to_set)
end
end
end
end
36 changes: 36 additions & 0 deletions core/app/models/spree/actions/capture_payment.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
module Spree
module Actions
class CapturePayment < Action
attr_reader :payment

def initialize(payment, amount: nil)
@payment = payment
@amount = amount
end

def amount
@amount ||= payment.money.money.cents
end

def perform
return true if payment.completed?
payment.started_processing!
begin
#payment.check_environment
# Standard ActiveMerchant capture usage
response = payment.payment_method.capture(
amount,
payment.response_code,
payment.gateway_options
)
money = ::Money.new(amount, payment.currency)
payment.capture_events.create!(amount: money.to_f)
payment.update_attributes(amount: payment.captured_amount)
payment.handle_response(response, :complete, :failure)
rescue ActiveMerchant::ConnectionError => e

end
end
end
end
end
18 changes: 5 additions & 13 deletions core/app/models/spree/order.rb
Original file line number Diff line number Diff line change
Expand Up @@ -246,21 +246,13 @@ def cancellations
@cancellations ||= Spree::OrderCancellations.new(self)
end

def interface
Spree::OrderInterface.new(self)
end

# Associates the specified user with the order.
def associate_user!(user, override_email = true)
self.user = user
attrs_to_set = { user_id: user.try(:id) }
attrs_to_set[:email] = user.try(:email) if override_email
attrs_to_set[:created_by_id] = user.try(:id) if self.created_by.blank?

if persisted?
# immediately persist the changes we just made, but don't use save since we might have an invalid address associated
self.class.unscoped.where(id: id).update_all(attrs_to_set)
end

attrs_to_set[:ship_address_attributes] = user.ship_address.attributes.except('id', 'updated_at', 'created_at') if user.try(:ship_address)
attrs_to_set[:bill_address_attributes] = user.bill_address.attributes.except('id', 'updated_at', 'created_at') if user.try(:bill_address)
assign_attributes(attrs_to_set)
interface.associate_user(user, override_email: override_email)
end

def generate_order_number(options = {})
Expand Down
24 changes: 24 additions & 0 deletions core/app/models/spree/order_interface.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
module Spree
class OrderInterface
attr_reader :order

def initialize(order)
@order = order
end

delegate :add, :remove, :update_cart, to: :contents

def associate_user(user, override_email: true)
Spree::Actions::AssociateUser.new(order, user, override_email: override_email).call
end

def capture_payment(payment, amount: nil)
Spree::Actions::CapturePayment.new(payment, amount: amount).call
end

private
def contents
Order::Contents.new(contents)
end
end
end
14 changes: 0 additions & 14 deletions core/app/models/spree/payment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -206,20 +206,6 @@ def invalidate_old_payments
end
end

def split_uncaptured_amount
if uncaptured_amount > 0
order.payments.create! amount: uncaptured_amount,
avs_response: avs_response,
cvv_response_code: cvv_response_code,
cvv_response_message: cvv_response_message,
payment_method: payment_method,
response_code: response_code,
source: source,
state: 'pending'
update_attributes(amount: captured_amount)
end
end

def update_order
if completed? || void?
order.updater.update_payment_total
Expand Down
20 changes: 4 additions & 16 deletions core/app/models/spree/payment/processing.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,7 @@ def purchase!
# Can be used to capture partial amounts of a payment, and will create
# a new pending payment record for the remaining amount to capture later.
def capture!(amount = nil)
return true if completed?
amount ||= money.money.cents
started_processing!
protect_from_connection_error do
check_environment
# Standard ActiveMerchant capture usage
response = payment_method.capture(
amount,
response_code,
gateway_options
)
money = ::Money.new(amount, currency)
capture_events.create!(amount: money.to_f)
split_uncaptured_amount
handle_response(response, :complete, :failure)
end
order.interface.capture_payment(self, amount: amount)
end

def void_transaction!
Expand Down Expand Up @@ -153,6 +138,9 @@ def handle_response(response, success_state, failure_state)
end
end

# FIXME
public :handle_response

def handle_void_response(response)
record_response(response)

Expand Down
5 changes: 1 addition & 4 deletions core/spec/models/spree/payment_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -341,17 +341,14 @@
expect(payment.payment_method).to receive(:capture).with(capture_amount, payment.response_code, anything).and_return(success_response)
end

it "should make payment complete & create pending payment for remaining amount" do
it "should make payment complete and update amount" do
expect(payment).to receive(:complete!)
payment.capture!(capture_amount)
order = payment.order
payments = order.payments

expect(payments.size).to eq 2
expect(payments.pending.first.amount).to eq 1
# Payment stays processing for spec because of receive(:complete!) stub.
expect(payments.processing.first.amount).to eq(capture_amount / 100)
expect(payments.processing.first.source).to eq(payments.pending.first.source)
end

it "logs capture events" do
Expand Down