From 45cd9cff4adb2ef064e99d7a1a59fd8aa1734ced Mon Sep 17 00:00:00 2001 From: Zee Spencer <50284+zspencer@users.noreply.github.com> Date: Sun, 16 Apr 2023 10:46:18 -0700 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=A5=97=F0=9F=A5=94=E2=9C=A8=20`Market?= =?UTF-8?q?place`:=20add=20`order=5Fby`=20and=20`delivery=5Fwindow`=20to?= =?UTF-8?q?=20`DeliveryArea`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - https://github.com/zinc-collective/convene/issues/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 Co-authored-by: Neer Malathapa Co-authored-by: Dicko Sow --- .../marketplace/delivery_area_policy.rb | 2 +- .../marketplace/delivery_areas/_form.html.erb | 2 ++ .../marketplace/delivery_areas_controller.rb | 2 +- app/furniture/marketplace/locales/en.yml | 2 ++ ...ry_window_to_marketplace_delivery_areas.rb | 10 +++++++ db/schema.rb | 4 ++- .../delivery_areas_controller_request_spec.rb | 30 ++++++++++++++++--- 7 files changed, 45 insertions(+), 7 deletions(-) create mode 100644 db/migrate/20230416172045_add_order_by_and_delivery_window_to_marketplace_delivery_areas.rb diff --git a/app/furniture/marketplace/delivery_area_policy.rb b/app/furniture/marketplace/delivery_area_policy.rb index e5e072496..5cf9968c7 100644 --- a/app/furniture/marketplace/delivery_area_policy.rb +++ b/app/furniture/marketplace/delivery_area_policy.rb @@ -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 diff --git a/app/furniture/marketplace/delivery_areas/_form.html.erb b/app/furniture/marketplace/delivery_areas/_form.html.erb index c2cff7903..50df1ded2 100644 --- a/app/furniture/marketplace/delivery_areas/_form.html.erb +++ b/app/furniture/marketplace/delivery_areas/_form.html.erb @@ -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 %> diff --git a/app/furniture/marketplace/delivery_areas_controller.rb b/app/furniture/marketplace/delivery_areas_controller.rb index a0ab75ad5..02dcbf390 100644 --- a/app/furniture/marketplace/delivery_areas_controller.rb +++ b/app/furniture/marketplace/delivery_areas_controller.rb @@ -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 diff --git a/app/furniture/marketplace/locales/en.yml b/app/furniture/marketplace/locales/en.yml index 0d6c16849..7eef11afa 100644 --- a/app/furniture/marketplace/locales/en.yml +++ b/app/furniture/marketplace/locales/en.yml @@ -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: diff --git a/db/migrate/20230416172045_add_order_by_and_delivery_window_to_marketplace_delivery_areas.rb b/db/migrate/20230416172045_add_order_by_and_delivery_window_to_marketplace_delivery_areas.rb new file mode 100644 index 000000000..cb89ea95b --- /dev/null +++ b/db/migrate/20230416172045_add_order_by_and_delivery_window_to_marketplace_delivery_areas.rb @@ -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 diff --git a/db/schema.rb b/db/schema.rb index 85fbf75c3..eba5ddcbc 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -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" @@ -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 diff --git a/spec/furniture/marketplace/delivery_areas_controller_request_spec.rb b/spec/furniture/marketplace/delivery_areas_controller_request_spec.rb index 8bcc2f49a..624febebd 100644 --- a/spec/furniture/marketplace/delivery_areas_controller_request_spec.rb +++ b/spec/furniture/marketplace/delivery_areas_controller_request_spec.rb @@ -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 @@ -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 From ba30c6cc37d7ea0183432443b9123dc9f3dbeba0 Mon Sep 17 00:00:00 2001 From: Zee Spencer <50284+zspencer@users.noreply.github.com> Date: Sun, 16 Apr 2023 11:22:34 -0700 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=A5=97=F0=9F=A5=94=E2=9C=A8=20`Market?= =?UTF-8?q?place`:=20Show=20`DeliveryArea`'s=20`#order=5Fby`=20and=20`#del?= =?UTF-8?q?ivery=5Fwindow`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - https://github.com/zinc-collective/convene/issues/1185 We added some tests to the `DeliveryAreaComponent` to make sure it looks reasonable in each use-case: - `#delivery_window` with no data - `#delivery window` with a string - `#order_by` with no data - `#order_by` with a string We also included "by" in the `_window.html.erb` partial so that people don't have to write it in their `order_by`. Co-authored-by: Neer Malathapa Co-authored-by: Dicko Sow --- .../delivery/windows/_window.html.erb | 7 ++-- .../delivery_area_component.html.erb | 17 ++++++--- .../marketplace/delivery_area_component.rb | 14 ++++++-- spec/factories/furniture/marketplace.rb | 2 ++ .../delivery_area_component_spec.rb | 36 +++++++++++++++++++ 5 files changed, 67 insertions(+), 9 deletions(-) create mode 100644 spec/furniture/marketplace/delivery_area_component_spec.rb diff --git a/app/furniture/marketplace/delivery/windows/_window.html.erb b/app/furniture/marketplace/delivery/windows/_window.html.erb index ba7e2b0a3..46b8e5333 100644 --- a/app/furniture/marketplace/delivery/windows/_window.html.erb +++ b/app/furniture/marketplace/delivery/windows/_window.html.erb @@ -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 %> diff --git a/app/furniture/marketplace/delivery_area_component.html.erb b/app/furniture/marketplace/delivery_area_component.html.erb index ff6c8fbb1..a205b34f7 100644 --- a/app/furniture/marketplace/delivery_area_component.html.erb +++ b/app/furniture/marketplace/delivery_area_component.html.erb @@ -4,12 +4,21 @@ <%= label %> -
- <%= price %> +
+
+ <%- if order_by.present? %> + Place orders by <%= order_by %> to ensure an on-time + <%- end %> + <%= render(delivery_window) %> +
+ +
+ <%= price %> +
-
+
+ <%- end %> diff --git a/app/furniture/marketplace/delivery_area_component.rb b/app/furniture/marketplace/delivery_area_component.rb index 2ebfbe4fa..0b58be3e9 100644 --- a/app/furniture/marketplace/delivery_area_component.rb +++ b/app/furniture/marketplace/delivery_area_component.rb @@ -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), diff --git a/spec/factories/furniture/marketplace.rb b/spec/factories/furniture/marketplace.rb index bbbf61f88..21599baaf 100644 --- a/spec/factories/furniture/marketplace.rb +++ b/spec/factories/furniture/marketplace.rb @@ -132,6 +132,8 @@ end factory :marketplace_delivery_area, class: "Marketplace::DeliveryArea" do + marketplace + label { Faker::Address.city } price { Faker::Commerce.price } end diff --git a/spec/furniture/marketplace/delivery_area_component_spec.rb b/spec/furniture/marketplace/delivery_area_component_spec.rb new file mode 100644 index 000000000..33983ece0 --- /dev/null +++ b/spec/furniture/marketplace/delivery_area_component_spec.rb @@ -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