Individual StandingOrder orders can be cancelled from Standing Order index

This commit is contained in:
Rob Harrington
2016-12-02 10:28:26 +11:00
parent 27b22acd37
commit 7644f08d5c
10 changed files with 151 additions and 28 deletions

View File

@@ -1,3 +1,7 @@
angular.module("admin.standingOrders").controller "OrdersPanelController", ($scope, OrderCycles) ->
$scope.standingOrder = $scope.object
$scope.orderCyclesByID = OrderCycles.byID
$scope.cancelOrder = (order) ->
if confirm(t('are_you_sure'))
$scope.standingOrder.cancelOrder(order)

View File

@@ -32,3 +32,11 @@ angular.module("admin.standingOrders").factory 'StandingOrderPrototype', ($http,
, (response) =>
StatusMessage.display 'failure', 'Oh no! I was unable to save your changes.'
angular.extend(@errors, response.data.errors)
cancelOrder: (order) ->
if order.id?
$http.put("/admin/standing_order_orders/#{order.id}/cancel").then (response) =>
angular.extend(order,response.data)
, (response) ->
InfoDialog.open 'error', response.data.errors[0]

View File

@@ -0,0 +1,17 @@
module Admin
class StandingOrderOrdersController < ResourceController
respond_to :json
def cancel
if @standing_order_order.cancel
respond_with(@standing_order_order) do |format|
format.json { render_as_json @standing_order_order }
end
else
respond_with(@standing_order_order) do |format|
format.json { render json: { errors: @standing_order_order.errors.full_messages }, status: :unprocessable_entity }
end
end
end
end
end

View File

@@ -260,6 +260,9 @@ class AbilityDecorator
can [:destroy], StandingLineItem do |standing_line_item|
user.enterprises.include?(standing_line_item.standing_order.shop)
end
can [:admin, :cancel], StandingOrderOrder do |standing_order_order|
user.enterprises.include?(standing_order_order.standing_order.shop)
end
end
def add_relationship_management_abilities(user)

View File

@@ -1,24 +1,25 @@
%script{ type: "text/ng-template", id: "admin/panels/standing_order_orders.html" }
%form{ name: 'standing_order_form', ng: { controller: 'OrdersPanelController' } }
%div{ style: 'width: 90%; margin: auto;' }
%table
%col{ style: 'width: 20%' }
%col{ style: 'width: 20%' }
%col{ style: 'width: 20%' }
%col{ style: 'width: 20%' }
%col{ style: 'width: 20%' }
%thead
%th Number
%th OC
%th Status
%th Total
%th.actions
%tbody
%tr{ ng: { repeat: 'order in standingOrder.not_closed_standing_order_orders' } }
%td
%a{ ng: { href: "{{::order.edit_path}}", bind: '::order.number' }, target: '_blank' }
%td{ ng: { bind: '::orderCyclesByID[order.order_cycle_id].name' } }
%td{ ng: { bind: '::order.status' } }
%td{ ng: { bind: '::order.total' } }
%td.actions
&nbsp;
%form.margin-top-30{ name: 'standing_order_form', ng: { controller: 'OrdersPanelController' } }
.row.standing-order-orders
.fourteen.columns.offset-by-one
%table
%col{ style: 'width: 25%' }
%col{ style: 'width: 25%' }
%col{ style: 'width: 25%' }
%col{ style: 'width: 15%' }
%col{ style: 'width: 10%' }
%thead
%th= t('admin.standing_orders.orders.number')
%th= t('admin.order_cycle')
%th= t('admin.standing_orders.orders.status')
%th= t('total')
%th.actions
%tbody
%tr.standing_order_order{ :id => "o_{{order.id}}", ng: { repeat: 'order in standingOrder.not_closed_standing_order_orders' } }
%td
%a{ ng: { href: "{{::order.edit_path}}", bind: '::order.number' }, target: '_blank' }
%td{ ng: { bind: '::orderCyclesByID[order.order_cycle_id].name' } }
%td.text-center{ ng: { bind: 'order.status' } }
%td.text-center{ ng: { bind: 'order.total' } }
%td.actions
%a.cancel-order.icon-remove.no-text{ href: 'javascript:void(0)', ng: { click: "cancelOrder(order)" }, 'ofn-with-tip' => t(:cancel_order) }

View File

@@ -33,8 +33,8 @@
= t('admin.shipping_method')
%th.actions
&nbsp;
%tbody.panel-ctrl{ object: 'standingOrder', ng: { repeat: "standingOrder in standingOrders | filter:query" } }
%tr.standing_order{ :id => "so_{{standingOrder.id}}", class: { even: "'even'", odd: "'odd'" } }
%tbody.panel-ctrl{ object: 'standingOrder', ng: { repeat: "standingOrder in standingOrders | filter:query track by standingOrder.id" } }
%tr.standing_order{ :id => "so_{{standingOrder.id}}", ng: { class: { even: "'even'", odd: "'odd'" } } }
%td.customer.text-center{ ng: { show: 'columns.customer.visible', bind: '::standingOrder.customer_email' } }
%td.schedule.text-center{ ng: { show: 'columns.schedule.visible', bind: '::standingOrder.schedule_name' } }
%td.items.panel-toggle.text-center{ name: 'products', ng: { show: 'columns.items.visible' } }

View File

@@ -809,6 +809,9 @@ en:
details: Details
invalid_error: Oops! Please fill in all of the required fields...
product_already_in_order: This product has already been added to the order. Please edit the quantity directly.
orders:
number: Number
status: Status
stripe_connect_settings:
edit:

View File

@@ -182,6 +182,10 @@ Openfoodnetwork::Application.routes.draw do
resources :standing_line_items, only: [], format: :json do
post :build, on: :collection
end
resources :standing_order_orders, only: [], format: :json do
put :cancel, on: :member
end
end
namespace :api do

View File

@@ -0,0 +1,52 @@
require 'spec_helper'
describe Admin::StandingOrderOrdersController, type: :controller do
include AuthenticationWorkflow
describe 'cancel' do
let!(:user) { create(:user, enterprise_limit: 10) }
let!(:shop) { create(:distributor_enterprise) }
let!(:order) { create(:order, order_cycle: create(:simple_order_cycle)) }
let!(:standing_order) { create(:standing_order_with_items, shop: shop, orders: [order]) }
let!(:standing_order_order) { standing_order.standing_order_orders.first }
before do
allow(controller).to receive(:spree_current_user) { user }
end
context 'json' do
let(:params) { { format: :json, id: standing_order_order.id } }
context 'as a regular user' do
it 'redirects to unauthorized' do
spree_put :cancel, params
expect(response).to redirect_to spree.unauthorized_path
end
end
context 'as an enterprise user' do
context "without authorisation" do
let!(:shop2) { create(:distributor_enterprise) }
before { shop2.update_attributes(owner: user) }
it 'redirects to unauthorized' do
spree_put :cancel, params
expect(response).to redirect_to spree.unauthorized_path
end
end
context "with authorisation" do
before { shop.update_attributes(owner: user) }
it 'renders the cancelled standing_order_order as json' do
spree_get :cancel, params
json_response = JSON.parse(response.body)
expect(json_response['status']).to eq "cancelled"
expect(json_response['id']).to eq standing_order_order.id
expect(standing_order_order.reload.cancelled_at).to be_within(5.seconds).of Time.now
end
end
end
end
end
end

View File

@@ -13,9 +13,16 @@ feature 'Standing Orders' do
before { quick_login_as user }
context 'listing standing orders' do
let!(:standing_order) { create(:standing_order, shop: shop) }
let!(:standing_order2) { create(:standing_order, shop: shop2) }
let!(:standing_order_unmanaged) { create(:standing_order, shop: shop_unmanaged) }
let!(:standing_order) { create(:standing_order_with_items, shop: shop) }
let!(:standing_order2) { create(:standing_order_with_items, shop: shop2) }
let!(:standing_order_unmanaged) { create(:standing_order_with_items, shop: shop_unmanaged) }
before do
# initialise standing orders
StandingOrderForm.new(standing_order).send(:initialise_orders!)
StandingOrderForm.new(standing_order2).send(:initialise_orders!)
StandingOrderForm.new(standing_order_unmanaged).send(:initialise_orders!)
end
it "passes the smoke test" do
visit spree.admin_path
@@ -59,6 +66,30 @@ feature 'Standing Orders' do
first("div#columns-dropdown div.menu div.menu_item", text: "Customer").click
expect(page).to_not have_selector "th.customer"
expect(page).to_not have_content standing_order.customer.email
# Viewing Orders
within "tr#so_#{standing_order.id}" do
expect(page).to have_selector "td.orders.panel-toggle", text: 1
page.find("td.orders.panel-toggle").trigger('click')
end
# save_screenshot '/Users/rob/Desktop/ss1.png'
# expect(page).to have_selector ".standing-order-orders"
within ".standing-order-orders" do
expect(page).to have_selector "tr.standing_order_order", count: 1
# Cancelling an order
standing_order_order = standing_order.standing_order_orders.first
within "tr#o_#{standing_order_order.id}" do
expect(page).to_not have_content 'CANCELLED'
accept_alert 'Are you sure?' do
find("a.cancel-order").trigger('click')
end
expect(page).to have_content 'CANCELLED'
expect(standing_order_order.reload.cancelled_at).to be_within(5.seconds).of Time.now
end
end
end
end