`);
+ $('#custom-confirm button.confirm').unbind( "click" ).click(() => {
+ $('#custom-confirm').hide();
+ callback(true, $('#send_cancellation_email').is(':checked'));
+ });
+ $('#custom-confirm button.cancel').click(() => {
+ $('#custom-confirm').hide();
+ callback(false)
+ });
+ $('#custom-confirm').show();
+}
+
ofnConfirm = function(callback) {
$('#custom-confirm').data($(event.target).data());
$('#custom-confirm button.confirm').click(callback);
diff --git a/app/controllers/spree/admin/orders_controller.rb b/app/controllers/spree/admin/orders_controller.rb
index c1f1ce10bd..55035f6a07 100644
--- a/app/controllers/spree/admin/orders_controller.rb
+++ b/app/controllers/spree/admin/orders_controller.rb
@@ -65,6 +65,7 @@ module Spree
def fire
event = params[:e]
+ @order.send_cancellation_email = params[:send_cancellation_email] == "true"
if @order.public_send(event.to_s)
flash[:success] = Spree.t(:order_updated)
else
diff --git a/app/models/spree/order.rb b/app/models/spree/order.rb
index 87c063007a..5a0cd48b19 100644
--- a/app/models/spree/order.rb
+++ b/app/models/spree/order.rb
@@ -105,6 +105,7 @@ module Spree
after_save_commit DefaultAddressUpdater
+ attribute :send_cancellation_email, type: :boolean, default: true
# -- Scopes
scope :not_empty, -> {
left_outer_joins(:line_items).where.not(spree_line_items: { id: nil })
@@ -659,7 +660,7 @@ module Spree
def after_cancel
shipments.each(&:cancel!)
- OrderMailer.cancel_email(id).deliver_later
+ OrderMailer.cancel_email(id).deliver_later if send_cancellation_email
self.payment_state = 'credit_owed' unless shipped?
end
diff --git a/app/views/spree/admin/shared/_routes.html.erb b/app/views/spree/admin/shared/_routes.html.erb
index a0a854781f..dc8fac6b9d 100644
--- a/app/views/spree/admin/shared/_routes.html.erb
+++ b/app/views/spree/admin/shared/_routes.html.erb
@@ -9,6 +9,7 @@
:variants_search => spree.admin_search_variants_url(:format => 'json'),
:taxons_search => main_app.api_v0_taxons_url(:format => 'json'),
:orders_api => main_app.api_v0_orders_url,
- :states_search => main_app.api_v0_states_url(:format => 'json')
+ :states_search => main_app.api_v0_states_url(:format => 'json'),
+ :cancel_order => spree.fire_admin_order_url(id: @order ? @order.number : "", e: 'cancel')
}.to_json %>;
diff --git a/app/webpacker/css/admin/orders.scss b/app/webpacker/css/admin/orders.scss
index 2316b27f66..8f5b724c35 100644
--- a/app/webpacker/css/admin/orders.scss
+++ b/app/webpacker/css/admin/orders.scss
@@ -148,5 +148,9 @@ table.index td.actions {
.message {
font-size: $h5-size;
padding: 1.2em 0;
+
+ .form {
+ padding: 1.2em 0;
+ }
}
}
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 1b53cf8ffe..585bc57ff0 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -3031,7 +3031,8 @@ See the %{link} to find out more about %{sitename}'s features and to start using
invalid: "invalid"
quantity_adjusted: "Insufficient stock available. Line item updated to maximum available quantity."
quantity_unchanged: "Quantity unchanged from previous amount."
- cannot_remove_last_item: "Cannot remove last item from order. Please cancel order instead."
+ cancel_the_order_html: "This will cancel the current order. Are you sure you want to proceed?"
+ cancel_the_order_send_cancelation_email: "Send a cancellation email to the customer"
resend_user_email_confirmation:
resend: "Resend"
sending: "Resend..."
@@ -3416,6 +3417,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using
tracking: "Tracking"
tracking_number: "Tracking Number"
order_total: "Order Total"
+ order_updated: "Order updated"
customer_details: "Customer Details"
customer_details_updated: "Customer Details updated"
customer_search: "Customer Search"
diff --git a/spec/system/admin/order_spec.rb b/spec/system/admin/order_spec.rb
index 7182da0851..7e726839d1 100644
--- a/spec/system/admin/order_spec.rb
+++ b/spec/system/admin/order_spec.rb
@@ -126,6 +126,88 @@ describe '
expect(page).not_to have_select2 "add_variant_id", with_options: [product.name]
end
+ context "deleting item of an order" do
+ context "when there a more than one items in the order" do
+ let(:line_item) { create(:line_item) }
+
+ before do
+ order.line_items << line_item
+ login_as_admin_and_visit spree.edit_admin_order_path(order)
+ find("a.delete-item").click
+ expect(page).to have_content "Are you sure?"
+ end
+
+ it "show a modal 'Are you sure?' that the user can close and then nothing change" do
+ within(".modal", visible: true) do
+ expect do
+ click_on("Cancel")
+ expect(page).not_to have_content "Are you sure?"
+ end.not_to change { order.line_items.length }
+ end
+ end
+
+ it "show a modal 'Are you sure?' that the user confirm and then the item is deleted" do
+ expect(order.line_items.length).to eq(2)
+ within(".modal", visible: true) do
+ expect do
+ click_on("OK")
+ expect(page).not_to have_css(".modal", visible: true)
+ end.to change { order.reload.line_items.length }.by(-1)
+ end
+ end
+ end
+
+ context "when it is the last item of an order" do
+ before do
+ # specify that order has only one line item
+ order.line_items = [order.line_items.first]
+ login_as_admin_and_visit spree.edit_admin_order_path(order)
+ find("a.delete-item").click
+ within(".modal", visible: true) do
+ # ignore first modal by confirming it
+ click_on("OK")
+ end
+ end
+
+ context "it shows a second modal about last item deletion and therefore about order cancellation" do
+ it "that the user can close and then nothing change" do
+ expect(page).to have_content "This will cancel the current order."
+ within(".modal", visible: true) do
+ click_on("Cancel")
+ end
+
+ expect(order.reload.line_items.length).to eq(1)
+ expect(page).to have_selector('tr.stock-item', count: 1)
+ end
+
+ context "that the user can confirm" do
+ it "and then the order is cancelled and no email is sent by default" do
+ expect do
+ within(".modal", visible: true) do
+ click_on("OK")
+ end
+ expect(page).to have_content "Cannot add item to canceled order"
+ expect(order.reload.line_items.length).to eq(0)
+ expect(order.reload.state).to eq("canceled")
+ end.to_not have_enqueued_mail(Spree::OrderMailer, :cancel_email)
+ end
+
+ it "and check the checkbox to send an email to the customer about its order cancellation" do
+ expect do
+ within(".modal", visible: true) do
+ check("send_cancellation_email")
+ click_on("OK")
+ end
+ expect(page).to have_content "Cannot add item to canceled order"
+ expect(order.reload.line_items.length).to eq(0)
+ expect(order.reload.state).to eq("canceled")
+ end.to have_enqueued_mail(Spree::OrderMailer, :cancel_email)
+ end
+ end
+ end
+ end
+ end
+
it "can't add more items than are available" do
# Move the order back to the cart state
order.state = 'cart'