Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Furniture: Marketplace #761

Closed
wants to merge 6 commits into from
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
1 change: 1 addition & 0 deletions .vscode/ltex.dictionary.en-US.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Piikup
1 change: 1 addition & 0 deletions app/furniture/furniture.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module Furniture
markdown_text_block: MarkdownTextBlock,
video_bridge: VideoBridge,
livestream: Livestream,
marketplace: Marketplace,
embedded_form: EmbeddedForm,
spotlight: Spotlight,
}.freeze
Expand Down
57 changes: 57 additions & 0 deletions app/furniture/marketplace.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# frozen_string_literal: true

# Provids Vendors a location to sell their products
class Marketplace
include Placeable

def self.append_routes(router)
router.namespace :marketplace do
router.resources :orders do
router.resources :items
router.resource :checkout
end
end
end

def delivery_fee=(delivery_fee)
settings['delivery_fee'] = delivery_fee
end

def delivery_fee
settings['delivery_fee']
end

def order_notification_email=(order_notification_email)
settings['order_notification_email'] = order_notification_email
end

def order_notification_email
settings['order_notification_email']
end

def stripe_account=(stripe_account)
settings['stripe_account'] = stripe_account
end

def stripe_account
settings['stripe_account']
end

def products
[{ name: "1lb of Bananas", price_cents: 1_39 }, { name: "32oz of Greek Yogurt", price_cents: 7_99 }].map do |product_attributes|
Marketplace::Product.new(product_attributes)
end
end

def order
orders.last || Marketplace::Order.create(location:placement)
end

def orders
Marketplace::Order.where(location: placement)
end

def attribute_names
super + %w[delivery_fee order_notification_email stripe_account]
end
end
5 changes: 5 additions & 0 deletions app/furniture/marketplace/_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<%= form.fields_for(:furniture) do |furniture_fields| %>
<%= render "text_field", attribute: :stripe_account, form: furniture_fields %>
<%= render "text_field", attribute: :delivery_fee, form: furniture_fields %>
<%= render "email_field", attribute: :order_notification_email, form: furniture_fields %>
<%- end %>
19 changes: 19 additions & 0 deletions app/furniture/marketplace/_in_room.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<%- marketplace = furniture %>
<div id="<%= dom_id(marketplace)%>">
<%- marketplace.products.each do |product| %>

<h3><%= product.name %> (<%= product.price.format %>)</h3>

<%= button_to "Add to Order", [space, room, :furniture, marketplace.order, :items], params: { marketplace_item: { product: product.name } }, method: :post %>
<%- end %>

<div id="<%= dom_id(marketplace.order)%>">
<div id="<%= dom_id(marketplace.order) %>-items">
</div>

<div id="<%= dom_id(marketplace.order) %>-total">
</div>

<%= link_to "Checkout", [space, room, :furniture, marketplace.order, :checkout], class: "button" %>
</div>
</div>
4 changes: 4 additions & 0 deletions app/furniture/marketplace/checkout.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class Marketplace::Checkout
include ActiveModel::Model
attr_accessor :order
end
4 changes: 4 additions & 0 deletions app/furniture/marketplace/checkouts/_checkout.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<div id="<%= dom_id(checkout.order)%>">

<h1>BOOGA BOGOA</h1>
</div>
17 changes: 17 additions & 0 deletions app/furniture/marketplace/checkouts_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

class Marketplace
class CheckoutsController < MarketplaceController
def show
render turbo_stream: turbo_stream.replace(dom_id(marketplace), checkout)
end

helper_method def checkout
order.checkout
end

helper_method def order
marketplace.orders.find(params[:order_id])
end
end
end
23 changes: 23 additions & 0 deletions app/furniture/marketplace/item.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
class Marketplace::Item
include ActiveModel::Model

def id
@id ||= SecureRandom.uuid
end

def persisted?
true
end

attr_accessor :product, :order

delegate :price, to: :product

def save
order.save
end

def quantity
1
end
end
7 changes: 7 additions & 0 deletions app/furniture/marketplace/item_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class Marketplace::ItemPolicy < ApplicationPolicy


def permitted_attributes(_params)
%i[product]
end
end
3 changes: 3 additions & 0 deletions app/furniture/marketplace/items/_item.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div id="<%=dom_id(item) %>">
<%= item.product.name %> x <%= item.quantity %> (<%= item.price.format %>)
</div>
32 changes: 32 additions & 0 deletions app/furniture/marketplace/items_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# frozen_string_literal: true

class Marketplace
class ItemsController < MarketplaceController
def create
item.save

render turbo_stream: turbo_stream
.append("#{dom_id(order)}-items", item)
end

private def item_params
policy(items.new).permit(params.require(:marketplace_item)).merge(order: order, product: product)
end

helper_method def item
@item ||= items.new(item_params)
end

helper_method def items
@items ||= order.items
end

helper_method def order
marketplace.orders.find(params[:order_id])
end

helper_method def product
marketplace.products.find { |p| p.name == params[:marketplace_item][:product] }
end
end
end
8 changes: 8 additions & 0 deletions app/furniture/marketplace/marketplace_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class Marketplace
class MarketplaceController < FurnitureController
# @returns [Marketplace]
helper_method def marketplace
room.furniture_placements.find_by(furniture_kind: 'marketplace').furniture
end
end
end
13 changes: 13 additions & 0 deletions app/furniture/marketplace/order.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class Marketplace::Order < Item
def items
Marketplace::Item
end

def marketplace
furniture
end

def checkout
Marketplace::Checkout.new(order: self)
end
end
8 changes: 8 additions & 0 deletions app/furniture/marketplace/product.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class Marketplace::Product
include ActiveModel::Model
attr_accessor :name, :price_cents

def price
Money.from_cents(price_cents, 'USD')
end
end
45 changes: 0 additions & 45 deletions features/furniture/delivery-order-form.feature.md

This file was deleted.

36 changes: 36 additions & 0 deletions features/furniture/marketplace.feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Feature: Furniture: Marketplace!

Whether you're a farmers market or other local distributor, transactions between
local vendors and the community is the cornerstone of a strong regional economy.

A Marketplace connects producers, distributors and consumers in a single Space.
## Scenario: Place a Delivery Order
For now, our primary client is local owned and operated delivery
organizations, like [Piikup](https://piikup.com/) or
[Candlestick](https://www.candlestickcourier.com/).

These organizations serve as distributors for regional vendors, closing the
last-mile and keeping money flowing within the community.

- Given a "Piikup Marketplace" Space
- And a "Marketplace" Furniture in the Entrance Hall to "Piikup Marketplace" Space is configured with:
| delivery_fee | $6.99 |
| order_notification_email | [email protected] |
| stripe_account | piikup-stripe-key |
- And a Marketplace Vendor "Mandela Grocery" in the "Piikup Marketplace" Space has:
| stripe_account | mandela-stripe-key |
| order_notification_email | [email protected] |
- And the Marketplace Vendor "Mandela Grocery" offers the following Products in the "Piikup Marketplace" Space
| name | price |
| 1lb of Bananas | $1.39 |
| 32oz of Greek Yogurt | $7.99 |
- When a Guest places a Delivery Marketplace Order in the "Piikup Marketplace" Space for:
| item | quantity | price |
| 1lb of Bananas | 4 | $5.56 |
| 32oz of Greek Yogurt | 1 | $7.99 |
| Delivery by Piikup | 1 | $6.99 |
- Then the Guest is charged $20.54 for their Marketplace Order
- And the Marketplace Order placed by the Guest in the "Piikup Marketplace" Space is delivered to "[email protected]"
- And the Stripe Account "piikup-stripe-key" receives a Payment of $6.99
- And the Marketplace Order placed by the Guest in the "Piikup Marketplace" Space is delivered to "[email protected]"
- And the Stripe Account "mandela-stripe-key" receives a Payment of $13.55
31 changes: 31 additions & 0 deletions features/steps/furniture/marketplace_steps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Given, When, Then } from "@cucumber/cucumber";
Given('{a} Marketplace Vendor {string} in {a} {space} has:', function (a, string, a2, space, dataTable) {
// Write code here that turns the phrase above into concrete actions
return 'pending';
});


Given('{a} Marketplace Vendor {string} offers {a} following Products in {a} {space}', function (a, string, a2, a3, space, dataTable) {
// Write code here that turns the phrase above into concrete actions
return 'pending';
});

When('{a} {actor} places {a} Delivery Marketplace Order in {a} {space} for:', function (a, actor, a2, a3, space, dataTable) {
// Write code here that turns the phrase above into concrete actions
return 'pending';
});

Then('{a} Marketplace Order placed by {a} {actor} in {a} {space} is delivered to {string}', function (a, a2, actor, a3, space, string) {
// Write code here that turns the phrase above into concrete actions
return 'pending';
});

Then('{a} {actor} is charged ${float} for their Marketplace Order', function (a, actor, float) {
// Write code here that turns the phrase above into concrete actions
return 'pending';
});

Then('{a} Stripe Account {string} receives {a} Payment of ${float}', function (a, string, a2, float) {
// Write code here that turns the phrase above into concrete actions
return 'pending';
});