Refactoring for drivy.engineering blog (Ruby 2.5)
class ConfirmOrder < Command | |
def initialize(order, payment_token, notify: true) | |
@order = order | |
@payment_token = payment_token | |
@notify = notify | |
end | |
validate do | |
payment_token_must_be_valid | |
payment_amount_must_match_sales_quote | |
end | |
perform do | |
capture_payment! | |
create_invoice_and_update_status | |
send_notifications | |
rescue Payment::CaptureError | |
add_error(:payment_capture_error) | |
end | |
private | |
def payment | |
@payment ||= @order.payments.new(token: @payment_token) | |
end | |
def payment_token_must_be_valid | |
add_error(:payment_token_invalid) unless payment.valid? | |
end | |
def payment_amount_must_match_sales_quote | |
add_error(:payment_amount_mismatch) unless payment_amount_match_sales_quote? | |
end | |
def payment_amount_match_sales_quote? | |
payment.amount == @order.sales_quote.amount && | |
payment.currency == @order.sales_quote.currency | |
end | |
def capture_payment! | |
payment.save! | |
payment.capture! | |
end | |
def create_invoice_and_update_status | |
Order.transaction do | |
create_invoice | |
update_status | |
end | |
end | |
def create_invoice | |
invoice = @order.invoices.create!({ | |
amount: @order.sales_quote.amount, | |
currency: @order.sales_quote.currency, | |
}) | |
@order.sales_quote.items.find_each do |item| | |
invoice.items.create!({ | |
product_id: item.product_id, | |
quantity: item.quantity, | |
unit_price: item.unit_price, | |
}) | |
end | |
end | |
def update_order_status | |
@order.update(status: :confirmed) | |
end | |
def send_notifications | |
return unless @notify | |
OrderMailer.preparation_details(@order).deliver_async | |
OrderMailer.confirmation(@order).deliver_async | |
OrderMailer.available_invoice(@order).deliver_async | |
end | |
end |
class ConfirmOrder < Command | |
def initialize(order, payment_token, notify: true) | |
@order = order | |
@payment_token = payment_token | |
@notify = notify | |
end | |
validate do | |
payment = @order.payments.new(token: @payment_token) | |
if !payment.valid? | |
add_error(:payment_token_invalid) | |
end | |
if payment.amount != @order.sales_quote.amount || payment.currency != @order.sales_quote.currency | |
add_error(:payment_amount_mismatch) | |
end | |
end | |
perform do | |
@order.payments.create!(token: @payment_token).capture! | |
Order.transaction do | |
invoice = @order.invoices.create!({ | |
amount: @order.sales_quote.amount, | |
currency: @order.sales_quote.currency, | |
}) | |
sales_quote.items.find_each do |item| | |
invoice.items.create!({ | |
product_id: item.product_id, | |
quantity: item.quantity, | |
unit_price: item.unit_price, | |
}) | |
end | |
@order.update(status: :confirmed) | |
end | |
if @notify | |
OrderMailer.preparation_details(@order).deliver_async | |
OrderMailer.confirmation(@order).deliver_async | |
OrderMailer.available_invoice(@order).deliver_async | |
end | |
rescue Payment::CaptureError => error | |
add_error(:payment_capture_error) | |
end | |
end |
This comment has been minimized.
This comment has been minimized.
Can you include implementation of |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
Hey, I'm wondering about the implementation of your
Command
class. Is there a difference betweenvalidate
andperform
? Is it just semantical ? So theCommand#perform!
method basically calls those two blocks ?