Skip to content

Commit

Permalink
🥗🧹 Marketplace: Delivery constraints live on DeliveryArea (#1420)
Browse files Browse the repository at this point in the history
`Marketplace`: `Delivery` constraints live on `DeliveryArea`

- #1325
- #1136
- #1185

Allowing a `Marketplace` to specify it's delivery fees, constraints,
etc. and a `DeliveryArea` to override them was putting us in a bit of a
mess from "how does data even?!"

This consolidates everything onto `DeliveryArea`, yay!
  • Loading branch information
zspencer authored May 4, 2023
1 parent 44d91e7 commit 4b292d3
Show file tree
Hide file tree
Showing 13 changed files with 43 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@ class Cart
class DeliveryExpectationsComponent < ApplicationComponent
attr_accessor :cart, :delivery_window, :order_by

def initialize(cart:, order_by: cart.marketplace.order_by,
delivery_window: cart.marketplace.delivery_window, **kwargs)
def initialize(cart:, order_by: cart.delivery_area&.order_by,
delivery_window: cart.delivery_area&.delivery_window, **kwargs)
super(**kwargs)

self.cart = cart
self.delivery_window = delivery_window
self.order_by = order_by
end

def render?
cart.delivery_area.present?
end
end
end
end
8 changes: 3 additions & 5 deletions app/furniture/marketplace/checkout.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ class Checkout < Model
location(parent: :cart)
include ActiveModel::Validations
attr_accessor :cart
delegate :shopper, :marketplace, :persisted?, to: :cart
delegate :shopper, :delivery_fee, :marketplace, :persisted?, to: :cart

# It would be nice to validate instead the presence of :ordered_products, but my attempts at this raise:
# ActiveRecord::HasManyThroughCantAssociateThroughHasOneOrManyReflection:
Expand All @@ -25,9 +25,7 @@ def create_stripe_session(success_url:, cancel_url:)
})
end

private

def stripe_line_items
private def stripe_line_items
return [] if cart.blank?

stripe_cart_products_line_items + stripe_delivery_fee_line_items + stripe_taxes_line_items
Expand All @@ -51,7 +49,7 @@ def stripe_line_items
{quantity: 1,
price_data: {
currency: "USD",
unit_amount: marketplace.delivery_fee_cents,
unit_amount: delivery_fee,
product_data: {name: "Delivery"}
}}
]
Expand Down
2 changes: 1 addition & 1 deletion app/furniture/marketplace/delivery.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def delivery_window
alias_method :window, :delivery_window

def fee
delivery_area&.price.presence || marketplace&.delivery_fee.presence
delivery_area&.price.presence || 0
end

def details_filled_in?
Expand Down
2 changes: 1 addition & 1 deletion app/furniture/marketplace/delivery_area_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def price
end

def example_cart
delivery_area.marketplace.carts.new
delivery_area.marketplace.carts.new(delivery_area: delivery_area)
end

delegate :order_by, to: :delivery_area
Expand Down
4 changes: 0 additions & 4 deletions app/furniture/marketplace/marketplace.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,7 @@ class Marketplace < Furniture
has_many :tax_rates, inverse_of: :marketplace
has_many :delivery_areas, inverse_of: :marketplace, dependent: :destroy

setting :delivery_fee_cents, default: 0
monetize :delivery_fee_cents
setting :delivery_window
setting :notify_emails
setting :order_by
setting :stripe_account
alias_method :vendor_stripe_account, :stripe_account
setting :stripe_webhook_endpoint
Expand Down
6 changes: 4 additions & 2 deletions app/furniture/marketplace/order.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,17 @@ def delivery
becomes(Delivery)
end

delegate :delivery_fee, to: :marketplace
def delivery_fee
delivery_area&.price
end
delegate :delivery_window, to: :delivery_area, allow_nil: true

def marketplace_name
marketplace.room.name
end

def price_total
product_total + delivery_fee + tax_total
[product_total, delivery_fee, tax_total].compact.sum
end
end
end
Binary file modified docs/erd.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 0 additions & 5 deletions spec/factories/furniture/marketplace.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@
notify_emails { Array.new((1..3).to_a.sample) { Faker::Internet.email }.join(",") }
end

trait :with_delivery_fees do
delivery_fee_cents { (10_00..25_00).to_a.sample }
end

trait :with_delivery_areas do
transient do
delivery_area_quantity { 1 }
Expand All @@ -42,7 +38,6 @@
trait :full do
with_tax_rates
with_delivery_areas
with_delivery_fees
with_notify_emails
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,32 @@
context "when the cart does not have a `delivery_area`" do
let(:cart) { build(:marketplace_cart, marketplace: marketplace) }

context "when the `marketplace` has an `order_by` without a `delivery_window`" do
let(:marketplace) { build(:marketplace, order_by: "by 8AM") }
specify { expect(component.render?).to be_falsey } # rubocop:disable RSpec/PredicateMatcher
end

context "when the cart has a delivey area" do
let(:cart) { build(:marketplace_cart, delivery_area: delivery_area, marketplace: marketplace) }

context "when the `delivery_area` has an `order_by` without a `delivery_window`" do
let(:delivery_area) { build(:marketplace_delivery_area, marketplace: marketplace, order_by: "by 8AM") }

it { is_expected.to have_content("Order by 8AM") }
end

context "when the `marketplace` has a `delivery_window` without an `order_by`" do
let(:marketplace) { build(:marketplace, delivery_window: "at Noon") }
context "when the `delivery_area` has a `delivery_window` without an `order_by`" do
let(:delivery_area) { build(:marketplace_delivery_area, marketplace: marketplace, delivery_window: "at Noon") }

it { is_expected.to have_content("Orders are delivered at Noon", normalize_ws: true) }
end

context "when the `marketplace` has `delivery_window` and an `order_by`" do
let(:marketplace) { build(:marketplace, delivery_window: "at Noon", order_by: "by 8AM") }
context "when the `delivery_area` has `delivery_window` and an `order_by`" do
let(:delivery_area) { build(:marketplace_delivery_area, marketplace: marketplace, delivery_window: "at Noon", order_by: "by 8AM") }

it { is_expected.to have_content("Orders placed by 8AM are delivered at Noon", normalize_ws: true) }
end

context "when the `marketplace` has neither an `order_by` nor a `delivery_window`" do
let(:marketplace) { build(:marketplace) }
context "when the `delivery_area` has neither an `order_by` nor a `delivery_window`" do
let(:delivery_area) { build(:marketplace_delivery_area, marketplace: marketplace) }

it {
expect(output).to have_content("Delivers at your chosen time")
Expand Down
5 changes: 3 additions & 2 deletions spec/furniture/marketplace/cart_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
describe "#price_total" do
subject(:price_total) { cart.price_total }

let(:marketplace) { create(:marketplace, delivery_fee_cents: 1200) }
let(:cart) { create(:marketplace_cart, marketplace: marketplace) }
let(:marketplace) { create(:marketplace) }
let(:delivery_area) { create(:marketplace_delivery_area, price_cents: 12_00) }
let(:cart) { create(:marketplace_cart, marketplace: marketplace, delivery_area: delivery_area) }
let(:product_a) { create(:marketplace_product, marketplace: cart.marketplace) }
let(:product_b) { create(:marketplace_product, marketplace: cart.marketplace, tax_rate_ids: [sales_tax.id]) }
let(:sales_tax) { create(:marketplace_tax_rate, marketplace: cart.marketplace, tax_rate: 5.0) }
Expand Down
20 changes: 3 additions & 17 deletions spec/furniture/marketplace/delivery_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,10 @@
describe "#fee" do
subject(:fee) { delivery.fee }

context "when there is not a marketplace delivery fee or a delivery area delivery fee" do
let(:delivery_area) { build(:marketplace_delivery_area, price_cents: nil, marketplace: marketplace) }
context "when `price_cents` is nil" do
let(:delivery_area) { build(:marketplace_delivery_area, marketplace: marketplace, price_cents: nil) }

it { is_expected.to eq(0) }
end

context "when the marketplace has a delivery fee and the delivery area has a delivery fee" do
let(:marketplace) { build(:marketplace, delivery_fee_cents: 25_00) }
let(:delivery_area) { build(:marketplace_delivery_area, price_cents: 50_00, marketplace: marketplace) }

it { is_expected.to eq(delivery_area.price) }
end

context "when the marketplace has a delivery fee but the delivery area does not" do
let(:marketplace) { build(:marketplace, delivery_fee_cents: 25_00) }
let(:delivery_area) { build(:marketplace_delivery_area, price_cents: nil, marketplace: marketplace) }

it { is_expected.to eq(marketplace.delivery_fee) }
it { is_expected.to be_zero }
end
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@
before { sign_in(space, member) }

it "updates the attributes" do
put polymorphic_path(marketplace.location), params: {marketplace: {delivery_fee: 50.00, delivery_window: "Tomorrow, mahhhhn...", order_by: "10AM"}}
marketplace_attributes = attributes_for(:marketplace, notify_emails: "notify@example.com")
put polymorphic_path(marketplace.location), params: {marketplace: marketplace_attributes}
marketplace.reload

expect(marketplace.reload.delivery_fee_cents).to eq(50_00)
expect(marketplace.reload.delivery_window).to eq("Tomorrow, mahhhhn...")
expect(marketplace.reload.order_by).to eq("10AM")
expect(marketplace.notify_emails).to eq(marketplace_attributes[:notify_emails])
end
end
end
7 changes: 4 additions & 3 deletions spec/furniture/marketplace/order_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
describe "#price_total" do
subject(:price_total) { order.price_total }

let(:marketplace) { create(:marketplace, delivery_fee_cents: 1200) }
let(:order) { create(:marketplace_order, marketplace: marketplace) }
let(:marketplace) { create(:marketplace) }
let(:delivery_area) { create(:marketplace_delivery_area, marketplace: marketplace, price_cents: 1200) }
let(:order) { create(:marketplace_order, marketplace: marketplace, delivery_area: delivery_area) }
let(:product_a) { create(:marketplace_product, marketplace: order.marketplace) }
let(:product_b) { create(:marketplace_product, marketplace: order.marketplace, tax_rate_ids: [sales_tax.id]) }
let(:sales_tax) { create(:marketplace_tax_rate, marketplace: order.marketplace, tax_rate: 5.0) }
Expand All @@ -24,7 +25,7 @@
order.ordered_products.create!(product: product_b, quantity: 2)
end

it { is_expected.to eql(product_a.price + product_b.price * 2 + marketplace.delivery_fee + (product_b.price * 2 * 0.05)) }
it { is_expected.to eql(product_a.price + product_b.price * 2 + delivery_area.price + (product_b.price * 2 * 0.05)) }
end

describe "#product_total" do
Expand Down

0 comments on commit 4b292d3

Please sign in to comment.