Skip to content

Commit

Permalink
Refactor order creation logic by introducing OrderCreator service and…
Browse files Browse the repository at this point in the history
… moving order item building to the Order model
  • Loading branch information
binos30 committed Jan 26, 2025
1 parent 2548974 commit 3c34789
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 33 deletions.
36 changes: 4 additions & 32 deletions app/controllers/webhooks_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,37 +25,7 @@ def stripe # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/Cyclom
case event.type
when "checkout.session.completed"
session = event.data.object
shipping_details = session["shipping_details"]
address =
"#{shipping_details["address"]["line1"]} #{shipping_details["address"]["city"]}, #{shipping_details["address"]["state"]} #{shipping_details["address"]["postal_code"]}" # rubocop:disable Layout/LineLength
full_session = Stripe::Checkout::Session.retrieve(id: session["id"], expand: ["line_items"])
line_items = full_session.line_items

Order.transaction do
order =
Order.new(
user_id: session["metadata"]["user_id"],
customer_full_name: session["metadata"]["user_full_name"],
customer_email: session["customer_details"]["email"],
customer_address: address,
total: session["amount_total"].to_f / 100
)
line_items["data"].each do |item|
product = Stripe::Product.retrieve(item["price"]["product"])
product_id = product["metadata"]["product_id"].to_i
stock = Stock.find(product["metadata"]["product_stock_id"])
order.order_items.build(
product_id:,
stock:,
product_name: product["name"],
product_price: item["price"]["unit_amount_decimal"].to_f / 100,
size: product["metadata"]["size"],
quantity: item["quantity"]
)
stock.update!(quantity: stock.quantity - item["quantity"].to_i)
end
order.save!
end
OrderCreator.call!(session)
when "customer.created"
customer = event.data.object
user = User.find_by(email: customer.email)
Expand All @@ -65,7 +35,9 @@ def stripe # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/Cyclom
user = User.find_by(stripe_customer_id: customer.id)
user&.update!(stripe_customer_id: nil)
else
logger.tagged("Stripe Checkout Webhook") { logger.error "Unhandled event type: #{event.type}" }
message = "Unhandled event type: #{event.type}"
logger.tagged("Stripe Checkout Webhook") { logger.error message }
return render json: { message: }
end

logger.tagged("Stripe Checkout Webhook") { logger.info "Checkout Success!" }
Expand Down
17 changes: 17 additions & 0 deletions app/models/order.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,23 @@ class Order < ApplicationRecord
scope :filter_by_customer,
->(customer) { where("CONCAT(users.first_name, ' ', users.last_name) ILIKE ?", "%#{customer}%") }

def build_order_items(line_items)
line_items["data"].each do |item|
product = Stripe::Product.retrieve(item["price"]["product"])
product_id = product["metadata"]["product_id"].to_i
stock = Stock.find(product["metadata"]["product_stock_id"])
order_items.build(
product_id:,
stock:,
product_name: product["name"],
product_price: item["price"]["unit_amount_decimal"].to_f / 100,
size: product["metadata"]["size"],
quantity: item["quantity"]
)
stock.update!(quantity: stock.quantity - item["quantity"].to_i)
end
end

def fulfill!
lock!

Expand Down
11 changes: 11 additions & 0 deletions app/services/application_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

class ApplicationService
def self.call(*args)
new(*args).call
end

def self.call!(*args)
new(*args).call!
end
end
28 changes: 28 additions & 0 deletions app/services/order_creator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# frozen_string_literal: true

class OrderCreator < ApplicationService
def initialize(session)
@session = session
end

def call!
shipping_details = @session["shipping_details"]
address =
"#{shipping_details["address"]["line1"]} #{shipping_details["address"]["city"]}, #{shipping_details["address"]["state"]} #{shipping_details["address"]["postal_code"]}" # rubocop:disable Layout/LineLength
full_session = Stripe::Checkout::Session.retrieve(id: @session["id"], expand: ["line_items"])
line_items = full_session.line_items

Order.transaction do
order =
Order.new(
user_id: @session["metadata"]["user_id"],
customer_full_name: @session["metadata"]["user_full_name"],
customer_email: @session["customer_details"]["email"],
customer_address: address,
total: @session["amount_total"].to_f / 100
)
order.build_order_items(line_items)
order.save!
end
end
end
4 changes: 3 additions & 1 deletion spec/rails_helper.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# frozen_string_literal: true

require "simplecov"
SimpleCov.start "rails"
SimpleCov.start "rails" do
add_group "Services", "app/services"
end

# This file is copied to spec/ when you run 'rails generate rspec:install'
require "spec_helper"
Expand Down

0 comments on commit 3c34789

Please sign in to comment.