From b98afc00ba579cdcbe91fc19613377cd073ee9f6 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 21 Feb 2018 18:56:59 +1100 Subject: [PATCH] Show message about resumable orders when unpausing a subscription --- .../services/subscription_actions.js.coffee | 8 ++- .../admin/subscriptions_controller.rb | 7 ++ app/models/proxy_order.rb | 2 + config/locales/en.yml | 1 + .../admin/subscriptions_controller_spec.rb | 67 +++++++++++++++++-- 5 files changed, 77 insertions(+), 8 deletions(-) diff --git a/app/assets/javascripts/admin/subscriptions/services/subscription_actions.js.coffee b/app/assets/javascripts/admin/subscriptions/services/subscription_actions.js.coffee index 80c959702f..3c56a131c9 100644 --- a/app/assets/javascripts/admin/subscriptions/services/subscription_actions.js.coffee +++ b/app/assets/javascripts/admin/subscriptions/services/subscription_actions.js.coffee @@ -55,8 +55,12 @@ angular.module("admin.subscriptions").factory 'SubscriptionActions', ($http, $in unpause: -> ConfirmDialog.open('error', t('admin.subscriptions.confirm_unpause_msg'), {confirm: t('admin.subscriptions.yes_i_am_sure')}) .then => - @$unpause().then angular.noop, -> - InfoDialog.open 'error', t('admin.subscriptions.unpause_failure_msg') + @$unpause().then angular.noop, (response) => + if response.data?.errors?.canceled_orders? + InfoDialog.open('info', response.data.errors.canceled_orders) + .then (=> @$unpause(canceled_orders: 'notified')) + else + InfoDialog.open 'error', t('admin.subscriptions.unpause_failure_msg') cancelOrder: (order) -> if order.id? diff --git a/app/controllers/admin/subscriptions_controller.rb b/app/controllers/admin/subscriptions_controller.rb index 32a24883c1..1233628dd6 100644 --- a/app/controllers/admin/subscriptions_controller.rb +++ b/app/controllers/admin/subscriptions_controller.rb @@ -7,6 +7,7 @@ module Admin before_filter :strip_banned_attrs, only: [:update] before_filter :wrap_nested_attrs, only: [:create, :update] before_filter :check_for_open_orders, only: [:cancel, :pause] + before_filter :check_for_canceled_orders, only: [:unpause] respond_to :json def index @@ -125,6 +126,12 @@ module Admin render json: { errors: { open_orders: t('admin.subscriptions.confirm_cancel_open_orders_msg') } }, status: :conflict end + def check_for_canceled_orders + return if params[:canceled_orders] == 'notified' + return if @subscription.proxy_orders.active.canceled.empty? + render json: { errors: { canceled_orders: t('admin.subscriptions.resume_canceled_orders_msg') } }, status: :conflict + end + def strip_banned_attrs params[:subscription].delete :schedule_id params[:subscription].delete :customer_id diff --git a/app/models/proxy_order.rb b/app/models/proxy_order.rb index a66b11ad9b..c1073b474d 100644 --- a/app/models/proxy_order.rb +++ b/app/models/proxy_order.rb @@ -9,8 +9,10 @@ class ProxyOrder < ActiveRecord::Base delegate :number, :completed_at, :total, to: :order, allow_nil: true + scope :active, -> { joins(:order_cycle).merge(OrderCycle.active) } scope :closed, -> { joins(:order_cycle).merge(OrderCycle.closed) } scope :not_closed, -> { joins(:order_cycle).merge(OrderCycle.not_closed) } + scope :canceled, -> { where('proxy_orders.canceled_at IS NOT NULL') } scope :not_canceled, -> { where('proxy_orders.canceled_at IS NULL') } scope :placed_and_open, -> { joins(:order).not_closed.where(spree_orders: { state: 'complete' }) } diff --git a/config/locales/en.yml b/config/locales/en.yml index 71e11de4be..898bb0584c 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -927,6 +927,7 @@ en: confirm_unpause_msg: Are you sure you want to unpause this subscription? unpause_failure_msg: 'Sorry, unpausing failed!' confirm_cancel_open_orders_msg: "Some orders for this subscription are currently open. The customer has already been notified that the order will be placed. Would you like to cancel these order(s) or keep them?" + resume_canceled_orders_msg: "Some orders for this subscription can be resumed right now. You can resume them from the orders dropdown." yes_cancel_them: Cancel them no_keep_them: Keep them yes_i_am_sure: Yes, I'm sure diff --git a/spec/controllers/admin/subscriptions_controller_spec.rb b/spec/controllers/admin/subscriptions_controller_spec.rb index 9a18613a25..28834f50f6 100644 --- a/spec/controllers/admin/subscriptions_controller_spec.rb +++ b/spec/controllers/admin/subscriptions_controller_spec.rb @@ -605,12 +605,67 @@ describe Admin::SubscriptionsController, type: :controller do context "with authorisation" do before { shop.update_attributes(owner: user) } - it 'renders the paused subscription as json' do - spree_put :unpause, params - json_response = JSON.parse(response.body) - expect(json_response['paused_at']).to be nil - expect(json_response['id']).to eq subscription.id - expect(subscription.reload.paused_at).to be nil + context "when at least one order in an open order cycle is 'complete'" do + let(:order_cycle) { subscription.order_cycles.first } + let(:proxy_order) { create(:proxy_order, subscription: subscription, order_cycle: order_cycle) } + let!(:order) { proxy_order.initialise_order! } + + before { while !order.completed? do break unless order.next! end } + + context "when no associated orders are 'canceled'" do + it 'renders the unpaused subscription as json, leaves the order untouched' do + spree_put :unpause, params + json_response = JSON.parse(response.body) + expect(json_response['paused_at']).to be nil + expect(json_response['id']).to eq subscription.id + expect(subscription.reload.paused_at).to be nil + expect(order.reload.state).to eq 'complete' + expect(proxy_order.reload.canceled_at).to be nil + end + end + + context "when at least one associate orders is 'canceled'" do + before do + Spree::MailMethod.create!( + environment: Rails.env, + preferred_mails_from: 'spree@example.com' + ) + proxy_order.cancel + end + + context "when no 'canceled_orders' directive has been provided" do + it "renders a message, informing the user that canceled order can be resumed" do + spree_put :unpause, params + expect(response.status).to be 409 + json_response = JSON.parse(response.body) + expect(json_response['errors']['canceled_orders']).to eq I18n.t('admin.subscriptions.resume_canceled_orders_msg') + end + end + + context "when 'notified' has been provided as the 'canceled_orders' directive" do + before { params.merge!(canceled_orders: 'notified') } + + it 'renders the unpaused subscription as json, leaves the order untouched' do + spree_put :unpause, params + json_response = JSON.parse(response.body) + expect(json_response['paused_at']).to be nil + expect(json_response['id']).to eq subscription.id + expect(subscription.reload.paused_at).to be nil + expect(order.reload.state).to eq 'canceled' + expect(proxy_order.reload.canceled_at).to_not be nil + end + end + end + end + + context "when no associated orders are 'complete'" do + it 'renders the unpaused subscription as json' do + spree_put :unpause, params + json_response = JSON.parse(response.body) + expect(json_response['paused_at']).to be nil + expect(json_response['id']).to eq subscription.id + expect(subscription.reload.paused_at).to be nil + end end end end