mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
Merge pull request #8653 from Matt-Yorkley/split-checkout-t-and-c
Split checkout T&Cs
This commit is contained in:
@@ -47,9 +47,10 @@ class SplitCheckoutController < ::BaseController
|
||||
end
|
||||
|
||||
def confirm_order
|
||||
return unless @order.confirmation? && params[:confirm_order]
|
||||
return unless summary_step? && @order.confirmation?
|
||||
return unless validate_summary! && @order.errors.empty?
|
||||
|
||||
@order.customer.touch :terms_and_conditions_accepted_at
|
||||
@order.confirm!
|
||||
end
|
||||
|
||||
@@ -58,17 +59,27 @@ class SplitCheckoutController < ::BaseController
|
||||
|
||||
@order.select_shipping_method(params[:shipping_method_id])
|
||||
@order.update(order_params)
|
||||
send("validate_#{params[:step]}!")
|
||||
|
||||
validate_current_step!
|
||||
|
||||
@order.errors.empty?
|
||||
end
|
||||
|
||||
def summary_step?
|
||||
params[:step] == "summary"
|
||||
end
|
||||
|
||||
def advance_order_state
|
||||
return if @order.complete?
|
||||
|
||||
OrderWorkflow.new(@order).advance_checkout(raw_params.slice(:shipping_method_id))
|
||||
end
|
||||
|
||||
def validate_current_step!
|
||||
step = ([params[:step]] & ["details", "payment", "summary"]).first
|
||||
send("validate_#{step}!")
|
||||
end
|
||||
|
||||
def validate_details!
|
||||
return true if params[:shipping_method_id].present?
|
||||
|
||||
@@ -83,6 +94,7 @@ class SplitCheckoutController < ::BaseController
|
||||
|
||||
def validate_summary!
|
||||
return true if params[:accept_terms]
|
||||
return true unless TermsOfService.required?(@order.distributor)
|
||||
|
||||
@order.errors.add(:terms_and_conditions, t("split_checkout.errors.terms_not_accepted"))
|
||||
end
|
||||
|
||||
@@ -7,21 +7,25 @@ module TermsAndConditionsHelper
|
||||
end
|
||||
|
||||
def render_terms_and_conditions
|
||||
if platform_terms_required? && terms_and_conditions_activated?
|
||||
if platform_terms_required? && distributor_terms_required?
|
||||
render("checkout/all_terms_and_conditions")
|
||||
elsif platform_terms_required?
|
||||
render "checkout/platform_terms_of_service"
|
||||
elsif terms_and_conditions_activated?
|
||||
elsif distributor_terms_required?
|
||||
render "checkout/terms_and_conditions"
|
||||
end
|
||||
end
|
||||
|
||||
def platform_terms_required?
|
||||
Spree::Config.shoppers_require_tos
|
||||
def any_terms_required?(distributor)
|
||||
TermsOfService.required?(distributor)
|
||||
end
|
||||
|
||||
def terms_and_conditions_activated?
|
||||
current_order.distributor.terms_and_conditions.file?
|
||||
def platform_terms_required?
|
||||
TermsOfService.platform_terms_required?
|
||||
end
|
||||
|
||||
def distributor_terms_required?
|
||||
TermsOfService.distributor_terms_required?(current_order.distributor)
|
||||
end
|
||||
|
||||
def all_terms_and_conditions_already_accepted?
|
||||
|
||||
@@ -10,4 +10,16 @@ class TermsOfService
|
||||
TermsOfServiceFile.updated_at
|
||||
end
|
||||
end
|
||||
|
||||
def self.required?(distributor)
|
||||
platform_terms_required? || distributor_terms_required?(distributor)
|
||||
end
|
||||
|
||||
def self.platform_terms_required?
|
||||
Spree::Config.shoppers_require_tos
|
||||
end
|
||||
|
||||
def self.distributor_terms_required?(distributor)
|
||||
distributor.terms_and_conditions.file?
|
||||
end
|
||||
end
|
||||
|
||||
@@ -71,15 +71,16 @@
|
||||
|
||||
= render 'spree/orders/summary', order: @order
|
||||
|
||||
%div.checkout-substep.medium-6
|
||||
%div.checkout-input
|
||||
= 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" }
|
||||
- if any_terms_required?(@order.distributor)
|
||||
%div.checkout-substep.medium-6
|
||||
%div.checkout-input
|
||||
= 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
|
||||
= f.error_message_on :terms_and_conditions, standalone: true
|
||||
|
||||
%div.checkout-input
|
||||
= t("split_checkout.step3.agree")
|
||||
%div.checkout-input
|
||||
= t("split_checkout.step3.agree")
|
||||
|
||||
%div.checkout-submit.medium-6
|
||||
= f.submit t("split_checkout.step3.submit"), name: "confirm_order", class: "button primary", disabled: @terms_and_conditions_accepted == false || @platform_tos_accepted == false
|
||||
|
||||
182
spec/controllers/split_checkout_controller_spec.rb
Normal file
182
spec/controllers/split_checkout_controller_spec.rb
Normal file
@@ -0,0 +1,182 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe SplitCheckoutController, type: :controller do
|
||||
let(:user) { order.user }
|
||||
let(:address) { create(:address) }
|
||||
let(:distributor) { create(:distributor_enterprise, with_payment_and_shipping: true) }
|
||||
let(:order_cycle) { create(:order_cycle, distributors: [distributor]) }
|
||||
let(:exchange) { order_cycle.exchanges.outgoing.first }
|
||||
let(:order) {
|
||||
create(:order_with_line_items, line_items_count: 1, distributor: distributor,
|
||||
order_cycle: order_cycle)
|
||||
}
|
||||
let(:payment_method) { distributor.payment_methods.first }
|
||||
let(:shipping_method) { distributor.shipping_methods.first }
|
||||
|
||||
before do
|
||||
allow(Flipper).to receive(:enabled?).with(:split_checkout) { true }
|
||||
allow(Flipper).to receive(:enabled?).with(:split_checkout, anything) { true }
|
||||
|
||||
exchange.variants << order.line_items.first.variant
|
||||
allow(controller).to receive(:current_order) { order }
|
||||
allow(controller).to receive(:spree_current_user) { user }
|
||||
end
|
||||
|
||||
describe "#edit" do
|
||||
it "renders the checkout" do
|
||||
get :edit, params: { step: "details" }
|
||||
expect(response.status).to eq 200
|
||||
end
|
||||
|
||||
it "redirects to current step if no step is given" do
|
||||
get :edit
|
||||
expect(response).to redirect_to checkout_step_path(:details)
|
||||
end
|
||||
|
||||
context "when line items in the cart are not valid" do
|
||||
before { allow(controller).to receive(:valid_order_line_items?) { false } }
|
||||
|
||||
it "redirects to cart" do
|
||||
get :edit
|
||||
expect(response).to redirect_to cart_path
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#update" do
|
||||
let(:checkout_params) { {} }
|
||||
let(:params) { { step: step }.merge(checkout_params) }
|
||||
|
||||
context "details step" do
|
||||
let(:step) { "details" }
|
||||
|
||||
context "with incomplete data" do
|
||||
let(:checkout_params) { { order: { email: user.email } } }
|
||||
|
||||
it "returns 422 and some feedback" do
|
||||
put :update, params: params
|
||||
|
||||
expect(response.status).to eq 422
|
||||
expect(flash[:error]).to eq "Saving failed, please update the highlighted fields."
|
||||
expect(order.reload.state).to eq "cart"
|
||||
end
|
||||
end
|
||||
|
||||
context "with complete data" do
|
||||
let(:checkout_params) do
|
||||
{
|
||||
order: {
|
||||
email: user.email,
|
||||
bill_address_attributes: address.to_param,
|
||||
ship_address_attributes: address.to_param
|
||||
},
|
||||
shipping_method_id: shipping_method.id
|
||||
}
|
||||
end
|
||||
|
||||
it "updates and redirects to payment step" do
|
||||
put :update, params: params
|
||||
|
||||
expect(response).to redirect_to checkout_step_path(:payment)
|
||||
expect(order.reload.state).to eq "payment"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "payment step" do
|
||||
let(:step) { "payment" }
|
||||
|
||||
before do
|
||||
order.bill_address = address
|
||||
order.ship_address = address
|
||||
order.select_shipping_method shipping_method.id
|
||||
OrderWorkflow.new(order).advance_to_payment
|
||||
end
|
||||
|
||||
context "with incomplete data" do
|
||||
let(:checkout_params) { { order: { email: user.email } } }
|
||||
|
||||
it "returns 422 and some feedback" do
|
||||
put :update, params: params
|
||||
|
||||
expect(response.status).to eq 422
|
||||
expect(flash[:error]).to eq "Saving failed, please update the highlighted fields."
|
||||
expect(order.reload.state).to eq "payment"
|
||||
end
|
||||
end
|
||||
|
||||
context "with complete data" do
|
||||
let(:checkout_params) do
|
||||
{
|
||||
order: {
|
||||
payments_attributes: [
|
||||
{ payment_method_id: payment_method.id }
|
||||
]
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
it "updates and redirects to payment step" do
|
||||
put :update, params: params
|
||||
|
||||
expect(response).to redirect_to checkout_step_path(:summary)
|
||||
expect(order.reload.state).to eq "confirmation"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "summary step" do
|
||||
let(:step) { "summary" }
|
||||
|
||||
before do
|
||||
order.bill_address = address
|
||||
order.ship_address = address
|
||||
order.select_shipping_method shipping_method.id
|
||||
OrderWorkflow.new(order).advance_to_payment
|
||||
|
||||
order.payments << build(:payment, amount: order.total, payment_method: payment_method)
|
||||
order.next
|
||||
end
|
||||
|
||||
describe "confirming the order" do
|
||||
it "completes the order and redirects to order confirmation" do
|
||||
put :update, params: params
|
||||
|
||||
expect(response).to redirect_to order_path(order)
|
||||
expect(order.reload.state).to eq "complete"
|
||||
end
|
||||
end
|
||||
|
||||
context "when accepting T&Cs is required" do
|
||||
before do
|
||||
allow(TermsOfService).to receive(:platform_terms_required?) { true }
|
||||
end
|
||||
|
||||
describe "submitting without accepting the T&Cs" do
|
||||
let(:checkout_params) { {} }
|
||||
|
||||
it "returns 422 and some feedback" do
|
||||
put :update, params: params
|
||||
|
||||
expect(response.status).to eq 422
|
||||
expect(flash[:error]).to eq "Saving failed, please update the highlighted fields."
|
||||
expect(order.reload.state).to eq "confirmation"
|
||||
end
|
||||
end
|
||||
|
||||
describe "submitting and accepting the T&Cs" do
|
||||
let(:checkout_params) { { accept_terms: true } }
|
||||
|
||||
it "completes the order and redirects to order confirmation" do
|
||||
put :update, params: params
|
||||
|
||||
expect(response).to redirect_to order_path(order)
|
||||
expect(order.reload.state).to eq "complete"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user