Skip to content

Commit

Permalink
🥗🥔✨ Marketplace: add order_by and delivery_window to `DeliveryA…
Browse files Browse the repository at this point in the history
…rea` (#1371)

- #1185

In order to support different timing for different `DeliveryArea`s,
we've given them `delivery_window` and `order_by` fields.

These fields will be used to communicate on the `Cart#show` and
`Order#show` screens what the timing expectations are for particular
orders.

Example:

- Catering orders for Lions Dance Cafe can be placed any time and
delivered anytime, but
- Dinner orders must be placed the same day by 3pm

### After
![Screenshot 2023-04-16 at 10 56 24
AM](https://user-images.githubusercontent.com/50284/232332194-f55236fa-2e61-4706-8dbb-5a2d801657a7.png)
![Screenshot 2023-04-16 at 10 56 15
AM](https://user-images.githubusercontent.com/50284/232332197-a25c6fd2-8495-4ebe-8ddf-e09a2154e590.png)
![Screenshot 2023-04-16 at 10 56 09
AM](https://user-images.githubusercontent.com/50284/232332199-0d20819d-7876-4425-88cc-372ddf3e1c81.png)
  • Loading branch information
zspencer authored Apr 17, 2023
2 parents b69f41d + 9023c14 commit af63625
Show file tree
Hide file tree
Showing 12 changed files with 112 additions and 16 deletions.
7 changes: 5 additions & 2 deletions app/furniture/marketplace/delivery/windows/_window.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
delivery
<%- if window.time_like? %>
<%= l(window.value, format: :day_month_date_hour_minute) %>
at <%= l(window.value, format: :day_month_date_hour_minute) %>
<%- elsif window.blank? %>
at your chosen time
<%- else %>
<%= window.value %>
for <%= window.value %>
<%- end %>
17 changes: 13 additions & 4 deletions app/furniture/marketplace/delivery_area_component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,21 @@
<%= label %>
</header>

<div class="italic">
<%= price %>
<div class="grow flex flex-col justify-between">
<div class="text-sm">
<%- if order_by.present? %>
Place orders by <%= order_by %> to ensure an on-time
<%- end %>
<%= render(delivery_window) %>
</div>

<div class="text-right mt-3 italic">
<%= price %>
</div>
</div>

<div class="flex flex-row justify-between">
<footer class="mt-3 flex flex-row justify-between">
<%= render edit_button if edit_button? %>
<%= render destroy_button if destroy_button? %>
</div>
</footer>
<%- end %>
14 changes: 11 additions & 3 deletions app/furniture/marketplace/delivery_area_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,21 @@ class DeliveryAreaComponent < ApplicationComponent
attr_accessor :delivery_area
delegate :label, to: :delivery_area

def initialize(delivery_area:, data: {}, classes: "")
super(data: data, classes: classes)
def initialize(delivery_area:, **kwargs)
super(**kwargs)

self.delivery_area = delivery_area
end

delegate :price, to: :delivery_area
def price
helpers.humanized_money_with_symbol(delivery_area.price)
end

delegate :order_by, to: :delivery_area

def delivery_window
Delivery::Window.new(value: delivery_area.delivery_window)
end

def edit_button
super(title: t("marketplace.delivery_areas.edit.link_to", name: delivery_area.label),
Expand Down
2 changes: 1 addition & 1 deletion app/furniture/marketplace/delivery_area_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def create?
alias_method :update?, :create?

def permitted_attributes(_)
[:label, :price]
[:label, :price, :order_by, :delivery_window]
end

class Scope < ApplicationScope
Expand Down
2 changes: 2 additions & 0 deletions app/furniture/marketplace/delivery_areas/_form.html.erb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<%= form_with(model: delivery_area.location) do |delivery_area_form| %>
<%= render "text_field", attribute: :label, form: delivery_area_form %>
<%= render "money_field", attribute: :price, form: delivery_area_form, required: true, step: 0.01, min: 0 %>
<%= render "text_field", attribute: :order_by, form: delivery_area_form %>
<%= render "text_field", attribute: :delivery_window, form: delivery_area_form %>

<%= delivery_area_form.submit %>
<%- end %>
2 changes: 1 addition & 1 deletion app/furniture/marketplace/delivery_areas_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def new

def update
if delivery_area.update(delivery_area_params)
redirect_to marketplace.location(child: :delivery_areas)
redirect_to marketplace.location(child: :delivery_areas), notice: t(".success", name: delivery_area.label)
else
render :edit
end
Expand Down
2 changes: 2 additions & 0 deletions app/furniture/marketplace/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ en:
link_to: "Add Delivery Area"
edit:
link_to: "Edit Delivery Area '%{name}'"
update:
success: "Changed Delivery Area '%{name}'"
destroy:
link_to: "Remove Delivery Area '%{name}'"
delivery_window:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class AddOrderByAndDeliveryWindowToMarketplaceDeliveryAreas < ActiveRecord::Migration[7.0]
def change
safety_assured do
change_table :marketplace_delivery_areas, bulk: true do |t|
t.string :delivery_window, default: nil
t.string :order_by, default: nil
end
end
end
end
4 changes: 3 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.0].define(version: 2023_04_14_040205) do
ActiveRecord::Schema[7.0].define(version: 2023_04_16_172045) do
# These are extensions that must be enabled in order to support this database
enable_extension "pgcrypto"
enable_extension "plpgsql"
Expand Down Expand Up @@ -134,6 +134,8 @@
t.string "price_currency", default: "USD", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "delivery_window"
t.string "order_by"
t.index ["marketplace_id"], name: "index_marketplace_delivery_areas_on_marketplace_id"
end

Expand Down
2 changes: 2 additions & 0 deletions spec/factories/furniture/marketplace.rb
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@
end

factory :marketplace_delivery_area, class: "Marketplace::DeliveryArea" do
marketplace

label { Faker::Address.city }
price { Faker::Commerce.price }
end
Expand Down
36 changes: 36 additions & 0 deletions spec/furniture/marketplace/delivery_area_component_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
require "rails_helper"

RSpec.describe Marketplace::DeliveryAreaComponent, type: :component do
subject(:output) { render_inline(component) }

let(:operator) { create(:person, operator: true) }

let(:component) { described_class.new(delivery_area: delivery_area, current_person: operator) }
let(:delivery_area) { create(:marketplace_delivery_area) }

it { is_expected.to have_content(delivery_area.label) }
it { is_expected.to have_content(controller.view_context.humanized_money_with_symbol(delivery_area.price)) }

it { is_expected.to have_selector("a[href='#{polymorphic_path(delivery_area.location)}'][data-turbo=true][data-turbo-stream=true][data-turbo-method=delete][data-method=delete][data-confirm='#{I18n.t("destroy.confirm")}']") }
it { is_expected.to have_selector("a[href='#{polymorphic_path(delivery_area.location(:edit))}'][data-turbo=true][data-turbo-method=get][data-turbo-stream=true]") }

context "when `#delivery_window` is empty" do
it { is_expected.to have_content "at your chosen time" }
end

context "when `#delivery_window`` is a string" do
let(:delivery_area) { create(:marketplace_delivery_area, delivery_window: "dinnertime same day") }

it { is_expected.to have_content "for #{delivery_area.delivery_window}" }
end

context "when #order_by is blank" do
it { is_expected.not_to have_content "Place orders by" }
end

context "when `#order_by` is set" do
let(:delivery_area) { create(:marketplace_delivery_area, order_by: "noon") }

it { is_expected.to have_content "by #{delivery_area.order_by}" }
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,15 @@
let(:perform_request) { get polymorphic_path(marketplace.location(:new, child: :delivery_area)) }

it { is_expected.to be_ok }
specify { perform_request && assert_select("form input", 3) && assert_select("#delivery_area_label") && assert_select("#delivery_area_price") }

specify do
perform_request
assert_select("form input", 5)
assert_select("#delivery_area_label")
assert_select("#delivery_area_price")
assert_select("#delivery_area_order_by")
assert_select("#delivery_area_delivery_window")
end
end

describe "#create" do
Expand All @@ -38,12 +46,26 @@
describe "#update" do
let(:delivery_area) { create(:marketplace_delivery_area, marketplace: marketplace) }
let(:perform_request) do
put polymorphic_path(delivery_area.location), params: {delivery_area: {label: "Dog", price: 60.00}}
put polymorphic_path(delivery_area.location), params: {
delivery_area: {
label: "Dog",
price: 60.00,
order_by: "3PM",
delivery_window: "6pm Same Day"
}
}

delivery_area.reload
end

it { is_expected.to redirect_to(marketplace.location(child: :delivery_areas)) }
specify { expect { result }.to change { delivery_area.reload.label }.to("Dog") }
specify { expect { result }.to change { delivery_area.reload.price }.to(Money.new(6000)) }

specify do
expect { result }.to change(delivery_area, :label).to("Dog")
.and(change(delivery_area, :price).to(Money.new(60_00)))
.and(change(delivery_area, :order_by).to("3PM"))
.and(change(delivery_area, :delivery_window).to("6pm Same Day"))
end
end

describe "#destroy" do
Expand Down

0 comments on commit af63625

Please sign in to comment.