diff --git a/app/furniture/furniture.rb b/app/furniture/furniture.rb index f0ae4fb9e..780d05abc 100644 --- a/app/furniture/furniture.rb +++ b/app/furniture/furniture.rb @@ -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 diff --git a/app/furniture/marketplace.rb b/app/furniture/marketplace.rb index c49c3974b..cc85a61b5 100644 --- a/app/furniture/marketplace.rb +++ b/app/furniture/marketplace.rb @@ -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 diff --git a/app/furniture/marketplace/breadcrumbs.rb b/app/furniture/marketplace/breadcrumbs.rb index 0d19aee35..3f803568d 100644 --- a/app/furniture/marketplace/breadcrumbs.rb +++ b/app/furniture/marketplace/breadcrumbs.rb @@ -17,6 +17,11 @@ 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) diff --git a/app/furniture/marketplace/cart.rb b/app/furniture/marketplace/cart.rb index 0c6eb845e..44f0e2b89 100644 --- a/app/furniture/marketplace/cart.rb +++ b/app/furniture/marketplace/cart.rb @@ -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 enum status: { pre_checkout: "pre_checkout", diff --git a/app/furniture/marketplace/cart_products_controller.rb b/app/furniture/marketplace/cart_products_controller.rb index ba1505bc7..3bec11b13 100644 --- a/app/furniture/marketplace/cart_products_controller.rb +++ b/app/furniture/marketplace/cart_products_controller.rb @@ -1,5 +1,5 @@ class Marketplace - class CartProductsController < FurnitureController + class CartProductsController < Controller def create authorize(cart_product) cart_product.save @@ -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 diff --git a/app/furniture/marketplace/checkout.rb b/app/furniture/marketplace/checkout.rb index 3d74f41b3..42c91bccb 100644 --- a/app/furniture/marketplace/checkout.rb +++ b/app/furniture/marketplace/checkout.rb @@ -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 # It would be nice to validate instead the presence of :ordered_products, but my attempts at this raise: @@ -38,6 +39,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 diff --git a/app/furniture/marketplace/checkouts/show.html.erb b/app/furniture/marketplace/checkouts/show.html.erb deleted file mode 100644 index 25c223628..000000000 --- a/app/furniture/marketplace/checkouts/show.html.erb +++ /dev/null @@ -1,2 +0,0 @@ -<%- breadcrumb :marketplace_checkout, checkout%> -<%= render checkout %> diff --git a/app/furniture/marketplace/checkouts_controller.rb b/app/furniture/marketplace/checkouts_controller.rb index 59c7e05ea..277ad865f 100644 --- a/app/furniture/marketplace/checkouts_controller.rb +++ b/app/furniture/marketplace/checkouts_controller.rb @@ -1,12 +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 @@ -35,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 diff --git a/app/furniture/marketplace/controller.rb b/app/furniture/marketplace/controller.rb new file mode 100644 index 000000000..b8b37b15f --- /dev/null +++ b/app/furniture/marketplace/controller.rb @@ -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 diff --git a/app/furniture/marketplace/marketplace.rb b/app/furniture/marketplace/marketplace.rb index 2adf1f20d..4078ee462 100644 --- a/app/furniture/marketplace/marketplace.rb +++ b/app/furniture/marketplace/marketplace.rb @@ -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) diff --git a/app/furniture/marketplace/order.rb b/app/furniture/marketplace/order.rb new file mode 100644 index 000000000..7ac3aa68b --- /dev/null +++ b/app/furniture/marketplace/order.rb @@ -0,0 +1,5 @@ +class Marketplace + class Order < Checkout + self.location_parent = :marketplace + end +end diff --git a/app/furniture/marketplace/order_policy.rb b/app/furniture/marketplace/order_policy.rb new file mode 100644 index 000000000..c64c7d7fe --- /dev/null +++ b/app/furniture/marketplace/order_policy.rb @@ -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 diff --git a/app/furniture/marketplace/checkouts/_checkout.html.erb b/app/furniture/marketplace/orders/_order.html.erb similarity index 82% rename from app/furniture/marketplace/checkouts/_checkout.html.erb rename to app/furniture/marketplace/orders/_order.html.erb index 573790e77..eb00aaa93 100644 --- a/app/furniture/marketplace/checkouts/_checkout.html.erb +++ b/app/furniture/marketplace/orders/_order.html.erb @@ -1,4 +1,4 @@ -

Ordered on <%= checkout.created_at.to_fs(:long_ordinal) %> +

Ordered on <%= order.created_at.to_fs(:long_ordinal) %>
@@ -16,14 +16,14 @@ - <%= render checkout.ordered_products %> + <%= render order.ordered_products %> - + diff --git a/app/furniture/marketplace/orders/show.html.erb b/app/furniture/marketplace/orders/show.html.erb new file mode 100644 index 000000000..29b7969cf --- /dev/null +++ b/app/furniture/marketplace/orders/show.html.erb @@ -0,0 +1,2 @@ +<%- breadcrumb :marketplace_order, order%> +<%= render order %> diff --git a/app/furniture/marketplace/orders_controller.rb b/app/furniture/marketplace/orders_controller.rb new file mode 100644 index 000000000..b0e7bfe09 --- /dev/null +++ b/app/furniture/marketplace/orders_controller.rb @@ -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 diff --git a/app/furniture/marketplace/products_controller.rb b/app/furniture/marketplace/products_controller.rb index 7c5dc18e7..bf6f8d08c 100644 --- a/app/furniture/marketplace/products_controller.rb +++ b/app/furniture/marketplace/products_controller.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class Marketplace - class ProductsController < FurnitureController + class ProductsController < Controller def new authorize(marketplace.products.new) end @@ -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]) diff --git a/app/furniture/marketplace/routes.rb b/app/furniture/marketplace/routes.rb new file mode 100644 index 000000000..e465eca8d --- /dev/null +++ b/app/furniture/marketplace/routes.rb @@ -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 diff --git a/spec/furniture/marketplace/checkouts_controller_request_spec.rb b/spec/furniture/marketplace/checkouts_controller_request_spec.rb index 531df7540..3f0f762c7 100644 --- a/spec/furniture/marketplace/checkouts_controller_request_spec.rb +++ b/spec/furniture/marketplace/checkouts_controller_request_spec.rb @@ -11,9 +11,10 @@ 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
Total: - <%= render "marketplace/carts/total" %> + <%= render "marketplace/carts/total", cart: order.cart %>