diff --git a/app/jobs/standing_order_placement_job.rb b/app/jobs/standing_order_placement_job.rb
index 118cbf5b76..956584d858 100644
--- a/app/jobs/standing_order_placement_job.rb
+++ b/app/jobs/standing_order_placement_job.rb
@@ -19,7 +19,10 @@ class StandingOrderPlacementJob
def process(order)
return if order.completed?
- changes = cap_quantity_and_store_changes(order) unless order.completed?
+ changes = cap_quantity_and_store_changes(order)
+ if order.line_items.where('quantity > 0').empty?
+ return send_empty_email(order, changes)
+ end
move_to_completion(order)
send_placement_email(order, changes)
end
@@ -66,4 +69,8 @@ class StandingOrderPlacementJob
return unless order.completed?
Spree::OrderMailer.standing_order_email(order.id, 'placement', changes).deliver
end
+
+ def send_empty_email(order, changes)
+ Spree::OrderMailer.standing_order_email(order.id, 'empty', changes).deliver
+ end
end
diff --git a/app/views/spree/order_mailer/standing_order_email.html.haml b/app/views/spree/order_mailer/standing_order_email.html.haml
index dd519f20ba..60d8191b6e 100644
--- a/app/views/spree/order_mailer/standing_order_email.html.haml
+++ b/app/views/spree/order_mailer/standing_order_email.html.haml
@@ -27,11 +27,15 @@
%p
= t("email_so_#{@type}_details_html", distributor: @order.distributor.name)
-- if @changes.any?
+- if @changes.any? && @type == 'placement'
%p.callout
= t("email_so_placement_changes")
+
= render 'order_summary'
-= render 'payment'
-= render 'shipping'
-= render 'special_instructions'
+
+- unless @type == 'empty'
+ = render 'payment'
+ = render 'shipping'
+ = render 'special_instructions'
+
= render 'signoff'
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 4be858f6f8..c64dea4474 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -1218,6 +1218,9 @@ See the %{link} to find out more about %{sitename}'s features and to start using
email_so_confirmation_intro_html: "Your order with %{distributor} is now confirmed"
email_so_confirmation_explainer_html: "This order was automatically placed for you, and it has now been finalised."
email_so_confirmation_details_html: "Here's everything you need to know about your order from %{distributor}:"
+ email_so_empty_intro_html: "We tried to place a new order with %{distributor}, but had some problems..."
+ email_so_empty_explainer_html: "Unfortunately, none of products that you ordered were available. The original quantities that you requested appear crossed-out below."
+ email_so_empty_details_html: "Here are the details of the order for %{distributor}:"
email_shipping_delivery_details: Delivery details
email_shipping_delivery_time: "Delivery on:"
email_shipping_delivery_address: "Delivery address:"
diff --git a/spec/jobs/standing_order_placement_job_spec.rb b/spec/jobs/standing_order_placement_job_spec.rb
index b1e4b17dba..aef6db69aa 100644
--- a/spec/jobs/standing_order_placement_job_spec.rb
+++ b/spec/jobs/standing_order_placement_job_spec.rb
@@ -122,12 +122,11 @@ describe StandingOrderPlacementJob do
let(:standing_order) { create(:standing_order, with_items: true) }
let(:proxy_order) { create(:proxy_order, standing_order: standing_order) }
let!(:order) { proxy_order.initialise_order! }
- let(:changes) { {} }
before do
expect_any_instance_of(Spree::Payment).to_not receive(:process!)
- allow(job).to receive(:cap_quantity_and_store_changes) { changes }
allow(job).to receive(:send_placement_email)
+ allow(job).to receive(:send_empty_email)
end
context "when the order is already complete" do
@@ -142,18 +141,31 @@ describe StandingOrderPlacementJob do
end
context "when the order is not already complete" do
- it "processes the order to completion, but does not process the payment" do
- # If this spec starts complaining about no shipping methods being available
- # on CI, there is probably another spec resetting the currency though Rails.cache.clear
- ActionMailer::Base.deliveries.clear
- expect{job.send(:process, order)}.to change{order.reload.completed_at}.from(nil)
- expect(order.completed_at).to be_within(5.seconds).of Time.now
- expect(order.payments.first.state).to eq "checkout"
+ context "when no stock items are available after capping stock" do
+ before do
+ allow(job).to receive(:unavailable_stock_lines_for) { order.line_items }
+ end
+
+ it "does not place the order, sends an empty_order email" do
+ expect{job.send(:process, order)}.to_not change{order.reload.completed_at}.from(nil)
+ expect(job).to_not have_received(:send_placement_email)
+ expect(job).to have_received(:send_empty_email)
+ end
end
- it "does not enqueue confirmation emails" do
- expect{job.send(:process, order)}.to_not enqueue_job ConfirmOrderJob
- expect(job).to have_received(:send_placement_email).with(order, changes).once
+ context "when at least one stock item is available after capping stock" do
+ it "processes the order to completion, but does not process the payment" do
+ # If this spec starts complaining about no shipping methods being available
+ # on CI, there is probably another spec resetting the currency though Rails.cache.clear
+ expect{job.send(:process, order)}.to change{order.reload.completed_at}.from(nil)
+ expect(order.completed_at).to be_within(5.seconds).of Time.now
+ expect(order.payments.first.state).to eq "checkout"
+ end
+
+ it "does not enqueue confirmation emails" do
+ expect{job.send(:process, order)}.to_not enqueue_job ConfirmOrderJob
+ expect(job).to have_received(:send_placement_email).with(order, anything).once
+ end
end
end
end
diff --git a/spec/mailers/order_mailer_spec.rb b/spec/mailers/order_mailer_spec.rb
index ecc19db510..864e3f1ab9 100644
--- a/spec/mailers/order_mailer_spec.rb
+++ b/spec/mailers/order_mailer_spec.rb
@@ -108,4 +108,21 @@ describe Spree::OrderMailer do
expect(body).to include "This order was automatically placed for you"
end
end
+
+ describe "empty order notification for standing orders" do
+ let(:standing_order) { create(:standing_order, with_items: true) }
+ let(:proxy_order) { create(:proxy_order, standing_order: standing_order) }
+ let!(:order) { proxy_order.initialise_order! }
+
+ before do
+ expect do
+ Spree::OrderMailer.standing_order_email(order.id, 'empty', {}).deliver
+ end.to change{Spree::OrderMailer.deliveries.count}.by(1)
+ end
+
+ it "sends the email" do
+ body = Spree::OrderMailer.deliveries.last.body.encoded
+ expect(body).to include "Unfortunately, none of products that you ordered were available"
+ end
+ end
end