From ebe2923512b5f24e63aac187a1512261bfed1e4c Mon Sep 17 00:00:00 2001
From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com>
Date: Wed, 1 Sep 2021 11:20:03 +0100
Subject: [PATCH 01/20] Improve form outputs and error handling
---
app/controllers/split_checkout_controller.rb | 12 ++++++++----
app/helpers/application_helper.rb | 18 +++++++++++++-----
app/views/split_checkout/_details.html.haml | 16 +++++++---------
app/views/split_checkout/_payment.html.haml | 7 ++++---
app/views/split_checkout/_summary.html.haml | 11 ++++-------
5 files changed, 36 insertions(+), 28 deletions(-)
diff --git a/app/controllers/split_checkout_controller.rb b/app/controllers/split_checkout_controller.rb
index f7d1e20cd7..073b9c6693 100644
--- a/app/controllers/split_checkout_controller.rb
+++ b/app/controllers/split_checkout_controller.rb
@@ -108,11 +108,8 @@ class SplitCheckoutController < ::BaseController
def confirm_order
return unless @order.confirmation? && params[:confirm_order]
+ return unless validate_terms_and_conditions!
- if params["accept_terms"] != "1"
- @order.errors.add(:base, "terms_not_accepted")
- return false
- end
@order.confirm!
end
@@ -139,6 +136,13 @@ class SplitCheckoutController < ::BaseController
@checkout_step ||= params[:step]
end
+ def validate_terms_and_conditions!
+ return true if params[:accept_terms]
+
+ @order.errors.add(:terms_and_conditions, t("split_checkout.errors.terms_not_accepted"))
+ false
+ end
+
def order_params
return @order_params unless @order_params.nil?
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index c00825f74d..e4e18601c7 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -4,14 +4,22 @@ module ApplicationHelper
include RawParams
include Pagy::Frontend
- def error_message_on(object, method, _options = {})
+ def error_message_on(object, method, options = {})
object = convert_to_model(object)
obj = object.respond_to?(:errors) ? object : instance_variable_get("@#{object}")
- if obj && obj.errors[method].present?
- errors = obj.errors[method].map { |err| h(err) }.join('
').html_safe
- content_tag(:span, errors, class: 'formError')
+
+ return "" unless obj && obj.errors[method].present?
+
+ errors = obj.errors[method].map { |err| h(err) }.join('
').html_safe
+
+ if options[:standalone]
+ content_tag(
+ :div,
+ content_tag(:span, errors, class: 'formError standalone'),
+ class: 'checkout-input'
+ )
else
- ''
+ content_tag(:span, errors, class: 'formError')
end
end
diff --git a/app/views/split_checkout/_details.html.haml b/app/views/split_checkout/_details.html.haml
index 0642870cbe..59504af294 100644
--- a/app/views/split_checkout/_details.html.haml
+++ b/app/views/split_checkout/_details.html.haml
@@ -71,10 +71,7 @@
- display_ship_address = false
- ship_method_description = nil
- - if selected_shipping_method == nil && @order.errors.messages_for(:base).include?("no_shipping_method_selected")
- %div.checkout-input
- %span.formError.standalone
- = t("split_checkout.step1.delivery_address.errors.no_shipping_method_selected")
+
- @shipping_methods.each do |shipping_method|
%div.checkout-input
= fields_for shipping_method do |shipping_method_form|
@@ -93,6 +90,8 @@
- if shipping_method.id == selected_shipping_method.to_i
- ship_method_description = shipping_method.description
+ = f.error_message_on :shipping_method, standalone: true
+
%div.checkout-input{"data-shippingmethod-target": "shippingMethodDescription", style: "display: #{ship_method_description == nil ? 'none' : 'block'}" }
#distributor_address.panel
%span{"data-shippingmethod-target": "shippingMethodDescriptionContent"} #{ship_method_description}
@@ -103,8 +102,8 @@
= @order.order_cycle.pickup_time_for(@order.distributor)
%div.checkout-input{ "data-toggle-target": "content", style: "display: #{display_ship_address ? 'block' : 'none'}" }
- = f.check_box "Checkout.ship_address_same_as_billing", { id: "Checkout.ship_address_same_as_billing", "data-action": "shippingmethod#showHideShippingAddress", "data-shippingmethod-target": "shippingAddressCheckbox", checked: @ship_address_same_as_billing == "1" }
- = f.label "Checkout.ship_address_same_as_billing", t(:checkout_address_same), { for: "Checkout.ship_address_same_as_billing" }
+ = f.check_box :ship_address_same_as_billing, { id: "ship_address_same_as_billing", name: "ship_address_same_as_billing", "data-action": "shippingmethod#showHideShippingAddress", "data-shippingmethod-target": "shippingAddressCheckbox", checked: @ship_address_same_as_billing == "1" }, 1, nil
+ = f.label :ship_address_same_as_billing, t(:checkout_address_same), { for: "ship_address_same_as_billing" }
%div{"data-shippingmethod-target": "shippingMethodAddress", style: "display: #{display_ship_address == false || @ship_address_same_as_billing == "1" ? 'none' : 'block'}" }
= f.fields :ship_address, model: @order.ship_address do |ship_address|
@@ -138,9 +137,8 @@
- if spree_current_user
%div.checkout-input{ "data-toggle-target": "content", style: "display: none" }
- = f.check_box "Checkout.default_ship_address", { id: "Checkout.default_ship_address" }
- = f.label "Checkout.default_ship_address", t(:checkout_default_ship_address), { for: "Checkout.default_ship_address" }
-
+ = f.check_box :default_ship_address, { id: "default_ship_address", name: "default_ship_address" }
+ = f.label :default_ship_address, t(:checkout_default_ship_address), { for: "default_ship_address" }
.div.checkout-input
= f.label :special_instructions, t(:checkout_instructions)
diff --git a/app/views/split_checkout/_payment.html.haml b/app/views/split_checkout/_payment.html.haml
index 4f4ded6433..02e9d7e28e 100644
--- a/app/views/split_checkout/_payment.html.haml
+++ b/app/views/split_checkout/_payment.html.haml
@@ -2,21 +2,22 @@
%div.checkout-substep{"data-controller": "paymentmethod"}
%div.checkout-title
= t("split_checkout.step2.payment_method.title")
+
- selected_payment_method = @order.payments&.with_state(:checkout)&.first&.payment_method_id
- available_payment_methods.each do |payment_method|
%div.checkout-input
= f.radio_button :payment_method_id, payment_method.id,
- name: "order[payments_attributes][][payment_method_id]",
id: "payment_method_#{payment_method.id}",
name: "order[payments_attributes][][payment_method_id]",
checked: (payment_method.id == selected_payment_method),
"data-action": "paymentmethod#selectPaymentMethod",
"data-paymentmethod-description": "#{payment_method.description}"
- = f.label payment_method.id, "#{payment_method.name} (#{payment_or_shipping_price(payment_method, @order)})", {for: "payment_method_" + payment_method.id.to_s }
+ = f.label :payment_method_id, "#{payment_method.name} (#{payment_or_shipping_price(payment_method, @order)})", for: "payment_method_#{payment_method.id}"
+
+ = f.error_message_on :payment_method, standalone: true
%div
.panel{"data-paymentmethod-target": "panel", style: "display: none"}
-
%div.checkout-substep
= t("split_checkout.step2.explaination")
diff --git a/app/views/split_checkout/_summary.html.haml b/app/views/split_checkout/_summary.html.haml
index 1f6bd3fea2..57c9c18ab5 100644
--- a/app/views/split_checkout/_summary.html.haml
+++ b/app/views/split_checkout/_summary.html.haml
@@ -72,14 +72,11 @@
= render 'spree/orders/summary', order: @order
%div.checkout-substep.medium-6
- - if @order.errors.messages_for(:base).include?("terms_not_accepted")
- %div.checkout-input
- %span.formError.standalone
- = t("split_checkout.errors.terms_not_accepted")
-
%div.checkout-input
- = f.check_box :accept_terms, {id: 'accept_terms', name: "accept_terms", "checked": "#{all_terms_and_conditions_already_accepted?}"}
- = f.label :accept_terms, t('split_checkout.step3.terms_and_conditions.message_html', terms_and_conditions_link: link_to( t("split_checkout.step3.terms_and_conditions.link_text"), @order.distributor.terms_and_conditions.url, target: '_blank'), tos_link: link_to_platform_terms), {for: "accept_terms"}
+ = f.check_box :accept_terms, { id: "accept_terms", name: "accept_terms", "checked": "#{all_terms_and_conditions_already_accepted?}" }, 1, nil
+ = f.label :accept_terms, t('split_checkout.step3.terms_and_conditions.message_html', terms_and_conditions_link: link_to( t("split_checkout.step3.terms_and_conditions.link_text"), @order.distributor.terms_and_conditions.url, target: '_blank'), tos_link: link_to_platform_terms), { for: "accept_terms" }
+
+ = f.error_message_on :terms_and_conditions, standalone: true
%div.checkout-input
= t("split_checkout.step3.agree")
From 3dd8ed85b4fdb55c85a2a6b921aadc81885cf7bf Mon Sep 17 00:00:00 2001
From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com>
Date: Wed, 1 Sep 2021 11:28:55 +0100
Subject: [PATCH 02/20] Implement manual shipping method selection
---
.../concerns/checkout_callbacks.rb | 1 +
app/models/concerns/order_shipment.rb | 2 ++
.../order_management/stock/estimator.rb | 28 +++++++++++--------
3 files changed, 20 insertions(+), 11 deletions(-)
diff --git a/app/controllers/concerns/checkout_callbacks.rb b/app/controllers/concerns/checkout_callbacks.rb
index f29b81d7dc..3e3e360bd4 100644
--- a/app/controllers/concerns/checkout_callbacks.rb
+++ b/app/controllers/concerns/checkout_callbacks.rb
@@ -27,6 +27,7 @@ module CheckoutCallbacks
def load_order
@order = current_order
+ @order.manual_shipping_selection = true
redirect_to(main_app.shop_path) && return if redirect_to_shop?
redirect_to_cart_path && return unless valid_order_line_items?
diff --git a/app/models/concerns/order_shipment.rb b/app/models/concerns/order_shipment.rb
index 267edf64f4..dd5ebeba01 100644
--- a/app/models/concerns/order_shipment.rb
+++ b/app/models/concerns/order_shipment.rb
@@ -13,6 +13,8 @@ require 'active_support/concern'
module OrderShipment
extend ActiveSupport::Concern
+ attr_accessor :manual_shipping_selection
+
def shipment
shipments.first
end
diff --git a/engines/order_management/app/services/order_management/stock/estimator.rb b/engines/order_management/app/services/order_management/stock/estimator.rb
index c97d9c3b99..371ef9b980 100644
--- a/engines/order_management/app/services/order_management/stock/estimator.rb
+++ b/engines/order_management/app/services/order_management/stock/estimator.rb
@@ -22,17 +22,8 @@ module OrderManagement
shipping_rates.sort_by! { |r| r.cost || 0 }
- unless shipping_rates.empty?
- if frontend_only
- shipping_rates.each do |rate|
- if rate.shipping_method.frontend?
- rate.selected = true
- break
- end
- end
- else
- shipping_rates.first.selected = true
- end
+ unless shipping_rates.empty? || order.manual_shipping_selection
+ select_first_shipping_method(shipping_rates, frontend_only)
end
shipping_rates
@@ -40,6 +31,21 @@ module OrderManagement
private
+ # Sets the first available shipping method to "selected".
+ # Note: seems like a hangover from Spree, we can probably just remove this at some point.
+ def select_first_shipping_method(shipping_rates, frontend_only)
+ if frontend_only
+ shipping_rates.each do |rate|
+ if rate.shipping_method.frontend?
+ rate.selected = true
+ break
+ end
+ end
+ else
+ shipping_rates.first.selected = true
+ end
+ end
+
def shipping_methods(package)
shipping_methods = package.shipping_methods
shipping_methods.delete_if { |ship_method| !ship_method.calculator.available?(package) }
From 978c882ed96dd8ca269a60af4c53c27de5688e39 Mon Sep 17 00:00:00 2001
From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com>
Date: Wed, 1 Sep 2021 11:43:06 +0100
Subject: [PATCH 03/20] Don't select a random shipping method in Shipment
---
app/models/spree/shipment.rb | 6 ++++--
spec/models/spree/shipment_spec.rb | 1 +
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/app/models/spree/shipment.rb b/app/models/spree/shipment.rb
index 804e09de3f..bf83aa35fb 100644
--- a/app/models/spree/shipment.rb
+++ b/app/models/spree/shipment.rb
@@ -84,7 +84,9 @@ module Spree
end
def shipping_method
- selected_shipping_rate.try(:shipping_method) || shipping_rates.first.try(:shipping_method)
+ method = selected_shipping_rate.try(:shipping_method)
+ method ||= shipping_rates.first.try(:shipping_method) unless order.manual_shipping_selection
+ method
end
def add_shipping_method(shipping_method, selected = false)
@@ -263,7 +265,7 @@ module Spree
fee_adjustment.amount = selected_shipping_rate.cost if fee_adjustment.open?
fee_adjustment.save!
fee_adjustment.reload
- elsif selected_shipping_rate_id
+ elsif shipping_method
shipping_method.create_adjustment(adjustment_label,
self,
true,
diff --git a/spec/models/spree/shipment_spec.rb b/spec/models/spree/shipment_spec.rb
index 1a18b3777c..f1f13edbb7 100644
--- a/spec/models/spree/shipment_spec.rb
+++ b/spec/models/spree/shipment_spec.rb
@@ -388,6 +388,7 @@ describe Spree::Shipment do
end
it "should create adjustment when not present" do
+ allow(shipment).to receive_messages(fee_adjustment: nil)
allow(shipment).to receive_messages(selected_shipping_rate_id: 1)
expect(shipping_method).to receive(:create_adjustment).with(shipment.adjustment_label,
shipment, true, "open")
From 2786fb30baec5cc852f830d90421fd256a1938f1 Mon Sep 17 00:00:00 2001
From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com>
Date: Wed, 1 Sep 2021 11:48:49 +0100
Subject: [PATCH 04/20] Simplify order advancing process
---
app/controllers/split_checkout_controller.rb | 13 +++----------
app/services/order_workflow.rb | 17 +++++++----------
2 files changed, 10 insertions(+), 20 deletions(-)
diff --git a/app/controllers/split_checkout_controller.rb b/app/controllers/split_checkout_controller.rb
index 073b9c6693..251d94a8a9 100644
--- a/app/controllers/split_checkout_controller.rb
+++ b/app/controllers/split_checkout_controller.rb
@@ -37,8 +37,7 @@ class SplitCheckoutController < ::BaseController
load_shipping_method
handle_shipping_method_selection
- confirm_or_update = confirm_order || update_order
- if confirm_or_update && advance_order_state
+ if confirm_order || update_order
clear_invalid_payments
redirect_to_step
else
@@ -117,19 +116,13 @@ class SplitCheckoutController < ::BaseController
return unless params[:order]
return if @order.state == "address" && params[:shipping_method_id].blank?
- @order.update(order_params)
+ @order.update(order_params) && advance_order_state
end
def advance_order_state
return true if @order.complete?
- workflow_options = raw_params.slice(:shipping_method_id)
-
- if @order.payments.empty?
- OrderWorkflow.new(@order).advance_to_payment(workflow_options)
- else
- OrderWorkflow.new(@order).advance_to_confirmation(workflow_options)
- end
+ OrderWorkflow.new(@order).advance_checkout(raw_params.slice(:shipping_method_id))
end
def checkout_step
diff --git a/app/services/order_workflow.rb b/app/services/order_workflow.rb
index 8fc1615c77..8f8b3028c9 100644
--- a/app/services/order_workflow.rb
+++ b/app/services/order_workflow.rb
@@ -23,19 +23,16 @@ class OrderWorkflow
result
end
- def advance_to_payment(options = {})
- if options[:shipping_method_id]
- order.select_shipping_method(options[:shipping_method_id])
- end
+ def advance_to_payment
advance_to_state("payment", advance_order_options)
end
- def advance_to_confirmation(options = {})
- if options[:shipping_method_id]
- order.select_shipping_method(options[:shipping_method_id])
- end
+ def advance_checkout(options = {})
+ order.select_shipping_method(options[:shipping_method_id])
- advance_to_state("confirmation")
+ advance_to = order.address? || order.delivery? ? "payment" : "confirmation"
+
+ advance_to_state(advance_to, advance_order_options.merge(options))
end
private
@@ -71,7 +68,7 @@ class OrderWorkflow
end
def after_transition_hook(options)
- if order.state == "delivery" && (options[:shipping_method_id])
+ if order.state == "delivery"
order.select_shipping_method(options[:shipping_method_id])
end
From ac4d721de0aaebcb6edb471bd0ac9e37cb8bde6e Mon Sep 17 00:00:00 2001
From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com>
Date: Wed, 1 Sep 2021 11:51:47 +0100
Subject: [PATCH 05/20] Extract #set_payment_amount method
---
app/controllers/split_checkout_controller.rb | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/app/controllers/split_checkout_controller.rb b/app/controllers/split_checkout_controller.rb
index 251d94a8a9..94d61277ef 100644
--- a/app/controllers/split_checkout_controller.rb
+++ b/app/controllers/split_checkout_controller.rb
@@ -146,14 +146,17 @@ class SplitCheckoutController < ::BaseController
payments_attributes: [:payment_method_id]
)
- if @order_params[:payments_attributes]
- # Set payment amount
- @order_params[:payments_attributes].first[:amount] = @order.total
- end
+ set_payment_amount
@order_params
end
+ def set_payment_amount
+ return unless @order_params[:payments_attributes]
+
+ @order_params[:payments_attributes].first[:amount] = @order.total
+ end
+
def redirect_to_step
case @order.state
when "cart", "address", "delivery"
From 3fabe308cdb0602473eba030230be3a4f61c0469 Mon Sep 17 00:00:00 2001
From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com>
Date: Wed, 1 Sep 2021 12:06:39 +0100
Subject: [PATCH 06/20] Extract #shipping_and_billing_match? helper
---
app/controllers/split_checkout_controller.rb | 7 -------
app/helpers/checkout_helper.rb | 4 ++++
app/views/split_checkout/_details.html.haml | 4 ++--
3 files changed, 6 insertions(+), 9 deletions(-)
diff --git a/app/controllers/split_checkout_controller.rb b/app/controllers/split_checkout_controller.rb
index 94d61277ef..98b3530e88 100644
--- a/app/controllers/split_checkout_controller.rb
+++ b/app/controllers/split_checkout_controller.rb
@@ -28,7 +28,6 @@ class SplitCheckoutController < ::BaseController
@order.errors.clear
@order.bill_address.errors.clear
@order.ship_address.errors.clear
- @ship_address_same_as_billing = "1" if ship_address_matches_bill_address?
rescue Spree::Core::GatewayError => e
rescue_from_spree_gateway_error(e)
end
@@ -51,12 +50,6 @@ class SplitCheckoutController < ::BaseController
private
- def ship_address_matches_bill_address?
- attrs_to_check = %w(firstname lastname address1 address2 state_id city zipcode phone country_id)
- ((@order.bill_address.attributes.to_a -
- @order.ship_address.attributes.to_a).map(&:first) & attrs_to_check).blank?
- end
-
def handle_shipping_method_selection
return unless @shipping_method
diff --git a/app/helpers/checkout_helper.rb b/app/helpers/checkout_helper.rb
index 1285ce297c..c5b22b4784 100644
--- a/app/helpers/checkout_helper.rb
+++ b/app/helpers/checkout_helper.rb
@@ -1,6 +1,10 @@
# frozen_string_literal: true
module CheckoutHelper
+ def shipping_and_billing_match?(order)
+ order.ship_address == order.bill_address
+ end
+
def guest_checkout_allowed?
current_order.distributor.allow_guest_orders?
end
diff --git a/app/views/split_checkout/_details.html.haml b/app/views/split_checkout/_details.html.haml
index 59504af294..dda5bd70d9 100644
--- a/app/views/split_checkout/_details.html.haml
+++ b/app/views/split_checkout/_details.html.haml
@@ -102,10 +102,10 @@
= @order.order_cycle.pickup_time_for(@order.distributor)
%div.checkout-input{ "data-toggle-target": "content", style: "display: #{display_ship_address ? 'block' : 'none'}" }
- = f.check_box :ship_address_same_as_billing, { id: "ship_address_same_as_billing", name: "ship_address_same_as_billing", "data-action": "shippingmethod#showHideShippingAddress", "data-shippingmethod-target": "shippingAddressCheckbox", checked: @ship_address_same_as_billing == "1" }, 1, nil
+ = f.check_box :ship_address_same_as_billing, { id: "ship_address_same_as_billing", name: "ship_address_same_as_billing", "data-action": "shippingmethod#showHideShippingAddress", "data-shippingmethod-target": "shippingAddressCheckbox", checked: shipping_and_billing_match?(@order) }, 1, nil
= f.label :ship_address_same_as_billing, t(:checkout_address_same), { for: "ship_address_same_as_billing" }
- %div{"data-shippingmethod-target": "shippingMethodAddress", style: "display: #{display_ship_address == false || @ship_address_same_as_billing == "1" ? 'none' : 'block'}" }
+ %div{"data-shippingmethod-target": "shippingMethodAddress", style: "display: #{display_ship_address == false || shipping_and_billing_match?(@order) ? 'none' : 'block'}" }
= f.fields :ship_address, model: @order.ship_address do |ship_address|
%div.checkout-input
= ship_address.label :address1, t("split_checkout.step1.address.address1.label")
From b7e1882bd8e45ba53fbacab22058a6109a0faa4c Mon Sep 17 00:00:00 2001
From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com>
Date: Wed, 1 Sep 2021 12:11:40 +0100
Subject: [PATCH 07/20] Simplify setting address params
---
app/controllers/split_checkout_controller.rb | 48 ++++++--------------
1 file changed, 13 insertions(+), 35 deletions(-)
diff --git a/app/controllers/split_checkout_controller.rb b/app/controllers/split_checkout_controller.rb
index 98b3530e88..450acf6058 100644
--- a/app/controllers/split_checkout_controller.rb
+++ b/app/controllers/split_checkout_controller.rb
@@ -34,7 +34,6 @@ class SplitCheckoutController < ::BaseController
def update
load_shipping_method
- handle_shipping_method_selection
if confirm_order || update_order
clear_invalid_payments
@@ -50,12 +49,6 @@ class SplitCheckoutController < ::BaseController
private
- def handle_shipping_method_selection
- return unless @shipping_method
-
- populate_ship_address_params
- end
-
def load_shipping_method
if params[:shipping_method_id]
@shipping_method = Spree::ShippingMethod.where(id: params[:shipping_method_id]).first
@@ -66,34 +59,6 @@ class SplitCheckoutController < ::BaseController
end
end
- def populate_ship_address_params
- return unless params.dig(:order, :ship_address_attributes).present? &&
- params.dig(:order, :bill_address_attributes).present?
-
- if params.dig(:order, "Checkout.ship_address_same_as_billing") == "1"
- params[:order][:ship_address_attributes] = params[:order][:bill_address_attributes]
- return
- end
-
- address_attrs = [
- :firstname,
- :lastname,
- :phone,
- :address1,
- :address2,
- :city,
- :state_id,
- :zipcode,
- :country_id,
- :id
- ]
- address_attrs.each do |attr|
- next if params[:order][:ship_address_attributes][attr].present?
-
- params[:order][:ship_address_attributes][attr] = params[:order][:bill_address_attributes][attr]
- end
- end
-
def clear_invalid_payments
@order.payments.with_state(:invalid).delete_all
end
@@ -139,11 +104,24 @@ class SplitCheckoutController < ::BaseController
payments_attributes: [:payment_method_id]
)
+ set_address_details
set_payment_amount
@order_params
end
+ def set_address_details
+ return unless @order_params[:ship_address_attributes] && @order_params[:bill_address_attributes]
+
+ if params[:ship_address_same_as_billing]
+ @order_params[:ship_address_attributes] = @order_params[:bill_address_attributes]
+ else
+ @order_params[:ship_address_attributes][:firstname] = @order_params[:bill_address_attributes][:firstname]
+ @order_params[:ship_address_attributes][:lastname] = @order_params[:bill_address_attributes][:lastname]
+ @order_params[:ship_address_attributes][:phone] = @order_params[:bill_address_attributes][:phone]
+ end
+ end
+
def set_payment_amount
return unless @order_params[:payments_attributes]
From 98004834332e7fa7cad6aa07dc70a6b82d6a6149 Mon Sep 17 00:00:00 2001
From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com>
Date: Wed, 1 Sep 2021 12:20:05 +0100
Subject: [PATCH 08/20] Simplify displaying selected shipping method
---
app/controllers/split_checkout_controller.rb | 12 ------------
app/views/split_checkout/_details.html.haml | 3 +--
2 files changed, 1 insertion(+), 14 deletions(-)
diff --git a/app/controllers/split_checkout_controller.rb b/app/controllers/split_checkout_controller.rb
index 450acf6058..8245dd57a7 100644
--- a/app/controllers/split_checkout_controller.rb
+++ b/app/controllers/split_checkout_controller.rb
@@ -33,8 +33,6 @@ class SplitCheckoutController < ::BaseController
end
def update
- load_shipping_method
-
if confirm_order || update_order
clear_invalid_payments
redirect_to_step
@@ -49,16 +47,6 @@ class SplitCheckoutController < ::BaseController
private
- def load_shipping_method
- if params[:shipping_method_id]
- @shipping_method = Spree::ShippingMethod.where(id: params[:shipping_method_id]).first
- @shipping_method_id = params[:shipping_method_id]
- else
- @shipping_method = @order.shipping_method
- @shipping_method_id = @shipping_method&.id
- end
- end
-
def clear_invalid_payments
@order.payments.with_state(:invalid).delete_all
end
diff --git a/app/views/split_checkout/_details.html.haml b/app/views/split_checkout/_details.html.haml
index dda5bd70d9..bd10cd0eb1 100644
--- a/app/views/split_checkout/_details.html.haml
+++ b/app/views/split_checkout/_details.html.haml
@@ -64,8 +64,7 @@
= f.label :checkout_default_bill_address, t(:checkout_default_bill_address)
%div.checkout-substep{ "data-controller": "toggle shippingmethod" }
- - selected_shipping_method = @order.shipping_method&.id || @shipping_method_id
- -# DELIVERY ADDRESS
+ - selected_shipping_method = @order.shipping_method&.id || params[:shipping_method_id]
%div.checkout-title
= t("split_checkout.step1.delivery_address.title")
From 6acb1f64844cf11766a877e6ff55a890feab9c5a Mon Sep 17 00:00:00 2001
From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com>
Date: Wed, 1 Sep 2021 12:25:20 +0100
Subject: [PATCH 09/20] Tidy up view variables
---
app/views/split_checkout/_details.html.haml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/views/split_checkout/_details.html.haml b/app/views/split_checkout/_details.html.haml
index bd10cd0eb1..4e0be37ac9 100644
--- a/app/views/split_checkout/_details.html.haml
+++ b/app/views/split_checkout/_details.html.haml
@@ -85,7 +85,7 @@
= shipping_method_form.label shipping_method.id, shipping_method.name, {for: "shipping_method_" + shipping_method.id.to_s }
%em.light
= payment_or_shipping_price(shipping_method, @order)
- - display_ship_address = display_ship_address || (shipping_method.id == selected_shipping_method.to_i && shipping_method.require_ship_address)
+ - display_ship_address = (shipping_method.id == selected_shipping_method.to_i && shipping_method.require_ship_address)
- if shipping_method.id == selected_shipping_method.to_i
- ship_method_description = shipping_method.description
@@ -104,7 +104,7 @@
= f.check_box :ship_address_same_as_billing, { id: "ship_address_same_as_billing", name: "ship_address_same_as_billing", "data-action": "shippingmethod#showHideShippingAddress", "data-shippingmethod-target": "shippingAddressCheckbox", checked: shipping_and_billing_match?(@order) }, 1, nil
= f.label :ship_address_same_as_billing, t(:checkout_address_same), { for: "ship_address_same_as_billing" }
- %div{"data-shippingmethod-target": "shippingMethodAddress", style: "display: #{display_ship_address == false || shipping_and_billing_match?(@order) ? 'none' : 'block'}" }
+ %div{"data-shippingmethod-target": "shippingMethodAddress", style: "display: #{!display_ship_address || shipping_and_billing_match?(@order) ? 'none' : 'block'}" }
= f.fields :ship_address, model: @order.ship_address do |ship_address|
%div.checkout-input
= ship_address.label :address1, t("split_checkout.step1.address.address1.label")
From 57504f42d89f092a46b52346bd63e6a7104329ac Mon Sep 17 00:00:00 2001
From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com>
Date: Wed, 1 Sep 2021 12:34:52 +0100
Subject: [PATCH 10/20] Move validations to state transitions
---
app/controllers/split_checkout_controller.rb | 6 +-----
app/models/spree/order/checkout.rb | 20 ++++++++++++++++++++
config/locales/en.yml | 4 ++--
3 files changed, 23 insertions(+), 7 deletions(-)
diff --git a/app/controllers/split_checkout_controller.rb b/app/controllers/split_checkout_controller.rb
index 8245dd57a7..952569c9e9 100644
--- a/app/controllers/split_checkout_controller.rb
+++ b/app/controllers/split_checkout_controller.rb
@@ -37,10 +37,7 @@ class SplitCheckoutController < ::BaseController
clear_invalid_payments
redirect_to_step
else
- if @shipping_method_id.blank?
- @order.errors.add(:base, "no_shipping_method_selected")
- end
- flash.now[:error] = "#{I18n.t('split_checkout.errors.global')}"
+ flash.now[:error] = I18n.t('split_checkout.errors.global')
render :edit
end
end
@@ -60,7 +57,6 @@ class SplitCheckoutController < ::BaseController
def update_order
return unless params[:order]
- return if @order.state == "address" && params[:shipping_method_id].blank?
@order.update(order_params) && advance_order_state
end
diff --git a/app/models/spree/order/checkout.rb b/app/models/spree/order/checkout.rb
index 148348ce1e..dd4d0a80e6 100644
--- a/app/models/spree/order/checkout.rb
+++ b/app/models/spree/order/checkout.rb
@@ -75,7 +75,9 @@ module Spree
before_transition to: :delivery, do: :create_proposed_shipments
before_transition to: :delivery, do: :ensure_available_shipping_rates
+ before_transition to: :payment, do: :validate_shipping_method!
before_transition to: :payment, do: :create_tax_charge!
+ before_transition to: :confirmation, do: :validate_payment_method!
after_transition to: :complete, do: :finalize!
after_transition to: :resumed, do: :after_resume
@@ -135,6 +137,24 @@ module Spree
updated_at: Time.zone.now,
)
end
+
+ private
+
+ def validate_shipping_method!
+ return unless user && Flipper.enabled?(:split_checkout, user)
+ return if shipping_method.present?
+
+ errors.add :shipping_method, I18n.t('split_checkout.errors.select_a_shipping_method')
+ throw :halt
+ end
+
+ def validate_payment_method!
+ return unless user && Flipper.enabled?(:split_checkout, user)
+ return if payments.any?
+
+ errors.add :payment_method, I18n.t('split_checkout.errors.select_a_payment_method')
+ throw :halt
+ end
end
end
end
diff --git a/config/locales/en.yml b/config/locales/en.yml
index f3a04446f6..0113a7e9a3 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -1660,8 +1660,6 @@ en:
label: Country
delivery_address:
title: Delivery address
- errors:
- no_shipping_method_selected: No shipping method selected
submit: Next - Payment method
cancel: Back to Edit basket
step2:
@@ -1697,6 +1695,8 @@ en:
required: Field cannot be blank
invalid_number: "Please enter a valid phone number"
invalid_email: "Please enter a valid email address"
+ select_a_shipping_method: Select a shipping method
+ select_a_payment_method: Select a payment method
order_paid: PAID
order_not_paid: NOT PAID
order_total: Total order
From 4cff185b4b08df847e352939f08eef5a6b9017dc Mon Sep 17 00:00:00 2001
From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com>
Date: Wed, 1 Sep 2021 12:36:27 +0100
Subject: [PATCH 11/20] Extract params handling to service
---
app/controllers/split_checkout_controller.rb | 34 +----------
app/services/checkout/params.rb | 63 ++++++++++++++++++++
2 files changed, 65 insertions(+), 32 deletions(-)
create mode 100644 app/services/checkout/params.rb
diff --git a/app/controllers/split_checkout_controller.rb b/app/controllers/split_checkout_controller.rb
index 952569c9e9..61276b4303 100644
--- a/app/controllers/split_checkout_controller.rb
+++ b/app/controllers/split_checkout_controller.rb
@@ -56,7 +56,7 @@ class SplitCheckoutController < ::BaseController
end
def update_order
- return unless params[:order]
+ return if @order.errors.any?
@order.update(order_params) && advance_order_state
end
@@ -79,37 +79,7 @@ class SplitCheckoutController < ::BaseController
end
def order_params
- return @order_params unless @order_params.nil?
-
- @order_params = params.require(:order).permit(
- :email, :shipping_method_id, :special_instructions,
- bill_address_attributes: PermittedAttributes::Address.attributes,
- ship_address_attributes: PermittedAttributes::Address.attributes,
- payments_attributes: [:payment_method_id]
- )
-
- set_address_details
- set_payment_amount
-
- @order_params
- end
-
- def set_address_details
- return unless @order_params[:ship_address_attributes] && @order_params[:bill_address_attributes]
-
- if params[:ship_address_same_as_billing]
- @order_params[:ship_address_attributes] = @order_params[:bill_address_attributes]
- else
- @order_params[:ship_address_attributes][:firstname] = @order_params[:bill_address_attributes][:firstname]
- @order_params[:ship_address_attributes][:lastname] = @order_params[:bill_address_attributes][:lastname]
- @order_params[:ship_address_attributes][:phone] = @order_params[:bill_address_attributes][:phone]
- end
- end
-
- def set_payment_amount
- return unless @order_params[:payments_attributes]
-
- @order_params[:payments_attributes].first[:amount] = @order.total
+ @order_params ||= Checkout::Params.new(@order, params).call
end
def redirect_to_step
diff --git a/app/services/checkout/params.rb b/app/services/checkout/params.rb
new file mode 100644
index 0000000000..51d0dcb780
--- /dev/null
+++ b/app/services/checkout/params.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+module Checkout
+ class Params
+ def initialize(order, params)
+ @params = params
+ @order = order
+ end
+
+ def call
+ return {} unless params[:order]
+
+ apply_strong_parameters
+ set_address_details
+ set_payment_amount
+
+ @order_params
+ end
+
+ private
+
+ attr_reader :params, :order
+
+ def apply_strong_parameters
+ @order_params = params.require(:order).permit(
+ :email, :shipping_method_id, :special_instructions,
+ bill_address_attributes: ::PermittedAttributes::Address.attributes,
+ ship_address_attributes: ::PermittedAttributes::Address.attributes,
+ payments_attributes: [:payment_method_id]
+ )
+ end
+
+ def set_address_details
+ return unless addresses_present?
+
+ if params[:ship_address_same_as_billing]
+ set_ship_address_from_bill_address
+ else
+ set_basic_details
+ end
+ end
+
+ def set_payment_amount
+ return unless @order_params[:payments_attributes]
+
+ @order_params[:payments_attributes].first[:amount] = order.total
+ end
+
+ def addresses_present?
+ @order_params[:ship_address_attributes] && @order_params[:bill_address_attributes]
+ end
+
+ def set_ship_address_from_bill_address
+ @order_params[:ship_address_attributes] = @order_params[:bill_address_attributes]
+ end
+
+ def set_basic_details
+ [:firstname, :lastname, :phone].each do |attr|
+ @order_params[:ship_address_attributes][attr] = @order_params[:bill_address_attributes][attr]
+ end
+ end
+ end
+end
From 1fca7d2a6ca288d1d95396ffde547407d10e35e4 Mon Sep 17 00:00:00 2001
From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com>
Date: Wed, 1 Sep 2021 12:36:45 +0100
Subject: [PATCH 12/20] Remove error-clearing from edit action
---
app/controllers/split_checkout_controller.rb | 3 ---
1 file changed, 3 deletions(-)
diff --git a/app/controllers/split_checkout_controller.rb b/app/controllers/split_checkout_controller.rb
index 61276b4303..f11c432aee 100644
--- a/app/controllers/split_checkout_controller.rb
+++ b/app/controllers/split_checkout_controller.rb
@@ -25,9 +25,6 @@ class SplitCheckoutController < ::BaseController
# a version of paypal that uses this controller, and more specifically
# the #action_failed method, then we can remove this call
# OrderCheckoutRestart.new(@order).call
- @order.errors.clear
- @order.bill_address.errors.clear
- @order.ship_address.errors.clear
rescue Spree::Core::GatewayError => e
rescue_from_spree_gateway_error(e)
end
From 9d6e5e9420e2f016e01c08e29a20b470ed6f46f4 Mon Sep 17 00:00:00 2001
From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com>
Date: Wed, 1 Sep 2021 13:00:17 +0100
Subject: [PATCH 13/20] Remove currently unused code
---
.../concerns/checkout_callbacks.rb | 2 +-
app/controllers/split_checkout_controller.rb | 44 +------------------
2 files changed, 2 insertions(+), 44 deletions(-)
diff --git a/app/controllers/concerns/checkout_callbacks.rb b/app/controllers/concerns/checkout_callbacks.rb
index 3e3e360bd4..638389cd59 100644
--- a/app/controllers/concerns/checkout_callbacks.rb
+++ b/app/controllers/concerns/checkout_callbacks.rb
@@ -14,7 +14,7 @@ module CheckoutCallbacks
prepend_before_action :require_distributor_chosen
before_action :load_order, :associate_user, :load_saved_addresses
- before_action :load_shipping_methods, :load_countries, if: -> { checkout_step == "details"}
+ before_action :load_shipping_methods, :load_countries, if: -> { params[:step] == "details"}
before_action :ensure_order_not_completed
before_action :ensure_checkout_allowed
diff --git a/app/controllers/split_checkout_controller.rb b/app/controllers/split_checkout_controller.rb
index f11c432aee..7467a8efcc 100644
--- a/app/controllers/split_checkout_controller.rb
+++ b/app/controllers/split_checkout_controller.rb
@@ -15,18 +15,9 @@ class SplitCheckoutController < ::BaseController
helper OrderHelper
def edit
- return handle_redirect_from_stripe if valid_payment_intent_provided?
-
- redirect_to_step unless checkout_step
+ redirect_to_step unless params[:step]
OrderWorkflow.new(@order).next if @order.cart?
-
- # This is only required because of spree_paypal_express. If we implement
- # a version of paypal that uses this controller, and more specifically
- # the #action_failed method, then we can remove this call
- # OrderCheckoutRestart.new(@order).call
- rescue Spree::Core::GatewayError => e
- rescue_from_spree_gateway_error(e)
end
def update
@@ -64,10 +55,6 @@ class SplitCheckoutController < ::BaseController
OrderWorkflow.new(@order).advance_checkout(raw_params.slice(:shipping_method_id))
end
- def checkout_step
- @checkout_step ||= params[:step]
- end
-
def validate_terms_and_conditions!
return true if params[:accept_terms]
@@ -91,33 +78,4 @@ class SplitCheckoutController < ::BaseController
redirect_to order_path(@order)
end
end
-
- def valid_payment_intent_provided?
- return false unless params["payment_intent"]&.starts_with?("pi_")
-
- last_payment = OrderPaymentFinder.new(@order).last_payment
- @order.state == "payment" &&
- last_payment&.state == "requires_authorization" &&
- last_payment&.response_code == params["payment_intent"]
- end
-
- def handle_redirect_from_stripe
- return checkout_failed unless @order.process_payments!
-
- if OrderWorkflow.new(@order).next && order_complete?
- checkout_succeeded
- redirect_to(order_path(@order)) && return
- else
- checkout_failed
- end
- end
-
- def order_complete?
- @order.state == "complete" || @order.completed?
- end
-
- def rescue_from_spree_gateway_error(error)
- flash[:error] = t(:spree_gateway_error_flash_for_checkout, error: error.message)
- action_failed(error)
- end
end
From 70513ae98950838b7c810b6815b731793a5c5f4d Mon Sep 17 00:00:00 2001
From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com>
Date: Sun, 5 Sep 2021 20:19:22 +0100
Subject: [PATCH 14/20] Don't transition to address before page load
---
app/controllers/split_checkout_controller.rb | 2 --
1 file changed, 2 deletions(-)
diff --git a/app/controllers/split_checkout_controller.rb b/app/controllers/split_checkout_controller.rb
index 7467a8efcc..3f872e296a 100644
--- a/app/controllers/split_checkout_controller.rb
+++ b/app/controllers/split_checkout_controller.rb
@@ -16,8 +16,6 @@ class SplitCheckoutController < ::BaseController
def edit
redirect_to_step unless params[:step]
-
- OrderWorkflow.new(@order).next if @order.cart?
end
def update
From e3e53b1504bca35e0855190126d0fe49ed898db4 Mon Sep 17 00:00:00 2001
From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com>
Date: Sun, 5 Sep 2021 21:17:15 +0100
Subject: [PATCH 15/20] Ensure feature toggle works for non-logged-in users
---
app/models/spree/order.rb | 2 +-
app/models/spree/order/checkout.rb | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/app/models/spree/order.rb b/app/models/spree/order.rb
index 301f17a422..1d37534b07 100644
--- a/app/models/spree/order.rb
+++ b/app/models/spree/order.rb
@@ -21,7 +21,7 @@ module Spree
order.payment_required?
}
go_to_state :confirmation, if: ->(order) {
- Flipper.enabled? :split_checkout, order.user
+ Flipper.enabled? :split_checkout
}
go_to_state :complete
end
diff --git a/app/models/spree/order/checkout.rb b/app/models/spree/order/checkout.rb
index dd4d0a80e6..d1e0d5d36c 100644
--- a/app/models/spree/order/checkout.rb
+++ b/app/models/spree/order/checkout.rb
@@ -141,7 +141,7 @@ module Spree
private
def validate_shipping_method!
- return unless user && Flipper.enabled?(:split_checkout, user)
+ return unless Flipper.enabled?(:split_checkout)
return if shipping_method.present?
errors.add :shipping_method, I18n.t('split_checkout.errors.select_a_shipping_method')
@@ -149,7 +149,7 @@ module Spree
end
def validate_payment_method!
- return unless user && Flipper.enabled?(:split_checkout, user)
+ return unless Flipper.enabled?(:split_checkout)
return if payments.any?
errors.add :payment_method, I18n.t('split_checkout.errors.select_a_payment_method')
From cfee804339c2caebc7326fe561c806cac98ba648 Mon Sep 17 00:00:00 2001
From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com>
Date: Mon, 6 Sep 2021 14:19:13 +0100
Subject: [PATCH 16/20] Improve concern loading
It shouldn't need `require` or `prepend`
---
app/models/concerns/order_shipment.rb | 4 +++-
app/models/spree/order.rb | 4 +---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/app/models/concerns/order_shipment.rb b/app/models/concerns/order_shipment.rb
index dd5ebeba01..0a1c30f625 100644
--- a/app/models/concerns/order_shipment.rb
+++ b/app/models/concerns/order_shipment.rb
@@ -13,7 +13,9 @@ require 'active_support/concern'
module OrderShipment
extend ActiveSupport::Concern
- attr_accessor :manual_shipping_selection
+ included do
+ attr_accessor :manual_shipping_selection
+ end
def shipment
shipments.first
diff --git a/app/models/spree/order.rb b/app/models/spree/order.rb
index 1d37534b07..a549cab3d9 100644
--- a/app/models/spree/order.rb
+++ b/app/models/spree/order.rb
@@ -4,12 +4,10 @@ require 'spree/order/checkout'
require 'open_food_network/enterprise_fee_calculator'
require 'open_food_network/feature_toggle'
require 'open_food_network/tag_rule_applicator'
-require 'concerns/order_shipment'
module Spree
class Order < ApplicationRecord
- prepend OrderShipment
-
+ include OrderShipment
include Checkout
include Balance
From c3b52ef00acaf9d00114177e4d6c098d6f59ffb2 Mon Sep 17 00:00:00 2001
From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com>
Date: Mon, 6 Sep 2021 14:19:35 +0100
Subject: [PATCH 17/20] Remove payments validation
---
app/models/spree/order.rb | 1 -
1 file changed, 1 deletion(-)
diff --git a/app/models/spree/order.rb b/app/models/spree/order.rb
index a549cab3d9..b9dbbc94dd 100644
--- a/app/models/spree/order.rb
+++ b/app/models/spree/order.rb
@@ -92,7 +92,6 @@ module Spree
validates :email, presence: true,
format: /\A([\w.%+\-']+)@([\w\-]+\.)+(\w{2,})\z/i,
if: :require_email
- validates :payments, presence: true, if: ->(order) { order.confirmation? && payment_required? }
make_permalink field: :number
From 71412f8d4b18d5a3c2bb21fcdd9e7931b271ea03 Mon Sep 17 00:00:00 2001
From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com>
Date: Mon, 6 Sep 2021 14:22:28 +0100
Subject: [PATCH 18/20] Update validations
---
app/controllers/concerns/checkout_callbacks.rb | 1 +
app/models/spree/order.rb | 14 +++++++++++---
app/models/spree/order/checkout.rb | 11 +----------
3 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/app/controllers/concerns/checkout_callbacks.rb b/app/controllers/concerns/checkout_callbacks.rb
index 638389cd59..bc50a80b09 100644
--- a/app/controllers/concerns/checkout_callbacks.rb
+++ b/app/controllers/concerns/checkout_callbacks.rb
@@ -28,6 +28,7 @@ module CheckoutCallbacks
def load_order
@order = current_order
@order.manual_shipping_selection = true
+ @order.checkout_processing = true
redirect_to(main_app.shop_path) && return if redirect_to_shop?
redirect_to_cart_path && return unless valid_order_line_items?
diff --git a/app/models/spree/order.rb b/app/models/spree/order.rb
index b9dbbc94dd..b3c2cc90b5 100644
--- a/app/models/spree/order.rb
+++ b/app/models/spree/order.rb
@@ -24,6 +24,9 @@ module Spree
go_to_state :complete
end
+ attr_accessor :use_billing
+ attr_accessor :checkout_processing
+
token_resource
belongs_to :user, class_name: Spree.user_class.to_s
@@ -79,8 +82,6 @@ module Spree
before_validation :associate_customer, unless: :customer_id?
before_validation :ensure_customer, unless: :customer_is_valid?
- attr_accessor :use_billing
-
before_create :link_by_email
after_create :create_tax_charge!
@@ -137,6 +138,13 @@ module Spree
scope :by_state, lambda { |state| where(state: state) }
scope :not_state, lambda { |state| where.not(state: state) }
+ def initialize(*_args)
+ @checkout_processing = nil
+ @manual_shipping_selection = nil
+
+ super
+ end
+
# For compatiblity with Calculator::PriceSack
def amount
line_items.inject(0.0) { |sum, li| sum + li.amount }
@@ -625,7 +633,7 @@ module Spree
# Determine if email is required (we don't want validation errors before we hit the checkout)
def require_email
- return true unless new_record? || (state == 'cart')
+ return true unless (new_record? || cart?) && !checkout_processing
end
def ensure_line_items_present
diff --git a/app/models/spree/order/checkout.rb b/app/models/spree/order/checkout.rb
index d1e0d5d36c..3671639bcc 100644
--- a/app/models/spree/order/checkout.rb
+++ b/app/models/spree/order/checkout.rb
@@ -75,7 +75,6 @@ module Spree
before_transition to: :delivery, do: :create_proposed_shipments
before_transition to: :delivery, do: :ensure_available_shipping_rates
- before_transition to: :payment, do: :validate_shipping_method!
before_transition to: :payment, do: :create_tax_charge!
before_transition to: :confirmation, do: :validate_payment_method!
@@ -140,16 +139,8 @@ module Spree
private
- def validate_shipping_method!
- return unless Flipper.enabled?(:split_checkout)
- return if shipping_method.present?
-
- errors.add :shipping_method, I18n.t('split_checkout.errors.select_a_shipping_method')
- throw :halt
- end
-
def validate_payment_method!
- return unless Flipper.enabled?(:split_checkout)
+ return unless checkout_processing
return if payments.any?
errors.add :payment_method, I18n.t('split_checkout.errors.select_a_payment_method')
From fb7a3a681b3a75b417e9a06737184efde14beb04 Mon Sep 17 00:00:00 2001
From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com>
Date: Mon, 6 Sep 2021 14:25:16 +0100
Subject: [PATCH 19/20] Validate attributes per checkout step and decouple
order-advancing
---
app/controllers/split_checkout_controller.rb | 26 ++++++++++++++++----
app/services/order_workflow.rb | 4 +--
2 files changed, 22 insertions(+), 8 deletions(-)
diff --git a/app/controllers/split_checkout_controller.rb b/app/controllers/split_checkout_controller.rb
index 3f872e296a..9849f10b19 100644
--- a/app/controllers/split_checkout_controller.rb
+++ b/app/controllers/split_checkout_controller.rb
@@ -21,6 +21,7 @@ class SplitCheckoutController < ::BaseController
def update
if confirm_order || update_order
clear_invalid_payments
+ advance_order_state
redirect_to_step
else
flash.now[:error] = I18n.t('split_checkout.errors.global')
@@ -36,7 +37,7 @@ class SplitCheckoutController < ::BaseController
def confirm_order
return unless @order.confirmation? && params[:confirm_order]
- return unless validate_terms_and_conditions!
+ return unless validate_summary! && @order.errors.empty?
@order.confirm!
end
@@ -44,20 +45,35 @@ class SplitCheckoutController < ::BaseController
def update_order
return if @order.errors.any?
- @order.update(order_params) && advance_order_state
+ @order.select_shipping_method(params[:shipping_method_id])
+ @order.update(order_params)
+ send("validate_#{params[:step]}!")
+
+ @order.errors.empty?
end
def advance_order_state
- return true if @order.complete?
+ return if @order.complete?
OrderWorkflow.new(@order).advance_checkout(raw_params.slice(:shipping_method_id))
end
- def validate_terms_and_conditions!
+ def validate_details!
+ return true if params[:shipping_method_id].present?
+
+ @order.errors.add :shipping_method, I18n.t('split_checkout.errors.select_a_shipping_method')
+ end
+
+ def validate_payment!
+ return true if params.dig(:order, :payments_attributes).present?
+
+ @order.errors.add :payment_method, I18n.t('split_checkout.errors.select_a_payment_method')
+ end
+
+ def validate_summary!
return true if params[:accept_terms]
@order.errors.add(:terms_and_conditions, t("split_checkout.errors.terms_not_accepted"))
- false
end
def order_params
diff --git a/app/services/order_workflow.rb b/app/services/order_workflow.rb
index 8f8b3028c9..b27a828370 100644
--- a/app/services/order_workflow.rb
+++ b/app/services/order_workflow.rb
@@ -28,9 +28,7 @@ class OrderWorkflow
end
def advance_checkout(options = {})
- order.select_shipping_method(options[:shipping_method_id])
-
- advance_to = order.address? || order.delivery? ? "payment" : "confirmation"
+ advance_to = order.state.in?(["cart", "address", "delivery"]) ? "payment" : "confirmation"
advance_to_state(advance_to, advance_order_options.merge(options))
end
From 3bcfc673f7b7b14972ee7a3ef48f8f8a7f0640ed Mon Sep 17 00:00:00 2001
From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com>
Date: Mon, 6 Sep 2021 20:27:10 +0100
Subject: [PATCH 20/20] Ensure selected shipping method is actually selected
Hashes with symbol keys != hashes with string keys :see_no_evil:
---
app/controllers/checkout_controller.rb | 2 +-
app/services/order_workflow.rb | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/app/controllers/checkout_controller.rb b/app/controllers/checkout_controller.rb
index cffa0877b7..6b0f08ba99 100644
--- a/app/controllers/checkout_controller.rb
+++ b/app/controllers/checkout_controller.rb
@@ -175,7 +175,7 @@ class CheckoutController < ::BaseController
return action_failed unless @order.process_payments!
end
- next if OrderWorkflow.new(@order).next({ shipping_method_id: shipping_method_id })
+ next if OrderWorkflow.new(@order).next({ "shipping_method_id" => shipping_method_id })
return action_failed
end
diff --git a/app/services/order_workflow.rb b/app/services/order_workflow.rb
index b27a828370..46596b67ce 100644
--- a/app/services/order_workflow.rb
+++ b/app/services/order_workflow.rb
@@ -37,7 +37,7 @@ class OrderWorkflow
def advance_order_options
shipping_method_id = order.shipping_method.id if order.shipping_method.present?
- { shipping_method_id: shipping_method_id }
+ { "shipping_method_id" => shipping_method_id }
end
def advance_to_state(target_state, options = {})
@@ -67,7 +67,7 @@ class OrderWorkflow
def after_transition_hook(options)
if order.state == "delivery"
- order.select_shipping_method(options[:shipping_method_id])
+ order.select_shipping_method(options["shipping_method_id"])
end
persist_all_payments if order.state == "payment"