Skip to content

Commit

Permalink
Marketplace: Differentiate between Checkout and Order
Browse files Browse the repository at this point in the history
Where `Checkout` is useful for handling a Checkout flow for the
Payment Processor, it doesn't make a ton of sense from a Buyer
perspective once the Cart has been Checked out.

I've sprouted an `Order` model, with corresponding Controllers, and
moved the `checkouts/show` and `checkouts/_checkout` views to
`orders/show` and `orders/_order`.
  • Loading branch information
zspencer committed Jan 20, 2023
1 parent 1c1e7c8 commit d6b9eb0
Show file tree
Hide file tree
Showing 18 changed files with 91 additions and 44 deletions.
1 change: 1 addition & 0 deletions app/furniture/furniture.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ module Furniture
def self.append_routes(router)
REGISTRY.each_value do |furniture|
furniture.append_routes(router) if furniture.respond_to?(:append_routes)
furniture.const_get(:Routes).append_routes(router) if furniture.const_defined?(:Routes)
end
end

Expand Down
10 changes: 0 additions & 10 deletions app/furniture/marketplace.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,5 @@
# @see features/furniture/marketplace.feature.md
class Marketplace
def self.append_routes(router)
router.resources :marketplaces, only: [:show, :edit, :update], module: "marketplace" do
router.resources :products
router.resources :carts do
router.resources :cart_products
end
router.resources :checkouts, only: [:show, :create]
end
end

def self.from_placement(placement)
placement.becomes(Marketplace)
end
Expand Down
6 changes: 6 additions & 0 deletions app/furniture/marketplace/breadcrumbs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@
link "Checkout", checkout.location
end

crumb :marketplace_order do |order|
parent :marketplace, order.marketplace
link "Order from #{order.created_at.to_fs(:long_ordinal)}", order.location
end


crumb :marketplace_products do |marketplace|
parent :edit_marketplace, marketplace
link t('marketplace.product.index'), marketplace.location(child: :products)
Expand Down
1 change: 1 addition & 0 deletions app/furniture/marketplace/cart.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class Cart < ApplicationRecord
has_many :cart_products, dependent: :destroy, inverse_of: :cart
has_many :products, through: :cart_products, inverse_of: :carts
has_one :checkout, inverse_of: :cart
has_one :order, inverse_of: :cart, class_name: "Order"

enum status: {
pre_checkout: "pre_checkout",
Expand Down
6 changes: 1 addition & 5 deletions app/furniture/marketplace/cart_products_controller.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class Marketplace
class CartProductsController < FurnitureController
class CartProductsController < Controller
def create
authorize(cart_product)
cart_product.save
Expand Down Expand Up @@ -98,10 +98,6 @@ def cart
marketplace.carts.find(params[:cart_id])
end

helper_method def marketplace
@marketplace ||= policy_scope(Marketplace).find(params[:marketplace_id])
end

def cart_product_params
params.require(:cart_product).permit(:quantity, :product_id)
end
Expand Down
8 changes: 7 additions & 1 deletion app/furniture/marketplace/checkout.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ class Checkout < ApplicationRecord
self.location_parent = :marketplace

belongs_to :cart, inverse_of: :checkout
delegate :marketplace, to: :cart

has_many :ordered_products, through: :cart, source: :cart_products, class_name: "Marketplace::OrderedProduct"
delegate :marketplace, to: :cart

belongs_to :shopper, inverse_of: :checkouts


Expand Down Expand Up @@ -37,6 +38,11 @@ def create_stripe_session(success_url: , cancel_url: )
})
end

def complete(stripe_session_id:)
update!(status: :paid, stripe_session_id: stripe_session_id)
cart.update!(status: :checked_out)
end

private

def stripe_line_items
Expand Down
2 changes: 0 additions & 2 deletions app/furniture/marketplace/checkouts/show.html.erb

This file was deleted.

19 changes: 3 additions & 16 deletions app/furniture/marketplace/checkouts_controller.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
class Marketplace
class CheckoutsController < FurnitureController

class CheckoutsController < Controller
def show
authorize(checkout)
if params[:stripe_session_id].present?
checkout.update!(status: :paid, stripe_session_id: params[:stripe_session_id])
checkout.cart.update!(status: :checked_out)
checkout.complete(stripe_session_id: params[:stripe_session_id])
flash[:notice] = t('.success')
end
redirect_to checkout.becomes(Order).location
end

def create
Expand Down Expand Up @@ -36,20 +35,8 @@ def create
end
end

helper_method def shopper
@shopper ||= if current_person.is_a?(Guest)
Shopper.find_or_create_by(id: session[:guest_shopper_id] ||= SecureRandom.uuid)
else
Shopper.find_or_create_by(person: current_person)
end
end

helper_method def cart
@cart ||= marketplace.carts.find_or_create_by(shopper: shopper, status: :pre_checkout)
end

helper_method def marketplace
@marketplace ||= policy_scope(Marketplace).find(params[:marketplace_id])
end
end
end
15 changes: 15 additions & 0 deletions app/furniture/marketplace/controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
class Marketplace
class Controller < FurnitureController
helper_method def marketplace
@marketplace ||= policy_scope(Marketplace).find(params[:marketplace_id])
end

helper_method def shopper
@shopper ||= if current_person.is_a?(Guest)
Shopper.find_or_create_by(id: session[:guest_shopper_id] ||= SecureRandom.uuid)
else
Shopper.find_or_create_by(person: current_person)
end
end
end
end
1 change: 1 addition & 0 deletions app/furniture/marketplace/marketplace.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class Marketplace < FurniturePlacement

has_many :products, inverse_of: :marketplace, dependent: :destroy
has_many :carts, inverse_of: :marketplace, dependent: :destroy
has_many :orders, through: :carts

# The Secret Stripe API key belonging to the owner of the Marketplace
def stripe_api_key=(key)
Expand Down
5 changes: 5 additions & 0 deletions app/furniture/marketplace/order.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class Marketplace
class Order < Checkout
self.location_parent = :marketplace
end
end
17 changes: 17 additions & 0 deletions app/furniture/marketplace/order_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

class Marketplace
class OrderPolicy < CheckoutPolicy
alias_method :order, :object

def show?
create?
end

class Scope < ApplicationScope
def resolve
scope.all
end
end
end
end
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<h1>Ordered on <%= checkout.created_at.to_fs(:long_ordinal) %>
<h1>Ordered on <%= order.created_at.to_fs(:long_ordinal) %>
<div class="-mx-4 mt-8 overflow-hidden shadow ring-1 ring-black ring-opacity-5 sm:-mx-6 md:mx-0 md:rounded-lg">
<table class="min-w-full divide-y divide-gray-300 table-fixed">
<thead class="bg-gray-50">
Expand All @@ -16,14 +16,14 @@
</tr>
</thead>
<tbody class="divide-y divide-gray-200 bg-white">
<%= render checkout.ordered_products %>
<%= render order.ordered_products %>
</tbody>
<tfoot id="checkout-footer-<%= checkout.id%>" class="bg-gray-50">
<tfoot id="checkout-footer-<%= order.id%>" class="bg-gray-50">
<tr>
<td></td>
<th scope="row" class="text-right px-1 py-3.5">Total: </th>
<td class="text-left px-3 py-3.5 font-bold">
<%= render "marketplace/carts/total" %>
<%= render "marketplace/carts/total", cart: order.cart %>
</td>
</tr>
</tfoot>
Expand Down
2 changes: 2 additions & 0 deletions app/furniture/marketplace/orders/show.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<%- breadcrumb :marketplace_order, order%>
<%= render order %>
11 changes: 11 additions & 0 deletions app/furniture/marketplace/orders_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class Marketplace
class OrdersController < Controller
def show
authorize(order)
end

helper_method def order
policy_scope(marketplace.orders).find(params[:id])
end
end
end
6 changes: 1 addition & 5 deletions app/furniture/marketplace/products_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# frozen_string_literal: true

class Marketplace
class ProductsController < FurnitureController
class ProductsController < Controller
def new
authorize(marketplace.products.new)
end
Expand Down Expand Up @@ -41,10 +41,6 @@ def update
end
end

helper_method def marketplace
@marketplace ||= policy_scope(Marketplace).find(params[:marketplace_id])
end

helper_method def product
@product ||= if params[:id]
policy_scope(marketplace.products).find(params[:id])
Expand Down
14 changes: 14 additions & 0 deletions app/furniture/marketplace/routes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class Marketplace
class Routes
def self.append_routes(router)
router.resources :marketplaces, only: [:show, :edit, :update], module: "marketplace" do
router.resources :orders, only: [:show]
router.resources :products
router.resources :carts do
router.resources :cart_products
end
router.resources :checkouts, only: [:show, :create]
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@
let(:checkout) { create(:marketplace_checkout, cart: cart, shopper: cart.shopper)}
context "when a stripe_session_id is in the params" do
it "marks the cart as checked out" do
get polymorphic_path([space, room, marketplace, checkout], { stripe_session_id: "12345" })
get polymorphic_path(checkout.location, { stripe_session_id: "12345" })
expect(cart.reload).to be_checked_out
expect(checkout.reload).to be_paid
expect(response).to redirect_to(checkout.becomes(Marketplace::Order).location)
end
end
end
Expand Down

0 comments on commit d6b9eb0

Please sign in to comment.