diff --git a/app/furniture/marketplace/cart.rb b/app/furniture/marketplace/cart.rb index bba801f96..9db6df934 100644 --- a/app/furniture/marketplace/cart.rb +++ b/app/furniture/marketplace/cart.rb @@ -17,6 +17,7 @@ class Cart < Record # this feels like it is starting to want to be it's own model... has_encrypted :delivery_address + attribute :delivery_window, ::Marketplace::Delivery::WindowType.new has_encrypted :contact_phone_number has_encrypted :contact_email @@ -33,15 +34,6 @@ def delivery @delivery ||= becomes(Delivery) end - def delivery_window - return marketplace.delivery_window if marketplace&.delivery_window.present? - return nil if super.blank? - - DateTime.parse(super) || 48.hours.from_now - rescue Date::Error => _e - 48.hours.from_now - end - def delivery_fee return marketplace.delivery_fee if delivery_address.present? diff --git a/app/furniture/marketplace/cart/deliveries/_form.html.erb b/app/furniture/marketplace/cart/deliveries/_form.html.erb index 0ba4629a8..192ddcbd0 100644 --- a/app/furniture/marketplace/cart/deliveries/_form.html.erb +++ b/app/furniture/marketplace/cart/deliveries/_form.html.erb @@ -1,12 +1,7 @@
<%= form_with model: delivery.location do |delivery_form| %> <%= render "text_field", attribute: :delivery_address, form: delivery_form %> - - <%- if delivery.marketplace.delivery_window.present? %> - <%= render "text_field", attribute: :delivery_window, form: delivery_form, disabled?: true %> - <%- else %> - <%= render "datetime_field", attribute: :delivery_window, form: delivery_form %> - <%- end %> + <%= render "window_field", attribute: :window, form: delivery_form %> <%= render "email_field", attribute: :contact_email, form: delivery_form %> <%= render "text_field", attribute: :contact_phone_number, form: delivery_form %> <%= delivery_form.submit %> diff --git a/app/furniture/marketplace/cart/deliveries/_window_field.html.erb b/app/furniture/marketplace/cart/deliveries/_window_field.html.erb new file mode 100644 index 000000000..9c524dfb2 --- /dev/null +++ b/app/furniture/marketplace/cart/deliveries/_window_field.html.erb @@ -0,0 +1,9 @@ +<%- delivery = form.object%> +<%- disabled = delivery.marketplace.delivery_window.present? %> +<%- window = form.object.send(attribute) %> + +<%- if window.value.is_a?(DateTime) || delivery.marketplace.delivery_window.blank? %> + <%= render "datetime_field", attribute: attribute, form: form, disabled?: disabled %> +<%- else %> + <%= render "text_field", attribute: attribute, form: form, disabled?: disabled %> +<%- end %> diff --git a/app/furniture/marketplace/cart/delivery.rb b/app/furniture/marketplace/cart/delivery.rb index 34e2a2392..31a5f9a36 100644 --- a/app/furniture/marketplace/cart/delivery.rb +++ b/app/furniture/marketplace/cart/delivery.rb @@ -3,6 +3,7 @@ class Cart class Delivery < Cart extend StripsNamespaceFromModelName location(routed_as: :resource, parent: :cart) + attribute :delivery_window, ::Marketplace::Delivery::WindowType.new validates :contact_email, presence: true validates :contact_phone_number, presence: true diff --git a/app/furniture/marketplace/carts/_cart.html.erb b/app/furniture/marketplace/carts/_cart.html.erb index 7d8320bc4..c4f263bdd 100644 --- a/app/furniture/marketplace/carts/_cart.html.erb +++ b/app/furniture/marketplace/carts/_cart.html.erb @@ -29,7 +29,7 @@ Orders placed by <%= cart.marketplace.order_by %> are delivered on <%= cart.marketplace.delivery_window %> <%- elsif cart.delivery_window.present? %> - Place orders <%= cart.marketplace.order_by %> to ensure an on-time delivery for <%= l(cart.delivery_window, format: :day_month_date_hour_minute) %>
+ Place orders <%= cart.marketplace.order_by %> to ensure an on-time delivery for <%= render(cart.delivery_window) %> <%= render Marketplace::Cart::Delivery::EditButtonComponent.new(cart.delivery) %> <%- end %>

diff --git a/app/furniture/marketplace/delivery.rb b/app/furniture/marketplace/delivery.rb new file mode 100644 index 000000000..e302e6f78 --- /dev/null +++ b/app/furniture/marketplace/delivery.rb @@ -0,0 +1,5 @@ +class Marketplace + class Delivery < Order + attribute :delivery_window, ::Marketplace::Delivery::WindowType.new + end +end diff --git a/app/furniture/marketplace/delivery/window.rb b/app/furniture/marketplace/delivery/window.rb new file mode 100644 index 000000000..24f1596fa --- /dev/null +++ b/app/furniture/marketplace/delivery/window.rb @@ -0,0 +1,21 @@ +class Marketplace + class Delivery + class Window < Model + attr_writer :value + + def value + return nil if @value.blank? + + DateTime.iso8601(@value) + rescue Date::Error => _e + @value + end + + delegate :strftime, to: :value + + def eql?(other) + value.eql?(other.value) + end + end + end +end diff --git a/app/furniture/marketplace/delivery/window_type.rb b/app/furniture/marketplace/delivery/window_type.rb new file mode 100644 index 000000000..129ff3613 --- /dev/null +++ b/app/furniture/marketplace/delivery/window_type.rb @@ -0,0 +1,13 @@ +class Marketplace + class Delivery + class WindowType < ActiveRecord::Type::Value + def deserialize(value) + Window.new(value: value) + end + end + + def cast(value) + Window.value(value: value) + end + end +end diff --git a/app/furniture/marketplace/delivery/windows/_window.html.erb b/app/furniture/marketplace/delivery/windows/_window.html.erb new file mode 100644 index 000000000..3e292cb85 --- /dev/null +++ b/app/furniture/marketplace/delivery/windows/_window.html.erb @@ -0,0 +1,5 @@ +<%- if window.value.is_a?(DateTime) %> + <%= l(window.value, format: :day_month_date_hour_minute) %> +<%- else %> + <%= window.value %> +<%- end %> diff --git a/app/furniture/marketplace/order.rb b/app/furniture/marketplace/order.rb index b36c28aaa..370d14206 100644 --- a/app/furniture/marketplace/order.rb +++ b/app/furniture/marketplace/order.rb @@ -12,6 +12,7 @@ class Order < Record has_many :products, through: :ordered_products, inverse_of: :orders has_encrypted :delivery_address + attribute :delivery_window, Delivery::WindowType.new has_encrypted :contact_phone_number has_encrypted :contact_email @@ -28,6 +29,10 @@ def tax_total ordered_products.sum(0, &:tax_amount) end + def delivery + becomes(Delivery) + end + delegate :delivery_fee, to: :marketplace def marketplace_name diff --git a/app/furniture/marketplace/order/email_receipt_component.html.erb b/app/furniture/marketplace/order/email_receipt_component.html.erb index c28a3acb7..871ac214e 100644 --- a/app/furniture/marketplace/order/email_receipt_component.html.erb +++ b/app/furniture/marketplace/order/email_receipt_component.html.erb @@ -49,7 +49,7 @@ Delivery Details Delivery Schedule: - <%= order.delivery_window %> + <%= render(order.delivery.window) %> Buyer Email: diff --git a/app/views/application/_datetime_field.html.erb b/app/views/application/_datetime_field.html.erb index 81583d9e5..fd69f7d66 100644 --- a/app/views/application/_datetime_field.html.erb +++ b/app/views/application/_datetime_field.html.erb @@ -1,5 +1,6 @@ +<%- disabled = local_assigns.fetch(:disabled?, false)%>
<%= form.label attribute %> - <%= form.datetime_field attribute %> + <%= form.datetime_field attribute, disabled: disabled %> <%= render partial: "error", locals: { model: form.object, attribute: attribute } %>
diff --git a/spec/furniture/marketplace/delivery/window_spec.rb b/spec/furniture/marketplace/delivery/window_spec.rb new file mode 100644 index 000000000..6ba5645e5 --- /dev/null +++ b/spec/furniture/marketplace/delivery/window_spec.rb @@ -0,0 +1,27 @@ +require "rails_helper" + +RSpec.describe Marketplace::Delivery::Window do + subject(:window) { described_class.new(value: value) } + + describe "#value" do + subject(:deserialize) { window.value } + + context "when the value is blank" do + let(:value) { "" } + + it { is_expected.to be_nil } + end + + context "when the value is an iso8601 String" do + let(:value) { DateTime.parse("2023-01-01 3:00pm").iso8601 } + + it { is_expected.to eql(DateTime.parse("2023-01-01 3:00pm")) } + end + + context "when the value is a plain string" do + let(:value) { "This Evening" } + + it { is_expected.to eql(value) } + end + end +end diff --git a/spec/furniture/marketplace/delivery/window_type_spec.rb b/spec/furniture/marketplace/delivery/window_type_spec.rb new file mode 100644 index 000000000..330f5337b --- /dev/null +++ b/spec/furniture/marketplace/delivery/window_type_spec.rb @@ -0,0 +1,11 @@ +require "rails_helper" + +RSpec.describe Marketplace::Delivery::WindowType do + subject(:type) { described_class.new } + + describe "#deserialize" do + subject(:deserialize) { type.deserialize("words") } + + it { is_expected.to eql(Marketplace::Delivery::Window.new(value: "words")) } + end +end