mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-27 01:43:22 +00:00
Require action from user when pausing/cancelling standing order with open orders
This commit is contained in:
@@ -6,6 +6,7 @@ module Admin
|
||||
before_filter :load_form_data, only: [:new, :edit]
|
||||
before_filter :strip_banned_attrs, only: [:update]
|
||||
before_filter :wrap_nested_attrs, only: [:create, :update]
|
||||
before_filter :check_for_open_orders, only: [:cancel, :pause]
|
||||
respond_to :json
|
||||
|
||||
def index
|
||||
@@ -48,7 +49,7 @@ module Admin
|
||||
end
|
||||
|
||||
def cancel
|
||||
@standing_order.cancel
|
||||
@standing_order.cancel(@open_orders_to_keep || [])
|
||||
|
||||
respond_with(@standing_order) do |format|
|
||||
format.json { render_as_json @standing_order, fee_calculator: fee_calculator }
|
||||
@@ -56,6 +57,10 @@ module Admin
|
||||
end
|
||||
|
||||
def pause
|
||||
unless params[:open_orders] == 'keep'
|
||||
@standing_order.proxy_orders.placed_and_open.each(&:cancel)
|
||||
end
|
||||
|
||||
@standing_order.update_attributes(paused_at: Time.zone.now)
|
||||
render_as_json @standing_order, fee_calculator: fee_calculator
|
||||
end
|
||||
@@ -116,6 +121,13 @@ module Admin
|
||||
end
|
||||
end
|
||||
|
||||
def check_for_open_orders
|
||||
return if params[:open_orders] == 'cancel'
|
||||
@open_orders_to_keep = @standing_order.proxy_orders.placed_and_open.pluck(:id)
|
||||
return if @open_orders_to_keep.empty? || params[:open_orders] == 'keep'
|
||||
return render json: { errors: { open_orders: t('admin.standing_orders.confirm_cancel_open_orders_msg') } }, status: :conflict
|
||||
end
|
||||
|
||||
def strip_banned_attrs
|
||||
params[:standing_order].delete :schedule_id
|
||||
params[:standing_order].delete :customer_id
|
||||
|
||||
@@ -8,6 +8,7 @@ class ProxyOrder < ActiveRecord::Base
|
||||
scope :closed, -> { joins(:order_cycle).merge(OrderCycle.closed) }
|
||||
scope :not_closed, -> { joins(:order_cycle).merge(OrderCycle.not_closed) }
|
||||
scope :not_canceled, where('proxy_orders.canceled_at IS NULL')
|
||||
scope :placed_and_open, joins(:order).not_closed.where(spree_orders: { state: 'complete' })
|
||||
|
||||
def state
|
||||
return 'canceled' if canceled?
|
||||
|
||||
@@ -30,10 +30,10 @@ class StandingOrder < ActiveRecord::Base
|
||||
proxy_orders.not_closed
|
||||
end
|
||||
|
||||
def cancel
|
||||
def cancel(keep_ids = [])
|
||||
transaction do
|
||||
self.update_column(:canceled_at, Time.zone.now)
|
||||
proxy_orders.each(&:cancel)
|
||||
proxy_orders.reject{ |o| keep_ids.include? o.id }.each(&:cancel)
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
@@ -858,6 +858,7 @@ en:
|
||||
pause_failure_msg: 'Sorry, pausing failed!'
|
||||
confirm_unpause_msg: Are you sure you want to unpause this standing order?
|
||||
unpause_failure_msg: 'Sorry, unpausing failed!'
|
||||
confirm_cancel_open_orders_msg: "Some orders for this standing order 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?"
|
||||
order_update_issues_msg: Some orders could not be automatically updated, this is most likely because they have been manually edited. Please review the issues listed below and make any adjustments to individual orders if required.
|
||||
no_results:
|
||||
no_standing_orders: No standing orders yet...
|
||||
|
||||
@@ -415,12 +415,66 @@ describe Admin::StandingOrdersController, type: :controller do
|
||||
context "with authorisation" do
|
||||
before { shop.update_attributes(owner: user) }
|
||||
|
||||
it 'renders the cancelled standing_order as json' do
|
||||
spree_put :cancel, params
|
||||
json_response = JSON.parse(response.body)
|
||||
expect(json_response['canceled_at']).to_not be nil
|
||||
expect(json_response['id']).to eq standing_order.id
|
||||
expect(standing_order.reload.canceled_at).to be_within(5.seconds).of Time.now
|
||||
context "when at least one associated order is still 'open'" do
|
||||
let(:order_cycle) { standing_order.order_cycles.first }
|
||||
let(:proxy_order) { create(:proxy_order, standing_order: standing_order, order_cycle: order_cycle) }
|
||||
let!(:order) { proxy_order.initialise_order! }
|
||||
|
||||
before { while !order.completed? do break unless order.next! end }
|
||||
|
||||
context "when no 'open_orders' directive has been provided" do
|
||||
it "renders an error, asking what to do" do
|
||||
spree_put :cancel, params
|
||||
expect(response.status).to be 409
|
||||
json_response = JSON.parse(response.body)
|
||||
expect(json_response['errors']['open_orders']).to eq I18n.t('admin.standing_orders.confirm_cancel_open_orders_msg')
|
||||
end
|
||||
end
|
||||
|
||||
context "when 'keep' has been provided as the 'open_orders' directive" do
|
||||
before { params.merge!({ open_orders: 'keep'}) }
|
||||
|
||||
it 'renders the cancelled standing_order as json, and does not cancel the open order' do
|
||||
spree_put :cancel, params
|
||||
json_response = JSON.parse(response.body)
|
||||
expect(json_response['canceled_at']).to_not be nil
|
||||
expect(json_response['id']).to eq standing_order.id
|
||||
expect(standing_order.reload.canceled_at).to be_within(5.seconds).of Time.now
|
||||
expect(order.reload.state).to eq 'complete'
|
||||
expect(proxy_order.reload.canceled_at).to be nil
|
||||
end
|
||||
end
|
||||
|
||||
context "when 'cancel' has been provided as the 'open_orders' directive" do
|
||||
let(:mail_mock) { double(:mail) }
|
||||
|
||||
before do
|
||||
params.merge!({ open_orders: 'cancel'})
|
||||
allow(Spree::OrderMailer).to receive(:cancel_email) { mail_mock }
|
||||
allow(mail_mock).to receive(:deliver)
|
||||
end
|
||||
|
||||
it 'renders the cancelled standing_order as json, and cancels the open order' do
|
||||
spree_put :cancel, params
|
||||
json_response = JSON.parse(response.body)
|
||||
expect(json_response['canceled_at']).to_not be nil
|
||||
expect(json_response['id']).to eq standing_order.id
|
||||
expect(standing_order.reload.canceled_at).to be_within(5.seconds).of Time.now
|
||||
expect(order.reload.state).to eq 'canceled'
|
||||
expect(proxy_order.reload.canceled_at).to be_within(5.seconds).of Time.now
|
||||
expect(mail_mock).to have_received(:deliver)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when no associated orders are still 'open'" do
|
||||
it 'renders the cancelled standing_order as json' do
|
||||
spree_put :cancel, params
|
||||
json_response = JSON.parse(response.body)
|
||||
expect(json_response['canceled_at']).to_not be nil
|
||||
expect(json_response['id']).to eq standing_order.id
|
||||
expect(standing_order.reload.canceled_at).to be_within(5.seconds).of Time.now
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -460,12 +514,66 @@ describe Admin::StandingOrdersController, type: :controller do
|
||||
context "with authorisation" do
|
||||
before { shop.update_attributes(owner: user) }
|
||||
|
||||
it 'renders the paused standing_order as json' do
|
||||
spree_put :pause, params
|
||||
json_response = JSON.parse(response.body)
|
||||
expect(json_response['paused_at']).to_not be nil
|
||||
expect(json_response['id']).to eq standing_order.id
|
||||
expect(standing_order.reload.paused_at).to be_within(5.seconds).of Time.now
|
||||
context "when at least one associated order is still 'open'" do
|
||||
let(:order_cycle) { standing_order.order_cycles.first }
|
||||
let(:proxy_order) { create(:proxy_order, standing_order: standing_order, order_cycle: order_cycle) }
|
||||
let!(:order) { proxy_order.initialise_order! }
|
||||
|
||||
before { while !order.completed? do break unless order.next! end }
|
||||
|
||||
context "when no 'open_orders' directive has been provided" do
|
||||
it "renders an error, asking what to do" do
|
||||
spree_put :pause, params
|
||||
expect(response.status).to be 409
|
||||
json_response = JSON.parse(response.body)
|
||||
expect(json_response['errors']['open_orders']).to eq I18n.t('admin.standing_orders.confirm_cancel_open_orders_msg')
|
||||
end
|
||||
end
|
||||
|
||||
context "when 'keep' has been provided as the 'open_orders' directive" do
|
||||
before { params.merge!({ open_orders: 'keep'}) }
|
||||
|
||||
it 'renders the paused standing_order as json, and does not cancel the open order' do
|
||||
spree_put :pause, params
|
||||
json_response = JSON.parse(response.body)
|
||||
expect(json_response['paused_at']).to_not be nil
|
||||
expect(json_response['id']).to eq standing_order.id
|
||||
expect(standing_order.reload.paused_at).to be_within(5.seconds).of Time.now
|
||||
expect(order.reload.state).to eq 'complete'
|
||||
expect(proxy_order.reload.canceled_at).to be nil
|
||||
end
|
||||
end
|
||||
|
||||
context "when 'cancel' has been provided as the 'open_orders' directive" do
|
||||
let(:mail_mock) { double(:mail) }
|
||||
|
||||
before do
|
||||
params.merge!({ open_orders: 'cancel'})
|
||||
allow(Spree::OrderMailer).to receive(:cancel_email) { mail_mock }
|
||||
allow(mail_mock).to receive(:deliver)
|
||||
end
|
||||
|
||||
it 'renders the paused standing_order as json, and cancels the open order' do
|
||||
spree_put :pause, params
|
||||
json_response = JSON.parse(response.body)
|
||||
expect(json_response['paused_at']).to_not be nil
|
||||
expect(json_response['id']).to eq standing_order.id
|
||||
expect(standing_order.reload.paused_at).to be_within(5.seconds).of Time.now
|
||||
expect(order.reload.state).to eq 'canceled'
|
||||
expect(proxy_order.reload.canceled_at).to be_within(5.seconds).of Time.now
|
||||
expect(mail_mock).to have_received(:deliver)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when no associated orders are still 'open'" do
|
||||
it 'renders the paused standing_order as json' do
|
||||
spree_put :pause, params
|
||||
json_response = JSON.parse(response.body)
|
||||
expect(json_response['paused_at']).to_not be nil
|
||||
expect(json_response['id']).to eq standing_order.id
|
||||
expect(standing_order.reload.paused_at).to be_within(5.seconds).of Time.now
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user